• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import {Component, ElementRef, Inject, Input} from '@angular/core';
17import {TraceTreeNode} from 'trace/trace_tree_node';
18import {PropertiesTreeNode, Terminal} from 'viewers/common/ui_tree_utils';
19import {UserOptions} from 'viewers/common/user_options';
20import {ViewerEvents} from 'viewers/common/viewer_events';
21
22@Component({
23  selector: 'properties-view',
24  template: `
25    <div class="view-header" [class.view-header-with-property-groups]="displayPropertyGroups">
26      <div class="title-filter">
27        <h2 class="properties-title mat-title">Properties</h2>
28
29        <mat-form-field>
30          <mat-label>Filter...</mat-label>
31
32          <input matInput [(ngModel)]="filterString" (ngModelChange)="filterTree()" name="filter" />
33        </mat-form-field>
34      </div>
35
36      <div class="view-controls">
37        <mat-checkbox
38          *ngFor="let option of objectKeys(userOptions)"
39          color="primary"
40          [(ngModel)]="userOptions[option].enabled"
41          (ngModelChange)="updateTree()"
42          [matTooltip]="userOptions[option].tooltip ?? ''"
43          >{{ userOptions[option].name }}</mat-checkbox
44        >
45      </div>
46
47      <property-groups
48        *ngIf="itemIsSelected() && displayPropertyGroups"
49        class="property-groups"
50        [item]="selectedFlickerItem"></property-groups>
51    </div>
52
53    <mat-divider></mat-divider>
54
55    <div class="properties-content">
56      <h3
57        *ngIf="objectKeys(propertiesTree).length > 0 && isProtoDump"
58        class="properties-title mat-subheading-2">
59        Properties - Proto Dump
60      </h3>
61
62      <div class="tree-wrapper">
63        <tree-view
64          *ngIf="objectKeys(propertiesTree).length > 0"
65          [item]="propertiesTree"
66          [showNode]="showNode"
67          [isLeaf]="isLeaf"
68          [isAlwaysCollapsed]="true"></tree-view>
69      </div>
70    </div>
71  `,
72  styles: [
73    `
74      .view-header {
75        display: flex;
76        flex-direction: column;
77        overflow-y: auto;
78        margin-bottom: 12px;
79      }
80
81      .view-header-with-property-groups {
82        flex: 3;
83      }
84
85      .title-filter {
86        display: flex;
87        flex-direction: row;
88        flex-wrap: wrap;
89        justify-content: space-between;
90      }
91
92      .view-controls {
93        display: flex;
94        flex-direction: row;
95        flex-wrap: wrap;
96        column-gap: 10px;
97        margin-bottom: 16px;
98      }
99
100      .properties-content {
101        flex: 1;
102        display: flex;
103        flex-direction: column;
104        overflow-y: auto;
105      }
106
107      .property-groups {
108        height: 100%;
109        overflow-y: auto;
110      }
111
112      .tree-wrapper {
113        overflow: auto;
114      }
115    `,
116  ],
117})
118export class PropertiesComponent {
119  objectKeys = Object.keys;
120  filterString = '';
121
122  @Input() userOptions: UserOptions = {};
123  @Input() propertiesTree: PropertiesTreeNode = {};
124  @Input() selectedFlickerItem: TraceTreeNode | null = null;
125  @Input() displayPropertyGroups = false;
126  @Input() isProtoDump = false;
127
128  constructor(@Inject(ElementRef) private elementRef: ElementRef) {}
129
130  filterTree() {
131    const event: CustomEvent = new CustomEvent(ViewerEvents.PropertiesFilterChange, {
132      bubbles: true,
133      detail: {filterString: this.filterString},
134    });
135    this.elementRef.nativeElement.dispatchEvent(event);
136  }
137
138  updateTree() {
139    const event: CustomEvent = new CustomEvent(ViewerEvents.PropertiesUserOptionsChange, {
140      bubbles: true,
141      detail: {userOptions: this.userOptions},
142    });
143    this.elementRef.nativeElement.dispatchEvent(event);
144  }
145
146  showNode(item: any) {
147    return (
148      !(item instanceof Terminal) &&
149      !(item.name instanceof Terminal) &&
150      !(item.propertyKey instanceof Terminal)
151    );
152  }
153
154  isLeaf(item: any) {
155    return (
156      !item.children ||
157      item.children.length === 0 ||
158      item.children.filter((c: any) => !(c instanceof Terminal)).length === 0
159    );
160  }
161
162  itemIsSelected() {
163    return this.selectedFlickerItem && Object.keys(this.selectedFlickerItem).length > 0;
164  }
165}
166