Skip to content

Commit

Permalink
multiselection with keyboard doesn't trigger activation which helps w…
Browse files Browse the repository at this point in the history
…ith performance
  • Loading branch information
zadam committed Oct 31, 2018
1 parent 63edde8 commit f06d8c7
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 54 deletions.
4 changes: 3 additions & 1 deletion src/public/javascripts/services/note_detail.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,11 @@ async function loadNoteDetail(noteId) {
return;
}

// only now that we're in sync with tree active node we will switch currentNote
currentNote = loadedNote;

refreshAttributes(); // needs to happend after loading the note itself because it references current noteId
// needs to happend after loading the note itself because it references current noteId
refreshAttributes();

if (isNewNoteCreated) {
isNewNoteCreated = false;
Expand Down
67 changes: 37 additions & 30 deletions src/public/javascripts/services/note_detail_relation_map.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ const $zoomInButton = $("#relation-map-zoom-in");
const $zoomOutButton = $("#relation-map-zoom-out");

let mapData;
let instance;
let jsPlumbInstance;
// outside of mapData because they are not persisted in the note content
let relations;
let pzInstance;

const uniDirectionalOverlays = [
[ "Arrow", {
Expand Down Expand Up @@ -95,7 +96,7 @@ async function loadNotesAndRelations() {

mapData.notes = mapData.notes.filter(note => note.id in data.noteTitles);

instance.batch(async function () {
jsPlumbInstance.batch(async function () {
for (const note of mapData.notes) {
const title = data.noteTitles[note.id];

Expand All @@ -107,7 +108,7 @@ async function loadNotesAndRelations() {
continue;
}

const connection = instance.connect({
const connection = jsPlumbInstance.connect({
source: relation.sourceNoteId,
target: relation.targetNoteId,
type: relation.type
Expand All @@ -121,63 +122,63 @@ async function loadNotesAndRelations() {
}

function initPanZoom() {
const pz = panzoom($relationMapCanvas[0], {
pzInstance = panzoom($relationMapCanvas[0], {
maxZoom: 2,
minZoom: 0.1,
smoothScroll: false
});

if (mapData.transform) {
pz.zoomTo(0, 0, mapData.transform.scale);
pz.moveTo(mapData.transform.x, mapData.transform.y);
pzInstance.zoomTo(0, 0, mapData.transform.scale);
pzInstance.moveTo(mapData.transform.x, mapData.transform.y);
}

pz.on('zoom', function (e) {
mapData.transform = pz.getTransform();
pzInstance.on('zoom', function (e) {
mapData.transform = pzInstance.getTransform();

saveData();
});

pz.on('panend', function (e) {
mapData.transform = pz.getTransform();
pzInstance.on('panend', function (e) {
mapData.transform = pzInstance.getTransform();

saveData();
}, true);

$zoomInButton.click(() => pz.zoomTo(0, 0, 1.2));
$zoomOutButton.click(() => pz.zoomTo(0, 0, 0.8));
$zoomInButton.click(() => pzInstance.zoomTo(0, 0, 1.2));
$zoomOutButton.click(() => pzInstance.zoomTo(0, 0, 0.8));
}

function cleanup() {
if (instance) {
if (jsPlumbInstance) {
// delete all endpoints and connections
instance.deleteEveryEndpoint();
jsPlumbInstance.deleteEveryEndpoint();

// without this we still end up with note boxes remaining in the canvas
$relationMapCanvas.empty();
}
}

function initJsPlumbInstance () {
if (instance) {
if (jsPlumbInstance) {
cleanup();

return;
}

instance = jsPlumb.getInstance({
jsPlumbInstance = jsPlumb.getInstance({
Endpoint: ["Dot", {radius: 2}],
Connector: "StateMachine",
ConnectionOverlays: uniDirectionalOverlays,
HoverPaintStyle: { stroke: "#777", strokeWidth: 1 },
Container: "relation-map-canvas"
});

instance.registerConnectionType("uniDirectional", { anchor:"Continuous", connector:"StateMachine", overlays: uniDirectionalOverlays });
jsPlumbInstance.registerConnectionType("uniDirectional", { anchor:"Continuous", connector:"StateMachine", overlays: uniDirectionalOverlays });

instance.registerConnectionType("biDirectional", { anchor:"Continuous", connector:"StateMachine", overlays: biDirectionalOverlays });
jsPlumbInstance.registerConnectionType("biDirectional", { anchor:"Continuous", connector:"StateMachine", overlays: biDirectionalOverlays });

instance.bind("connection", connectionCreatedHandler);
jsPlumbInstance.bind("connection", connectionCreatedHandler);

$relationMapCanvas.contextmenu({
delegate: ".note-box",
Expand All @@ -199,7 +200,7 @@ function initJsPlumbInstance () {
select: relationContextMenuHandler
});

instance.bind("contextmenu", function (c, e) {
jsPlumbInstance.bind("contextmenu", function (c, e) {
e.preventDefault();

$relationMapCanvas.contextmenuRelation("open", e, { connection: c });
Expand All @@ -221,7 +222,7 @@ async function connectionCreatedHandler(info, originalEvent) {
const name = prompt("Specify new relation name:");

if (!name || !name.trim()) {
instance.deleteConnection(connection);
jsPlumbInstance.deleteConnection(connection);

return;
}
Expand All @@ -237,7 +238,7 @@ async function connectionCreatedHandler(info, originalEvent) {
if (relationExists) {
alert("Connection '" + name + "' between these notes already exists.");

instance.deleteConnection(connection);
jsPlumbInstance.deleteConnection(connection);

return;
}
Expand All @@ -262,7 +263,7 @@ async function relationContextMenuHandler(event, ui) {

await server.remove(`notes/${relation.sourceNoteId}/relations/${relation.name}/to/${relation.targetNoteId}`);

instance.deleteConnection(connection);
jsPlumbInstance.deleteConnection(connection);

relations = relations.filter(relation => relation.attributeId !== connection.id);
}
Expand All @@ -277,7 +278,7 @@ async function noteContextMenuHandler(event, ui) {
return;
}

instance.remove(noteId);
jsPlumbInstance.remove(noteId);

mapData.notes = mapData.notes.filter(note => note.id !== noteId);

Expand Down Expand Up @@ -314,9 +315,9 @@ async function createNoteBox(id, title, x, y) {
.css("left", x + "px")
.css("top", y + "px");

instance.getContainer().appendChild($noteBox[0]);
jsPlumbInstance.getContainer().appendChild($noteBox[0]);

instance.draggable($noteBox[0], {
jsPlumbInstance.draggable($noteBox[0], {
start:function(params) {},
drag:function(params) {},
stop:function(params) {
Expand All @@ -333,7 +334,7 @@ async function createNoteBox(id, title, x, y) {
}
});

instance.makeSource($noteBox[0], {
jsPlumbInstance.makeSource($noteBox[0], {
filter: ".endpoint",
anchor: "Continuous",
connectorStyle: { stroke: "#000", strokeWidth: 1 },
Expand All @@ -343,7 +344,7 @@ async function createNoteBox(id, title, x, y) {
}
});

instance.makeTarget($noteBox[0], {
jsPlumbInstance.makeTarget($noteBox[0], {
dropOptions: { hoverClass: "dragHover" },
anchor: "Continuous",
allowLoopback: true
Expand Down Expand Up @@ -385,11 +386,13 @@ $addChildNotesButton.click(async () => {
saveData();

// delete all endpoints and connections
instance.deleteEveryEndpoint();
jsPlumbInstance.deleteEveryEndpoint();

await loadNotesAndRelations();
});

let clipboard = null;

$createChildNote.click(async () => {
const title = prompt("Enter title of new note", "new note");

Expand All @@ -410,9 +413,13 @@ $createChildNote.click(async () => {

mapData.notes.push({ id: note.noteId, x, y });

await createNoteBox(note.noteId, title, x, y);
clipboard = { id: note.noteId, title };

// await createNoteBox(note.noteId, title, x, y);
});



export default {
show,
getContent: () => JSON.stringify(mapData),
Expand Down
9 changes: 9 additions & 0 deletions src/public/javascripts/services/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ const $notePathCount = $("#note-path-count");

let startNotePath = null;

// focused & not active node can happen during multiselection where the node is selected but not activated
// (its content is not displayed in the detail)
function getFocusedNode() {
const tree = $tree.fancytree("getTree");

return tree.getFocusNode();
}

// note that if you want to access data like noteId or isProtected, you need to go into "data" property
function getCurrentNode() {
return $tree.fancytree("getActiveNode");
Expand Down Expand Up @@ -615,6 +623,7 @@ export default {
setProtected,
expandToNote,
activateNote,
getFocusedNode,
getCurrentNode,
getCurrentNotePath,
setCurrentNotePathToHash,
Expand Down
16 changes: 10 additions & 6 deletions src/public/javascripts/services/tree_keybindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ const keyBindings = {

return false;
},
"shift+up": node => {
node.navigate($.ui.keyCode.UP, true).then(() => {
const currentNode = treeService.getCurrentNode();
"shift+up": () => {
const node = treeService.getFocusedNode();

node.navigate($.ui.keyCode.UP, false).then(() => {
const currentNode = treeService.getFocusedNode();

if (currentNode.isSelected()) {
node.setSelected(false);
Expand All @@ -53,9 +55,11 @@ const keyBindings = {

return false;
},
"shift+down": node => {
node.navigate($.ui.keyCode.DOWN, true).then(() => {
const currentNode = treeService.getCurrentNode();
"shift+down": () => {
const node = treeService.getFocusedNode();

node.navigate($.ui.keyCode.DOWN, false).then(() => {
const currentNode = treeService.getFocusedNode();

if (currentNode.isSelected()) {
node.setSelected(false);
Expand Down
Loading

0 comments on commit f06d8c7

Please sign in to comment.