| // Copyright (C) 2023 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| import m from 'mithril'; |
| import {getPlatform, Hotkey, Key, parseHotkey, Platform} from '../base/hotkeys'; |
| import {Icon} from './icon'; |
| |
| export interface HotkeyGlyphsAttrs { |
| hotkey: Hotkey; |
| spoof?: Platform; |
| } |
| |
| // Renders a hotkey as a series of little keycaps. |
| export class HotkeyGlyphs implements m.ClassComponent<HotkeyGlyphsAttrs> { |
| view({attrs}: m.Vnode<HotkeyGlyphsAttrs>) { |
| const {hotkey, spoof} = attrs; |
| |
| const platform = spoof || getPlatform(); |
| const result = parseHotkey(hotkey); |
| if (result) { |
| const {key, modifier} = result; |
| const hasMod = modifier.includes('Mod'); |
| const hasCtrl = modifier.includes('Ctrl'); |
| const hasAlt = modifier.includes('Alt'); |
| const hasShift = modifier.includes('Shift'); |
| |
| return m( |
| 'span.pf-hotkey', |
| hasMod && m('span.pf-keycap', glyphForMod(platform)), |
| hasCtrl && m('span.pf-keycap', glyphForCtrl(platform)), |
| hasAlt && m('span.pf-keycap', glyphForAlt(platform)), |
| hasShift && m('span.pf-keycap', glyphForShift()), |
| m('span.pf-keycap', glyphForKey(key, platform)), |
| ); |
| } else { |
| return m('span.pf-keycap', '???'); |
| } |
| } |
| } |
| |
| export interface KeycapGlyphsAttrs { |
| keyValue: Key; |
| spoof?: Platform; |
| } |
| |
| // Renders a single keycap. |
| export class KeycapGlyph implements m.ClassComponent<KeycapGlyphsAttrs> { |
| view({attrs}: m.Vnode<KeycapGlyphsAttrs>) { |
| const {keyValue, spoof} = attrs; |
| const platform = spoof || getPlatform(); |
| return m('span.pf-keycap', glyphForKey(keyValue, platform)); |
| } |
| } |
| |
| function glyphForKey(key: Key, platform: Platform): m.Children { |
| if (key === 'Enter') { |
| return m(Icon, {icon: 'keyboard_return'}); |
| } else if (key === 'ArrowUp') { |
| return m(Icon, {icon: 'arrow_upward'}); |
| } else if (key === 'ArrowDown') { |
| return m(Icon, {icon: 'arrow_downward'}); |
| } else if (key === 'Space') { |
| return m(Icon, {icon: 'space_bar'}); |
| } else if (key === 'Escape') { |
| if (platform === 'Mac') { |
| return 'esc'; |
| } else { |
| return 'Esc'; |
| } |
| } else { |
| return key; |
| } |
| } |
| |
| function glyphForMod(platform: Platform): m.Children { |
| if (platform === 'Mac') { |
| return m(Icon, {icon: 'keyboard_command_key'}); |
| } else { |
| return 'Ctrl'; |
| } |
| } |
| |
| function glyphForShift(): m.Children { |
| return m(Icon, {icon: 'shift'}); |
| } |
| |
| function glyphForCtrl(platform: Platform): m.Children { |
| if (platform === 'Mac') { |
| return m(Icon, {icon: 'keyboard_control_key'}); |
| } else { |
| return 'Ctrl'; |
| } |
| } |
| |
| function glyphForAlt(platform: Platform): m.Children { |
| if (platform === 'Mac') { |
| return m(Icon, {icon: 'keyboard_option_key'}); |
| } else { |
| return 'Alt'; |
| } |
| } |