Skip to content

Commit

Permalink
feat: keybind input element
Browse files Browse the repository at this point in the history
  • Loading branch information
SpikeHD committed Jun 15, 2024
1 parent fc7c018 commit a983b00
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 10 deletions.
2 changes: 1 addition & 1 deletion components/Dropdown.tsx.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

font-size: 16px;
width: 100%;
border-radius: 3px;
border-radius: 4px;
color: var(--text-normal);
background-color: var(--input-background);
border: none;
Expand Down
109 changes: 109 additions & 0 deletions components/KeybindInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { keyToStr, strToKey } from '../util/keyUtil.js'
import { css, classes } from './KeybindInput.tsx.scss'

const {
solid: {
createSignal
},
ui: {
Text,
injectCss
}
} = shelter

interface Props {
onKeybindChange(keybind: number[]): void

// style overrides
style?: string
disabled?: boolean
}

let injectedCss = false

export function KeybindInput(props: Props) {
if (!injectedCss) {
injectedCss = true
injectCss(css)
}

const [recording, setRecording] = createSignal(false)
// numbers mean (in order)
const [keybind, setKeybind] = createSignal([])

const keyDown = (e) => {
// If the key is already in the keybind, don't add it again
if (keybind().includes(e.key) || keybind().includes(e.key.toLowerCase())) {
return
}

// if ctrl, alt, or shift, add it to the front of the keybind
switch (e.key) {
case 'Control':
case 'Alt':
case 'Shift':
case 'Meta':
setKeybind([e.key, ...keybind()])
break
default:
setKeybind([...keybind(), e.key.toLowerCase()])
}
}

const keyUp = (e) => {
setKeybind(keybind().filter((k) => k !== e.key && k !== e.key.toLowerCase()))
}

const setRecordingState = () => {
if (recording()) {
// Remove all event listeners
window.removeEventListener('keydown', keyDown),
window.removeEventListener('keyup', keyUp)

// Set the keybind
props.onKeybindChange(keybind())

setRecording(false)

return
}

// Clear the keybind
setKeybind([])

// Create event listeners to set the keybind based on what is being held down
// Order should be (if they are pressed): Ctrl -> Alt -> Shift -> Everything else
// If a key is released, it should be removed from the keybind
window.addEventListener('keydown', keyDown),
window.addEventListener('keyup', keyUp)

setRecording(true)
}

return (
<div
class={classes.keybindContainer + ' ' + (recording() ? classes.recording : null)}
style={props.style}
>
<div class={classes.keybindInput}>
<Text class={!keybind().length ? classes.keybindPlaceholder : ''}>
{
keybind().length ? keybind().map((k, i) => {
const key = k.length > 1 ? k : k.toUpperCase()
return i === keybind().length - 1 ? key : key + ' + '
}) : 'No Keybind Set'
}
</Text>

</div>
<div
class={classes.keybindButton}
onClick={() => {
setRecordingState()
}}
>
<Text>{recording() ? 'Stop Recording' : 'Edit Keybind'}</Text>
</div>
</div>
)
}
73 changes: 73 additions & 0 deletions components/KeybindInput.tsx.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
.keybindContainer {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;

width: 100%;
height: 40px;

border-radius: 4px;

background: var(--input-background);
color: var(--text-normal);
border: 1px solid transparent;

padding: 4px;

transition: all 0.2s;
}

.keybindContainer:hover {
border: 1px solid var(--status-danger);
}

.recording {
.keybindButton {
background: hsl(var(--red-400-hsl)/.1);
color: var(--status-danger);
}

.keybindButton:hover {
background: hsl(var(--red-400-hsl)/.2);
}

border: 1px solid var(--status-danger);
}

.keybindInput {
background: transparent;

display: flex;
align-items: center;
}

.keybindPlaceholder {
color: var(--text-muted) !important;
}

.keybindButton {
height: 30px;
width: 50%;

margin: 0;
padding: 4px;

border-radius: 4px;

display: flex;
align-items: center;

background: var(--button-secondary-background);
color: var(--white-500);

border: 1px solid transparent;

cursor: pointer;

transition: all 0.2s;
}

.keybindButton:hover {
background: var(--button-secondary-background-hover);
}
16 changes: 10 additions & 6 deletions plugins/dorion-custom-keybinds/components/KeybindSection.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { css, classes } from './KeybindSection.tsx.scss'
import { Dropdown } from '../../../components/Dropdown'
import { KeybindInput } from '../../../components/KeybindInput'

const {
ui: {
Expand Down Expand Up @@ -38,22 +39,25 @@ export function KeybindSection(props) {

<Dropdown
value={props.name}
options={Object.entries(props.keybindActionTypes).map(([key, value]) => {
return {
value: key,
label: value
}
})}
options={props.keybindActionTypes}
onChange={(e) => {
console.log(e)
}}
style='width: 90%'
></Dropdown>
</div>

<div class={classes.keybindArea}>
<Header size={HeaderTags.H5}>
Keybind
</Header>

<KeybindInput
onKeybindChange={(keybind) => {
console.log(keybind)
}}
style='width: 90%'
/>
</div>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
.keybindArea {
display: flex;
flex-direction: column;
align-items
}

.actionSection {
Expand Down
2 changes: 1 addition & 1 deletion plugins/dorion-ptt/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { keyToStr } from './keyUtil.js'
import { keyToStr } from '../../util/keyUtil.js'
import { invoke, event } from '../../api/api.js'

const {
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"module": "nodenext",
"moduleResolution": "nodenext"
},
"include": ["plugins/**/*.ts", "plugins/**/*.tsx", "node_modules/@uwu/shelter-defs/**/*.d.ts", "plugins/clean-home/index.tsx"]
"include": ["plugins/**/*.ts", "plugins/**/*.tsx", "node_modules/@uwu/shelter-defs/**/*.d.ts", "plugins/clean-home/index.tsx", "util/keyUtil.ts"]
}
30 changes: 30 additions & 0 deletions plugins/dorion-ptt/keyUtil.ts → util/keyUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const Keycode = {
220: 'BackSlash', 186: 'Semicolon', 222: 'Apostrophe', 188: 'Comma', 190: 'Dot', 191: 'Slash'
}

// Convert a key code to a string
export const keyToStr = (key: number) => {
let keyStr = ''

Expand All @@ -35,4 +36,33 @@ export const keyToStr = (key: number) => {
}

return keyStr
}

// Convert a key string to a key code
export const strToKey = (str: string) => {
let key = 0

// get char code of uppercase letter
if (str >= 'A' && str <= 'Z') {
key = str.charCodeAt(0)
}

// get char code of lowercase letter
if (str >= 'a' && str <= 'z') {
key = str.charCodeAt(0) - 32
}

// get char code of number
if (str >= '0' && str <= '9') {
key = str.charCodeAt(0)
}

// Get everything else
for (const [k, v] of Object.entries(Keycode)) {
if (v === str) {
key = parseInt(k)
}
}

return key
}

0 comments on commit a983b00

Please sign in to comment.