Subversion Repositories svn.mios32

Rev

Rev 1626 | Rev 1759 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
877 tk 1
/* -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*- */
2
// $Id: MiosStudio.cpp 1724 2013-03-28 20:23:40Z tk $
3
/*
4
 * MIDI Monitor Component
5
 *
6
 * ==========================================================================
7
 *
8
 *  Copyright (C) 2010 Thorsten Klose (tk@midibox.org)
9
 *  Licensed for personal non-commercial use only.
10
 *  All other rights reserved.
11
 *
12
 * ==========================================================================
13
 */
14
 
15
#include "MiosStudio.h"
16
 
17
//==============================================================================
18
MiosStudio::MiosStudio()
908 tk 19
    : uploadWindow(0)
20
    , midiInMonitor(0)
21
    , midiOutMonitor(0)
22
    , miosTerminal(0)
23
    , midiKeyboard(0)
917 tk 24
    , initialMidiScanCounter(1) // start step-wise MIDI port scan
877 tk 25
{
908 tk 26
    uploadHandler = new UploadHandler(this);
1502 tk 27
    sysexPatchDb = new SysexPatchDb();
908 tk 28
 
878 tk 29
    addAndMakeVisible(uploadWindow = new UploadWindow(this));
30
    addAndMakeVisible(midiInMonitor = new MidiMonitor(this, true));
31
    addAndMakeVisible(midiOutMonitor = new MidiMonitor(this, false));
32
    addAndMakeVisible(miosTerminal = new MiosTerminal(this));
33
    addAndMakeVisible(midiKeyboard = new MidiKeyboard(this));
877 tk 34
 
1189 tk 35
    // tools are created and made visible via tools button in Upload Window
36
    sysexToolWindow = 0;
37
    oscToolWindow = 0;
38
    midio128ToolWindow = 0;
39
    mbCvToolWindow = 0;
40
    mbhpMfToolWindow = 0;
1502 tk 41
    sysexLibrarianWindow = 0;
1542 tk 42
    miosFileBrowserWindow = 0;
927 tk 43
 
1626 tk 44
    addAndMakeVisible(horizontalDividerBar1 = new StretchableLayoutResizerBar(&horizontalLayout, 1, false));
45
    addAndMakeVisible(horizontalDividerBar2 = new StretchableLayoutResizerBar(&horizontalLayout, 3, false));
46
    addAndMakeVisible(horizontalDividerBar3 = new StretchableLayoutResizerBar(&horizontalLayout, 5, false));
47
    addAndMakeVisible(verticalDividerBarMonitors = new StretchableLayoutResizerBar(&verticalLayoutMonitors, 1, true));
48
    addAndMakeVisible(resizer = new ResizableCornerComponent(this, &resizeLimits));
49
    resizeLimits.setSizeLimits(200, 100, 2048, 2048);
50
 
937 tk 51
    commandManager = new ApplicationCommandManager();
52
    commandManager->registerAllCommandsForTarget(this);
53
    commandManager->registerAllCommandsForTarget(JUCEApplication::getInstance());
54
    addKeyListener(commandManager->getKeyMappings());
55
    setApplicationCommandManagerToWatch(commandManager);
56
 
1626 tk 57
    updateLayout();
877 tk 58
 
878 tk 59
    Timer::startTimer(1);
60
 
937 tk 61
    setSize(800, 650);
877 tk 62
}
63
 
64
MiosStudio::~MiosStudio()
65
{
927 tk 66
    deleteAndZero(uploadHandler);
1189 tk 67
    if( sysexToolWindow )
68
        deleteAndZero(sysexToolWindow);
69
    if( oscToolWindow )
70
        deleteAndZero(oscToolWindow);
71
    if( midio128ToolWindow )
72
        deleteAndZero(midio128ToolWindow);
73
    if( mbCvToolWindow )
74
        deleteAndZero(mbCvToolWindow);
75
    if( mbhpMfToolWindow )
76
        deleteAndZero(mbhpMfToolWindow);
1502 tk 77
    if( sysexLibrarianWindow )
78
        deleteAndZero(sysexLibrarianWindow);
1542 tk 79
    if( miosFileBrowserWindow )
80
        deleteAndZero(miosFileBrowserWindow);
923 tk 81
 
82
    // try: avoid crash under Windows by disabling all MIDI INs/OUTs
937 tk 83
    closeMidiPorts();
877 tk 84
}
85
 
86
//==============================================================================
87
void MiosStudio::paint (Graphics& g)
88
{
928 tk 89
    g.fillAll(Colour(0xffc1d0ff));
877 tk 90
}
91
 
92
void MiosStudio::resized()
93
{
1626 tk 94
    horizontalLayout.layOutComponents(layoutHComps.getRawDataPointer(), layoutHComps.size(),
877 tk 95
                                       4, 4,
96
                                       getWidth() - 8, getHeight() - 8,
97
                                       true,  // lay out above each other
98
                                       true); // resize the components' heights as well as widths
99
 
1626 tk 100
    if( layoutVComps.size() ) {
101
        verticalLayoutMonitors.layOutComponents(layoutVComps.getRawDataPointer(), layoutVComps.size(),
102
                                                4,
103
                                                4 + horizontalLayout.getItemCurrentPosition(0),
104
                                                getWidth() - 8,
105
                                                horizontalLayout.getItemCurrentAbsoluteSize(0),
106
                                                false, // lay out side-by-side
107
                                                true); // resize the components' heights as well as widths
108
    }
877 tk 109
 
927 tk 110
    resizer->setBounds(getWidth()-16, getHeight()-16, 16, 16);
877 tk 111
}
878 tk 112
 
113
 
114
//==============================================================================
115
void MiosStudio::handleIncomingMidiMessage(MidiInput* source, const MidiMessage& message)
116
{
1724 tk 117
    uint8 *data = (uint8 *)message.getRawData();
939 tk 118
    uint32 size = message.getRawDataSize();
119
 
878 tk 120
    // TK: the Juce specific "MidiBuffer" sporatically throws an assertion when overloaded
121
    // therefore I'm using a std::queue instead
122
 
891 tk 123
 
939 tk 124
    // ugly fix for reduced buffer size under windows...
125
    if( size > 2 && data[0] == 0xf0 && data[size-1] != 0xf7 ) {
126
        // first message without F7 at the end
127
        sysexReceiveBuffer.clear();
128
        for(int pos=0; pos<size; ++pos)
129
            sysexReceiveBuffer.add(data[pos]);
130
        return; // hopefully we will receive F7 with the next call
131
 
132
    } else if( sysexReceiveBuffer.size() && !(data[0] & 0x80) && data[size-1] != 0xf7 ) {
133
        // continued message without F7 at the end
134
        for(int pos=0; pos<size; ++pos)
135
            sysexReceiveBuffer.add(data[pos]);
136
        return; // hopefully we will receive F7 with the next call
137
 
138
    } else if( sysexReceiveBuffer.size() && data[size-1] == 0xf7 ) {
139
        // finally we received F7
940 tk 140
        for(int pos=0; pos<size; ++pos)
141
            sysexReceiveBuffer.add(data[pos]);
142
 
939 tk 143
        // propagate combined message
144
        uint8 *bufferedData = &sysexReceiveBuffer.getReference(0);        
145
        MidiMessage combinedMessage(bufferedData, sysexReceiveBuffer.size());
146
        sysexReceiveBuffer.clear();
147
 
148
        const ScopedLock sl(midiInQueueLock); // lock will be released at end of function
149
        midiInQueue.push(combinedMessage);
150
 
151
        // propagate to upload handler
152
        uploadHandler->handleIncomingMidiMessage(source, combinedMessage);
153
 
154
    } else {
155
        sysexReceiveBuffer.clear();
156
 
157
        const ScopedLock sl(midiInQueueLock); // lock will be released at end of function
158
        midiInQueue.push(message);
159
 
160
        // propagate to upload handler
161
        uploadHandler->handleIncomingMidiMessage(source, message);
162
    }
878 tk 163
}
164
 
165
 
166
//==============================================================================
928 tk 167
void MiosStudio::sendMidiMessage(MidiMessage &message)
891 tk 168
{
169
    MidiOutput *out = audioDeviceManager.getDefaultMidiOutput();
928 tk 170
 
171
    // if timestamp isn't set, to this now to ensure a plausible MIDI Out monitor output
172
    if( message.getTimeStamp() == 0 )
173
        message.setTimeStamp((double)Time::getMillisecondCounter() / 1000.0);
174
 
891 tk 175
    if( out )
176
        out->sendMessageNow(message);
177
 
928 tk 178
    const ScopedLock sl(midiOutQueueLock); // lock will be released at end of function
891 tk 179
    midiOutQueue.push(message);
180
}
181
 
182
 
183
//==============================================================================
937 tk 184
void MiosStudio::closeMidiPorts(void)
185
{
186
    const StringArray allMidiIns(MidiInput::getDevices());
187
    for (int i = allMidiIns.size(); --i >= 0;)
188
        audioDeviceManager.setMidiInputEnabled(allMidiIns[i], false);
189
 
190
    audioDeviceManager.setDefaultMidiOutput(String::empty);
191
}
192
 
193
 
194
//==============================================================================
878 tk 195
void MiosStudio::timerCallback()
196
{
917 tk 197
    // step-wise MIDI port scan after startup
198
    if( initialMidiScanCounter ) {
199
        switch( initialMidiScanCounter ) {
200
        case 1:
201
            midiInMonitor->scanMidiDevices();
202
            ++initialMidiScanCounter;
203
            break;
878 tk 204
 
917 tk 205
        case 2:
206
            midiOutMonitor->scanMidiDevices();
207
            ++initialMidiScanCounter;
208
            break;
878 tk 209
 
917 tk 210
        case 3:
211
            audioDeviceManager.addMidiInputCallback(String::empty, this);
212
            if( getMidiOutput() != String::empty )
213
                uploadWindow->queryCore();
878 tk 214
 
917 tk 215
            initialMidiScanCounter = 0; // stop scan
216
            break;
217
        }
218
    } else {
1050 tk 219
        // important: only broadcast 1..5 messages per timer tick to avoid GUI hangups when
917 tk 220
        // a large bulk of data is received
878 tk 221
 
1050 tk 222
        for(int checkLoop=0; checkLoop<5; ++checkLoop) {
223
            if( !midiInQueue.empty() ) {
224
                const ScopedLock sl(midiInQueueLock); // lock will be released at end of this scope
928 tk 225
 
1050 tk 226
                MidiMessage &message = midiInQueue.front();
917 tk 227
 
1724 tk 228
                uint8 *data = (uint8 *)message.getRawData();
1050 tk 229
                if( data[0] >= 0x80 && data[0] < 0xf8 )
230
                    runningStatus = data[0];
917 tk 231
 
1050 tk 232
                // propagate incoming event to MIDI components
233
                midiInMonitor->handleIncomingMidiMessage(message, runningStatus);
917 tk 234
 
1050 tk 235
                // filter runtime events for following components to improve performance
236
                if( data[0] < 0xf8 ) {
1189 tk 237
                    if( sysexToolWindow )
238
                        sysexToolWindow->handleIncomingMidiMessage(message, runningStatus);
239
                    if( midio128ToolWindow )
240
                        midio128ToolWindow->handleIncomingMidiMessage(message, runningStatus);
241
                    if( mbCvToolWindow )
242
                        mbCvToolWindow->handleIncomingMidiMessage(message, runningStatus);
243
                    if( mbhpMfToolWindow )
244
                        mbhpMfToolWindow->handleIncomingMidiMessage(message, runningStatus);
1502 tk 245
                    if( sysexLibrarianWindow )
246
                        sysexLibrarianWindow->handleIncomingMidiMessage(message, runningStatus);
1542 tk 247
                    if( miosFileBrowserWindow )
248
                        miosFileBrowserWindow->handleIncomingMidiMessage(message, runningStatus);
1050 tk 249
                    miosTerminal->handleIncomingMidiMessage(message, runningStatus);
250
                    midiKeyboard->handleIncomingMidiMessage(message, runningStatus);
251
                }
252
 
253
                midiInQueue.pop();
917 tk 254
            }
255
 
1050 tk 256
            if( !midiOutQueue.empty() ) {
257
                const ScopedLock sl(midiOutQueueLock); // lock will be released at end of this scope
878 tk 258
 
1050 tk 259
                MidiMessage &message = midiOutQueue.front();
928 tk 260
 
1050 tk 261
                midiOutMonitor->handleIncomingMidiMessage(message, message.getRawData()[0]);
878 tk 262
 
1050 tk 263
                midiOutQueue.pop();
264
            }
917 tk 265
        }
894 tk 266
    }
878 tk 267
}
268
 
269
 
270
//==============================================================================
271
void MiosStudio::setMidiInput(const String &port)
272
{
273
    const StringArray allMidiIns(MidiInput::getDevices());
274
    for (int i = allMidiIns.size(); --i >= 0;) {
275
        bool enabled = allMidiIns[i] == port;
276
        audioDeviceManager.setMidiInputEnabled(allMidiIns[i], enabled);
277
    }
278
 
279
    // propagate port change
928 tk 280
    if( uploadWindow && initialMidiScanCounter == 0 && port != String::empty )
908 tk 281
        uploadWindow->midiPortChanged();
282
 
1595 tk 283
    // store setting if MIDI input selected
284
    if( port != String::empty ) {
1724 tk 285
        PropertiesFile *propertiesFile = MiosStudioProperties::getInstance()->getCommonSettings(true);
1595 tk 286
        if( propertiesFile )
287
            propertiesFile->setValue(T("midiIn"), port);
288
    }
878 tk 289
}
290
 
908 tk 291
String MiosStudio::getMidiInput(void)
292
{
917 tk 293
    // restore setting
1724 tk 294
    PropertiesFile *propertiesFile = MiosStudioProperties::getInstance()->getCommonSettings(true);
917 tk 295
    return propertiesFile ? propertiesFile->getValue(T("midiIn"), String::empty) : String::empty;
908 tk 296
}
297
 
878 tk 298
void MiosStudio::setMidiOutput(const String &port)
299
{
300
    audioDeviceManager.setDefaultMidiOutput(port);
301
 
302
    // propagate port change
928 tk 303
    if( uploadWindow && initialMidiScanCounter == 0 && port != String::empty )
908 tk 304
        uploadWindow->midiPortChanged();
305
 
1595 tk 306
    // store setting if MIDI output selected
307
    if( port != String::empty ) {
1724 tk 308
        PropertiesFile *propertiesFile = MiosStudioProperties::getInstance()->getCommonSettings(true);
1595 tk 309
        if( propertiesFile )
310
            propertiesFile->setValue(T("midiOut"), port);
311
    }
878 tk 312
}
313
 
908 tk 314
String MiosStudio::getMidiOutput(void)
315
{
917 tk 316
    // restore setting
1724 tk 317
    PropertiesFile *propertiesFile = MiosStudioProperties::getInstance()->getCommonSettings(true);
917 tk 318
    return propertiesFile ? propertiesFile->getValue(T("midiOut"), String::empty) : String::empty;
908 tk 319
}
937 tk 320
 
321
 
322
 
323
 
324
//==============================================================================
1724 tk 325
StringArray MiosStudio::getMenuBarNames()
937 tk 326
{
1724 tk 327
    const char* const names[] = { "Application", "Tools", "Help", 0 };
937 tk 328
 
1724 tk 329
    return StringArray ((const char**) names);
937 tk 330
}
331
 
1724 tk 332
PopupMenu MiosStudio::getMenuForIndex(int topLevelMenuIndex, const String& menuName)
937 tk 333
{
334
    PopupMenu menu;
335
 
336
    if( topLevelMenuIndex == 0 ) {
337
        // "Application" menu
1626 tk 338
        menu.addCommandItem(commandManager, enableMonitors);
339
        menu.addCommandItem(commandManager, enableUpload);
340
        menu.addCommandItem(commandManager, enableTerminal);
341
        menu.addCommandItem(commandManager, enableKeyboard);
342
        menu.addSeparator();
937 tk 343
        menu.addCommandItem(commandManager, rescanDevices);
344
        menu.addSeparator();
345
        menu.addCommandItem(commandManager, StandardApplicationCommandIDs::quit);
346
    } else if( topLevelMenuIndex == 1 ) {
347
        // "Tools" menu
348
        menu.addCommandItem(commandManager, showSysexTool);
1502 tk 349
        menu.addCommandItem(commandManager, showSysexLibrarian);
1003 tk 350
        menu.addCommandItem(commandManager, showOscTool);
937 tk 351
        menu.addCommandItem(commandManager, showMidio128Tool);
352
        menu.addCommandItem(commandManager, showMbCvTool);
1131 tk 353
        menu.addCommandItem(commandManager, showMbhpMfTool);
1542 tk 354
        menu.addCommandItem(commandManager, showMiosFileBrowser);
937 tk 355
    } else if( topLevelMenuIndex == 2 ) {
356
        // "Help" menu
357
        menu.addCommandItem(commandManager, showMiosStudioPage);
358
        menu.addCommandItem(commandManager, showTroubleshootingPage);
359
    }
360
 
361
    return menu;
362
}
363
 
364
void MiosStudio::menuItemSelected(int menuItemID, int topLevelMenuIndex)
365
{
366
}
367
 
368
 
369
//==============================================================================
370
// The following methods implement the ApplicationCommandTarget interface, allowing
371
// this window to publish a set of actions it can perform, and which can be mapped
372
// onto menus, keypresses, etc.
373
 
374
ApplicationCommandTarget* MiosStudio::getNextCommandTarget()
375
{
376
    // this will return the next parent component that is an ApplicationCommandTarget (in this
377
    // case, there probably isn't one, but it's best to use this method in your own apps).
378
    return findFirstTargetParentComponent();
379
}
380
 
381
void MiosStudio::getAllCommands(Array <CommandID>& commands)
382
{
383
    // this returns the set of all commands that this target can perform..
384
    const CommandID ids[] = { showSysexTool,
1003 tk 385
                              showOscTool,
937 tk 386
                              showMidio128Tool,
387
                              showMbCvTool,
1131 tk 388
                              showMbhpMfTool,
1502 tk 389
                              showSysexLibrarian,
1542 tk 390
                              showMiosFileBrowser,
1626 tk 391
                              enableMonitors,
392
                              enableUpload,
393
                              enableTerminal,
394
                              enableKeyboard,
937 tk 395
                              rescanDevices,
396
                              showMiosStudioPage,
397
                              showTroubleshootingPage
398
    };
399
 
400
    commands.addArray (ids, numElementsInArray (ids));
401
}
402
 
403
// This method is used when something needs to find out the details about one of the commands
404
// that this object can perform..
405
void MiosStudio::getCommandInfo(const CommandID commandID, ApplicationCommandInfo& result)
406
{
407
    const String applicationCategory (T("Application"));
408
    const String toolsCategory(T("Tools"));
409
    const String helpCategory (T("Help"));
410
 
411
    switch( commandID ) {
1626 tk 412
    case enableMonitors:
413
        result.setInfo(T("Show MIDI Monitors"), T("Enables/disables the MIDI IN/OUT Monitors"), applicationCategory, 0);
414
        result.setTicked(verticalDividerBarMonitors->isVisible());
1724 tk 415
        result.addDefaultKeypress('M', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
1626 tk 416
        break;
417
 
418
    case enableUpload:
419
        result.setInfo(T("Show Upload Window"), T("Enables/disables the Upload Window"), applicationCategory, 0);
420
        result.setTicked(uploadWindow->isVisible());
1724 tk 421
        result.addDefaultKeypress('U', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
1626 tk 422
        break;
423
 
424
    case enableTerminal:
425
        result.setInfo(T("Show MIOS Terminal"), T("Enables/disables the MIOS Terminal"), applicationCategory, 0);
426
        result.setTicked(miosTerminal->isVisible());
1724 tk 427
        result.addDefaultKeypress('T', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
1626 tk 428
        break;
429
 
430
    case enableKeyboard:
431
        result.setInfo(T("Show Virtual Keyboard"), T("Enables/disables the virtual Keyboard"), applicationCategory, 0);
432
        result.setTicked(midiKeyboard->isVisible());
1724 tk 433
        result.addDefaultKeypress('K', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
1626 tk 434
        break;
435
 
937 tk 436
    case rescanDevices:
437
        result.setInfo(T("Rescan MIDI Devices"), T("Updates the MIDI In/Out port lists"), applicationCategory, 0);
1724 tk 438
        result.addDefaultKeypress('R', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
937 tk 439
        break;
440
 
441
    case showSysexTool:
442
        result.setInfo(T("SysEx Tool"), T("Allows to send and receive SysEx dumps"), toolsCategory, 0);
1189 tk 443
        result.setTicked(sysexToolWindow && sysexToolWindow->isVisible());
1724 tk 444
        result.addDefaultKeypress('1', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
937 tk 445
        break;
446
 
1542 tk 447
    case showSysexLibrarian:
448
        result.setInfo(T("SysEx Librarian"), T("Allows to manage SysEx files"), toolsCategory, 0);
449
        result.setTicked(sysexLibrarianWindow && sysexLibrarianWindow->isVisible());
1724 tk 450
        result.addDefaultKeypress('2', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
1542 tk 451
        break;
452
 
1003 tk 453
    case showOscTool:
454
        result.setInfo(T("OSC Tool"), T("Allows to send and receive OSC messages"), toolsCategory, 0);
1189 tk 455
        result.setTicked(oscToolWindow && oscToolWindow->isVisible());
1724 tk 456
        result.addDefaultKeypress('3', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
1003 tk 457
        break;
458
 
937 tk 459
    case showMidio128Tool:
1463 tk 460
        result.setInfo(T("MIDIO128 V2 Tool"), T("Allows to configure a MIDIO128 V2"), toolsCategory, 0);
1189 tk 461
        result.setTicked(midio128ToolWindow && midio128ToolWindow->isVisible());
1724 tk 462
        result.addDefaultKeypress('4', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
937 tk 463
        break;
464
 
465
    case showMbCvTool:
1463 tk 466
        result.setInfo(T("MIDIbox CV V1 Tool"), T("Allows to configure a MIDIbox CV V1"), toolsCategory, 0);
1189 tk 467
        result.setTicked(mbCvToolWindow && mbCvToolWindow->isVisible());
1724 tk 468
        result.addDefaultKeypress('5', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
937 tk 469
        break;
470
 
1131 tk 471
    case showMbhpMfTool:
1463 tk 472
        result.setInfo(T("MBHP_MF_NG Tool"), T("Allows to configure the MBHP_MF_NG firmware"), toolsCategory, 0);
1189 tk 473
        result.setTicked(mbhpMfToolWindow && mbhpMfToolWindow->isVisible());
1724 tk 474
        result.addDefaultKeypress('6', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
1131 tk 475
        break;
476
 
1542 tk 477
    case showMiosFileBrowser:
478
        result.setInfo(T("MIOS32 File Browser"), T("Allows to send and receive files to/from MIOS32 applications"), toolsCategory, 0);
479
        result.setTicked(miosFileBrowserWindow && miosFileBrowserWindow->isVisible());
1724 tk 480
        result.addDefaultKeypress('7', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
1502 tk 481
        break;
482
 
937 tk 483
    case showMiosStudioPage:
484
        result.setInfo(T("MIOS Studio Page (Web)"), T("Opens the MIOS Studio page on uCApps.de"), helpCategory, 0);
1724 tk 485
        result.addDefaultKeypress ('H', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
937 tk 486
        break;
487
 
488
    case showTroubleshootingPage:
489
        result.setInfo(T("MIDI Troubleshooting Page (Web)"), T("Opens the MIDI Troubleshooting page on uCApps.de"), helpCategory, 0);
1724 tk 490
        result.addDefaultKeypress ('I', ModifierKeys::commandModifier|ModifierKeys::shiftModifier);
937 tk 491
        break;
492
    }
493
}
494
 
495
// this is the ApplicationCommandTarget method that is used to actually perform one of our commands..
496
bool MiosStudio::perform(const InvocationInfo& info)
497
{
498
    switch( info.commandID ) {
1626 tk 499
    case enableMonitors:
500
        if( verticalDividerBarMonitors->isVisible() ) {
501
            midiInMonitor->setVisible(false);
502
            verticalDividerBarMonitors->setVisible(false);
503
            midiOutMonitor->setVisible(false);
504
        } else {
505
            midiInMonitor->setVisible(true);
506
            verticalDividerBarMonitors->setVisible(true);
507
            midiOutMonitor->setVisible(true);
508
        }
509
        updateLayout();
510
        break;
511
 
512
    case enableUpload:        
513
        if( horizontalDividerBar1->isVisible() ) {
514
            horizontalDividerBar1->setVisible(false);
515
            uploadWindow->setVisible(false);
516
        } else {
517
            horizontalDividerBar1->setVisible(true);
518
            uploadWindow->setVisible(true);
519
        }
520
        updateLayout();
521
        break;
522
 
523
    case enableTerminal:
524
        if( horizontalDividerBar2->isVisible() ) {
525
            horizontalDividerBar2->setVisible(false);
526
            miosTerminal->setVisible(false);
527
        } else {
528
            horizontalDividerBar2->setVisible(true);
529
            miosTerminal->setVisible(true);
530
        }
531
        updateLayout();
532
        break;
533
 
534
    case enableKeyboard:
535
        if( horizontalDividerBar3->isVisible() ) {
536
            horizontalDividerBar3->setVisible(false);
537
            midiKeyboard->setVisible(false);
538
        } else {
539
            horizontalDividerBar3->setVisible(true);
540
            midiKeyboard->setVisible(true);
541
        }
542
        updateLayout();
543
        break;
544
 
937 tk 545
    case rescanDevices:
1555 tk 546
        // TK: doesn't always work, therefore some warnings ;-)
547
        if( AlertWindow::showOkCancelBox(AlertWindow::WarningIcon,
548
                                         T("Rescan MIDI Devices"),
549
                                         T("Please note that the rescan function\nmostly doesn't work properly!\nIt's better to restart MIOS Studio!\n"),
550
                                         T("I've no idea what this means"),
551
                                         T("Understood")) ) {
552
            if( AlertWindow::showOkCancelBox(AlertWindow::WarningIcon,
553
                                             T("Rescan MIDI Devices"),
554
                                             T("This means that it's better to quit MIOS Studio now, and open it again!\n"),
555
                                             T("I've still no idea what this means"),
556
                                             T("Understood")) ) {
557
                AlertWindow::showOkCancelBox(AlertWindow::WarningIcon,
558
                                             T("Rescan MIDI Devices"),
559
                                             T("Switched to Newbie Mode:\n"),
560
                                             T("Quit"),
561
                                             T("Quit"));
562
                // ;-)
563
                JUCEApplication::quit();
564
            }
565
        }
566
 
937 tk 567
        closeMidiPorts();
568
        initialMidiScanCounter = 1;
569
        break;
570
 
571
    case showSysexTool:
1189 tk 572
        if( !sysexToolWindow )
573
            sysexToolWindow = new SysexToolWindow(this);
937 tk 574
        sysexToolWindow->setVisible(true);
575
        sysexToolWindow->toFront(true);
576
        break;
577
 
1003 tk 578
    case showOscTool:
1189 tk 579
        if( !oscToolWindow )
580
            oscToolWindow = new OscToolWindow(this);
1003 tk 581
        oscToolWindow->setVisible(true);
582
        oscToolWindow->toFront(true);
583
        break;
584
 
937 tk 585
    case showMidio128Tool:
1189 tk 586
        if( !midio128ToolWindow )
587
            midio128ToolWindow = new Midio128ToolWindow(this);
937 tk 588
        midio128ToolWindow->setVisible(true);
589
        midio128ToolWindow->toFront(true);
590
        break;
591
 
592
    case showMbCvTool:
1189 tk 593
        if( !mbCvToolWindow )
594
            mbCvToolWindow = new MbCvToolWindow(this);
937 tk 595
        mbCvToolWindow->setVisible(true);
596
        mbCvToolWindow->toFront(true);
597
        break;
598
 
1131 tk 599
    case showMbhpMfTool:
1189 tk 600
        if( !mbhpMfToolWindow )
601
            mbhpMfToolWindow = new MbhpMfToolWindow(this);
1131 tk 602
        mbhpMfToolWindow->setVisible(true);
603
        mbhpMfToolWindow->toFront(true);
604
        break;
605
 
1502 tk 606
    case showSysexLibrarian:
607
        if( !sysexLibrarianWindow )
608
            sysexLibrarianWindow = new SysexLibrarianWindow(this);
609
        sysexLibrarianWindow->setVisible(true);
610
        sysexLibrarianWindow->toFront(true);
611
        break;
612
 
1542 tk 613
    case showMiosFileBrowser:
614
        if( !miosFileBrowserWindow )
615
            miosFileBrowserWindow = new MiosFileBrowserWindow(this);
616
        miosFileBrowserWindow->setVisible(true);
617
        miosFileBrowserWindow->toFront(true);
618
        break;
619
 
937 tk 620
    case showMiosStudioPage: {
621
        URL webpage(T("http://www.uCApps.de/mios_studio.html"));
622
        webpage.launchInDefaultBrowser();
623
    }  break;
624
 
625
    case showTroubleshootingPage: {
626
        URL webpage(T("http://www.uCApps.de/howto_debug_midi.html"));
627
        webpage.launchInDefaultBrowser();
628
    } break;
629
    default:
630
        return false;
631
    }
632
 
633
    return true;
634
};
1626 tk 635
 
636
 
637
void MiosStudio::updateLayout(void)
638
{
639
    ////////////////////////////////////////////////////////////////////////////////////////////////
640
    layoutHComps.clear();
641
    horizontalLayout.clearAllItems();
642
 
643
    int itemIx = 0;
644
    if( verticalDividerBarMonitors->isVisible() ) {
645
        horizontalLayout.setItemLayout(itemIx++,    50,   -1, -1); // MIDI In/Out Monitors
646
        layoutHComps.add(0);
647
    }
648
 
649
    if( uploadWindow->isVisible() ) {
650
        if( itemIx ) {
651
            horizontalLayout.setItemLayout(itemIx++,    8,      8,     8); // Resizer
652
            layoutHComps.add(horizontalDividerBar1);
653
        }
654
 
655
        horizontalLayout.setItemLayout(itemIx++,   186,    186,  186); // Upload Window
656
        layoutHComps.add(uploadWindow);
657
    }
658
 
659
    if( miosTerminal->isVisible() ) {
660
        if( itemIx ) {
661
            horizontalLayout.setItemLayout(itemIx++,    8,      8,     8); // Resizer
662
            layoutHComps.add(horizontalDividerBar2);
663
        }
664
 
665
        horizontalLayout.setItemLayout(itemIx++,   50,   -1, -1); // MIOS Terminal
666
        layoutHComps.add(miosTerminal);
667
 
668
    }
669
 
670
    if( midiKeyboard->isVisible() ) {
671
        if( itemIx ) {
672
            horizontalLayout.setItemLayout(itemIx++,    8,      8,     8); // Resizer
673
            layoutHComps.add(horizontalDividerBar3);
674
        }
675
 
676
        horizontalLayout.setItemLayout(itemIx++,   124,    124,  124); // MIDI Keyboard
677
        layoutHComps.add(midiKeyboard);
678
    }
679
 
680
    // dummy to ensure that MIDI keyboard or upload window is displayed with right size if all other components invisible
681
    horizontalLayout.setItemLayout(itemIx++,   0, 0, 0);
682
    layoutHComps.add(0);
683
 
684
    ////////////////////////////////////////////////////////////////////////////////////////////////
685
    layoutVComps.clear();
686
    verticalLayoutMonitors.clearAllItems();
687
    if( verticalDividerBarMonitors->isVisible() ) {
688
        //                                   num  min   max   prefered  
689
        verticalLayoutMonitors.setItemLayout(0, -0.2, -0.8, -0.5); // MIDI In Monitor
690
        layoutVComps.add(midiInMonitor);
691
 
692
        verticalLayoutMonitors.setItemLayout(1,    8,    8,    8); // resizer
693
        layoutVComps.add(verticalDividerBarMonitors);
694
 
695
        verticalLayoutMonitors.setItemLayout(2, -0.2, -0.8, -0.5); // MIDI Out Monitor
696
        layoutVComps.add(midiOutMonitor);
697
    }
698
 
699
 
700
    ////////////////////////////////////////////////////////////////////////////////////////////////
701
    resized();
702
}
703