Use flex instead of fixed sizes
Bug: 251087601 Test: npm run and check scaling with different screen sizes Change-Id: I18efdd1250f0598ca2a01414dfa24e25b2bd6232
This commit is contained in:
@@ -30,7 +30,7 @@ exports.config = {
|
||||
args: ["--headless", "--disable-gpu", "--window-size=1280x1024"]
|
||||
}
|
||||
},
|
||||
chromeDriver: "./node_modules/webdriver-manager/selenium/chromedriver_105.0.5195.52",
|
||||
chromeDriver: "./node_modules/webdriver-manager/selenium/chromedriver_106.0.5249.61",
|
||||
|
||||
allScriptsTimeout: 10000,
|
||||
getPageTimeout: 10000,
|
||||
|
||||
@@ -68,7 +68,7 @@ describe("AdbProxyComponent", () => {
|
||||
it("check correct icon and message displays if unauthorised proxy", () => {
|
||||
component.proxy.setState(ProxyState.UNAUTH);
|
||||
fixture.detectChanges();
|
||||
expect(htmlElement.querySelector(".adb-info")?.innerHTML).toBe("Proxy authorisation required");
|
||||
expect(htmlElement.querySelector(".adb-info")?.innerHTML).toBe("Proxy authorisation required.");
|
||||
expect(htmlElement.querySelector(".adb-icon")?.innerHTML).toBe("lock");
|
||||
});
|
||||
|
||||
|
||||
@@ -19,52 +19,64 @@ import { proxyClient, ProxyClient, ProxyState } from "trace_collection/proxy_cli
|
||||
@Component({
|
||||
selector: "adb-proxy",
|
||||
template: `
|
||||
<div *ngIf="proxy.state===states.NO_PROXY">
|
||||
<div class="further-adb-info">
|
||||
<p>Launch the Winscope ADB Connect proxy to capture traces directly from your browser.<br/>Python 3.5+ and ADB are required.</p>
|
||||
<p>Run:<br/>python3 $ANDROID_BUILD_TOP/development/tools/winscope-ng/src/adb/winscope_proxy.py</p>
|
||||
<p>Or get it from the AOSP repository.</p>
|
||||
</div>
|
||||
<div *ngIf="proxy.state===states.NO_PROXY" class="further-adb-info">
|
||||
<p class="mat-body-1">Launch the Winscope ADB Connect proxy to capture traces directly from your browser.</p>
|
||||
<p class="mat-body-1">Python 3.5+ and ADB are required.</p>
|
||||
<p class="mat-body-1">Run: <code>python3 $ANDROID_BUILD_TOP/development/tools/winscope-ng/src/adb/winscope_proxy.py</code></p>
|
||||
<p class="mat-body-1">Or get it from the AOSP repository.</p>
|
||||
<div>
|
||||
<button mat-stroked-button (click)="downloadFromAosp()">Download from AOSP</button>
|
||||
<button mat-stroked-button class="retry" (click)="restart()">Retry</button>
|
||||
<button color="primary" mat-stroked-button (click)="downloadFromAosp()">Download from AOSP</button>
|
||||
<button color="primary" mat-stroked-button class="retry" (click)="restart()">Retry</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="proxy.state===states.INVALID_VERSION">
|
||||
<div id="icon-information">
|
||||
<div *ngIf="proxy.state===states.INVALID_VERSION" class="further-adb-info">
|
||||
<p class="icon-information mat-body-1">
|
||||
<mat-icon class="adb-icon">update</mat-icon>
|
||||
<span class="adb-info">Your local proxy version is incompatible with Winscope.</span>
|
||||
</div>
|
||||
<div class="further-adb-info">
|
||||
<p>Please update the proxy to version {{ proxyVersion }}.</p>
|
||||
<p>Run:<br/>python3 $ANDROID_BUILD_TOP/development/tools/winscope-ng/src/adb/winscope_proxy.py</p>
|
||||
<p>Or get it from the AOSP repository.</p>
|
||||
</div>
|
||||
</p>
|
||||
<p class="mat-body-1">Please update the proxy to version {{ proxyVersion }}.</p>
|
||||
<p class="mat-body-1">Run: <code>python3 $ANDROID_BUILD_TOP/development/tools/winscope-ng/src/adb/winscope_proxy.py</code></p>
|
||||
<p class="mat-body-1">Or get it from the AOSP repository.</p>
|
||||
<div>
|
||||
<button mat-stroked-button (click)="downloadFromAosp()">Download from AOSP</button>
|
||||
<button mat-stroked-button class="retry" (click)="restart()">Retry</button>
|
||||
<button color="primary" mat-stroked-button (click)="downloadFromAosp()">Download from AOSP</button>
|
||||
<button color="primary" mat-stroked-button class="retry" (click)="restart()">Retry</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="proxy.state===states.UNAUTH">
|
||||
<div id="icon-information">
|
||||
<div *ngIf="proxy.state===states.UNAUTH" class="further-adb-info">
|
||||
<p class="icon-information mat-body-1">
|
||||
<mat-icon class="adb-icon">lock</mat-icon>
|
||||
<span class="adb-info">Proxy authorisation required</span>
|
||||
</div>
|
||||
<div class="further-adb-info">
|
||||
<p>Enter Winscope proxy token:</p>
|
||||
<mat-form-field class="proxy-key-field">
|
||||
<input matInput [(ngModel)]="proxyKeyItem" name="proxy-key"/>
|
||||
</mat-form-field>
|
||||
<p>The proxy token is printed to console on proxy launch, copy and paste it above.</p>
|
||||
</div>
|
||||
<span class="adb-info">Proxy authorisation required.</span>
|
||||
</p>
|
||||
<p class="mat-body-1">Enter Winscope proxy token:</p>
|
||||
<mat-form-field class="proxy-key-field">
|
||||
<input matInput [(ngModel)]="proxyKeyItem" name="proxy-key"/>
|
||||
</mat-form-field>
|
||||
<p class="mat-body-1">The proxy token is printed to console on proxy launch, copy and paste it above.</p>
|
||||
<div>
|
||||
<button mat-stroked-button class="retry" (click)="restart()">Connect</button>
|
||||
<button color="primary" mat-stroked-button class="retry" (click)="restart()">Connect</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
styles: [".proxy-key-field {width: 30rem}"]
|
||||
styles: [
|
||||
`
|
||||
.icon-information {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.further-adb-info {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.further-adb-info p {
|
||||
margin: 10px 0;
|
||||
}
|
||||
.proxy-key-field {
|
||||
width: 30rem
|
||||
}
|
||||
`
|
||||
]
|
||||
})
|
||||
export class AdbProxyComponent {
|
||||
@Input()
|
||||
|
||||
@@ -83,7 +83,7 @@ describe("AppComponent", () => {
|
||||
component.dataLoaded = false;
|
||||
fixture.detectChanges();
|
||||
expect(htmlElement.querySelector(".welcome-info")).toBeTruthy();
|
||||
expect(htmlElement.querySelector(".viewers.hide")).toBeTruthy();
|
||||
expect(htmlElement.querySelector("#viewers")).toBeNull();
|
||||
});
|
||||
|
||||
it("displays correct elements when data loaded", async () => {
|
||||
@@ -91,6 +91,6 @@ describe("AppComponent", () => {
|
||||
fixture.detectChanges();
|
||||
expect(htmlElement.querySelector("#collect-traces-card")).toBeFalsy();
|
||||
expect(htmlElement.querySelector("#upload-traces-card")).toBeFalsy();
|
||||
expect(htmlElement.querySelector(".viewers.show")).toBeTruthy();
|
||||
expect(htmlElement.querySelector("#viewers")).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,43 +28,41 @@ import { ViewerInputMethodComponent } from "viewers/components/viewer_input_meth
|
||||
selector: "app-root",
|
||||
template: `
|
||||
<mat-toolbar class="app-toolbar">
|
||||
<span id="app-title">Winscope</span>
|
||||
<p id="app-title" class="mat-display-1">Winscope</p>
|
||||
<span class="toolbar-wrapper">
|
||||
<button mat-stroked-button *ngIf="dataLoaded" (click)="toggleTimestamp()">Start/End Timestamp</button>
|
||||
<button class="upload-new-btn" mat-stroked-button *ngIf="dataLoaded" (click)="clearData()">Upload New</button>
|
||||
<button *ngIf="dataLoaded" color="primary" mat-stroked-button (click)="toggleTimestamp()">Start/End Timestamp</button>
|
||||
<button *ngIf="dataLoaded" color="primary" mat-stroked-button (click)="clearData()">Upload New</button>
|
||||
</span>
|
||||
</mat-toolbar>
|
||||
|
||||
<div class="welcome-info" *ngIf="!dataLoaded">
|
||||
<span>Welcome to Winscope. Please select source to view traces.</span>
|
||||
</div>
|
||||
<h1 *ngIf="!dataLoaded" class="welcome-info mat-headline">Welcome to Winscope. Please select source to view traces.</h1>
|
||||
|
||||
<div *ngIf="!dataLoaded" fxLayout="row wrap" fxLayoutGap="10px grid" class="card-grid">
|
||||
<mat-card class="homepage-card" id="collect-traces-card">
|
||||
<collect-traces [traceCoordinator]="traceCoordinator" (dataLoadedChange)="onDataLoadedChange($event)"[store]="store"></collect-traces>
|
||||
<div *ngIf="!dataLoaded" class="card-grid">
|
||||
<mat-card id="collect-traces-card" class="homepage-card">
|
||||
<collect-traces [traceCoordinator]="traceCoordinator" (dataLoadedChange)="onDataLoadedChange($event)" [store]="store"></collect-traces>
|
||||
</mat-card>
|
||||
<mat-card class="homepage-card" id="upload-traces-card">
|
||||
<mat-card id="upload-traces-card" class="homepage-card">
|
||||
<upload-traces [traceCoordinator]="traceCoordinator" (dataLoadedChange)="onDataLoadedChange($event)"></upload-traces>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
||||
<div id="viewers" [class]="showViewers()">
|
||||
<trace-view
|
||||
<trace-view
|
||||
*ngIf="dataLoaded"
|
||||
id="viewers"
|
||||
[store]="store"
|
||||
[traceCoordinator]="traceCoordinator"
|
||||
></trace-view>
|
||||
</div>
|
||||
></trace-view>
|
||||
|
||||
<div id="timescrub">
|
||||
<div *ngIf="dataLoaded" id="timescrub">
|
||||
<mat-slider
|
||||
*ngIf="dataLoaded"
|
||||
color="primary"
|
||||
class="time-slider"
|
||||
step="1"
|
||||
min="0"
|
||||
[max]="this.allTimestamps.length-1"
|
||||
aria-label="units"
|
||||
[value]="currentTimestampIndex"
|
||||
(input)="updateCurrentTimestamp($event)"
|
||||
class="time-slider"
|
||||
></mat-slider>
|
||||
</div>
|
||||
<div id="timestamps">
|
||||
@@ -72,36 +70,50 @@ import { ViewerInputMethodComponent } from "viewers/components/viewer_input_meth
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
.time-slider {
|
||||
width: 100%
|
||||
}
|
||||
.upload-new-btn {
|
||||
float: right;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
}
|
||||
.app-toolbar {
|
||||
background-color: white;
|
||||
border-bottom: 1px solid var(--default-border);
|
||||
box-shadow: none;
|
||||
background-color: rgba(1, 1, 1, 0);
|
||||
height: 56px;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
#app-title {
|
||||
margin: 12px 0;
|
||||
}
|
||||
.toolbar-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
align-content: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.welcome-info {
|
||||
margin: 16px 0;
|
||||
text-align: center;
|
||||
font: inherit;
|
||||
padding: 40px;
|
||||
}
|
||||
.homepage-card {
|
||||
flex: 1;
|
||||
margin: 10px;
|
||||
overflow: auto;
|
||||
border: 1px solid var(--default-border);
|
||||
}
|
||||
|
||||
.homepage-card mat-card-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
}
|
||||
#viewers {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
}
|
||||
#timescrub {
|
||||
padding: 8px;
|
||||
border-top: 1px solid var(--default-border);
|
||||
}
|
||||
.time-slider {
|
||||
width: 100%
|
||||
}
|
||||
`
|
||||
],
|
||||
@@ -157,11 +169,6 @@ export class AppComponent {
|
||||
proxyClient.adbData = [];
|
||||
}
|
||||
|
||||
public showViewers() {
|
||||
const isShown = this.dataLoaded ? "show" : "hide";
|
||||
return `viewers ${isShown}`;
|
||||
}
|
||||
|
||||
public onDataLoadedChange(dataLoaded: boolean) {
|
||||
if (dataLoaded && !(this.traceCoordinator.getViewers().length > 0)) {
|
||||
this.allTimestamps = this.traceCoordinator.getTimestamps();
|
||||
|
||||
@@ -28,88 +28,90 @@ import { ParserErrorSnackBarComponent } from "./parser_error_snack_bar_component
|
||||
@Component({
|
||||
selector: "collect-traces",
|
||||
template: `
|
||||
<mat-card-title id="title">Collect Traces</mat-card-title>
|
||||
<mat-card-content>
|
||||
<mat-card-title id="title">Collect Traces</mat-card-title>
|
||||
<mat-card-content>
|
||||
|
||||
<div class="connecting-message" *ngIf="connect.isConnectingState()"><span>Connecting...</span></div>
|
||||
<p *ngIf="connect.isConnectingState()" class="connecting-message mat-body-1">Connecting...</p>
|
||||
|
||||
<div class="set-up-adb" *ngIf="!connect.adbSuccess()">
|
||||
<button id="proxy-tab" mat-stroked-button [ngClass]="tabClass(true)" (click)="displayAdbProxyTab()">ADB Proxy</button>
|
||||
<!-- <button id="web-tab" mat-raised-button [ngClass]="tabClass(false)" (click)="displayWebAdbTab()">Web ADB</button> -->
|
||||
<div *ngIf="!connect.adbSuccess()" class="set-up-adb">
|
||||
<button id="proxy-tab" color="primary" mat-stroked-button [ngClass]="tabClass(true)" (click)="displayAdbProxyTab()">ADB Proxy</button>
|
||||
<!-- <button id="web-tab" color="primary" mat-raised-button [ngClass]="tabClass(false)" (click)="displayWebAdbTab()">Web ADB</button> -->
|
||||
<adb-proxy *ngIf="isAdbProxy" [(proxy)]="connect.proxy!" (addKey)="onAddKey($event)"></adb-proxy>
|
||||
<!-- <web-adb *ngIf="!isAdbProxy"></web-adb> TODO: fix web adb workflow -->
|
||||
</div>
|
||||
|
||||
<div id="devices-connecting" *ngIf="connect.isDevicesState()">
|
||||
<span> {{ objectKeys(connect.devices()).length > 0 ? "Connected devices:" : "No devices detected" }}</span>
|
||||
<mat-list class="device-choice">
|
||||
<mat-list-item *ngFor="let deviceId of objectKeys(connect.devices())" (click)="connect.selectDevice(deviceId)">
|
||||
<mat-icon class="icon-message">
|
||||
{{ connect.devices()[deviceId].authorised ? "smartphone" : "screen_lock_portrait" }}
|
||||
</mat-icon>
|
||||
<span class="icon-message">
|
||||
{{ connect.devices()[deviceId].authorised ? connect.devices()[deviceId].model : "unauthorised" }} ({{ deviceId }})
|
||||
</span>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
<p class="mat-body-1"> {{ objectKeys(connect.devices()).length > 0 ? "Connected devices:" : "No devices detected" }}</p>
|
||||
<mat-list *ngIf="objectKeys(connect.devices()).length > 0">
|
||||
<mat-list-item *ngFor="let deviceId of objectKeys(connect.devices())" (click)="connect.selectDevice(deviceId)">
|
||||
<mat-icon>
|
||||
{{ connect.devices()[deviceId].authorised ? "smartphone" : "screen_lock_portrait" }}
|
||||
</mat-icon>
|
||||
{{ connect.devices()[deviceId].authorised ? connect.devices()[deviceId].model : "unauthorised" }} ({{ deviceId }})
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</div>
|
||||
|
||||
<div id="trace-collection-config" *ngIf="connect.isStartTraceState()">
|
||||
<div class="device-choice">
|
||||
<mat-list class="device-choice">
|
||||
<mat-list-item>
|
||||
<mat-icon class="icon-message">smartphone</mat-icon>
|
||||
<span class="icon-message">
|
||||
{{ connect.selectedDevice().model }} ({{ connect.selectedDeviceId() }})
|
||||
</span>
|
||||
<button class="change-btn" mat-raised-button (click)="connect.resetLastDevice()">Change device</button>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
</div>
|
||||
<mat-list>
|
||||
<mat-list-item>
|
||||
<mat-icon>smartphone</mat-icon>
|
||||
{{ connect.selectedDevice().model }} ({{ connect.selectedDeviceId() }})
|
||||
<button color="primary" class="change-btn" mat-button (click)="connect.resetLastDevice()">Change device</button>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
|
||||
<div class="trace-section">
|
||||
<trace-config
|
||||
[traces]="setTraces.DYNAMIC_TRACES"
|
||||
></trace-config>
|
||||
<button class="start-btn" mat-stroked-button (click)="startTracing()">Start trace</button>
|
||||
<trace-config [traces]="setTraces.DYNAMIC_TRACES"></trace-config>
|
||||
<button color="primary" mat-stroked-button class="start-btn" (click)="startTracing()">Start trace</button>
|
||||
</div>
|
||||
|
||||
<div class="dump-section">
|
||||
<p class="subtitle">Dump targets</p>
|
||||
<h3 class="mat-subheading-2">Dump targets</h3>
|
||||
<div class="selection">
|
||||
<mat-checkbox
|
||||
*ngFor="let dumpKey of objectKeys(setTraces.DUMPS)"
|
||||
color="primary"
|
||||
[(ngModel)]="setTraces.DUMPS[dumpKey].run"
|
||||
>{{setTraces.DUMPS[dumpKey].name}}</mat-checkbox>
|
||||
<button class="dump-btn" mat-stroked-button (click)="dumpState()">Dump state</button>
|
||||
<button color="primary" class="dump-btn" mat-stroked-button (click)="dumpState()">Dump state</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="unknown-error" *ngIf="connect.isErrorState()">
|
||||
<mat-icon class="icon-message">error</mat-icon>
|
||||
<span class="icon-message">Error:</span>
|
||||
<pre>
|
||||
{{ connect.proxy?.errorText }}
|
||||
</pre>
|
||||
<button class="retry-btn" mat-raised-button (click)="connect.restart()">Retry</button>
|
||||
<div *ngIf="connect.isErrorState()" class="unknown-error">
|
||||
<p class="error-wrapper mat-body-1">
|
||||
<mat-icon>error</mat-icon>
|
||||
Error:
|
||||
</p>
|
||||
<pre> {{ connect.proxy?.errorText }} </pre>
|
||||
<button color="primary" class="retry-btn" mat-raised-button (click)="connect.restart()">Retry</button>
|
||||
</div>
|
||||
|
||||
<div class="end-tracing" *ngIf="connect.isEndTraceState()">
|
||||
<span>Tracing...</span>
|
||||
<div *ngIf="connect.isEndTraceState()" class="end-tracing">
|
||||
<p class="mat-body-1">Tracing...</p>
|
||||
<mat-progress-bar md-indeterminate value="{{connect.loadProgress}}"></mat-progress-bar>
|
||||
<button class="end-btn" mat-raised-button (click)="endTrace()">End trace</button>
|
||||
<button color="primary" class="end-btn" mat-raised-button (click)="endTrace()">End trace</button>
|
||||
</div>
|
||||
|
||||
<div class="load-data" *ngIf="connect.isLoadDataState()">
|
||||
<span>Loading data...</span>
|
||||
<div *ngIf="connect.isLoadDataState()" class="load-data">
|
||||
<p class="mat-body-1">Loading data...</p>
|
||||
<mat-progress-bar md-indeterminate></mat-progress-bar>
|
||||
</div>
|
||||
|
||||
</mat-card-content>
|
||||
</mat-card-content>
|
||||
`,
|
||||
styles: [
|
||||
".device-choice {cursor: pointer}",
|
||||
`
|
||||
.change-btn {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.error-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
`
|
||||
]
|
||||
})
|
||||
export class CollectTracesComponent implements OnInit, OnDestroy {
|
||||
|
||||
@@ -21,15 +21,28 @@ import { ParserError, ParserErrorType } from "parsers/parser_factory";
|
||||
@Component({
|
||||
selector: "upload-snack-bar",
|
||||
template: `
|
||||
<div class="flex">
|
||||
<div class="message-wrapper">
|
||||
<p class="data" *ngFor="let msg of errorMessages">{{msg}}</p>
|
||||
</div>
|
||||
<button class="icon-button close" (click)="snackBarRef.dismiss()">
|
||||
<mat-icon class="icon-button close-snackbar">close</mat-icon>
|
||||
<div class="snack-bar-container">
|
||||
<p *ngFor="let msg of errorMessages" class="snack-bar-content mat-body-1">{{msg}}</p>
|
||||
<button color="primary" mat-button class="snack-bar-action" (click)="snackBarRef.dismiss()">
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
.snack-bar-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.snack-bar-content {
|
||||
color: white;
|
||||
}
|
||||
.snack-bar-action {
|
||||
margin-left: 12px;
|
||||
}
|
||||
`
|
||||
]
|
||||
})
|
||||
|
||||
export class ParserErrorSnackBarComponent {
|
||||
|
||||
@@ -20,57 +20,61 @@ import { EnableConfiguration, SelectionConfiguration, TraceConfiguration, TraceC
|
||||
selector: "trace-config",
|
||||
template: `
|
||||
<div class="card-block">
|
||||
<p class="subtitle">Trace targets</p>
|
||||
<ul class="checkboxes">
|
||||
<div *ngFor="let traceKey of objectKeys(traces)">
|
||||
<h3 class="mat-subheading-2">Trace targets</h3>
|
||||
<div class="checkboxes">
|
||||
<mat-checkbox
|
||||
*ngFor="let traceKey of objectKeys(traces)"
|
||||
color="primary"
|
||||
class="trace-box"
|
||||
[checked]="traces[traceKey].run"
|
||||
[indeterminate]="traces[traceKey].isTraceCollection ? someTraces(traces[traceKey]) : false"
|
||||
(change)="changeRunTrace($event.checked, traces[traceKey])"
|
||||
>{{traces[traceKey].name}}</mat-checkbox>
|
||||
</div>
|
||||
|
||||
<ng-container *ngFor="let traceKey of advancedConfigTraces()">
|
||||
<h3 class="mat-subheading-2">{{traces[traceKey].name}} configuration</h3>
|
||||
|
||||
<div *ngIf="traces[traceKey].config?.enableConfigs" class="config-opt">
|
||||
<mat-checkbox
|
||||
class="trace-box"
|
||||
[checked]="traces[traceKey].run"
|
||||
[indeterminate]="traces[traceKey].isTraceCollection ? someTraces(traces[traceKey]) : false"
|
||||
(change)="changeRunTrace($event.checked, traces[traceKey])"
|
||||
>{{traces[traceKey].name}}</mat-checkbox>
|
||||
</div>
|
||||
</ul>
|
||||
*ngFor="let enableConfig of traceEnableConfigs(traces[traceKey])"
|
||||
color="primary"
|
||||
class="enable-config"
|
||||
[disabled]="!traces[traceKey].run && !traces[traceKey].isTraceCollection"
|
||||
[(ngModel)]="enableConfig.enabled"
|
||||
(ngModelChange)="changeTraceCollectionConfig(traces[traceKey])"
|
||||
>{{enableConfig.name}}</mat-checkbox>
|
||||
|
||||
<div *ngFor="let traceKey of advancedConfigTraces()">
|
||||
<p class="subtitle">{{traces[traceKey].name}} configuration</p>
|
||||
<div>
|
||||
<div class="config-opt" *ngIf="traces[traceKey].config?.enableConfigs">
|
||||
<mat-checkbox
|
||||
*ngFor="let enableConfig of traceEnableConfigs(traces[traceKey])"
|
||||
class="enable-config"
|
||||
[disabled]="!traces[traceKey].run && !traces[traceKey].isTraceCollection"
|
||||
[(ngModel)]="enableConfig.enabled"
|
||||
(ngModelChange)="changeTraceCollectionConfig(traces[traceKey])"
|
||||
>{{enableConfig.name}}</mat-checkbox>
|
||||
|
||||
<div class="config-opt" *ngIf="traces[traceKey].config?.selectionConfigs">
|
||||
<div *ngIf="traces[traceKey].config?.selectionConfigs" class="config-opt">
|
||||
<mat-form-field
|
||||
appearance="fill"
|
||||
class="config-selection"
|
||||
*ngFor="let selectionConfig of traceSelectionConfigs(traces[traceKey])"
|
||||
><mat-label>{{selectionConfig.name}}</mat-label>
|
||||
<mat-select class="selected-value" [(value)]="selectionConfig.value" [disabled]="!traces[traceKey].run">
|
||||
<mat-option
|
||||
*ngFor="let option of selectionConfig.options"
|
||||
value="{{option}}"
|
||||
>{{ option }}</mat-option>
|
||||
</mat-select>
|
||||
*ngFor="let selectionConfig of traceSelectionConfigs(traces[traceKey])"
|
||||
class="config-selection"
|
||||
appearance="fill">
|
||||
<mat-label>{{selectionConfig.name}}</mat-label>
|
||||
<mat-select class="selected-value" [(value)]="selectionConfig.value" [disabled]="!traces[traceKey].run">
|
||||
<mat-option
|
||||
*ngFor="let option of selectionConfig.options"
|
||||
value="{{option}}"
|
||||
>{{ option }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
.checkboxes {
|
||||
columns: 3 10em;
|
||||
padding: 0;
|
||||
.card-block {
|
||||
margin: 15px;
|
||||
}
|
||||
.config-opt {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
.checkboxes {
|
||||
padding: 0;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
.config-selection {
|
||||
margin: 0 5px;
|
||||
}
|
||||
`
|
||||
]
|
||||
|
||||
@@ -27,54 +27,47 @@ import { Viewer } from "viewers/viewer";
|
||||
@Component({
|
||||
selector: "trace-view",
|
||||
template: `
|
||||
<mat-card class="trace-card">
|
||||
<mat-card-header class="trace-view-header">
|
||||
<span class="header-items-wrapper">
|
||||
<nav mat-tab-nav-bar class="viewer-nav-bar">
|
||||
<a
|
||||
mat-tab-link
|
||||
*ngFor="let tab of viewerTabs"
|
||||
[active]="isCurrentActiveCard(tab.cardId)"
|
||||
(click)="showViewer(tab.cardId)"
|
||||
class="viewer-tab"
|
||||
>{{tab.label}}</a>
|
||||
</nav>
|
||||
<button
|
||||
mat-stroked-button
|
||||
class="icon-button save-btn"
|
||||
(click)="downloadAllTraces()"
|
||||
>Download all traces</button>
|
||||
</span>
|
||||
</mat-card-header>
|
||||
<mat-card-content class="trace-view-content">
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
<div class="header-items-wrapper">
|
||||
<nav mat-tab-nav-bar class="viewer-nav-bar">
|
||||
<a
|
||||
*ngFor="let tab of viewerTabs"
|
||||
mat-tab-link
|
||||
[active]="isCurrentActiveCard(tab.cardId)"
|
||||
(click)="showViewer(tab.cardId)"
|
||||
class="viewer-tab"
|
||||
>{{tab.label}}</a>
|
||||
</nav>
|
||||
<button
|
||||
color="primary"
|
||||
mat-button
|
||||
class="save-btn"
|
||||
(click)="downloadAllTraces()"
|
||||
>Download all traces</button>
|
||||
</div>
|
||||
<div class="trace-view-content">
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
:host /deep/ .trace-view-header .mat-card-header-text {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-items-wrapper {
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.viewer-nav-bar {
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.trace-view-content {
|
||||
height: 0;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
float: right;
|
||||
vertical-align: middle;
|
||||
border: none;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
`
|
||||
]
|
||||
|
||||
@@ -24,98 +24,70 @@ import { ParserError } from "parsers/parser_factory";
|
||||
@Component({
|
||||
selector: "upload-traces",
|
||||
template: `
|
||||
<mat-card-title id="title">Upload Traces</mat-card-title>
|
||||
<mat-card-content>
|
||||
<div
|
||||
class="drop-box"
|
||||
ref="drop-box"
|
||||
(dragleave)="onFileDragOut($event)"
|
||||
(dragover)="onFileDragIn($event)"
|
||||
(drop)="onHandleFileDrop($event)"
|
||||
(click)="fileDropRef.click()"
|
||||
>
|
||||
<input
|
||||
hidden
|
||||
class="input-files"
|
||||
id="fileDropRef"
|
||||
type="file"
|
||||
(change)="onInputFile($event)"
|
||||
#fileDropRef
|
||||
multiple
|
||||
/>
|
||||
<mat-list
|
||||
class="uploaded-files"
|
||||
*ngIf="this.loadedTraces.length > 0"
|
||||
>
|
||||
<mat-list-item *ngFor="let trace of loadedTraces" class="listed-file">
|
||||
<span class="listed-file">
|
||||
<mat-icon class= "listed-file-item">{{TRACE_INFO[trace.type].icon}}</mat-icon>
|
||||
<span class="listed-file-item">{{trace.name}} ({{TRACE_INFO[trace.type].name}})</span>
|
||||
<button
|
||||
(click)="onRemoveTrace($event, trace)"
|
||||
class="icon-button close-btn listed-file-item"
|
||||
><mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</span>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
<span *ngIf="this.loadedTraces.length === 0" class="drop-info">Drag your .winscope file(s) or click to upload</span>
|
||||
</div>
|
||||
<mat-card-title id="title">Upload Traces</mat-card-title>
|
||||
<mat-card-content>
|
||||
<div
|
||||
class="drop-box"
|
||||
ref="drop-box"
|
||||
(dragleave)="onFileDragOut($event)"
|
||||
(dragover)="onFileDragIn($event)"
|
||||
(drop)="onHandleFileDrop($event)"
|
||||
(click)="fileDropRef.click()"
|
||||
>
|
||||
<input
|
||||
id="fileDropRef"
|
||||
hidden
|
||||
type="file"
|
||||
multiple
|
||||
#fileDropRef
|
||||
(change)="onInputFile($event)"
|
||||
/>
|
||||
<mat-list *ngIf="this.loadedTraces.length > 0" class="uploaded-files">
|
||||
<mat-list-item *ngFor="let trace of loadedTraces">
|
||||
<mat-icon>{{TRACE_INFO[trace.type].icon}}</mat-icon>
|
||||
{{trace.name}} ({{TRACE_INFO[trace.type].name}})
|
||||
<button
|
||||
color="primary"
|
||||
mat-icon-button
|
||||
class="close-btn"
|
||||
(click)="onRemoveTrace($event, trace)"
|
||||
><mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
<p *ngIf="this.loadedTraces.length === 0" class="drop-info mat-body-1">Drag your .winscope file(s) or click to upload</p>
|
||||
</div>
|
||||
|
||||
<div class="load-traces-btns" *ngIf="this.loadedTraces.length > 0">
|
||||
<button mat-raised-button class="load-btn" (click)="onLoadData()">View traces</button>
|
||||
<button mat-stroked-button for="fileDropRef" (click)="fileDropRef.click()">Upload another file</button>
|
||||
<button mat-stroked-button (click)="onClearData()">Clear all</button>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<div *ngIf="this.loadedTraces.length > 0">
|
||||
<button color="primary" mat-raised-button class="load-btn" (click)="onLoadData()">View traces</button>
|
||||
<button color="primary" mat-stroked-button for="fileDropRef" (click)="fileDropRef.click()">Upload another file</button>
|
||||
<button color="primary" mat-stroked-button (click)="onClearData()">Clear all</button>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
.drop-box {
|
||||
outline: 2px dashed var(--default-border);
|
||||
outline-offset: -10px;
|
||||
background: white;
|
||||
padding: 10px 10px 10px 10px;
|
||||
height: 400px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.drop-info {
|
||||
font-weight: normal;
|
||||
pointer-events: none;
|
||||
margin: auto;
|
||||
}
|
||||
#inputfile {
|
||||
margin: auto;
|
||||
outline: 2px dashed var(--default-border);
|
||||
outline-offset: -10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.uploaded-files {
|
||||
text-align: left;
|
||||
height: 400px;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
}
|
||||
.listed-file {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.listed-file-item {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
align-items: center;
|
||||
overflow: auto;
|
||||
}
|
||||
.close-btn {
|
||||
float: right;
|
||||
margin-left: auto;
|
||||
}
|
||||
.drop-info {
|
||||
pointer-events: none;
|
||||
margin: auto;
|
||||
}
|
||||
`
|
||||
]
|
||||
|
||||
@@ -18,19 +18,23 @@ import {Component} from "@angular/core";
|
||||
@Component({
|
||||
selector: "web-adb",
|
||||
template: `
|
||||
<div id="info-message">
|
||||
<p class="text-icon-wrapper mat-body-1">
|
||||
<mat-icon class="adb-icon">info</mat-icon>
|
||||
<span class="adb-info">Add new device</span>
|
||||
</div>
|
||||
<div>
|
||||
<p>Click the button below to follow instructions in the Chrome pop-up.</p>
|
||||
<p>Selecting a device will kill all existing ADB connections.</p>
|
||||
</div>
|
||||
<div>
|
||||
<button mat-raised-button>Select a device</button>
|
||||
</div>
|
||||
</p>
|
||||
<p class="mat-body-1">Click the button below to follow instructions in the Chrome pop-up.</p>
|
||||
<p class="mat-body-1">Selecting a device will kill all existing ADB connections.</p>
|
||||
<button color="primary" mat-raised-button>Select a device</button>
|
||||
`,
|
||||
styles: [".icon-message {vertical-align: middle;}"]
|
||||
styles: [
|
||||
`
|
||||
.text-icon-wrapper {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
`
|
||||
]
|
||||
})
|
||||
export class WebAdbComponent {
|
||||
adbDevice = null;
|
||||
|
||||
55
tools/winscope-ng/src/material-theme.scss
Normal file
55
tools/winscope-ng/src/material-theme.scss
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@use '@angular/material' as mat;
|
||||
|
||||
@import 'https://fonts.googleapis.com/icon?family=Material+Icons';
|
||||
@import '//fonts.googleapis.com/css2?family=Google+Sans';
|
||||
|
||||
$primary: mat.define-palette(mat.$blue-palette, 700);
|
||||
$accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
|
||||
|
||||
$typography: mat.define-typography-config(
|
||||
$font-family: 'Roboto, sans-serif'
|
||||
);
|
||||
|
||||
@include mat.core($typography);
|
||||
|
||||
$theme: mat.define-light-theme((
|
||||
color: (
|
||||
primary: $primary,
|
||||
accent: $accent,
|
||||
)
|
||||
));
|
||||
|
||||
@include mat.core-theme($theme);
|
||||
|
||||
@include mat.button-theme($theme);
|
||||
@include mat.card-theme($theme);
|
||||
@include mat.checkbox-theme($theme);
|
||||
@include mat.form-field-theme($theme);
|
||||
@include mat.grid-list-theme($theme);
|
||||
@include mat.icon-theme($theme);
|
||||
@include mat.input-theme($theme);
|
||||
@include mat.list-theme($theme);
|
||||
@include mat.progress-bar-theme($theme);
|
||||
@include mat.progress-spinner-theme($theme);
|
||||
@include mat.radio-theme($theme);
|
||||
@include mat.select-theme($theme);
|
||||
@include mat.slider-theme($theme);
|
||||
@include mat.snack-bar-theme($theme);
|
||||
@include mat.tabs-theme($theme);
|
||||
@include mat.tooltip-theme($theme);
|
||||
@include mat.toolbar-theme($theme);
|
||||
@@ -13,95 +13,46 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
|
||||
@import 'https://fonts.googleapis.com/icon?family=Material+Icons';
|
||||
@import '//fonts.googleapis.com/css2?family=Google+Sans';
|
||||
|
||||
:root {
|
||||
html {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
--default-border: #DADCE0;
|
||||
--default-blue: #1A73E8;
|
||||
}
|
||||
|
||||
:root .mat-stroked-button {
|
||||
margin: 10px;
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mat-snack-bar-container, .close-snackbar {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.mat-snack-bar-container .flex {
|
||||
display: inline-flex;
|
||||
align-items: baseline;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.mat-snack-bar-container .data {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mat-snack-bar-container .message-wrapper, .mat-snack-bar-container .close {
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#app-title {
|
||||
font-family: 'Google Sans', sans-serif;
|
||||
font-size: 30;
|
||||
}
|
||||
|
||||
#title {
|
||||
font-family: 'Google Sans', sans-serif;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.labels-canvas div {
|
||||
font-family: 'Google Sans', sans-serif;
|
||||
}
|
||||
|
||||
h1, p, span {
|
||||
font-family: 'Google Sans Text', sans-serif;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
button span {
|
||||
font-family: 'Google Sans', sans-serif;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.homepage-card {
|
||||
border: 1px solid var(--default-border);
|
||||
width: 50%;
|
||||
height: 48rem;
|
||||
display: flex;
|
||||
overflow: auto;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.homepage-card mat-card-content {
|
||||
app-root {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.trace-card {
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
border: none;
|
||||
box-shadow: none !important;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
.mat-headline, .mat-title, .mat-subheading-2, .mat-body-1, .mat-body-2, .mat-small {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button.mat-raised-button {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
button.mat-stroked-button {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
mat-checkbox {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.card-grid {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -109,159 +60,3 @@ button {
|
||||
flex-direction: row;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
mat-checkbox {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
|
||||
.mat-form-field {
|
||||
margin: 2px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.icon-message, .adb-icon, .adb-info {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.file-icon {
|
||||
vertical-align: middle;
|
||||
outline: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.card-block {
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
button.mat-raised-button {
|
||||
background-color: var(--default-blue);
|
||||
color: white;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
button.mat-raised-button span {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.tab.inactive {
|
||||
background-color:white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.input {
|
||||
opacity: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.file-input-prompt {
|
||||
color: white;
|
||||
background-color: var(--default-blue);
|
||||
border-radius: 21.5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.viewers.hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
.icon-button {
|
||||
background: none;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#trace-collection-config button {
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
color: var(--default-blue);
|
||||
}
|
||||
|
||||
.device-choice button {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.trace-section button, .dump-section button {
|
||||
border: 1px solid var(--default-border);
|
||||
}
|
||||
|
||||
/* changing colors of pre-built theme */
|
||||
.mat-accent .mat-option.mat-selected:not(.mat-option-disabled){color: var(--default-blue)}
|
||||
.mat-pseudo-checkbox-checked,.mat-pseudo-checkbox-indeterminate,.mat-accent .mat-pseudo-checkbox-checked,.mat-accent .mat-pseudo-checkbox-indeterminate{background:var(--default-blue)}
|
||||
.mat-badge-accent .mat-badge-content{background:var(--default-blue);}
|
||||
.mat-button.mat-accent,.mat-icon-button.mat-accent,.mat-stroked-button.mat-accent, .mat-stroked-button{color:var(--default-blue)}
|
||||
.mat-button.mat-accent .mat-button-focus-overlay,.mat-icon-button.mat-accent .mat-button-focus-overlay,.mat-stroked-button.mat-accent .mat-button-focus-overlay{background-color:var(--default-blue)}
|
||||
.mat-flat-button.mat-accent,.mat-raised-button.mat-accent,.mat-fab.mat-accent,.mat-mini-fab.mat-accent{background-color:var(--default-blue)}
|
||||
.mat-checkbox-checked.mat-accent .mat-checkbox-background{background-color:var(--default-blue)}
|
||||
.mat-checkbox-checked:not(.mat-checkbox-disabled).mat-accent .mat-ripple-element,.mat-checkbox:active:not(.mat-checkbox-disabled).mat-accent .mat-ripple-element{background:var(--default-blue)}
|
||||
.mat-chip.mat-standard-chip.mat-chip-selected.mat-accent{background-color:var(--default-blue);}
|
||||
.mat-datepicker-content.mat-accent .mat-calendar-body-selected{background-color:var(--default-blue);}
|
||||
.mat-datepicker-toggle-active.mat-accent{color:var(--default-blue)}
|
||||
.mat-form-field.mat-focused .mat-form-field-label.mat-accent{color:var(--default-blue)}
|
||||
.mat-focused .mat-form-field-required-marker{color:var(--default-blue)}
|
||||
.mat-form-field.mat-focused .mat-form-field-ripple.mat-accent{background-color:var(--default-blue)}
|
||||
.mat-form-field-type-mat-native-select.mat-focused:not(.mat-form-field-invalid).mat-accent .mat-form-field-infix::after{color:var(--default-blue)}
|
||||
.mat-form-field-appearance-outline.mat-focused.mat-accent .mat-form-field-outline-thick{color:var(--default-blue)}
|
||||
.mat-icon.mat-accent{color:var(--default-blue)}
|
||||
.mat-form-field.mat-accent .mat-input-element{caret-color:var(--default-blue)}
|
||||
.mat-progress-bar.mat-accent .mat-progress-bar-fill::after{background-color:var(--default-blue)}
|
||||
.mat-progress-spinner.mat-accent circle,.mat-spinner.mat-accent circle{stroke:var(--default-blue)}
|
||||
.mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:var(--default-blue)}
|
||||
.mat-radio-button.mat-accent .mat-radio-inner-circle,.mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),.mat-radio-button.mat-accent.mat-radio-checked .mat-radio-persistent-ripple,.mat-radio-button.mat-accent:active .mat-radio-persistent-ripple{background-color:var(--default-blue)}
|
||||
.mat-form-field.mat-focused.mat-accent .mat-select-arrow{color:var(--default-blue)}
|
||||
.mat-slide-toggle.mat-checked .mat-slide-toggle-thumb{background-color:var(--default-blue)}
|
||||
.mat-slide-toggle.mat-checked .mat-ripple-element{background-color:var(--default-blue)}
|
||||
.mat-slider.mat-accent .mat-slider-track-fill,.mat-slider.mat-accent .mat-slider-thumb,.mat-slider.mat-accent .mat-slider-thumb-label{background-color:var(--default-blue)}
|
||||
.mat-step-header.mat-accent .mat-step-icon-selected,.mat-step-header.mat-accent .mat-step-icon-state-done,.mat-step-header.mat-accent .mat-step-icon-state-edit{background-color:var(--default-blue);}
|
||||
.mat-tab-group.mat-accent .mat-ink-bar,.mat-tab-nav-bar.mat-accent .mat-ink-bar{background-color:var(--default-blue)}
|
||||
.mat-tab-group.mat-background-accent>.mat-tab-header,.mat-tab-group.mat-background-accent>.mat-tab-link-container,.mat-tab-group.mat-background-accent>.mat-tab-header-pagination,.mat-tab-nav-bar.mat-background-accent>.mat-tab-header,.mat-tab-nav-bar.mat-background-accent>.mat-tab-link-container,.mat-tab-nav-bar.mat-background-accent>.mat-tab-header-pagination{background-color:var(--default-blue)}
|
||||
.mat-toolbar.mat-accent{background:var(--default-blue);}
|
||||
.mat-simple-snackbar-action{color:var(--default-blue)}
|
||||
|
||||
/* changing fonts of pre-built theme */
|
||||
.mat-h1,.mat-headline,.mat-typography .mat-h1,.mat-typography .mat-headline,.mat-typography h1{font:400 24px/32px "Google Sans", sans-serif;letter-spacing:normal;margin:0 0 16px}
|
||||
.mat-h2,.mat-title,.mat-typography .mat-h2,.mat-typography .mat-title,.mat-typography h2{font:500 20px/32px "Google Sans", sans-serif;letter-spacing:normal;margin:0 0 16px}
|
||||
.mat-h3,.mat-subheading-2,.mat-typography .mat-h3,.mat-typography .mat-subheading-2,.mat-typography h3{font:400 16px/28px "Google Sans", sans-serif;letter-spacing:normal;margin:0 0 16px}
|
||||
.mat-h4,.mat-subheading-1,.mat-typography .mat-h4,.mat-typography .mat-subheading-1,.mat-typography h4{font:400 15px/24px "Google Sans", sans-serif;letter-spacing:normal;margin:0 0 16px}
|
||||
.mat-h5,.mat-typography .mat-h5,.mat-typography h5{font:400 calc(14px * 0.83)/20px "Google Sans", sans-serif;margin:0 0 12px}
|
||||
.mat-h6,.mat-typography .mat-h6,.mat-typography h6{font:400 calc(14px * 0.67)/20px "Google Sans", sans-serif;margin:0 0 12px}
|
||||
.mat-body-strong,.mat-body-2,.mat-typography .mat-body-strong,.mat-typography .mat-body-2{font:500 14px/24px "Google Sans Text", sans-serif;letter-spacing:normal}
|
||||
.mat-body,.mat-body-1,.mat-typography .mat-body,.mat-typography .mat-body-1,.mat-typography{font-family:"Google Sans Text", sans-serif;}
|
||||
.mat-small,.mat-caption,.mat-typography .mat-small,.mat-typography .mat-caption{font:400 12px/20px "Google Sans Text", sans-serif;letter-spacing:normal}
|
||||
.mat-display-4,.mat-typography .mat-display-4{font:300 112px/112px "Google Sans", sans-serif;letter-spacing:-0.05em;margin:0 0 56px}
|
||||
.mat-display-3,.mat-typography .mat-display-3{font:400 56px/56px "Google Sans", sans-serif;letter-spacing:-0.02em;margin:0 0 64px}
|
||||
.mat-display-2,.mat-typography .mat-display-2{font:400 45px/48px "Google Sans", sans-serif;letter-spacing:-0.005em;margin:0 0 64px}
|
||||
.mat-display-1,.mat-typography .mat-display-1{font:400 34px/40px "Google Sans", sans-serif;letter-spacing:normal;margin:0 0 64px}
|
||||
.mat-select-trigger{font-family:"Google Sans", sans-serif;}
|
||||
.mat-radio-button{font-family:"Google Sans", sans-serif}
|
||||
.mat-select{font-family:"Google Sans", sans-serif}
|
||||
.mat-slide-toggle-content{font-family:"Google Sans", sans-serif}
|
||||
.mat-slider-thumb-label-text{font-family:"Google Sans", sans-serif}
|
||||
.mat-stepper-vertical,.mat-stepper-horizontal{font-family:"Google Sans", sans-serif}
|
||||
.mat-tab-group{font-family:"Google Sans", sans-serif}
|
||||
.mat-tab-label,.mat-tab-link{font-family:"Google Sans", sans-serif; font-weight: 500;}
|
||||
.mat-toolbar,.mat-toolbar h1,.mat-toolbar h2,.mat-toolbar h3,.mat-toolbar h4,.mat-toolbar h5,.mat-toolbar h6{font-family:"Google Sans", sans-serif;}
|
||||
.mat-tooltip{font-family:"Google Sans", sans-serif;}
|
||||
.mat-list-item{font-family:"Google Sans", sans-serif}
|
||||
.mat-list-option{font-family:"Google Sans", sans-serif}
|
||||
.mat-list-base .mat-subheader{font-family:"Google Sans", sans-serif;}
|
||||
.mat-list-base[dense] .mat-subheader{font-family:"Google Sans", sans-serif;}
|
||||
.mat-option{font-family:"Google Sans", sans-serif;}
|
||||
.mat-optgroup-label{font-family:"Google Sans", sans-serif}
|
||||
.mat-simple-snackbar{font-family:"Google Sans", sans-serif;}
|
||||
|
||||
@@ -18,44 +18,54 @@ import { Component, Input } from "@angular/core";
|
||||
@Component({
|
||||
selector: "coordinates-table",
|
||||
template: `
|
||||
<span class="coord-null-value" *ngIf="!hasCoordinates()">null</span>
|
||||
<div class="coord-table-wrapper" *ngIf="hasCoordinates()">
|
||||
<table class="table">
|
||||
<tr class="header-row">
|
||||
<td>Left</td>
|
||||
<td>Top</td>
|
||||
<td>Right</td>
|
||||
<td>Bottom</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ coordinates.left }}</td>
|
||||
<td>{{ coordinates.top }}</td>
|
||||
<td>{{ coordinates.right }}</td>
|
||||
<td>{{ coordinates.bottom }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<p *ngIf="!hasCoordinates()" class="mat-body-1">null</p>
|
||||
<table *ngIf="hasCoordinates()" class="table">
|
||||
<tr class="header-row">
|
||||
<td>
|
||||
<p class="mat-body-1">Left</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="mat-body-1">Top</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="mat-body-1">Right</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="mat-body-1">Bottom</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p class="mat-body-1">{{ coordinates.left }}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="mat-body-1">{{ coordinates.top }}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="mat-body-1">{{ coordinates.right }}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="mat-body-1">{{ coordinates.bottom }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
.coord-null-value {
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
.table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.coord-table-wrapper {
|
||||
margin-left: 10px;
|
||||
display: inline-flex;
|
||||
padding: 3px 0px;
|
||||
.table td {
|
||||
padding: 1px 5px;
|
||||
border: 1px solid var(--default-border);
|
||||
text-align: center;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.coord-table-wrapper td, .coord-table-wrapper th {
|
||||
height: auto;
|
||||
border: 1px solid ar(--default-border);
|
||||
}
|
||||
|
||||
.coord-table-wrapper .header-row td {
|
||||
.header-row td {
|
||||
color: gray;
|
||||
font-weight: 600;
|
||||
}
|
||||
`
|
||||
],
|
||||
|
||||
@@ -25,10 +25,10 @@ import { TableProperties } from "viewers/common/table_properties";
|
||||
@Component({
|
||||
selector: "hierarchy-view",
|
||||
template: `
|
||||
<mat-card-header class="view-header">
|
||||
<div class="view-header">
|
||||
<div class="title-filter">
|
||||
<span class="hierarchy-title">Hierarchy</span>
|
||||
<mat-form-field class="filter-field">
|
||||
<h2 class="hierarchy-title mat-title">Hierarchy</h2>
|
||||
<mat-form-field>
|
||||
<mat-label>Filter...</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -40,6 +40,7 @@ import { TableProperties } from "viewers/common/table_properties";
|
||||
</div>
|
||||
<div class="view-controls">
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
*ngFor="let option of objectKeys(userOptions)"
|
||||
class="trace-box"
|
||||
[(ngModel)]="userOptions[option].enabled"
|
||||
@@ -51,7 +52,7 @@ import { TableProperties } from "viewers/common/table_properties";
|
||||
class="properties-table"
|
||||
[properties]="tableProperties"
|
||||
></properties-table>
|
||||
<div class="pinned-items" *ngIf="pinnedItems.length > 0">
|
||||
<div *ngIf="pinnedItems.length > 0" class="pinned-items">
|
||||
<tree-node
|
||||
*ngFor="let pinnedItem of pinnedItems"
|
||||
class="node"
|
||||
@@ -65,11 +66,10 @@ import { TableProperties } from "viewers/common/table_properties";
|
||||
(click)="onPinnedNodeClick($event, pinnedItem)"
|
||||
></tree-node>
|
||||
</div>
|
||||
</mat-card-header>
|
||||
<mat-card-content class="hierarchy-content" [style]="maxHierarchyHeight()">
|
||||
</div>
|
||||
<div class="hierarchy-content">
|
||||
<div class="tree-wrapper">
|
||||
<tree-view
|
||||
class="tree-view"
|
||||
*ngIf="tree"
|
||||
[isFlattened]="isFlattened()"
|
||||
[isShaded]="true"
|
||||
@@ -85,72 +85,48 @@ import { TableProperties } from "viewers/common/table_properties";
|
||||
(selectedTreeChange)="selectedTreeChange($event)"
|
||||
></tree-view>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
.view-header {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 3.75rem;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-bottom: 1px solid var(--default-border);
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.title-filter {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.hierarchy-title {
|
||||
font-weight: medium;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.filter-field {
|
||||
font-size: 16px;
|
||||
transform: scale(0.7);
|
||||
right: 0px;
|
||||
position: absolute;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.view-controls {
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.hierarchy-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.tree-view {
|
||||
white-space: pre-line;
|
||||
flex: 1 0 0;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.properties-table {
|
||||
padding-top: 5px;
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hierarchy-content {
|
||||
height: 0;
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.pinned-items {
|
||||
border: 2px solid yellow;
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 2px solid yellow;
|
||||
}
|
||||
|
||||
.tree-wrapper {
|
||||
overflow-y: auto
|
||||
}
|
||||
`,
|
||||
nodeStyles
|
||||
@@ -179,14 +155,6 @@ export class HierarchyComponent {
|
||||
return this.userOptions["flat"]?.enabled;
|
||||
}
|
||||
|
||||
public maxHierarchyHeight() {
|
||||
const headerHeight = this.elementRef.nativeElement.querySelector(".view-header").clientHeight;
|
||||
const max = this.tableProperties ? 400 : 800;
|
||||
return {
|
||||
height: `${max - headerHeight}px`
|
||||
};
|
||||
}
|
||||
|
||||
public onPinnedNodeClick(event: MouseEvent, pinnedItem: HierarchyTreeNode) {
|
||||
event.preventDefault();
|
||||
if (window.getSelection()?.type === "range") {
|
||||
|
||||
@@ -21,343 +21,289 @@ import { ViewerEvents } from "viewers/common/viewer_events";
|
||||
@Component({
|
||||
selector: "ime-additional-properties",
|
||||
template: `
|
||||
<mat-card-header class="view-header">
|
||||
<div class="title-filter">
|
||||
<span class="additional-properties-title">WM & SF Properties</span>
|
||||
</div>
|
||||
</mat-card-header>
|
||||
<mat-card-content class="additional-properties-content">
|
||||
<h2 class="view-header mat-title">WM & SF Properties</h2>
|
||||
<div class="additional-properties-content">
|
||||
<div *ngIf="isAllPropertiesNull()" class="group">
|
||||
There is no corresponding WM / SF additionalProperties for this IME entry –
|
||||
no WM / SF entry is recorded before this IME entry in time.
|
||||
View later frames for WM & SF properties.
|
||||
<p class="mat-body-1">
|
||||
There is no corresponding WM / SF additionalProperties for this IME entry –
|
||||
no WM / SF entry is recorded before this IME entry in time.
|
||||
View later frames for WM & SF properties.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div *ngIf="isImeManagerService">
|
||||
<ng-container *ngIf="isImeManagerService">
|
||||
<div class="group">
|
||||
<button
|
||||
class="text-button group-header"
|
||||
*ngIf="wmProtoOrNull()"
|
||||
color="primary"
|
||||
mat-button
|
||||
class="group-header"
|
||||
[class]="{ 'selected': isHighlighted(wmProtoOrNull()) }"
|
||||
(click)="onClickShowInPropertiesPanel(wmProtoOrNull(), additionalProperties.wm?.name)">
|
||||
WMState
|
||||
</button>
|
||||
<span class="group-header" *ngIf="!wmProtoOrNull()">WMState</span>
|
||||
<div class="full-width">
|
||||
<span class="value" *ngIf="additionalProperties.wm">{{
|
||||
additionalProperties.wm.name }}</span>
|
||||
<span *ngIf="!additionalProperties.wm">There is no corresponding WMState entry.</span>
|
||||
<h3 *ngIf="!wmProtoOrNull()" class="group-header mat-subheading-2">WMState</h3>
|
||||
<div class="left-column">
|
||||
<p *ngIf="additionalProperties.wm" class="mat-body-1">
|
||||
{{ additionalProperties.wm.name }}
|
||||
</p>
|
||||
<p *ngIf="!additionalProperties.wm" class="mat-body-1">
|
||||
There is no corresponding WMState entry.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group" *ngIf="wmInsetsSourceProviderOrNull()">
|
||||
<div *ngIf="wmInsetsSourceProviderOrNull()" class="group">
|
||||
<button
|
||||
class="text-button group-header"
|
||||
color="primary"
|
||||
mat-button
|
||||
class="group-header"
|
||||
[class]="{ 'selected': isHighlighted(wmInsetsSourceProviderOrNull()) }"
|
||||
(click)="onClickShowInPropertiesPanel(wmInsetsSourceProviderOrNull(), 'Ime Insets Source Provider')">
|
||||
IME Insets Source Provider
|
||||
</button>
|
||||
<div class="full-width">
|
||||
<div></div>
|
||||
<span class="key">Source Frame:</span>
|
||||
<coordinates-table
|
||||
[coordinates]="wmInsetsSourceProviderSourceFrameOrNull()"
|
||||
></coordinates-table>
|
||||
<div></div>
|
||||
<span class="key">Source Visible:</span>
|
||||
<span class="value">{{
|
||||
wmInsetsSourceProviderSourceVisibleOrNull() }}</span>
|
||||
<div></div>
|
||||
<span class="key">Source Visible Frame:</span>
|
||||
<coordinates-table
|
||||
[coordinates]="wmInsetsSourceProviderSourceVisibleFrameOrNull()"
|
||||
></coordinates-table>
|
||||
<div></div>
|
||||
<span class="key">Position:</span>
|
||||
<span class="value">{{ wmInsetsSourceProviderPositionOrNull() }}</span>
|
||||
<div></div>
|
||||
<span class="key">IsLeashReadyForDispatching:</span>
|
||||
<span class="value">{{
|
||||
wmInsetsSourceProviderIsLeashReadyOrNull() }}</span>
|
||||
<div></div>
|
||||
<span class="key">Controllable:</span>
|
||||
<span class="value">{{
|
||||
wmInsetsSourceProviderControllableOrNull() }}</span>
|
||||
<div></div>
|
||||
<div class="left-column">
|
||||
<p class="mat-body-2">Source Frame:</p>
|
||||
<coordinates-table [coordinates]="wmInsetsSourceProviderSourceFrameOrNull()"></coordinates-table>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Source Visible:</span>
|
||||
&ngsp;
|
||||
{{ wmInsetsSourceProviderSourceVisibleOrNull() }}
|
||||
</p>
|
||||
<p class="mat-body-2">Source Visible Frame:</p>
|
||||
<coordinates-table [coordinates]="wmInsetsSourceProviderSourceVisibleFrameOrNull()"></coordinates-table>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Position:</span>
|
||||
&ngsp;
|
||||
{{ wmInsetsSourceProviderPositionOrNull() }}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">IsLeashReadyForDispatching:</span>
|
||||
&ngsp;
|
||||
{{ wmInsetsSourceProviderIsLeashReadyOrNull() }}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Controllable:</span>
|
||||
&ngsp;
|
||||
{{ wmInsetsSourceProviderControllableOrNull() }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group" *ngIf="wmImeControlTargetOrNull()">
|
||||
<div *ngIf="wmImeControlTargetOrNull()" class="group">
|
||||
<button
|
||||
class="text-button group-header"
|
||||
color="primary"
|
||||
mat-button
|
||||
class="group-header"
|
||||
[class]="{ 'selected': isHighlighted(wmImeControlTargetOrNull()) }"
|
||||
(click)="onClickShowInPropertiesPanel(wmImeControlTargetOrNull(), 'Ime Control Target')">
|
||||
IME Control Target
|
||||
</button>
|
||||
<div class="full-width">
|
||||
<span class="key" *ngIf="wmImeControlTargetTitleOrNull()">Title:</span>
|
||||
<span class="value" *ngIf="wmImeControlTargetTitleOrNull()">{{
|
||||
wmImeControlTargetTitleOrNull() }}</span>
|
||||
<div class="left-column">
|
||||
<p *ngIf="wmImeControlTargetTitleOrNull()" class="mat-body-1">
|
||||
<span class="mat-body-2">Title:</span>
|
||||
&ngsp;
|
||||
{{ wmImeControlTargetTitleOrNull() }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group" *ngIf="wmImeInputTargetOrNull()">
|
||||
<div *ngIf="wmImeInputTargetOrNull()" class="group">
|
||||
<button
|
||||
class="text-button group-header"
|
||||
color="primary"
|
||||
mat-button
|
||||
class="group-header"
|
||||
[class]="{ 'selected': isHighlighted(wmImeInputTargetOrNull()) }"
|
||||
(click)="onClickShowInPropertiesPanel(wmImeInputTargetOrNull(), 'Ime Input Target')">
|
||||
IME Input Target
|
||||
</button>
|
||||
<div class="full-width">
|
||||
<span class="key" *ngIf="wmImeInputTargetTitleOrNull()">Title:</span>
|
||||
<span class="value" *ngIf="wmImeInputTargetTitleOrNull()">{{
|
||||
wmImeInputTargetTitleOrNull() }}</span>
|
||||
<div class="left-column">
|
||||
<p *ngIf="wmImeInputTargetTitleOrNull()" class="mat-body-1">
|
||||
<span class="mat-body-2">Title:</span>
|
||||
&ngsp;
|
||||
{{ wmImeInputTargetTitleOrNull() }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group" *ngIf="wmImeLayeringTargetOrNull()">
|
||||
<div *ngIf="wmImeLayeringTargetOrNull()" class="group">
|
||||
<button
|
||||
class="text-button group-header"
|
||||
color="primary"
|
||||
mat-button
|
||||
class="group-header"
|
||||
[class]="{ 'selected': isHighlighted(wmImeLayeringTargetOrNull()) }"
|
||||
(click)="onClickShowInPropertiesPanel(wmImeLayeringTargetOrNull(), 'Ime Layering Target')">
|
||||
IME Layering Target
|
||||
</button>
|
||||
<div class="full-width">
|
||||
<span class="key" *ngIf="wmImeLayeringTargetTitleOrNull()">Title:</span>
|
||||
<span class="value" *ngIf="wmImeLayeringTargetTitleOrNull()">{{
|
||||
wmImeLayeringTargetTitleOrNull() }}</span>
|
||||
<div class="left-column">
|
||||
<p *ngIf="wmImeLayeringTargetTitleOrNull()" class="mat-body-1">
|
||||
<span class="mat-body-2">Title:</span>
|
||||
&ngsp;
|
||||
{{ wmImeLayeringTargetTitleOrNull() }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<div *ngIf="!isImeManagerService">
|
||||
<ng-container *ngIf="!isImeManagerService">
|
||||
<!-- Ime Client or Ime Service -->
|
||||
<div class="group">
|
||||
<button
|
||||
class="text-button group-header"
|
||||
*ngIf="wmProtoOrNull()"
|
||||
color="primary"
|
||||
mat-button
|
||||
class="group-header"
|
||||
[class]="{ 'selected': isHighlighted(wmProtoOrNull()) }"
|
||||
(click)="onClickShowInPropertiesPanel(wmProtoOrNull(), additionalProperties.wm?.name)">
|
||||
WMState
|
||||
</button>
|
||||
<span class="group-header" *ngIf="!wmProtoOrNull()">WMState</span>
|
||||
<div class="full-width">
|
||||
<span class="value" *ngIf="additionalProperties.wm">{{
|
||||
additionalProperties.wm.name }}</span>
|
||||
<span *ngIf="!additionalProperties.wm">There is no corresponding WMState entry.</span>
|
||||
<h3 *ngIf="!wmProtoOrNull()" class="group-header mat-subheading-2">WMState</h3>
|
||||
<div class="left-column">
|
||||
<p *ngIf="additionalProperties.wm" class="mat-body-1">{{
|
||||
additionalProperties.wm.name
|
||||
}}</p>
|
||||
<p *ngIf="!additionalProperties.wm" class="mat-body-1">
|
||||
There is no corresponding WMState entry.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<span class="group-header">SFLayer</span>
|
||||
<div class="full-width">
|
||||
<span class="value" *ngIf="additionalProperties.sf">{{
|
||||
additionalProperties.sf.name }}</span>
|
||||
<span *ngIf="!additionalProperties.sf">There is no corresponding SFLayer entry.</span>
|
||||
<h3 class="group-header mat-subheading-2">SFLayer</h3>
|
||||
<div class="left-column">
|
||||
<p *ngIf="additionalProperties.sf" class="mat-body-1">{{
|
||||
additionalProperties.sf.name
|
||||
}}</p>
|
||||
<p *ngIf="!additionalProperties.sf" class="mat-body-1">
|
||||
There is no corresponding SFLayer entry.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group" *ngIf="additionalProperties.wm">
|
||||
<span class="group-header">Focus</span>
|
||||
<div class="full-width">
|
||||
<span class="key">Focused App:</span>
|
||||
<span class="value">{{ additionalProperties.wm.focusedApp }}</span>
|
||||
<div></div>
|
||||
<span class="key">Focused Activity:</span>
|
||||
<span class="value">{{ additionalProperties.wm.focusedActivity }}</span>
|
||||
<div></div>
|
||||
<span class="key">Focused Window:</span>
|
||||
<span class="value">{{ additionalProperties.wm.focusedWindow }}</span>
|
||||
<div></div>
|
||||
<span class="key" *ngIf="additionalProperties.sf">Focused Window Color:</span>
|
||||
<span class="value" *ngIf="additionalProperties.sf">{{
|
||||
additionalProperties.sf.focusedWindow.color
|
||||
}}</span>
|
||||
<div></div>
|
||||
<span class="key">Input Control Target Frame:</span>
|
||||
<coordinates-table
|
||||
[coordinates]="wmControlTargetFrameOrNull()"
|
||||
></coordinates-table>
|
||||
<div></div>
|
||||
<div *ngIf="additionalProperties.wm" class="group">
|
||||
<h3 class="group-header mat-subheading-2">Focus</h3>
|
||||
<div class="left-column">
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Focused App:</span>
|
||||
&ngsp;
|
||||
{{ additionalProperties.wm.focusedApp }}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Focused Activity:</span>
|
||||
&ngsp;
|
||||
{{ additionalProperties.wm.focusedActivity }}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Focused Window:</span>
|
||||
&ngsp;
|
||||
{{ additionalProperties.wm.focusedWindow }}
|
||||
</p>
|
||||
<p *ngIf="additionalProperties.sf" class="mat-body-1">
|
||||
<span class="mat-body-2">Focused Window Color:</span>
|
||||
&ngsp;
|
||||
{{ additionalProperties.sf.focusedWindow.color }}
|
||||
</p>
|
||||
<p class="mat-body-2">Input Control Target Frame:</p>
|
||||
<coordinates-table [coordinates]="wmControlTargetFrameOrNull()"></coordinates-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<span class="group-header">Visibility</span>
|
||||
<div class="full-width">
|
||||
<span class="key" *ngIf="additionalProperties.wm">InputMethod Window:</span>
|
||||
<span class="value" *ngIf="additionalProperties.wm">{{
|
||||
additionalProperties.wm.isInputMethodWindowVisible
|
||||
}}</span>
|
||||
<div></div>
|
||||
<span class="key" *ngIf="additionalProperties.sf">InputMethod Surface:</span>
|
||||
<span class="value" *ngIf="additionalProperties.sf">{{
|
||||
additionalProperties.sf.inputMethodSurface.isInputMethodSurfaceVisible }}</span>
|
||||
<div></div>
|
||||
<h3 class="group-header mat-subheading-2">Visibility</h3>
|
||||
<div class="left-column">
|
||||
<p *ngIf="additionalProperties.wm" class="mat-body-1">
|
||||
<span class="mat-body-2">InputMethod Window:</span>
|
||||
&ngsp;
|
||||
{{ additionalProperties.wm.isInputMethodWindowVisible }}
|
||||
</p>
|
||||
<p *ngIf="additionalProperties.sf" class="mat-body-1">
|
||||
<span class="mat-body-2">InputMethod Surface:</span>
|
||||
&ngsp;
|
||||
{{ additionalProperties.sf.inputMethodSurface.isInputMethodSurfaceVisible }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group" *ngIf="additionalProperties.sf">
|
||||
<div *ngIf="additionalProperties.sf" class="group">
|
||||
<button
|
||||
class="text-button group-header"
|
||||
color="primary"
|
||||
mat-button
|
||||
class="group-header"
|
||||
[class]="{ 'selected': isHighlighted(additionalProperties.sf.imeContainer) }"
|
||||
(click)="onClickShowInPropertiesPanel(additionalProperties.sf.imeContainer)">
|
||||
Ime Container
|
||||
</button>
|
||||
<div class="full-width">
|
||||
<span class="key">ZOrderRelativeOfId:</span>
|
||||
<span class="value">{{
|
||||
additionalProperties.sf.imeContainer.zOrderRelativeOfId
|
||||
}}</span>
|
||||
<div></div>
|
||||
<span class="key">Z:</span>
|
||||
<span class="value">{{ additionalProperties.sf.imeContainer.z }}</span>
|
||||
<div></div>
|
||||
<div class="left-column">
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">ZOrderRelativeOfId:</span>
|
||||
&ngsp;
|
||||
{{ additionalProperties.sf.imeContainer.zOrderRelativeOfId }}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Z:</span>
|
||||
&ngsp;
|
||||
{{ additionalProperties.sf.imeContainer.z }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group" *ngIf="additionalProperties.sf">
|
||||
<div *ngIf="additionalProperties.sf" class="group">
|
||||
<button
|
||||
class="text-button group-header"
|
||||
[class]="{
|
||||
'selected': isHighlighted(additionalProperties.sf.inputMethodSurface)
|
||||
}"
|
||||
(click)="onClickShowInPropertiesPanel(
|
||||
additionalProperties.sf.inputMethodSurface)">
|
||||
color="primary"
|
||||
mat-button
|
||||
class="group-header"
|
||||
[class]="{ 'selected': isHighlighted(additionalProperties.sf.inputMethodSurface) }"
|
||||
(click)="onClickShowInPropertiesPanel(additionalProperties.sf.inputMethodSurface)">
|
||||
Input Method Surface
|
||||
</button>
|
||||
<div class="full-width">
|
||||
<span class="key">ScreenBounds:</span>
|
||||
<coordinates-table
|
||||
[coordinates]="sfImeContainerScreenBoundsOrNull()"
|
||||
></coordinates-table>
|
||||
<div></div>
|
||||
<span class="key">Rect:</span>
|
||||
<coordinates-table
|
||||
[coordinates]="sfImeContainerRectOrNull()"
|
||||
></coordinates-table>
|
||||
<div></div>
|
||||
<div class="left-column">
|
||||
<p class="mat-body-2">ScreenBounds:</p>
|
||||
<coordinates-table [coordinates]="sfImeContainerScreenBoundsOrNull()"></coordinates-table>
|
||||
</div>
|
||||
<div class="right-column">
|
||||
<p class="mat-body-2">Rect:</p>
|
||||
<coordinates-table [coordinates]="sfImeContainerRectOrNull()"></coordinates-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</ng-container>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
.view-header {
|
||||
width: 100%;
|
||||
height: 2.5rem;
|
||||
border-bottom: 1px solid var(--default-border);
|
||||
}
|
||||
|
||||
.title-filter {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.additional-properties-title {
|
||||
font-weight: medium;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.additional-properties-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 375px;
|
||||
height: 0;
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.container {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.group {
|
||||
padding: 0.5rem;
|
||||
border-bottom: thin solid rgba(0, 0, 0, 0.12);
|
||||
flex-direction: row;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border-bottom: 1px solid var(--default-border);
|
||||
}
|
||||
|
||||
.group .key {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.group .value {
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
word-break: break-all !important;
|
||||
.mat-body-1 {
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.group-header {
|
||||
justify-content: center;
|
||||
text-align: left;
|
||||
padding: 0px 5px;
|
||||
width: 95px;
|
||||
display: inline-block;
|
||||
font-size: bigger;
|
||||
height: 100%;
|
||||
width: 80px;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
line-height: normal;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
p.group-header {
|
||||
color: grey;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.left-column {
|
||||
width: 320px;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
overflow: auto;
|
||||
padding-right: 20px;
|
||||
flex: 1;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.right-column {
|
||||
width: 320px;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
overflow: auto;
|
||||
flex: 1;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.column-header {
|
||||
font-weight: medium;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.element-summary {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.element-summary .key {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.element-summary .value {
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
.tree-view {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.text-button {
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-family: roboto;
|
||||
color: blue;
|
||||
text-decoration: underline;
|
||||
text-decoration-color: blue;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.text-button:focus {
|
||||
color: purple;
|
||||
}
|
||||
|
||||
.text-button.selected {
|
||||
color: purple;
|
||||
}
|
||||
|
||||
|
||||
`
|
||||
],
|
||||
})
|
||||
|
||||
@@ -22,10 +22,10 @@ import { PropertiesTreeNode, Terminal} from "viewers/common/ui_tree_utils";
|
||||
@Component({
|
||||
selector: "properties-view",
|
||||
template: `
|
||||
<mat-card-header class="view-header">
|
||||
<div class="view-header">
|
||||
<div class="title-filter">
|
||||
<span class="properties-title">Properties</span>
|
||||
<mat-form-field class="filter-field">
|
||||
<h2 class="properties-title mat-title">Properties</h2>
|
||||
<mat-form-field>
|
||||
<mat-label>Filter...</mat-label>
|
||||
<input
|
||||
matInput
|
||||
@@ -38,92 +38,69 @@ import { PropertiesTreeNode, Terminal} from "viewers/common/ui_tree_utils";
|
||||
<div class="view-controls">
|
||||
<mat-checkbox
|
||||
*ngFor="let option of objectKeys(userOptions)"
|
||||
color="primary"
|
||||
class="trace-box"
|
||||
[(ngModel)]="userOptions[option].enabled"
|
||||
(ngModelChange)="updateTree()"
|
||||
[matTooltip]="userOptions[option].tooltip ?? ''"
|
||||
>{{userOptions[option].name}}</mat-checkbox>
|
||||
</div>
|
||||
<div *ngIf="itemIsSelected() && propertyGroups" class="element-summary">
|
||||
<property-groups
|
||||
[item]="selectedFlickerItem"
|
||||
></property-groups>
|
||||
</div>
|
||||
</mat-card-header>
|
||||
<mat-card-content class="properties-content" [style]="maxPropertiesHeight()">
|
||||
<span *ngIf="objectKeys(propertiesTree).length > 0 && isProtoDump" class="properties-title"> Properties - Proto Dump </span>
|
||||
<property-groups
|
||||
*ngIf="itemIsSelected() && propertyGroups"
|
||||
class="property-groups"
|
||||
[item]="selectedFlickerItem"
|
||||
></property-groups>
|
||||
</div>
|
||||
<div class="properties-content">
|
||||
<h3 *ngIf="objectKeys(propertiesTree).length > 0 && isProtoDump" class="properties-title mat-subheading-2">Properties - Proto Dump</h3>
|
||||
<div class="tree-wrapper">
|
||||
<tree-view
|
||||
class="tree-view"
|
||||
*ngIf="objectKeys(propertiesTree).length > 0"
|
||||
[item]="propertiesTree"
|
||||
[showNode]="showNode"
|
||||
[isLeaf]="isLeaf"
|
||||
*ngIf="objectKeys(propertiesTree).length > 0"
|
||||
[isAlwaysCollapsed]="true"
|
||||
></tree-view>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
.view-header {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 3.75rem;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid lightgrey;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-bottom: 1px solid var(--default-border);
|
||||
padding-bottom: 12px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.title-filter {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.properties-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.filter-field {
|
||||
font-size: 16px;
|
||||
transform: scale(0.7);
|
||||
right: 0px;
|
||||
position: absolute;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.view-controls {
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
margin-left: 5px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.properties-content{
|
||||
.properties-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
overflow-x:hidden
|
||||
}
|
||||
|
||||
.element-summary {
|
||||
padding: 1rem;
|
||||
border-bottom: thin solid rgba(0,0,0,.12);
|
||||
.property-groups {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.element-summary .key {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.element-summary .value {
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
.tree-view {
|
||||
white-space: pre-line;
|
||||
flex: 1 0 0;
|
||||
height: 100%;
|
||||
.tree-wrapper {
|
||||
overflow-y: auto
|
||||
}
|
||||
`,
|
||||
@@ -144,13 +121,6 @@ export class PropertiesComponent {
|
||||
@Inject(ElementRef) private elementRef: ElementRef,
|
||||
) {}
|
||||
|
||||
public maxPropertiesHeight() {
|
||||
const headerHeight = this.elementRef.nativeElement.querySelector(".view-header").clientHeight;
|
||||
return {
|
||||
height: `${800 - headerHeight}px`
|
||||
};
|
||||
}
|
||||
|
||||
public filterTree() {
|
||||
const event: CustomEvent = new CustomEvent(
|
||||
ViewerEvents.PropertiesFilterChange,
|
||||
|
||||
@@ -19,49 +19,33 @@ import { TableProperties } from "viewers/common/table_properties";
|
||||
@Component({
|
||||
selector: "properties-table",
|
||||
template: `
|
||||
<div class="properties-table-wrapper">
|
||||
<table class="table">
|
||||
<tr *ngFor="let entry of objectEntries(properties)">
|
||||
<td class="table-cell-name">
|
||||
<span>{{ entry[0] }}</span>
|
||||
<p class="mat-body-1">{{ entry[0] }}</p>
|
||||
</td>
|
||||
<td class="table-cell-value">
|
||||
<span>{{ entry[1] != undefined ? entry[1] : 'undefined' }}</span>
|
||||
<p class="mat-body-1">{{ entry[1] != undefined ? entry[1] : 'undefined' }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
.properties-table-wrapper {
|
||||
border-bottom: 1px solid var(--default-border);
|
||||
}
|
||||
|
||||
.properties-table-wrapper .table-cell-name {
|
||||
background-color: rgba(158, 192, 200, 0.281);
|
||||
border: 1px solid var(--default-border);
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.properties-table-wrapper .table-cell-value {
|
||||
overflow-wrap: anywhere;
|
||||
border: 1px solid var(--default-border);
|
||||
height: 20px;
|
||||
padding: 0;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.properties-table-wrapper table {
|
||||
height: auto;
|
||||
border-collapse: collapse;
|
||||
.table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.properties-table-wrapper span {
|
||||
padding: 5px;
|
||||
.table-cell-name, .table-cell-value {
|
||||
padding: 1px 5px;
|
||||
border: 1px solid var(--default-border);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.table-cell-name {
|
||||
width: 20%;
|
||||
background-color: rgba(158, 192, 200, 0.281);
|
||||
}
|
||||
`
|
||||
],
|
||||
|
||||
@@ -19,263 +19,258 @@ import { Layer } from "common/trace/flickerlib/common";
|
||||
@Component({
|
||||
selector: "property-groups",
|
||||
template: `
|
||||
<div>
|
||||
<div class="group">
|
||||
<span class="group-header">
|
||||
<span class="group-heading">Visibility</span>
|
||||
</span>
|
||||
<div class="left-column">
|
||||
<span class="key">Flags:</span>
|
||||
<span class="value">{{ item.flags }}</span>
|
||||
<div></div>
|
||||
<div *ngIf="summary().length > 0">
|
||||
<div *ngFor="let reason of summary()">
|
||||
<span class="key">{{ reason.key }}:</span>
|
||||
<span class="value">{{ reason.value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="group-header mat-subheading-2">Visibility</h3>
|
||||
<div class="left-column">
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Flags:</span>
|
||||
&ngsp;
|
||||
{{ item.flags }}
|
||||
</p>
|
||||
<p *ngFor="let reason of summary()" class="mat-body-1">
|
||||
<span class="mat-body-2">{{ reason.key }}:</span>
|
||||
&ngsp;
|
||||
{{ reason.value }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="group">
|
||||
<span class="group-header">Geometry</span>
|
||||
<div class="left-column">
|
||||
<div class="column-header">Calculated</div>
|
||||
<span class="key">Transform:</span>
|
||||
<transform-matrix [transform]="item.transform" [formatFloat]="formatFloat"></transform-matrix>
|
||||
<div></div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<h3 class="group-header mat-subheading-2">Geometry</h3>
|
||||
<div class="left-column">
|
||||
<p class="column-header mat-small">Calculated</p>
|
||||
<p class="property mat-body-2">Transform:</p>
|
||||
<transform-matrix [transform]="item.transform" [formatFloat]="formatFloat"></transform-matrix>
|
||||
<p class="mat-body-1">
|
||||
<span
|
||||
class="key"
|
||||
class="mat-body-2"
|
||||
matTooltip="Raw value read from proto.bounds. This is the buffer size or
|
||||
requested crop cropped by parent bounds."
|
||||
>Crop:</span>
|
||||
<span class="value">{{ item.bounds }}</span>
|
||||
<div></div>
|
||||
&ngsp;
|
||||
{{ item.bounds }}
|
||||
<p class="mat-body-1">
|
||||
<span
|
||||
class="key"
|
||||
class="mat-body-2"
|
||||
matTooltip="Raw value read from proto.screenBounds. This is the calculated crop
|
||||
transformed."
|
||||
>Final Bounds:</span>
|
||||
<span class="value">{{ item.screenBounds }}</span>
|
||||
</div>
|
||||
<div class="right-column">
|
||||
<div class="column-header">Requested</div>
|
||||
<span class="key">Transform:</span>
|
||||
<transform-matrix [transform]="item.requestedTransform" [formatFloat]="formatFloat"></transform-matrix>
|
||||
<div></div>
|
||||
<span class="key">Crop:</span>
|
||||
<span class="value">{{ item.crop ? item.crop : "[empty]" }}</span>
|
||||
</div>
|
||||
&ngsp;
|
||||
{{ item.screenBounds }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="group">
|
||||
<span class="group-header">
|
||||
<span class="group-heading">Buffer</span>
|
||||
</span>
|
||||
<div *ngIf="item.isBufferLayer" class="left-column">
|
||||
<div></div>
|
||||
<span class="key">Size:</span>
|
||||
<span class="value">{{ item.activeBuffer }}</span>
|
||||
<div></div>
|
||||
<span class="key">Frame Number:</span>
|
||||
<span class="value">{{ item.currFrame }}</span>
|
||||
<div></div>
|
||||
<div class="right-column">
|
||||
<p class="column-header mat-small">Requested</p>
|
||||
<p class="property mat-body-2">Transform:</p>
|
||||
<transform-matrix [transform]="item.requestedTransform" [formatFloat]="formatFloat"></transform-matrix>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Crop:</span>
|
||||
&ngsp;
|
||||
{{ item.crop
|
||||
? item.crop
|
||||
: "[empty]"
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<h3 class="group-header mat-subheading-2">Buffer</h3>
|
||||
<div class="left-column">
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Size:</span>
|
||||
&ngsp;
|
||||
{{ item.activeBuffer }}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Frame Number:</span>
|
||||
&ngsp;
|
||||
{{ item.currFrame }}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span
|
||||
class="key"
|
||||
class="mat-body-2"
|
||||
matTooltip="Rotates or flips the buffer in place. Used with display transform
|
||||
hint to cancel out any buffer transformation when sending to
|
||||
HWC."
|
||||
>Transform:</span>
|
||||
<span class="value">{{ item.bufferTransform }}</span>
|
||||
</div>
|
||||
<div *ngIf="item.isBufferLayer" class="right-column">
|
||||
<div></div>
|
||||
&ngsp;
|
||||
{{ item.bufferTransform }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="right-column">
|
||||
<p class="mat-body-1">
|
||||
<span
|
||||
class="key"
|
||||
class="mat-body-2"
|
||||
matTooltip="Scales buffer to the frame by overriding the requested transform
|
||||
for this item."
|
||||
>Destination Frame:</span>
|
||||
<span class="value">{{ getDestinationFrame() }}</span>
|
||||
<div></div>
|
||||
<span
|
||||
*ngIf="hasIgnoreDestinationFrame()"
|
||||
class="value"
|
||||
>Destination Frame ignored because item has eIgnoreDestinationFrame
|
||||
flag set.
|
||||
</span>
|
||||
</div>
|
||||
<div *ngIf="item.isContainerLayer" class="left-column">
|
||||
<span class="key"></span>
|
||||
<span class="value">Container item</span>
|
||||
</div>
|
||||
<div *ngIf="item.isEffectLayer" class="left-column">
|
||||
<span class="key"></span>
|
||||
<span class="value">Effect item</span>
|
||||
</div>
|
||||
&ngsp;
|
||||
{{ getDestinationFrame() }}
|
||||
</p>
|
||||
<p *ngIf="hasIgnoreDestinationFrame()" class="mat-body-1">
|
||||
Destination Frame ignored because item has eIgnoreDestinationFrame
|
||||
flag set.
|
||||
</p>
|
||||
</div>
|
||||
<div class="group">
|
||||
<span class="group-header">
|
||||
<span class="group-heading">Hierarchy</span>
|
||||
</span>
|
||||
<div class="left-column">
|
||||
<div></div>
|
||||
<span class="key">z-order:</span>
|
||||
<span class="value">{{ item.z }}</span>
|
||||
<div></div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<h3 class="group-header mat-subheading-2">Hierarchy</h3>
|
||||
<div class="left-column">
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">z-order:</span>
|
||||
&ngsp;
|
||||
{{ item.z }}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span
|
||||
class="key"
|
||||
class="mat-body-2"
|
||||
matTooltip="item is z-ordered relative to its relative parents but its bounds
|
||||
and other properties are inherited from its parents."
|
||||
>relative parent:</span>
|
||||
<span class="value">
|
||||
{{ item.zOrderRelativeOfId == -1 ? "none" : item.zOrderRelativeOfId }}
|
||||
</span>
|
||||
</div>
|
||||
&ngsp;
|
||||
{{
|
||||
item.zOrderRelativeOfId == -1
|
||||
? "none"
|
||||
: item.zOrderRelativeOfId
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
<div class="group">
|
||||
<span class="group-header">
|
||||
<span class="group-heading">Effects</span>
|
||||
</span>
|
||||
<div class="left-column">
|
||||
<div class="column-header">Calculated</div>
|
||||
<span class="key">Color:</span>
|
||||
<span class="value">{{ item.color }}</span>
|
||||
<div></div>
|
||||
<span class="key">Shadow:</span>
|
||||
<span class="value">{{ item.shadowRadius }} px</span>
|
||||
<div></div>
|
||||
<span class="key">Corner Radius:</span>
|
||||
<span class="value">{{ formatFloat(item.cornerRadius) }} px</span>
|
||||
<div></div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<h3 class="group-header mat-subheading-2">Effects</h3>
|
||||
<div class="left-column">
|
||||
<p class="column-header mat-small">Calculated</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Color:</span>
|
||||
&ngsp;
|
||||
{{ item.color }}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Shadow:</span>
|
||||
&ngsp;
|
||||
{{ item.shadowRadius }} px
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Corner Radius:</span>
|
||||
&ngsp;
|
||||
{{ formatFloat(item.cornerRadius) }} px
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span
|
||||
class="key"
|
||||
class="mat-body-2"
|
||||
matTooltip="Crop used to define the bounds of the corner radii. If the bounds
|
||||
are greater than the item bounds then the rounded corner will not
|
||||
be visible."
|
||||
>Corner Radius Crop:</span>
|
||||
<span class="value">{{ item.cornerRadiusCrop }}</span>
|
||||
<div></div>
|
||||
<span class="key">Blur:</span>
|
||||
<span class="value">
|
||||
{{
|
||||
item.proto?.backgroundBlurRadius
|
||||
? item.proto?.backgroundBlurRadius
|
||||
: 0
|
||||
}} px
|
||||
</span>
|
||||
</div>
|
||||
<div class="right-column">
|
||||
<div class="column-header">Requested</div>
|
||||
<span class="key">Color:</span>
|
||||
<span class="value">{{ item.requestedColor }}</span>
|
||||
<div></div>
|
||||
<span class="key">Shadow:</span>
|
||||
<span class="value">
|
||||
{{
|
||||
item.proto?.requestedShadowRadius
|
||||
? item.proto?.requestedShadowRadius
|
||||
: 0
|
||||
}} px
|
||||
</span>
|
||||
<div></div>
|
||||
<span class="key">Corner Radius:</span>
|
||||
<span class="value">
|
||||
{{
|
||||
item.proto?.requestedCornerRadius
|
||||
? formatFloat(item.proto?.requestedCornerRadius)
|
||||
: 0
|
||||
}} px
|
||||
</span>
|
||||
</div>
|
||||
&ngsp;
|
||||
{{ item.cornerRadiusCrop }}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Blur:</span>
|
||||
&ngsp;
|
||||
{{
|
||||
item.proto?.backgroundBlurRadius
|
||||
? item.proto?.backgroundBlurRadius
|
||||
: 0
|
||||
}} px
|
||||
</p>
|
||||
</div>
|
||||
<div class="group">
|
||||
<span class="group-header">
|
||||
<span class="group-heading">Input</span>
|
||||
</span>
|
||||
<div *ngIf="hasInputChannel()" class="left-column">
|
||||
<span class="key">To Display Transform:</span>
|
||||
<transform-matrix [transform]="item.inputTransform" [formatFloat]="formatFloat"></transform-matrix>
|
||||
<div></div>
|
||||
<span class="key">Touchable Region:</span>
|
||||
<span class="value">{{ item.inputRegion }}</span>
|
||||
</div>
|
||||
<div *ngIf="hasInputChannel()" class="right-column">
|
||||
<span class="key">Config:</span>
|
||||
<span class="value"></span>
|
||||
<div></div>
|
||||
<span class="key">Focusable:</span>
|
||||
<span class="value">{{ item.proto?.inputWindowInfo.focusable }}</span>
|
||||
<div></div>
|
||||
<span class="key">Crop touch region with item:</span>
|
||||
<span class="value">
|
||||
{{
|
||||
item.proto?.inputWindowInfo.cropLayerId <= 0
|
||||
? "none"
|
||||
: item.proto?.inputWindowInfo.cropLayerId
|
||||
}}
|
||||
</span>
|
||||
<div></div>
|
||||
<span class="key">Replace touch region with crop:</span>
|
||||
<span class="value">
|
||||
{{
|
||||
item.proto?.inputWindowInfo.replaceTouchableRegionWithCrop
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
<div *ngIf="!hasInputChannel()" class="left-column">
|
||||
<span class="key"></span>
|
||||
<span class="value">No input channel set</span>
|
||||
</div>
|
||||
<div class="right-column">
|
||||
<p class="column-header mat-small">Requested</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Color:</span>
|
||||
&ngsp;
|
||||
{{ item.requestedColor }}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Shadow:</span>
|
||||
&ngsp;
|
||||
{{
|
||||
item.proto?.requestedShadowRadius
|
||||
? item.proto?.requestedShadowRadius
|
||||
: 0
|
||||
}} px
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Corner Radius:</span>
|
||||
&ngsp;
|
||||
{{
|
||||
item.proto?.requestedCornerRadius
|
||||
? formatFloat(item.proto?.requestedCornerRadius)
|
||||
: 0
|
||||
}} px
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="group">
|
||||
<h3 class="group-header mat-subheading-2">Input</h3>
|
||||
<div *ngIf="hasInputChannel()" class="left-column">
|
||||
<p class="property mat-body-2">To Display Transform:</p>
|
||||
<transform-matrix [transform]="item.inputTransform" [formatFloat]="formatFloat"></transform-matrix>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Touchable Region:</span>
|
||||
&ngsp;
|
||||
{{ item.inputRegion }}
|
||||
</p>
|
||||
</div>
|
||||
<div *ngIf="hasInputChannel()" class="right-column">
|
||||
<p class="column-header mat-small">Config</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Focusable:</span>
|
||||
&ngsp;
|
||||
{{ item.proto?.inputWindowInfo.focusable }}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Crop touch region with item:</span>
|
||||
&ngsp;
|
||||
{{
|
||||
item.proto?.inputWindowInfo.cropLayerId <= 0
|
||||
? "none"
|
||||
: item.proto?.inputWindowInfo.cropLayerId
|
||||
}}
|
||||
</p>
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Replace touch region with crop:</span>
|
||||
&ngsp;
|
||||
{{ item.proto?.inputWindowInfo.replaceTouchableRegionWithCrop }}
|
||||
</p>
|
||||
</div>
|
||||
<div *ngIf="!hasInputChannel()" class="left-column">
|
||||
<p class="mat-body-1">
|
||||
<span class="mat-body-2">Input channel:</span>
|
||||
&ngsp;
|
||||
not set
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
.group {
|
||||
padding: 0.5rem;
|
||||
border-bottom: thin solid rgba(0, 0, 0, 0.12);
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.group .key {
|
||||
font-weight: 500;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.group .value {
|
||||
color: rgba(0, 0, 0, 0.75);
|
||||
flex-direction: row;
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid var(--default-border);
|
||||
}
|
||||
|
||||
.group-header {
|
||||
justify-content: center;
|
||||
padding: 0px 5px;
|
||||
width: 80px;
|
||||
display: inline-block;
|
||||
font-size: bigger;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.left-column {
|
||||
width: 320px;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
overflow: auto;
|
||||
border-right: 5px solid rgba(#000, 0.12);
|
||||
padding-right: 20px;
|
||||
flex: 1;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.right-column {
|
||||
width: 320px;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
overflow: auto;
|
||||
border: 1px solid rgba(#000, 0.12);
|
||||
flex: 1;
|
||||
border: 1px solid var(--default-border);
|
||||
border-left-width: 5px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.column-header {
|
||||
font-weight: lighter;
|
||||
font-size: smaller;
|
||||
color: grey;
|
||||
}
|
||||
`
|
||||
],
|
||||
|
||||
@@ -48,7 +48,7 @@ export class CanvasGraphics {
|
||||
|
||||
//set canvas size
|
||||
this.canvas.style.width = "100%";
|
||||
this.canvas.style.height = "40rem";
|
||||
this.canvas.style.height = "100%";
|
||||
|
||||
this.orbit?.reset();
|
||||
|
||||
@@ -71,7 +71,7 @@ export class CanvasGraphics {
|
||||
this.labelRenderer.domElement.style.position = "absolute";
|
||||
this.labelRenderer.domElement.style.top = "0px";
|
||||
this.labelRenderer.domElement.style.width = "100%";
|
||||
this.labelRenderer.domElement.style.height = "40rem";
|
||||
this.labelRenderer.domElement.style.height = "100%";
|
||||
this.labelRenderer.domElement.className = "labels-canvas";
|
||||
this.labelRenderer.domElement.style.pointerEvents = "none";
|
||||
this.canvasContainer?.appendChild(this.labelRenderer.domElement);
|
||||
@@ -87,8 +87,8 @@ export class CanvasGraphics {
|
||||
let xShift = 0, yShift = 3.5, labelYShift = 0;
|
||||
|
||||
if (this.isLandscape) {
|
||||
xShift = 1;
|
||||
yShift = 1.5;
|
||||
xShift = -1;
|
||||
yShift = 2.5;
|
||||
labelYShift = 1.25;
|
||||
}
|
||||
|
||||
@@ -477,7 +477,7 @@ export class CanvasGraphics {
|
||||
private readonly MAX_LABEL_SHIFT = 0.305;
|
||||
private readonly MAX_ZOOM = 2.5;
|
||||
private readonly MIN_ZOOM = 0.5;
|
||||
private readonly INIT_ZOOM = 1;
|
||||
private readonly INIT_ZOOM = 0.75;
|
||||
private readonly INIT_FONT_SIZE = 10;
|
||||
private readonly INIT_CAMERA_POS = new THREE.Vector3(4, 4, 6);
|
||||
private readonly INIT_TARGET = new THREE.Vector3(0, 0, 0);
|
||||
|
||||
@@ -23,49 +23,46 @@ import { ViewerEvents } from "viewers/common/viewer_events";
|
||||
@Component({
|
||||
selector: "rects-view",
|
||||
template: `
|
||||
<mat-card-header class="view-controls">
|
||||
<div class="rects-title">
|
||||
<span>Layers</span>
|
||||
</div>
|
||||
<div class="view-controls">
|
||||
<h2 class="mat-title">Layers</h2>
|
||||
<div class="top-view-controls">
|
||||
<div class="top-view-controls">
|
||||
<mat-checkbox
|
||||
class="rects-checkbox control-item"
|
||||
[checked]="visibleView()"
|
||||
(change)="onChangeView($event.checked!)"
|
||||
>Only visible</mat-checkbox>
|
||||
<mat-checkbox
|
||||
[disabled]="visibleView() || !hasVirtualDisplays"
|
||||
class="rects-checkbox control-item"
|
||||
[checked]="showVirtualDisplays()"
|
||||
(change)="updateVirtualDisplays($event.checked!)"
|
||||
>Show virtual</mat-checkbox>
|
||||
<div class="right-btn-container control-item">
|
||||
<button class="right-btn" (click)="updateZoom(true)">
|
||||
<mat-icon aria-hidden="true">
|
||||
zoom_in
|
||||
</mat-icon>
|
||||
</button>
|
||||
<button class="right-btn" (click)="updateZoom(false)">
|
||||
<mat-icon aria-hidden="true">
|
||||
zoom_out
|
||||
</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
class="right-btn"
|
||||
(click)="resetCamera()"
|
||||
matTooltip="Restore camera settings"
|
||||
>
|
||||
<mat-icon aria-hidden="true">
|
||||
restore
|
||||
</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
[checked]="visibleView()"
|
||||
(change)="onChangeView($event.checked!)"
|
||||
>Only visible</mat-checkbox>
|
||||
<mat-checkbox
|
||||
color="primary"
|
||||
[disabled]="visibleView() || !hasVirtualDisplays"
|
||||
[checked]="showVirtualDisplays()"
|
||||
(change)="updateVirtualDisplays($event.checked!)"
|
||||
>Show virtual</mat-checkbox>
|
||||
<div class="right-btn-container">
|
||||
<button color="primary" mat-icon-button (click)="updateZoom(true)">
|
||||
<mat-icon aria-hidden="true">
|
||||
zoom_in
|
||||
</mat-icon>
|
||||
</button>
|
||||
<button color="primary" mat-icon-button (click)="updateZoom(false)">
|
||||
<mat-icon aria-hidden="true">
|
||||
zoom_out
|
||||
</mat-icon>
|
||||
</button>
|
||||
<button
|
||||
color="primary"
|
||||
mat-icon-button
|
||||
matTooltip="Restore camera settings"
|
||||
(click)="resetCamera()"
|
||||
>
|
||||
<mat-icon aria-hidden="true">
|
||||
restore
|
||||
</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slider-view-controls">
|
||||
<div class="slider" [class.rotation]="true">
|
||||
<span class="slider-label">Rotation</span>
|
||||
<p class="slider-label mat-body-2">Rotation</p>
|
||||
<mat-slider
|
||||
step="0.001"
|
||||
min="0"
|
||||
@@ -73,10 +70,11 @@ import { ViewerEvents } from "viewers/common/viewer_events";
|
||||
aria-label="units"
|
||||
[value]="xCameraPos()"
|
||||
(input)="updateRotation($event.value!)"
|
||||
color="primary"
|
||||
></mat-slider>
|
||||
</div>
|
||||
<div class="slider" [class.spacing]="true">
|
||||
<span class="slider-label">Spacing</span>
|
||||
<p class="slider-label mat-body-2">Spacing</p>
|
||||
<mat-slider
|
||||
class="spacing-slider"
|
||||
step="0.001"
|
||||
@@ -85,111 +83,63 @@ import { ViewerEvents } from "viewers/common/viewer_events";
|
||||
aria-label="units"
|
||||
[value]="getLayerSeparation()"
|
||||
(input)="updateLayerSeparation($event.value!)"
|
||||
color="primary"
|
||||
></mat-slider>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-header>
|
||||
<mat-card-content class="rects-content">
|
||||
</div>
|
||||
<div class="rects-content">
|
||||
<div class="canvas-container">
|
||||
<canvas class="rects-canvas" (click)="onRectClick($event)" oncontextmenu="return false">
|
||||
</canvas>
|
||||
</div>
|
||||
<div class="tabs" *ngIf="displayIds.length > 1">
|
||||
<button mat-raised-button *ngFor="let displayId of displayIds" (click)="changeDisplayId(displayId)">{{displayId}}</button>
|
||||
<div *ngIf="displayIds.length > 1" class="tabs">
|
||||
<button color="primary" mat-raised-button *ngFor="let displayId of displayIds" (click)="changeDisplayId(displayId)">{{displayId}}</button>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
@import 'https://fonts.googleapis.com/icon?family=Material+Icons';
|
||||
|
||||
:host /deep/ .mat-card-header-text {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
.view-controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-bottom: 1px solid var(--default-border);
|
||||
}
|
||||
.rects-title {
|
||||
font-size: 16px;
|
||||
font-weight: medium;
|
||||
font-family: inherit;
|
||||
width: 100%;
|
||||
.top-view-controls, .slider-view-controls {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.rects-content {
|
||||
position: relative;
|
||||
.right-btn-container {
|
||||
margin-left: auto;
|
||||
}
|
||||
.canvas-container {
|
||||
height: 40rem;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.labels-canvas, .rects-canvas {
|
||||
height: 40rem;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
}
|
||||
.rects-canvas {
|
||||
cursor: pointer;
|
||||
}
|
||||
.view-controls {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
min-height: 4rem;
|
||||
width: 100%;
|
||||
}
|
||||
.slider-view-controls, .top-view-controls {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
height: 3rem;
|
||||
width: 100%;
|
||||
}
|
||||
.top-view-controls {
|
||||
vertical-align: middle;
|
||||
.slider-view-controls {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.slider {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
.slider-label {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
.slider.spacing {
|
||||
float: right;
|
||||
.rects-content {
|
||||
height: 0;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.slider span, .slider mat-slider {
|
||||
display: block;
|
||||
padding-left: 0px;
|
||||
padding-top: 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.right-btn-container {
|
||||
.canvas-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
float: right;
|
||||
}
|
||||
.right-btn {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
.labels-canvas, .rects-canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
.rects-checkbox {
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
margin-left: 5px;
|
||||
}
|
||||
mat-icon {
|
||||
margin: 5px
|
||||
}
|
||||
.mat-checkbox .mat-checkbox-frame, .mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-indeterminate .mat-checkbox-background {
|
||||
transform: scale(0.7);
|
||||
}
|
||||
.control-item {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
align-items: center;
|
||||
.rects-canvas {
|
||||
cursor: pointer;
|
||||
}
|
||||
`
|
||||
]
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
export const nodeStyles = `
|
||||
.node {position: relative;display: inline-block;padding: 2px; height: 100%; width: 100%;}
|
||||
.node {position: relative;display: inline-block;padding: 2px 0; width: 100%;}
|
||||
.node.clickable {cursor: pointer;}
|
||||
.node:not(.selected).added,
|
||||
.node:not(.selected).addedMove {
|
||||
@@ -59,12 +59,18 @@ export const nodeInnerItemStyles = `
|
||||
.pin-node-btn {padding: 0; transform: scale(0.7)}
|
||||
.description {align-items: center; flex: 1 1 auto; vertical-align: middle; word-break: break-all;}
|
||||
.leaf-node-icon-wrapper{padding-left: 6px; padding-right: 6px; min-height: 24px; width: 24px; position:relative; align-content: center; vertical-align: middle;}
|
||||
.icon-button { background: none;border: none;display: inline-block;vertical-align: middle;}
|
||||
|
||||
.icon-button {
|
||||
background: none;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.expand-tree-btn {
|
||||
float: right;
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.expand-tree-btn.modified {
|
||||
|
||||
@@ -14,15 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
export const treeNodeDataViewStyles = `
|
||||
.kind {font-weight: bold}
|
||||
|
||||
span {overflow-wrap: break-word; flex: 1 1 auto; width: 0; word-break: break-all}
|
||||
|
||||
.tree-view-internal-chip {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tree-view-chip {
|
||||
margin: 0 5px;
|
||||
padding: 0 10px;
|
||||
border-radius: 10px;
|
||||
background-color: #aaa;
|
||||
@@ -31,22 +28,18 @@ export const treeNodeDataViewStyles = `
|
||||
|
||||
.tree-view-chip.tree-view-chip-warn {
|
||||
background-color: #ffaa6b;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.tree-view-chip.tree-view-chip-error {
|
||||
background-color: #ff6b6b;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.tree-view-chip.tree-view-chip-gpu {
|
||||
background-color: #00c853;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.tree-view-chip.tree-view-chip-hwc {
|
||||
background-color: #448aff;
|
||||
color: black;
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -19,22 +19,36 @@ import { Transform } from "common/trace/flickerlib/common";
|
||||
@Component({
|
||||
selector: "transform-matrix",
|
||||
template: `
|
||||
<div class="matrix" *ngIf="transform" [matTooltip]="transform.getTypeAsString()">
|
||||
<div class="cell">{{ formatFloat(transform.matrix.dsdx) }}</div>
|
||||
<div class="cell">{{ formatFloat(transform.matrix.dsdy) }}</div>
|
||||
<div class="cell" matTooltip="Translate x">
|
||||
<div *ngIf="transform" class="matrix" [matTooltip]="transform.getTypeAsString()">
|
||||
<p class="cell mat-body-1">
|
||||
{{ formatFloat(transform.matrix.dsdx) }}
|
||||
</p>
|
||||
<p class="cell mat-body-1">
|
||||
{{ formatFloat(transform.matrix.dsdy) }}
|
||||
</p>
|
||||
<p class="cell mat-body-1" matTooltip="Translate x">
|
||||
{{ formatFloat(transform.matrix.tx) }}
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<div class="cell">{{ formatFloat(transform.matrix.dtdx) }}</div>
|
||||
<div class="cell">{{ formatFloat(transform.matrix.dtdy) }}</div>
|
||||
<div class="cell" matTooltip="Translate y">
|
||||
<p class="cell mat-body-1">
|
||||
{{ formatFloat(transform.matrix.dtdx) }}
|
||||
</p>
|
||||
<p class="cell mat-body-1">
|
||||
{{ formatFloat(transform.matrix.dtdy) }}
|
||||
</p>
|
||||
<p class="cell mat-body-1" matTooltip="Translate y">
|
||||
{{ formatFloat(transform.matrix.ty) }}
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<div class="cell">0</div>
|
||||
<div class="cell">0</div>
|
||||
<div class="cell">1</div>
|
||||
<p class="cell mat-body-1">
|
||||
0
|
||||
</p>
|
||||
<p class="cell mat-body-1">
|
||||
0
|
||||
</p>
|
||||
<p class="cell mat-body-1">
|
||||
1
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
@@ -43,10 +57,10 @@ import { Transform } from "common/trace/flickerlib/common";
|
||||
display: grid;
|
||||
grid-gap: 1px;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cell {
|
||||
padding-left: 10px;
|
||||
background-color: #F8F9FA;
|
||||
}
|
||||
`
|
||||
|
||||
@@ -22,56 +22,53 @@ import { TraceType } from "common/trace/trace_type";
|
||||
@Component({
|
||||
selector: "tree-view",
|
||||
template: `
|
||||
<div class="tree-view">
|
||||
<tree-node
|
||||
class="node"
|
||||
*ngIf="showNode(item)"
|
||||
[class.leaf]="isLeaf(this.item)"
|
||||
[class.selected]="isHighlighted(item, highlightedItems)"
|
||||
[class.clickable]="isClickable()"
|
||||
[class.shaded]="isShaded"
|
||||
[class.hover]="nodeHover"
|
||||
[class.childHover]="childHover"
|
||||
[isAlwaysCollapsed]="isAlwaysCollapsed"
|
||||
[class]="diffClass(item)"
|
||||
[style]="nodeOffsetStyle()"
|
||||
[item]="item"
|
||||
[flattened]="isFlattened"
|
||||
[isLeaf]="isLeaf(this.item)"
|
||||
[isCollapsed]="isAlwaysCollapsed ?? isCollapsed()"
|
||||
[hasChildren]="hasChildren()"
|
||||
[isPinned]="isPinned()"
|
||||
(toggleTreeChange)="toggleTree()"
|
||||
(click)="onNodeClick($event)"
|
||||
(expandTreeChange)="expandTree()"
|
||||
(pinNodeChange)="propagateNewPinnedItem($event)"
|
||||
></tree-node>
|
||||
<tree-node
|
||||
*ngIf="showNode(item)"
|
||||
class="node"
|
||||
[class.leaf]="isLeaf(this.item)"
|
||||
[class.selected]="isHighlighted(item, highlightedItems)"
|
||||
[class.clickable]="isClickable()"
|
||||
[class.shaded]="isShaded"
|
||||
[class.hover]="nodeHover"
|
||||
[class.childHover]="childHover"
|
||||
[isAlwaysCollapsed]="isAlwaysCollapsed"
|
||||
[class]="diffClass(item)"
|
||||
[style]="nodeOffsetStyle()"
|
||||
[item]="item"
|
||||
[flattened]="isFlattened"
|
||||
[isLeaf]="isLeaf(this.item)"
|
||||
[isCollapsed]="isAlwaysCollapsed ?? isCollapsed()"
|
||||
[hasChildren]="hasChildren()"
|
||||
[isPinned]="isPinned()"
|
||||
(toggleTreeChange)="toggleTree()"
|
||||
(click)="onNodeClick($event)"
|
||||
(expandTreeChange)="expandTree()"
|
||||
(pinNodeChange)="propagateNewPinnedItem($event)"
|
||||
></tree-node>
|
||||
|
||||
<div class="children" *ngIf="hasChildren()" [hidden]="!isCollapsed()" [style]="childrenIndentation()">
|
||||
<ng-container *ngFor="let child of children()">
|
||||
<tree-view
|
||||
class="childrenTree"
|
||||
[item]="child"
|
||||
[store]="store"
|
||||
[showNode]="showNode"
|
||||
[isLeaf]="isLeaf"
|
||||
[dependencies]="dependencies"
|
||||
[isFlattened]="isFlattened"
|
||||
[isShaded]="!isShaded"
|
||||
[useGlobalCollapsedState]="useGlobalCollapsedState"
|
||||
[initialDepth]="initialDepth + 1"
|
||||
[highlightedItems]="highlightedItems"
|
||||
[pinnedItems]="pinnedItems"
|
||||
(highlightedItemChange)="propagateNewHighlightedItem($event)"
|
||||
(pinnedItemChange)="propagateNewPinnedItem($event)"
|
||||
(selectedTreeChange)="propagateNewSelectedTree($event)"
|
||||
[itemsClickable]="itemsClickable"
|
||||
(hoverStart)="childHover = true"
|
||||
(hoverEnd)="childHover = false"
|
||||
></tree-view>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="hasChildren()" class="children" [hidden]="!isCollapsed()" [style]="childrenIndentation()">
|
||||
<tree-view
|
||||
*ngFor="let child of children()"
|
||||
class="childrenTree"
|
||||
[item]="child"
|
||||
[store]="store"
|
||||
[showNode]="showNode"
|
||||
[isLeaf]="isLeaf"
|
||||
[dependencies]="dependencies"
|
||||
[isFlattened]="isFlattened"
|
||||
[isShaded]="!isShaded"
|
||||
[useGlobalCollapsedState]="useGlobalCollapsedState"
|
||||
[initialDepth]="initialDepth + 1"
|
||||
[highlightedItems]="highlightedItems"
|
||||
[pinnedItems]="pinnedItems"
|
||||
(highlightedItemChange)="propagateNewHighlightedItem($event)"
|
||||
(pinnedItemChange)="propagateNewPinnedItem($event)"
|
||||
(selectedTreeChange)="propagateNewSelectedTree($event)"
|
||||
[itemsClickable]="itemsClickable"
|
||||
(hoverStart)="childHover = true"
|
||||
(hoverEnd)="childHover = false"
|
||||
></tree-view>
|
||||
</div>
|
||||
`,
|
||||
styles: [nodeStyles, treeNodeDataViewStyles]
|
||||
})
|
||||
|
||||
@@ -21,53 +21,50 @@ import { UiTreeUtils, UiTreeNode, DiffType, HierarchyTreeNode } from "viewers/co
|
||||
selector: "tree-node",
|
||||
template: `
|
||||
<button
|
||||
*ngIf="showChevron()"
|
||||
color="primary"
|
||||
class="icon-button toggle-tree-btn"
|
||||
(click)="toggleTree($event)"
|
||||
*ngIf="showChevron()"
|
||||
>
|
||||
<mat-icon class="icon-button">
|
||||
<mat-icon>
|
||||
{{isCollapsed ? "arrow_drop_down" : "chevron_right"}}
|
||||
</mat-icon>
|
||||
</button>
|
||||
|
||||
<div
|
||||
class="leaf-node-icon-wrapper"
|
||||
*ngIf="showLeafNodeIcon()"
|
||||
>
|
||||
<div *ngIf="showLeafNodeIcon()" class="leaf-node-icon-wrapper">
|
||||
<mat-icon class="leaf-node-icon"></mat-icon>
|
||||
</div>
|
||||
|
||||
<button
|
||||
*ngIf="showPinNodeIcon()"
|
||||
color="primary"
|
||||
class="icon-button pin-node-btn"
|
||||
(click)="pinNode($event)"
|
||||
*ngIf="showPinNodeIcon()"
|
||||
>
|
||||
<mat-icon class="icon-button">
|
||||
<mat-icon>
|
||||
{{isPinned ? "star" : "star_border"}}
|
||||
</mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="description">
|
||||
<tree-node-data-view
|
||||
[item]="item"
|
||||
*ngIf="!isPropertiesTreeNode()"
|
||||
[item]="item"
|
||||
></tree-node-data-view>
|
||||
<tree-node-properties-data-view
|
||||
[item]="item"
|
||||
*ngIf="isPropertiesTreeNode()"
|
||||
[item]="item"
|
||||
></tree-node-properties-data-view>
|
||||
</div>
|
||||
|
||||
<button
|
||||
*ngIf="hasChildren && !isCollapsed"
|
||||
(click)="expandTree($event)"
|
||||
color="primary"
|
||||
class="icon-button expand-tree-btn"
|
||||
[class]="collapseDiffClass"
|
||||
(click)="expandTree($event)"
|
||||
>
|
||||
<mat-icon
|
||||
aria-hidden="true"
|
||||
class="icon-button"
|
||||
>
|
||||
<mat-icon aria-hidden="true">
|
||||
more_horiz
|
||||
</mat-icon>
|
||||
</button>
|
||||
|
||||
@@ -21,11 +21,11 @@ import Chip from "viewers/common/chip";
|
||||
@Component({
|
||||
selector: "tree-node-data-view",
|
||||
template: `
|
||||
<span>
|
||||
<span class="kind">{{item.kind}}</span>
|
||||
<span *ngIf="item.kind && item.name">-</span>
|
||||
<span class="mat-body-1">
|
||||
<span class="mat-body-2">{{item.kind}}</span>
|
||||
<ng-container *ngIf="item.kind && item.name">&ngsp;-&ngsp;</ng-container>
|
||||
<span *ngIf="showShortName()" [matTooltip]="itemTooltip()">{{ itemShortName() }}</span>
|
||||
<span *ngIf="!showShortName()">{{item.name}}</span>
|
||||
<ng-container *ngIf="!showShortName()">{{item.name}}</ng-container>
|
||||
<div
|
||||
*ngFor="let chip of chips()"
|
||||
[class]="chipClass(chip)"
|
||||
|
||||
@@ -20,11 +20,13 @@ import { PropertiesTreeNode } from "viewers/common/ui_tree_utils";
|
||||
@Component({
|
||||
selector: "tree-node-properties-data-view",
|
||||
template: `
|
||||
<span>
|
||||
<p class="mat-body-1">
|
||||
<span class="key">{{ item.propertyKey }}</span>
|
||||
<span *ngIf="item.propertyValue">: </span>
|
||||
<span class="value" *ngIf="item.propertyValue" [class]="[valueClass()]">{{ item.propertyValue }}</span>
|
||||
</span>
|
||||
<ng-container *ngIf="item.propertyValue">
|
||||
:&ngsp;
|
||||
<span [class]="[valueClass()]" class="value">{{ item.propertyValue }}</span>
|
||||
</ng-container>
|
||||
</p>
|
||||
`,
|
||||
styles: [ treeNodePropertiesDataViewStyles ]
|
||||
})
|
||||
@@ -52,6 +54,7 @@ export class TreeNodePropertiesDataViewComponent {
|
||||
if (!isNaN(Number(this.item.propertyValue))) {
|
||||
return "number";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,98 +25,54 @@ import { ImeUiData } from "viewers/common/ime_ui_data";
|
||||
@Component({
|
||||
selector: "viewer-input-method",
|
||||
template: `
|
||||
<div fxLayout="row wrap" fxLayoutGap="10px grid" class="card-grid">
|
||||
<div class="card-grid">
|
||||
<div class="left-views">
|
||||
<mat-card class="hierarchy-view" [style]="hierarchyHeight()">
|
||||
<hierarchy-view
|
||||
[tree]="inputData?.tree ?? null"
|
||||
[dependencies]="inputData?.dependencies ?? []"
|
||||
[highlightedItems]="inputData?.highlightedItems ?? []"
|
||||
[pinnedItems]="inputData?.pinnedItems ?? []"
|
||||
[tableProperties]="inputData?.hierarchyTableProperties"
|
||||
[store]="store"
|
||||
[userOptions]="inputData?.hierarchyUserOptions ?? {}"
|
||||
></hierarchy-view>
|
||||
</mat-card>
|
||||
<mat-card *ngIf="inputData?.additionalProperties" class="ime-additional-properties-view">
|
||||
<ime-additional-properties
|
||||
[additionalProperties]="inputData?.additionalProperties!"
|
||||
></ime-additional-properties>
|
||||
</mat-card>
|
||||
<hierarchy-view
|
||||
class="hierarchy-view"
|
||||
[tree]="inputData?.tree ?? null"
|
||||
[dependencies]="inputData?.dependencies ?? []"
|
||||
[highlightedItems]="inputData?.highlightedItems ?? []"
|
||||
[pinnedItems]="inputData?.pinnedItems ?? []"
|
||||
[tableProperties]="inputData?.hierarchyTableProperties"
|
||||
[store]="store"
|
||||
[userOptions]="inputData?.hierarchyUserOptions ?? {}"
|
||||
></hierarchy-view>
|
||||
<ime-additional-properties
|
||||
*ngIf="inputData?.additionalProperties"
|
||||
class="ime-additional-properties-view"
|
||||
[additionalProperties]="inputData?.additionalProperties!"
|
||||
></ime-additional-properties>
|
||||
</div>
|
||||
<mat-card class="properties-view">
|
||||
<properties-view
|
||||
[userOptions]="inputData?.propertiesUserOptions ?? {}"
|
||||
[propertiesTree]="inputData?.propertiesTree ?? {}"
|
||||
></properties-view>
|
||||
</mat-card>
|
||||
<properties-view
|
||||
class="properties-view"
|
||||
[userOptions]="inputData?.propertiesUserOptions ?? {}"
|
||||
[propertiesTree]="inputData?.propertiesTree ?? {}"
|
||||
></properties-view>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
@import 'https://fonts.googleapis.com/icon?family=Material+Icons';
|
||||
:root {
|
||||
--default-border: #DADCE0;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
margin: 5px
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
background: none;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.header-button {
|
||||
background: none;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.card-grid {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.left-views {
|
||||
font: inherit;
|
||||
margin: 0px;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.hierarchy-view, .ime-additional-properties-view {
|
||||
font: inherit;
|
||||
margin: 0px;
|
||||
border-radius: 0;
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 1px solid var(--default-border);
|
||||
border-right: 1px solid var(--default-border);
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.ime-additional-properties-view {
|
||||
height: 404px;
|
||||
}
|
||||
|
||||
.properties-view {
|
||||
font: inherit;
|
||||
margin: 0px;
|
||||
width: 50%;
|
||||
height: 52.5rem;
|
||||
border-radius: 0;
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 1px solid var(--default-border);
|
||||
border-left: 1px solid var(--default-border);
|
||||
box-shadow: none !important;
|
||||
}
|
||||
`,
|
||||
]
|
||||
@@ -127,10 +83,4 @@ export class ViewerInputMethodComponent {
|
||||
@Input() active = false;
|
||||
TRACE_INFO = TRACE_INFO;
|
||||
TraceType = TraceType;
|
||||
|
||||
public hierarchyHeight() {
|
||||
return {
|
||||
height: `${this.inputData?.additionalProperties ? 404 : 840}px`
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,102 +25,63 @@ import { PersistentStore } from "common/persistent_store";
|
||||
@Component({
|
||||
selector: "viewer-surface-flinger",
|
||||
template: `
|
||||
<div fxLayout="row wrap" fxLayoutGap="10px grid" class="card-grid">
|
||||
<mat-card id="sf-rects-view" class="rects-view">
|
||||
<rects-view
|
||||
[rects]="inputData?.rects ?? []"
|
||||
[highlightedItems]="inputData?.highlightedItems ?? []"
|
||||
[displayIds]="inputData?.displayIds ?? []"
|
||||
[forceRefresh]="active"
|
||||
[hasVirtualDisplays]="inputData?.hasVirtualDisplays ?? false"
|
||||
></rects-view>
|
||||
</mat-card>
|
||||
<div fxLayout="row wrap" fxLayoutGap="10px grid" class="card-grid">
|
||||
<mat-card id="sf-hierarchy-view" class="hierarchy-view">
|
||||
<hierarchy-view
|
||||
[tree]="inputData?.tree ?? null"
|
||||
[dependencies]="inputData?.dependencies ?? []"
|
||||
[highlightedItems]="inputData?.highlightedItems ?? []"
|
||||
[pinnedItems]="inputData?.pinnedItems ?? []"
|
||||
[store]="store"
|
||||
[userOptions]="inputData?.hierarchyUserOptions ?? {}"
|
||||
></hierarchy-view>
|
||||
</mat-card>
|
||||
<mat-card id="sf-properties-view" class="properties-view">
|
||||
<properties-view
|
||||
[userOptions]="inputData?.propertiesUserOptions ?? {}"
|
||||
[propertiesTree]="inputData?.propertiesTree ?? {}"
|
||||
[selectedFlickerItem]="inputData?.selectedLayer ?? {}"
|
||||
[propertyGroups]="true"
|
||||
[isProtoDump]="true"
|
||||
></properties-view>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-grid">
|
||||
<rects-view
|
||||
id="sf-rects-view"
|
||||
class="rects-view"
|
||||
[rects]="inputData?.rects ?? []"
|
||||
[highlightedItems]="inputData?.highlightedItems ?? []"
|
||||
[displayIds]="inputData?.displayIds ?? []"
|
||||
[forceRefresh]="active"
|
||||
[hasVirtualDisplays]="inputData?.hasVirtualDisplays ?? false"
|
||||
></rects-view>
|
||||
<hierarchy-view
|
||||
id="sf-hierarchy-view"
|
||||
class="hierarchy-view"
|
||||
[tree]="inputData?.tree ?? null"
|
||||
[dependencies]="inputData?.dependencies ?? []"
|
||||
[highlightedItems]="inputData?.highlightedItems ?? []"
|
||||
[pinnedItems]="inputData?.pinnedItems ?? []"
|
||||
[store]="store"
|
||||
[userOptions]="inputData?.hierarchyUserOptions ?? {}"
|
||||
></hierarchy-view>
|
||||
<properties-view
|
||||
id="sf-properties-view"
|
||||
class="properties-view"
|
||||
[userOptions]="inputData?.propertiesUserOptions ?? {}"
|
||||
[propertiesTree]="inputData?.propertiesTree ?? {}"
|
||||
[selectedFlickerItem]="inputData?.selectedLayer ?? {}"
|
||||
[propertyGroups]="true"
|
||||
[isProtoDump]="true"
|
||||
></properties-view>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
@import 'https://fonts.googleapis.com/icon?family=Material+Icons';
|
||||
:root {
|
||||
--default-border: #DADCE0;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
margin: 5px
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
background: none;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.header-button {
|
||||
background: none;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.card-grid {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.rects-view {
|
||||
font: inherit;
|
||||
flex: none;
|
||||
width: 350px;
|
||||
height: 52.5rem;
|
||||
margin: 0px;
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 1px solid var(--default-border);
|
||||
border-right: 1px solid var(--default-border);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.hierarchy-view {
|
||||
font: inherit;
|
||||
margin: 0px;
|
||||
width: 50%;
|
||||
height: 52.5rem;
|
||||
border-radius: 0;
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 1px solid var(--default-border);
|
||||
border-right: 1px solid var(--default-border);
|
||||
border-left: 1px solid var(--default-border);
|
||||
}
|
||||
|
||||
.properties-view {
|
||||
font: inherit;
|
||||
margin: 0px;
|
||||
width: 50%;
|
||||
height: 52.5rem;
|
||||
border-radius: 0;
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 1px solid var(--default-border);
|
||||
border-left: 1px solid var(--default-border);
|
||||
}
|
||||
`,
|
||||
]
|
||||
|
||||
@@ -25,99 +25,60 @@ import { PersistentStore } from "common/persistent_store";
|
||||
@Component({
|
||||
selector: "viewer-window-manager",
|
||||
template: `
|
||||
<div fxLayout="row wrap" fxLayoutGap="10px grid" class="card-grid">
|
||||
<mat-card id="wm-rects-view" class="rects-view">
|
||||
<rects-view
|
||||
[rects]="inputData?.rects ?? []"
|
||||
[displayIds]="inputData?.displayIds ?? []"
|
||||
[highlightedItems]="inputData?.highlightedItems ?? []"
|
||||
[forceRefresh]="active"
|
||||
></rects-view>
|
||||
</mat-card>
|
||||
<div fxLayout="row wrap" fxLayoutGap="10px grid" class="card-grid">
|
||||
<mat-card id="wm-hierarchy-view" class="hierarchy-view">
|
||||
<hierarchy-view
|
||||
[tree]="inputData?.tree ?? null"
|
||||
[dependencies]="inputData?.dependencies ?? []"
|
||||
[highlightedItems]="inputData?.highlightedItems ?? []"
|
||||
[pinnedItems]="inputData?.pinnedItems ?? []"
|
||||
[store]="store"
|
||||
[userOptions]="inputData?.hierarchyUserOptions ?? {}"
|
||||
></hierarchy-view>
|
||||
</mat-card>
|
||||
<mat-card id="wm-properties-view" class="properties-view">
|
||||
<properties-view
|
||||
[userOptions]="inputData?.propertiesUserOptions ?? {}"
|
||||
[propertiesTree]="inputData?.propertiesTree ?? {}"
|
||||
[isProtoDump]="true"
|
||||
></properties-view>
|
||||
</mat-card>
|
||||
</div>
|
||||
<div class="card-grid">
|
||||
<rects-view
|
||||
id="wm-rects-view"
|
||||
class="rects-view"
|
||||
[rects]="inputData?.rects ?? []"
|
||||
[displayIds]="inputData?.displayIds ?? []"
|
||||
[highlightedItems]="inputData?.highlightedItems ?? []"
|
||||
[forceRefresh]="active"
|
||||
></rects-view>
|
||||
<hierarchy-view
|
||||
id="wm-hierarchy-view"
|
||||
class="hierarchy-view"
|
||||
[tree]="inputData?.tree ?? null"
|
||||
[dependencies]="inputData?.dependencies ?? []"
|
||||
[highlightedItems]="inputData?.highlightedItems ?? []"
|
||||
[pinnedItems]="inputData?.pinnedItems ?? []"
|
||||
[store]="store"
|
||||
[userOptions]="inputData?.hierarchyUserOptions ?? {}"
|
||||
></hierarchy-view>
|
||||
<properties-view
|
||||
id="wm-properties-view"
|
||||
class="properties-view"
|
||||
[userOptions]="inputData?.propertiesUserOptions ?? {}"
|
||||
[propertiesTree]="inputData?.propertiesTree ?? {}"
|
||||
[isProtoDump]="true"
|
||||
></properties-view>
|
||||
</div>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
@import 'https://fonts.googleapis.com/icon?family=Material+Icons';
|
||||
:root {
|
||||
--default-border: #DADCE0;
|
||||
}
|
||||
|
||||
mat-icon {
|
||||
margin: 5px
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
background: none;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.header-button {
|
||||
background: none;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.card-grid {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.rects-view {
|
||||
font: inherit;
|
||||
flex: none;
|
||||
width: 350px;
|
||||
height: 52.5rem;
|
||||
margin: 0px;
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 1px solid var(--default-border);
|
||||
border-right: 1px solid var(--default-border);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.hierarchy-view {
|
||||
font: inherit;
|
||||
margin: 0px;
|
||||
width: 50%;
|
||||
height: 52.5rem;
|
||||
border-radius: 0;
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 1px solid var(--default-border);
|
||||
border-right: 1px solid var(--default-border);
|
||||
border-left: 1px solid var(--default-border);
|
||||
}
|
||||
|
||||
.properties-view {
|
||||
font: inherit;
|
||||
margin: 0px;
|
||||
width: 50%;
|
||||
height: 52.5rem;
|
||||
border-radius: 0;
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 1px solid var(--default-border);
|
||||
border-left: 1px solid var(--default-border);
|
||||
}
|
||||
`,
|
||||
]
|
||||
|
||||
@@ -46,6 +46,10 @@ module.exports = {
|
||||
test: /\.css$/,
|
||||
use: ["style-loader", "css-loader"]
|
||||
},
|
||||
{
|
||||
test: /\.s[ac]ss$/i,
|
||||
use: ["style-loader", "css-loader", "sass-loader"]
|
||||
},
|
||||
{
|
||||
test: /\.proto$/,
|
||||
loader: 'proto-loader',
|
||||
|
||||
@@ -20,7 +20,10 @@ const configDev = {
|
||||
mode: 'development',
|
||||
entry: {
|
||||
polyfills: "./src/polyfills.ts",
|
||||
styles: "./src/styles.css",
|
||||
styles: [
|
||||
"./src/material-theme.scss",
|
||||
"./src/styles.css"
|
||||
],
|
||||
app: "./src/main.dev.ts"
|
||||
},
|
||||
devtool: "source-map",
|
||||
|
||||
@@ -23,7 +23,10 @@ const configProd = {
|
||||
mode: 'production',
|
||||
entry: {
|
||||
polyfills: "./src/polyfills.ts",
|
||||
styles: "./src/styles.css",
|
||||
styles: [
|
||||
"./src/material-theme.scss",
|
||||
"./src/styles.css"
|
||||
],
|
||||
app: "./src/main.prod.ts"
|
||||
},
|
||||
output: {
|
||||
|
||||
Reference in New Issue
Block a user