1010import edu .wpi .grip .core .events .ConnectionRemovedEvent ;
1111import edu .wpi .grip .core .events .SocketConnectedChangedEvent ;
1212import javafx .beans .property .BooleanProperty ;
13+ import javafx .beans .property .ObjectProperty ;
1314import javafx .beans .property .SimpleBooleanProperty ;
15+ import javafx .beans .property .SimpleObjectProperty ;
1416import javafx .css .PseudoClass ;
1517import javafx .scene .control .Button ;
1618import javafx .scene .control .Tooltip ;
1921import javafx .scene .input .TransferMode ;
2022
2123import java .util .Collections ;
22- import java .util .Optional ;
2324import java .util .Set ;
2425import java .util .stream .Collectors ;
2526
3031 */
3132public class SocketHandleView extends Button {
3233
34+ private static final PseudoClass DISABLED_PSEUDO_CLASS = PseudoClass .getPseudoClass ("disabled" );
3335 private static final PseudoClass CONNECTING_PSEUDO_CLASS = PseudoClass .getPseudoClass ("connecting" );
3436 private static final PseudoClass CONNECTED_PSEUDO_CLASS = PseudoClass .getPseudoClass ("connected" );
3537
@@ -41,8 +43,8 @@ public class SocketHandleView extends Button {
4143 * connection to be made.
4244 */
4345 @ Singleton
44- protected static final class SocketHandleDraggingSocketService {
45- private Optional <Socket > draggingSocket = Optional . empty ( );
46+ protected static final class DragService {
47+ private final ObjectProperty <Socket > socket = new SimpleObjectProperty <>( this , "socket" );
4648 }
4749
4850 final private BooleanProperty connectingProperty = new SimpleBooleanProperty (this , "connecting" , false );
@@ -56,7 +58,7 @@ public interface Factory {
5658 SocketHandleView (EventBus eventBus ,
5759 Pipeline pipeline ,
5860 Connection .Factory <Object > connectionFactory ,
59- SocketHandleDraggingSocketService draggingSocketService ,
61+ DragService dragService ,
6062 @ Assisted Socket socket ) {
6163 this .eventBus = eventBus ;
6264 this .socket = socket ;
@@ -92,20 +94,27 @@ public interface Factory {
9294 mouseEvent .consume ();
9395
9496 this .connectingProperty .set (true );
95- draggingSocketService . draggingSocket = Optional . of (this .socket );
97+ dragService . socket . setValue (this .socket );
9698 });
9799
98100 // Remove the "connecting" property (which changes the appearance of the handle) when the user moves the cursor
99101 // out of the socket handle or completes the drag. If the user moves the cursor away, it only disables the
100102 // connecting property if it's not the socket that the user started dragging from, since that one is supposed
101103 // to be dragged away.
102- this .setOnDragExited (dragEvent ->
103- draggingSocketService .draggingSocket .ifPresent (other -> this .connectingProperty .set (this .socket == other )));
104- this .setOnDragDone (dragEvent -> this .connectingProperty .set (false ));
104+ this .setOnDragExited (dragEvent -> {
105+ Socket <?> other = dragService .socket .getValue ();
106+ if (other != null ) this .connectingProperty .set (this .socket == other );
107+ });
108+
109+ this .setOnDragDone (dragEvent -> {
110+ this .connectingProperty .set (false );
111+ dragService .socket .setValue (null );
112+ });
105113
106114 // When the user drops the connection onto another socket, add a new connection.
107115 this .setOnDragDropped (dragEvent -> {
108- draggingSocketService .draggingSocket .ifPresent (other -> {
116+ Socket <?> other = dragService .socket .getValue ();
117+ if (other != null ) {
109118 InputSocket inputSocket ;
110119 OutputSocket outputSocket ;
111120
@@ -127,17 +136,23 @@ public interface Factory {
127136 }
128137 final Connection connection = connectionFactory .create (outputSocket , inputSocket );
129138 eventBus .post (new ConnectionAddedEvent (connection ));
130- });
139+ }
131140 });
132141
133142 // Accept a drag event if it's possible to connect the two sockets
134143 this .setOnDragOver (dragEvent -> {
135- draggingSocketService .draggingSocket .ifPresent (other -> {
136- if (pipeline .canConnect (this .socket , other )) {
137- dragEvent .acceptTransferModes (TransferMode .ANY );
138- this .connectingProperty .set (true );
139- }
140- });
144+ Socket <?> other = dragService .socket .getValue ();
145+ if (other != null && pipeline .canConnect (this .socket , other )) {
146+ dragEvent .acceptTransferModes (TransferMode .ANY );
147+ this .connectingProperty .set (true );
148+ }
149+ });
150+
151+ // While dragging, disable any socket that we can't drag onto, providing visual feedback to the user about
152+ // what can be connected.
153+ dragService .socket .addListener (observable -> {
154+ Socket <?> other = dragService .socket .getValue ();
155+ pseudoClassStateChanged (DISABLED_PSEUDO_CLASS , other != null && !pipeline .canConnect (socket , other ));
141156 });
142157 }
143158
0 commit comments