diff --git a/src/uxbox/data/workspace.cljs b/src/uxbox/data/workspace.cljs index 637f1c2407..ef29a4ba24 100644 --- a/src/uxbox/data/workspace.cljs +++ b/src/uxbox/data/workspace.cljs @@ -191,21 +191,22 @@ sh/-rotate rotation)))) (defn update-shape-size - [sid {:keys [width height lock] :as opts}] + "A helper event just for update the position + of the shape using the width and heigt attrs + instread final point of coordinates. + + WARN: only works with shapes that works + with height and width such are" + [sid {:keys [width height] :as opts}] (sc/validate! +shape-update-size-schema+ opts) (reify rs/UpdateEvent (-apply-update [_ state] - (let [shape (get-in state [:shapes-by-id sid]) - size (select-keys shape [:width :height]) - size (merge size - (when width {:width width}) - (when height {:height height}))] - (update-in state [:shapes-by-id sid] - shapes/-resize size))))) + (let [size [width height]] + (update-in state [:shapes-by-id sid] sh/-resize' size))))) (defn update-shape-position - [sid {:keys [x y] :as opts}] + [sid {:keys [x1 y1 x2 y2] :as opts}] (sc/validate! +shape-update-position-schema+ opts) (reify rs/UpdateEvent diff --git a/src/uxbox/shapes.cljs b/src/uxbox/shapes.cljs index fa75ca3dc1..0a8815a79c 100644 --- a/src/uxbox/shapes.cljs +++ b/src/uxbox/shapes.cljs @@ -45,6 +45,10 @@ dispatch-by-type :hierarchy #'+hierarchy+) +(defmulti -resize' + dispatch-by-type + :hierarchy #'+hierarchy+) + (defmulti -rotate dispatch-by-type :hierarchy #'+hierarchy+) @@ -70,20 +74,56 @@ ;; Implementation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Initialize + (defmethod -initialize ::shape - [shape props] - (merge shape props)) + [shape {:keys [x1 y1 x2 y2]}] + (merge shape + (when x1 {:x x1}) + (when y1 {:y y1}) + (when (and x2 x1) {:width (- x2 x1)}) + (when (and y2 y1) {:height (- y2 y1)}))) (defmethod -initialize :builtin/group - [shape {:keys [x y width height]}] + [shape {:keys [x1 y1 x2 y2]}] shape) -;; (defmethod -initialize :builtin/line -;; [shape {:keys [x y width height]}] -;; (merge shape -;; {:x1 x :y1 y -;; :x2 (+ x width) -;; :y2 (+ y height)})) +(defmethod -initialize :builtin/line + [shape {:keys [x1 y1 x2 y2]}] + (merge shape + (when x1 {:x1 x1}) + (when y1 {:y1 y1}) + (when x2 {:x2 x2}) + (when y2 {:y2 y2}))) + +;; Resize + +(defmethod -resize :builtin/line + [shape [x2 y2]] + (assoc shape + :x2 x2 :y2 y2)) + +(defmethod -resize :default + [shape _] + (throw (ex-info "Not implemented" (select-keys shape [:type])))) + +(defmethod -resize' :builtin/icon + [shape [width height]] + (merge shape + (when width {:width width}) + (when height {:height height}))) + +(defmethod -resize' :builtin/group + [shape [width height]] + (merge shape + (when width {:width width}) + (when height {:height height}))) + +(defmethod -resize' :default + [shape _] + (throw (ex-info "Not implemented" (select-keys shape [:type])))) + +;; Move (defmethod -move ::shape [shape {:keys [dx dy] :as opts}] @@ -97,23 +137,13 @@ :dx (+ (:dx shape 0) dx) :dy (+ (:dy shape 0) dy))) -;; (defmethod -move :builtin/line -;; [shape {:keys [dx dy] :as opts}] -;; (assoc shape -;; :x1 (+ (:x1 shape) dx) -;; :y1 (+ (:y1 shape) dy) -;; :x2 (+ (:x2 shape) dx) -;; :y2 (+ (:y2 shape) dy))) - -(defmethod -resize ::shape - [shape {:keys [width height] :as opts}] +(defmethod -move :builtin/line + [shape {:keys [dx dy] :as opts}] (assoc shape - :width width - :height height)) - -(defmethod -resize :builtin/line - [shape {:keys [width height] :as opts}] - (throw (ex-info "Not implemented" {}))) + :x1 (+ (:x1 shape) dx) + :y1 (+ (:y1 shape) dy) + :x2 (+ (:x2 shape) dx) + :y2 (+ (:y2 shape) dy))) (defmethod -rotate ::shape [shape rotation] @@ -129,8 +159,15 @@ (assoc $ :y (+ (:y shape) (:dy group 0))) (container-rect $)))) +(defmethod -outer-rect :builtin/line + [shape] + (let [{:keys [x1 y1 x2 y2]} shape + props {:x x1 :y y1 :width (- x2 x1) :height (- y2 y1)} + shape (merge shape props)] + (container-rect shape))) + (defmethod -outer-rect :builtin/group - [{:keys [id group rotation dx dy view-box] :as shape}] + [{:keys [id group rotation dx dy] :as shape}] (let [shapes (->> (:items shape) (map #(get-in @st/state [:shapes-by-id %])) (map -outer-rect)) diff --git a/src/uxbox/ui/shapes.cljs b/src/uxbox/ui/shapes.cljs index a61c7413ad..885313aa2a 100644 --- a/src/uxbox/ui/shapes.cljs +++ b/src/uxbox/ui/shapes.cljs @@ -42,6 +42,12 @@ (html [:g attrs data]))) +(defmethod sh/-render :builtin/line + [{:keys [id x1 y1 x2 y2]}] + (html + [:line {:x1 x1 :y1 y1 :x2 x2 :y2 y2 + :stroke "black" + :stroke-width "1"}])) ;; FIXME: the impl should be more clear. diff --git a/src/uxbox/ui/workspace/options.cljs b/src/uxbox/ui/workspace/options.cljs index f06fa1e925..cb39f85c78 100644 --- a/src/uxbox/ui/workspace/options.cljs +++ b/src/uxbox/ui/workspace/options.cljs @@ -14,11 +14,9 @@ [uxbox.util.data :refer (parse-int parse-float)])) (def +menus-map+ - {:builtin/icon [:menu/measures :menu/fill :menu/stroke] - :builtin/rect [:menu/measures :menu/fill :menu/stroke] - :builtin/circle [:menu/measures :menu/fill :menu/stroke] + {:builtin/icon [:menu/icon-measures :menu/fill :menu/stroke] :builtin/line [:menu/stroke] - :builtin/group [:menu/measures]}) + :builtin/group []}) (def +menus-by-id+ {:menu/measures @@ -44,8 +42,8 @@ [new-x new-y])) (defn- get-position - [{:keys [page width] :as shape}] - (let [{:keys [x y]} (sh/-outer-rect shape) + [{:keys [page] :as shape}] + (let [{:keys [x y width]} (sh/-outer-rect shape) vx (+ x width 50) vy (- y 50)] (viewportcoord->clientcoord page vx vy))) @@ -162,26 +160,25 @@ :step "0.0001" :on-change on-opacity-change}]]]]))) -(defmethod -render-menu :menu/measures +(defmethod -render-menu :menu/icon-measures [menu own shape] (letfn [(on-size-change [attr event] (let [value (dom/event->value event) value (parse-int value 0) - sid (:id shape)] - (-> (dw/update-shape-size sid {attr value}) - (rs/emit!)))) + sid (:id shape) + props {attr value}] + (rs/emit! (dw/update-shape-size sid props)))) (on-rotation-change [event] (let [value (dom/event->value event) value (parse-int value 0) sid (:id shape)] - (-> (dw/update-shape-rotation sid value) - (rs/emit!)))) + (rs/emit! (dw/update-shape-rotation sid value)))) (on-pos-change [attr event] (let [value (dom/event->value event) value (parse-int value nil) - sid (:id shape)] - (-> (dw/update-shape-position sid {attr value}) - (rs/emit!))))] + sid (:id shape) + props {attr value}] + (rs/emit! (dw/update-shape-position sid props))))] (html [:div.element-set {:key (str (:id menu))} [:div.element-set-title (:name menu)] @@ -209,12 +206,12 @@ {:placeholder "x" :type "number" :value (:x shape "") - :on-change (partial on-pos-change :x)}] + :on-change (partial on-pos-change :x1)}] [:input#width.input-text {:placeholder "y" :type "number" :value (:y shape "") - :on-change (partial on-pos-change :y)}]] + :on-change (partial on-pos-change :y1)}]] [:span "Rotation"] [:div.row-flex @@ -234,19 +231,20 @@ zoom 1 menus (get +menus-map+ (:type shape)) active-menu (:menu @local (first menus))] - (html - [:div#element-options.element-options - {:style {:left (* popup-x zoom) :top (- (* popup-y zoom) scroll)}} - [:ul.element-icons - (for [menu-id (get +menus-map+ (:type shape)) - :let [menu (get +menus-by-id+ menu-id) - selected? (= active-menu menu-id)]] - [:li#e-info {:on-click #(swap! local assoc :menu menu-id) - :key (str "menu-" (:id menu)) - :class (when selected? "selected")} - (:icon menu)])] - (let [menu (get +menus-by-id+ active-menu)] - (-render-menu menu own shape))]))) + (when (seq menus) + (html + [:div#element-options.element-options + {:style {:left (* popup-x zoom) :top (- (* popup-y zoom) scroll)}} + [:ul.element-icons + (for [menu-id (get +menus-map+ (:type shape)) + :let [menu (get +menus-by-id+ menu-id) + selected? (= active-menu menu-id)]] + [:li#e-info {:on-click #(swap! local assoc :menu menu-id) + :key (str "menu-" (:id menu)) + :class (when selected? "selected")} + (:icon menu)])] + (let [menu (get +menus-by-id+ active-menu)] + (-render-menu menu own shape))])))) (def ^:static element-opts (mx/component diff --git a/src/uxbox/ui/workspace/toolboxes/layers.cljs b/src/uxbox/ui/workspace/toolboxes/layers.cljs index 867af754f2..0154e4c062 100644 --- a/src/uxbox/ui/workspace/toolboxes/layers.cljs +++ b/src/uxbox/ui/workspace/toolboxes/layers.cljs @@ -74,6 +74,7 @@ [item] (case (:type item) :builtin/icon (shapes/-render-svg item) + :builtin/line i/line :builtin/rect i/box :builtin/group i/folder))