@@ -17,9 +17,20 @@ class W_Marker extends Widget {
1717 private final int MARKER_BUTTON_HEIGHT = 20 ;
1818 private final int MARKER_BUTTON_GRID_CELL_HEIGHT = 30 ;
1919 private final int MAX_NUMBER_OF_MARKER_BUTTONS = 8 ;
20+ private final int MARKER_BUTTON_GRID_EXTERIOR_PADDING = 10 ;
2021 private Button [] markerButtons = new Button [MAX_NUMBER_OF_MARKER_BUTTONS ];
2122 private Grid markerButtonGrid;
2223
24+ private Textfield markerReceiveIPTextfield;
25+ private Textfield markerReceivePortTextfield;
26+ private String markerReceiveIP = " 127.0.0.1" ;
27+ private int markerReceivePort = 12350 ;
28+ private final int MARKER_RECEIVE_TEXTFIELD_WIDTH = 100 ;
29+ private final int MARKER_RECEIVE_TEXTFIELD_HEIGHT = 20 ;
30+ private int markerReceiveX, markerReceiveY, markerReceiveW, markerReceiveH;
31+
32+ private hypermedia.net. UDP udpReceiver;
33+
2334 private MarkerBar markerBar;
2435 private int graphX, graphY, graphW, graphH;
2536 private int PAD_FIVE = 5 ;
@@ -47,11 +58,20 @@ class W_Marker extends Widget {
4758 markerButtonGrid. setDrawTableBorder(true );
4859 markerButtonGrid. setDrawTableInnerLines(true );
4960
61+ udpReceiver = new UDP (_parent, markerReceivePort);
62+ udpReceiver. listen(true );
63+ udpReceiver. log(true );
64+ udpReceiver. setReceiveHandler(" receiveMarkerViaUdp" );
65+
66+ createMarkerReceiveUI();
67+
5068 // Add all cp5 elements to a list so that they can be checked for overlap
5169 cp5ElementsToCheckForOverlap = new ArrayList<controlP5. Controller > ();
5270 for (int i = 0 ; i < MAX_NUMBER_OF_MARKER_BUTTONS ; i++ ) {
5371 cp5ElementsToCheckForOverlap. add(markerButtons[i]);
5472 }
73+ cp5ElementsToCheckForOverlap. add(markerReceiveIPTextfield);
74+ cp5ElementsToCheckForOverlap. add(markerReceivePortTextfield);
5575 }
5676
5777 public void update (){
@@ -83,6 +103,8 @@ class W_Marker extends Widget {
83103
84104 resizeMarkerButtonGrid();
85105
106+ updateMarkerReceiveUIPosition();
107+
86108 updateGraphDims();
87109 markerBar. screenResized(graphX, graphY, graphW, graphH);
88110
@@ -97,7 +119,7 @@ class W_Marker extends Widget {
97119
98120 private void resizeMarkerButtonGrid () {
99121 int tableX = x + GRAPH_PADDING ;
100- int tableY = y + GRAPH_PADDING ;
122+ int tableY = y + MARKER_BUTTON_GRID_EXTERIOR_PADDING ;
101123 int tableW = w - GRAPH_PADDING * 2 ;
102124 int tableH = y - graphY - GRAPH_PADDING * 2 ;
103125 markerButtonGrid. setDim(tableX, tableY, tableW);
@@ -117,6 +139,20 @@ class W_Marker extends Widget {
117139 }
118140 }
119141
142+ private void updateMarkerReceiveUIPosition () {
143+ final int MARKER_UI_PADDING_Y = 10 ;
144+ markerReceiveX = x + GRAPH_PADDING ;
145+ markerReceiveY = y + MARKER_BUTTON_GRID_EXTERIOR_PADDING * 2 + MARKER_BUTTON_GRID_CELL_HEIGHT * 2 ;
146+ println (markerReceiveY);
147+ markerReceiveW = w - GRAPH_PADDING * 2 ;
148+ markerReceiveH = MARKER_RECEIVE_TEXTFIELD_HEIGHT + MARKER_UI_PADDING_Y ;
149+ int halfMarkerReceiveW = markerReceiveW / 2 ;
150+ int markerReceiveUIMiddle = markerReceiveX + halfMarkerReceiveW;
151+
152+ markerReceiveIPTextfield. setPosition(markerReceiveX, markerReceiveY + MARKER_UI_PADDING_Y / 2 );
153+ markerReceivePortTextfield. setPosition(markerReceiveUIMiddle, markerReceiveY + MARKER_UI_PADDING_Y / 2 );
154+ }
155+
120156 private void createMarkerButtons () {
121157 for (int i = 0 ; i < MAX_NUMBER_OF_MARKER_BUTTONS ; i++ ) {
122158 // Create marker buttons
@@ -131,7 +167,7 @@ class W_Marker extends Widget {
131167 newButton. setBorderColor(OBJECT_BORDER_GREY );
132168 newButton. onRelease(new CallbackListener () {
133169 public void controlEvent (CallbackEvent theEvent ) {
134- insertMarkerFromKeyboardOrButton (markerNumber);
170+ insertMarker (markerNumber);
135171 }
136172 });
137173 newButton. setDescription(" Click to insert marker " + markerNumber + " into the data stream." );
@@ -144,35 +180,61 @@ class W_Marker extends Widget {
144180 public boolean checkForMarkerKeyPress (char keyPress ) {
145181 switch (keyPress) {
146182 case ' z' :
147- insertMarkerFromKeyboardOrButton (1 );
183+ insertMarker (1 );
148184 return true ;
149185 case ' x' :
150- insertMarkerFromKeyboardOrButton (2 );
186+ insertMarker (2 );
151187 return true ;
152188 case ' c' :
153- insertMarkerFromKeyboardOrButton (3 );
189+ insertMarker (3 );
154190 return true ;
155191 case ' v' :
156- insertMarkerFromKeyboardOrButton (4 );
192+ insertMarker (4 );
157193 return true ;
158194 case ' Z' :
159- insertMarkerFromKeyboardOrButton (5 );
195+ insertMarker (5 );
160196 return true ;
161197 case ' X' :
162- insertMarkerFromKeyboardOrButton (6 );
198+ insertMarker (6 );
163199 return true ;
164200 case ' C' :
165- insertMarkerFromKeyboardOrButton (7 );
201+ insertMarker (7 );
166202 return true ;
167203 case ' V' :
168- insertMarkerFromKeyboardOrButton (8 );
204+ insertMarker (8 );
169205 return true ;
170206 default :
171207 return false ;
172208 }
173209 }
174210
175- private void insertMarkerFromKeyboardOrButton (int markerNumber ) {
211+ private void createMarkerReceiveUI () {
212+ markerReceiveIPTextfield = createTextfield(" markerReceiveIPTextfield" , markerReceiveIP);
213+ markerReceivePortTextfield = createTextfield(" markerReceivePortTextfield" , Integer . toString(markerReceivePort));
214+ updateMarkerReceiveUIPosition();
215+ }
216+
217+ /* Create textfields for network parameters */
218+ private Textfield createTextfield (String name , String default_text ) {
219+ Textfield myTextfield = localCP5. addTextfield(name). align(10 , 100 , 10 , 100 ) // Alignment
220+ .setSize(MARKER_RECEIVE_TEXTFIELD_WIDTH , MARKER_RECEIVE_TEXTFIELD_HEIGHT ) // Size of textfield
221+ .setFont(f2)
222+ .setFocus(false ) // Deselects textfield
223+ .setColor(OPENBCI_DARKBLUE )
224+ .setColorBackground(color (255 , 255 , 255 )) // text field bg color
225+ .setColorValueLabel(OPENBCI_DARKBLUE ) // text color
226+ .setColorForeground(OPENBCI_DARKBLUE ) // border color when not selected
227+ .setColorActive(isSelected_color) // border color when selected
228+ .setColorCursor(OPENBCI_DARKBLUE )
229+ .setText(default_text) // Default text in the field
230+ .setCaptionLabel(" " ) // Remove caption label
231+ .setVisible(true ) // Initially visible
232+ .setAutoClear(true ) // Autoclear
233+ ;
234+ return myTextfield;
235+ }
236+
237+ private void insertMarker (int markerNumber ) {
176238 int markerChannel = ((DataSource )currentBoard). getMarkerChannel();
177239
178240 if (currentBoard instanceof BoardBrainFlow ) {
@@ -182,6 +244,16 @@ class W_Marker extends Widget {
182244 }
183245 }
184246
247+ public void insertMarkerFromExternal (float markerValue ) {
248+ int markerChannel = ((DataSource )currentBoard). getMarkerChannel();
249+
250+ if (currentBoard instanceof BoardBrainFlow ) {
251+ if (markerChannel != - 1 ) {
252+ ((Board )currentBoard). insertMarker(markerValue);
253+ }
254+ }
255+ }
256+
185257 public void setMarkerWindow (int n ) {
186258 markerWindow = markerWindow. values()[n];
187259 markerBar. adjustTimeAxis(markerWindow. getValue());
@@ -207,16 +279,15 @@ class W_Marker extends Widget {
207279 return markerCount;
208280 }
209281
210- };
282+ public String getMarkerReceiveIP () {
283+ return getIpAddrFromStr(markerReceiveIPTextfield. getText());
284+ }
211285
212- // The following global functions are used by the Marker widget dropdowns. This method is the least amount of code.
213- public void markerWindowDropdown (int n ) {
214- w_marker. setMarkerWindow(n);
215- }
286+ public String getMarkerReceivePort () {
287+ return dropNonPrintableChars(markerReceivePortTextfield. getText());
288+ }
216289
217- public void markerCountDropdown (int n ) {
218- w_marker. setMarkerCount(n);
219- }
290+ }; // end class W_Marker
220291
221292// This class contains the time series plot for displaying the markers over time
222293class MarkerBar {
@@ -373,8 +444,7 @@ class MarkerBar {
373444 }
374445}; // end of class
375446
376-
377-
447+ // Enum for the Marker Window in W_Marker class
378448public enum MarkerWindow implements IndexingInterface
379449{
380450 FIVE (0 , 5 , " 5 sec" ),
@@ -415,6 +485,7 @@ public enum MarkerWindow implements IndexingInterface
415485 }
416486}
417487
488+ // Enum for the Marker Count in W_Marker class
418489public enum MarkerCount implements IndexingInterface
419490{
420491 FOUR (0 , 4 , " 4" ),
@@ -452,4 +523,27 @@ public enum MarkerCount implements IndexingInterface
452523 }
453524 return enumStrings;
454525 }
526+ }
527+
528+ // The following global functions are used by the Marker widget dropdowns. This method is the least amount of code.
529+ public void markerWindowDropdown (int n ) {
530+ w_marker. setMarkerWindow(n);
531+ }
532+
533+ public void markerCountDropdown (int n ) {
534+ w_marker. setMarkerCount(n);
535+ }
536+
537+ // Custom UDP receive handler for receiving markers from external sources
538+ public void receiveMarkerViaUdp ( byte [] data , String ip , int port ) {
539+ float markerValue = convertByteArrayToFloat(data);
540+ String message = Float . toString(markerValue);
541+
542+ // println( "received: \""+message+"\" from "+ip+" on port "+port );
543+ w_marker. insertMarkerFromExternal(markerValue);
544+ }
545+
546+ public float convertByteArrayToFloat (byte [] array ) {
547+ ByteBuffer buffer = ByteBuffer . wrap(array);
548+ return buffer. getFloat();
455549}
0 commit comments