GUI2 Command to Unpin or Freeze selected or all nodes

Change-Id: I4f0494a3fadc04dd09afbd096ea1f0d4f73d5c4f
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.ts
index 10bc846..601159d 100644
--- a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.ts
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/topology/topology.component.ts
@@ -84,6 +84,7 @@
 const PREF_PORTHL = 'porthl';
 const PREF_SUMMARY = 'summary';
 const PREF_TOOLBAR = 'toolbar';
+const PREF_PINNED = 'pinned';
 
 /**
  * Model of the topo2_prefs object - this is a subset of the overall Prefs returned
@@ -103,6 +104,7 @@
     summary: number;
     toolbar: number;
     grid: number;
+    pinned: number;
 }
 
 /**
@@ -402,7 +404,7 @@
             P: [(token) => {this.togglePorts(token); }, 'Toggle Port Highlighting'],
             Q: [() => {this.cycleGridDisplay(); }, 'Cycle grid display'],
             R: [() => {this.resetZoom(); }, 'Reset pan / zoom'],
-            U: [() => {this.unpinNode(); }, 'Unpin node (mouse over)'],
+            U: [() => {this.unpinOrFreezeNodes(); }, 'Unpin or freeze nodes'],
             X: [() => {this.resetNodeLocation(); }, 'Reset Node Location'],
             dot: [() => {this.toggleToolbar(); }, 'Toggle Toolbar'],
             0: [() => {this.cancelTraffic(); }, 'Cancel traffic monitoring'],
@@ -602,16 +604,30 @@
         this.log.debug('equalizing masters');
     }
 
+    /**
+     * If any nodes with fixed positions had been dragged out of place
+     * then put back where they belong
+     * If there are some devices selected reset only these
+     */
     protected resetNodeLocation() {
-        // TODO: Implement reset locations
-        this.force.resetNodeLocations();
-        this.flashMsg = this.lionFn('fl_reset_node_locations');
-        this.log.debug('resetting node location');
+        const numNodes = this.force.resetNodeLocations();
+        this.flashMsg = this.lionFn('fl_reset_node_locations') +
+            '(' + String(numNodes) + ')';
+        this.log.debug('resetting ', numNodes, 'node(s) location');
     }
 
-    protected unpinNode() {
-        // TODO: Implement this
-        this.log.debug('unpinning node');
+    /**
+     * Toggle floating nodes between pinned and frozen
+     * If there are floating nodes selected toggle only these
+     */
+    protected unpinOrFreezeNodes() {
+        const pinned: boolean = !Boolean(this.prefsState.pinned);
+        const numNodes = this.force.unpinOrFreezeNodes(pinned);
+        this.flashMsg = this.lionFn(pinned ?
+            'fl_pinned_floating_nodes' : 'fl_unpinned_floating_nodes') +
+            '(' + String(numNodes) + ')';
+        this.updatePrefsState(PREF_PINNED, pinned ? 1 : 0);
+        this.log.debug('Toggling pinning for floating ', numNodes, 'nodes', pinned);
     }
 
     /**