2323
2424package processing .app ;
2525
26+ import javax .imageio .ImageIO ;
2627import javax .swing .*;
2728import javax .swing .event .MouseInputListener ;
29+
30+ import com .thizzer .jtouchbar .JTouchBar ;
31+ import com .thizzer .jtouchbar .item .TouchBarItem ;
32+ import com .thizzer .jtouchbar .item .view .TouchBarButton ;
33+
34+ import processing .app .helpers .OSUtils ;
35+
2836import java .awt .*;
2937import java .awt .event .KeyEvent ;
3038import java .awt .event .MouseEvent ;
39+ import java .awt .event .WindowAdapter ;
40+ import java .awt .event .WindowEvent ;
41+ import java .awt .image .BufferedImage ;
42+ import java .io .ByteArrayOutputStream ;
43+ import java .io .IOException ;
3144
3245import static processing .app .I18n .tr ;
3346import static processing .app .Theme .scale ;
@@ -92,10 +105,13 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
92105 private final Color bgcolor ;
93106
94107 private static Image [][] buttonImages ;
108+ private static com .thizzer .jtouchbar .common .Image [][] touchBarImages ;
95109 private int currentRollover ;
96110
97111 private JPopupMenu popup ;
98112 private final JMenu menu ;
113+ private JTouchBar touchBar ;
114+ private TouchBarButton [] touchBarButtons ;
99115
100116 private int buttonCount ;
101117 private int [] state = new int [BUTTON_COUNT ];
@@ -133,10 +149,47 @@ public EditorToolbar(Editor editor, JMenu menu) {
133149 statusFont = Theme .getFont ("buttons.status.font" );
134150 statusColor = Theme .getColor ("buttons.status.color" );
135151
152+ if (OSUtils .isMacOS ()) {
153+ editor .addWindowListener (new WindowAdapter () {
154+ public void windowActivated (WindowEvent e ) {
155+ if (touchBar == null ) {
156+ buildTouchBar ();
157+
158+ touchBar .show (editor );
159+ }
160+ }
161+ });
162+ }
163+
136164 addMouseListener (this );
137165 addMouseMotionListener (this );
138166 KeyboardFocusManager .getCurrentKeyboardFocusManager ().addKeyEventDispatcher (this );
139167 }
168+
169+ private void buildTouchBar () {
170+ loadTouchBarImages ();
171+
172+ touchBar = new JTouchBar ();
173+ touchBarButtons = new TouchBarButton [BUTTON_COUNT ];
174+ touchBar .setCustomizationIdentifier ("Arduino" );
175+
176+ for (int i = 0 ; i < BUTTON_COUNT ; i ++) {
177+ final int selection = i ;
178+
179+ // add spacers before NEW and SERIAL buttons
180+ if (i == NEW ) {
181+ touchBar .addItem (new TouchBarItem (TouchBarItem .NSTouchBarItemIdentifierFixedSpaceSmall ));
182+ } else if (i == SERIAL ) {
183+ touchBar .addItem (new TouchBarItem (TouchBarItem .NSTouchBarItemIdentifierFlexibleSpace ));
184+ }
185+
186+ touchBarButtons [i ] = new TouchBarButton ();
187+ touchBarButtons [i ].setImage (touchBarImages [i ][ROLLOVER ]);
188+ touchBarButtons [i ].setAction (event -> handleSelectionPressed (selection ));
189+
190+ touchBar .addItem (new TouchBarItem (title [i ], touchBarButtons [i ]));
191+ }
192+ }
140193
141194 private void loadButtons () {
142195 Image allButtons = Theme .getThemeImage ("buttons" , this ,
@@ -157,6 +210,36 @@ private void loadButtons() {
157210 }
158211 }
159212 }
213+
214+ private void loadTouchBarImages () {
215+ Image allButtonsRetina = Theme .getThemeImage ("buttons" , this ,
216+ BUTTON_IMAGE_SIZE * BUTTON_COUNT * 2 ,
217+ BUTTON_IMAGE_SIZE * 3 * 2 );
218+ touchBarImages = new com .thizzer .jtouchbar .common .Image [BUTTON_COUNT ][3 ];
219+
220+ for (int i = 0 ; i < BUTTON_COUNT ; i ++) {
221+ for (int state = 0 ; state < 3 ; state ++) {
222+ BufferedImage image = new BufferedImage (BUTTON_WIDTH * 2 , BUTTON_HEIGHT * 2 ,
223+ BufferedImage .TYPE_INT_ARGB );
224+ Graphics g = image .getGraphics ();
225+
226+ int offset = (BUTTON_IMAGE_SIZE * 2 - BUTTON_WIDTH * 2 ) / 2 ;
227+ g .drawImage (allButtonsRetina , -(i * BUTTON_IMAGE_SIZE * 2 ) - offset ,
228+ (-2 + state ) * BUTTON_IMAGE_SIZE * 2 , null );
229+
230+ // convert the image to a PNG to display on the touch bar
231+ ByteArrayOutputStream pngStream = new ByteArrayOutputStream ();
232+
233+ try {
234+ ImageIO .write (image , "PNG" , pngStream );
235+
236+ touchBarImages [i ][state ] = new com .thizzer .jtouchbar .common .Image (pngStream .toByteArray ());
237+ } catch (IOException e ) {
238+ // ignore errors
239+ }
240+ }
241+ }
242+ }
160243
161244 @ Override
162245 public void paintComponent (Graphics screen ) {
@@ -305,6 +388,15 @@ private void setState(int slot, int newState, boolean updateAfter) {
305388 if (updateAfter ) {
306389 repaint ();
307390 }
391+
392+ if (touchBarButtons != null ) {
393+ if (newState == INACTIVE ) {
394+ // use ROLLOVER state when INACTIVE
395+ newState = ROLLOVER ;
396+ }
397+
398+ touchBarButtons [slot ].setImage (touchBarImages [slot ][newState ]);
399+ }
308400 }
309401
310402
@@ -339,6 +431,20 @@ public void mousePressed(MouseEvent e) {
339431 if (sel == -1 ) return ;
340432 currentRollover = -1 ;
341433
434+ handleSelectionPressed (sel , e .isShiftDown (), x , y );
435+ }
436+
437+ public void mouseClicked (MouseEvent e ) {
438+ }
439+
440+ public void mouseReleased (MouseEvent e ) {
441+ }
442+
443+ private void handleSelectionPressed (int sel ) {
444+ handleSelectionPressed (sel , false , 0 , 0 );
445+ }
446+
447+ private void handleSelectionPressed (int sel , boolean isShiftDown , int x , int y ) {
342448 switch (sel ) {
343449 case RUN :
344450 if (!editor .avoidMultipleOperations ) {
@@ -347,10 +453,10 @@ public void mousePressed(MouseEvent e) {
347453 }
348454 break ;
349455
350- // case STOP:
351- // editor.handleStop();
352- // break;
353- //
456+ // case STOP:
457+ // editor.handleStop();
458+ // break;
459+ //
354460 case OPEN :
355461 popup = menu .getPopupMenu ();
356462 popup .show (EditorToolbar .this , x , y );
@@ -365,7 +471,7 @@ public void mousePressed(MouseEvent e) {
365471 break ;
366472
367473 case SAVE :
368- if (e . isShiftDown () ) {
474+ if (isShiftDown ) {
369475 editor .handleSaveAs ();
370476 } else {
371477 editor .handleSave (false );
@@ -375,7 +481,7 @@ public void mousePressed(MouseEvent e) {
375481 case EXPORT :
376482 // launch a timeout timer which can reenable to upload button functionality an
377483 if (!editor .avoidMultipleOperations ) {
378- editor .handleExport (e . isShiftDown () );
484+ editor .handleExport (isShiftDown );
379485 }
380486 break ;
381487
@@ -388,15 +494,6 @@ public void mousePressed(MouseEvent e) {
388494 }
389495 }
390496
391-
392- public void mouseClicked (MouseEvent e ) {
393- }
394-
395-
396- public void mouseReleased (MouseEvent e ) {
397- }
398-
399-
400497 /**
401498 * Set a particular button to be active.
402499 */
0 commit comments