(e)
| 1941 | exclThresholdSlider.value = bucketThreshold; |
| 1942 | exclThresholdVal.value = bucketThreshold; |
| 1943 | _lastHoverTriIdx = -1; |
| 1944 | }); |
| 1945 | |
| 1946 | exclClearBtn.addEventListener('click', () => { |
| 1947 | if (paintTree) paintTree.clearLayer(_activeSlot()); |
| 1948 | refreshExclusionOverlay(); |
| 1949 | }); |
| 1950 | |
| 1951 | // Clicking a mask-mode button pre-selects the fill tool so painting can |
| 1952 | // start without an extra click (an already-active brush is kept). Only the |
| 1953 | // buttons do this — programmatic setSelectionMode() calls (project load, |
| 1954 | // session restore) must not activate a paint tool. |
| 1955 | exclModeExcludeBtn.addEventListener('click', () => { |
| 1956 | maskModeChosen = true; |
| 1957 | setSelectionMode(false); // early-returns if already exclude… |
| 1958 | updateMaskModeButtons(); // …so refresh the highlight explicitly |
| 1959 | if (!exclusionTool) setExclusionTool('bucket'); |
| 1960 | }); |
| 1961 | exclModeIncludeBtn.addEventListener('click', () => { |
| 1962 | maskModeChosen = true; |
| 1963 | setSelectionMode(true); |
| 1964 | updateMaskModeButtons(); |
| 1965 | if (!exclusionTool) setExclusionTool('bucket'); |
| 1966 | }); |
| 1967 | |
| 1968 | // ── Canvas mouse events for exclusion painting ──────────────────────────── |
| 1969 | canvas.addEventListener('mousedown', (e) => { |
| 1970 | if (!currentGeometry || e.button !== 0) return; |
| 1971 | |
| 1972 | // Rotation gizmo takes priority |
| 1973 | if (isGizmoDragging()) return; |
| 1974 | |
| 1975 | // Place on Face mode |
| 1976 | if (placeOnFaceActive) { |
| 1977 | e.preventDefault(); |
| 1978 | handlePlaceOnFaceClick(e); |
| 1979 | return; |
| 1980 | } |
no test coverage detected