annotate Source/GUI/MainWindow.cpp @ 31:88287c1c2c92

Added an auxiliary MIDI input control, and moved the logging out of the window into the menu to make space in the GUI. Also updated the main window to be rescalable vertically for showing more mappings.
author Andrew McPherson <andrewm@eecs.qmul.ac.uk>
date Thu, 20 Mar 2014 00:14:00 +0000
parents cfbcd31a54e7
children e8965409903e
rev   line source
andrewm@0 1 /*
andrewm@0 2 TouchKeys: multi-touch musical keyboard control software
andrewm@0 3 Copyright (c) 2013 Andrew McPherson
andrewm@0 4
andrewm@0 5 This program is free software: you can redistribute it and/or modify
andrewm@0 6 it under the terms of the GNU General Public License as published by
andrewm@0 7 the Free Software Foundation, either version 3 of the License, or
andrewm@0 8 (at your option) any later version.
andrewm@0 9
andrewm@0 10 This program is distributed in the hope that it will be useful,
andrewm@0 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
andrewm@0 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
andrewm@0 13 GNU General Public License for more details.
andrewm@0 14
andrewm@0 15 You should have received a copy of the GNU General Public License
andrewm@0 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
andrewm@0 17
andrewm@0 18 =====================================================================
andrewm@0 19
andrewm@0 20 MainWindow.cpp: the control window, plus menu bar and Juce application methods
andrewm@0 21 */
andrewm@0 22
andrewm@0 23 #include "../../JuceLibraryCode/JuceHeader.h"
andrewm@0 24 #include "MainWindow.h"
andrewm@0 25
andrewm@0 26 //==============================================================================
andrewm@0 27 MainWindow::MainWindow(MainApplicationController& controller)
andrewm@0 28 : DocumentWindow ("TouchKeys", Colours::lightgrey, DocumentWindow::allButtons),
andrewm@0 29 controller_(controller)
andrewm@0 30 {
andrewm@0 31 commandManager_.registerAllCommandsForTarget(this);
andrewm@0 32 commandManager_.registerAllCommandsForTarget(JUCEApplication::getInstance());
andrewm@0 33
andrewm@0 34 // This lets the command manager use keypresses that arrive in our window to send
andrewm@0 35 // out commands
andrewm@0 36 addKeyListener(commandManager_.getKeyMappings());
andrewm@0 37
andrewm@0 38 // Create the menu bar, either in the window or at the top of the screen
andrewm@0 39 #if JUCE_MAC
andrewm@0 40 MenuBarModel::setMacMainMenu(this);
andrewm@0 41 #else
andrewm@0 42 // Menu bar goes at the top of the window
andrewm@0 43 setMenuBar(this);
andrewm@0 44
andrewm@0 45 // Window height should change to accommodate it
andrewm@0 46 Component *actualMenuBar = getMenuBarComponent();
andrewm@0 47 if(actualMenuBar != 0) {
andrewm@20 48 juce::Rectangle<int> r = actualMenuBar->getBounds();
andrewm@0 49 setSize(getWidth(), getHeight() + r.getHeight());
andrewm@0 50 }
andrewm@0 51 #endif /* JUCE_MAC */
andrewm@0 52
andrewm@0 53 // Tells our menu bar model that it should watch this command manager for
andrewm@0 54 // changes, and send change messages accordingly.
andrewm@0 55 setApplicationCommandManagerToWatch(&commandManager_);
andrewm@0 56
andrewm@0 57 mainComponent_.setMainApplicationController(&controller_);
andrewm@0 58 setContentNonOwned(&mainComponent_, true);
andrewm@0 59
andrewm@0 60 commandManager_.setFirstCommandTarget(this);
andrewm@0 61
andrewm@0 62 // Start a timer that will keep the interface in sync with the application
andrewm@0 63 startTimer(50);
andrewm@0 64
andrewm@0 65 centreWithSize (getWidth(), getHeight());
andrewm@0 66 setUsingNativeTitleBar(true);
andrewm@31 67
andrewm@31 68 // Allow resizing to be larger vertically
andrewm@31 69 setResizable(true, true);
andrewm@31 70 setResizeLimits(getWidth(), getHeight(), getWidth(), 2048);
andrewm@31 71
andrewm@0 72 setVisible (true);
andrewm@0 73 }
andrewm@0 74
andrewm@0 75 MainWindow::~MainWindow() {
andrewm@0 76 // Delete the menu bar before exiting
andrewm@0 77 #if JUCE_MAC
andrewm@0 78 MenuBarModel::setMacMainMenu(nullptr);
andrewm@0 79 #else
andrewm@0 80 setMenuBar(nullptr);
andrewm@0 81 #endif /* JUCE_MAC */
andrewm@0 82 }
andrewm@0 83
andrewm@0 84 // Handle periodic GUI updates, keeping the GUI in sync with the underlying system
andrewm@0 85 void MainWindow::timerCallback() {
andrewm@0 86 mainComponent_.synchronize();
andrewm@0 87 }
andrewm@0 88
andrewm@0 89 // ***** Juce menu bar methods ****
andrewm@0 90 StringArray MainWindow::getMenuBarNames() {
andrewm@0 91 const char* const names[] = { "File", "Edit", "Control", "Window", nullptr };
andrewm@0 92
andrewm@0 93 return StringArray (names);
andrewm@0 94 }
andrewm@0 95
andrewm@0 96 PopupMenu MainWindow::getMenuForIndex(int menuIndex, const String& menuName) {
andrewm@0 97 PopupMenu menu;
andrewm@0 98
andrewm@0 99 if(menuIndex == 0) { // File
andrewm@0 100 menu.addCommandItem(&commandManager_, kCommandNewPreset);
andrewm@0 101 menu.addSeparator();
andrewm@0 102 menu.addCommandItem(&commandManager_, kCommandOpenPreset);
andrewm@0 103 menu.addSeparator();
andrewm@0 104 menu.addCommandItem(&commandManager_, kCommandSavePreset);
andrewm@0 105 menu.addCommandItem(&commandManager_, kCommandSavePresetAs);
andrewm@0 106 #ifndef JUCE_MAC
andrewm@0 107 menu.addSeparator();
andrewm@0 108 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::quit);
andrewm@0 109 #endif
andrewm@0 110 }
andrewm@0 111 else if(menuIndex == 1) { // Edit
andrewm@0 112 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::undo);
andrewm@0 113 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::redo);
andrewm@0 114 menu.addSeparator();
andrewm@0 115 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::cut);
andrewm@0 116 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::copy);
andrewm@0 117 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::paste);
andrewm@0 118 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::del);
andrewm@0 119 menu.addSeparator();
andrewm@0 120 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::selectAll);
andrewm@0 121 }
andrewm@0 122 else if(menuIndex == 2) { // Control
andrewm@0 123 menu.addCommandItem(&commandManager_, kCommandRescanDevices);
andrewm@0 124 menu.addSeparator();
andrewm@31 125 menu.addCommandItem(&commandManager_, kCommandLoggingStartStop);
andrewm@31 126 menu.addCommandItem(&commandManager_, kCommandLoggingPlay);
andrewm@31 127 menu.addSeparator();
andrewm@0 128 menu.addCommandItem(&commandManager_, kCommandEnableExperimentalMappings);
andrewm@17 129 #ifdef ENABLE_TOUCHKEYS_SENSOR_TEST
andrewm@17 130 menu.addCommandItem(&commandManager_, kCommandTestTouchkeySensors);
andrewm@17 131 #endif
andrewm@0 132 }
andrewm@0 133 else if(menuIndex == 3) { // Window
andrewm@0 134 menu.addCommandItem(&commandManager_, kCommandShowControlWindow);
andrewm@0 135 menu.addCommandItem(&commandManager_, kCommandShowKeyboardWindow);
andrewm@0 136 }
andrewm@0 137
andrewm@0 138 return menu;
andrewm@0 139 }
andrewm@0 140
andrewm@0 141 void MainWindow::menuItemSelected(int menuItemID, int topLevelMenuIndex) {
andrewm@0 142 // TODO
andrewm@0 143 }
andrewm@0 144
andrewm@0 145 // **** Command Manager methods *****
andrewm@0 146
andrewm@0 147 ApplicationCommandTarget* MainWindow::getNextCommandTarget() {
andrewm@0 148 return findFirstTargetParentComponent();
andrewm@0 149 }
andrewm@0 150
andrewm@0 151 // this returns the set of all commands that this target can perform..
andrewm@0 152 void MainWindow::getAllCommands(Array <CommandID>& commands) {
andrewm@0 153 // this returns the set of all commands that this target can perform..
andrewm@0 154 const CommandID ids[] = {
andrewm@0 155 // File
andrewm@0 156 kCommandNewPreset, kCommandOpenPreset, kCommandSavePreset,
andrewm@0 157 kCommandSavePresetAs,
andrewm@0 158 // Edit
andrewm@0 159 StandardApplicationCommandIDs::undo,
andrewm@0 160 StandardApplicationCommandIDs::redo,
andrewm@0 161 StandardApplicationCommandIDs::cut,
andrewm@0 162 StandardApplicationCommandIDs::copy,
andrewm@0 163 StandardApplicationCommandIDs::paste,
andrewm@0 164 StandardApplicationCommandIDs::del,
andrewm@0 165 StandardApplicationCommandIDs::selectAll,
andrewm@0 166 // Control
andrewm@0 167 kCommandRescanDevices,
andrewm@31 168 kCommandLoggingStartStop,
andrewm@31 169 kCommandLoggingPlay,
andrewm@0 170 kCommandEnableExperimentalMappings,
andrewm@17 171 #ifdef ENABLE_TOUCHKEYS_SENSOR_TEST
andrewm@17 172 kCommandTestTouchkeySensors,
andrewm@17 173 #endif
andrewm@0 174 // Window
andrewm@0 175 kCommandShowControlWindow,
andrewm@0 176 kCommandShowKeyboardWindow
andrewm@0 177 };
andrewm@0 178
andrewm@0 179 commands.addArray (ids, numElementsInArray(ids));
andrewm@0 180 }
andrewm@0 181
andrewm@0 182 // This method is used when something needs to find out the details about one of the commands
andrewm@0 183 // that this object can perform..
andrewm@0 184 void MainWindow::getCommandInfo(CommandID commandID, ApplicationCommandInfo& result) {
andrewm@0 185 const String presetsCategory("Presets");
andrewm@0 186 const String editsCategory("Editing");
andrewm@0 187 const String controlCategory("Control");
andrewm@0 188 const String windowCategory("Window");
andrewm@0 189
andrewm@0 190 switch (commandID) {
andrewm@0 191
andrewm@0 192 // *** File Menu ***
andrewm@0 193 case kCommandNewPreset:
andrewm@0 194 result.setInfo("New Preset", "Clears the current settings", presetsCategory, 0);
andrewm@0 195 result.setTicked(false);
andrewm@0 196 result.setActive(false);
andrewm@0 197 result.addDefaultKeypress ('N', ModifierKeys::commandModifier);
andrewm@0 198 break;
andrewm@0 199 case kCommandOpenPreset:
andrewm@0 200 result.setInfo("Open Preset...", "Opens an existing preset", presetsCategory, 0);
andrewm@0 201 result.setTicked(false);
andrewm@0 202 result.setActive(false);
andrewm@0 203 result.addDefaultKeypress ('O', ModifierKeys::commandModifier);
andrewm@0 204 break;
andrewm@0 205 case kCommandSavePreset:
andrewm@0 206 result.setInfo("Save Preset", "Saves the current preset", presetsCategory, 0);
andrewm@0 207 result.setTicked(false);
andrewm@0 208 result.setActive(false);
andrewm@0 209 result.addDefaultKeypress ('S', ModifierKeys::commandModifier);
andrewm@0 210 break;
andrewm@0 211 case kCommandSavePresetAs:
andrewm@0 212 result.setInfo("Save Preset As...", "Saves the current preset with a new name", presetsCategory, 0);
andrewm@0 213 result.setTicked (false);
andrewm@0 214 result.setActive(false);
andrewm@0 215 break;
andrewm@0 216 // Quit command is handled by JuceApplication
andrewm@0 217
andrewm@0 218 // *** Edit Menu ***
andrewm@0 219 case StandardApplicationCommandIDs::undo:
andrewm@0 220 result.setInfo("Undo", "Undo", editsCategory, 0);
andrewm@0 221 result.setTicked(false);
andrewm@0 222 result.setActive(false);
andrewm@0 223 result.addDefaultKeypress ('Z', ModifierKeys::commandModifier);
andrewm@0 224 break;
andrewm@0 225 case StandardApplicationCommandIDs::redo:
andrewm@0 226 result.setInfo("Redo", "Redo", editsCategory, 0);
andrewm@0 227 result.setTicked(false);
andrewm@0 228 result.setActive(false);
andrewm@0 229 result.addDefaultKeypress ('Z', ModifierKeys::commandModifier | ModifierKeys::shiftModifier);
andrewm@0 230 break;
andrewm@0 231 case StandardApplicationCommandIDs::cut:
andrewm@0 232 result.setInfo("Cut", "Cut", editsCategory, 0);
andrewm@0 233 result.setTicked(false);
andrewm@0 234 result.setActive(false);
andrewm@0 235 result.addDefaultKeypress ('X', ModifierKeys::commandModifier);
andrewm@0 236 break;
andrewm@0 237 case StandardApplicationCommandIDs::copy:
andrewm@0 238 result.setInfo("Copy", "Copy", editsCategory, 0);
andrewm@0 239 result.setTicked(false);
andrewm@0 240 result.setActive(false);
andrewm@0 241 result.addDefaultKeypress ('C', ModifierKeys::commandModifier);
andrewm@0 242 break;
andrewm@0 243 case StandardApplicationCommandIDs::paste:
andrewm@0 244 result.setInfo("Paste", "Paste", editsCategory, 0);
andrewm@0 245 result.setTicked(false);
andrewm@0 246 result.setActive(false);
andrewm@0 247 result.addDefaultKeypress ('V', ModifierKeys::commandModifier);
andrewm@0 248 break;
andrewm@0 249 case StandardApplicationCommandIDs::del:
andrewm@0 250 result.setInfo("Delete", "Delete", editsCategory, 0);
andrewm@0 251 result.setTicked(false);
andrewm@0 252 result.setActive(false);
andrewm@0 253 break;
andrewm@0 254 case StandardApplicationCommandIDs::selectAll:
andrewm@0 255 result.setInfo("Select All", "Select All", editsCategory, 0);
andrewm@0 256 result.setTicked(false);
andrewm@0 257 result.setActive(false);
andrewm@0 258 result.addDefaultKeypress ('A', ModifierKeys::commandModifier);
andrewm@0 259 break;
andrewm@0 260
andrewm@0 261 // *** Control Menu ***
andrewm@0 262 case kCommandRescanDevices:
andrewm@0 263 result.setInfo("Rescan Devices", "Rescans available TouchKeys and MIDI devices", controlCategory, 0);
andrewm@0 264 result.setTicked(false);
andrewm@28 265 result.setActive(true);
andrewm@0 266 result.addDefaultKeypress ('R', ModifierKeys::commandModifier);
andrewm@0 267 break;
andrewm@31 268 case kCommandLoggingStartStop:
andrewm@31 269 result.setInfo("Record Log File", "Records TouchKeys and MIDI data to file", controlCategory, 0);
andrewm@31 270 result.setTicked(controller_.isLogging());
andrewm@31 271 result.setActive(true);
andrewm@31 272 break;
andrewm@31 273 case kCommandLoggingPlay:
andrewm@31 274 result.setInfo("Play Log...", "Plays TouchKeys and MIDI from file", controlCategory, 0);
andrewm@31 275 result.setTicked(false);
andrewm@31 276 result.setActive(false);
andrewm@31 277 break;
andrewm@0 278 case kCommandEnableExperimentalMappings:
andrewm@0 279 result.setInfo("Enable Experimental Mappings", "Enables mappings which are still experimental", controlCategory, 0);
andrewm@0 280 result.setTicked(controller_.experimentalMappingsEnabled());
andrewm@0 281 break;
andrewm@17 282 #ifdef ENABLE_TOUCHKEYS_SENSOR_TEST
andrewm@17 283 case kCommandTestTouchkeySensors:
andrewm@17 284 result.setInfo("Test TouchKeys Sensors", "Enables a test of individual TouchKeys sensors", controlCategory, 0);
andrewm@17 285 result.setActive(controller_.availableTouchkeyDevices().size() > 0);
andrewm@17 286 result.setTicked(controller_.touchkeySensorTestIsRunning());
andrewm@17 287 break;
andrewm@17 288 #endif
andrewm@0 289
andrewm@0 290 // *** Window Menu ***
andrewm@0 291 case kCommandShowControlWindow:
andrewm@0 292 result.setInfo("TouchKeys Controls", "Show control and mapping window", windowCategory, 0);
andrewm@0 293 result.setTicked(false);
andrewm@12 294 result.addDefaultKeypress ('1', ModifierKeys::commandModifier);
andrewm@0 295 break;
andrewm@0 296 case kCommandShowKeyboardWindow:
andrewm@0 297 result.setInfo("Keyboard Display", "Show keyboard display", windowCategory, 0);
andrewm@0 298 result.setTicked(false);
andrewm@12 299 result.addDefaultKeypress ('2', ModifierKeys::commandModifier);
andrewm@0 300 break;
andrewm@0 301
andrewm@0 302 default:
andrewm@0 303 break;
andrewm@0 304 };
andrewm@0 305 }
andrewm@0 306
andrewm@0 307 bool MainWindow::perform(const InvocationInfo& info) {
andrewm@0 308 switch (info.commandID)
andrewm@0 309 {
andrewm@0 310 case kCommandNewPreset:
andrewm@0 311 break;
andrewm@0 312 case kCommandRescanDevices:
andrewm@28 313 controller_.tellDevicesToUpdate();
andrewm@0 314 break;
andrewm@31 315 case kCommandLoggingStartStop:
andrewm@31 316 if(controller_.isLogging())
andrewm@31 317 controller_.stopLogging();
andrewm@31 318 else
andrewm@31 319 controller_.startLogging();
andrewm@31 320 break;
andrewm@31 321 case kCommandLoggingPlay:
andrewm@31 322 // TODO
andrewm@31 323 break;
andrewm@0 324 case kCommandEnableExperimentalMappings:
andrewm@0 325 controller_.setExperimentalMappingsEnabled(!controller_.experimentalMappingsEnabled());
andrewm@0 326 break;
andrewm@17 327 #ifdef ENABLE_TOUCHKEYS_SENSOR_TEST
andrewm@17 328 case kCommandTestTouchkeySensors:
andrewm@17 329 if(!controller_.touchkeySensorTestIsRunning())
andrewm@17 330 controller_.touchkeySensorTestStart(mainComponent_.currentTouchkeysSelectedPath().toUTF8(), controller_.touchkeyDeviceLowestMidiNote());
andrewm@17 331 else
andrewm@17 332 controller_.touchkeySensorTestStop();
andrewm@17 333 break;
andrewm@17 334 #endif
andrewm@0 335 case kCommandShowControlWindow:
andrewm@0 336 toFront(true);
andrewm@0 337 break;
andrewm@0 338 case kCommandShowKeyboardWindow:
andrewm@0 339 controller_.showKeyboardDisplayWindow();
andrewm@0 340 break;
andrewm@0 341
andrewm@0 342 default:
andrewm@0 343 return false;
andrewm@0 344 };
andrewm@0 345
andrewm@0 346 return true;
andrewm@0 347 }