summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Levy <alon@pobox.com>2014-12-04 13:41:04 +0200
committerAlon Levy <alon@pobox.com>2014-12-04 13:42:12 +0200
commit8227fdd4239cf3393c3728350c266673749d6b44 (patch)
tree7d132f3604e65ecfa8ce7429be6a06dfb8050598 /src
parentf11f4005656d5df9649b59edd1e44b21b63d89e7 (diff)
svgInput modularized, works mostly
missing correct width (setting it on the input instead of the FO) plus only chrome looks ok for link, FF still misplaced.
Diffstat (limited to 'src')
-rw-r--r--src/rz_core.js231
1 files changed, 131 insertions, 100 deletions
diff --git a/src/rz_core.js b/src/rz_core.js
index 2bf71e78..858fa15d 100644
--- a/src/rz_core.js
+++ b/src/rz_core.js
@@ -15,22 +15,132 @@ var addednodes = [],
drag,
force;
-// SVG Util
-function appendForeignElementInputWithID(base, elemid, width, height)
-{
- var input = document.createElement('input'),
- body = document.createElement('body'),
- fo = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
+// "CSS" for SVG elements. Reused for editing elements.
+var node_text_dx = 15,
+ node_text_dy = '.30em',
+ svg_input_fo_node_x = node_text_dx,
+ svg_input_fo_node_y = '-.70em',
+ svg_input_fo_height = '28px',
+ svg_input_fo_width = '100px';
+
+
+/**
+ * svgInput - creates an embedded input element under a given
+ *
+ * edit_node(@sibling, @node)
+ * edit_link(@sibling, @link)
+ */
+var svgInput = (function() {
+ function appendForeignElementInputWithID(base, elemid, width, height)
+ {
+ var input = document.createElement('input'),
+ body = document.createElement('body'),
+ fo = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
+
+ body.appendChild(input);
+
+ fo.setAttribute('width', width || svg_input_fo_width);
+ fo.setAttribute('height', height || svg_input_fo_height);
+ fo.style.pointerEvents = 'none';
+ input.style.pointerEvents = 'all';
+ fo.appendChild(body);
+ base.appendChild(fo);
+ input.setAttribute('id', elemid);
+ return input;
+ }
+
+ function editname_on_keydown(e) {
+ var ret = undefined,
+ jelement = createOrGetSvgInput(),
+ element = jelement[0],
+ newname = jelement.val(),
+ fo = createOrGetSvgInputFO(),
+ d;
+
+ if (element != this) {
+ console.log('unexpected editname_on_keypress this should be the svg-input element');
+ }
+
+ if (e.which == 13 || e.which == 27) {
+ fo.hide();
+ ret = false;
+ d = jelement.data().d;
+ if (e.which == 13 && newname != d.name) {
+ if (d.hasOwnProperty('__src')) {
+ graph.editLink(d.__src.id, d.__dst.id, newname);
+ } else {
+ graph.editName(d.id, newname);
+ }
+ update_view__graph(true);
+ }
+ }
+ rz_bus.ui_key.push({where: consts.KEYSTROKE_WHERE_EDIT_NODE, keys: [e.which]});
+ return ret;
+ };
+
+
+ // FIXME: element being deleted. Some delete is legit - removal of related element. Some isn't (a click).
+ // Instead of investigating (time constraint) reparenting as sibling, and introducing
+ // this function. Cost of creation of element is negligble, it's just ugly..
+ function createOrGetSvgInput()
+ {
+ var svg_input_name = 'svg-input',
+ svg_input_selector = '#' + svg_input_name,
+ svg_input = $(svg_input_selector);
+
+ if (svg_input.length == 0) {
+ console.log('creating new svg-input');
+ svg_input = $(appendForeignElementInputWithID(vis[0][0], svg_input_name));
+ svg_input.on('keydown', editname_on_keydown);
+ }
+ return svg_input;
+ }
+
+ function createOrGetSvgInputFO()
+ {
+ return createOrGetSvgInput().parent().parent();
+ }
+ /*
+ * @param e visual node element
+ * @param n node model object
+ */
+ function enable(e, n) {
+ var oldname = n.name,
+ svg_input = createOrGetSvgInput(e, n),
+ fo = createOrGetSvgInputFO(),
+ is_link = n.hasOwnProperty('__src');
+
+ e.parentNode.appendChild(fo[0]); // This will unparent from the old parent
+ if (is_link) {
+ fo.attr('transform', e.getAttribute('transform'));
+ // XXX links set the text-anchor middle attribute. no idea how to do that
+ fo.attr('x', -$(e).width() / 2);
+ fo.attr('y', -$(e).height() / 2 - 3); // XXX This minus 3 is only kinda ok.
+ fo.attr('class', 'svg-input-fo-link');
+ } else {
+ fo.attr('x', svg_input_fo_node_x);
+ fo.attr('y', svg_input_fo_node_y);
+ fo.attr('transform', null);
+ fo.attr('class', 'svg-input-fo-node');
+ }
+ // Set width correctly
+ svg_input.attr('width', Math.max($(e).width() * 1.2, $(e).width() + 50));
+ fo.show();
+ svg_input.val(oldname);
+ svg_input.data().d = n;
+ svg_input.focus();
+ // TODO: set cursor to correct location in text
+ }
+
+ return {
+ enable: enable,
+ hide: function() {
+ createOrGetSvgInputFO().hide();
+ }
+ };
+}());
+
- body.appendChild(input);
-
- fo.setAttribute('width', width || '100px');
- fo.setAttribute('height', height || '100px');
- fo.appendChild(body);
- base.appendChild(fo);
- input.setAttribute('id', elemid);
- return input;
-}
function recenterZoom() {
vis.attr("transform", "translate(0,0)scale(1)");
@@ -163,7 +273,7 @@ function canvas_handler_dblclick(){
var n_ve = locate_visual_element(n); // locate visual element
var on_slowdown_cb = function(){
- editNodeText($(n_ve).find('.nodetext'), n);
+ svgInput.enable($(n_ve).find('.nodetext'), n);
observer.disconnect();
}
var mutation_handler = rz_observer.new_Mutation_Handler__on_dxy_slowdown(on_slowdown_cb);
@@ -264,7 +374,7 @@ function update_view__graph(no_relayout) {
.attr("text-anchor", "middle")
.on("click", function(d, i) {
if (d.state !== "temp") {
- editLinkText(this, d);
+ svgInput.enable(this, d);
}
});
@@ -305,15 +415,15 @@ function update_view__graph(no_relayout) {
nodetext = nodeEnter.insert("text")
.attr("class", "nodetext graph")
- .attr("dx", 15)
- .attr("dy", ".30em")
+ .attr("dx", node_text_dx)
+ .attr("dy", node_text_dy)
.on("click", function(d, i) {
if (d3.event.defaultPrevented) {
// drag happened, ignore click https://github.com/mbostock/d3/wiki/Drag-Behavior#on
return;
}
if (d.state !== "temp") {
- editNodeText(this, d);
+ svgInput.enable(this, d);
selection.update([d]);
showNodeInfo(this.parentNode.node, i);
update_view__graph(true);
@@ -583,91 +693,12 @@ function showNodeInfo(d, i) {
}
function overlay_mousedown() {
- createOrGetSvgInputFO().hide();
+ svgInput.hide();
selection.clear();
view.hide();
update_view__graph(true);
}
-function editname_on_keypress(e) {
- var ret = undefined,
- element = createOrGetSvgInput(),
- newname = element.val(),
- fo = createOrGetSvgInputFO(),
- d;
-
- if (element != this) {
- console.log('unexpected editname_on_keypress this should be the svg-input element');
- }
-
- if (e.which == 13 || e.which == 27) {
- fo.hide();
- ret = false;
- d = element.data().d;
- if (e.which == 13 && newname != d.name) {
- if (d.hasOwnProperty('__src')) {
- graph.editLink(d.__src.id, d.__dst.id, newname);
- } else {
- graph.editName(d.id, newname);
- }
- update_view__graph(true);
- }
- }
- rz_bus.ui_key.push({where: consts.KEYSTROKE_WHERE_EDIT_NODE, keys: [e.which]});
- return ret;
-};
-
-function createOrGetSvgInput()
-{
- var svg_input_name = 'svg-input',
- svg_input_selector = '#' + svg_input_name,
- svg_input = $(svg_input_selector);
-
- if (svg_input.length == 0) {
- console.log('creating new svg-input');
- svg_input = $(appendForeignElementInputWithID(vis[0][0], svg_input_name));
- svg_input.on('keypress', editname_on_keypress);
- }
- return svg_input;
-}
-
-function createOrGetSvgInputFO()
-{
- return createOrGetSvgInput().parent().parent();
-}
-
-/**
- * @param e visual node element
- * @param n node model object
- */
-function editBothText(e, n) {
- var oldname = n.name,
- svg_input = createOrGetSvgInput(),
- fo = createOrGetSvgInputFO(),
- is_link = n.hasOwnProperty('__src');
-
- e.parentNode.appendChild(fo[0]); // This will unparent from the old parent
- if (is_link) {
- fo.attr('transform', e.getAttribute('transform'));
- fo.attr('dx', null);
- fo.attr('dy', null);
- svg_input.attr('class', 'linklabel graph');
- } else {
- fo.attr('dx', e.getAttribute('dx'));
- fo.attr('dy', e.getAttribute('dy'));
- fo.attr('transform', null);
- svg_input.attr('class', 'nodetext graph');
- }
- fo.show();
- svg_input.val(oldname);
- svg_input.data().d = n;
- svg_input.focus();
- // TODO: set cursor to correct location in text
-}
-
-var editLinkText = editBothText;
-var editNodeText = editBothText;
-
return {
graph: graph,
force: force,