summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Simianer <p@simianer.de>2015-11-23 11:20:32 +0100
committerPatrick Simianer <p@simianer.de>2015-11-23 11:20:32 +0100
commit3b92468ae3ca659010381fe0fa4d5a383d0208d7 (patch)
tree6358319feff3d7a535e74885cd885952c053ff45
parent711bbbd5b7955fe71767fd6cc3cbe76bc3380b96 (diff)
drag-n-drop -> keyboard interface
-rw-r--r--derivation-editor.js878
-rw-r--r--raphael.inline_text_editing.js2
2 files changed, 701 insertions, 179 deletions
diff --git a/derivation-editor.js b/derivation-editor.js
index eecf90a..2a9fbcf 100644
--- a/derivation-editor.js
+++ b/derivation-editor.js
@@ -14,7 +14,7 @@ var DE_paper,
// ui
DE_ui_margin = 32,
DE_ui_padding = DE_ui_margin/3,
- DE_ui_xbegin = 5,
+ DE_ui_xbegin = 10,
DE_ui_ybegin = 5,
DE_ui_box_height = 32,
DE_ui_line_margin = 64,
@@ -22,16 +22,14 @@ var DE_paper,
DE_ui_ytarget = DE_ui_ysource+DE_ui_line_margin;
DE_ui_font_size = 14,
DE_ui_font_width = -1,
+///////////////////////////////////////////////////////////////////////////////
DE_ui_stroke_width = 1,
DE_ui_stroke_width_hi = 4,
DE_ui_align_stroke = "#000",
DE_ui_align_stroke_hi = "#000",
- DE_ui_fill_opacity_hi = { "fill-opacity": .2 },
- DE_ui_text_att = { "fill": "#000", "stroke": "none",
- "text-anchor": "start", "font-size": DE_ui_font_size,
+ DE_ui_text_att = { "text-anchor": "start", "font-size": DE_ui_font_size,
"font-family": "Times New Roman" },
- DE_ui_shape_att = { "fill": "red", "stroke": "#000", "fill-opacity": 0,
- "stroke-width": DE_ui_stroke_width }
+///////////////////////////////////////////////////////////////////////////////
// dragging
DE_cur_drag = null,
DE_dragging = false,
@@ -47,10 +45,167 @@ var DE_paper,
DE_edit_mode = false,
// removing
DE_rm_mult = [],
+ // keyboard interface
+ DE_kbd_focused_phrase = null,
+ DE_kbd_move_mode = false,
+ DE_kbd_select_mode = false,
+ // done
+ DE_target_done = [],
// data
DE_data_source = null,
DE_data_target = null,
- DE_data_align = null;
+ DE_data_align = null,
+ // lock
+ DE_locked = false;
+
+
+/******************************************************************************
+ *
+ * style
+ *
+ */
+var ch_style = function (item, shape_att, text_att, anim=false, anim_dur=50)
+{
+ if (!anim) {
+ item.attr(shape_att);
+ if (item.pair)
+ item.pair.attr(text_att);
+ } else {
+ item.animate(shape_att, anim_dur);
+ item.pair.animate(text_att, anim_dur);
+ }
+}
+
+var DE_ui_style_normal = function (item, type=null)
+{
+ if (!type)
+ type = item["type_"];
+ var to_delete = false;
+ var color = stroke_color = "#000";
+ var text_color = "#fff";
+ if (DE_rm_mult.indexOf(item)>-1)
+ color = stroke_color = "#f00";
+ if (DE_target_done.indexOf(item)>-1) {
+ color = "#fff";
+ text_color = stroke_color= "#000";
+ }
+ var shape_att;
+ var text_att;
+ if (type == "source") {
+ shape_att = {
+ "fill": "#fff",
+ "fill-opacity": 1.0,
+ "stroke": "#000",
+ "stroke-width": 1
+ };
+ text_att = {
+ "fill": "#000",
+ "fill-opacity": 1.0,
+ "stroke": "none",
+ "stroke-width": 0
+ };
+ } else { // type == "target"
+ shape_att = {
+ "fill": color,
+ "fill-opacity": 1.0,
+ "stroke": stroke_color,
+ "stroke-width": 1
+ };
+ text_att = {
+ "fill": text_color,
+ "fill-opacity": 1.0,
+ "stroke": text_color,
+ "stroke-width": 0
+ };
+ }
+
+ ch_style(item, shape_att, text_att);
+}
+
+var DE_ui_style_highlight = function (item, type=null)
+{
+ if (!type)
+ type = item["type_"];
+ var to_delete = false;
+ var color = stroke_color = "#000";
+ var stroke_width = 9;
+ var text_color = "#fff";
+ if (DE_rm_mult.indexOf(item)>-1)
+ color = stroke_color = "#f00";
+ if (DE_target_done.indexOf(item)>-1) {
+ color = "#fff";
+ text_color = stroke_color = "#000";
+ stroke_width = 5;
+ }
+ var shape_att;
+ var text_att;
+ if (type == "source") {
+ shape_att = {
+ "fill": "#fff",
+ "fill-opacity": 1.0,
+ "stroke": "#000",
+ "stroke-width": 3
+ };
+ text_att = {
+ "fill": "#000",
+ "fill-opacity": 1.0,
+ "stroke": "none",
+ "stroke-width": 0
+ };
+ } else { // type == "target"
+ shape_att = {
+ "fill": color,
+ "fill-opacity": 1.0,
+ "stroke": stroke_color,
+ "stroke-width": stroke_width
+ };
+ text_att = {
+ "fill": text_color,
+ "fill-opacity": 1.0,
+ "stroke": text_color,
+ "stroke-width": 0
+ };
+ }
+
+ ch_style(item, shape_att, text_att);
+}
+
+var DE_ui_style_mark = function (item, type=null)
+{
+ if (!type)
+ type = item["type_"];
+ var shape_att;
+ var text_att;
+ if (type == "source") {
+ shape_att = {
+ "fill": "#ff0000",
+ "fill-opacity": 0.25,
+ "stroke": "#000",
+ "stroke-width": 3
+ };
+ text_att = {
+ "fill": "#000",
+ "fill-opacity": 1.0,
+ "stroke": "none",
+ "stroke-width": 0
+ };
+ } else { // type == "target"
+ shape_att = {
+ "fill": "#000",
+ "fill-opacity": 1.0,
+ "stroke": "#000000",
+ "stroke-width": 9
+ };
+ text_att = {
+ "fill": "#fff",
+ "fill-opacity": 1.0,
+ "stroke": "#fff",
+ "stroke-width": 0
+ };
+ }
+
+ ch_style(item, shape_att, text_att);
+}
/******************************************************************************
*
@@ -78,8 +233,15 @@ Raphael.fn.connection = function (obj1, obj2, line, bg)
line.line.attr({path: path});
} else {
return {
- bg: bg && bg.split && this.path(path).attr({stroke: bg.split("|")[0], fill: "none", "stroke-width": bg.split("|")[1] || 3}),
- line: this.path(path).attr({stroke: DE_ui_align_stroke, fill: "none"}),
+ bg: bg && bg.split && this.path(path).attr({
+ "stroke": bg.split("|")[0],
+ "fill": "none",
+ "stroke-width": bg.split("|")[1] || 3
+ }),
+ line: this.path(path).attr({
+ "stroke": DE_ui_align_stroke,
+ "fill": "none"
+ }),
from: obj1,
to: obj2
};
@@ -96,7 +258,10 @@ var DE_make_conn = function(obj1, obj2)
DE_connections[DE_conn_str(obj1,obj2)] = DE_paper.connection(obj1, obj2);
if (DE_connect_mode) {
DE_new_conns.push(DE_connections[DE_conn_str(obj1,obj2)]);
- DE_connections[DE_conn_str(obj1,obj2)].line.attr({"stroke":DE_ui_align_stroke_hi,"stroke-width":DE_ui_stroke_width_hi});
+ DE_connections[DE_conn_str(obj1,obj2)].line.attr({
+ "stroke":DE_ui_align_stroke_hi,
+ "stroke-width":DE_ui_stroke_width_hi
+ });
}
}
@@ -117,6 +282,11 @@ var DE_rm_conn = function (id1, id2)
if (b)
break;
}
+ for (c in DE_connections) {
+ a = c.split("-");
+ if (id1 == parseInt(a[0]) && parseInt(a[1])==DE_kbd_focused_phrase["id_"])
+ return;
+ }
DE_shapes_by_id[id1].attr({"stroke-width":DE_ui_stroke_width});
}
@@ -189,7 +359,7 @@ var DE_up = function () {
* snap-to-grid
*
*/
-var DE_colldetect = function (dir) // FIXME
+var DE_colldetect = function (dir)
{
DE_target_shapes.sort(function(a, b) {
return a["grid_"]-b["grid_"];
@@ -208,8 +378,7 @@ var DE_colldetect = function (dir) // FIXME
continue;
var b_left = b.attr("x");
var b_right = b.attr("x")+b.attr("width");
- if (!(a_left >= b_right || a_right <= b_left)) {
- //b.attr({"stroke":"green","stroke-width":4});
+ if (!(a_left >= b_right || a_right <= b_left)) { // collision!
if (a["grid_"] > b["grid_"]) { // a should be right of b
a.attr({"x": a.attr("x")+(a_right-b_left)});
a.pair.attr({"x": a.pair.attr("x")+(a_right-b_left)});
@@ -229,8 +398,7 @@ var DE_collide = function (obj)
// not a shape
if (!obj["id_"] || obj.type!="rect")
return;
- if (DE_cur_drag["grid_tmp_"] > obj["grid_tmp_"]) {
- // right -> left
+ if (DE_cur_drag["grid_tmp_"] > obj["grid_tmp_"]) { // right -> left
/*if (DE_cur_drag.getBBox().width < obj.getBBox().width &&
DE_cur_drag.getBBox().x > (obj.getBBox().x+obj.getBBox().width/1000)) { // ignored tolerance, when
return; // dragging onto shapes
@@ -240,8 +408,7 @@ var DE_collide = function (obj)
att = { x: obj.pair.attr("x")+DE_cur_drag.getBBox().width+(DE_ui_margin-2*DE_ui_padding) };
obj.pair.attr(att);
DE_colldetect("rl");
- } else {
- // left -> right
+ } else { // left -> right
/*if (DE_cur_drag.getBBox().width < obj.getBBox().width &&
DE_cur_drag.getBBox().x < (obj.getBBox().x+obj.getBBox().width/1000)) {
return;
@@ -271,8 +438,7 @@ var DE_snap_to_grid = function (anim=false, ignore_cur_drag=false)
if (DE_cur_drag) { // fix glitch when calling from DE_add_object() and up()
DE_cur_drag["grid_"] = DE_new_pos;
cur_id = DE_cur_drag["id_"];
- if (DE_new_pos > DE_old_pos) {
- // left -> right
+ if (DE_new_pos > DE_old_pos) { // left -> right
for (var i=0; i < DE_target_shapes.length; i++) {
pos = DE_target_shapes[i]["grid_"];
id_ = DE_target_shapes[i]["id_"];
@@ -284,8 +450,7 @@ var DE_snap_to_grid = function (anim=false, ignore_cur_drag=false)
continue;
}
}
- } else if (DE_new_pos < DE_old_pos) {
- // right -> left
+ } else if (DE_new_pos < DE_old_pos) { // right -> left
for (var i=0; i < DE_target_shapes.length; i++) {
pos = DE_target_shapes[i]["grid_"];
id_ = DE_target_shapes[i]["id_"];
@@ -319,7 +484,8 @@ var DE_snap_to_grid = function (anim=false, ignore_cur_drag=false)
}
att = { x: obj.getBBox().x+DE_ui_padding };
if (anim) {
- obj.pair.animate(att,125);
+ //obj.pair.animate(att,50);
+ obj.pair.attr(att);
} else {
obj.pair.attr(att);
}
@@ -348,6 +514,178 @@ var DE_debug_DE_snap_to_grid = function () {
/******************************************************************************
*
+ * mouseover-out / click events
+ *
+ */
+DE_item_mouseover = function (item)
+{
+ if (DE_locked) return;
+ if (DE_dragging) return;
+ if (DE_edit_mode) return;
+
+ // fix z-index
+ //this.pair.toBack();
+ //this.toFront();
+
+ // reset others
+ var not_reset = [];
+ for (c in DE_connections) {
+ if (DE_shapes_by_id[parseInt(c.split("-")[1])] != DE_kbd_focused_phrase ||
+ c.split("-")[1] != DE_kbd_focused_phrase["id_"])
+ DE_connections[c].line.attr({"stroke-width":DE_ui_stroke_width});
+ if (c.split("-")[1] == DE_kbd_focused_phrase["id_"])
+ not_reset.push(c.split("-")[0]);
+ }
+ for (sh in DE_shapes_by_id) {
+ if (sh != DE_kbd_focused_phrase["id_"]
+ && not_reset.indexOf(sh)==-1) {
+ if (!(DE_connect_mode_shape && sh==DE_connect_mode_shape["id_"])) {
+ DE_ui_style_normal(DE_shapes_by_id[sh]);
+ }
+ }
+ }
+
+ var idx, other_idx;
+ if (item["type_"] == "target") {
+ idx = 1;
+ other_idx = 0;
+ } else {
+ idx = 0;
+ other_idx = 1;
+ }
+ for (c in DE_connections) {
+ if (parseInt(c.split("-")[idx]) == item["id_"]) {
+ DE_connections[c].line.attr({"stroke-width":DE_ui_stroke_width_hi});
+ if (DE_shapes_by_id[parseInt(c.split("-")[other_idx])] != DE_connect_mode_shape)
+ DE_ui_style_highlight(DE_shapes_by_id[parseInt(c.split("-")[other_idx])]);
+ }
+ }
+
+ if (item != DE_connect_mode_shape)
+ DE_ui_style_highlight(item);
+}
+
+DE_item_mouseout = function (item)
+{
+ if (DE_cur_drag) return;
+ if (DE_edit_mode) return; // FIXME
+ if (item == DE_connect_mode_shape) return;
+ if (item == DE_kbd_focused_phrase) return;
+
+ // fix z-index
+ //this.pair.toFront();
+ //this.toBack();
+
+ var idx, other_idx;
+ if (item["type_"] == "target") {
+ idx = 1;
+ other_idx = 0;
+ } else {
+ idx = 0;
+ other_idx = 1;
+ }
+ var aligned_with_focused = false;
+ for (c in DE_connections) {
+ if (parseInt(c.split("-")[idx]) == item["id_"]) {
+ var obj = DE_shapes_by_id[parseInt(c.split("-")[other_idx])];
+ if (parseInt(c.split("-")[1]) != DE_kbd_focused_phrase["id_"]) {
+ var x = false;
+ for (d in DE_connections) {
+ if (d == c.split("-")[0]+'-'+DE_kbd_focused_phrase["id_"]) {
+ x = true;
+ break;
+ }
+ }
+ if (!x) {
+ if (!(DE_connect_mode_shape && obj["id_"]==DE_connect_mode_shape["id_"]))
+ DE_ui_style_normal(obj);
+ }
+ DE_connections[c].line.attr({"stroke-width":DE_ui_stroke_width});
+ } else {
+ aligned_with_focused = true;
+ }
+ }
+ }
+ if (!aligned_with_focused)
+ DE_ui_style_normal(item);
+ for (var i=0; i<DE_new_conns.length; i++) {
+ DE_new_conns[i].line.attr({"stroke-width":DE_ui_stroke_width});
+ }
+ DE_new_conns = [];
+}
+
+var DE_item_click_target = function (e, item)
+{
+ if (DE_locked) return;
+ if (DE_connect_mode) {
+ if (DE_connections[DE_conn_str(DE_connect_mode_shape,item)]) {
+ DE_rm_conn(DE_connect_mode_shape["id_"], item["id_"]);
+ DE_ui_style_normal(DE_connect_mode_shape);
+ } else {
+ DE_ui_style_highlight(DE_connect_mode_shape);
+ DE_make_conn(DE_connect_mode_shape, item);
+ }
+ DE_connect_mode = false;
+ DE_connect_mode_shape = null;
+ } else { // delete
+ if (e.altKey) {
+ if (DE_target_done.indexOf(item)>-1) return;
+ var index = DE_rm_mult.indexOf(item);
+ if (index != -1) {
+ DE_rm_mult.splice(index, 1);
+ for (c in DE_connections) {
+ var i = parseInt(c.split("-")[1]);
+ if (i == item["id_"])
+ DE_connections[c].line.attr({"stroke":"#000"});
+ }
+ DE_ui_style_highlight(item);
+ } else {
+ item.attr({"stroke":"red", "fill":"red"});
+ for (c in DE_connections) {
+ var i = parseInt(c.split("-")[1]);
+ if (i == item["id_"])
+ DE_connections[c].line.attr({"stroke":"#f00"});
+ }
+ DE_rm_mult.push(item);
+ }
+ } else if(e.shiftKey && false) { // add
+ var x = DE_shapes_by_id[item["id_"]].attr("x")+DE_shapes_by_id[item["id_"]].attr("width")
+ +2*DE_ui_padding;
+ var new_obj = DE_make_obj(x, "", "target");
+ var new_grid = item["grid_"]+1;
+ new_obj["grid_"] = new_grid;
+ new_obj.pair["grid_"] = new_grid;
+ for (var i=0; i<DE_target_shapes.length; i++) {
+ var sh = DE_target_shapes[i];
+ if (sh!=new_obj && sh["grid_"] >=new_grid) {
+ sh["grid_"] += 1;
+ sh.pair["grid_"] += 1;
+ }
+ }
+ DE_snap_to_grid(true);
+ }
+ }
+}
+
+var DE_item_click_source = function (e, item)
+{
+ if (DE_locked) return;
+ if (DE_connect_mode) {
+ if (item != DE_connect_mode_shape)
+ return;
+ if (item != DE_kbd_focused_phrase)
+ DE_ui_style_highlight(item);
+ DE_connect_mode = false;
+ DE_connect_mode_shape = null;
+ } else {
+ DE_ui_style_mark(item);
+ DE_connect_mode = true;
+ DE_connect_mode_shape = item;
+ }
+}
+
+/******************************************************************************
+ *
* add/remove objects
*
*/
@@ -364,180 +702,68 @@ var DE_make_obj = function (x, text, type)
// make shape obj
var x_shape = DE_texts[DE_texts.length-1].getBBox().x-DE_ui_padding,
x_width = DE_texts[DE_texts.length-1].getBBox().width+(2*DE_ui_padding);
- DE_shapes.push(DE_paper.rect(x_shape, y, x_width, DE_ui_box_height, 5).attr(DE_ui_shape_att));
+ DE_shapes.push(DE_paper.rect(x_shape, y, x_width, DE_ui_box_height, 5));
tx = DE_texts[DE_texts.length-1];
sh = DE_shapes[DE_shapes.length-1];
// fix z-index
- tx.toBack();
- sh.toFront();
+ tx.toFront();
+ sh.toBack();
// pair text/shape
tx.pair = DE_shapes[DE_shapes.length-1];
sh.pair = DE_texts[DE_texts.length-1];
+ // style
+ DE_ui_style_normal(DE_shapes[DE_shapes.length-1]);
// meta
sh["type_"] = type;
sh["id_"] = DE_id;
DE_shapes_by_id[DE_id] = sh;
if (type == "target") {
- sh.drag(DE_move, DE_dragger, DE_up).onDragOver(function(obj) { DE_collide(obj); })
- sh.attr({ cursor: "move" });
- tx.drag(DE_move, DE_dragger, DE_up);
+ // :'(
+ //sh.drag(DE_move, DE_dragger, DE_up).onDragOver(function(obj) { DE_collide(obj); })
+ //sh.attr({ cursor: "move" });
+ //tx.drag(DE_move, DE_dragger, DE_up);
sh["grid_"] = DE_next_grid;
sh["grid_tmp_"] = DE_next_grid;
sh.click(function(e) {
- if (DE_connect_mode) {
- if (DE_connections[DE_conn_str(DE_connect_mode_shape,this)]) {
- DE_rm_conn(DE_connect_mode_shape["id_"], this["id_"]);
- } else {
- DE_make_conn(DE_connect_mode_shape, this);
- DE_connect_mode_shape.attr({"stroke":DE_ui_align_stroke_hi,"stroke-width":DE_ui_stroke_width_hi});
- }
- DE_connect_mode_shape.attr({"fill-opacity": 0});
- DE_connect_mode = false;
- DE_connect_mode_shape = null;
- } else { // delete
- if (e.shiftKey) {
- var index = DE_rm_mult.indexOf(this);
- if (index != -1) {
- DE_rm_mult.splice(index, 1);
- this.animate({"stroke":"#000"});
- this.animate({"fill-opacity":0});
- } else {
- this.animate({"stroke":"red"});
- DE_rm_mult.push(this);
- }
- } else if(e.ctrlKey) { // add
- var x = DE_shapes_by_id[this["id_"]].attr("x")+DE_shapes_by_id[this["id_"]].attr("width")
- +2*DE_ui_padding;
- var new_obj = DE_make_obj(x, "", "target");
- var new_grid = this["grid_"]+1;
- new_obj["grid_"] = new_grid;
- new_obj.pair["grid_"] = new_grid;
- for (var i=0; i<DE_target_shapes.length; i++) {
- var sh = DE_target_shapes[i];
- if (sh!=new_obj && sh["grid_"] >=new_grid) {
- sh["grid_"] += 1;
- sh.pair["grid_"] += 1;
- }
- }
- DE_snap_to_grid(true);
- }
- }
+ DE_item_click_target(e, this);
+ });
+ tx.click(function(e) {
+ DE_item_click_target(e, this.pair);
});
DE_target_shapes.push(sh);
// inline text editing
DE_paper.inlineTextEditing(tx);
sh.dblclick(function(){
- if (DE_edit_mode) return;
- DE_edit_mode = true;
- this.pair.toFront();
- this.toBack();
- //this.animate({"opacity":0}, 250);
- DE_cur_ed = this.pair;
- DE_cur_ed_shape = this;
- var input = DE_cur_ed.inlineTextEditing.startEditing();
- input.addEventListener("keypress", function(e) {
- if (e.keyCode==27||e.keyCode==37||e.keyCode==38||e.keyCode==39||e.keyCode==40) {
- // esc, arrows, backspace
- return;
- } else if (e.keyCode == 8) {
- // backspace
- DE_cur_ed_shape.animate({width:DE_cur_ed_shape.getBBox().width-DE_ui_font_width},125);
- setTimeout(function(){DE_snap_to_grid(true);},125);
- } else if (e.keyCode == 13) {
- // return
- e.preventDefault();
- DE_cur_ed.inlineTextEditing.stopEditing();
- DE_cur_ed_shape.toFront();
- DE_cur_ed.toBack();
- DE_cur_ed_shape.animate({width:DE_cur_ed.getBBox().width+(DE_ui_margin-DE_ui_padding)},125);
- setTimeout(function(){DE_snap_to_grid(true);},125);
- DE_edit_mode = false;
- } else {
- // input
- DE_cur_ed_shape.animate({width:(this.value.length*DE_ui_font_width)+2*DE_ui_font_width+2*DE_ui_padding},25);
- setTimeout(function(){
- DE_snap_to_grid(true);
- DE_paper.setSize(DE_paper.width+DE_ui_font_width, DE_paper.height);
- },25);
- }
- });
- input.addEventListener("blur", function(e) {
- DE_cur_ed.inlineTextEditing.stopEditing();
- DE_cur_ed_shape.toFront();
- DE_cur_ed.toBack();
- DE_cur_ed_shape.animate({width:DE_cur_ed.getBBox().width+(DE_ui_margin-DE_ui_padding)},125);
- setTimeout(function(){DE_snap_to_grid(true);},125);
- DE_edit_mode = false;
- }, true);
+ DE_enter_edit_mode(this);
});
+ tx.dblclick(function(){
+ DE_enter_edit_mode(this.pair);
+ })
} else if (type == "source") {
- sh.click(function() {
- if (DE_connect_mode) {
- if (this != DE_connect_mode_shape)
- return;
- this.animate({"fill-opacity": 0}, 250);
- DE_connect_mode = false;
- DE_connect_mode_shape = null;
- } else {
- this.animate(DE_ui_fill_opacity_hi, 250);
- DE_connect_mode = true;
- DE_connect_mode_shape = this;
- }
+ sh.click(function(e) {
+ DE_item_click_source(e, this);
+ });
+ tx.click(function(e) {
+ DE_item_click_source(e, this.pair);
});
}
+
// mouseover -out
sh.mouseover(function() {
- if (DE_dragging) return;
- if (DE_edit_mode) return;
-
- // reset others
- for (c in DE_connections) {
- DE_connections[c].line.attr({"stroke":DE_ui_align_stroke,"stroke-width":DE_ui_stroke_width});
- }
- for (sh in DE_shapes_by_id) {
- DE_shapes_by_id[sh].attr({"stroke-width":DE_ui_stroke_width});
- }
-
- var idx, other_idx;
- if (this["type_"] == "target") {
- idx = 1;
- other_idx = 0;
- } else {
- idx = 0;
- other_idx = 1;
- }
- for (c in DE_connections) {
- if (parseInt(c.split("-")[idx]) == this["id_"]) {
- DE_connections[c].line.attr({"stroke":DE_ui_align_stroke_hi,"stroke-width":DE_ui_stroke_width_hi});
- DE_shapes_by_id[parseInt(c.split("-")[other_idx])].attr({"stroke-width":DE_ui_stroke_width_hi});
- }
- }
- this.animate({"stroke-width":DE_ui_stroke_width_hi})
+ DE_item_mouseover(this);
});
sh.mouseout(function() {
- if (DE_cur_drag) return;
- if (DE_edit_mode) return; // FIXME
- var idx, other_idx;
- if (this["type_"] == "target") {
- idx = 1;
- other_idx = 0;
- } else {
- idx = 0;
- other_idx = 1;
- }
- for (c in DE_connections) {
- if (parseInt(c.split("-")[idx]) == this["id_"]) {
- DE_connections[c].line.attr({"stroke":DE_ui_align_stroke,"stroke-width":DE_ui_stroke_width});
- DE_shapes_by_id[parseInt(c.split("-")[other_idx])].attr({"stroke-width":DE_ui_stroke_width});
- }
- }
- this.animate({"stroke-width":DE_ui_stroke_width})
- for (var i=0; i<DE_new_conns.length; i++) {
- DE_new_conns[i].line.attr({"stroke":DE_ui_align_stroke,"stroke-width":DE_ui_stroke_width});
- }
- DE_new_conns = [];
+ DE_item_mouseout(this);
+ });
+ tx.mouseover(function() {
+ DE_item_mouseover(this.pair);
});
+ tx.mouseout(function() {
+ //DE_item_mouseout(this.pair);
+ });
+
DE_id++;
+
if (type == "target")
DE_next_grid++;
@@ -561,9 +787,17 @@ var DE_add_object = function()
"",
"target");
}
- DE_paper.setSize(DE_paper.width+DE_target_shapes[DE_target_shapes.length-1].getBBox().width+DE_ui_margin, DE_paper.height);
+ DE_paper.setSize(
+ DE_paper.width
+ +DE_target_shapes[DE_target_shapes.length-1].getBBox().width
+ +DE_ui_margin,
+ DE_paper.height);
DE_cur_drag = null;
+
+ if (DE_target_shapes.length==1)
+ DE_kbd_focus_shape(DE_target_shapes[0]);
+
DE_snap_to_grid(true);
}
@@ -582,6 +816,7 @@ var DE_make_objs = function (a, type)
var rm_obj = function(obj)
{
+ if (!obj) return;
var del = DE_shapes_by_id[obj["id_"]];
if (!del)
return;
@@ -624,17 +859,58 @@ var rm_obj = function(obj)
DE_next_grid = 0;
DE_cur_drag = null;
DE_snap_to_grid(true);
+
return;
}
-$(document).keypress(function(e){
- if (DE_rm_mult.length>0 && e.which==0) {
- for (var i=0; i<DE_rm_mult.length; i++) {
- rm_obj(DE_rm_mult[i]);
+var DE_enter_edit_mode = function (sh, kbd=false)
+{
+ if (DE_locked) return;
+ if (DE_edit_mode) return;
+ if (kbd && !DE_kbd_focused_phrase) return;
+ if (DE_target_done.indexOf(sh)>-1) return;
+ if (DE_rm_mult.indexOf(sh)>-1) return;
+ DE_edit_mode = true;
+ //sh.pair.toFront();
+ //sh.toBack();
+ DE_cur_ed = sh.pair;
+ DE_cur_ed_shape = sh;
+ var input = DE_cur_ed.inlineTextEditing.startEditing();
+ input.addEventListener("keypress", function(e) {
+ if (e.keyCode==27
+ || e.keyCode==37
+ || e.keyCode==38
+ || e.keyCode==39
+ || e.keyCode==40) { // esc, arrows, backspace
+ return;
+ } else if (e.keyCode == 8) { // backspace
+ DE_cur_ed_shape.animate({width:DE_cur_ed_shape.getBBox().width-DE_ui_font_width},50);
+ setTimeout(function(){DE_snap_to_grid(true);},125);
+ } else if (e.keyCode == 13) { // return
+ e.preventDefault();
+ DE_cur_ed.inlineTextEditing.stopEditing();
+ //DE_cur_ed_shape.toFront();
+ //DE_cur_ed.toBack();
+ DE_cur_ed_shape.animate({width:DE_cur_ed.getBBox().width+(DE_ui_margin-DE_ui_padding)},50);
+ setTimeout(function(){DE_snap_to_grid(true);},125);
+ DE_edit_mode = false;
+ } else { // input
+ DE_cur_ed_shape.animate({width:(this.value.length*DE_ui_font_width)+2*DE_ui_font_width+2*DE_ui_padding},25);
+ setTimeout(function(){
+ DE_snap_to_grid(true);
+ DE_paper.setSize(DE_paper.width+DE_ui_font_width, DE_paper.height);
+ },25);
}
- DE_rm_mult = [];
- }
-});
+ });
+ input.addEventListener("blur", function(e) {
+ DE_cur_ed.inlineTextEditing.stopEditing();
+ //DE_cur_ed_shape.toFront();
+ //DE_cur_ed.toBack();
+ DE_cur_ed_shape.animate({width:DE_cur_ed.getBBox().width+(DE_ui_margin-DE_ui_padding)},125);
+ //setTimeout(function(){DE_snap_to_grid(true);},125);
+ DE_edit_mode = false;
+ }, true);
+}
/******************************************************************************
*
@@ -647,7 +923,7 @@ var DE_extract_data = function ()
d = {};
d["source"] = [];
d["target"] = [];
- d["align"] = [];
+ d["align"] = [];
// target
var ids = [];
DE_target_shapes.sort(function(a, b) {
@@ -713,6 +989,11 @@ var DE_reset = function()
DE_cur_ed_shape = null;
DE_connect_mode = false;
DE_connect_mode_shape = null;
+ DE_kbd_focused_phrase = null;
+ DE_kbd_move_mode = false;
+ DE_kbd_select_mode = false;
+ DE_target_done = [];
+ DE_locked = false;
document.getElementById("holder").parentElement.removeChild(
document.getElementById("holder")
@@ -743,8 +1024,12 @@ var DE_init = function ()
d += DE_data_target[i].length;
}
DE_ui_font_width = DE_paper.text(-100,-100,"a").getBBox().width;
- var avg_box_len = (Math.max(c,d)/Math.max(DE_data_source.length,DE_data_target.length))*DE_ui_font_width;
- var paper_width = DE_ui_xbegin+(Math.max(DE_data_source.length,DE_data_target.length)*(DE_ui_margin+DE_ui_padding+avg_box_len)),
+ var avg_box_len = (Math.max(c,d)
+ / Math.max(DE_data_source.length,DE_data_target.length))*DE_ui_font_width;
+ var paper_width = DE_ui_xbegin+(Math.max(
+ DE_data_source.length,
+ DE_data_target.length)
+ * (DE_ui_margin+DE_ui_padding+avg_box_len)),
paper_height = DE_ui_ybegin+2*DE_ui_box_height+DE_ui_line_margin;
DE_paper.setSize(paper_width, paper_height);
@@ -754,5 +1039,242 @@ var DE_init = function ()
DE_make_objs(DE_data_target, "target");
// initial connections from alignment
DE_make_conns_from_a(DE_data_align);
+
+ // kbd interace
+ DE_kbd_start_interface();
+}
+
+/******************************************************************************
+ * keyboard interface
+ *
+ */
+document.onkeypress = function (e) {
+ if (DE_locked) return;
+ if (DE_edit_mode) return;
+
+ e = e || window.event;
+ var char_code = e.which || e.keyCode;
+ var char_str = String.fromCharCode(char_code);
+
+ if (char_str == "X"
+ && !DE_edit_mode
+ && DE_kbd_focused_phrase
+ && DE_rm_mult.indexOf(DE_kbd_focused_phrase)==-1) {
+ if (DE_target_done.indexOf(DE_kbd_focused_phrase)>-1) {
+ DE_target_done.splice(DE_target_done.indexOf(DE_kbd_focused_phrase),1);
+ } else {
+ DE_target_done.push(DE_kbd_focused_phrase);
+ DE_kbd_move_mode = false;
+ DE_kbd_select_mode = true;
+ }
+ DE_ui_style_highlight(DE_kbd_focused_phrase);
+ }
+
+ if (char_str == "A") { // add
+ if (DE_target_shapes.length > 0) {
+ var x = DE_kbd_focused_phrase.attr("x")+DE_kbd_focused_phrase.attr("width")
+ +2*DE_ui_padding;
+ var new_obj = DE_make_obj(x, "", "target");
+ var new_grid = DE_kbd_focused_phrase["grid_"]+1;
+ new_obj["grid_"] = new_grid;
+ new_obj.pair["grid_"] = new_grid;
+ for (var i=0; i<DE_target_shapes.length; i++) {
+ var sh = DE_target_shapes[i];
+ if (sh!=new_obj && sh["grid_"] >=new_grid) {
+ sh["grid_"] += 1;
+ sh.pair["grid_"] += 1;
+ }
+ }
+ } else {
+ var new_obj = DE_make_obj(0, "", "target");
+ DE_kbd_focus_shape(new_obj);
+ }
+ DE_snap_to_grid(true);
+ } else if (char_str == "M") { // move mode
+ if (DE_kbd_move_mode) {
+ DE_kbd_move_mode = false;
+ DE_kbd_select_mode = true;
+ } else {
+ if (DE_target_done.indexOf(DE_kbd_focused_phrase)>-1) return;
+ DE_kbd_move_mode = true;
+ DE_kbd_select_mode = false;
+ }
+ } else if (char_str == "E") { // edit mode
+ DE_enter_edit_mode(DE_kbd_focused_phrase, true);
+ } else if (char_str=="S") { // select mode
+ if (DE_kbd_select_mode) {
+ DE_kbd_move_mode = false;
+ } else {
+ DE_kbd_select_mode = true;
+ DE_kbd_move_mode = false;
+ }
+ } else if (char_str == "D") { // remove
+ var x = false;
+ if (DE_rm_mult.indexOf(DE_kbd_focused_phrase) > -1)
+ x = true;
+ if (DE_rm_mult.length>0) {
+ for (var i=0; i<DE_rm_mult.length; i++) {
+ rm_obj(DE_rm_mult[i]);
+ }
+ DE_rm_mult = [];
+ if (x) {
+ DE_kbd_select_mode = true;
+ DE_kbd_move_mode = false;
+ if (DE_target_shapes.length > 0)
+ DE_kbd_focus_shape(DE_target_shapes[0]);
+ }
+ } else {
+ var d = DE_kbd_focused_phrase;
+ if (DE_target_done.indexOf(d) > -1) return;
+ DE_kbd_focused_phrase = DE_kbd_get_next_to("right", DE_kbd_focused_phrase);
+ if (!DE_kbd_focused_phrase) {
+ DE_kbd_focused_phrase = DE_kbd_get_next_to("left", d);
+ }
+ DE_kbd_focus_shape(DE_kbd_focused_phrase);
+ rm_obj(d);
+ }
+ }
+
+ if (DE_kbd_select_mode && DE_kbd_focused_phrase) { // select <- ->
+ if (e.keyCode == 39) { // right
+ e.preventDefault();
+ DE_kbd_select_phrase("right", DE_kbd_focused_phrase);
+ } else if (e.keyCode == 37) { // left
+ e.preventDefault();
+ DE_kbd_select_phrase("left", DE_kbd_focused_phrase);
+ }
+ }
+
+ if (DE_kbd_move_mode && DE_kbd_focused_phrase) { // move <- ->
+ if (e.keyCode == 39) { // right
+ e.preventDefault();
+ DE_kbd_swap("right", DE_kbd_focused_phrase);
+ } else if (e.keyCode == 37) { // left
+ e.preventDefault();
+ DE_kbd_swap("left", DE_kbd_focused_phrase);
+ }
+ }
+};
+
+var DE_kbd_get_next_to = function(dir, shape)
+{
+ if (!shape) return null;
+
+ DE_target_shapes.sort(function(a, b) {
+ return a["grid_"]-b["grid_"];
+ });
+
+ for (var i=0; i<DE_target_shapes.length; i++)
+ DE_target_shapes[i]["grid_"] = i;
+
+ var grid_pos = [];
+ for (var i=0; i<DE_target_shapes.length; i++)
+ grid_pos.push(DE_target_shapes[i]["grid_"]);
+ var at = grid_pos.indexOf(shape["grid_"]);
+ if ((at==0 && dir=="left") || (at==DE_target_shapes.length-1 && dir=="right"))
+ return;
+
+ var obj = null;
+ if (dir == "left") {
+ obj = DE_target_shapes[at-1];
+ } else { // right
+ obj = DE_target_shapes[at+1];
+ }
+
+ return obj;
+}
+
+var DE_kbd_select_phrase = function(dir="right", shape)
+{
+ var obj = DE_kbd_get_next_to(dir, shape);
+
+ if (obj)
+ DE_kbd_focus_shape(obj, DE_kbd_focused_phrase);
+}
+
+var DE_kbd_focus_shape = function(obj, obj2=null)
+{
+ if (!obj) return;
+
+ // reset others
+ for (c in DE_connections)
+ DE_connections[c].line.attr({"stroke-width":DE_ui_stroke_width});
+ for (sh in DE_shapes_by_id)
+ DE_ui_style_normal(DE_shapes_by_id[sh]);
+
+ DE_kbd_focused_phrase = obj;
+
+ // style
+ DE_ui_style_highlight(obj);
+ for (c in DE_connections) {
+ if (parseInt(c.split("-")[1]) == DE_kbd_focused_phrase["id_"]) {
+ DE_connections[c].line.attr({"stroke-width":DE_ui_stroke_width_hi});
+ DE_ui_style_highlight(DE_shapes_by_id[parseInt(c.split("-")[0])], "source");
+ }
+ }
+ if (obj2)
+ DE_ui_style_normal(obj2);
+}
+
+var DE_kbd_swap = function(dir="right", shape)
+{
+ if (DE_edit_mode) return;
+ if (!shape) return;
+ if (DE_target_done.indexOf(shape)>-1) return;
+
+ DE_target_shapes.sort(function(a, b) {
+ return a["grid_"]-b["grid_"];
+ });
+ var grid_pos = [];
+ for (var i=0; i<DE_target_shapes.length; i++)
+ grid_pos.push(DE_target_shapes[i]["grid_"]);
+ var at = grid_pos.indexOf(shape["grid_"]);
+ if ((at == 0 && dir=="left") || (at == DE_target_shapes.length-1 && dir=="right"))
+ return;
+
+ var obj = null;
+ if (dir == "left") {
+ obj = DE_target_shapes[at-1];
+ } else { // right
+ obj = DE_target_shapes[at+1];
+ }
+
+ // right -> left
+ if (dir == "left") {
+ att = { x: obj.attr("x")+shape.getBBox().width+(DE_ui_margin-2*DE_ui_padding) };
+ obj.attr(att);
+ att = { x: obj.pair.attr("x")+shape.getBBox().width+(DE_ui_margin-2*DE_ui_padding) };
+ obj.pair.attr(att);
+
+ att = { x: shape.attr("x")-(obj.getBBox().width+(DE_ui_margin-2*DE_ui_padding)) };
+ shape.attr(att);
+ att = { x: shape.pair.attr("x")-(obj.getBBox().width+(DE_ui_margin-2*DE_ui_padding)) };
+ shape.pair.attr(att);
+ } else { // right
+ att = { x: obj.attr("x")-(shape.getBBox().width+(DE_ui_margin-2*DE_ui_padding)) };
+ obj.attr(att);
+ att = { x: obj.pair.attr("x")-(shape.getBBox().width+(DE_ui_margin-2*DE_ui_padding)) };
+ obj.pair.attr(att);
+
+ att = { x: shape.attr("x")+(obj.getBBox().width+(DE_ui_margin-2*DE_ui_padding)) };
+ shape.attr(att);
+ att = { x: shape.pair.attr("x")+(obj.getBBox().width+(DE_ui_margin-2*DE_ui_padding)) };
+ shape.pair.attr(att);
+ }
+
+ // grid pos
+ var tmp_pos = shape["grid_"];
+ shape["grid_"] = obj["grid_"];
+ obj["grid_"] = tmp_pos;
+
+ for (key in DE_connections) {
+ DE_paper.connection(DE_connections[key]);
+ }
+}
+
+var DE_kbd_start_interface = function ()
+{
+ DE_kbd_focus_shape(DE_target_shapes[0]);
+ DE_kbd_select_mode = true;
}
diff --git a/raphael.inline_text_editing.js b/raphael.inline_text_editing.js
index ccc37ed..ca17af0 100644
--- a/raphael.inline_text_editing.js
+++ b/raphael.inline_text_editing.js
@@ -99,7 +99,7 @@
// Prepare input styles
var oStyles = {
position: 'absolute',
- background: 'red',
+ background: 'black',
left: x-3+'px',
top: y-3+'px',
width: width+10+'px',