blob: 9e1bb7564f51a9bcc72f94bfe0eece80bb042228 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview
* 'keyboard-remap-key-row' contains a key with icon label and dropdown menu to
* allow users to customize the remapped key.
*/
import 'chrome://resources/cr_components/settings_prefs/prefs.js';
import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
import '../../settings_shared.css.js';
import '/shared/settings/controls/settings_dropdown_menu.js';
import '../../settings_shared.css.js';
import '../os_settings_icons.html.js';
import {DropdownMenuOptionList} from '/shared/settings/controls/settings_dropdown_menu.js';
import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
import {assertNotReached} from 'chrome://resources/js/assert_ts.js';
import {PolymerElementProperties} from 'chrome://resources/polymer/v3_0/polymer/interfaces.js';
import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {MetaKey, ModifierKey} from './input_device_settings_types.js';
import {getTemplate} from './keyboard_remap_modifier_key_row.html.js';
/**
* Refers to the state of an 'remap-key' icon.
*/
enum KeyState {
DEFAULT_REMAPPING = 'default-remapping',
MODIFIER_REMAPPED = 'modifier-remapped',
}
type KeyIcon = 'cr:search'|'os-settings:launcher'|'os-settings:assistant'|'';
const KeyboardRemapModifierKeyRowElementBase = I18nMixin(PolymerElement);
export class KeyboardRemapModifierKeyRowElement extends
KeyboardRemapModifierKeyRowElementBase {
static get is(): string {
return 'keyboard-remap-modifier-key-row';
}
static get properties(): PolymerElementProperties {
return {
keyLabel: {
type: String,
value: '',
computed: 'getKeyLabel(metaKey)',
},
metaKeyLabel: {
type: String,
value: '',
computed: 'getMetaKeyLabel(metaKey)',
},
keyState: {
type: String,
value: KeyState.DEFAULT_REMAPPING,
reflectToAttribute: true,
computed: 'computeKeyState(pref.value)',
},
pref: {
type: Object,
},
metaKey: {
type: Number,
},
key: {
type: Number,
},
defaultRemappings: {
type: Object,
},
keyMapTargets: {
type: Object,
},
keyIcon: {
type: String,
value: '',
computed: 'getKeyIcon(key, metaKey)',
},
removeTopBorder: {
type: Boolean,
reflectToAttribute: true,
},
};
}
protected keyLabel: string;
private metaKeyLabel: string;
private keyMapTargets: DropdownMenuOptionList;
private keyIcon: KeyIcon;
keyState: KeyState;
pref: chrome.settingsPrivate.PrefObject;
metaKey: MetaKey;
key: ModifierKey;
defaultRemappings: {[key: number]: ModifierKey};
override ready() {
super.ready();
this.setUpKeyMapTargets();
}
static get template(): HTMLTemplateElement {
return getTemplate();
}
/**
* Whenever the key remapping is changed, update the keyState to change
* the icon color between default and highlighted.
*/
private computeKeyState(): KeyState {
return this.defaultRemappings[this.key] === this.pref.value ?
KeyState.DEFAULT_REMAPPING :
KeyState.MODIFIER_REMAPPED;
}
/**
* Populate the metaKey label according to metaKey.
*/
private getMetaKeyLabel(): string {
switch (this.metaKey) {
case MetaKey.kCommand: {
return this.i18n('perDeviceKeyboardKeyCommand');
}
case MetaKey.kExternalMeta: {
return this.i18n('keyboardKeyMeta');
}
// Launcher and Search key will display icon instead of text.
case MetaKey.kLauncher:
case MetaKey.kSearch:
return '';
}
}
/**
* Populate the key label inside the keyboard key icon.
*/
private getKeyLabel(): string {
switch (this.key) {
case ModifierKey.kAlt: {
return this.i18n('perDeviceKeyboardKeyAlt');
}
case ModifierKey.kAssistant: {
return this.i18n('perDeviceKeyboardKeyAssistant');
}
case ModifierKey.kBackspace: {
return this.i18n('perDeviceKeyboardKeyBackspace');
}
case ModifierKey.kCapsLock: {
return this.i18n('perDeviceKeyboardKeyCapsLock');
}
case ModifierKey.kControl: {
return this.i18n('perDeviceKeyboardKeyCtrl');
}
case ModifierKey.kEscape: {
return this.i18n('perDeviceKeyboardKeyEscape');
}
case ModifierKey.kMeta: {
return this.getMetaKeyLabel();
}
default:
assertNotReached('Invalid modifier key: ' + this.key);
}
}
private setUpKeyMapTargets(): void {
// Ordering is according to UX, but values match ModifierKey.
this.keyMapTargets = [
{
value: ModifierKey.kMeta,
name: this.i18n('perDeviceKeyboardKeySearch'),
},
{
value: ModifierKey.kControl,
name: this.i18n('perDeviceKeyboardKeyCtrl'),
},
{
value: ModifierKey.kAlt,
name: this.i18n('perDeviceKeyboardKeyAlt'),
},
{
value: ModifierKey.kCapsLock,
name: this.i18n('perDeviceKeyboardKeyCapsLock'),
},
{
value: ModifierKey.kEscape,
name: this.i18n('perDeviceKeyboardKeyEscape'),
},
{
value: ModifierKey.kBackspace,
name: this.i18n('perDeviceKeyboardKeyBackspace'),
},
{
value: ModifierKey.kAssistant,
name: this.i18n('perDeviceKeyboardKeyAssistant'),
},
{
value: ModifierKey.kVoid,
name: this.i18n('perDeviceKeyboardKeyDisabled'),
},
];
}
private getKeyIcon(): KeyIcon {
if (this.key === ModifierKey.kMeta) {
if (this.metaKey === MetaKey.kSearch) {
return 'cr:search';
}
if (this.metaKey === MetaKey.kLauncher) {
return 'os-settings:launcher';
}
} else if (this.key === ModifierKey.kAssistant) {
return 'os-settings:assistant';
}
return '';
}
}
declare global {
interface HTMLElementTagNameMap {
'keyboard-remap-modifier-key-row': KeyboardRemapModifierKeyRowElement;
}
}
customElements.define(
KeyboardRemapModifierKeyRowElement.is, KeyboardRemapModifierKeyRowElement);