annotate Source/GUI/MainWindow.cpp @ 20:dfff66c07936

Lots of minor changes to support building on Visual Studio. A few MSVC-specific #ifdefs to eliminate things Visual Studio doesn't like. This version now compiles on Windows (provided liblo, Juce and pthread are present) but the TouchKeys device support is not yet enabled. Also, the code now needs to be re-checked on Mac and Linux.
author Andrew McPherson <andrewm@eecs.qmul.ac.uk>
date Sun, 09 Feb 2014 18:40:51 +0000
parents 73d2ec21de9a
children cfbcd31a54e7
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@0 67 setVisible (true);
andrewm@0 68 }
andrewm@0 69
andrewm@0 70 MainWindow::~MainWindow() {
andrewm@0 71 // Delete the menu bar before exiting
andrewm@0 72 #if JUCE_MAC
andrewm@0 73 MenuBarModel::setMacMainMenu(nullptr);
andrewm@0 74 #else
andrewm@0 75 setMenuBar(nullptr);
andrewm@0 76 #endif /* JUCE_MAC */
andrewm@0 77 }
andrewm@0 78
andrewm@0 79 // Handle periodic GUI updates, keeping the GUI in sync with the underlying system
andrewm@0 80 void MainWindow::timerCallback() {
andrewm@0 81 mainComponent_.synchronize();
andrewm@0 82 }
andrewm@0 83
andrewm@0 84 // ***** Juce menu bar methods ****
andrewm@0 85 StringArray MainWindow::getMenuBarNames() {
andrewm@0 86 const char* const names[] = { "File", "Edit", "Control", "Window", nullptr };
andrewm@0 87
andrewm@0 88 return StringArray (names);
andrewm@0 89 }
andrewm@0 90
andrewm@0 91 PopupMenu MainWindow::getMenuForIndex(int menuIndex, const String& menuName) {
andrewm@0 92 PopupMenu menu;
andrewm@0 93
andrewm@0 94 if(menuIndex == 0) { // File
andrewm@0 95 menu.addCommandItem(&commandManager_, kCommandNewPreset);
andrewm@0 96 menu.addSeparator();
andrewm@0 97 menu.addCommandItem(&commandManager_, kCommandOpenPreset);
andrewm@0 98 menu.addSeparator();
andrewm@0 99 menu.addCommandItem(&commandManager_, kCommandSavePreset);
andrewm@0 100 menu.addCommandItem(&commandManager_, kCommandSavePresetAs);
andrewm@0 101 #ifndef JUCE_MAC
andrewm@0 102 menu.addSeparator();
andrewm@0 103 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::quit);
andrewm@0 104 #endif
andrewm@0 105 }
andrewm@0 106 else if(menuIndex == 1) { // Edit
andrewm@0 107 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::undo);
andrewm@0 108 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::redo);
andrewm@0 109 menu.addSeparator();
andrewm@0 110 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::cut);
andrewm@0 111 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::copy);
andrewm@0 112 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::paste);
andrewm@0 113 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::del);
andrewm@0 114 menu.addSeparator();
andrewm@0 115 menu.addCommandItem(&commandManager_, StandardApplicationCommandIDs::selectAll);
andrewm@0 116 }
andrewm@0 117 else if(menuIndex == 2) { // Control
andrewm@0 118 menu.addCommandItem(&commandManager_, kCommandRescanDevices);
andrewm@0 119 menu.addSeparator();
andrewm@0 120 menu.addCommandItem(&commandManager_, kCommandEnableExperimentalMappings);
andrewm@17 121 #ifdef ENABLE_TOUCHKEYS_SENSOR_TEST
andrewm@17 122 menu.addCommandItem(&commandManager_, kCommandTestTouchkeySensors);
andrewm@17 123 #endif
andrewm@0 124 }
andrewm@0 125 else if(menuIndex == 3) { // Window
andrewm@0 126 menu.addCommandItem(&commandManager_, kCommandShowControlWindow);
andrewm@0 127 menu.addCommandItem(&commandManager_, kCommandShowKeyboardWindow);
andrewm@0 128 }
andrewm@0 129
andrewm@0 130 return menu;
andrewm@0 131 }
andrewm@0 132
andrewm@0 133 void MainWindow::menuItemSelected(int menuItemID, int topLevelMenuIndex) {
andrewm@0 134 // TODO
andrewm@0 135 }
andrewm@0 136
andrewm@0 137 // **** Command Manager methods *****
andrewm@0 138
andrewm@0 139 ApplicationCommandTarget* MainWindow::getNextCommandTarget() {
andrewm@0 140 return findFirstTargetParentComponent();
andrewm@0 141 }
andrewm@0 142
andrewm@0 143 // this returns the set of all commands that this target can perform..
andrewm@0 144 void MainWindow::getAllCommands(Array <CommandID>& commands) {
andrewm@0 145 // this returns the set of all commands that this target can perform..
andrewm@0 146 const CommandID ids[] = {
andrewm@0 147 // File
andrewm@0 148 kCommandNewPreset, kCommandOpenPreset, kCommandSavePreset,
andrewm@0 149 kCommandSavePresetAs,
andrewm@0 150 // Edit
andrewm@0 151 StandardApplicationCommandIDs::undo,
andrewm@0 152 StandardApplicationCommandIDs::redo,
andrewm@0 153 StandardApplicationCommandIDs::cut,
andrewm@0 154 StandardApplicationCommandIDs::copy,
andrewm@0 155 StandardApplicationCommandIDs::paste,
andrewm@0 156 StandardApplicationCommandIDs::del,
andrewm@0 157 StandardApplicationCommandIDs::selectAll,
andrewm@0 158 // Control
andrewm@0 159 kCommandRescanDevices,
andrewm@0 160 kCommandEnableExperimentalMappings,
andrewm@17 161 #ifdef ENABLE_TOUCHKEYS_SENSOR_TEST
andrewm@17 162 kCommandTestTouchkeySensors,
andrewm@17 163 #endif
andrewm@0 164 // Window
andrewm@0 165 kCommandShowControlWindow,
andrewm@0 166 kCommandShowKeyboardWindow
andrewm@0 167 };
andrewm@0 168
andrewm@0 169 commands.addArray (ids, numElementsInArray(ids));
andrewm@0 170 }
andrewm@0 171
andrewm@0 172 // This method is used when something needs to find out the details about one of the commands
andrewm@0 173 // that this object can perform..
andrewm@0 174 void MainWindow::getCommandInfo(CommandID commandID, ApplicationCommandInfo& result) {
andrewm@0 175 const String presetsCategory("Presets");
andrewm@0 176 const String editsCategory("Editing");
andrewm@0 177 const String controlCategory("Control");
andrewm@0 178 const String windowCategory("Window");
andrewm@0 179
andrewm@0 180 switch (commandID) {
andrewm@0 181
andrewm@0 182 // *** File Menu ***
andrewm@0 183 case kCommandNewPreset:
andrewm@0 184 result.setInfo("New Preset", "Clears the current settings", presetsCategory, 0);
andrewm@0 185 result.setTicked(false);
andrewm@0 186 result.setActive(false);
andrewm@0 187 result.addDefaultKeypress ('N', ModifierKeys::commandModifier);
andrewm@0 188 break;
andrewm@0 189 case kCommandOpenPreset:
andrewm@0 190 result.setInfo("Open Preset...", "Opens an existing preset", presetsCategory, 0);
andrewm@0 191 result.setTicked(false);
andrewm@0 192 result.setActive(false);
andrewm@0 193 result.addDefaultKeypress ('O', ModifierKeys::commandModifier);
andrewm@0 194 break;
andrewm@0 195 case kCommandSavePreset:
andrewm@0 196 result.setInfo("Save Preset", "Saves the current preset", presetsCategory, 0);
andrewm@0 197 result.setTicked(false);
andrewm@0 198 result.setActive(false);
andrewm@0 199 result.addDefaultKeypress ('S', ModifierKeys::commandModifier);
andrewm@0 200 break;
andrewm@0 201 case kCommandSavePresetAs:
andrewm@0 202 result.setInfo("Save Preset As...", "Saves the current preset with a new name", presetsCategory, 0);
andrewm@0 203 result.setTicked (false);
andrewm@0 204 result.setActive(false);
andrewm@0 205 break;
andrewm@0 206 // Quit command is handled by JuceApplication
andrewm@0 207
andrewm@0 208 // *** Edit Menu ***
andrewm@0 209 case StandardApplicationCommandIDs::undo:
andrewm@0 210 result.setInfo("Undo", "Undo", editsCategory, 0);
andrewm@0 211 result.setTicked(false);
andrewm@0 212 result.setActive(false);
andrewm@0 213 result.addDefaultKeypress ('Z', ModifierKeys::commandModifier);
andrewm@0 214 break;
andrewm@0 215 case StandardApplicationCommandIDs::redo:
andrewm@0 216 result.setInfo("Redo", "Redo", editsCategory, 0);
andrewm@0 217 result.setTicked(false);
andrewm@0 218 result.setActive(false);
andrewm@0 219 result.addDefaultKeypress ('Z', ModifierKeys::commandModifier | ModifierKeys::shiftModifier);
andrewm@0 220 break;
andrewm@0 221 case StandardApplicationCommandIDs::cut:
andrewm@0 222 result.setInfo("Cut", "Cut", editsCategory, 0);
andrewm@0 223 result.setTicked(false);
andrewm@0 224 result.setActive(false);
andrewm@0 225 result.addDefaultKeypress ('X', ModifierKeys::commandModifier);
andrewm@0 226 break;
andrewm@0 227 case StandardApplicationCommandIDs::copy:
andrewm@0 228 result.setInfo("Copy", "Copy", editsCategory, 0);
andrewm@0 229 result.setTicked(false);
andrewm@0 230 result.setActive(false);
andrewm@0 231 result.addDefaultKeypress ('C', ModifierKeys::commandModifier);
andrewm@0 232 break;
andrewm@0 233 case StandardApplicationCommandIDs::paste:
andrewm@0 234 result.setInfo("Paste", "Paste", editsCategory, 0);
andrewm@0 235 result.setTicked(false);
andrewm@0 236 result.setActive(false);
andrewm@0 237 result.addDefaultKeypress ('V', ModifierKeys::commandModifier);
andrewm@0 238 break;
andrewm@0 239 case StandardApplicationCommandIDs::del:
andrewm@0 240 result.setInfo("Delete", "Delete", editsCategory, 0);
andrewm@0 241 result.setTicked(false);
andrewm@0 242 result.setActive(false);
andrewm@0 243 break;
andrewm@0 244 case StandardApplicationCommandIDs::selectAll:
andrewm@0 245 result.setInfo("Select All", "Select All", editsCategory, 0);
andrewm@0 246 result.setTicked(false);
andrewm@0 247 result.setActive(false);
andrewm@0 248 result.addDefaultKeypress ('A', ModifierKeys::commandModifier);
andrewm@0 249 break;
andrewm@0 250
andrewm@0 251 // *** Control Menu ***
andrewm@0 252 case kCommandRescanDevices:
andrewm@0 253 result.setInfo("Rescan Devices", "Rescans available TouchKeys and MIDI devices", controlCategory, 0);
andrewm@0 254 result.setTicked(false);
andrewm@0 255 result.setActive(false);
andrewm@0 256 result.addDefaultKeypress ('R', ModifierKeys::commandModifier);
andrewm@0 257 break;
andrewm@0 258 case kCommandEnableExperimentalMappings:
andrewm@0 259 result.setInfo("Enable Experimental Mappings", "Enables mappings which are still experimental", controlCategory, 0);
andrewm@0 260 result.setTicked(controller_.experimentalMappingsEnabled());
andrewm@0 261 break;
andrewm@17 262 #ifdef ENABLE_TOUCHKEYS_SENSOR_TEST
andrewm@17 263 case kCommandTestTouchkeySensors:
andrewm@17 264 result.setInfo("Test TouchKeys Sensors", "Enables a test of individual TouchKeys sensors", controlCategory, 0);
andrewm@17 265 result.setActive(controller_.availableTouchkeyDevices().size() > 0);
andrewm@17 266 result.setTicked(controller_.touchkeySensorTestIsRunning());
andrewm@17 267 break;
andrewm@17 268 #endif
andrewm@0 269
andrewm@0 270 // *** Window Menu ***
andrewm@0 271 case kCommandShowControlWindow:
andrewm@0 272 result.setInfo("TouchKeys Controls", "Show control and mapping window", windowCategory, 0);
andrewm@0 273 result.setTicked(false);
andrewm@12 274 result.addDefaultKeypress ('1', ModifierKeys::commandModifier);
andrewm@0 275 break;
andrewm@0 276 case kCommandShowKeyboardWindow:
andrewm@0 277 result.setInfo("Keyboard Display", "Show keyboard display", windowCategory, 0);
andrewm@0 278 result.setTicked(false);
andrewm@12 279 result.addDefaultKeypress ('2', ModifierKeys::commandModifier);
andrewm@0 280 break;
andrewm@0 281
andrewm@0 282 default:
andrewm@0 283 break;
andrewm@0 284 };
andrewm@0 285 }
andrewm@0 286
andrewm@0 287 bool MainWindow::perform(const InvocationInfo& info) {
andrewm@0 288 switch (info.commandID)
andrewm@0 289 {
andrewm@0 290 case kCommandNewPreset:
andrewm@0 291 break;
andrewm@0 292 case kCommandRescanDevices:
andrewm@0 293 std::cout << "Rescan\n";
andrewm@0 294 break;
andrewm@0 295 case kCommandEnableExperimentalMappings:
andrewm@0 296 controller_.setExperimentalMappingsEnabled(!controller_.experimentalMappingsEnabled());
andrewm@0 297 break;
andrewm@17 298 #ifdef ENABLE_TOUCHKEYS_SENSOR_TEST
andrewm@17 299 case kCommandTestTouchkeySensors:
andrewm@17 300 if(!controller_.touchkeySensorTestIsRunning())
andrewm@17 301 controller_.touchkeySensorTestStart(mainComponent_.currentTouchkeysSelectedPath().toUTF8(), controller_.touchkeyDeviceLowestMidiNote());
andrewm@17 302 else
andrewm@17 303 controller_.touchkeySensorTestStop();
andrewm@17 304 break;
andrewm@17 305 #endif
andrewm@0 306 case kCommandShowControlWindow:
andrewm@0 307 toFront(true);
andrewm@0 308 break;
andrewm@0 309 case kCommandShowKeyboardWindow:
andrewm@0 310 controller_.showKeyboardDisplayWindow();
andrewm@0 311 break;
andrewm@0 312
andrewm@0 313 default:
andrewm@0 314 return false;
andrewm@0 315 };
andrewm@0 316
andrewm@0 317 return true;
andrewm@0 318 }