Simon Hunt

ONOS-2186 - GUI Topo Overlay - (WIP)

- added isActive() predicate to UiTopoOverlay.
- auto-select single intent in an intent selection group.
- clean up mouse over/out handling.

Change-Id: I0f951bd26fcfc791d73bb8121ebbe002086294ea
......@@ -33,6 +33,8 @@ public class UiTopoOverlay {
private final String id;
private boolean isActive = false;
/**
* Creates a new user interface topology view overlay descriptor.
*
......@@ -62,14 +64,23 @@ public class UiTopoOverlay {
* Callback invoked when this overlay is activated.
*/
public void activate() {
log.debug("Overlay '{}' Activated", id);
isActive = true;
}
/**
* Callback invoked when this overlay is deactivated.
*/
public void deactivate() {
log.debug("Overlay '{}' Deactivated", id);
isActive = false;
}
/**
* Returns true if this overlay is currently active.
*
* @return true if overlay active
*/
public boolean isActive() {
return isActive;
}
/**
......
......@@ -30,6 +30,7 @@ import static com.google.common.base.Strings.isNullOrEmpty;
*/
public class TopoOverlayCache {
private static final String EMPTY = "";
private static final UiTopoOverlay NONE = new NullOverlay();
private final Map<String, UiTopoOverlay> overlays = new HashMap<>();
......@@ -95,20 +96,21 @@ public class TopoOverlayCache {
return overlays.size();
}
/**
* Returns true if the identifier of the currently active overlay
* matches the given parameter.
*
* @param overlayId overlay identifier
* @return true if this matches the ID of currently active overlay
*/
public boolean isActive(String overlayId) {
return currentOverlay().id().equals(overlayId);
}
// overlay instance representing "no overlay selected"
private static class NullOverlay extends UiTopoOverlay {
public NullOverlay() {
super(null);
}
// override activate and deactivate, so no log messages are written
@Override
public void activate() {
}
@Override
public void deactivate() {
super(EMPTY);
}
}
}
......
......@@ -399,7 +399,9 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
.build();
intentService.submit(intent);
traffic.monitor(intent);
if (overlayCache.isActive(TrafficOverlay.TRAFFIC_ID)) {
traffic.monitor(intent);
}
}
}
......@@ -432,7 +434,9 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
.build();
intentService.submit(intent);
traffic.monitor(intent);
if (overlayCache.isActive(TrafficOverlay.TRAFFIC_ID)) {
traffic.monitor(intent);
}
}
}
......
......@@ -25,7 +25,10 @@ import org.onosproject.ui.topo.PropertyPanel;
* Topology Overlay for network traffic.
*/
public class TrafficOverlay extends UiTopoOverlay {
private static final String TRAFFIC_ID = "traffic";
/**
* Traffic Overlay identifier.
*/
public static final String TRAFFIC_ID = "traffic";
private static final String SDF_ID = "showDeviceFlows";
private static final String SRT_ID = "showRelatedTraffic";
......@@ -38,10 +41,22 @@ public class TrafficOverlay extends UiTopoOverlay {
super(TRAFFIC_ID);
}
// override activate and deactivate, to write log messages
@Override
public void activate() {
super.activate();
log.debug("TrafficOverlay Activated");
}
@Override
public void deactivate() {
super.deactivate();
log.debug("TrafficOverlay Deactivated");
}
@Override
public void modifyDeviceDetails(PropertyPanel pp) {
pp.addButton(SHOW_DEVICE_FLOWS)
.addButton(SHOW_RELATED_TRAFFIC);
}
}
......
......@@ -51,6 +51,9 @@ public class IntentSelection {
public IntentSelection(NodeSelection nodes, TopoIntentFilter filter) {
this.nodes = nodes;
intents = filter.findPathIntents(nodes.hosts(), nodes.devices());
if (intents.size() == 1) {
index = 0; // pre-select a single intent
}
}
/**
......
......@@ -229,9 +229,9 @@
tps.displaySomething();
}
// returns true if we are hovering over a node, or any nodes are selected
// returns true if one or more nodes are selected.
function somethingSelected() {
return hovered || nSel();
return nSel();
}
function clickConsumed(x) {
......
......@@ -41,13 +41,15 @@
// Helper functions
// invoked in response to change in selection and/or mouseover/out:
function requestTrafficForMode() {
function requestTrafficForMode(mouse) {
if (trafficMode === 'flows') {
requestDeviceLinkFlows();
} else if (trafficMode === 'intents') {
requestRelatedIntents();
if (!mouse || hoverMode === 'intents') {
requestRelatedIntents();
}
} else {
cancelTraffic();
// do nothing
}
}
......@@ -89,8 +91,8 @@
// === -------------------------------------------------------------
// Traffic requests invoked from keystrokes or toolbar buttons...
function cancelTraffic() {
if (!trafficMode) {
function cancelTraffic(forced) {
if (!trafficMode || (!forced && trafficMode === 'allFlowPort')) {
return false;
}
......@@ -101,15 +103,15 @@
}
function showAllFlowTraffic() {
trafficMode = 'allFlow';
hoverMode = 'all';
trafficMode = 'allFlowPort';
hoverMode = null;
wss.sendEvent('requestAllFlowTraffic');
flash.flash('All Flow Traffic');
}
function showAllPortTraffic() {
trafficMode = 'allPort';
hoverMode = 'all';
trafficMode = 'allFlowPort';
hoverMode = null;
wss.sendEvent('requestAllPortTraffic');
flash.flash('All Port Traffic');
}
......@@ -161,6 +163,8 @@
two: so[1],
ids: so
});
trafficMode = 'intents';
hoverMode = null;
flash.flash('Host-to-Host flow added');
}
......@@ -171,6 +175,8 @@
dst: so[so.length - 1],
ids: so
});
trafficMode = 'intents';
hoverMode = null;
flash.flash('Multi-Source flow added');
}
......
......@@ -45,7 +45,7 @@
},
deactivate: function () {
tts.cancelTraffic();
tts.cancelTraffic(true);
$log.debug("Traffic overlay DEACTIVATED");
},
......@@ -69,7 +69,7 @@
// NOTE: fully qual. button ID is derived from overlay-id and key-name
keyBindings: {
0: {
cb: function () { tts.cancelTraffic(); },
cb: function () { tts.cancelTraffic(true); },
tt: 'Cancel traffic monitoring',
gid: 'xMark'
},
......@@ -137,10 +137,10 @@
// mouse hooks
mouseover: function (m) {
// m has id, class, and type properties
tts.requestTrafficForMode();
tts.requestTrafficForMode(true);
},
mouseout: function () {
tts.requestTrafficForMode();
tts.requestTrafficForMode(true);
}
}
};
......