15
15
*/
16
16
17
17
#include "core/core.h"
18
+ #include "core/structs.h"
18
19
#include "handmade_math.h"
19
20
#include "render/draw.h"
20
21
#include "stb_ds.h"
@@ -39,29 +40,36 @@ static const char *stateNames[] = {
39
40
[STATE_SELECT_AREA ] = "SelArea" ,
40
41
[STATE_SELECT_ONE ] = "SelOne" ,
41
42
[STATE_MOVE_SELECTION ] = "MoveSel" ,
43
+ [STATE_CLICK_ENDPOINT ] = "ClickEndpoint" ,
42
44
[STATE_CLICK_PORT ] = "ClickPort" ,
43
45
[STATE_DRAG_WIRING ] = "DragWiring" ,
44
46
[STATE_START_CLICK_WIRING ] = "StartClickWiring" ,
45
47
[STATE_CLICK_WIRING ] = "ClickWiring" ,
46
48
[STATE_CONNECT_PORT ] = "ConnectPort" ,
47
49
[STATE_FLOATING_WIRE ] = "FloatingWire" ,
50
+ [STATE_CANCEL_WIRE ] = "CancelWire" ,
48
51
[STATE_ADDING_COMPONENT ] = "AddingComponent" ,
49
52
[STATE_ADD_COMPONENT ] = "AddComponent" ,
50
53
};
51
54
52
55
static void ux_mouse_down_state_machine (CircuitUX * ux , HMM_Vec2 worldMousePos ) {
53
56
bool rightDown = ux -> input .modifiers & MODIFIER_RMB ;
54
57
bool leftDown = ux -> input .modifiers & MODIFIER_LMB ;
58
+ bool shiftDown = ux -> input .modifiers & MODIFIER_SHIFT ;
59
+ bool escDown = bv_is_set (ux -> input .keysDown , KEYCODE_ESCAPE );
55
60
56
61
bool overPort = false;
57
62
bool overItem = false;
63
+ bool overEndpoint = false;
58
64
59
65
for (size_t i = 0 ; i < arrlen (ux -> view .hovered ); i ++ ) {
60
66
ID id = ux -> view .hovered [i ];
61
67
if (id_type (id ) == ID_PORT ) {
62
68
overPort = true;
63
69
} else if (id_type (id ) == ID_COMPONENT || id_type (id ) == ID_WAYPOINT ) {
64
70
overItem = true;
71
+ } else if (id_type (id ) == ID_ENDPOINT ) {
72
+ overEndpoint = true;
65
73
}
66
74
}
67
75
@@ -102,6 +110,12 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
102
110
if (leftDown ) {
103
111
if (inSelection ) {
104
112
state = STATE_MOVE_SELECTION ;
113
+ } else if (overEndpoint ) {
114
+ if (shiftDown && overPort ) {
115
+ state = STATE_CLICK_PORT ;
116
+ } else {
117
+ state = STATE_CLICK_ENDPOINT ;
118
+ }
105
119
} else if (overPort ) {
106
120
state = STATE_CLICK_PORT ;
107
121
} else if (overItem ) {
@@ -152,6 +166,7 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
152
166
state = STATE_UP ;
153
167
}
154
168
break ;
169
+ case STATE_CLICK_ENDPOINT : // fallthrough
155
170
case STATE_CLICK_PORT :
156
171
if (!leftDown ) {
157
172
state = STATE_START_CLICK_WIRING ;
@@ -160,7 +175,9 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
160
175
}
161
176
break ;
162
177
case STATE_DRAG_WIRING :
163
- if (overPort && !leftDown ) {
178
+ if (escDown ) {
179
+ state = STATE_CANCEL_WIRE ;
180
+ } else if (overPort && !leftDown ) {
164
181
state = STATE_CONNECT_PORT ;
165
182
} else if (!overPort && !leftDown ) {
166
183
state = STATE_FLOATING_WIRE ;
@@ -178,6 +195,8 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
178
195
} else if (!overPort ) {
179
196
state = STATE_FLOATING_WIRE ;
180
197
}
198
+ } else if (escDown ) {
199
+ state = STATE_CANCEL_WIRE ;
181
200
}
182
201
break ;
183
202
case STATE_CONNECT_PORT :
@@ -190,6 +209,11 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
190
209
state = STATE_UP ;
191
210
}
192
211
break ;
212
+ case STATE_CANCEL_WIRE :
213
+ if (!leftDown && !escDown ) {
214
+ state = STATE_UP ;
215
+ }
216
+ break ;
193
217
case STATE_ADDING_COMPONENT :
194
218
if (leftDown ) {
195
219
state = STATE_ADD_COMPONENT ;
@@ -282,6 +306,16 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
282
306
}
283
307
break ;
284
308
309
+ case STATE_CLICK_ENDPOINT :
310
+ for (size_t i = 0 ; i < arrlen (ux -> view .hovered ); i ++ ) {
311
+ ID id = ux -> view .hovered [i ];
312
+ if (id_type (id ) == ID_ENDPOINT ) {
313
+ ux_continue_wire (ux , id );
314
+ break ;
315
+ }
316
+ }
317
+ break ;
318
+
285
319
case STATE_CLICK_PORT :
286
320
for (size_t i = 0 ; i < arrlen (ux -> view .hovered ); i ++ ) {
287
321
ID id = ux -> view .hovered [i ];
@@ -305,11 +339,23 @@ static void ux_mouse_down_state_machine(CircuitUX *ux, HMM_Vec2 worldMousePos) {
305
339
ID id = ux -> view .hovered [i ];
306
340
if (id_type (id ) == ID_PORT ) {
307
341
ux_connect_wire (ux , id );
342
+ ux_route (ux );
308
343
break ;
309
344
}
310
345
}
311
346
break ;
312
347
348
+ case STATE_CANCEL_WIRE :
349
+ ux_cancel_wire (ux );
350
+
351
+ // rebuild the BVH after removing things
352
+ ux_build_bvh (ux );
353
+
354
+ log_debug ("routing after cancel" );
355
+ ux_route (ux );
356
+ log_debug ("cancelled wire, finished routing" );
357
+ break ;
358
+
313
359
default :
314
360
break ;
315
361
}
@@ -559,19 +605,48 @@ void ux_start_wire(CircuitUX *ux, PortID portID) {
559
605
circuit_add_endpoint (& ux -> view .circuit , netID , NO_PORT , HMM_V2 (0 , 0 ));
560
606
}
561
607
608
+ void ux_continue_wire (CircuitUX * ux , EndpointID endpointID ) {
609
+ ux -> newNet = false;
610
+ ux -> endpointStart = NO_ENDPOINT ;
611
+ ux -> endpointEnd = endpointID ;
612
+ Endpoint * endpoint = circuit_endpoint_ptr (& ux -> view .circuit , endpointID );
613
+ if (endpoint -> port != NO_PORT ) {
614
+ // disconnect endpoint from port
615
+ Port * port = circuit_port_ptr (& ux -> view .circuit , endpoint -> port );
616
+ port -> endpoint = NO_ENDPOINT ;
617
+ endpoint -> port = NO_PORT ;
618
+ }
619
+ Net * net = circuit_net_ptr (& ux -> view .circuit , endpoint -> net );
620
+ int count = 0 ;
621
+ EndpointID netEndpointID = net -> endpointFirst ;
622
+ EndpointID otherEndpointID = NO_ENDPOINT ;
623
+ while (circuit_has (& ux -> view .circuit , netEndpointID )) {
624
+ Endpoint * endpoint = circuit_endpoint_ptr (& ux -> view .circuit , netEndpointID );
625
+ if (netEndpointID != endpointID ) {
626
+ otherEndpointID = netEndpointID ;
627
+ }
628
+ count ++ ;
629
+ netEndpointID = endpoint -> next ;
630
+ }
631
+ if (count <= 2 ) {
632
+ ux -> newNet = true;
633
+ ux -> endpointStart = otherEndpointID ;
634
+ }
635
+ }
636
+
562
637
void ux_cancel_wire (CircuitUX * ux ) {
638
+ NetID netID = circuit_endpoint_ptr (& ux -> view .circuit , ux -> endpointEnd )-> net ;
563
639
circuit_del (& ux -> view .circuit , ux -> endpointEnd );
564
640
if (ux -> newNet ) {
565
- Endpoint * endpoint =
566
- circuit_endpoint_ptr (& ux -> view .circuit , ux -> endpointStart );
567
- NetID netID = endpoint -> net ;
568
- circuit_del (& ux -> view .circuit , ux -> endpointStart );
641
+ if (circuit_has (& ux -> view .circuit , ux -> endpointStart )) {
642
+ circuit_del (& ux -> view .circuit , ux -> endpointStart );
643
+ }
569
644
circuit_del (& ux -> view .circuit , netID );
570
645
}
646
+
571
647
ux -> newNet = false;
572
648
ux -> endpointStart = NO_ENDPOINT ;
573
649
ux -> endpointEnd = NO_ENDPOINT ;
574
- ux_route (ux );
575
650
}
576
651
577
652
void ux_connect_wire (CircuitUX * ux , PortID portID ) {
@@ -583,7 +658,6 @@ void ux_connect_wire(CircuitUX *ux, PortID portID) {
583
658
}
584
659
585
660
circuit_endpoint_connect (& ux -> view .circuit , ux -> endpointEnd , portID );
586
- ux_route (ux );
587
661
588
662
ux -> newNet = false;
589
663
ux -> endpointStart = NO_ENDPOINT ;
0 commit comments