From a6b892ed35ae634065ed400ce9bd66b3083b6414 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Mon, 15 Oct 2012 22:48:12 +0200 Subject: [PATCH] boards and cpu type menus --- app/src/processing/app/Base.java | 163 +++++++++++++++++++++++++---- app/src/processing/app/Editor.java | 9 +- hardware/arduino/avr/boards.txt | 32 ++++++ 3 files changed, 181 insertions(+), 23 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 5754a8264..d6250f5fd 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -1107,15 +1107,17 @@ public class Base { } - public void rebuildBoardsMenu(JMenu menu) { + public void rebuildBoardsMenu(JMenu boardsMenu, final JMenu cpuTypeMenu) { String selPackage = Preferences.get("target_package"); String selPlatform = Preferences.get("target_platform"); String selBoard = Preferences.get("board"); - - menu.removeAll(); + String selBoardContainer = Preferences.get("board_container"); + + boardsMenu.removeAll(); boolean first = true; - ButtonGroup group = new ButtonGroup(); + ButtonGroup boardsButtonGroup = new ButtonGroup(); + ButtonGroup cpuTypesButtonGroup = new ButtonGroup(); // Cycle through all packages for (TargetPackage targetPackage : packages.values()) { @@ -1128,43 +1130,162 @@ public class Base { // Add a title for each group of boards if (!first) - menu.add(new JSeparator()); - first = false; + boardsMenu.add(new JSeparator()); + first = false; JMenuItem separator = new JMenuItem(targetPlatform.getPreferences().get("name")); separator.setEnabled(false); - menu.add(separator); + boardsMenu.add(separator); // For every platform cycle through all boards - for (String board : targetPlatform.getOrderedBoards()) { + for (String boardID : targetPlatform.getOrderedBoards()) { + + PreferencesMap boardAttributes = boards.get(boardID); + final String boardContainer = boardAttributes.get("container"); + + AbstractAction filterCPUTypeMenuAction = new AbstractAction() { + + @Override + public void actionPerformed(ActionEvent e) { + Preferences.set("board_container", (String) getValue("board_container")); + + cpuTypeMenu.setEnabled(true); + + for (int i = 0; i < cpuTypeMenu.getItemCount(); i++) { + JMenuItem cpuTypeMenuItem = cpuTypeMenu.getItem(i); + boolean visible = boardContainer.equals(cpuTypeMenuItem.getAction().getValue("board_container")); + cpuTypeMenuItem.setVisible(visible); + } + + JMenuItem selectSelectedOrFirstVisibleMenuItem = selectVisibleSelectedOrFirstMenuItem(cpuTypeMenu); + selectSelectedOrFirstVisibleMenuItem.doClick(); + } + }; + filterCPUTypeMenuAction.putValue("board_container", boardContainer); - // Setup a menu item for the current board - String boardName = boards.get(board).get("name"); @SuppressWarnings("serial") - AbstractAction action = new AbstractAction(boardName) { + final AbstractAction selectBoardAction = new AbstractAction(boardAttributes.get("cpu")) { public void actionPerformed(ActionEvent actionevent) { Preferences.set("target_package", (String) getValue("package")); Preferences.set("target_platform", (String) getValue("platform")); Preferences.set("board", (String) getValue("board")); - + onBoardOrPortChange(); Sketch.buildSettingChanged(); rebuildImportMenu(Editor.importMenu); rebuildExamplesMenu(Editor.examplesMenu); } }; - action.putValue("package", packageName); - action.putValue("platform", platformName); - action.putValue("board", board); - JMenuItem item = new JRadioButtonMenuItem(action); - if (packageName.equals(selPackage) && - platformName.equals(selPlatform) && board.equals(selBoard)) { - item.setSelected(true); + selectBoardAction.putValue("package", packageName); + selectBoardAction.putValue("platform", platformName); + selectBoardAction.putValue("board", boardID); + selectBoardAction.putValue("board_container", boardContainer); + + if (boardContainer != null) { + findOrCreateBoardContainerMenu(boardsMenu, boardsButtonGroup, boardContainer, filterCPUTypeMenuAction); + + JMenuItem item = new JRadioButtonMenuItem(selectBoardAction); + cpuTypesButtonGroup.add(item); + cpuTypeMenu.add(item); + } else { + AbstractAction selectBoardWithoutContainerAction = new AbstractAction(boardAttributes.get("name")) { + + @Override + public void actionPerformed(ActionEvent e) { + cpuTypeMenu.setEnabled(false); + selectBoardAction.actionPerformed(e); + } + }; + JMenuItem item = new JRadioButtonMenuItem(selectBoardWithoutContainerAction); + boardsButtonGroup.add(item); + boardsMenu.add(item); } - group.add(item); - menu.add(item); } } } + + JMenuItem selectedBoardMenu; + if (selBoardContainer == null) { + selectedBoardMenu = selectFirstEnabledMenuItem(boardsMenu); + } else { + selectedBoardMenu = selectMenuItemByBoardContainer(boardsMenu, selBoardContainer); + } + selectedBoardMenu.doClick(); + + if (cpuTypeMenu.isEnabled()) { + JMenuItem selectedCPUTypeMenu; + if (selBoard == null) { + selectedCPUTypeMenu = selectFirstEnabledMenuItem(cpuTypeMenu); + } else { + selectedCPUTypeMenu = selectMenuItemByBoardPackagePlatform(cpuTypeMenu, selBoard, selPackage, selPlatform); + } + selectedCPUTypeMenu.doClick(); + } + } + + private static JMenuItem selectVisibleSelectedOrFirstMenuItem(JMenu menu) { + JMenuItem firstVisible = null; + for (int i = 0; i < menu.getItemCount(); i++) { + JMenuItem item = menu.getItem(i); + if (item != null && item.isVisible()) { + if (item.isSelected()) { + return item; + } + if (firstVisible == null) { + firstVisible = item; + } + } + } + + if (firstVisible != null) { + return firstVisible; + } + + throw new IllegalStateException("Menu has no enabled items"); + } + + private static JMenuItem selectFirstEnabledMenuItem(JMenu menu) { + for (int i = 0; i < menu.getItemCount(); i++) { + JMenuItem item = menu.getItem(i); + if (item != null && item.isEnabled()) { + return item; + } + } + throw new IllegalStateException("Menu has no enabled items"); + } + + private static JMenuItem selectMenuItemByBoardContainer(JMenu menu, String boardContainer) { + for (int i = 0; i < menu.getItemCount(); i++) { + JMenuItem item = menu.getItem(i); + if (item != null && item.getAction() != null && boardContainer.equals(item.getAction().getValue("board_container"))) { + return item; + } + } + return selectFirstEnabledMenuItem(menu); + } + + private static JMenuItem selectMenuItemByBoardPackagePlatform(JMenu menu, String selBoard, String selPackage, String selPlatform) { + for (int i = 0; i < menu.getItemCount(); i++) { + JMenuItem item = menu.getItem(i); + if (item != null && item.getAction() != null && selBoard.equals(item.getAction().getValue("board")) + && selPackage.equals(item.getAction().getValue("package")) && selPlatform.equals(item.getAction().getValue("platform"))) { + return item; + } + } + return selectFirstEnabledMenuItem(menu); + } + + private JMenuItem findOrCreateBoardContainerMenu(JMenu boardsMenu, ButtonGroup boardsButtonGroup, String boardContainerName, AbstractAction boardMenuAction) { + for (int i = 0; i < boardsMenu.getItemCount(); i++ ) { + JMenuItem boardContainer = boardsMenu.getItem(i); + if (boardContainer != null && boardContainerName.equals(boardContainer.getText())) { + return boardContainer; + } + } + JMenuItem item = new JRadioButtonMenuItem(boardMenuAction); + item.setText(boardContainerName); + boardsButtonGroup.add(item); + boardsMenu.add(item); + return item; } public void rebuildProgrammerMenu(JMenu menu) { diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 07c821956..7b15b8ba5 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -97,6 +97,7 @@ public class Editor extends JFrame implements RunnerListener { // actually used are determined by the preferences, which are shared) static JMenu boardsMenu; static JMenu serialMenu; + static JMenu cpuTypeMenu; static SerialMenuListener serialMenuListener; static SerialMonitor serialMonitor; @@ -179,7 +180,8 @@ public class Editor extends JFrame implements RunnerListener { fileMenu.insert(examplesMenu, 3); sketchMenu.insert(importMenu, 4); toolsMenu.insert(boardsMenu, numTools); - toolsMenu.insert(serialMenu, numTools + 1); + toolsMenu.insert(cpuTypeMenu, numTools + 1); + toolsMenu.insert(serialMenu, numTools + 2); } // added for 1.0.5 @@ -190,6 +192,7 @@ public class Editor extends JFrame implements RunnerListener { fileMenu.remove(examplesMenu); sketchMenu.remove(importMenu); toolsMenu.remove(boardsMenu); + toolsMenu.remove(cpuTypeMenu); toolsMenu.remove(serialMenu); } }); @@ -680,12 +683,14 @@ public class Editor extends JFrame implements RunnerListener { if (boardsMenu == null) { boardsMenu = new JMenu(_("Board")); - base.rebuildBoardsMenu(boardsMenu); + cpuTypeMenu = new JMenu(_("CPUType")); + base.rebuildBoardsMenu(boardsMenu, cpuTypeMenu); //Debug: rebuild imports importMenu.removeAll(); base.rebuildImportMenu(importMenu); } menu.add(boardsMenu); + menu.add(cpuTypeMenu); if (serialMenuListener == null) serialMenuListener = new SerialMenuListener(); diff --git a/hardware/arduino/avr/boards.txt b/hardware/arduino/avr/boards.txt index 26e71803c..c8e4637b5 100644 --- a/hardware/arduino/avr/boards.txt +++ b/hardware/arduino/avr/boards.txt @@ -68,6 +68,8 @@ diecimila.build.variant=standard ############################################################## nano328.name=Arduino Nano w/ ATmega328 +nano328.cpu=ATmega328 +nano328.container=Arduino Nano nano328.upload.tool=avrdude nano328.upload.protocol=arduino @@ -90,6 +92,8 @@ nano328.build.variant=eightanaloginputs ############################################################## nano.name=Arduino Nano w/ ATmega168 +nano.cpu=ATmega168 +nano.container=Arduino Nano nano.upload.tool=avrdude nano.upload.protocol=arduino @@ -112,6 +116,8 @@ nano.build.variant=eightanaloginputs ############################################################## mega2560.name=Arduino Mega 2560 or Mega ADK +mega2560.cpu=2560 or ADK +mega2560.container=Arduino Mega mega2560.upload.tool=avrdude mega2560.upload.protocol=stk500v2 @@ -134,6 +140,8 @@ mega2560.build.variant=mega ############################################################## mega.name=Arduino Mega (ATmega1280) +mega.cpu=ATmega1280 +mega.container=Arduino Mega mega.upload.tool=avrdude mega.upload.protocol=arduino @@ -183,6 +191,8 @@ leonardo.build.extra_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} ############################################################## mini328.name=Arduino Mini w/ ATmega328 +mini328.cpu=ATmega328 +mini328.container=Arduino Mini mini328.upload.tool=avrdude mini328.upload.protocol=arduino @@ -205,6 +215,8 @@ mini328.build.variant=eightanaloginputs ############################################################## mini.name=Arduino Mini w/ ATmega168 +mini.cpu=ATmega168 +mini.container=Arduino Mini mini.upload.tool=avrdude mini.upload.protocol=arduino @@ -271,6 +283,8 @@ fio.build.variant=eightanaloginputs ############################################################## bt328.name=Arduino BT w/ ATmega328 +bt328.cpu=ATmega328 +bt328.container=Arduino BT bt328.upload.tool=avrdude bt328.upload.protocol=arduino @@ -294,6 +308,8 @@ bt328.build.variant=eightanaloginputs ############################################################## bt.name=Arduino BT w/ ATmega168 +bt.cpu=ATmega168 +bt.container=Arduino BT bt.upload.tool=avrdude bt.upload.protocol=arduino @@ -317,6 +333,8 @@ bt.build.variant=eightanaloginputs ############################################################## lilypad328.name=LilyPad Arduino w/ ATmega328 +lilypad328.cpu=ATmega328 +lilypad328.container=LilyPad Arduino lilypad328.upload.tool=avrdude lilypad328.upload.protocol=arduino @@ -339,6 +357,8 @@ lilypad328.build.variant=standard ############################################################## lilypad.name=LilyPad Arduino w/ ATmega168 +lilypad.cpu=ATmega168 +lilypad.container=LilyPad Arduino lilypad.upload.tool=avrdude lilypad.upload.protocol=arduino @@ -361,6 +381,8 @@ lilypad.build.variant=standard ############################################################## pro5v328.name=Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328 +pro5v328.cpu=ATmega328 (5V, 16 MHz) +pro5v328.container=Arduino Pro or Pro Mini pro5v328.upload.tool=avrdude pro5v328.upload.protocol=arduino @@ -383,6 +405,8 @@ pro5v328.build.variant=standard ############################################################## pro5v.name=Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega168 +pro5v.cpu=ATmega168 (5V, 16 MHz) +pro5v.container=Arduino Pro or Pro Mini pro5v.upload.tool=avrdude pro5v.upload.protocol=arduino @@ -405,6 +429,8 @@ pro5v.build.variant=standard ############################################################## pro328.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328 +pro328.cpu=ATmega328 (3.3V, 8 MHz) +pro328.container=Arduino Pro or Pro Mini pro328.upload.tool=avrdude pro328.upload.protocol=arduino @@ -427,6 +453,8 @@ pro328.build.variant=standard ############################################################## pro.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168 +pro.cpu=ATmega168 (3.3V, 8 MHz) +pro.container=Arduino Pro or Pro Mini pro.upload.tool=avrdude pro.upload.protocol=arduino @@ -449,6 +477,8 @@ pro.build.variant=standard ############################################################## atmega168.name=Arduino NG or older w/ ATmega168 +atmega168.cpu=ATmega168 +atmega168.container=Arduino NG or older atmega168.upload.tool=avrdude atmega168.upload.protocol=arduino @@ -471,6 +501,8 @@ atmega168.build.variant=standard ############################################################## atmega8.name=Arduino NG or older w/ ATmega8 +atmega8.cpu=ATmega8 +atmega8.container=Arduino NG or older atmega8.upload.tool=avrdude atmega8.upload.protocol=arduino