Skip to content

Commit

Permalink
initial version of SetView parameter management
Browse files Browse the repository at this point in the history
  • Loading branch information
fde31 committed Dec 20, 2024
1 parent 219069d commit ac6b357
Show file tree
Hide file tree
Showing 14 changed files with 405 additions and 57 deletions.
106 changes: 92 additions & 14 deletions src/actions/sets.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { writePacket } from "osc";
import { OSCArgument, writePacket } from "osc";
import { oscQueryBridge } from "../controller/oscqueryBridgeController";
import { ActionBase, AppThunk } from "../lib/store";
import { GraphSetRecord, GraphSetViewRecord } from "../models/set";
Expand Down Expand Up @@ -469,14 +469,18 @@ export const updateSetViewParameterListOnRemote = (setView: GraphSetViewRecord,
}
};

export const removeParameterFromSetView = (setView: GraphSetViewRecord, param: ParameterRecord): AppThunk =>
export const decreaseParameterIndexInSetView = (setView: GraphSetViewRecord, param: ParameterRecord): AppThunk =>
(dispatch) => {
try {
const params = setView.params.toArray().filter(entry => param.instanceIndex !== entry.instanceIndex || param.index !== entry.paramIndex);
const currentIndex = setView.params.findIndex(entry => entry.instanceIndex === param.instanceIndex && entry.paramIndex === param.index);
if (currentIndex <= 0) return;

const newList = setView.params
.delete(currentIndex)
.insert(currentIndex - 1, { instanceIndex: param.instanceIndex, paramIndex: param.index });
const message = {
address: `/rnbo/inst/control/sets/views/list/${setView.id}/params`,
args: params.map(p => ({ type: "s", value: instanceAndParamIndicesToSetViewEntry(p.instanceIndex, p.paramIndex) }))
args: newList.toArray().map(p => ({ type: "s", value: instanceAndParamIndicesToSetViewEntry(p.instanceIndex, p.paramIndex) }))
};
oscQueryBridge.sendPacket(writePacket(message));
} catch (err) {
Expand All @@ -489,15 +493,16 @@ export const removeParameterFromSetView = (setView: GraphSetViewRecord, param: P
}
};

export const decreaseParameterIndexInSetView = (setView: GraphSetViewRecord, param: ParameterRecord): AppThunk =>
export const increaseParameterIndexInSetView = (setView: GraphSetViewRecord, param: ParameterRecord): AppThunk =>
(dispatch) => {
try {
const currentIndex = setView.params.findIndex(entry => entry.instanceIndex === param.instanceIndex && entry.paramIndex === param.index);
if (currentIndex <= 0) return;
if (currentIndex >= setView.params.size) return;

const newList = setView.params
.delete(currentIndex)
.insert(currentIndex - 1, { instanceIndex: param.instanceIndex, paramIndex: param.index });
.insert(currentIndex + 1, { instanceIndex: param.instanceIndex, paramIndex: param.index });

const message = {
address: `/rnbo/inst/control/sets/views/list/${setView.id}/params`,
args: newList.toArray().map(p => ({ type: "s", value: instanceAndParamIndicesToSetViewEntry(p.instanceIndex, p.paramIndex) }))
Expand All @@ -513,19 +518,92 @@ export const decreaseParameterIndexInSetView = (setView: GraphSetViewRecord, par
}
};

export const increaseParameterIndexInSetView = (setView: GraphSetViewRecord, param: ParameterRecord): AppThunk =>
export const removeParameterFromSetView = (setView: GraphSetViewRecord, param: ParameterRecord): AppThunk =>
(dispatch) => {
try {
const currentIndex = setView.params.findIndex(entry => entry.instanceIndex === param.instanceIndex && entry.paramIndex === param.index);
if (currentIndex >= setView.params.size) return;
if (!setView.paramIds.has(param.setViewId)) return;
const params = setView.paramIds.remove(param.setViewId).toArray().map(pId => ({ type: "s", value: pId }));

const newList = setView.params
.delete(currentIndex)
.insert(currentIndex + 1, { instanceIndex: param.instanceIndex, paramIndex: param.index })
const message = {
address: `/rnbo/inst/control/sets/views/list/${setView.id}/params`,
args: params
};
oscQueryBridge.sendPacket(writePacket(message));
} catch (err) {
dispatch(showNotification({
level: NotificationLevel.error,
title: `Error while trying to update parameter list of SetView "${setView.name}"`,
message: "Please check the console for further details."
}));
console.log(err);
}
};

export const removeAllParamtersFromSetView = (setView: GraphSetViewRecord): AppThunk =>
(dispatch) => {
try {
const message = {
address: `/rnbo/inst/control/sets/views/list/${setView.id}/params`,
args: newList.toArray().map(p => ({ type: "s", value: instanceAndParamIndicesToSetViewEntry(p.instanceIndex, p.paramIndex) }))
args: [] as OSCArgument[]
};
oscQueryBridge.sendPacket(writePacket(message));
} catch (err) {
dispatch(showNotification({
level: NotificationLevel.error,
title: `Error while trying to update parameter list of SetView "${setView.name}"`,
message: "Please check the console for further details."
}));
console.log(err);
}
};

export const addParameterToSetView = (setView: GraphSetViewRecord, param: ParameterRecord): AppThunk =>
(dispatch) => {
try {
if (setView.paramIds.has(param.setViewId)) return;
const params = setView.paramIds.toArray().map(pId => ({ type: "s", value: pId }));
params.push({ type: "s", value: instanceAndParamIndicesToSetViewEntry(param.instanceIndex, param.index) });

const message = {
address: `/rnbo/inst/control/sets/views/list/${setView.id}/params`,
args: params
};
oscQueryBridge.sendPacket(writePacket(message));
} catch (err) {
dispatch(showNotification({
level: NotificationLevel.error,
title: `Error while trying to update parameter list of SetView "${setView.name}"`,
message: "Please check the console for further details."
}));
console.log(err);
}
};

export const addAllParamtersToSetView = (setView: GraphSetViewRecord): AppThunk =>
(dispatch, getState) => {
try {
const state = getState();
const params = setView.params.withMutations(list => {
getPatcherInstanceParameters(state)
.valueSeq()
.sort((a, b) => {
if (a.instanceIndex < b.instanceIndex) return -1;
if (a.instanceIndex > b.instanceIndex) return 1;
if (a.index < b.index) return -1;
if (a.index > b.index) return 1;
return 0;
})
.forEach(param => {
if (!setView.paramIds.has(param.setViewId)) {
list.push({ instanceIndex: param.instanceIndex, paramIndex: param.index });
}
});
}).toArray();


const message = {
address: `/rnbo/inst/control/sets/views/list/${setView.id}/params`,
args: params.map(p => ({ type: "s", value: instanceAndParamIndicesToSetViewEntry(p.instanceIndex, p.paramIndex) }))
};
oscQueryBridge.sendPacket(writePacket(message));
} catch (err) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/instance/paramTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ const InstanceParameterTab: FunctionComponent<InstanceParameterTabProps> = memo(

const onClearParameterMidiMapping = useCallback((param: ParameterRecord) => {
dispatch(clearParameterMIDIMappingOnRemote(param));
}, [dispatch, instance]);
}, [dispatch]);

const onSearch = useDebouncedCallback((query: string) => {
setSearchValue(query);
Expand Down
2 changes: 1 addition & 1 deletion src/components/midi/mappedParameterItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const MIDIMappedParameter: FC<MIDIMappedParamProps> = memo(function WrappedMIDIM

const onUpdateMapping = useCallback((value: string) => {
onUpdateMIDIMapping(param, value);
}, [instance, param, onUpdateMIDIMapping]);
}, [param, onUpdateMIDIMapping]);

return (
<Table.Tr>
Expand Down
4 changes: 2 additions & 2 deletions src/components/nav/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { getShowSettingsModal } from "../../selectors/settings";
import { ExternalNavLink, NavLink } from "./link";
import { useRouter } from "next/router";
import { getFirstPatcherNodeIndex } from "../../selectors/graph";
import { mdiChartSankeyVariant, mdiCog, mdiFileMusic, mdiHelpCircle, mdiKnob, mdiMidiPort, mdiVectorSquare } from "@mdi/js";
import { mdiChartSankeyVariant, mdiCog, mdiFileMusic, mdiHelpCircle, mdiMidiPort, mdiVectorSquare, mdiTableEye } from "@mdi/js";

const AppNav: FunctionComponent = memo(function WrappedNav() {

Expand Down Expand Up @@ -52,7 +52,7 @@ const AppNav: FunctionComponent = memo(function WrappedNav() {
isActive={ pathname === "/files" }
/>
<NavLink
icon={ mdiKnob }
icon={ mdiTableEye }
label="SetViews"
href={{ pathname: "/setviews", query: { ...restQuery } }}
isActive={ pathname === "/setviews" }
Expand Down
2 changes: 1 addition & 1 deletion src/components/parameter/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export type ParameterItemProps = {
const ParameterItem: FC<ParameterItemProps> = memo(function WrappedParameter({
disabled = false,
param,
onSetNormalizedValue,
onSetNormalizedValue
}: ParameterItemProps) {

const [localValue, setLocalValue] = useState(param.normalizedValue);
Expand Down
46 changes: 30 additions & 16 deletions src/components/parameter/parameters.module.css
Original file line number Diff line number Diff line change
@@ -1,45 +1,59 @@
.parameterWrap {
background-color: var(--parameter-bg-color);
break-inside: avoid-column;
flex: 1;
outline-style: solid;
outline-width: 3px;
page-break-inside: avoid;
padding: 2px 2px var(--mantine-spacing-xl) 2px;
margin-bottom: 6px;
margin-bottom: 6;
}

.paramWithMIDIMapping {

background-color: var(--parameter-bg-color);
outline-color: transparent;
outline-style: solid;
outline-width: 4px;

&[data-instance-mapping="true"] {
cursor: pointer;
background-color: var(--parameter-mapping-bg-color);

&:hover {
background-color: var(--parameter-active-mapping-bg-color);
}

> * {
pointer-events: none;
}
}

&[data-active-mappping="true"] {
outline-color:var(--parameter-active-midi-outline);
background-color: var(--parameter-active-mapping-bg-color);
outline-color: var(--parameter-active-mapping-outline);
}
}

.paramWithActiveInstanceMapping {
cursor: pointer;
.paramWithSetViewWrap {

.parameterItem {
background-color: var(--parameter-active-midi-bg-color);
pointer-events: none;
}
background-color: var(--parameter-bg-color);
outline-color: transparent;
}

.parameterList {
gap: var(--mantine-spacing-xl);
column-gap: var(--mantine-spacing-xl);
min-height: 100%;

&[data-color-scheme="light"] {
--parameter-bg-color: transparent;
--parameter-active-midi-bg-color: var(--mantine-color-violet-1);
--parameter-active-midi-outline: var(--mantine-color-violet-4);
--parameter-mapping-bg-color: var(--mantine-color-violet-1);
--parameter-active-mapping-bg-color: var(--mantine-color-violet-2);
--parameter-active-mapping-outline: var(--mantine-color-violet-5);
}

&[data-color-scheme="dark"] {
--parameter-bg-color: transparent;
--parameter-active-midi-bg-color: var(--mantine-color-violet-9);
--parameter-active-midi-outline: var(--mantine-color-violet-3);
--parameter-mapping-bg-color: var(--mantine-color-violet-9);
--parameter-active-mapping-bg-color: var(--mantine-color-violet-4);
--parameter-active-mapping-outline: var(--mantine-color-violet-2);
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/components/parameter/withMidiMapping.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ export function withParameterMIDIMapping(

return (
<div
className={ `${classes.parameterWrap} ${classes.paramWithMIDIMapping} ${instanceIsMIDIMapping ? classes.paramWithActiveInstanceMapping : ""}` }
className={ `${classes.parameterWrap} ${classes.paramWithMIDIMapping}` }
data-instance-mapping={ instanceIsMIDIMapping }
data-active-mappping={ param.waitingForMidiMapping }
onClick={ instanceIsMIDIMapping ? onTriggerActivateMIDIMapping : null }
>
Expand Down Expand Up @@ -98,14 +99,13 @@ export function withParameterMIDIMapping(
<WrappedComponent param={ param } disabled={ instanceIsMIDIMapping } { ...props } />
<Menu position="bottom-end" disabled={ instanceIsMIDIMapping } >
<Menu.Target>
<Tooltip label="Open Parameter Action Menu">
<ActionIcon variant="subtle" color="gray" size="md" className={ classes.parameterItemActionMenuTarget } >
<Tooltip label="Open Parameter Menu" disabled={ instanceIsMIDIMapping }>
<ActionIcon variant="subtle" color="gray" size="md" disabled={ instanceIsMIDIMapping } >
<IconElement path={ mdiDotsVertical } />
</ActionIcon>
</Tooltip>
</Menu.Target>
<Menu.Dropdown>
<Menu.Label>Parameter Actions</Menu.Label>
<Menu.Item leftSection={ <IconElement path={ mdiCodeBraces } /> } onClick={ toggleMetaEditor }>
Edit Metadata
</Menu.Item>
Expand Down
17 changes: 7 additions & 10 deletions src/components/parameter/withSetViewWrap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import classes from "./parameters.module.css";
import { ActionIcon, Group, Indicator, Menu, Tooltip } from "@mantine/core";
import { formatMIDIMappingToDisplay } from "../../lib/util";
import { MIDIMetaMappingType } from "../../lib/constants";
import { mdiArrowDown, mdiArrowUp, mdiDotsVertical, mdiMinus } from "@mdi/js";
import { mdiArrowDown, mdiArrowUp, mdiDotsVertical, mdiMinusBox } from "@mdi/js";
import { IconElement } from "../elements/icon";

export type ParameterSetViewWrapProps = {
Expand Down Expand Up @@ -48,9 +48,7 @@ export function withParameterSetViewWrap(
: undefined;

return (
<div
className={ `${classes.parameterWrap}` }
>
<div className={ `${classes.parameterWrap} ${classes.paramWithSetViewWrap}` } >
<Group justify="space-between">
<Tooltip label={ indicatorText } disabled={ !indicatorText }>
<Indicator
Expand All @@ -68,22 +66,21 @@ export function withParameterSetViewWrap(
<WrappedComponent index={ index } param={ param } { ...props } />
<Menu position="bottom-end" >
<Menu.Target>
<Tooltip label="Open Parameter Action Menu">
<ActionIcon variant="subtle" color="gray" size="md" className={ classes.parameterItemActionMenuTarget } >
<Tooltip label="Open Parameter Menu">
<ActionIcon variant="subtle" color="gray" size="md" >
<IconElement path={ mdiDotsVertical } />
</ActionIcon>
</Tooltip>
</Menu.Target>
<Menu.Dropdown>
<Menu.Label>SetView Parameter Actions</Menu.Label>
<Menu.Item leftSection={ <IconElement path={ mdiArrowUp } /> } onClick={ onTriggerMoveUp } disabled={ index === 0 } >
<Menu.Item leftSection={ <IconElement path={ mdiArrowUp } /> } onClick={ onTriggerMoveUp } disabled={ index === 0 } >
Move Up
</Menu.Item>
<Menu.Item leftSection={ <IconElement path={ mdiArrowDown } /> } onClick={ onTriggerMoveDown } disabled={ index === listSize - 1 } >
<Menu.Item leftSection={ <IconElement path={ mdiArrowDown } /> } onClick={ onTriggerMoveDown } disabled={ index === listSize - 1} >
Move Down
</Menu.Item>
<Menu.Divider />
<Menu.Item color="red" leftSection={ <IconElement path={ mdiMinus } /> } onClick={ onTriggerRemoveFromSetView } >
<Menu.Item color="red" leftSection={ <IconElement path={ mdiMinusBox } /> } onClick={ onTriggerRemoveFromSetView } >
Remove from SetView
</Menu.Item>
</Menu.Dropdown>
Expand Down
4 changes: 2 additions & 2 deletions src/components/setViews/drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Map as ImmuMap }from "immutable";
import { Divider, Drawer, Group, Stack, Text } from "@mantine/core";
import { FC, useCallback } from "react";
import { IconElement } from "../elements/icon";
import { mdiKnob } from "@mdi/js";
import { mdiTableEye } from "@mdi/js";
import { DrawerSectionTitle } from "../page/drawer";
import { CreateSetViewForm } from "./create";
import { GraphSetViewRecord } from "../../models/set";
Expand Down Expand Up @@ -55,7 +55,7 @@ const SetViewDrawer: FC<CreateSetViewModalProps> = ({
opened={ open }
onClose={ onClose }
position="right"
title={ <Group gap="xs"><IconElement path={ mdiKnob }/> SetViews</Group> }
title={ <Group gap="xs"><IconElement path={ mdiTableEye }/> SetViews</Group> }
>
<CreateSetViewForm onSave={ onCreateSetView } />
<Divider mt="lg" />
Expand Down
Loading

0 comments on commit ac6b357

Please sign in to comment.