Skip to content

Commit

Permalink
Make type colors themeable (#2847)
Browse files Browse the repository at this point in the history
* Make type colors themeable

* Move theme color selection to hook

* move common type colors to root selector

* remove unused vars

---------

Co-authored-by: Michael Schmidt <[email protected]>
  • Loading branch information
joeyballentine and RunDevelopment authored May 18, 2024
1 parent 5fe05c5 commit 4bddc84
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 68 deletions.
20 changes: 20 additions & 0 deletions src/renderer/colors.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@
}
}

:root {
/* type colors */
--type-color-directory: #805ad5;
--type-color-image: #d69e2e;
--type-color-number: #3182ce;
--type-color-string: #10b52c;
--type-color-torch: #dd6b20;
--type-color-onnx: #63b3ed;
--type-color-ncnn: #ed64a6;
}

:root[data-theme='dark'] {
/* backgrounds */
--bg-800: var(--theme-800);
Expand Down Expand Up @@ -316,4 +327,13 @@
900: #151515,
)
);

/* type colors */
--type-color-directory: #db7f85;
--type-color-image: #67b6f4;
--type-color-number: #f9d600;
--type-color-string: #72e4b9;
--type-color-torch: #fbae2e;
--type-color-onnx: #ac9fdc;
--type-color-ncnn: #ae5354;
}
4 changes: 2 additions & 2 deletions src/renderer/components/CustomEdge/CustomEdge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { BackendContext } from '../../contexts/BackendContext';
import { ExecutionContext, NodeExecutionStatus } from '../../contexts/ExecutionContext';
import { GlobalContext, GlobalVolatileContext } from '../../contexts/GlobalNodeState';
import { useSettings } from '../../contexts/SettingsContext';
import { getTypeAccentColors } from '../../helpers/accentColors';
import { shadeColor } from '../../helpers/colorTools';
import {
BREAKPOINT_RADIUS,
Expand All @@ -21,6 +20,7 @@ import {
} from '../../helpers/graphUtils';
import { useEdgeMenu } from '../../hooks/useEdgeMenu';
import './CustomEdge.scss';
import { useTypeColor } from '../../hooks/useTypeColor';

const EDGE_CLASS = {
RUNNING: 'running',
Expand Down Expand Up @@ -179,7 +179,7 @@ export const CustomEdge = memo(
c.typeState.functions.get(source)?.outputs.get(outputId)
);

const [accentColor] = getTypeAccentColors(type || definitionType);
const [accentColor] = useTypeColor(type || definitionType);
const currentColor = selected ? shadeColor(accentColor, -40) : accentColor;

const buttonSize = 32;
Expand Down
5 changes: 3 additions & 2 deletions src/renderer/components/NodeDocumentation/NodeDocs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import { prettyPrintType } from '../../../common/types/pretty';
import { withoutError, withoutNull } from '../../../common/types/util';
import { capitalize, isAutoInput } from '../../../common/util';
import { BackendContext } from '../../contexts/BackendContext';
import { getCategoryAccentColor, getTypeAccentColors } from '../../helpers/accentColors';
import { getCategoryAccentColor } from '../../helpers/accentColors';
import { useTypeColor } from '../../hooks/useTypeColor';
import { IconFactory } from '../CustomIcons';
import { Markdown } from '../Markdown';
import { TypeTag } from '../TypeTag';
Expand Down Expand Up @@ -112,7 +113,7 @@ const InputOutputItem = memo(
? schema.iteratorInputs.some((i) => i.inputs.includes(item.id))
: schema.iteratorOutputs.some((i) => i.outputs.includes(item.id));

const handleColors = getTypeAccentColors(type);
const handleColors = useTypeColor(type);

const isFileInput = item.kind === 'file';
const supportedFileTypes = isFileInput ? item.filetypes : [];
Expand Down
10 changes: 7 additions & 3 deletions src/renderer/components/inputs/InputContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import { assertNever, stringifyTargetHandle } from '../../../common/util';
import { VALID, invalid } from '../../../common/Validity';
import { GlobalVolatileContext } from '../../contexts/GlobalNodeState';
import { InputContext } from '../../contexts/InputContext';
import { getTypeAccentColors } from '../../helpers/accentColors';
import { defaultColor } from '../../helpers/accentColors';
import { useSourceTypeColor } from '../../hooks/useSourceTypeColor';
import { useTypeColor } from '../../hooks/useTypeColor';
import { Handle } from '../Handle';
import { Markdown } from '../Markdown';
import { TypeTag } from '../TypeTag';
Expand Down Expand Up @@ -64,7 +65,7 @@ export const InputHandle = memo(
});
}, [connectingFrom, id, targetHandle, isValidConnection]);

const handleColors = getTypeAccentColors(connectableType);
const handleColors = useTypeColor(connectableType);

const sourceTypeColor = useSourceTypeColor(targetHandle);

Expand All @@ -81,7 +82,10 @@ export const InputHandle = memo(
>
<Handle
connectedColor={
isConnected ? sourceTypeColor ?? handleColors[0] : undefined
isConnected
? (sourceTypeColor === defaultColor ? null : sourceTypeColor) ??
handleColors[0]
: undefined
}
handleColors={handleColors}
id={targetHandle}
Expand Down
6 changes: 3 additions & 3 deletions src/renderer/components/inputs/elements/StyledSlider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
Tooltip,
useColorModeValue,
} from '@chakra-ui/react';
import { MouseEventHandler, memo, useMemo, useState } from 'react';
import { getTypeAccentColors } from '../../../helpers/accentColors';
import { MouseEventHandler, memo, useState } from 'react';
import { useTypeColor } from '../../../hooks/useTypeColor';

export interface Scale {
toScale(value: number): number;
Expand Down Expand Up @@ -143,7 +143,7 @@ export const StyledSlider = memo(
}: StyledSliderProps) => {
const [showTooltip, setShowTooltip] = useState(false);

const [typeAccentColor] = useMemo(() => getTypeAccentColors(NumberType.instance), []);
const [typeAccentColor] = useTypeColor(NumberType.instance);

let customBackground;
if (style.type === 'gradient') {
Expand Down
7 changes: 2 additions & 5 deletions src/renderer/components/node/BreakPoint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { useContext, useContextSelector } from 'use-context-selector';
import { EdgeData, NodeData, OutputId } from '../../../common/common-types';
import { BackendContext } from '../../contexts/BackendContext';
import { GlobalContext, GlobalVolatileContext } from '../../contexts/GlobalNodeState';
import { getTypeAccentColors } from '../../helpers/accentColors';
import { UseContextMenu, useContextMenu } from '../../hooks/useContextMenu';
import { useTypeColor } from '../../hooks/useTypeColor';

const useBreakPointMenu = (id: string): UseContextMenu => {
const { removeNodesById, removeEdgeBreakpoint } = useContext(GlobalContext);
Expand Down Expand Up @@ -96,10 +96,7 @@ const BreakPointInner = memo(({ id }: NodeProps) => {
[leftEdge, typeState]
);

const [accentColor] = useMemo(
() => getTypeAccentColors(type || definitionType),
[type, definitionType]
);
const [accentColor] = useTypeColor(type || definitionType);

return (
<Box
Expand Down
81 changes: 52 additions & 29 deletions src/renderer/components/node/CollapsedHandles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { Box } from '@chakra-ui/react';
import { memo } from 'react';
import { Handle, Position } from 'reactflow';
import { useContextSelector } from 'use-context-selector';
import { Output } from '../../../common/common-types';
import { FunctionDefinition } from '../../../common/types/function';
import { stringifySourceHandle, stringifyTargetHandle } from '../../../common/util';
import { BackendContext } from '../../contexts/BackendContext';
import { defaultColor, getTypeAccentColors } from '../../helpers/accentColors';
import { NodeState } from '../../helpers/nodeState';
import { useSourceTypeColor } from '../../hooks/useSourceTypeColor';
import { useTypeColor } from '../../hooks/useTypeColor';
import { getBackground } from '../Handle';

interface InputHandleProps {
Expand All @@ -31,7 +33,7 @@ const InputHandle = memo(({ isIterated, targetHandle }: InputHandleProps) => {
isConnectable={false}
position={Position.Left}
style={{
borderColor: sourceTypeColor || defaultColor,
borderColor: sourceTypeColor,
borderRadius: isIterated ? '10%' : '50%',
}}
type="target"
Expand All @@ -40,6 +42,46 @@ const InputHandle = memo(({ isIterated, targetHandle }: InputHandleProps) => {
);
});

interface OutputHandleProps {
output: Output;
nodeState: NodeState;
functionDefinition: FunctionDefinition | undefined;
isIterated: boolean;
sourceHandle: string;
}

const OutputHandle = memo(
({ output, nodeState, functionDefinition, isIterated, sourceHandle }: OutputHandleProps) => {
const functions = functionDefinition?.outputDefaults;
const definitionType = functions?.get(output.id) ?? NeverType.instance;
const type = nodeState.type.instance?.outputs.get(output.id);

const handleColors = useTypeColor(type || definitionType);

return (
<Box
h="6px"
key={sourceHandle}
ml="auto"
position="relative"
w="6px"
>
<Handle
className="output-handle"
id={sourceHandle}
isConnectable={false}
position={Position.Right}
style={{
borderColor: getBackground(handleColors),
borderRadius: isIterated ? '10%' : '50%',
}}
type="source"
/>
</Box>
);
}
);

interface CollapsedHandlesProps {
nodeState: NodeState;
}
Expand Down Expand Up @@ -98,36 +140,17 @@ export const CollapsedHandles = memo(({ nodeState }: CollapsedHandlesProps) => {
if (!isConnected) {
return null;
}

const functions = functionDefinition?.outputDefaults;
const definitionType = functions?.get(output.id) ?? NeverType.instance;
const type = nodeState.type.instance?.outputs.get(output.id);
const handleColors = getTypeAccentColors(type || definitionType);

const isIterated = iteratedOutputs.has(output.id);

const sourceHandle = stringifySourceHandle({ nodeId, outputId: output.id });

return (
<Box
h="6px"
key={sourceHandle}
ml="auto"
position="relative"
w="6px"
>
<Handle
className="output-handle"
id={sourceHandle}
isConnectable={false}
position={Position.Right}
style={{
borderColor: getBackground(handleColors),
borderRadius: isIterated ? '10%' : '50%',
}}
type="source"
/>
</Box>
<OutputHandle
functionDefinition={functionDefinition}
isIterated={isIterated}
key={output.id}
nodeState={nodeState}
output={output}
sourceHandle={sourceHandle}
/>
);
})}
</Box>
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/components/outputs/OutputContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Output, OutputId } from '../../../common/common-types';
import { stringifySourceHandle } from '../../../common/util';
import { VALID, invalid } from '../../../common/Validity';
import { GlobalVolatileContext } from '../../contexts/GlobalNodeState';
import { getTypeAccentColors } from '../../helpers/accentColors';
import { useTypeColor } from '../../hooks/useTypeColor';
import { Handle } from '../Handle';
import { TypeTags } from '../TypeTag';

Expand Down Expand Up @@ -53,7 +53,7 @@ export const OutputHandle = memo(
});
}, [connectingFrom, id, sourceHandle, isValidConnection]);

const handleColors = getTypeAccentColors(type || definitionType);
const handleColors = useTypeColor(type || definitionType);

return (
<Center
Expand Down
37 changes: 27 additions & 10 deletions src/renderer/helpers/accentColors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,39 @@ import {
import { CategoryMap } from '../../common/CategoryMap';
import { CategoryId } from '../../common/common-types';
import { getChainnerScope } from '../../common/types/chainner-scope';
import { lazy } from '../../common/util';

export const defaultColor = '#718096';

const colorList = lazy(() => {
const getComputedColor = (color: string) =>
getComputedStyle(document.documentElement).getPropertyValue(color);

const colorList = () => {
const scope = getChainnerScope();
return [
{ type: evaluate(new NamedExpression('Directory'), scope), color: '#805AD5' },
{ type: evaluate(new NamedExpression('Image'), scope), color: '#D69E2E' },
{ type: NumberType.instance, color: '#3182CE' },
{ type: StringType.instance, color: '#10b52c' },
{ type: evaluate(new NamedExpression('PyTorchModel'), scope), color: '#DD6B20' },
{ type: evaluate(new NamedExpression('OnnxModel'), scope), color: '#63B3ED' },
{ type: evaluate(new NamedExpression('NcnnNetwork'), scope), color: '#ED64A6' },
{
type: evaluate(new NamedExpression('Directory'), scope),
color: getComputedColor('--type-color-directory'),
},
{
type: evaluate(new NamedExpression('Image'), scope),
color: getComputedColor('--type-color-image'),
},
{ type: NumberType.instance, color: getComputedColor('--type-color-number') },
{ type: StringType.instance, color: getComputedColor('--type-color-string') },
{
type: evaluate(new NamedExpression('PyTorchModel'), scope),
color: getComputedColor('--type-color-torch'),
},
{
type: evaluate(new NamedExpression('OnnxModel'), scope),
color: getComputedColor('--type-color-onnx'),
},
{
type: evaluate(new NamedExpression('NcnnNetwork'), scope),
color: getComputedColor('--type-color-ncnn'),
},
];
});
};

const defaultColorList = [defaultColor] as const;

Expand Down
21 changes: 9 additions & 12 deletions src/renderer/hooks/useSourceTypeColor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { NodeData } from '../../common/common-types';
import { parseSourceHandle } from '../../common/util';
import { BackendContext } from '../contexts/BackendContext';
import { GlobalVolatileContext } from '../contexts/GlobalNodeState';
import { defaultColor, getTypeAccentColors } from '../helpers/accentColors';
import { useTypeColor } from './useTypeColor';

export const useSourceTypeColor = (targetHandle: string) => {
const { functionDefinitions } = useContext(BackendContext);
Expand All @@ -17,27 +17,24 @@ export const useSourceTypeColor = (targetHandle: string) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [edgeChanges, getEdges, targetHandle]);

const sourceTypeColor = useMemo(() => {
const sourceType = useMemo(() => {
if (sourceHandle) {
const source = parseSourceHandle(sourceHandle);
const sourceNode: Node<NodeData> | undefined = getNode(source.nodeId);
if (sourceNode) {
const sourceDef = functionDefinitions.get(sourceNode.data.schemaId);
if (!sourceDef) {
return defaultColor;
return;
}
const sourceType =
return (
typeState.functions.get(source.nodeId)?.outputs.get(source.outputId) ??
sourceDef.outputDefaults.get(source.outputId);
if (!sourceType) {
return defaultColor;
}
return getTypeAccentColors(sourceType)[0];
sourceDef.outputDefaults.get(source.outputId)
);
}
return defaultColor;
}
return null;
}, [sourceHandle, functionDefinitions, typeState, getNode]);

return sourceTypeColor;
const sourceTypeColor = useTypeColor(sourceType);

return sourceTypeColor[0];
};
10 changes: 10 additions & 0 deletions src/renderer/hooks/useTypeColor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Type } from '@chainner/navi';
import { useMemo } from 'react';
import { useSettings } from '../contexts/SettingsContext';
import { defaultColor, getTypeAccentColors } from '../helpers/accentColors';

export const useTypeColor = (type: Type | undefined) => {
const { theme } = useSettings();
// eslint-disable-next-line react-hooks/exhaustive-deps
return useMemo(() => (type ? getTypeAccentColors(type) : [defaultColor]), [type, theme]);
};

0 comments on commit 4bddc84

Please sign in to comment.