diff --git a/frontend/resources/images/cursors/zoom-in.svg b/frontend/resources/images/cursors/zoom-in.svg
new file mode 100644
index 000000000..ecd153448
--- /dev/null
+++ b/frontend/resources/images/cursors/zoom-in.svg
@@ -0,0 +1 @@
+
diff --git a/frontend/resources/images/cursors/zoom-out.svg b/frontend/resources/images/cursors/zoom-out.svg
new file mode 100644
index 000000000..65a5a300f
--- /dev/null
+++ b/frontend/resources/images/cursors/zoom-out.svg
@@ -0,0 +1 @@
+
diff --git a/frontend/resources/images/cursors/zoom.svg b/frontend/resources/images/cursors/zoom.svg
new file mode 100644
index 000000000..9650153fe
--- /dev/null
+++ b/frontend/resources/images/cursors/zoom.svg
@@ -0,0 +1 @@
+
diff --git a/frontend/resources/styles/main/partials/debug-icons-preview.scss b/frontend/resources/styles/main/partials/debug-icons-preview.scss
index 8ddba1688..afca85123 100644
--- a/frontend/resources/styles/main/partials/debug-icons-preview.scss
+++ b/frontend/resources/styles/main/partials/debug-icons-preview.scss
@@ -2,7 +2,9 @@
display: flex;
flex-direction: column;
overflow: scroll;
+ height: 100%;
}
+
.debug-icons-preview {
display: flex;
flex-wrap: wrap;
diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs
index 46b554a22..264874a94 100644
--- a/frontend/src/app/main/data/workspace/selection.cljs
+++ b/frontend/src/app/main/data/workspace/selection.cljs
@@ -47,7 +47,7 @@
(assoc-in state [:workspace-local :selrect] selrect))))
(defn handle-area-selection
- [preserve?]
+ [preserve? ignore-groups?]
(letfn [(data->selrect [data]
(let [start (:start data)
stop (:stop data)
@@ -91,7 +91,7 @@
(rx/buffer-time 100)
(rx/map #(last %))
(rx/dedupe)
- (rx/map #(select-shapes-by-current-selrect preserve?))))
+ (rx/map #(select-shapes-by-current-selrect preserve? ignore-groups?))))
(rx/of (update-selrect nil))))))))
@@ -218,7 +218,7 @@
;; --- Select Shapes (By selrect)
(defn select-shapes-by-current-selrect
- [preserve?]
+ [preserve? ignore-groups?]
(ptk/reify ::select-shapes-by-current-selrect
ptk/WatchEvent
(watch [_ state _]
@@ -237,6 +237,7 @@
:page-id page-id
:rect selrect
:include-frames? true
+ :ignore-groups? ignore-groups?
:full-frame? true})
(rx/map #(cp/clean-loops objects %))
(rx/map #(into initial-set (filter (comp not blocked?)) %))
diff --git a/frontend/src/app/main/ui/cursors.cljs b/frontend/src/app/main/ui/cursors.cljs
index a57575099..2d571ed06 100644
--- a/frontend/src/app/main/ui/cursors.cljs
+++ b/frontend/src/app/main/ui/cursors.cljs
@@ -30,6 +30,9 @@
(def pointer-node (cursor-ref :pointer-node 0 0 10 32))
(def resize-alt (cursor-ref :resize-alt))
(def text (cursor-ref :text))
+(def zoom (cursor-ref :zoom))
+(def zoom-in (cursor-ref :zoom-in))
+(def zoom-out (cursor-ref :zoom-out))
;; Dynamic cursors
(def resize-ew (cursor-fn :resize-h 0))
diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs
index f88972c48..def9a0852 100644
--- a/frontend/src/app/main/ui/workspace/viewport.cljs
+++ b/frontend/src/app/main/ui/workspace/viewport.cljs
@@ -115,21 +115,21 @@
node-editing? (and edition (not= :text (get-in base-objects [edition :type])))
text-editing? (and edition (= :text (get-in base-objects [edition :type])))
- on-click (actions/on-click hover selected edition drawing-path? drawing-tool)
+ on-click (actions/on-click hover selected edition drawing-path? drawing-tool space?)
on-context-menu (actions/on-context-menu hover hover-ids)
on-double-click (actions/on-double-click hover hover-ids drawing-path? base-objects edition)
on-drag-enter (actions/on-drag-enter)
on-drag-over (actions/on-drag-over)
on-drop (actions/on-drop file viewport-ref zoom)
on-mouse-down (actions/on-mouse-down @hover selected edition drawing-tool text-editing? node-editing?
- drawing-path? create-comment? space? viewport-ref zoom)
+ drawing-path? create-comment? space? viewport-ref zoom panning)
on-mouse-up (actions/on-mouse-up disable-paste)
on-pointer-down (actions/on-pointer-down)
on-pointer-enter (actions/on-pointer-enter in-viewport?)
on-pointer-leave (actions/on-pointer-leave in-viewport?)
on-pointer-move (actions/on-pointer-move viewport-ref zoom move-stream)
on-pointer-up (actions/on-pointer-up)
- on-move-selected (actions/on-move-selected hover hover-ids selected)
+ on-move-selected (actions/on-move-selected hover hover-ids selected space?)
on-menu-selected (actions/on-menu-selected hover hover-ids selected)
on-frame-enter (actions/on-frame-enter frame-hover)
@@ -162,15 +162,13 @@
(hooks/setup-dom-events viewport-ref zoom disable-paste in-viewport?)
(hooks/setup-viewport-size viewport-ref)
- (hooks/setup-cursor cursor alt? panning drawing-tool drawing-path? node-editing?)
+ (hooks/setup-cursor cursor alt? ctrl? space? panning drawing-tool drawing-path? node-editing?)
(hooks/setup-keyboard alt? ctrl? space?)
(hooks/setup-hover-shapes page-id move-stream base-objects transform selected ctrl? hover hover-ids @hover-disabled? zoom)
(hooks/setup-viewport-modifiers modifiers base-objects)
(hooks/setup-shortcuts node-editing? drawing-path?)
(hooks/setup-active-frames base-objects vbox hover active-frames)
-
-
[:div.viewport
[:div.viewport-overlays
@@ -245,7 +243,7 @@
[:& outline/shape-outlines
{:objects base-objects
:selected selected
- :hover (when (not= :frame (:type @hover))
+ :hover (when (or @ctrl? (not= :frame (:type @hover)))
#{(or @frame-hover (:id @hover))})
:edition edition
:zoom zoom}])
@@ -262,7 +260,7 @@
:shapes selected-shapes
:zoom zoom
:edition edition
- :disable-handlers (or drawing-tool edition)
+ :disable-handlers (or drawing-tool edition @space?)
:on-move-selected on-move-selected
:on-context-menu on-menu-selected}])
diff --git a/frontend/src/app/main/ui/workspace/viewport/actions.cljs b/frontend/src/app/main/ui/workspace/viewport/actions.cljs
index 486288374..084f9ec8f 100644
--- a/frontend/src/app/main/ui/workspace/viewport/actions.cljs
+++ b/frontend/src/app/main/ui/workspace/viewport/actions.cljs
@@ -28,10 +28,11 @@
(defn on-mouse-down
[{:keys [id blocked hidden type]} selected edition drawing-tool text-editing?
- node-editing? drawing-path? create-comment? space? viewport-ref zoom]
+ node-editing? drawing-path? create-comment? space? viewport-ref zoom panning]
(mf/use-callback
(mf/deps id blocked hidden type selected edition drawing-tool text-editing?
- node-editing? drawing-path? create-comment? space? viewport-ref zoom)
+ node-editing? drawing-path? create-comment? @space? viewport-ref zoom
+ panning)
(fn [bevent]
(when (or (dom/class? (dom/get-target bevent) "viewport-controls")
(dom/class? (dom/get-target bevent) "viewport-selrect"))
@@ -42,62 +43,75 @@
shift? (kbd/shift? event)
alt? (kbd/alt? event)
- left-click? (= 1 (.-which event))
- middle-click? (= 2 (.-which event))
+ left-click? (and (not panning) (= 1 (.-which event)))
+ middle-click? (and (not panning) (= 2 (.-which event)))
frame? (= :frame type)
selected? (contains? selected id)]
- (when middle-click?
- (dom/prevent-default bevent)
- (if ctrl?
- (let [raw-pt (dom/get-client-position event)
- viewport (mf/ref-val viewport-ref)
- pt (utils/translate-point-to-viewport viewport zoom raw-pt)]
- (st/emit! (dw/start-zooming pt)))
- (st/emit! (dw/start-panning))))
+ (cond
+ middle-click?
+ (do
+ (dom/prevent-default bevent)
+ (if ctrl?
+ (let [raw-pt (dom/get-client-position event)
+ viewport (mf/ref-val viewport-ref)
+ pt (utils/translate-point-to-viewport viewport zoom raw-pt)]
+ (st/emit! (dw/start-zooming pt)))
+ (st/emit! (dw/start-panning))))
- (when left-click?
- (st/emit! (ms/->MouseEvent :down ctrl? shift? alt?))
- (when (and (not= edition id) text-editing?)
- (st/emit! dw/clear-edition-mode))
+ left-click?
+ (do
+ (st/emit! (ms/->MouseEvent :down ctrl? shift? alt?))
- (when (and (not text-editing?)
- (not blocked)
- (not hidden)
- (not create-comment?)
- (not drawing-path?))
- (cond
- drawing-tool
- (st/emit! (dd/start-drawing drawing-tool))
+ (when (and (not= edition id) text-editing?)
+ (st/emit! dw/clear-edition-mode))
- node-editing?
- ;; Handle path node area selection
- (st/emit! (dwdp/handle-area-selection shift?))
+ (when (and (not text-editing?)
+ (not blocked)
+ (not hidden)
+ (not create-comment?)
+ (not drawing-path?))
+ (cond
+ node-editing?
+ ;; Handle path node area selection
+ (st/emit! (dwdp/handle-area-selection shift?))
- @space?
- (st/emit! (dw/start-panning))
+ (and @space? ctrl?)
+ (let [raw-pt (dom/get-client-position event)
+ viewport (mf/ref-val viewport-ref)
+ pt (utils/translate-point-to-viewport viewport zoom raw-pt)]
+ (st/emit! (dw/start-zooming pt)))
- (or (not id) (and frame? (not selected?)))
- (st/emit! (dw/handle-area-selection shift?))
+ @space?
+ (st/emit! (dw/start-panning))
- (not drawing-tool)
- (st/emit! (when (or shift? (not selected?))
- (dw/select-shape id shift?))
- (dw/start-move-selected))))))))))
+ drawing-tool
+ (st/emit! (dd/start-drawing drawing-tool))
+
+ (or (not id) (and frame? (not selected?)) ctrl?)
+ (st/emit! (dw/handle-area-selection shift? ctrl?))
+
+ (not drawing-tool)
+ (st/emit! (when (or shift? (not selected?))
+ (dw/select-shape id shift?))
+ (dw/start-move-selected)))))))))))
(defn on-move-selected
- [hover hover-ids selected]
+ [hover hover-ids selected space?]
(mf/use-callback
- (mf/deps @hover @hover-ids selected)
+ (mf/deps @hover @hover-ids selected @space?)
(fn [bevent]
(let [event (.-nativeEvent bevent)
shift? (kbd/shift? event)
+ ctrl? (kbd/ctrl? event)
left-click? (= 1 (.-which event))]
(when (and left-click?
+ (not ctrl?)
(not shift?)
+ (not @space?)
(or (not @hover)
(= :frame (:type @hover))
(some #(contains? selected %) @hover-ids)))
@@ -130,9 +144,9 @@
(reset! frame-hover nil))))
(defn on-click
- [hover selected edition drawing-path? drawing-tool]
+ [hover selected edition drawing-path? drawing-tool space?]
(mf/use-callback
- (mf/deps @hover selected edition drawing-path? drawing-tool)
+ (mf/deps @hover selected edition drawing-path? drawing-tool @space?)
(fn [event]
(when (or (dom/class? (dom/get-target event) "viewport-controls")
(dom/class? (dom/get-target event) "viewport-selrect"))
@@ -147,7 +161,8 @@
(when (and hovering?
(not shift?)
- (not frame?)
+ (or ctrl? (not frame?))
+ (not @space?)
(not selected?)
(not edition)
(not drawing-path?)
@@ -229,17 +244,17 @@
middle-click? (= 2 (.-which event))]
(when left-click?
- (st/emit! (dw/finish-panning)
- (ms/->MouseEvent :up ctrl? shift? alt?)))
+ (st/emit! (ms/->MouseEvent :up ctrl? shift? alt?)))
(when middle-click?
(dom/prevent-default event)
;; We store this so in Firefox the middle button won't do a paste of the content
(reset! disable-paste true)
- (timers/schedule #(reset! disable-paste false))
- (st/emit! (dw/finish-panning)
- (dw/finish-zooming)))))))
+ (timers/schedule #(reset! disable-paste false)))
+
+ (st/emit! (dw/finish-panning)
+ (dw/finish-zooming))))))
(defn on-pointer-enter [in-viewport?]
(mf/use-callback
diff --git a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs
index 21ea3e700..49c1d9315 100644
--- a/frontend/src/app/main/ui/workspace/viewport/hooks.cljs
+++ b/frontend/src/app/main/ui/workspace/viewport/hooks.cljs
@@ -57,13 +57,14 @@
;; We schedule the event so it fires after `initialize-page` event
(timers/schedule #(st/emit! (dw/initialize-viewport size)))))))
-(defn setup-cursor [cursor alt? panning drawing-tool drawing-path? path-editing?]
+(defn setup-cursor [cursor alt? ctrl? space? panning drawing-tool drawing-path? path-editing?]
(mf/use-effect
- (mf/deps @cursor @alt? panning drawing-tool drawing-path? path-editing?)
+ (mf/deps @cursor @alt? @ctrl? @space? panning drawing-tool drawing-path? path-editing?)
(fn []
(let [new-cursor
(cond
- panning (utils/get-cursor :hand)
+ (and @ctrl? @space?) (utils/get-cursor :zoom)
+ (or panning @space?) (utils/get-cursor :hand)
(= drawing-tool :comments) (utils/get-cursor :comments)
(= drawing-tool :frame) (utils/get-cursor :create-artboard)
(= drawing-tool :rect) (utils/get-cursor :create-rectangle)
diff --git a/frontend/src/app/main/ui/workspace/viewport/utils.cljs b/frontend/src/app/main/ui/workspace/viewport/utils.cljs
index 9c0734afa..873061070 100644
--- a/frontend/src/app/main/ui/workspace/viewport/utils.cljs
+++ b/frontend/src/app/main/ui/workspace/viewport/utils.cljs
@@ -179,4 +179,7 @@
:pencil cur/pencil
:create-shape cur/create-shape
:duplicate cur/duplicate
+ :zoom cur/zoom
+ :zoom-in cur/zoom-in
+ :zooom-out cur/zoom-out
cur/pointer-inner))
diff --git a/frontend/src/app/worker/selection.cljs b/frontend/src/app/worker/selection.cljs
index d0b229034..ed0412f86 100644
--- a/frontend/src/app/worker/selection.cljs
+++ b/frontend/src/app/worker/selection.cljs
@@ -105,7 +105,7 @@
(assoc data :index index :z-index z-index)))
(defn- query-index
- [{index :index z-index :z-index} rect frame-id full-frame? include-frames? clip-children? reverse?]
+ [{index :index z-index :z-index} rect frame-id full-frame? include-frames? ignore-groups? clip-children? reverse?]
(let [result (-> (qdt/search index (clj->js rect))
(es6-iterator-seq))
@@ -117,6 +117,7 @@
(or (not frame-id) (= frame-id (:frame-id shape)))
(case (:type shape)
:frame include-frames?
+ (:bool :group) (not ignore-groups?)
true)
(or (not full-frame?)
@@ -189,10 +190,10 @@
nil)
(defmethod impl/handler :selection/query
- [{:keys [page-id rect frame-id reverse? full-frame? include-frames? clip-children?]
+ [{:keys [page-id rect frame-id reverse? full-frame? include-frames? ignore-groups? clip-children?]
:or {reverse? false full-frame? false include-frames? false clip-children? true} :as message}]
(when-let [index (get @state page-id)]
- (query-index index rect frame-id full-frame? include-frames? clip-children? reverse?)))
+ (query-index index rect frame-id full-frame? include-frames? ignore-groups? clip-children? reverse?)))
(defmethod impl/handler :selection/query-z-index
[{:keys [page-id objects ids]}]