diff --git a/src/uxbox/data/workspace.cljs b/src/uxbox/data/workspace.cljs index ee9b8266b..3a82393f9 100644 --- a/src/uxbox/data/workspace.cljs +++ b/src/uxbox/data/workspace.cljs @@ -229,6 +229,17 @@ (-apply-update [_ state] (update-in state [:shapes-by-id sid] sh/-move' [x y])))) +(defn update-line + [sid props] + (reify + rs/UpdateEvent + (-apply-update [_ state] + (let [shape (get-in state [:shapes-by-id sid]) + props (select-keys props [:x1 :y1 :x2 :y2]) + props' (select-keys shape [:x1 :y1 :x2 :y2])] + (update-in state [:shapes-by-id sid] sh/-initialize + (merge props' props)))))) + ;; TODO: rename fill to "color" for consistency. (defn update-shape-fill diff --git a/src/uxbox/ui/workspace/options.cljs b/src/uxbox/ui/workspace/options.cljs index 3e5684f8d..a4749aae0 100644 --- a/src/uxbox/ui/workspace/options.cljs +++ b/src/uxbox/ui/workspace/options.cljs @@ -13,27 +13,41 @@ [uxbox.ui.workspace.base :as wb] [uxbox.util.data :refer (parse-int parse-float read-string)])) -(def +menus-map+ - {:builtin/icon [:menu/icon-measures :menu/fill :menu/stroke] - :builtin/line [:menu/stroke] - :builtin/rect [:menu/icon-measures :menu/stroke :menu/fill] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Constants +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(def ^:static ^:private +menus-map+ + {:builtin/icon [:menu/rect-measures :menu/fill :menu/stroke] + :builtin/rect [:menu/rect-measures :menu/fill :menu/stroke] + :builtin/line [:menu/line-measures :menu/stroke] + :builtin/circle [:menu/circle-measures :menu/fill :menu/stroke] :builtin/group []}) -(def +menus-by-id+ - {:menu/icon-measures - {:name "Size & position" - :icon i/infocard - :id :menu/icon-measures} +(def ^:static ^:private +menus-by-id+ + {:menu/rect-measures + {:name "Size, position & rotation" + :icon i/infocard} + + :menu/line-measures + {:name "Size, position & rotation" + :icon i/infocard} + + :menu/circle-measures + {:name "Size, position & rotation" + :icon i/infocard} :menu/fill {:name "Fill" - :icon i/fill - :id :menu/fill} + :icon i/fill} :menu/stroke {:name "Stroke" - :icon i/stroke - :id :menu/stroke}}) + :icon i/stroke}}) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Helpers +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defn- viewportcoord->clientcoord [pageid viewport-x viewport-y] @@ -49,6 +63,10 @@ vy (- y 50)] (viewportcoord->clientcoord page vx vy))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Implementation +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (defmulti -render-menu (fn [menu own shape] (:id menu))) @@ -102,11 +120,6 @@ :on-change on-color-change}]] (recent-colors shape #(change-stroke {:color %})) - [:span "Border radius"] - [:div.row-flex - [:input.input-text {:type "text" :placeholder "rx"}] - [:span.lock-size i/lock] - [:input.input-text {:type "text" :placeholder "ry"}]] ;; SLIDEBAR FOR ROTATION AND OPACITY [:span "Opacity"] @@ -161,7 +174,7 @@ :step "0.0001" :on-change on-opacity-change}]]]]))) -(defmethod -render-menu :menu/icon-measures +(defmethod -render-menu :menu/rect-measures [menu own shape] (letfn [(on-size-change [attr event] (let [value (dom/event->value event) @@ -179,7 +192,8 @@ value (parse-int value nil) sid (:id shape) props {attr value}] - (rs/emit! (dw/update-shape-position sid props))))] + (rs/emit! (dw/update-shape-position sid props)))) + (on-border-change [attr event])] (html [:div.element-set {:key (str (:id menu))} [:div.element-set-title (:name menu)] @@ -214,6 +228,19 @@ :value (:y shape "") :on-change (partial on-pos-change :y)}]] + [:span "Border radius"] + [:div.row-flex + [:input#width.input-text + {:placeholder "rx" + :type "number" + :value (:rx shape "") + :on-change (partial on-border-change :rx)}] + [:input#width.input-text + {:placeholder "ry" + :type "number" + :value (:ry shape "") + :on-change (partial on-border-change :ry)}]] + [:span "Rotation"] [:div.row-flex [:input.slidebar @@ -221,7 +248,164 @@ :min 0 :max 360 :value (:rotation shape 0) - :on-change on-rotation-change}]]]]))) + :on-change on-rotation-change}]] + + [:div.row-flex + [:input#width.input-text + {:placeholder "" + :type "number" + :min 0 + :max 360 + :value (:rotation shape "0") + :on-change on-rotation-change + }] + [:input.input-text + {:style {:visibility "hidden"}}] + ]]] + ))) + +(defmethod -render-menu :menu/circle-measures + [menu own shape] + (letfn [(on-size-change [attr event] + (let [value (dom/event->value event) + value (parse-int value 0) + 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)] + #_(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) + 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)] + [:div.element-set-content + ;; SLIDEBAR FOR ROTATION AND OPACITY + [:span "Size"] + [:div.row-flex + [:input#width.input-text + {:placeholder "Width" + :type "number" + :min "0" + :value (:rx shape) + :on-change (partial on-size-change :rx)}] + [:div.lock-size i/lock] + [:input#width.input-text + {:placeholder "Height" + :type "number" + :min "0" + :value (:ry shape) + :on-change (partial on-size-change :ry)}]] + + [:span "Position"] + [:div.row-flex + [:input#width.input-text + {:placeholder "cx" + :type "number" + :value (:cx shape "") + :on-change (partial on-pos-change :cx)}] + [:input#width.input-text + {:placeholder "cy" + :type "number" + :value (:cy shape "") + :on-change (partial on-pos-change :cy)}]] + + [:span "Rotation"] + [:div.row-flex + [:input.slidebar + {:type "range" + :min 0 + :max 360 + :value (:rotation shape 0) + :on-change on-rotation-change}]] + + [:div.row-flex + [:input#width.input-text + {:placeholder "" + :type "number" + :min 0 + :max 360 + :value (:rotation shape "0") + :on-change on-rotation-change + }] + [:input.input-text + {:style {:visibility "hidden"}}] + ]]] + ))) + +(defmethod -render-menu :menu/line-measures + [menu own shape] + (letfn [(on-rotation-change [event] + (let [value (dom/event->value event) + value (parse-int value 0) + sid (:id shape)] + (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) + props {attr value}] + (rs/emit! (dw/update-line sid props))))] + (html + [:div.element-set {:key (str (:id menu))} + [:div.element-set-title (:name menu)] + [:div.element-set-content + [:span "Position"] + [:div.row-flex + [:input#width.input-text + {:placeholder "x1" + :type "number" + :value (:x1 shape "") + :on-change (partial on-pos-change :x1)}] + [:input#width.input-text + {:placeholder "y1" + :type "number" + :value (:y1 shape "") + :on-change (partial on-pos-change :y1)}]] + + [:div.row-flex + [:input#width.input-text + {:placeholder "x2" + :type "number" + :value (:x2 shape "") + :on-change (partial on-pos-change :x2)}] + [:input#width.input-text + {:placeholder "y2" + :type "number" + :value (:y2 shape "") + :on-change (partial on-pos-change :y2)}]] + + [:span "Rotation"] + [:div.row-flex + [:input.slidebar + {:type "range" + :min 0 + :max 360 + :value (:rotation shape 0) + :on-change on-rotation-change}]] + + [:div.row-flex + [:input#width.input-text + {:placeholder "" + :type "number" + :min 0 + :max 360 + :value (:rotation shape "0") + :on-change on-rotation-change + }] + [:input.input-text + {:style {:visibility "hidden"}}] + ]]] + ))) + + (defn element-opts-render [own shape] @@ -239,12 +423,14 @@ [:ul.element-icons (for [menu-id (get +menus-map+ (:type shape)) :let [menu (get +menus-by-id+ menu-id) + menu (assoc menu :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)] + (let [menu (get +menus-by-id+ active-menu) + menu (assoc menu :id active-menu)] (-render-menu menu own shape))])))) (def ^:static element-opts