Skip to content

Commit d4d7062

Browse files
sandeepmistrycmaglie
authored andcommitted
Add macOS Touch Bar support
1 parent f09bb9d commit d4d7062

File tree

4 files changed

+135
-16
lines changed

4 files changed

+135
-16
lines changed

app/.classpath

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
<classpathentry kind="src" path="test"/>
55
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
66
<classpathentry combineaccessrules="false" kind="src" path="/arduino-core"/>
7-
<classpathentry kind="output" path="bin"/>
87
<classpathentry kind="lib" path="lib/apple.jar"/>
98
<classpathentry kind="lib" path="lib/batik-1.8.jar"/>
109
<classpathentry kind="lib" path="lib/batik-anim-1.8.jar"/>
@@ -53,4 +52,6 @@
5352
<classpathentry kind="lib" path="test-lib/fest-swing-1.2.jar"/>
5453
<classpathentry kind="lib" path="test-lib/fest-util-1.1.2.jar"/>
5554
<classpathentry kind="lib" path="test-lib/jcip-annotations-1.0.jar"/>
55+
<classpathentry kind="lib" path="lib/jtouchbar-0.2.0-20180827.120213-5.jar"/>
56+
<classpathentry kind="output" path="bin"/>
5657
</classpath>
317 KB
Binary file not shown.

app/lib/jtouchbar.LICENSE.MIT.txt

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 thizzer.com
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

app/src/processing/app/EditorToolbar.java

+112-15
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,24 @@
2323

2424
package processing.app;
2525

26+
import javax.imageio.ImageIO;
2627
import javax.swing.*;
2728
import 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+
2836
import java.awt.*;
2937
import java.awt.event.KeyEvent;
3038
import 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

3245
import static processing.app.I18n.tr;
3346
import 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

Comments
 (0)