refactor: remove PinSelector component and associated styles
This commit is contained in:
parent
b152cb1919
commit
9ce4ad0147
|
|
@ -1,134 +0,0 @@
|
|||
.pin-selector-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pin-selector {
|
||||
position: relative;
|
||||
background-color: #2d2d2d;
|
||||
border: 1px solid #555;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
min-width: 320px;
|
||||
max-width: 400px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.pin-selector-header {
|
||||
margin-bottom: 15px;
|
||||
border-bottom: 1px solid #444;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.pin-selector-header h4 {
|
||||
margin: 0 0 5px 0;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.component-type-label {
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.pin-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.pin-group-label {
|
||||
font-size: 13px;
|
||||
color: #aaa;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.pin-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.pin-button {
|
||||
padding: 8px 4px;
|
||||
background-color: #3d3d3d;
|
||||
border: 1px solid #555;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.pin-button:hover {
|
||||
background-color: #4d4d4d;
|
||||
border-color: #007acc;
|
||||
}
|
||||
|
||||
.pin-button.selected {
|
||||
background-color: #007acc;
|
||||
border-color: #007acc;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.pin-button.current {
|
||||
background-color: #28a745;
|
||||
border-color: #28a745;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.pin-button.selected.current {
|
||||
background-color: #007acc;
|
||||
border-color: #007acc;
|
||||
}
|
||||
|
||||
.pin-selector-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
margin-top: 15px;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid #444;
|
||||
}
|
||||
|
||||
.pin-selector-footer .btn {
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.pin-selector-footer .btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.pin-selector-footer .btn-primary {
|
||||
background-color: #007acc;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.pin-selector-footer .btn-primary:hover:not(:disabled) {
|
||||
background-color: #005a9e;
|
||||
}
|
||||
|
||||
.pin-selector-footer .btn-secondary {
|
||||
background-color: #6c757d;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.pin-selector-footer .btn-secondary:hover {
|
||||
background-color: #5a6268;
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
import { useState } from 'react';
|
||||
import './PinSelector.css';
|
||||
|
||||
interface PinSelectorProps {
|
||||
componentId: string;
|
||||
componentType: string;
|
||||
currentPin?: number;
|
||||
onPinSelect: (componentId: string, pin: number) => void;
|
||||
onClose: () => void;
|
||||
position: { x: number; y: number };
|
||||
}
|
||||
|
||||
// Arduino Uno pin groups
|
||||
const PIN_GROUPS = [
|
||||
{
|
||||
label: 'Digital Pins',
|
||||
pins: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
|
||||
},
|
||||
{
|
||||
label: 'Analog Pins',
|
||||
pins: [14, 15, 16, 17, 18, 19], // A0-A5
|
||||
},
|
||||
];
|
||||
|
||||
export const PinSelector = ({
|
||||
componentId,
|
||||
componentType,
|
||||
currentPin,
|
||||
onPinSelect,
|
||||
onClose,
|
||||
position,
|
||||
}: PinSelectorProps) => {
|
||||
const [selectedPin, setSelectedPin] = useState<number | undefined>(currentPin);
|
||||
|
||||
const handlePinClick = (pin: number) => {
|
||||
setSelectedPin(pin);
|
||||
};
|
||||
|
||||
const handleConfirm = () => {
|
||||
if (selectedPin !== undefined) {
|
||||
onPinSelect(componentId, selectedPin);
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
|
||||
const formatPinLabel = (pin: number): string => {
|
||||
if (pin >= 14 && pin <= 19) {
|
||||
return `A${pin - 14}`;
|
||||
}
|
||||
return `D${pin}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="pin-selector-overlay" onClick={onClose}>
|
||||
<div
|
||||
className="pin-selector"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="pin-selector-header">
|
||||
<h4>Select Pin</h4>
|
||||
<span className="component-type-label">{componentType}</span>
|
||||
</div>
|
||||
|
||||
{PIN_GROUPS.map((group) => (
|
||||
<div key={group.label} className="pin-group">
|
||||
<div className="pin-group-label">{group.label}</div>
|
||||
<div className="pin-grid">
|
||||
{group.pins.map((pin) => (
|
||||
<button
|
||||
key={pin}
|
||||
className={`pin-button ${selectedPin === pin ? 'selected' : ''} ${
|
||||
currentPin === pin ? 'current' : ''
|
||||
}`}
|
||||
onClick={() => handlePinClick(pin)}
|
||||
>
|
||||
{formatPinLabel(pin)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
<div className="pin-selector-footer">
|
||||
<button className="btn btn-secondary" onClick={onClose}>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
onClick={handleConfirm}
|
||||
disabled={selectedPin === undefined}
|
||||
>
|
||||
Confirm
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -7,7 +7,6 @@ import { SensorControlPanel } from './SensorControlPanel';
|
|||
import { SENSOR_CONTROLS } from '../../simulation/sensorControlConfig';
|
||||
import { DynamicComponent, createComponentFromMetadata } from '../DynamicComponent';
|
||||
import { ComponentRegistry } from '../../services/ComponentRegistry';
|
||||
import { PinSelector } from './PinSelector';
|
||||
import { getTabSessionId } from '../../simulation/Esp32Bridge';
|
||||
import { WireLayer } from './WireLayer';
|
||||
import type { SegmentHandle } from './WireLayer';
|
||||
|
|
@ -107,8 +106,6 @@ export const SimulatorCanvas = () => {
|
|||
|
||||
// Component selection
|
||||
const [selectedComponentId, setSelectedComponentId] = useState<string | null>(null);
|
||||
const [showPinSelector, setShowPinSelector] = useState(false);
|
||||
const [pinSelectorPos, setPinSelectorPos] = useState({ x: 0, y: 0 });
|
||||
|
||||
// Component property dialog
|
||||
const [showPropertyDialog, setShowPropertyDialog] = useState(false);
|
||||
|
|
@ -573,14 +570,18 @@ export const SimulatorCanvas = () => {
|
|||
const boardId = touchId.slice('__board__:'.length);
|
||||
useSimulatorStore.getState().setActiveBoardId(boardId);
|
||||
} else if (touchId !== '__board__') {
|
||||
// Short tap on component → open property dialog or sensor panel
|
||||
// Short tap on component → open property dialog or sensor panel.
|
||||
// While the simulator is running, components stay interactive —
|
||||
// only sensor panels may open; property editing is disabled.
|
||||
const component = componentsRef.current.find(
|
||||
(c) => c.id === touchId
|
||||
);
|
||||
if (component) {
|
||||
if (runningRef.current && SENSOR_CONTROLS[component.metadataId] !== undefined) {
|
||||
setSensorControlComponentId(touchId);
|
||||
setSensorControlMetadataId(component.metadataId);
|
||||
if (runningRef.current) {
|
||||
if (SENSOR_CONTROLS[component.metadataId] !== undefined) {
|
||||
setSensorControlComponentId(touchId);
|
||||
setSensorControlMetadataId(component.metadataId);
|
||||
}
|
||||
} else {
|
||||
setPropertyDialogComponentId(touchId);
|
||||
setPropertyDialogPosition({
|
||||
|
|
@ -903,24 +904,6 @@ export const SimulatorCanvas = () => {
|
|||
setShowComponentPicker(false);
|
||||
};
|
||||
|
||||
// Component selection (double click to open pin selector)
|
||||
const handleComponentDoubleClick = (componentId: string, event: React.MouseEvent) => {
|
||||
event.stopPropagation();
|
||||
setSelectedComponentId(componentId);
|
||||
setPinSelectorPos({ x: event.clientX, y: event.clientY });
|
||||
setShowPinSelector(true);
|
||||
};
|
||||
|
||||
// Pin assignment
|
||||
const handlePinSelect = (componentId: string, pin: number) => {
|
||||
updateComponent(componentId, {
|
||||
properties: {
|
||||
...components.find((c) => c.id === componentId)?.properties,
|
||||
pin,
|
||||
},
|
||||
} as any);
|
||||
};
|
||||
|
||||
// Component rotation
|
||||
const handleRotateComponent = (componentId: string) => {
|
||||
const component = components.find((c) => c.id === componentId);
|
||||
|
|
@ -937,7 +920,7 @@ export const SimulatorCanvas = () => {
|
|||
|
||||
// Component dragging handlers
|
||||
const handleComponentMouseDown = (componentId: string, e: React.MouseEvent) => {
|
||||
if (showPinSelector || showPropertyDialog) return;
|
||||
if (showPropertyDialog) return;
|
||||
|
||||
e.stopPropagation();
|
||||
const component = components.find((c) => c.id === componentId);
|
||||
|
|
@ -1056,10 +1039,15 @@ export const SimulatorCanvas = () => {
|
|||
} else if (draggedComponentId !== '__board__') {
|
||||
const component = components.find((c) => c.id === draggedComponentId);
|
||||
if (component) {
|
||||
// During simulation: sensor components show the SensorControlPanel
|
||||
if (running && SENSOR_CONTROLS[component.metadataId] !== undefined) {
|
||||
setSensorControlComponentId(draggedComponentId);
|
||||
setSensorControlMetadataId(component.metadataId);
|
||||
if (running) {
|
||||
// During simulation only sensor panels open on click — every
|
||||
// other component is interactive (pushbutton, switch, pot, …)
|
||||
// and must handle its own clicks, so we suppress the property
|
||||
// dialog entirely.
|
||||
if (SENSOR_CONTROLS[component.metadataId] !== undefined) {
|
||||
setSensorControlComponentId(draggedComponentId);
|
||||
setSensorControlMetadataId(component.metadataId);
|
||||
}
|
||||
} else {
|
||||
setPropertyDialogComponentId(draggedComponentId);
|
||||
setPropertyDialogPosition({
|
||||
|
|
@ -1294,12 +1282,6 @@ export const SimulatorCanvas = () => {
|
|||
onMouseDown={(e) => {
|
||||
handleComponentMouseDown(component.id, e);
|
||||
}}
|
||||
onDoubleClick={(e) => {
|
||||
// Only handle UI events when simulation is NOT running
|
||||
if (!running) {
|
||||
handleComponentDoubleClick(component.id, e);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Pin overlay for wire creation - hide when running */}
|
||||
|
|
@ -1595,22 +1577,6 @@ export const SimulatorCanvas = () => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pin Selector Modal */}
|
||||
{showPinSelector && selectedComponentId && (
|
||||
<PinSelector
|
||||
componentId={selectedComponentId}
|
||||
componentType={
|
||||
components.find((c) => c.id === selectedComponentId)?.metadataId || 'unknown'
|
||||
}
|
||||
currentPin={
|
||||
components.find((c) => c.id === selectedComponentId)?.properties.pin as number | undefined
|
||||
}
|
||||
onPinSelect={handlePinSelect}
|
||||
onClose={() => setShowPinSelector(false)}
|
||||
position={pinSelectorPos}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Component Property Dialog */}
|
||||
{showPropertyDialog && propertyDialogComponentId && (() => {
|
||||
const component = components.find((c) => c.id === propertyDialogComponentId);
|
||||
|
|
|
|||
Loading…
Reference in New Issue