Commit 5505237d authored by Romain Loth's avatar Romain Loth

Merge branch 'CTRLZ' into dev + fix changeLevel CTRL+Z when doubleClick event

parents 7b837e1f ba844cc0
......@@ -169,7 +169,7 @@ TW.conf = (function(TW){
// TW.geomap = false;
// TW.twittertimeline = false;
TWConf.maxPastStates = 5 ; // number of TW.states to remember (~CTRL-Z)
TWConf.maxPastStates = 15 ; // number of TW.states to remember (~CTRL-Z)
// Layout options
......
......@@ -128,6 +128,7 @@ function SelectionEngine() {
* Main function for any selecting action
*
* @nodes: eg targeted array (only ids)
* @noState: bool flag to avoid registering new state (useful for CTRL+Z)
*
* external usage : clickHandler, search, changeType, filters, tag click...
*/
......@@ -136,12 +137,14 @@ function SelectionEngine() {
if (!args) args = {}
if (isUndef(args.nodes)) args.nodes = []
if (isUndef(args.noState)) args.noState = false
if (TW.conf.debug.logSelections) {
var tMS2_deb = performance.now()
console.log("IN SelectionEngine.MultipleSelection2:")
console.log("nodes", args.nodes)
console.log(
"IN SelectionEngine.MultipleSelection2:", args.nodes,
"noState:", args.noState
)
}
// deselects only the active ones (based on SystemState())
......@@ -318,8 +321,10 @@ function SelectionEngine() {
}
// it's a new SystemState
TW.pushGUIState( { 'sels': theSelection,
'rels': activeRelations } )
if (! args.noState) {
TW.pushGUIState( { 'sels': theSelection,
'rels': activeRelations } )
}
// we send our "gotNodeSet" event
// (signal for plugins that a search-selection was done or a new hand picked selection)
......@@ -334,7 +339,6 @@ function SelectionEngine() {
TW.partialGraph.render();
updateRelatedNodesPanel( theSelection , same, oppos )
if (TW.conf.debug.logSelections) {
......@@ -839,27 +843,34 @@ var TinaWebJS = function ( sigmacanvas ) {
}
var timeoutIdCTRLZ = window.setTimeout(function() {
// console.log("pop state")
let previousState = TW.states.pop()
if (TW.gui.selectionActive) {
deselectNodes(TW.SystemState())
TW.gui.selectionActive = false
}
console.log("pop state")
TW.states.pop()
deselectNodes(previousState)
let returningState = TW.SystemState()
if (returningState.selectionNids.length) {
TW.instance.selNgn.MultipleSelection2({nodes:returningState.selectionNids})
// restoring level (will also restore selections)
if (returningState.level != previousState.level) {
changeLevel(returningState)
}
else {
cancelSelection()
// restoring selection
if (returningState.selectionNids.length) {
TW.gui.selectionActive = true
// changes active/highlight and refresh
// POSS turn the nostate version into a select fun like deselect (ie no state, no refresh)
TW.instance.selNgn.MultipleSelection2({
nodes: returningState.selectionNids,
noState: true
})
}
else {
TW.gui.selectionActive = false
TW.partialGraph.refresh()
}
}
TW.partialGraph.refresh()
}, 100)
}
} );
......@@ -934,7 +945,7 @@ var TinaWebJS = function ( sigmacanvas ) {
// when one node and normal click
// ===============================
partialGraph.bind('clickNode', function(e) {
// console.log("clickNode event e", e.data.node)
// console.log("clickNode event e", e)
// new sigma.js gives easy access to clicked node!
var theNodeId = e.data.node.id
......@@ -948,7 +959,26 @@ var TinaWebJS = function ( sigmacanvas ) {
} )
// 2)
if(targeted.length>0) {
selInst.MultipleSelection2( {nodes:targeted} )
// we still check if the selection is unchanged before create state
let currentNids = TW.SystemState().selectionNids
let sameNids = true
if (currentNids.length != targeted.length) {
sameNids = false
}
else {
for (var j in currentNids) {
if (currentNids[j] != targeted[j]) {
sameNids = false
break
}
}
}
// iff new selection, create effects and state
if (!sameNids) {
selInst.MultipleSelection2( {nodes:targeted} )
}
}
}
// case with a selector circle cursor handled
......@@ -958,10 +988,24 @@ var TinaWebJS = function ( sigmacanvas ) {
// doubleClick creates new meso view around clicked node
partialGraph.bind('doubleClickNode', function(e) {
var theNodeId = e.data.node.id
selInst.MultipleSelection2( {nodes:[theNodeId]} )
let newZoomState = Object.assign(TW.SystemState(), {level:false})
changeLevel(newZoomState)
// /!\ doubleClick will also fire 2 singleClick events /!\
//
// https://github.com/jacomyal/sigma.js/issues/208
// https://github.com/jacomyal/sigma.js/issues/506
//
// (order: clickNode, doubleClickNode, clickNode)
// 1st 2nd (NOW) 3rd
// so if this was also a new selection, the 1st clickNode did handle it
// => we just create the new zoom level
// NB2: we never switch back to macro level from doubleClick
// A - create new zoom level state
TW.pushGUIState({ level: false })
// B - apply it without changing state
changeLevel(TW.SystemState())
})
// when click in the empty background
......
......@@ -575,18 +575,31 @@ function getNeighbors(sourceNids, relKey) {
// v
// local selection SysSt = {level: false, activetypes:XY}
//
// POSS: rewrite using .hidden instead of add/remove
//
// optional args:
// @optionalTgtState: in rare cases we already have it (like CTRL+Z)
// (=> avoid redoing property computations and state push)
// POSS: rewrite using .hidden instead of add/remove
function changeLevel(optionalTgtState) {
console.log('got optionalTgtState', optionalTgtState)
// show waiting cursor
TW.gui.elHtml.classList.add('waiting');
// let the waiting cursor appear
setTimeout(function() {
var present = TW.SystemState(); // Last
// array of nids [144, 384, 543]
let sels = optionalTgtState ? optionalTgtState.selectionNids : present.selectionNids
var sels
if (optionalTgtState) {
sels = optionalTgtState.selectionNids
}
else {
var present = TW.SystemState(); // Last
sels = present.selectionNids
deselectNodes()
}
let selsChecker = {}
for (let i in sels) {
......@@ -599,8 +612,14 @@ function changeLevel(optionalTgtState) {
// types eg [true] <=> '1'
// [true, true] <=> '1|1'
var activetypes = present.activetypes;
var activereltypes = present.activereltypes
if (optionalTgtState) {
activetypes = optionalTgtState.activetypes
activereltypes = optionalTgtState.activereltypes
}
else {
activetypes = present.activetypes;
activereltypes = present.activereltypes;
}
TW.partialGraph.graph.clear();
......@@ -677,12 +696,16 @@ function changeLevel(optionalTgtState) {
// console.log("returning to global took:", t1-t0)
}
// sels and activereltypes unchanged, no need to call MultipleSelection2
// Selection is unchanged, but all the nodes are new
// so we call MultipleSelection2 to set up node attributes
TW.instance.selNgn.MultipleSelection2({nodes:sels, noState:true});
TW.pushGUIState({
level: futurelevel,
sels: sels
})
// if caller already had the state, he may or may not want to push it
if (! optionalTgtState) {
TW.pushGUIState({
level: futurelevel
})
}
TW.partialGraph.camera.goTo({x:0, y:0, ratio:1.2, angle: 0})
TW.partialGraph.refresh()
......
......@@ -17,6 +17,8 @@ TW.pushGUIState = function( args ) {
// counter à toutes fins utiles
newState.id ++
// console.log("pushGUIState:", newState.id)
// 2) we update it with provided args
if (!isUndef(args.activetypes)) newState.activetypes = args.activetypes
if (!isUndef(args.activereltypes)) newState.activereltypes = args.activereltypes
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment