• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2022 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import m from 'mithril';
16
17import {Engine} from '../trace_processor/engine';
18
19export interface NewBottomTabArgs<Config> {
20  engine: Engine;
21  tag?: string;
22  uuid: string;
23  config: Config;
24}
25
26// An interface representing a bottom tab displayed on the panel in the bottom
27// of the ui (e.g. "Current Selection").
28//
29// The implementations of this class are provided by different plugins, which
30// register the implementations with bottomTabRegistry, keyed by a unique name
31// for each type of BottomTab.
32//
33// Lifetime: the instances of this class are owned by BottomTabPanel and exist
34// for as long as a tab header is shown to the user in the bottom tab list (with
35// minor exceptions, like a small grace period between when the tab is related).
36//
37// BottomTab implementations should pass the unique identifier(s) for the
38// content displayed via the |Config| and fetch additional details via Engine
39// instead of relying on getting the data from the global storage. For example,
40// for tabs corresponding to details of the selected objects on a track, a new
41// BottomTab should be created for each new selection.
42export abstract class BottomTabBase<Config = {}> {
43  // Config for this details panel. Should be serializable.
44  protected readonly config: Config;
45  // Engine for running queries and fetching additional data.
46  protected readonly engine: Engine;
47  // Optional tag, which is used to ensure that only one tab
48  // with the same tag can exist - adding a new tab with the same tag
49  // (e.g. 'current_selection') would close the previous one. This
50  // also can be used to close existing tab.
51  readonly tag?: string;
52  // Unique id for this details panel. Can be used to close previously opened
53  // panel.
54  readonly uuid: string;
55
56  constructor(args: NewBottomTabArgs<Config>) {
57    this.config = args.config;
58    this.engine = args.engine;
59    this.tag = args.tag;
60    this.uuid = args.uuid;
61  }
62
63  // Entry point for customisation of the displayed title for this panel.
64  abstract getTitle(): string;
65
66  // Generate a mithril node for this component.
67  abstract renderPanel(): m.Children;
68
69  // API for the tab to notify the TabList that it's still preparing the data.
70  // If true, adding a new tab will be delayed for a short while (~50ms) to
71  // reduce the flickering.
72  //
73  // Note: it's a "poll" rather than "push" API: there is no explicit API
74  // for the tabs to notify the tab list, as the tabs are expected to schedule
75  // global redraw anyway and the tab list will poll the tabs as necessary
76  // during the redraw.
77  isLoading(): boolean {
78    return false;
79  }
80}
81
82// BottomTabBase provides a more generic API allowing users to provide their
83// custom mithril component, which would allow them to listen to mithril
84// lifecycle events. Most cases, however, don't need them and BottomTab
85// provides a simplified API for the common case.
86export abstract class BottomTab<Config = {}> extends BottomTabBase<Config> {
87  constructor(args: NewBottomTabArgs<Config>) {
88    super(args);
89  }
90
91  abstract viewTab(): m.Children;
92
93  renderPanel(): m.Children {
94    return m(BottomTabAdapter, {
95      key: this.uuid,
96      panel: this,
97    } as BottomTabAdapterAttrs);
98  }
99}
100
101interface BottomTabAdapterAttrs {
102  panel: BottomTab;
103}
104
105class BottomTabAdapter implements m.ClassComponent<BottomTabAdapterAttrs> {
106  view(vnode: m.CVnode<BottomTabAdapterAttrs>): void | m.Children {
107    return vnode.attrs.panel.viewTab();
108  }
109}
110