xref: /aosp_15_r20/external/perfetto/ui/src/components/widgets/duration.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker// Copyright (C) 2023 The Android Open Source Project
2*6dbdd20aSAndroid Build Coastguard Worker//
3*6dbdd20aSAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*6dbdd20aSAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*6dbdd20aSAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*6dbdd20aSAndroid Build Coastguard Worker//
7*6dbdd20aSAndroid Build Coastguard Worker//      http://www.apache.org/licenses/LICENSE-2.0
8*6dbdd20aSAndroid Build Coastguard Worker//
9*6dbdd20aSAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*6dbdd20aSAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*6dbdd20aSAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*6dbdd20aSAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*6dbdd20aSAndroid Build Coastguard Worker// limitations under the License.
14*6dbdd20aSAndroid Build Coastguard Worker
15*6dbdd20aSAndroid Build Coastguard Workerimport m from 'mithril';
16*6dbdd20aSAndroid Build Coastguard Workerimport {copyToClipboard} from '../../base/clipboard';
17*6dbdd20aSAndroid Build Coastguard Workerimport {assertExists} from '../../base/logging';
18*6dbdd20aSAndroid Build Coastguard Workerimport {Icons} from '../../base/semantic_icons';
19*6dbdd20aSAndroid Build Coastguard Workerimport {duration} from '../../base/time';
20*6dbdd20aSAndroid Build Coastguard Workerimport {AppImpl} from '../../core/app_impl';
21*6dbdd20aSAndroid Build Coastguard Workerimport {Anchor} from '../../widgets/anchor';
22*6dbdd20aSAndroid Build Coastguard Workerimport {MenuDivider, MenuItem, PopupMenu2} from '../../widgets/menu';
23*6dbdd20aSAndroid Build Coastguard Workerimport {Trace} from '../../public/trace';
24*6dbdd20aSAndroid Build Coastguard Workerimport {formatDuration} from '../time_utils';
25*6dbdd20aSAndroid Build Coastguard Workerimport {DurationPrecisionMenuItem} from './duration_precision_menu_items';
26*6dbdd20aSAndroid Build Coastguard Workerimport {TimestampFormatMenuItem} from './timestamp_format_menu';
27*6dbdd20aSAndroid Build Coastguard Worker
28*6dbdd20aSAndroid Build Coastguard Workerinterface DurationWidgetAttrs {
29*6dbdd20aSAndroid Build Coastguard Worker  dur: duration;
30*6dbdd20aSAndroid Build Coastguard Worker  extraMenuItems?: m.Child[];
31*6dbdd20aSAndroid Build Coastguard Worker}
32*6dbdd20aSAndroid Build Coastguard Worker
33*6dbdd20aSAndroid Build Coastguard Workerexport class DurationWidget implements m.ClassComponent<DurationWidgetAttrs> {
34*6dbdd20aSAndroid Build Coastguard Worker  private readonly trace: Trace;
35*6dbdd20aSAndroid Build Coastguard Worker
36*6dbdd20aSAndroid Build Coastguard Worker  constructor() {
37*6dbdd20aSAndroid Build Coastguard Worker    // TODO(primiano): the Trace object should be injected into the attrs, but
38*6dbdd20aSAndroid Build Coastguard Worker    // there are too many users of this class and doing so requires a larger
39*6dbdd20aSAndroid Build Coastguard Worker    // refactoring CL. Either that or we should find a different way to plumb
40*6dbdd20aSAndroid Build Coastguard Worker    // the hoverCursorTimestamp.
41*6dbdd20aSAndroid Build Coastguard Worker    this.trace = assertExists(AppImpl.instance.trace);
42*6dbdd20aSAndroid Build Coastguard Worker  }
43*6dbdd20aSAndroid Build Coastguard Worker
44*6dbdd20aSAndroid Build Coastguard Worker  view({attrs}: m.Vnode<DurationWidgetAttrs>) {
45*6dbdd20aSAndroid Build Coastguard Worker    const {dur} = attrs;
46*6dbdd20aSAndroid Build Coastguard Worker
47*6dbdd20aSAndroid Build Coastguard Worker    if (dur === -1n) {
48*6dbdd20aSAndroid Build Coastguard Worker      return '(Did not end)';
49*6dbdd20aSAndroid Build Coastguard Worker    }
50*6dbdd20aSAndroid Build Coastguard Worker
51*6dbdd20aSAndroid Build Coastguard Worker    return m(
52*6dbdd20aSAndroid Build Coastguard Worker      PopupMenu2,
53*6dbdd20aSAndroid Build Coastguard Worker      {
54*6dbdd20aSAndroid Build Coastguard Worker        trigger: m(Anchor, formatDuration(this.trace, dur)),
55*6dbdd20aSAndroid Build Coastguard Worker      },
56*6dbdd20aSAndroid Build Coastguard Worker      m(MenuItem, {
57*6dbdd20aSAndroid Build Coastguard Worker        icon: Icons.Copy,
58*6dbdd20aSAndroid Build Coastguard Worker        label: `Copy raw value`,
59*6dbdd20aSAndroid Build Coastguard Worker        onclick: () => {
60*6dbdd20aSAndroid Build Coastguard Worker          copyToClipboard(dur.toString());
61*6dbdd20aSAndroid Build Coastguard Worker        },
62*6dbdd20aSAndroid Build Coastguard Worker      }),
63*6dbdd20aSAndroid Build Coastguard Worker      m(TimestampFormatMenuItem, {trace: this.trace}),
64*6dbdd20aSAndroid Build Coastguard Worker      m(DurationPrecisionMenuItem, {trace: this.trace}),
65*6dbdd20aSAndroid Build Coastguard Worker      attrs.extraMenuItems ? [m(MenuDivider), attrs.extraMenuItems] : null,
66*6dbdd20aSAndroid Build Coastguard Worker    );
67*6dbdd20aSAndroid Build Coastguard Worker  }
68*6dbdd20aSAndroid Build Coastguard Worker}
69