mirror of
https://github.com/penpot/penpot.git
synced 2025-01-26 08:29:42 -05:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
582ec187f8
9 changed files with 125 additions and 42 deletions
|
@ -41,6 +41,9 @@
|
||||||
- Fix shortcuts for zoom now take into account the mouse position [#2924](https://github.com/penpot/penpot/issues/2924)
|
- Fix shortcuts for zoom now take into account the mouse position [#2924](https://github.com/penpot/penpot/issues/2924)
|
||||||
- Fix close colorpicker on Firefox when mouse-up is outside the picker [#2911](https://github.com/penpot/penpot/issues/2911)
|
- Fix close colorpicker on Firefox when mouse-up is outside the picker [#2911](https://github.com/penpot/penpot/issues/2911)
|
||||||
- Fix problems with touch devices and Wacom tablets [#2216](https://github.com/penpot/penpot/issues/2216)
|
- Fix problems with touch devices and Wacom tablets [#2216](https://github.com/penpot/penpot/issues/2216)
|
||||||
|
- Fix problem with board titles misplaced [Taiga #4738](https://tree.taiga.io/project/penpot/issue/4738)
|
||||||
|
- Fix problem with alt getting stuck when alt+tab [Taiga #5013](https://tree.taiga.io/project/penpot/issue/5013)
|
||||||
|
- Fix problem with z positioning of elements [Taiga #5014](https://tree.taiga.io/project/penpot/issue/5014)
|
||||||
|
|
||||||
### :heart: Community contributions by (Thank you!)
|
### :heart: Community contributions by (Thank you!)
|
||||||
- To @ondrejkonec: for contributing to the code with:
|
- To @ondrejkonec: for contributing to the code with:
|
||||||
|
|
|
@ -309,12 +309,12 @@
|
||||||
(-> (or modifiers (empty))
|
(-> (or modifiers (empty))
|
||||||
(update :structure-child conj (scale-content-op value))))
|
(update :structure-child conj (scale-content-op value))))
|
||||||
|
|
||||||
(defn change-property
|
(defn change-recursive-property
|
||||||
[modifiers property value]
|
[modifiers property value]
|
||||||
(-> (or modifiers (empty))
|
(-> (or modifiers (empty))
|
||||||
(update :structure-child conj (change-property-op property value))))
|
(update :structure-child conj (change-property-op property value))))
|
||||||
|
|
||||||
(defn change-parent-property
|
(defn change-property
|
||||||
[modifiers property value]
|
[modifiers property value]
|
||||||
(-> (or modifiers (empty))
|
(-> (or modifiers (empty))
|
||||||
(update :structure-parent conj (change-property-op property value))))
|
(update :structure-parent conj (change-property-op property value))))
|
||||||
|
|
|
@ -148,17 +148,17 @@
|
||||||
[base idx-a idx-b]))
|
[base idx-a idx-b]))
|
||||||
|
|
||||||
(defn is-shape-over-shape?
|
(defn is-shape-over-shape?
|
||||||
[objects base-shape-id over-shape-id]
|
[objects base-shape-id over-shape-id bottom-frames?]
|
||||||
|
|
||||||
(let [[base index-a index-b] (get-base objects base-shape-id over-shape-id)]
|
(let [[base index-a index-b] (get-base objects base-shape-id over-shape-id)]
|
||||||
(cond
|
(cond
|
||||||
;; The base the base shape, so the other item is bellow
|
;; The base the base shape, so the other item is bellow (if not bottom-frames)
|
||||||
(= base base-shape-id)
|
(= base base-shape-id)
|
||||||
false
|
(and bottom-frames? (cph/frame-shape? objects base))
|
||||||
|
|
||||||
;; The base is the testing over, so it's over
|
;; The base is the testing over, so it's over (if not bottom-frames)
|
||||||
(= base over-shape-id)
|
(= base over-shape-id)
|
||||||
true
|
(or (not bottom-frames?) (not (cph/frame-shape? objects base)))
|
||||||
|
|
||||||
;; Check which index is lower
|
;; Check which index is lower
|
||||||
:else
|
:else
|
||||||
|
@ -177,29 +177,19 @@
|
||||||
([objects ids]
|
([objects ids]
|
||||||
(sort-z-index objects ids nil))
|
(sort-z-index objects ids nil))
|
||||||
|
|
||||||
([objects ids {:keys [bottom-frames?] :as options}]
|
([objects ids {:keys [bottom-frames?] :as options
|
||||||
(letfn [(comp [id-a id-b]
|
:or {bottom-frames? false}}]
|
||||||
(let [frame-a? (= :frame (dm/get-in objects [id-a :type]))
|
(letfn [
|
||||||
frame-b? (= :frame (dm/get-in objects [id-b :type]))]
|
(comp [id-a id-b]
|
||||||
(cond
|
(cond
|
||||||
(= id-a id-b)
|
(= id-a id-b)
|
||||||
0
|
0
|
||||||
|
|
||||||
(and (not frame-a?) frame-b?)
|
(is-shape-over-shape? objects id-a id-b bottom-frames?)
|
||||||
(if bottom-frames? -1 1)
|
1
|
||||||
|
|
||||||
(and frame-a? (not frame-b?))
|
:else
|
||||||
(if bottom-frames? 1 -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)
|
|
||||||
-1
|
|
||||||
|
|
||||||
:else
|
|
||||||
1)))]
|
|
||||||
(sort comp ids))))
|
(sort comp ids))))
|
||||||
|
|
||||||
(defn frame-id-by-position
|
(defn frame-id-by-position
|
||||||
|
|
|
@ -432,6 +432,7 @@ span.element-name {
|
||||||
background-color: $color-white;
|
background-color: $color-white;
|
||||||
color: $color-gray-50;
|
color: $color-gray-50;
|
||||||
border-radius: $br4;
|
border-radius: $br4;
|
||||||
|
z-index: 1;
|
||||||
span {
|
span {
|
||||||
padding: 10px 20px 10px 10px;
|
padding: 10px 20px 10px 10px;
|
||||||
border-radius: $br4;
|
border-radius: $br4;
|
||||||
|
|
|
@ -1008,6 +1008,13 @@
|
||||||
;; Navigation
|
;; Navigation
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defn workspace-focus-lost
|
||||||
|
[]
|
||||||
|
(ptk/reify ::workspace-focus-lost
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(assoc-in state [:workspace-global :show-distances?] false))))
|
||||||
|
|
||||||
(defn navigate-to-project
|
(defn navigate-to-project
|
||||||
[project-id]
|
[project-id]
|
||||||
(ptk/reify ::navigate-to-project
|
(ptk/reify ::navigate-to-project
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
[app.main.data.workspace.libraries :as dwl]
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
[app.main.data.workspace.persistence :as dwp]
|
[app.main.data.workspace.persistence :as dwp]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
|
[app.util.globals :refer [global]]
|
||||||
|
[app.util.object :as obj]
|
||||||
[app.util.time :as dt]
|
[app.util.time :as dt]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[cljs.spec.alpha :as s]
|
[cljs.spec.alpha :as s]
|
||||||
|
@ -37,7 +39,8 @@
|
||||||
profile-id (:profile-id state)
|
profile-id (:profile-id state)
|
||||||
|
|
||||||
initmsg [{:type :subscribe-file
|
initmsg [{:type :subscribe-file
|
||||||
:file-id file-id}
|
:file-id file-id
|
||||||
|
:version (obj/get global "penpotVersion")}
|
||||||
{:type :subscribe-team
|
{:type :subscribe-team
|
||||||
:team-id team-id}]
|
:team-id team-id}]
|
||||||
|
|
||||||
|
@ -130,7 +133,7 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
(defn handle-presence
|
(defn handle-presence
|
||||||
[{:keys [type session-id profile-id] :as message}]
|
[{:keys [type session-id profile-id version] :as message}]
|
||||||
(letfn [(get-next-color [presence]
|
(letfn [(get-next-color [presence]
|
||||||
(let [xfm (comp (map second)
|
(let [xfm (comp (map second)
|
||||||
(map :color)
|
(map :color)
|
||||||
|
@ -149,6 +152,7 @@
|
||||||
(assoc :id session-id)
|
(assoc :id session-id)
|
||||||
(assoc :profile-id profile-id)
|
(assoc :profile-id profile-id)
|
||||||
(assoc :updated-at (dt/now))
|
(assoc :updated-at (dt/now))
|
||||||
|
(assoc :version version)
|
||||||
(update :color update-color presence)
|
(update :color update-color presence)
|
||||||
(assoc :text-color (if (contains? ["#00fa9a" "#ffd700" "#dda0dd" "#ffafda"]
|
(assoc :text-color (if (contains? ["#00fa9a" "#ffd700" "#dda0dd" "#ffafda"]
|
||||||
(update-color (:color presence) presence))
|
(update-color (:color presence) presence))
|
||||||
|
@ -197,8 +201,9 @@
|
||||||
(-deref [_] {:changes changes})
|
(-deref [_] {:changes changes})
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ state _]
|
||||||
(let [position-data-operation?
|
(let [page-id (:current-page-id state)
|
||||||
|
position-data-operation?
|
||||||
(fn [{:keys [type attr]}]
|
(fn [{:keys [type attr]}]
|
||||||
(and (= :set type) (= attr :position-data)))
|
(and (= :set type) (= attr :position-data)))
|
||||||
|
|
||||||
|
@ -213,7 +218,8 @@
|
||||||
;; Remove the position data from remote operations. Will be changed localy, otherwise
|
;; Remove the position data from remote operations. Will be changed localy, otherwise
|
||||||
;; creates a strange "out-of-sync" behaviour.
|
;; creates a strange "out-of-sync" behaviour.
|
||||||
(cond-> change
|
(cond-> change
|
||||||
(= :mod-obj (:type change))
|
(and (= page-id (:page-id change))
|
||||||
|
(= :mod-obj (:type change)))
|
||||||
(update :operations #(d/removev position-data-operation? %))))
|
(update :operations #(d/removev position-data-operation? %))))
|
||||||
|
|
||||||
process-page-changes
|
process-page-changes
|
||||||
|
@ -223,7 +229,10 @@
|
||||||
;; We update `position-data` from the incoming message
|
;; We update `position-data` from the incoming message
|
||||||
changes (->> changes
|
changes (->> changes
|
||||||
(mapv update-position-data)
|
(mapv update-position-data)
|
||||||
(d/removev :ignore-remote?))
|
(d/removev (fn [change]
|
||||||
|
(and (= page-id (:page-id change))
|
||||||
|
(:ignore-remote? change)))))
|
||||||
|
|
||||||
changes-by-pages (group-by :page-id changes)]
|
changes-by-pages (group-by :page-id changes)]
|
||||||
|
|
||||||
(rx/merge
|
(rx/merge
|
||||||
|
|
|
@ -184,10 +184,10 @@
|
||||||
(ctm/resize scalev resize-origin shape-transform shape-transform-inverse)
|
(ctm/resize scalev resize-origin shape-transform shape-transform-inverse)
|
||||||
|
|
||||||
(cond-> set-fix-width?
|
(cond-> set-fix-width?
|
||||||
(ctm/change-parent-property :layout-item-h-sizing :fix))
|
(ctm/change-property :layout-item-h-sizing :fix))
|
||||||
|
|
||||||
(cond-> set-fix-height?
|
(cond-> set-fix-height?
|
||||||
(ctm/change-parent-property :layout-item-v-sizing :fix))
|
(ctm/change-property :layout-item-v-sizing :fix))
|
||||||
|
|
||||||
(cond-> scale-text
|
(cond-> scale-text
|
||||||
(ctm/scale-content (:x scalev))))
|
(ctm/scale-content (:x scalev))))
|
||||||
|
@ -739,6 +739,13 @@
|
||||||
#{}
|
#{}
|
||||||
(into (d/ordered-set) (find-all-empty-parents #{})))
|
(into (d/ordered-set) (find-all-empty-parents #{})))
|
||||||
|
|
||||||
|
;; Not move absolute shapes that won't change parent
|
||||||
|
moving-shapes
|
||||||
|
(->> moving-shapes
|
||||||
|
(remove (fn [shape]
|
||||||
|
(and (ctl/layout-absolute? shape)
|
||||||
|
(= frame-id (:parent-id shape))))))
|
||||||
|
|
||||||
changes
|
changes
|
||||||
(-> (pcb/empty-changes it page-id)
|
(-> (pcb/empty-changes it page-id)
|
||||||
(pcb/with-objects objects)
|
(pcb/with-objects objects)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
(ns app.main.ui.workspace
|
(ns app.main.ui.workspace
|
||||||
|
(:import goog.events.EventType)
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.main.data.messages :as msg]
|
[app.main.data.messages :as msg]
|
||||||
|
@ -31,9 +32,11 @@
|
||||||
[app.main.ui.workspace.textpalette :refer [textpalette]]
|
[app.main.ui.workspace.textpalette :refer [textpalette]]
|
||||||
[app.main.ui.workspace.viewport :refer [viewport]]
|
[app.main.ui.workspace.viewport :refer [viewport]]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
|
[app.util.globals :as globals]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[debug :refer [debug?]]
|
[debug :refer [debug?]]
|
||||||
|
[goog.events :as events]
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
@ -135,7 +138,19 @@
|
||||||
|
|
||||||
components-v2 (features/use-feature :components-v2)
|
components-v2 (features/use-feature :components-v2)
|
||||||
|
|
||||||
background-color (:background-color wglobal)]
|
background-color (:background-color wglobal)
|
||||||
|
|
||||||
|
focus-out
|
||||||
|
(mf/use-callback
|
||||||
|
(fn []
|
||||||
|
(st/emit! (dw/workspace-focus-lost))))]
|
||||||
|
|
||||||
|
(mf/use-effect
|
||||||
|
(mf/deps focus-out)
|
||||||
|
(fn []
|
||||||
|
(let [keys [(events/listen globals/document EventType.FOCUSOUT focus-out)]]
|
||||||
|
#(doseq [key keys]
|
||||||
|
(events/unlistenByKey key)))))
|
||||||
|
|
||||||
;; Setting the layout preset by its name
|
;; Setting the layout preset by its name
|
||||||
(mf/with-effect [layout-name]
|
(mf/with-effect [layout-name]
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.math :as mth]
|
||||||
[app.main.ui.cursors :as cur]
|
[app.main.ui.cursors :as cur]
|
||||||
[app.main.ui.formats :refer [format-number]]))
|
[app.main.ui.formats :refer [format-number]]))
|
||||||
|
|
||||||
|
@ -42,7 +42,58 @@
|
||||||
(let [inv-zoom (/ 1 zoom)]
|
(let [inv-zoom (/ 1 zoom)]
|
||||||
(dm/fmt "scale(%, %) translate(%, %)" inv-zoom inv-zoom (* zoom x) (* zoom y))))
|
(dm/fmt "scale(%, %) translate(%, %)" inv-zoom inv-zoom (* zoom x) (* zoom y))))
|
||||||
|
|
||||||
(defn title-transform [{:keys [selrect] :as shape} zoom]
|
(defn left?
|
||||||
(let [transform (gsh/transform-str shape {:no-flip true})
|
[cur cand]
|
||||||
label-pos (gpt/point (:x selrect) (- (:y selrect) (/ 10 zoom)))]
|
(let [closex? (mth/close? (:x cand) (:x cur))]
|
||||||
(dm/str transform " " (text-transform label-pos zoom))))
|
(cond
|
||||||
|
(and closex? (< (:y cand) (:y cur))) cand
|
||||||
|
closex? cur
|
||||||
|
(< (:x cand) (:x cur)) cand
|
||||||
|
:else cur)))
|
||||||
|
|
||||||
|
(defn top?
|
||||||
|
[cur cand]
|
||||||
|
(let [closey? (mth/close? (:y cand) (:y cur))]
|
||||||
|
(cond
|
||||||
|
(and closey? (< (:x cand) (:x cur))) cand
|
||||||
|
closey? cur
|
||||||
|
(< (:y cand) (:y cur)) cand
|
||||||
|
:else cur)))
|
||||||
|
|
||||||
|
(defn right?
|
||||||
|
[cur cand]
|
||||||
|
(let [closex? (mth/close? (:x cand) (:x cur))]
|
||||||
|
(cond
|
||||||
|
(and closex? (< (:y cand) (:y cur))) cand
|
||||||
|
closex? cur
|
||||||
|
(> (:x cand) (:x cur)) cand
|
||||||
|
:else cur)))
|
||||||
|
|
||||||
|
(defn title-transform [{:keys [points] :as shape} zoom]
|
||||||
|
(let [leftmost (->> points (reduce left?))
|
||||||
|
topmost (->> points (remove #{leftmost}) (reduce top?))
|
||||||
|
rightmost (->> points (remove #{leftmost topmost}) (reduce right?))
|
||||||
|
|
||||||
|
left-top (gpt/to-vec leftmost topmost)
|
||||||
|
left-top-angle (gpt/angle left-top)
|
||||||
|
|
||||||
|
top-right (gpt/to-vec topmost rightmost)
|
||||||
|
top-right-angle (gpt/angle top-right)
|
||||||
|
|
||||||
|
;; Choose the position that creates the less angle between left-side and top-side
|
||||||
|
[label-pos angle v-pos]
|
||||||
|
(if (< (mth/abs left-top-angle) (mth/abs top-right-angle))
|
||||||
|
[leftmost left-top-angle (gpt/perpendicular left-top)]
|
||||||
|
[topmost top-right-angle (gpt/perpendicular top-right)])
|
||||||
|
|
||||||
|
|
||||||
|
label-pos
|
||||||
|
(gpt/subtract label-pos (gpt/scale (gpt/unit v-pos) (/ 10 zoom)))]
|
||||||
|
|
||||||
|
(dm/fmt "rotate(% %,%) scale(%, %) translate(%, %)"
|
||||||
|
;; rotate
|
||||||
|
angle (:x label-pos) (:y label-pos)
|
||||||
|
;; scale
|
||||||
|
(/ 1 zoom) (/ 1 zoom)
|
||||||
|
;; translate
|
||||||
|
(* zoom (:x label-pos)) (* zoom (:y label-pos)))))
|
||||||
|
|
Loading…
Add table
Reference in a new issue