annotate Source/GUI/MappingListComponent.cpp @ 56:b4a2d2ae43cf tip

merge
author Andrew McPherson <andrewm@eecs.qmul.ac.uk>
date Fri, 23 Nov 2018 15:48:14 +0000
parents 85577160a0d4
children
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 MappingListComponent.cpp: manages a ListBox to display the current
andrewm@0 21 mappigns associated with a keyboard segment.
andrewm@0 22 */
andrewm@0 23
andrewm@0 24 #ifndef TOUCHKEYS_NO_GUI
andrewm@0 25
andrewm@0 26 #include "../JuceLibraryCode/JuceHeader.h"
andrewm@0 27 #include "MappingListComponent.h"
andrewm@41 28 #include "MappingExtendedEditorWindow.h"
andrewm@0 29
andrewm@0 30 //==============================================================================
andrewm@0 31 MappingListComponent::MappingListComponent() : controller_(0), keyboardSegment_(0),
andrewm@0 32 lastMappingFactoryIdentifier_(-1) {
andrewm@0 33 // In your constructor, you should add any child components, and
andrewm@0 34 // initialise any special settings that your component needs.
andrewm@0 35 addAndMakeVisible(&listBox_);
andrewm@0 36 listBox_.setModel(this);
andrewm@0 37 listBox_.setColour(ListBox::outlineColourId, Colours::grey);
andrewm@0 38 listBox_.setOutlineThickness(1);
andrewm@0 39 listBox_.setRowHeight(72);
andrewm@0 40 }
andrewm@0 41
andrewm@41 42 MappingListComponent::~MappingListComponent() {
andrewm@41 43 clearExtendedEditorWindows();
andrewm@0 44 }
andrewm@0 45
andrewm@0 46 void MappingListComponent::resized() {
andrewm@0 47 // This method is where you should set the bounds of any child
andrewm@0 48 // components that your component contains..
andrewm@0 49 listBox_.setBoundsInset (BorderSize<int> (4));
andrewm@0 50 }
andrewm@0 51
andrewm@0 52 // Delete the given factory from the mapping list
andrewm@0 53 void MappingListComponent::deleteMapping(MappingFactory* factory) {
andrewm@0 54 if(keyboardSegment_ == 0 || factory == 0)
andrewm@0 55 return;
andrewm@0 56 keyboardSegment_->removeMappingFactory(factory);
andrewm@0 57 }
andrewm@0 58
andrewm@0 59 int MappingListComponent::getNumRows() {
andrewm@0 60 if(controller_ == 0 || keyboardSegment_ == 0)
andrewm@0 61 return 0;
andrewm@0 62 return keyboardSegment_->mappingFactories().size();
andrewm@0 63 }
andrewm@0 64
andrewm@0 65 // Given a row number and a possibly an existing component, return the component
andrewm@0 66 // that should be drawn in this row of the list. Whenever a new component is created,
andrewm@0 67 // the existing one should be deleted by this method (according to Juce docs).
andrewm@0 68 Component* MappingListComponent::refreshComponentForRow(int rowNumber, bool isRowSelected, Component *existingComponentToUpdate) {
andrewm@0 69 if(keyboardSegment_ == 0)
andrewm@0 70 return 0;
andrewm@0 71
andrewm@0 72 //std::cout << "refreshing component for row " << rowNumber << " (given " << existingComponentToUpdate << ")\n";
andrewm@0 73 if(rowNumber < 0 || rowNumber >= getNumRows()) {
andrewm@0 74 if(existingComponentToUpdate != 0)
andrewm@0 75 delete existingComponentToUpdate;
andrewm@0 76 return 0;
andrewm@0 77 }
andrewm@0 78
andrewm@0 79 // Get the current component for the row, creating it if it doesn't exist
andrewm@0 80 MappingListItem *listItem = static_cast<MappingListItem*>(existingComponentToUpdate);
andrewm@0 81 if(listItem == 0) {
andrewm@0 82 listItem = new MappingListItem(*this);
andrewm@0 83 listItem->setMappingFactory(keyboardSegment_->mappingFactories()[rowNumber]);
andrewm@0 84 //std::cout << "item " << listItem << " was updated to factory " << keyboardSegment_->mappingFactories()[rowNumber] << std::endl;
andrewm@0 85 }
andrewm@0 86 else {
andrewm@0 87 // Component exists; does it still point to a factory?
andrewm@0 88 if(rowNumber >= keyboardSegment_->mappingFactories().size()) {
andrewm@0 89 //std::cout << "Deleting component " << listItem << std::endl;
andrewm@0 90 delete listItem;
andrewm@0 91 return 0;
andrewm@0 92 }
andrewm@0 93 else if(keyboardSegment_->mappingFactories()[rowNumber] != listItem->mappingFactory()) {
andrewm@0 94 //std::cout << "Changing item " << listItem << " to point to factory " << keyboardSegment_->mappingFactories()[rowNumber] << std::endl;
andrewm@0 95 listItem->setMappingFactory(keyboardSegment_->mappingFactories()[rowNumber]);
andrewm@0 96 }
andrewm@0 97 }
andrewm@0 98
andrewm@0 99 return listItem;
andrewm@0 100 }
andrewm@0 101
andrewm@0 102 // Return whether a given component is selected or not (called by MappingListItem)
andrewm@0 103 bool MappingListComponent::isComponentSelected(Component *component) {
andrewm@0 104 int rowNumber = listBox_.getRowNumberOfComponent(component);
andrewm@0 105 if(rowNumber < 0)
andrewm@0 106 return false;
andrewm@0 107 return listBox_.isRowSelected(rowNumber);
andrewm@0 108 }
andrewm@0 109
andrewm@0 110
andrewm@41 111 void MappingListComponent::synchronize() {
andrewm@0 112 if(keyboardSegment_ != 0) {
andrewm@0 113 if(lastMappingFactoryIdentifier_ != keyboardSegment_->mappingFactoryUniqueIdentifier()) {
andrewm@0 114 lastMappingFactoryIdentifier_ = keyboardSegment_->mappingFactoryUniqueIdentifier();
andrewm@0 115 listBox_.updateContent();
andrewm@41 116 updateExtendedEditorWindows();
andrewm@0 117 }
andrewm@0 118 }
andrewm@0 119
andrewm@0 120 for(int i = 0; i < getNumRows(); i++) {
andrewm@0 121 MappingListItem *listItem = static_cast<MappingListItem*>(listBox_.getComponentForRowNumber(i));
andrewm@0 122 if(listItem != 0)
andrewm@0 123 listItem->synchronize();
andrewm@0 124 }
andrewm@41 125
andrewm@41 126 synchronizeExtendedEditorWindows();
andrewm@41 127 }
andrewm@41 128
andrewm@41 129 // Open an extended editor window for the given component
andrewm@41 130 // Store the new window in the list; it is deleted when it is closed
andrewm@41 131 void MappingListComponent::openExtendedEditorWindow(MappingFactory *factory) {
andrewm@41 132 if(factory == 0)
andrewm@41 133 return;
andrewm@41 134
andrewm@41 135 ScopedLock sl(extendedEditorWindowsMutex_);
andrewm@41 136
andrewm@41 137 MappingExtendedEditorWindow *window = new MappingExtendedEditorWindow(*this,
andrewm@41 138 *keyboardSegment_, *factory);
andrewm@41 139 extendedEditorWindows_.push_back(window);
andrewm@41 140 }
andrewm@41 141
andrewm@41 142 // Close an extended editor window and remove it from the list
andrewm@41 143 void MappingListComponent::closeExtendedEditorWindow(MappingExtendedEditorWindow *window) {
andrewm@41 144 ScopedLock sl(extendedEditorWindowsMutex_);
andrewm@41 145
andrewm@41 146 closeExtendedEditorWindowHelper(window);
andrewm@41 147 }
andrewm@41 148
andrewm@41 149 MappingExtendedEditorWindow* MappingListComponent::extendedEditorWindowForFactory(MappingFactory *factory) {
andrewm@41 150 ScopedLock sl(extendedEditorWindowsMutex_);
andrewm@41 151
andrewm@41 152 list<MappingExtendedEditorWindow*>::iterator it;
andrewm@41 153 for(it = extendedEditorWindows_.begin(); it != extendedEditorWindows_.end(); ++it) {
andrewm@41 154 if((*it)->factory() == factory)
andrewm@41 155 return *it;
andrewm@41 156 }
andrewm@41 157
andrewm@41 158 return 0;
andrewm@41 159 }
andrewm@41 160
andrewm@41 161 // Update extended editor windows
andrewm@41 162 void MappingListComponent::synchronizeExtendedEditorWindows() {
andrewm@41 163 // Update extended editor windows
andrewm@41 164 ScopedLock sl(extendedEditorWindowsMutex_);
andrewm@41 165
andrewm@41 166 list<MappingExtendedEditorWindow*>::iterator it;
andrewm@41 167 for(it = extendedEditorWindows_.begin(); it != extendedEditorWindows_.end(); ++it) {
andrewm@41 168 (*it)->synchronize();
andrewm@41 169 }
andrewm@41 170 }
andrewm@41 171
andrewm@41 172 // Close an extended editor window and remove it from the list (interval version without lock)
andrewm@41 173 void MappingListComponent::closeExtendedEditorWindowHelper(MappingExtendedEditorWindow *window) {
andrewm@41 174 window->setVisible(false);
andrewm@41 175
andrewm@41 176 list<MappingExtendedEditorWindow*>::iterator it;
andrewm@41 177 bool found = true;
andrewm@41 178
andrewm@41 179 // Remove this window from the list (handling multiple entries just in case)
andrewm@41 180 while(found) {
andrewm@41 181 found = false;
andrewm@41 182 for(it = extendedEditorWindows_.begin(); it != extendedEditorWindows_.end(); ++it) {
andrewm@41 183 if(*it == window) {
andrewm@41 184 extendedEditorWindows_.erase(it);
andrewm@41 185 found = true;
andrewm@41 186 break;
andrewm@41 187 }
andrewm@41 188 }
andrewm@41 189 }
andrewm@41 190
andrewm@41 191 // Delete the window which in turn deletes the editor component
andrewm@41 192 delete window;
andrewm@41 193 }
andrewm@41 194
andrewm@41 195 // Find the invalid extended editor windows and close them
andrewm@41 196 void MappingListComponent::updateExtendedEditorWindows() {
andrewm@41 197 ScopedLock sl(extendedEditorWindowsMutex_);
andrewm@41 198
andrewm@41 199 list<MappingExtendedEditorWindow*>::iterator it;
andrewm@41 200 bool found = true;
andrewm@41 201
andrewm@41 202 // Remove the window from the list if it is invalid
andrewm@41 203 while(found) {
andrewm@41 204 found = false;
andrewm@41 205 for(it = extendedEditorWindows_.begin(); it != extendedEditorWindows_.end(); ++it) {
andrewm@41 206 if(!(*it)->isValid()) {
andrewm@41 207 closeExtendedEditorWindowHelper(*it);
andrewm@41 208 found = true;
andrewm@41 209 break;
andrewm@41 210 }
andrewm@41 211 }
andrewm@41 212 }
andrewm@41 213 }
andrewm@41 214
andrewm@41 215 // Remove all extend editor windows
andrewm@41 216 void MappingListComponent::clearExtendedEditorWindows() {
andrewm@41 217 ScopedLock sl(extendedEditorWindowsMutex_);
andrewm@41 218
andrewm@41 219 list<MappingExtendedEditorWindow*>::iterator it;
andrewm@41 220 for(it = extendedEditorWindows_.begin(); it != extendedEditorWindows_.end(); ++it) {
andrewm@41 221 delete *it;
andrewm@41 222 }
andrewm@41 223
andrewm@41 224 extendedEditorWindows_.clear();
andrewm@0 225 }
andrewm@0 226
andrewm@0 227 #endif // TOUCHKEYS_NO_GUI