Programmatic keybindings for sidebar and toolbar

This commit is contained in:
Frank Noirot
2024-08-01 15:22:47 -04:00
parent cac848ab22
commit 3ba79406d8
2 changed files with 45 additions and 45 deletions

View File

@ -22,6 +22,7 @@ import {
ToolbarModeName,
} from 'lib/toolbar'
import { useKclContext } from 'lang/KclProvider'
import { useInteractionMapContext } from 'hooks/useInteractionMapContext'
export function Toolbar({
className = '',
@ -29,31 +30,6 @@ export function Toolbar({
}: React.HTMLAttributes<HTMLElement>) {
const { state, send, context } = useModelingContext()
const { commandBarSend } = useCommandsContext()
useInteractionMap(
[
{
name: 'sketch',
title: 'Start Sketch',
sequence: 'shift+s',
action: () =>
send({ type: 'Enter sketch', data: { forceNewSketch: true } }),
guard: () => state.can('Enter sketch'),
},
{
name: 'extrude',
title: 'Extrude',
sequence: 'ctrl+c shift+e',
action: () =>
commandBarSend({
type: 'Find and select command',
data: { name: 'Extrude', groupId: 'modeling' },
}),
guard: () => state.can('Extrude'),
},
],
[commandBarSend, state],
KEYBINDING_CATEGORIES.MODELING
)
const iconClassName =
'group-disabled:text-chalkboard-50 !text-inherit dark:group-enabled:group-hover:!text-inherit'
const bgClassName = '!bg-transparent'
@ -284,19 +260,34 @@ const ToolbarItemContents = memo(function ToolbarItemContents({
itemConfig: ToolbarItemResolved
configCallbackProps: ToolbarItemCallbackProps
}) {
// useHotkeys(
// itemConfig.hotkey || '',
// () => {
// itemConfig.onClick(configCallbackProps)
// },
// {
// enabled:
// itemConfig.status === 'available' &&
// !!itemConfig.hotkey &&
// !itemConfig.disabled &&
// !itemConfig.disableHotkey,
// }
// )
const { state: interactionMapState } = useInteractionMapContext()
const resolvedSequence =
interactionMapState.context.overrides[
`${KEYBINDING_CATEGORIES.MODELING}.${itemConfig.id}`
] ||
(itemConfig.hotkey instanceof Array
? itemConfig.hotkey[0]
: itemConfig.hotkey) ||
''
useInteractionMap(
[
{
name: itemConfig.id,
title: itemConfig.title,
sequence: resolvedSequence,
action: () => itemConfig.onClick(configCallbackProps),
guard: () =>
!(
itemConfig.status === 'available' &&
!!itemConfig.hotkey &&
!itemConfig.disabled &&
!itemConfig.disableHotkey
),
},
],
[configCallbackProps.modelingSend, configCallbackProps.commandBarSend],
KEYBINDING_CATEGORIES.MODELING
)
return (
<>
@ -318,8 +309,8 @@ const ToolbarItemContents = memo(function ToolbarItemContents({
>
{itemConfig.title}
</span>
{itemConfig.status === 'available' && itemConfig.hotkey ? (
<kbd className="flex-none hotkey">{itemConfig.hotkey}</kbd>
{itemConfig.status === 'available' && resolvedSequence ? (
<kbd className="flex-none hotkey">{resolvedSequence}</kbd>
) : itemConfig.status === 'kcl-only' ? (
<>
<span className="text-wrap font-sans flex-0 text-chalkboard-70 dark:text-chalkboard-40">

View File

@ -1,4 +1,5 @@
import { ActionIcon } from 'components/ActionIcon'
import { CustomIcon } from 'components/CustomIcon'
import { useInteractionMapContext } from 'hooks/useInteractionMapContext'
import { resolveInteractionEvent } from 'lib/keyboard'
import {
@ -115,20 +116,25 @@ function KeybindingField({ item }: { item: InteractionMapItem }) {
return isEditing ? (
<form
key={item.ownerId + '-' + item.name}
className="flex gap-2 justify-between items-start"
className="flex gap-2 justify-between items-center"
onSubmit={handleSubmit}
>
<h3>{item.title}</h3>
<InteractionSequence sequence={newSequence} showNoSequence />
<input type="hidden" value={item.sequence} name="sequence" />
<button className="p-0 m-0" onClick={() => setIsEditing(false)}>
<CustomIcon name="close" className="w-5 h-5" />
<span className="sr-only">Cancel</span>
</button>
<button ref={submitRef} className="p-0 m-0" type="submit">
<ActionIcon icon="checkmark" />
<CustomIcon name="checkmark" className="w-5 h-5" />
<span className="sr-only">Save</span>
</button>
</form>
) : (
<div
key={item.ownerId + '-' + item.name}
className="flex gap-2 justify-between items-start"
className="flex gap-2 justify-between items-center"
>
<h3>{item.title}</h3>
<InteractionSequence
@ -142,7 +148,8 @@ function KeybindingField({ item }: { item: InteractionMapItem }) {
className="p-0 m-0"
onClick={() => setIsEditing(true)}
>
<ActionIcon icon="sketch" />
<CustomIcon name="sketch" className="w-5 h-5" />
<span className="sr-only">Edit</span>
</button>
</div>
)
@ -156,7 +163,9 @@ export function InteractionSequence({
}: HTMLProps<HTMLDivElement> & { sequence: string; showNoSequence?: boolean }) {
return sequence.length ? (
<div
className={'flex-1 flex flex-wrap justify-end gap-3 ' + className}
className={
'cursor-default flex-1 flex flex-wrap justify-end gap-3 ' + className
}
{...props}
>
{sequence.split(' ').map((chord, i) => (