diff --git a/cli/src/main/java/org/onosproject/cli/net/LayoutAddCommand.java b/cli/src/main/java/org/onosproject/cli/net/LayoutAddCommand.java index dd47e01364..5b1604e404 100644 --- a/cli/src/main/java/org/onosproject/cli/net/LayoutAddCommand.java +++ b/cli/src/main/java/org/onosproject/cli/net/LayoutAddCommand.java @@ -29,6 +29,17 @@ import static org.onosproject.ui.model.topo.UiTopoLayoutId.layoutId; /** * Add a new UI layout. + *

+ *

+ * layout-add {layout-id} {bg-ref} \
+ *   [ {region-id} {parent-layout-id} {scale} {offset-x} {offset-y} ]
+ * 
+ * Note that if you want to skip a parameter, but set later parameters, + * use dot (".") as a placeholder for null. For example, no associated region + * or parent layout, but setting the scale and offset for the root layout... + *
+ * layout-add root @bayareaGEO . . 1.2 0.0 -4.0
+ * 
*/ @Command(scope = "onos", name = "layout-add", description = "Adds a new UI layout.") @@ -36,8 +47,14 @@ public class LayoutAddCommand extends AbstractShellCommand { private static final char CODE_GEO = '@'; private static final char CODE_GRID = '+'; + + private static final String NULL_TOKEN = "."; private static final String ROOT = "root"; + private static final double DEFAULT_SCALE = 1.0; + private static final double DEFAULT_OFFSET = 0.0; + + @Argument(index = 0, name = "id", description = "Layout ID", required = true, multiValued = false) String id = null; @@ -54,6 +71,18 @@ public class LayoutAddCommand extends AbstractShellCommand { required = false, multiValued = false) String parentId = null; + @Argument(index = 4, name = "scale", description = "Zoom scale (optional; default 1.0)", + required = false, multiValued = false) + String zoomScale = null; + + @Argument(index = 5, name = "offx", description = "Zoom offset-X (optional; default 0.0)", + required = false, multiValued = false) + String zoomOffsetX = null; + + @Argument(index = 6, name = "offy", description = "Zoom offset-Y (optional; default 0.0)", + required = false, multiValued = false) + String zoomOffsetY = null; + private RegionService regionService; @Override @@ -61,38 +90,73 @@ public class LayoutAddCommand extends AbstractShellCommand { UiTopoLayoutService service = get(UiTopoLayoutService.class); RegionService regionService = get(RegionService.class); + UiTopoLayout layout; + if (ROOT.equals(id)) { - // set the background for the root layout - setAppropriateBackground(service.getRootLayout(), backgroundRef); + layout = service.getRootLayout(); + setAppropriateBackground(layout); + setZoomParameters(layout); return; } - Region region = regionId == null ? null : regionService.getRegion(regionId(regionId)); - UiTopoLayoutId pid = parentId == null ? UiTopoLayoutId.DEFAULT_ID : layoutId(parentId); + // Otherwise, it is a user-defined layout... - UiTopoLayout layout = new UiTopoLayout(layoutId(id)).region(region).parent(pid); - setAppropriateBackground(layout, backgroundRef); + Region region = nullToken(regionId) ? null : regionService.getRegion(regionId(regionId)); + UiTopoLayoutId pid = nullToken(parentId) ? UiTopoLayoutId.DEFAULT_ID : layoutId(parentId); + + layout = new UiTopoLayout(layoutId(id)).region(region).parent(pid); + + setAppropriateBackground(layout); + setZoomParameters(layout); service.addLayout(layout); } - private void setAppropriateBackground(UiTopoLayout layout, String bgRef) { + private boolean nullToken(String token) { + return token == null || token.equals(NULL_TOKEN); + } + + private void setAppropriateBackground(UiTopoLayout layout) { /* * A note about the format of bgref.. it should be one of: * "." - signifies no background * "@{map-id}" - signifies geo background (map) * "+{sprite-id}" - signifies grid background (sprite) * - * For example, "!", "@bayareaGEO", "+segmentRouting" + * For example, ".", "@bayareaGEO", "+segmentRouting" */ - char type = bgRef.charAt(0); + char type = backgroundRef.charAt(0); if (type == CODE_GEO) { // GEO (map) reference - layout.geomap(bgRef.substring(1)); + layout.geomap(backgroundRef.substring(1)); } else if (type == CODE_GRID) { // Grid (sprite) reference - layout.sprites(bgRef.substring(1)); + layout.sprites(backgroundRef.substring(1)); } + // simply ignore null token (".") + } + + private double parseDouble(String s, double def) { + if (nullToken(s)) { + return def; + } + + double result; + try { + result = Double.parseDouble(s); + } catch (NumberFormatException e) { + result = def; + } + + return result; + } + + private void setZoomParameters(UiTopoLayout layout) { + double scale = parseDouble(zoomScale, DEFAULT_SCALE); + double offsetX = parseDouble(zoomOffsetX, DEFAULT_OFFSET); + double offsetY = parseDouble(zoomOffsetY, DEFAULT_OFFSET); + + layout.scale(scale).offsetX(offsetX).offsetY(offsetY); } } diff --git a/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopoLayout.java b/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopoLayout.java index 45fdb80020..9c55b7db8e 100644 --- a/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopoLayout.java +++ b/core/api/src/main/java/org/onosproject/ui/model/topo/UiTopoLayout.java @@ -27,7 +27,7 @@ import static com.google.common.base.Preconditions.checkNotNull; * Represents a specific "subset" of the UI model of the network topology * that a user might wish to view. Backed by a {@link Region}. *

- * These instances include information about which geo-map (or sprite definition) + * These instances include information about which geo-map or grid-layout * should be displayed, along with zoom and offset parameters. */ public class UiTopoLayout { diff --git a/tools/test/topos/regions-bayarea-grid.sh b/tools/test/topos/regions-bayarea-grid.sh index a7a3e4a1a3..80716cf0d2 100755 --- a/tools/test/topos/regions-bayarea-grid.sh +++ b/tools/test/topos/regions-bayarea-grid.sh @@ -262,13 +262,15 @@ EOF ### Add layouts, associating backing regions, and optional parent. # -# layout-add +# layout-add \ +# [ ] +# onos ${host} <<-EOF -layout-add root @bayareaGEO +layout-add root @bayareaGEO . . 0.4 -layout-add lC01 +segmentRouting c01 +layout-add lC01 +segmentRouting c01 . 0.9 5.2 -4.0 layout-add lC02 +segmentRouting c02 layout-add lC03 +segmentRouting c03 layout-add lC04 . c04 # testing no-background