diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e6db4e..e370c6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This change ## [Unreleased] +- Add proportional node support + user svg node - Move node collapsed to node :extra-data - Upgrade clindex to 0.3.2 diff --git a/README.md b/README.md index a09ad60..6c5eaef 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ You can index a project by runnning : clj -m clograms.server some-project-folder clj # you can also use cljs to index clojurescript projects ``` -## For developers +## Diagrams For diagrams use clograms with the diagram.edn in the repo or take a look at the [exported pdf](/docs/clograms.pdf) diff --git a/resources/public/css/main.css b/resources/public/css/main.css index c5d26bd..6f6b611 100644 --- a/resources/public/css/main.css +++ b/resources/public/css/main.css @@ -248,35 +248,20 @@ svg .svg-node .svg-port:hover { cursor: crosshair; } -svg .group-shape rect { - stroke: grey; - stroke-width: 4; - fill: transparent; -} - -svg .group-shape text { - stroke: none; - fill: #eee; -} - -svg .rectangle-shape { +svg g.custom-node { stroke: black; fill: #336699; } -svg .rectangle-shape text { +svg g.custom-node text { stroke: none; fill: #eee; } -svg .circle-shape { - stroke: black; - fill: #336699; -} - -svg .circle-shape text { - stroke: none; - fill: #eee; +svg g.custom-node.group-shape rect { + stroke: grey; + stroke-width: 4; + fill: transparent; } body { diff --git a/src/clj-styles/clograms/styles/main.clj b/src/clj-styles/clograms/styles/main.clj index e948dee..49e62c3 100644 --- a/src/clj-styles/clograms/styles/main.clj +++ b/src/clj-styles/clograms/styles/main.clj @@ -147,17 +147,14 @@ [:.svg-port {:z-index 100 :fill :transparent} [:&:hover {:cursor :crosshair}]]] - [:.group-shape - [:rect {:stroke :grey - :stroke-width 4 - :fill :transparent}] - [:text {:stroke :none :fill (color :main-font)}]] - [:.rectangle-shape {:stroke :black - :fill (color :shape)} - [:text {:stroke :none :fill (color :main-font)}]] - [:.circle-shape {:stroke :black - :fill (color :shape)} - [:text {:stroke :none :fill (color :main-font)}]]]) + [:g.custom-node + {:stroke :black + :fill (color :shape)} + [:text {:stroke :none :fill (color :main-font)}] + [:&.group-shape + [:rect {:stroke :grey + :stroke-width 4 + :fill :transparent}]]]]) (def general [:body {:background-color (str (color :background) " !important") diff --git a/src/clj/clograms/server.clj b/src/clj/clograms/server.clj index 0959690..291f1e6 100644 --- a/src/clj/clograms/server.clj +++ b/src/clj/clograms/server.clj @@ -41,6 +41,7 @@ (comment (-main "/home/jmonetta/my-projects/clindex" "clj") + (-main "/home/jmonetta/my-projects/clograms" "cljs") (-main "/home/jmonetta/my-projects/district0x/memefactory" "cljs") diff --git a/src/cljs/clograms/core.cljs b/src/cljs/clograms/core.cljs index 5d9ea53..e636480 100644 --- a/src/cljs/clograms/core.cljs +++ b/src/cljs/clograms/core.cljs @@ -34,19 +34,20 @@ (throw (js/Error. (str "Cannot compare " x " to " y)))))) (defn mount-root [] - (re/register-node-component! :clograms/project-node [:div nodes/project-node-component]) - (re/register-node-component! :clograms/namespace-node [:div nodes/namespace-node-component]) - (re/register-node-component! :clograms/function-node [:div nodes/function-node-component]) - (re/register-node-component! :clograms/var-node [:div nodes/var-node-component]) - (re/register-node-component! :clograms/multimethod-node [:div nodes/multimethod-node-component]) - (re/register-node-component! :clograms/re-frame-subs-node [:div nodes/re-frame-subs-node-component]) - (re/register-node-component! :clograms/re-frame-event-node [:div nodes/re-frame-event-node-component]) - (re/register-node-component! :clograms/re-frame-fx-node [:div nodes/re-frame-fx-node-component]) - (re/register-node-component! :clograms/re-frame-cofx-node [:div nodes/re-frame-cofx-node-component]) - (re/register-node-component! :clograms/spec-node [:div nodes/spec-node-component]) - (re/register-node-component! :clograms/rectangle-node [:svg nodes/rectangle-node-component]) - (re/register-node-component! :clograms/circle-node [:svg nodes/circle-node-component]) - (re/register-node-component! :clograms/group-node [:svg nodes/group-node-component]) + (re/register-node-component! :clograms/project-node {:type :div :comp nodes/project-node-component}) + (re/register-node-component! :clograms/namespace-node {:type :div :comp nodes/namespace-node-component}) + (re/register-node-component! :clograms/function-node {:type :div :comp nodes/function-node-component}) + (re/register-node-component! :clograms/var-node {:type :div :comp nodes/var-node-component}) + (re/register-node-component! :clograms/multimethod-node {:type :div :comp nodes/multimethod-node-component}) + (re/register-node-component! :clograms/re-frame-subs-node {:type :div :comp nodes/re-frame-subs-node-component}) + (re/register-node-component! :clograms/re-frame-event-node {:type :div :comp nodes/re-frame-event-node-component}) + (re/register-node-component! :clograms/re-frame-fx-node {:type :div :comp nodes/re-frame-fx-node-component}) + (re/register-node-component! :clograms/re-frame-cofx-node {:type :div :comp nodes/re-frame-cofx-node-component}) + (re/register-node-component! :clograms/spec-node {:type :div :comp nodes/spec-node-component}) + (re/register-node-component! :clograms/rectangle-node {:type :svg :comp nodes/rectangle-node-component}) + (re/register-node-component! :clograms/circle-node {:type :svg :comp nodes/circle-node-component :prop-resize? true}) + (re/register-node-component! :clograms/group-node {:type :svg :comp nodes/group-node-component}) + (re/register-node-component! :clograms/user-node {:type :svg :comp nodes/user-node-component :prop-resize? true}) (re/register-link-component! :clograms/line-link links/line-link-component) (re-frame/clear-subscription-cache!) (reagent/render [main-screen/main-panel] diff --git a/src/cljs/clograms/re_grams/re_grams.cljs b/src/cljs/clograms/re_grams/re_grams.cljs index 1197a44..f8ed527 100644 --- a/src/cljs/clograms/re_grams/re_grams.cljs +++ b/src/cljs/clograms/re_grams/re_grams.cljs @@ -128,7 +128,7 @@ (def svg-port-side 7) (defn port [node p] - (let [[node-graph-type] (get @node-components (:diagram.node/type node)) + (let [node-comp (get @node-components (:diagram.node/type node)) grab-sub (subscribe [::grab]) node-id (::id node) update-after-render (fn [p-cmp] @@ -151,7 +151,7 @@ :tmp-link-from [node-id (:id p)]} [(.-clientX evt) (.-clientY evt)]])) :on-mouse-up (fn [evt] (dispatch [::add-link (get-in @grab-sub [:grab-object :tmp-link-from]) [node-id (:id p)]]))} ] - (case node-graph-type + (case (:type node-comp) :div [:div.div-port props-map [:div.port-inner]] :svg [:rect.svg-port (merge props-map p {:width svg-port-side :height svg-port-side})]) @@ -215,14 +215,16 @@ [(.-clientX evt) (.-clientY evt)]])))) (defn build-svg-node-resizer-handler [n] - (fn [evt] - (.stopPropagation evt) - (when (= left-button (.-buttons evt)) - (dispatch [::grab {:diagram.object/type :node-resizer - ::id (::id n) - :start-pos [(:x n) (:y n)] - :start-size [(:w n) (:h n)]} - [(.-clientX evt) (.-clientY evt)]])))) + (let [{:keys [prop-resize?]} (get @node-components (:diagram.node/type n) default-node)] + (fn [evt] + (.stopPropagation evt) + (when (= left-button (.-buttons evt)) + (dispatch [::grab {:diagram.object/type :node-resizer + ::id (::id n) + :start-pos [(:x n) (:y n)] + :start-size [(:w n) (:h n)] + :prop-resize? prop-resize?} + [(.-clientX evt) (.-clientY evt)]]))))) (defn port-position [node port-id] (let [[nx ny nw nh] ((juxt :x :y :w :h) node) @@ -238,7 +240,7 @@ port-id))) (defn svg-node [n] - (let [[_ node-component] (get @node-components (:diagram.node/type n) default-node) + (let [node-comp (get @node-components (:diagram.node/type n) default-node) selected-node-id (subscribe [::selected-node-id])] [:g.svg-node.node {:class (when (= @selected-node-id (::id n)) "selected") :on-click (build-node-click-handler n) @@ -249,14 +251,14 @@ ^{:key (:id p)} [port n (merge p (port-position n (:id p)))]) - [node-component n] + [(:comp node-comp) n] [:circle.resizer {:cx (:w n) :cy (:h n) :r 20 :on-mouse-down (build-svg-node-resizer-handler n)}]])) (defn div-node [n] - (let [[_ node-component] (get @node-components (:diagram.node/type n) default-node) + (let [node-comp (get @node-components (:diagram.node/type n) default-node) selected-node-id (subscribe [::selected-node-id]) update-after-render (fn [n-cmp] (let [dn (r/dom-node n-cmp) @@ -280,7 +282,7 @@ ^{:key (:id p)} [port n p]) - [node-component n]])}))) + [(:comp node-comp) n]])}))) (defn drag [db current-cli-coord] (if-let [{:keys [cli-origin grab-object]} (get-in db [::diagram :grab])] @@ -304,8 +306,10 @@ drag-x (- current-dia-x start-dia-x) drag-y (- current-dia-y start-dia-y) [obj-start-width obj-start-height] (:start-size grab-object) - end-width (+ obj-start-width drag-x) - end-height (+ obj-start-height drag-y)] + [end-width end-height] (if (:prop-resize? grab-object) + (let [drag (max drag-x drag-y)] + [(+ obj-start-width drag) (+ obj-start-height drag)]) + [(+ obj-start-width drag-x) (+ obj-start-height drag-y)])] (-> db' (assoc-in [::diagram :nodes (::id grab-object) :w] end-width) (assoc-in [::diagram :nodes (::id grab-object) :h] end-height))) @@ -403,8 +407,8 @@ :reagent-render (fn [dia] (let [{:keys [nodes links link-config grab translate scale scale-origin]} dia [tx ty] translate - div-nodes (filter #(= (first (get @node-components (:diagram.node/type %))) :div) (vals nodes)) - svg-nodes (filter #(= (first (get @node-components (:diagram.node/type %))) :svg) (vals nodes))] + div-nodes (filter #(= (:type (get @node-components (:diagram.node/type %))) :div) (vals nodes)) + svg-nodes (filter #(= (:type (get @node-components (:diagram.node/type %))) :svg) (vals nodes))] [:div.diagram-layer {:style {:overflow :hidden} :on-mouse-down (fn [evt] (.stopPropagation evt) @@ -452,8 +456,8 @@ ^{:key (::id n)} [div-node n]))]]]))})) -(defn register-node-component! [node-type [node-graph-type component-fn]] - (swap! node-components assoc node-type [node-graph-type component-fn])) +(defn register-node-component! [node-type comp-desc] + (swap! node-components assoc node-type comp-desc)) (defn register-link-component! [link-type component-fn] (swap! link-components assoc link-type component-fn)) diff --git a/src/cljs/clograms/re_grams/re_grams_spec.cljs b/src/cljs/clograms/re_grams/re_grams_spec.cljs index 1668b49..554e4d3 100644 --- a/src/cljs/clograms/re_grams/re_grams_spec.cljs +++ b/src/cljs/clograms/re_grams/re_grams_spec.cljs @@ -66,12 +66,13 @@ (s/def ::cli-current ::coord) (s/def ::start-pos ::coord) (s/def ::start-size (s/tuple number? number?)) - +(s/def ::prop-resize? boolean?) (s/def ::grab-object (s/keys :req [:diagram.object/type] :opt [::rg/id] :req-un [::start-pos] :opt-un [::tmp-link-from - ::start-size])) + ::start-size + ::prop-resize?])) (s/def ::grab (s/nilable (s/keys :req-un [::cli-origin diff --git a/src/cljs/clograms/ui/components/nodes.cljs b/src/cljs/clograms/ui/components/nodes.cljs index a005e5d..0c4aebd 100644 --- a/src/cljs/clograms/ui/components/nodes.cljs +++ b/src/cljs/clograms/ui/components/nodes.cljs @@ -6,7 +6,8 @@ [clograms.ui.components.menues :as menues] [clograms.re-grams.re-grams :as rg] [clojure.string :as str] - [clograms.ui.components.general :as gral-components])) + [clograms.ui.components.general :as gral-components] + [goog.string :as gstring])) (defn node-wrapper [{:keys [ctx-menu node]} child] (let [node-color (re-frame/subscribe [::subs/node-color (:entity node)])] @@ -256,3 +257,24 @@ :rx 3}] [:text {:x 5 :y 20} (or (-> node :extra-data :label) "") ]]}]) + + +(defn user-node-component [node] + (let [draw-height 350 + draw-width 266 + scale (/ (:h node) draw-height)] + [shape-wrapper + {:ctx-menu (shape-menu node) + :child + [:g.user-shape.custom-node + [:g {:transform (gstring/format "translate(0,0) scale(%f)" scale)} + [:path {:d "M175,171.173c38.914,0,70.463-38.318,70.463-85.586C245.463,38.318,235.105,0,175,0s-70.465,38.318-70.465,85.587 C104.535,132.855,136.084,171.173,175,171.173z"}] + [:path {:d "M41.909,301.853C41.897,298.971,41.885,301.041,41.909,301.853L41.909,301.853z"}] + [:path {:d "M308.085,304.104C308.123,303.315,308.098,298.63,308.085,304.104L308.085,304.104z"}] + [:path {:d "M307.935,298.397c-1.305-82.342-12.059-105.805-94.352-120.657c0,0-11.584,14.761-38.584,14.761 + s-38.586-14.761-38.586-14.761c-81.395,14.69-92.803,37.805-94.303,117.982c-0.123,6.547-0.18,6.891-0.202,6.131 + c0.005,1.424,0.011,4.058,0.011,8.651c0,0,19.592,39.496,133.08,39.496c113.486,0,133.08-39.496,133.08-39.496 + c0-2.951,0.002-5.003,0.005-6.399C308.062,304.575,308.018,303.664,307.935,298.397z"}]] + [:text {:x (quot (:w node) 2) :y (:h node) + :text-anchor :middle} + (-> node :extra-data :label)]]}])) diff --git a/src/cljs/clograms/ui/components/toolbars.cljs b/src/cljs/clograms/ui/components/toolbars.cljs index 5c98546..80430c4 100644 --- a/src/cljs/clograms/ui/components/toolbars.cljs +++ b/src/cljs/clograms/ui/components/toolbars.cljs @@ -7,7 +7,8 @@ [re-com.core :as re-com] [clograms.db :as db] [clograms.re-grams.re-grams :as rg] - [clograms.ui.components.general :as gral-components])) + [clograms.ui.components.general :as gral-components] + [clograms.ui.components.nodes :as nodes])) (defn draggable-project [project] [:div.draggable-project.draggable-entity @@ -197,14 +198,16 @@ [:div [:div.draggable-shape (drag-map :clograms/rectangle-node) [:svg {:width 30 :height 30} - [:rect.rectangle-shape (merge {:width 30 :height 30 :rx 3})]]] + (nodes/rectangle-node-component {:w 30 :h 30 :extra-data {:label ""}})]] [:div.draggable-shape (drag-map :clograms/circle-node) [:svg {:width 30 :height 30} - [:circle.circle-shape {:r 15 :cx 15 :cy 15}]]] + (nodes/circle-node-component {:w 30 :h 30 :extra-data {:label ""}})]] [:div.draggable-shape (drag-map :clograms/group-node) [:svg {:width 30 :height 30} - [:g.group-shape - [:rect {:width 30 :height 30 :rx 3}]]]]])) + (nodes/group-node-component {:w 30 :h 30 :extra-data {:label ""}})]] + [:div.draggable-shape (drag-map :clograms/user-node) + [:svg {:width 30 :height 30} + (nodes/user-node-component {:w 30 :h 30 :extra-data {:label ""}})]]])) (defn side-bar [] (let [namespace-node (fn [n]