xref: /aosp_15_r20/external/perfetto/ui/src/widgets/hotkey_glyphs.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1// Copyright (C) 2023 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';
16import {getPlatform, Hotkey, Key, parseHotkey, Platform} from '../base/hotkeys';
17import {Icon} from './icon';
18
19export interface HotkeyGlyphsAttrs {
20  hotkey: Hotkey;
21  spoof?: Platform;
22}
23
24// Renders a hotkey as a series of little keycaps.
25export class HotkeyGlyphs implements m.ClassComponent<HotkeyGlyphsAttrs> {
26  view({attrs}: m.Vnode<HotkeyGlyphsAttrs>) {
27    const {hotkey, spoof} = attrs;
28
29    const platform = spoof || getPlatform();
30    const result = parseHotkey(hotkey);
31    if (result) {
32      const {key, modifier} = result;
33      const hasMod = modifier.includes('Mod');
34      const hasCtrl = modifier.includes('Ctrl');
35      const hasAlt = modifier.includes('Alt');
36      const hasShift = modifier.includes('Shift');
37
38      return m(
39        'span.pf-hotkey',
40        hasMod && m('span.pf-keycap', glyphForMod(platform)),
41        hasCtrl && m('span.pf-keycap', glyphForCtrl(platform)),
42        hasAlt && m('span.pf-keycap', glyphForAlt(platform)),
43        hasShift && m('span.pf-keycap', glyphForShift()),
44        m('span.pf-keycap', glyphForKey(key, platform)),
45      );
46    } else {
47      return m('span.pf-keycap', '???');
48    }
49  }
50}
51
52export interface KeycapGlyphsAttrs {
53  keyValue: Key;
54  spoof?: Platform;
55}
56
57// Renders a single keycap.
58export class KeycapGlyph implements m.ClassComponent<KeycapGlyphsAttrs> {
59  view({attrs}: m.Vnode<KeycapGlyphsAttrs>) {
60    const {keyValue, spoof} = attrs;
61    const platform = spoof || getPlatform();
62    return m('span.pf-keycap', glyphForKey(keyValue, platform));
63  }
64}
65
66function glyphForKey(key: Key, platform: Platform): m.Children {
67  if (key === 'Enter') {
68    return m(Icon, {icon: 'keyboard_return'});
69  } else if (key === 'ArrowUp') {
70    return m(Icon, {icon: 'arrow_upward'});
71  } else if (key === 'ArrowDown') {
72    return m(Icon, {icon: 'arrow_downward'});
73  } else if (key === 'Space') {
74    return m(Icon, {icon: 'space_bar'});
75  } else if (key === 'Escape') {
76    if (platform === 'Mac') {
77      return 'esc';
78    } else {
79      return 'Esc';
80    }
81  } else {
82    return key;
83  }
84}
85
86function glyphForMod(platform: Platform): m.Children {
87  if (platform === 'Mac') {
88    return m(Icon, {icon: 'keyboard_command_key'});
89  } else {
90    return 'Ctrl';
91  }
92}
93
94function glyphForShift(): m.Children {
95  return m(Icon, {icon: 'shift'});
96}
97
98function glyphForCtrl(platform: Platform): m.Children {
99  if (platform === 'Mac') {
100    return m(Icon, {icon: 'keyboard_control_key'});
101  } else {
102    return 'Ctrl';
103  }
104}
105
106function glyphForAlt(platform: Platform): m.Children {
107  if (platform === 'Mac') {
108    return m(Icon, {icon: 'keyboard_option_key'});
109  } else {
110    return 'Alt';
111  }
112}
113