MCPcopy Create free account
hub / github.com/Oslonline/dithering-studio / AlgorithmControls

Function AlgorithmControls

src/components/panels/AlgorithmControls.tsx:19–88  ·  view source on GitHub ↗
({ pattern, setPattern, threshold, setThreshold, invert, setInvert, paletteId, asciiRamp, setAsciiRamp, groupByCategory })

Source from the content-addressed store, hash-verified

17}
18
19export const AlgorithmControls: React.FC<AlgorithmControlsProps> = ({ pattern, setPattern, threshold, setThreshold, invert, setInvert, paletteId, asciiRamp, setAsciiRamp, groupByCategory }) => {
20 const { t } = useTranslation();
21 const algo = algorithms.find((a) => a.id === pattern);
22 const supportsThreshold = !!algo?.supportsThreshold;
23 const isAscii = pattern === 25 || (algo?.name.toLowerCase().includes('ascii'));
24
25 const renderOptions = () => {
26 if (!groupByCategory) {
27 return algorithms.map((a) => (
28 <option key={a.id} value={a.id}>
29 {a.name}
30 </option>
31 ));
32 }
33 const groups = getAlgorithmsByCategory();
34 const order: ["Error Diffusion", "Ordered", "Other"] = ["Error Diffusion", "Ordered", "Other"];
35 return order.map((cat) => {
36 const list = groups[cat];
37 if (!list) return null;
38 const labelKey = cat === 'Error Diffusion' ? 'tool.algorithmPanel.errorDiffusion' : cat === 'Ordered' ? 'tool.algorithmPanel.ordered' : 'tool.algorithmPanel.other';
39 return (
40 <optgroup key={cat} label={t(labelKey)}>
41 {list.map((a) => (
42 <option key={a.id} value={a.id}>
43 {a.name}
44 </option>
45 ))}
46 </optgroup>
47 );
48 });
49 };
50
51 return (
52 <div className="space-y-3">
53 <div>
54 <label htmlFor="algo-select" className="sr-only">
55 {t('tool.algorithmPanel.title')}
56 </label>
57 <select id="algo-select" className="clean-input" value={pattern} onChange={(e) => setPattern(Number(e.target.value))}>
58 {renderOptions()}
59 </select>
60 </div>
61 {supportsThreshold && (
62 <div className="space-y-1">
63 <div className="flex items-center justify-between">
64 <span className="font-mono text-[10px] tracking-wide text-gray-400">{t('tool.algorithmPanel.luminanceThreshold')}</span>
65 <span className="text-[10px] text-gray-500">{threshold}</span>
66 </div>
67 <input type="range" min={0} max={255} value={threshold} className="clean-range" onChange={(e) => setThreshold(Number(e.target.value))} aria-label={t('tool.algorithmPanel.threshold')} />
68 </div>
69 )}
70 <div className="grid grid-cols-1 gap-2">
71 <button type="button" onClick={() => !paletteId && setInvert((v: boolean) => !v)} disabled={!!paletteId} className={`clean-btn justify-center text-[10px] ${invert ? "border-blue-600 text-blue-400" : ""} ${paletteId ? "cursor-not-allowed opacity-40" : ""}`}>
72 {t('tool.algorithmPanel.invert')}
73 </button>
74 </div>
75 {isAscii && setAsciiRamp && (
76 <div className="space-y-1">

Callers

nothing calls this directly

Calls 1

renderOptionsFunction · 0.70

Tested by

no test coverage detected