this repo has no description

multiselect works

phaz.uk 41952266 60049985

verified
Changed files
+98 -63
src
+92 -53
src/App.tsx
··· 1 - import { createSignal, onCleanup, onMount } from "solid-js"; 1 + import { createEffect, createSignal, onCleanup, onMount } from "solid-js"; 2 2 import "./App.css"; 3 3 import { renderBackgroundGrid, renderContextMenu, renderNodes, renderNullTab, renderTempDrawing } from "./renderer"; 4 4 import { lerp } from "./utils/lerp"; ··· 10 10 import { ContextMenu } from "./structs/ContextMenu"; 11 11 import { NodeManager } from "./Mangers/NodeManager"; 12 12 import { TabMenu } from "./components/TabMenu"; 13 + import { ConfirmationPopup } from "./components/ConfirmationPopup"; 13 14 14 15 import * as keybinds from './keybinds'; 15 16 import { listen } from "@tauri-apps/api/event"; 16 - import { ConfirmationPopup } from "./components/ConfirmationPopup"; 17 17 18 18 let App = () => { 19 - let [ selectedNodes, setSelectedNodes ] = createSignal<Node[]>([]); 19 + let [ selectedNodes, setSelectedNodes ] = createSignal<Node[]>([], { equals: false }); 20 20 21 21 let canvas!: HTMLCanvasElement; 22 22 let ctx: CanvasRenderingContext2D; ··· 57 57 visible: false 58 58 } 59 59 60 + createEffect(() => { 61 + let snodes = selectedNodes(); 62 + 63 + let anodes = NodeManager.Instance.GetNodes(); 64 + if(!anodes)return; 65 + 66 + for(let node of anodes)node.selected = false; 67 + for(let node of snodes)node.selected = true; 68 + }) 69 + 60 70 onMount(async () => { 61 71 NodeManager.Instance.HookTabChange(() => setSelectedNodes([])); 62 72 ··· 110 120 contextMenu.visible = true; 111 121 } 112 122 123 + let isShiftClick = false; 113 124 canvas.onmousedown = ( e ) => { 125 + isShiftClick = e.shiftKey; 126 + 114 127 if( 115 128 e.clientY < 60 || 116 129 e.clientX < 220 || ··· 156 169 157 170 if(nodes){ 158 171 nodes.map(node => { 159 - if(!e.shiftKey)node.selected = false; 160 - 161 172 if(isPointInRectApplyOffset(canvas, { x: offset[0], y: offset[1], scale }, 162 173 e.clientX, e.clientY, 163 174 node.x - 20, node.y, node.w + 40, node.h ··· 216 227 217 228 movingNode = clickedNode; 218 229 219 - if(!e.shiftKey){ 220 - if(clickedNode){ 221 - clickedNode.selected = true; 222 - setSelectedNodes([ clickedNode ]); 223 - } else{ 224 - setSelectedNodes([]); 225 - } 226 - } else{ 227 - clickedNode.selected = true; 228 - 229 - let snodes = selectedNodes(); 230 - if(!snodes.find(x => x.id === clickedNode!.id)){ 231 - snodes.push(clickedNode); 232 - clickedNode.selected = true; 233 - 234 - setSelectedNodes(snodes); 235 - } 236 - } 237 - 238 230 isMouseDown = true; 239 231 mouseStartPos = [ e.clientX, e.clientY ]; 232 + mouseMovePos = [ e.clientX, e.clientY ]; 240 233 } 241 234 242 235 canvas.onmousemove = ( e ) => { ··· 262 255 snodes.push(hoveredNode); 263 256 264 257 // @ts-ignore 265 - hoveredNode.selected = true; 258 + hoveredNode.x = Math.round(hoveredNode.x / 10) * 10; 259 + // @ts-ignore 260 + hoveredNode.y = Math.round(hoveredNode.y / 10) * 10; 261 + 266 262 setSelectedNodes(snodes); 267 263 } 268 264 } 269 265 270 266 return; 271 - } 267 + } else if(isShiftClick)return; 272 268 273 269 if(isMouseDown){ 274 270 if(isDrawing){ 275 271 drawingTo = screenToWorldSpace(canvas, { x: offset[0], y: offset[1], scale }, e.clientX - 10 * scale, e.clientY - 10 * scale) as [ number, number ]; 276 272 } else if(movingNode){ 277 - movingNode.x = movingNode.x - (mouseStartPos[0] - e.clientX) / scale; 278 - movingNode.y = movingNode.y - (mouseStartPos[1] - e.clientY) / scale; 273 + let nodes = selectedNodes(); 279 274 280 - mouseStartPos = [ e.clientX, e.clientY ]; 275 + for(let node of nodes){ 276 + node.x = node.x - (mouseMovePos[0] - e.clientX) / scale; 277 + node.y = node.y - (mouseMovePos[1] - e.clientY) / scale; 278 + } 279 + 280 + mouseMovePos = [ e.clientX, e.clientY ]; 281 281 NodeManager.Instance.UpdateConfig(); 282 282 } else{ 283 - offsetTarget = [ offsetTarget[0] - (mouseStartPos[0] - e.clientX) / scale, offsetTarget[1] - (mouseStartPos[1] - e.clientY) / scale ]; 284 - mouseStartPos = [ e.clientX, e.clientY ]; 283 + offsetTarget = [ offsetTarget[0] - (mouseMovePos[0] - e.clientX) / scale, offsetTarget[1] - (mouseMovePos[1] - e.clientY) / scale ]; 284 + mouseMovePos = [ e.clientX, e.clientY ]; 285 285 286 286 screenMoved = true; 287 287 } ··· 325 325 326 326 canvas.onmouseup = ( e ) => { 327 327 let nodes = NodeManager.Instance.GetNodes(); 328 + let clickedNode; 328 329 329 330 if(nodes){ 330 331 nodes.map(node => { 331 - node.inputs.map(( input, i ) => { 332 - if(isPointInRectApplyOffset(canvas, { x: offset[0], y: offset[1], scale }, 333 - e.clientX, e.clientY, 334 - node.x - 10, 335 - node.y + 50 + (30 * i), 336 - 20, 20 337 - )){ 338 - if(isDrawing){ 339 - let fromType = NodeIOResolveAnyTypes(drawingFrom!); 340 - let toType = NodeIOResolveAnyTypes(input); 332 + if(isPointInRectApplyOffset(canvas, { x: offset[0], y: offset[1], scale }, 333 + e.clientX, e.clientY, 334 + node.x - 20, node.y, node.w + 40, node.h 335 + )){ 336 + clickedNode = node; 337 + 338 + node.inputs.map(( input, i ) => { 339 + if(isPointInRectApplyOffset(canvas, { x: offset[0], y: offset[1], scale }, 340 + e.clientX, e.clientY, 341 + node.x - 10, 342 + node.y + 50 + (30 * i), 343 + 20, 20 344 + )){ 345 + if(isDrawing){ 346 + let fromType = NodeIOResolveAnyTypes(drawingFrom!); 347 + let toType = NodeIOResolveAnyTypes(input); 341 348 342 - if( 343 - drawingFrom!.connections.indexOf(input) === -1 && 344 - ( 345 - toType === null || 346 - NodeIOCanCast(fromType, toType) 347 - ) 348 - ){ 349 - drawingFrom!.connections.push(input); 350 - input.connections.push(drawingFrom!); 349 + if( 350 + drawingFrom!.connections.indexOf(input) === -1 && 351 + ( 352 + toType === null || 353 + NodeIOCanCast(fromType, toType) 354 + ) 355 + ){ 356 + drawingFrom!.connections.push(input); 357 + input.connections.push(drawingFrom!); 351 358 352 - NodeManager.Instance.UpdateConfig(); 359 + NodeManager.Instance.UpdateConfig(); 360 + } 353 361 } 354 362 } 355 - } 356 - }) 363 + }) 364 + } 357 365 }) 366 + } 367 + 368 + let diffX = mouseStartPos[0] - e.clientX; 369 + let diffY = mouseStartPos[1] - e.clientY; 370 + 371 + let dist = Math.sqrt(diffX * diffX + diffY * diffY); 372 + 373 + if(dist < 10){ 374 + if(clickedNode){ 375 + if(e.shiftKey){ 376 + let snodes = selectedNodes(); 377 + if(snodes.indexOf(clickedNode) === -1)snodes.push(clickedNode); 378 + 379 + // @ts-ignore 380 + clickedNode.x = Math.round(clickedNode.x / 10) * 10; 381 + // @ts-ignore 382 + clickedNode.y = Math.round(clickedNode.y / 10) * 10; 383 + 384 + setSelectedNodes(snodes); 385 + } else{ 386 + // @ts-ignore 387 + clickedNode.x = Math.round(clickedNode.x / 10) * 10; 388 + // @ts-ignore 389 + clickedNode.y = Math.round(clickedNode.y / 10) * 10; 390 + 391 + setSelectedNodes([ clickedNode ]); 392 + } 393 + } else { 394 + setSelectedNodes([]); 395 + } 358 396 } 359 397 360 398 isDrawing = false; ··· 407 445 408 446 let isMouseDown = false; 409 447 let mouseStartPos = [ 0, 0 ]; 448 + let mouseMovePos = [ 0, 0 ]; 410 449 411 450 let interval = setInterval(() => { 412 451 if(screenMoved){
+2 -2
src/Nodes/OSCTrigger.tsx
··· 10 10 typeId: 'osctrigger', 11 11 12 12 w: 200, 13 - h: 55, 13 + h: 50, 14 14 15 15 statics: [ 16 16 { ··· 83 83 } 84 84 }); 85 85 86 - node.h = 65 + (parameters.length + 1) * 30; 86 + node.h = 60 + (parameters.length + 1) * 30; 87 87 NodeManager.Instance.UpdateConfig(); 88 88 } 89 89 };
+1 -1
src/Nodes/Statics/Float.tsx
··· 7 7 typeId: 'staticfloat', 8 8 9 9 w: 200, 10 - h: 85, 10 + h: 80, 11 11 12 12 statics: [{ 13 13 type: NodeType.Float,
+1 -1
src/Nodes/Statics/Int.tsx
··· 7 7 typeId: 'staticint', 8 8 9 9 w: 200, 10 - h: 85, 10 + h: 80, 11 11 12 12 statics: [{ 13 13 type: NodeType.Int,
+1 -1
src/Nodes/Statics/String.tsx
··· 7 7 typeId: 'staticstring', 8 8 9 9 w: 200, 10 - h: 85, 10 + h: 80, 11 11 12 12 statics: [{ 13 13 type: NodeType.String,
+1 -5
src/components/ControlBar.tsx
··· 1 1 import './ControlBar.css'; 2 2 3 - import { Accessor, createEffect, createSignal, For, Match, Show, Switch } from 'solid-js'; 3 + import { Accessor, createSignal, For, Match, Show, Switch } from 'solid-js'; 4 4 import { Node, NodeType } from '../structs/node'; 5 5 import { TextInput } from './TextInput'; 6 6 import { invoke } from '@tauri-apps/api/core'; ··· 14 14 } 15 15 16 16 export let ControlBar = ( props: ControlBarProps ) => { 17 - createEffect(() => { 18 - console.log(props.node()); 19 - }) 20 - 21 17 return ( 22 18 <div class="control-bar"> 23 19 <For each={props.node()[0]?.statics}>