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){ ...@@ -169,7 +169,7 @@ TW.conf = (function(TW){
// TW.geomap = false; // TW.geomap = false;
// TW.twittertimeline = 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 // Layout options
......
...@@ -128,6 +128,7 @@ function SelectionEngine() { ...@@ -128,6 +128,7 @@ function SelectionEngine() {
* Main function for any selecting action * Main function for any selecting action
* *
* @nodes: eg targeted array (only ids) * @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... * external usage : clickHandler, search, changeType, filters, tag click...
*/ */
...@@ -136,12 +137,14 @@ function SelectionEngine() { ...@@ -136,12 +137,14 @@ function SelectionEngine() {
if (!args) args = {} if (!args) args = {}
if (isUndef(args.nodes)) args.nodes = [] if (isUndef(args.nodes)) args.nodes = []
if (isUndef(args.noState)) args.noState = false
if (TW.conf.debug.logSelections) { if (TW.conf.debug.logSelections) {
var tMS2_deb = performance.now() var tMS2_deb = performance.now()
console.log(
console.log("IN SelectionEngine.MultipleSelection2:") "IN SelectionEngine.MultipleSelection2:", args.nodes,
console.log("nodes", args.nodes) "noState:", args.noState
)
} }
// deselects only the active ones (based on SystemState()) // deselects only the active ones (based on SystemState())
...@@ -318,8 +321,10 @@ function SelectionEngine() { ...@@ -318,8 +321,10 @@ function SelectionEngine() {
} }
// it's a new SystemState // it's a new SystemState
if (! args.noState) {
TW.pushGUIState( { 'sels': theSelection, TW.pushGUIState( { 'sels': theSelection,
'rels': activeRelations } ) 'rels': activeRelations } )
}
// we send our "gotNodeSet" event // we send our "gotNodeSet" event
// (signal for plugins that a search-selection was done or a new hand picked selection) // (signal for plugins that a search-selection was done or a new hand picked selection)
...@@ -334,7 +339,6 @@ function SelectionEngine() { ...@@ -334,7 +339,6 @@ function SelectionEngine() {
TW.partialGraph.render(); TW.partialGraph.render();
updateRelatedNodesPanel( theSelection , same, oppos ) updateRelatedNodesPanel( theSelection , same, oppos )
if (TW.conf.debug.logSelections) { if (TW.conf.debug.logSelections) {
...@@ -839,27 +843,34 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -839,27 +843,34 @@ var TinaWebJS = function ( sigmacanvas ) {
} }
var timeoutIdCTRLZ = window.setTimeout(function() { var timeoutIdCTRLZ = window.setTimeout(function() {
// console.log("pop state")
let previousState = TW.states.pop()
if (TW.gui.selectionActive) { deselectNodes(previousState)
deselectNodes(TW.SystemState())
TW.gui.selectionActive = false
}
console.log("pop state")
TW.states.pop()
let returningState = TW.SystemState() 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 { 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) }, 100)
} }
} ); } );
...@@ -934,7 +945,7 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -934,7 +945,7 @@ var TinaWebJS = function ( sigmacanvas ) {
// when one node and normal click // when one node and normal click
// =============================== // ===============================
partialGraph.bind('clickNode', function(e) { 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! // new sigma.js gives easy access to clicked node!
var theNodeId = e.data.node.id var theNodeId = e.data.node.id
...@@ -948,9 +959,28 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -948,9 +959,28 @@ var TinaWebJS = function ( sigmacanvas ) {
} ) } )
// 2) // 2)
if(targeted.length>0) { if(targeted.length>0) {
// 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} ) selInst.MultipleSelection2( {nodes:targeted} )
} }
} }
}
// case with a selector circle cursor handled // case with a selector circle cursor handled
// just before, at click event // just before, at click event
}) })
...@@ -958,10 +988,24 @@ var TinaWebJS = function ( sigmacanvas ) { ...@@ -958,10 +988,24 @@ var TinaWebJS = function ( sigmacanvas ) {
// doubleClick creates new meso view around clicked node // doubleClick creates new meso view around clicked node
partialGraph.bind('doubleClickNode', function(e) { partialGraph.bind('doubleClickNode', function(e) {
var theNodeId = e.data.node.id // /!\ doubleClick will also fire 2 singleClick events /!\
selInst.MultipleSelection2( {nodes:[theNodeId]} ) //
let newZoomState = Object.assign(TW.SystemState(), {level:false}) // https://github.com/jacomyal/sigma.js/issues/208
changeLevel(newZoomState) // 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 // when click in the empty background
......
...@@ -575,18 +575,31 @@ function getNeighbors(sourceNids, relKey) { ...@@ -575,18 +575,31 @@ function getNeighbors(sourceNids, relKey) {
// v // v
// local selection SysSt = {level: false, activetypes:XY} // local selection SysSt = {level: false, activetypes:XY}
// //
// 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 // POSS: rewrite using .hidden instead of add/remove
//
function changeLevel(optionalTgtState) { function changeLevel(optionalTgtState) {
console.log('got optionalTgtState', optionalTgtState)
// show waiting cursor // show waiting cursor
TW.gui.elHtml.classList.add('waiting'); TW.gui.elHtml.classList.add('waiting');
// let the waiting cursor appear // let the waiting cursor appear
setTimeout(function() { setTimeout(function() {
var present = TW.SystemState(); // Last
// array of nids [144, 384, 543] // 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 = {} let selsChecker = {}
for (let i in sels) { for (let i in sels) {
...@@ -599,8 +612,14 @@ function changeLevel(optionalTgtState) { ...@@ -599,8 +612,14 @@ function changeLevel(optionalTgtState) {
// types eg [true] <=> '1' // types eg [true] <=> '1'
// [true, true] <=> '1|1' // [true, true] <=> '1|1'
var activetypes = present.activetypes; if (optionalTgtState) {
var activereltypes = present.activereltypes activetypes = optionalTgtState.activetypes
activereltypes = optionalTgtState.activereltypes
}
else {
activetypes = present.activetypes;
activereltypes = present.activereltypes;
}
TW.partialGraph.graph.clear(); TW.partialGraph.graph.clear();
...@@ -677,12 +696,16 @@ function changeLevel(optionalTgtState) { ...@@ -677,12 +696,16 @@ function changeLevel(optionalTgtState) {
// console.log("returning to global took:", t1-t0) // 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});
// if caller already had the state, he may or may not want to push it
if (! optionalTgtState) {
TW.pushGUIState({ TW.pushGUIState({
level: futurelevel, level: futurelevel
sels: sels
}) })
}
TW.partialGraph.camera.goTo({x:0, y:0, ratio:1.2, angle: 0}) TW.partialGraph.camera.goTo({x:0, y:0, ratio:1.2, angle: 0})
TW.partialGraph.refresh() TW.partialGraph.refresh()
......
...@@ -17,6 +17,8 @@ TW.pushGUIState = function( args ) { ...@@ -17,6 +17,8 @@ TW.pushGUIState = function( args ) {
// counter à toutes fins utiles // counter à toutes fins utiles
newState.id ++ newState.id ++
// console.log("pushGUIState:", newState.id)
// 2) we update it with provided args // 2) we update it with provided args
if (!isUndef(args.activetypes)) newState.activetypes = args.activetypes if (!isUndef(args.activetypes)) newState.activetypes = args.activetypes
if (!isUndef(args.activereltypes)) newState.activereltypes = args.activereltypes 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