Use only 'stableId' to identify Layer/WindowState

The RectsComponent and TreeComponent used to rely on the `id` property
instead of `stableId` to identify elements of type Layer/WIndowState.
This created issues in cases where an element doesn't provide an `id`,
e.g. root layer.

Fix: b/263554032
Test: npm run build:all && npm run test:all
Change-Id: If296baa5402b100f67f5326a065ef569aaf2b842
This commit is contained in:
Kean Mariotti
2022-12-22 14:14:59 +00:00
parent 653c91a241
commit 70945707bd
10 changed files with 41 additions and 40 deletions

View File

@@ -24,7 +24,7 @@ export interface Rectangle {
isVisible: boolean;
isDisplay: boolean;
ref: any;
id: number;
id: string;
displayId: number;
isVirtual: boolean;
isClickable: boolean;

View File

@@ -85,7 +85,7 @@ export class UiTreeUtils
}
public static isHighlighted(item: UiTreeNode, highlightedItems: Array<string>) {
return item instanceof HierarchyTreeNode && highlightedItems.includes(`${item.id}`);
return item instanceof HierarchyTreeNode && highlightedItems.includes(`${item.stableId}`);
}
public static isVisibleNode(kind: string, type?: string) {

View File

@@ -241,7 +241,7 @@ export class Canvas {
mesh.position.x = rect.center.x;
mesh.position.y = rect.center.y;
mesh.position.z = rect.center.z;
mesh.name = `${rect.id}`;
mesh.name = rect.id;
return mesh;
}
@@ -266,13 +266,13 @@ export class Canvas {
return mesh;
}
private propagateUpdateHighlightedItems(event: MouseEvent, newId: number) {
private propagateUpdateHighlightedItems(event: MouseEvent, newId: string) {
event.preventDefault();
const highlightedChangeEvent: CustomEvent = new CustomEvent(
ViewerEvents.HighlightedChange,
{
bubbles: true,
detail: { id: `${newId}` }
detail: { id: newId }
});
event.target?.dispatchEvent(highlightedChangeEvent);
}

View File

@@ -39,7 +39,7 @@ class Mapper3D {
private static readonly ZOOM_FACTOR_STEP = 0.2;
private rects: Rectangle[] = [];
private highlightedRectIds: number[] = [];
private highlightedRectIds: string[] = [];
private cameraRotationFactor = Mapper3D.CAMERA_ROTATION_FACTOR_INIT;
private zSpacingFactor = Mapper3D.Z_SPACING_FACTOR_INIT;
private zoomFactor = Mapper3D.ZOOM_FACTOR_INIT;
@@ -52,7 +52,7 @@ class Mapper3D {
this.rects = rects;
}
setHighlightedRectIds(ids: number[]) {
setHighlightedRectIds(ids: string[]) {
this.highlightedRectIds = ids;
}
@@ -297,7 +297,7 @@ class Mapper3D {
})
];
let maxIndex = 0;
for (var i = 1; i < lineStarts.length; i++) {
for (let i = 1; i < lineStarts.length; i++) {
if (lineStarts[i].x > lineStarts[maxIndex].x) {
maxIndex = i;
}

View File

@@ -15,6 +15,7 @@
*/
import { CommonModule } from "@angular/common";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { Rectangle } from "viewers/common/rectangle";
import { RectsComponent } from "viewers/components/rects/rects.component";
import { MatCheckboxModule } from "@angular/material/checkbox";
import { MatDividerModule } from "@angular/material/divider";
@@ -69,7 +70,7 @@ describe("RectsComponent", () => {
it("draws scene when input data changes", async () => {
spyOn(Canvas.prototype, "draw").and.callThrough();
const inputRect = {
const inputRect: Rectangle = {
topLeft: {x:0, y:0},
bottomRight: {x:1, y:-1},
label: "rectangle1",
@@ -88,7 +89,7 @@ describe("RectsComponent", () => {
isVisible: true,
isDisplay: false,
ref: null,
id: 12345,
id: "test-id-1234",
displayId: 0,
isVirtual: false,
isClickable: false

View File

@@ -190,15 +190,15 @@ export class RectsComponent implements OnInit, OnDestroy {
}
}
@Input() set highlightedItems(ids: string[]) {
this.internalHighlightedItems = ids.map(id => Number(id));
@Input() set highlightedItems(stableIds: string[]) {
this.internalHighlightedItems = stableIds;
this.mapper3d.setHighlightedRectIds(this.internalHighlightedItems);
this.drawScene();
}
private internalRects: Rectangle[] = [];
private internalDisplayIds: number[] = [];
private internalHighlightedItems: number[] = [];
private internalHighlightedItems: string[] = [];
private mapper3d: Mapper3D;
private canvas?: Canvas;

View File

@@ -34,7 +34,7 @@ export interface Box3D {
}
export interface Rect3D {
id: number;
id: string;
center: Point3D;
width: number;
height: number;
@@ -65,7 +65,7 @@ export interface Label3D {
textCenter: Point3D;
text: string;
isHighlighted: boolean;
rectId: number;
rectId: string;
}
export interface Circle3D {

View File

@@ -147,8 +147,8 @@ export class TreeComponent {
return;
}
if (!this.isLeaf(this.item) && event.detail % 2 === 0) {
// Double click collapsable node
const isDoubleClick = event.detail % 2 === 0;
if (!this.isLeaf(this.item) && isDoubleClick) {
event.preventDefault();
this.toggleTree();
} else {
@@ -167,10 +167,10 @@ export class TreeComponent {
private updateHighlightedItems() {
if (this.item instanceof HierarchyTreeNode) {
if (this.item && this.item.id) {
this.highlightedItemChange.emit(`${this.item.id}`);
} else if (!this.item.id) {
this.selectedTreeChange.emit(this.item);
if (this.item.stableId) {
this.highlightedItemChange.emit(`${this.item.stableId}`);
} else if (!this.item.stableId) {
//this.selectedTreeChange.emit(this.item);
}
}
}

View File

@@ -107,11 +107,11 @@ export class Presenter {
private generateRects(): Rectangle[] {
const displayRects = this.entry.displays.map((display: any) => {
const rect = display.layerStackSpace;
rect.label = `Display`;
rect.label = "Display";
if (display.name) {
rect.label += ` - ${display.name}`;
}
rect.id = display.id;
rect.stableId = `Display - ${display.id}`;
rect.displayId = display.layerStackId;
rect.isDisplay = true;
rect.isVirtual = display.isVirtual ?? false;
@@ -122,18 +122,7 @@ export class Presenter {
}) ?? [];
this.displayIds = [];
const rects = this.getLayersForRectsView()
.sort((layer1: any, layer2: any) => {
const absZLayer1 = layer1.zOrderPath;
const absZLayer2 = layer2.zOrderPath;
let elA, elB, i, len;
for (i = 0, len = Math.min(absZLayer1.length, absZLayer2.length); i < len; i++) {
elA = absZLayer1[i];
elB = absZLayer2[i];
if (elA > elB) return -1;
if (elA < elB) return 1;
}
return absZLayer2.length - absZLayer1.length;
})
.sort(this.compareLayerZ)
.map((it: any) => {
const rect = it.rect;
rect.displayId = it.stackId;
@@ -156,6 +145,17 @@ export class Presenter {
.filter((it: any) => it.isVisible || (!onlyVisible && it.occludedBy.length > 0));
}
private compareLayerZ(a: Layer, b: Layer): number {
const zipLength = Math.min(a.zOrderPath.length, b.zOrderPath.length);
for (let i = 0; i < zipLength; ++i) {
const zOrderA = a.zOrderPath[i];
const zOrderB = b.zOrderPath[i];
if (zOrderA > zOrderB) return -1;
if (zOrderA < zOrderB) return 1;
}
return b.zOrderPath.length - a.zOrderPath.length;
}
private updateSelectedTreeUiData() {
if (this.selectedHierarchyTree) {
this.uiData.propertiesTree = this.getTreeWithTransformedProperties(this.selectedHierarchyTree);
@@ -221,7 +221,7 @@ export class Presenter {
isVisible: rect.ref?.isVisible ?? false,
isDisplay: rect.isDisplay ?? false,
ref: rect.ref,
id: rect.id ?? rect.ref.id,
id: rect.stableId ?? rect.ref.stableId,
displayId: rect.displayId ?? rect.ref.stackId,
isVirtual: rect.isVirtual ?? false,
isClickable: !(rect.isDisplay ?? false)

View File

@@ -106,17 +106,17 @@ export class Presenter {
}
private generateRects(): Rectangle[] {
const displayRects = this.entry?.displays?.map((display: DisplayContent) => {
const displayRects: Rectangle[] = this.entry?.displays?.map((display: DisplayContent) => {
const rect = display.displayRect;
rect.label = `Display - ${display.title}`;
rect.id = display.layerId;
rect.stableId = display.stableId;
rect.displayId = display.id;
rect.isDisplay = true;
rect.isVirtual = false;
return rect;
}) ?? [];
this.displayIds = [];
const rects = this.entry?.windowStates
const rects: Rectangle[] = this.entry?.windowStates
?.sort((a: any, b: any) => b.computedZ - a.computedZ)
.map((it: any) => {
const rect = it.rect;
@@ -185,7 +185,7 @@ export class Presenter {
isVisible: rect.ref?.isVisible ?? false,
isDisplay: rect.isDisplay ?? false,
ref: rect.ref,
id: rect.id ?? rect.ref.id,
id: rect.stableId ?? rect.ref.stableId,
displayId: rect.displayId ?? rect.ref.stackId,
isVirtual: rect.isVirtual ?? false,
isClickable: !rect.isDisplay,