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