mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-04 03:40:07 +00:00
This commit is contained in:
parent
52e8c35a72
commit
d47cf9e8d6
30 changed files with 6194 additions and 5916 deletions
|
|
@ -30,7 +30,6 @@
|
|||
*/
|
||||
|
||||
#include "../../../juce_Config.h"
|
||||
#if JUCE_BUILD_GUI_CLASSES
|
||||
|
||||
#if JUCE_ALSA
|
||||
|
||||
|
|
@ -1040,5 +1039,3 @@ AudioIODeviceType* juce_createDefaultAudioIODeviceType() { return 0; }
|
|||
END_JUCE_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@
|
|||
*/
|
||||
|
||||
#include "../../../juce_Config.h"
|
||||
#if JUCE_BUILD_GUI_CLASSES
|
||||
|
||||
#include "linuxincludes.h"
|
||||
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
|
||||
|
||||
|
|
@ -56,5 +54,3 @@ void FileChooser::showPlatformDialog (OwnedArray<File>& results,
|
|||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@
|
|||
*/
|
||||
|
||||
#include "../../../juce_Config.h"
|
||||
#if JUCE_BUILD_GUI_CLASSES
|
||||
|
||||
#include "linuxincludes.h"
|
||||
|
||||
/* Got a build error here? You'll need to install the freetype library...
|
||||
|
|
@ -640,5 +638,3 @@ void Font::getDefaultFontNames (String& defaultSans, String& defaultSerif, Strin
|
|||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
*/
|
||||
|
||||
#include "../../../juce_Config.h"
|
||||
#if JUCE_BUILD_GUI_CLASSES
|
||||
|
||||
#include "linuxincludes.h"
|
||||
#include <stdio.h>
|
||||
|
|
@ -419,5 +418,3 @@ bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages)
|
|||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
*/
|
||||
|
||||
#include "../../../juce_Config.h"
|
||||
#if JUCE_BUILD_GUI_CLASSES
|
||||
|
||||
#if JUCE_ALSA
|
||||
|
||||
|
|
@ -486,5 +485,3 @@ MidiInput* MidiInput::createNewDevice (const String&, MidiInputCallback*) { re
|
|||
END_JUCE_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -255,7 +255,8 @@ void Process::lowerPrivilege()
|
|||
}
|
||||
}
|
||||
|
||||
#if JUCE_BUILD_GUI_CLASSES
|
||||
#if ! JUCE_ONLY_BUILD_CORE_LIBRARY
|
||||
|
||||
void* PlatformUtilities::loadDynamicLibrary (const String& name)
|
||||
{
|
||||
return dlopen ((const char*) name.toUTF8(), RTLD_LOCAL | RTLD_NOW);
|
||||
|
|
@ -270,7 +271,7 @@ void* PlatformUtilities::getProcedureEntryPoint (void* libraryHandle, const Stri
|
|||
{
|
||||
return dlsym (libraryHandle, (const char*) procedureName);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -30,9 +30,6 @@
|
|||
*/
|
||||
|
||||
#include "../../../juce_Config.h"
|
||||
|
||||
#if JUCE_BUILD_GUI_CLASSES
|
||||
|
||||
#include "linuxincludes.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
|
@ -3354,5 +3351,3 @@ const int KeyPress::rewindKey = (0xffeeff03) | extendedKeyModifier;
|
|||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
//==============================================================================
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
#define OpenDiskDevice MakeObjCClassName(OpenDiskDevice)
|
||||
|
||||
@interface OpenDiskDevice : NSObject
|
||||
{
|
||||
DRDevice* device;
|
||||
|
|
@ -53,6 +55,8 @@ END_JUCE_NAMESPACE
|
|||
@end
|
||||
|
||||
//==============================================================================
|
||||
#define AudioTrackProducer MakeObjCClassName(AudioTrackProducer)
|
||||
|
||||
@interface AudioTrackProducer : NSObject
|
||||
{
|
||||
JUCE_NAMESPACE::AudioSource* source;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
END_JUCE_NAMESPACE
|
||||
using namespace JUCE_NAMESPACE;
|
||||
|
||||
#define JuceFileChooserDelegate MakeObjCClassName(JuceFileChooserDelegate)
|
||||
|
||||
@interface JuceFileChooserDelegate : NSObject
|
||||
{
|
||||
StringArray* filters;
|
||||
|
|
|
|||
|
|
@ -1,414 +1,429 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
//==============================================================================
|
||||
class JuceMainMenuHandler;
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
using namespace JUCE_NAMESPACE;
|
||||
|
||||
@interface JuceMenuCallback : NSObject
|
||||
{
|
||||
JuceMainMenuHandler* owner;
|
||||
}
|
||||
|
||||
- (JuceMenuCallback*) initWithOwner: (JuceMainMenuHandler*) owner_;
|
||||
- (void) dealloc;
|
||||
- (void) menuItemInvoked: (id) menu;
|
||||
|
||||
@end
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class JuceMainMenuHandler : private MenuBarModelListener,
|
||||
private DeletedAtShutdown
|
||||
{
|
||||
public:
|
||||
static JuceMainMenuHandler* instance;
|
||||
|
||||
//==============================================================================
|
||||
JuceMainMenuHandler() throw()
|
||||
: currentModel (0)
|
||||
{
|
||||
callback = [[JuceMenuCallback alloc] initWithOwner: this];
|
||||
}
|
||||
|
||||
~JuceMainMenuHandler() throw()
|
||||
{
|
||||
setMenu (0);
|
||||
|
||||
jassert (instance == this);
|
||||
instance = 0;
|
||||
|
||||
[callback release];
|
||||
}
|
||||
|
||||
void setMenu (MenuBarModel* const newMenuBarModel) throw()
|
||||
{
|
||||
if (currentModel != newMenuBarModel)
|
||||
{
|
||||
if (currentModel != 0)
|
||||
currentModel->removeListener (this);
|
||||
|
||||
currentModel = newMenuBarModel;
|
||||
|
||||
if (currentModel != 0)
|
||||
currentModel->addListener (this);
|
||||
|
||||
menuBarItemsChanged (0);
|
||||
}
|
||||
}
|
||||
|
||||
void addSubMenu (NSMenu* parent, const PopupMenu& child,
|
||||
const String& name, int& menuId, int& tag)
|
||||
{
|
||||
NSMenuItem* item = [parent addItemWithTitle: juceStringToNS (name)
|
||||
action: nil
|
||||
keyEquivalent: @""];
|
||||
[item setTag: tag];
|
||||
|
||||
NSMenu* sub = createMenu (child, name, menuId, tag);
|
||||
|
||||
[parent setSubmenu: sub forItem: item];
|
||||
[sub setAutoenablesItems: false];
|
||||
[sub release];
|
||||
}
|
||||
|
||||
void menuBarItemsChanged (MenuBarModel*)
|
||||
{
|
||||
NSMenu* menuBar = [NSApp mainMenu];
|
||||
while ([menuBar numberOfItems] > 1)
|
||||
[menuBar removeItemAtIndex: 1];
|
||||
|
||||
if (currentModel != 0)
|
||||
{
|
||||
const StringArray menuNames (currentModel->getMenuBarNames());
|
||||
int menuId = 1;
|
||||
|
||||
for (int i = 0; i < menuNames.size(); ++i)
|
||||
{
|
||||
const PopupMenu menu (currentModel->getMenuForIndex (i, menuNames [i]));
|
||||
addSubMenu (menuBar, menu, menuNames [i], menuId, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void flashMenuBar (NSMenu* menu)
|
||||
{
|
||||
const unichar f35Key = NSF35FunctionKey;
|
||||
NSString* f35String = [NSString stringWithCharacters: &f35Key length: 1];
|
||||
|
||||
NSMenuItem* item = [[NSMenuItem alloc] initWithTitle: @"x"
|
||||
action: nil
|
||||
keyEquivalent: f35String];
|
||||
[item setTarget: nil];
|
||||
[menu insertItem: item atIndex: [menu numberOfItems]];
|
||||
[item release];
|
||||
|
||||
NSEvent* f35Event = [NSEvent keyEventWithType: NSKeyDown
|
||||
location: NSZeroPoint
|
||||
modifierFlags: NSCommandKeyMask
|
||||
timestamp: 0
|
||||
windowNumber: 0
|
||||
context: [NSGraphicsContext currentContext]
|
||||
characters: f35String
|
||||
charactersIgnoringModifiers: f35String
|
||||
isARepeat: NO
|
||||
keyCode: 0];
|
||||
|
||||
[menu performKeyEquivalent: f35Event];
|
||||
[menu removeItem: item];
|
||||
}
|
||||
|
||||
void menuCommandInvoked (MenuBarModel*, const ApplicationCommandTarget::InvocationInfo& info)
|
||||
{
|
||||
NSMenuItem* item = [[NSApp mainMenu] itemWithTag: info.commandID];
|
||||
|
||||
if (item != 0)
|
||||
flashMenuBar ([item menu]);
|
||||
}
|
||||
|
||||
void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const
|
||||
{
|
||||
if (currentModel != 0)
|
||||
{
|
||||
if (commandManager != 0)
|
||||
{
|
||||
ApplicationCommandTarget::InvocationInfo info (commandId);
|
||||
info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu;
|
||||
|
||||
commandManager->invoke (info, true);
|
||||
}
|
||||
|
||||
currentModel->menuItemSelected (commandId, topLevelIndex);
|
||||
}
|
||||
}
|
||||
|
||||
MenuBarModel* currentModel;
|
||||
|
||||
private:
|
||||
JuceMenuCallback* callback;
|
||||
|
||||
NSMenu* createMenu (const PopupMenu menu,
|
||||
const String& menuName,
|
||||
int& id,
|
||||
const int topLevelIndex)
|
||||
{
|
||||
NSMenu* m = [[NSMenu alloc] initWithTitle: juceStringToNS (menuName)];
|
||||
|
||||
[m setAutoenablesItems: false];
|
||||
|
||||
PopupMenu::MenuItemIterator iter (menu);
|
||||
|
||||
while (iter.next())
|
||||
{
|
||||
NSString* text = juceStringToNS (iter.itemName.upToFirstOccurrenceOf (T("<end>"), false, true));
|
||||
|
||||
if (iter.isSeparator)
|
||||
{
|
||||
[m addItem: [NSMenuItem separatorItem]];
|
||||
}
|
||||
else if (iter.isSectionHeader)
|
||||
{
|
||||
NSMenuItem* item = [m addItemWithTitle: text
|
||||
action: nil
|
||||
keyEquivalent: @""];
|
||||
|
||||
[item setEnabled: iter.isEnabled];
|
||||
}
|
||||
else if (iter.subMenu != 0)
|
||||
{
|
||||
NSMenuItem* item = [m addItemWithTitle: text
|
||||
action: nil
|
||||
keyEquivalent: @""];
|
||||
|
||||
[item setTag: iter.itemId];
|
||||
[item setEnabled: iter.isEnabled];
|
||||
|
||||
NSMenu* sub = createMenu (*iter.subMenu, iter.itemName, id, topLevelIndex);
|
||||
[m setSubmenu: sub forItem: item];
|
||||
[sub release];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSMenuItem* item = [m addItemWithTitle: text
|
||||
action: @selector (menuItemInvoked:)
|
||||
keyEquivalent: @""];
|
||||
|
||||
[item setTag: iter.itemId];
|
||||
[item setEnabled: iter.isEnabled];
|
||||
[item setState: iter.isTicked ? NSOnState : NSOffState];
|
||||
[item setTarget: (id) callback];
|
||||
|
||||
NSMutableArray* info = [NSMutableArray arrayWithObject: [NSNumber numberWithUnsignedLongLong: (pointer_sized_int) (void*) iter.commandManager]];
|
||||
[info addObject: [NSNumber numberWithInt: topLevelIndex]];
|
||||
[item setRepresentedObject: info];
|
||||
|
||||
if (iter.commandManager != 0)
|
||||
{
|
||||
const Array <KeyPress> keyPresses (iter.commandManager->getKeyMappings()
|
||||
->getKeyPressesAssignedToCommand (iter.itemId));
|
||||
|
||||
if (keyPresses.size() > 0)
|
||||
{
|
||||
const KeyPress& kp = keyPresses.getReference(0);
|
||||
|
||||
juce_wchar key = kp.getTextCharacter();
|
||||
|
||||
if (kp.getKeyCode() == KeyPress::backspaceKey)
|
||||
key = NSBackspaceCharacter;
|
||||
else if (kp.getKeyCode() == KeyPress::deleteKey)
|
||||
key = NSDeleteCharacter;
|
||||
else if (key == 0)
|
||||
key = (juce_wchar) kp.getKeyCode();
|
||||
|
||||
unsigned int mods = 0;
|
||||
if (kp.getModifiers().isShiftDown())
|
||||
mods |= NSShiftKeyMask;
|
||||
if (kp.getModifiers().isCtrlDown())
|
||||
mods |= NSControlKeyMask;
|
||||
if (kp.getModifiers().isAltDown())
|
||||
mods |= NSAlternateKeyMask;
|
||||
if (kp.getModifiers().isCommandDown())
|
||||
mods |= NSCommandKeyMask;
|
||||
|
||||
[item setKeyEquivalent: juceStringToNS (String::charToString (key))];
|
||||
[item setKeyEquivalentModifierMask: mods];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[m update];
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
JuceMainMenuHandler* JuceMainMenuHandler::instance = 0;
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
@implementation JuceMenuCallback
|
||||
|
||||
- (JuceMenuCallback*) initWithOwner: (JuceMainMenuHandler*) owner_
|
||||
{
|
||||
[super init];
|
||||
owner = owner_;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) menuItemInvoked: (id) menu
|
||||
{
|
||||
NSMenuItem* item = (NSMenuItem*) menu;
|
||||
|
||||
if ([[item representedObject] isKindOfClass: [NSArray class]])
|
||||
{
|
||||
NSArray* info = (NSArray*) [item representedObject];
|
||||
|
||||
owner->invoke ([item tag],
|
||||
(ApplicationCommandManager*) (pointer_sized_int)
|
||||
[((NSNumber*) [info objectAtIndex: 0]) unsignedLongLongValue],
|
||||
(int) [((NSNumber*) [info objectAtIndex: 1]) intValue]);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
void MenuBarModel::setMacMainMenu (MenuBarModel* newMenuBarModel) throw()
|
||||
{
|
||||
if (getMacMainMenu() != newMenuBarModel)
|
||||
{
|
||||
if (newMenuBarModel == 0)
|
||||
{
|
||||
delete JuceMainMenuHandler::instance;
|
||||
jassert (JuceMainMenuHandler::instance == 0); // should be zeroed in the destructor
|
||||
}
|
||||
else
|
||||
{
|
||||
if (JuceMainMenuHandler::instance == 0)
|
||||
JuceMainMenuHandler::instance = new JuceMainMenuHandler();
|
||||
|
||||
JuceMainMenuHandler::instance->setMenu (newMenuBarModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MenuBarModel* MenuBarModel::getMacMainMenu() throw()
|
||||
{
|
||||
return JuceMainMenuHandler::instance != 0
|
||||
? JuceMainMenuHandler::instance->currentModel : 0;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
static NSMenu* createStandardAppMenu (const String& appName)
|
||||
{
|
||||
NSMenu* menu = [[NSMenu alloc] initWithTitle: @"Apple"];
|
||||
NSMenuItem* item;
|
||||
|
||||
// xxx should allow the 'about' and 'preferences' items to be turned on programatically...
|
||||
/* item = [menu addItemWithTitle: juceStringToNS ("About " + appName)]
|
||||
action: @selector(orderFrontStandardAboutPanel:) keyEquivalent: @""];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
*/
|
||||
|
||||
/* item = [menu addItemWithTitle: NSLocalizedString (@"Preferences...", nil)
|
||||
action: nil keyEquivalent: @","];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
*/
|
||||
|
||||
// Services...
|
||||
item = [menu addItemWithTitle: NSLocalizedString (@"Services", nil)
|
||||
action: nil keyEquivalent: @""];
|
||||
NSMenu* servicesMenu = [[NSMenu alloc] initWithTitle: @"Services"];
|
||||
[menu setSubmenu: servicesMenu forItem: item];
|
||||
[NSApp setServicesMenu: servicesMenu];
|
||||
[servicesMenu release];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
|
||||
// Hide + Show stuff...
|
||||
item = [menu addItemWithTitle: juceStringToNS ("Hide " + appName)
|
||||
action: @selector (hide:) keyEquivalent: @"h"];
|
||||
[item setTarget: NSApp];
|
||||
|
||||
item = [menu addItemWithTitle: NSLocalizedString (@"Hide Others", nil)
|
||||
action: @selector (hideOtherApplications:) keyEquivalent: @"h"];
|
||||
[item setKeyEquivalentModifierMask: NSCommandKeyMask | NSAlternateKeyMask];
|
||||
[item setTarget: NSApp];
|
||||
|
||||
item = [menu addItemWithTitle: NSLocalizedString (@"Show All", nil)
|
||||
action: @selector (unhideAllApplications:) keyEquivalent: @""];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
|
||||
// Quit item....
|
||||
item = [menu addItemWithTitle: juceStringToNS ("Quit " + appName)
|
||||
action: @selector (terminate:) keyEquivalent: @"q"];
|
||||
[item setTarget: NSApp];
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
// Since our app has no NIB, this initialises a standard app menu...
|
||||
void initialiseMainMenu()
|
||||
{
|
||||
if (JUCEApplication::getInstance() != 0) // only needed in an app
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSMenu* mainMenu = [[NSMenu alloc] initWithTitle: @"MainMenu"];
|
||||
NSMenuItem* item = [mainMenu addItemWithTitle: @"Apple" action: nil keyEquivalent: @""];
|
||||
|
||||
NSMenu* appMenu = createStandardAppMenu (JUCEApplication::getInstance()->getApplicationName());
|
||||
|
||||
[NSApp performSelector: @selector (setAppleMenu:) withObject: appMenu];
|
||||
[mainMenu setSubmenu: appMenu forItem: item];
|
||||
|
||||
[NSApp setMainMenu: mainMenu];
|
||||
[appMenu release];
|
||||
[mainMenu release];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
//==============================================================================
|
||||
class JuceMainMenuHandler;
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
using namespace JUCE_NAMESPACE;
|
||||
|
||||
#define JuceMenuCallback MakeObjCClassName(JuceMenuCallback)
|
||||
|
||||
@interface JuceMenuCallback : NSObject
|
||||
{
|
||||
JuceMainMenuHandler* owner;
|
||||
}
|
||||
|
||||
- (JuceMenuCallback*) initWithOwner: (JuceMainMenuHandler*) owner_;
|
||||
- (void) dealloc;
|
||||
- (void) menuItemInvoked: (id) menu;
|
||||
|
||||
@end
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class JuceMainMenuHandler : private MenuBarModelListener,
|
||||
private DeletedAtShutdown
|
||||
{
|
||||
public:
|
||||
static JuceMainMenuHandler* instance;
|
||||
|
||||
//==============================================================================
|
||||
JuceMainMenuHandler() throw()
|
||||
: currentModel (0)
|
||||
{
|
||||
callback = [[JuceMenuCallback alloc] initWithOwner: this];
|
||||
}
|
||||
|
||||
~JuceMainMenuHandler() throw()
|
||||
{
|
||||
setMenu (0);
|
||||
|
||||
jassert (instance == this);
|
||||
instance = 0;
|
||||
|
||||
[callback release];
|
||||
}
|
||||
|
||||
void setMenu (MenuBarModel* const newMenuBarModel) throw()
|
||||
{
|
||||
if (currentModel != newMenuBarModel)
|
||||
{
|
||||
if (currentModel != 0)
|
||||
currentModel->removeListener (this);
|
||||
|
||||
currentModel = newMenuBarModel;
|
||||
|
||||
if (currentModel != 0)
|
||||
currentModel->addListener (this);
|
||||
|
||||
menuBarItemsChanged (0);
|
||||
}
|
||||
}
|
||||
|
||||
void addSubMenu (NSMenu* parent, const PopupMenu& child,
|
||||
const String& name, int& menuId, int& tag)
|
||||
{
|
||||
NSMenuItem* item = [parent addItemWithTitle: juceStringToNS (name)
|
||||
action: nil
|
||||
keyEquivalent: @""];
|
||||
[item setTag: tag];
|
||||
|
||||
NSMenu* sub = createMenu (child, name, menuId, tag);
|
||||
|
||||
[parent setSubmenu: sub forItem: item];
|
||||
[sub setAutoenablesItems: false];
|
||||
[sub release];
|
||||
}
|
||||
|
||||
void menuBarItemsChanged (MenuBarModel*)
|
||||
{
|
||||
NSMenu* menuBar = [NSApp mainMenu];
|
||||
while ([menuBar numberOfItems] > 1)
|
||||
[menuBar removeItemAtIndex: 1];
|
||||
|
||||
if (currentModel != 0)
|
||||
{
|
||||
const StringArray menuNames (currentModel->getMenuBarNames());
|
||||
int menuId = 1;
|
||||
|
||||
for (int i = 0; i < menuNames.size(); ++i)
|
||||
{
|
||||
const PopupMenu menu (currentModel->getMenuForIndex (i, menuNames [i]));
|
||||
addSubMenu (menuBar, menu, menuNames [i], menuId, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void flashMenuBar (NSMenu* menu)
|
||||
{
|
||||
const unichar f35Key = NSF35FunctionKey;
|
||||
NSString* f35String = [NSString stringWithCharacters: &f35Key length: 1];
|
||||
|
||||
NSMenuItem* item = [[NSMenuItem alloc] initWithTitle: @"x"
|
||||
action: nil
|
||||
keyEquivalent: f35String];
|
||||
[item setTarget: nil];
|
||||
[menu insertItem: item atIndex: [menu numberOfItems]];
|
||||
[item release];
|
||||
|
||||
NSEvent* f35Event = [NSEvent keyEventWithType: NSKeyDown
|
||||
location: NSZeroPoint
|
||||
modifierFlags: NSCommandKeyMask
|
||||
timestamp: 0
|
||||
windowNumber: 0
|
||||
context: [NSGraphicsContext currentContext]
|
||||
characters: f35String
|
||||
charactersIgnoringModifiers: f35String
|
||||
isARepeat: NO
|
||||
keyCode: 0];
|
||||
|
||||
[menu performKeyEquivalent: f35Event];
|
||||
[menu removeItem: item];
|
||||
}
|
||||
|
||||
void menuCommandInvoked (MenuBarModel*, const ApplicationCommandTarget::InvocationInfo& info)
|
||||
{
|
||||
NSMenuItem* item = [[NSApp mainMenu] itemWithTag: info.commandID];
|
||||
|
||||
if (item != 0)
|
||||
flashMenuBar ([item menu]);
|
||||
}
|
||||
|
||||
void invoke (const int commandId, ApplicationCommandManager* const commandManager, const int topLevelIndex) const
|
||||
{
|
||||
if (currentModel != 0)
|
||||
{
|
||||
if (commandManager != 0)
|
||||
{
|
||||
ApplicationCommandTarget::InvocationInfo info (commandId);
|
||||
info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu;
|
||||
|
||||
commandManager->invoke (info, true);
|
||||
}
|
||||
|
||||
currentModel->menuItemSelected (commandId, topLevelIndex);
|
||||
}
|
||||
}
|
||||
|
||||
MenuBarModel* currentModel;
|
||||
|
||||
private:
|
||||
JuceMenuCallback* callback;
|
||||
|
||||
NSMenu* createMenu (const PopupMenu menu,
|
||||
const String& menuName,
|
||||
int& id,
|
||||
const int topLevelIndex)
|
||||
{
|
||||
NSMenu* m = [[NSMenu alloc] initWithTitle: juceStringToNS (menuName)];
|
||||
|
||||
[m setAutoenablesItems: false];
|
||||
|
||||
PopupMenu::MenuItemIterator iter (menu);
|
||||
|
||||
while (iter.next())
|
||||
{
|
||||
NSString* text = juceStringToNS (iter.itemName.upToFirstOccurrenceOf (T("<end>"), false, true));
|
||||
|
||||
if (iter.isSeparator)
|
||||
{
|
||||
[m addItem: [NSMenuItem separatorItem]];
|
||||
}
|
||||
else if (iter.isSectionHeader)
|
||||
{
|
||||
NSMenuItem* item = [m addItemWithTitle: text
|
||||
action: nil
|
||||
keyEquivalent: @""];
|
||||
|
||||
[item setEnabled: iter.isEnabled];
|
||||
}
|
||||
else if (iter.subMenu != 0)
|
||||
{
|
||||
NSMenuItem* item = [m addItemWithTitle: text
|
||||
action: nil
|
||||
keyEquivalent: @""];
|
||||
|
||||
[item setTag: iter.itemId];
|
||||
[item setEnabled: iter.isEnabled];
|
||||
|
||||
NSMenu* sub = createMenu (*iter.subMenu, iter.itemName, id, topLevelIndex);
|
||||
[m setSubmenu: sub forItem: item];
|
||||
[sub release];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSMenuItem* item = [m addItemWithTitle: text
|
||||
action: @selector (menuItemInvoked:)
|
||||
keyEquivalent: @""];
|
||||
|
||||
[item setTag: iter.itemId];
|
||||
[item setEnabled: iter.isEnabled];
|
||||
[item setState: iter.isTicked ? NSOnState : NSOffState];
|
||||
[item setTarget: (id) callback];
|
||||
|
||||
NSMutableArray* info = [NSMutableArray arrayWithObject: [NSNumber numberWithUnsignedLongLong: (pointer_sized_int) (void*) iter.commandManager]];
|
||||
[info addObject: [NSNumber numberWithInt: topLevelIndex]];
|
||||
[item setRepresentedObject: info];
|
||||
|
||||
if (iter.commandManager != 0)
|
||||
{
|
||||
const Array <KeyPress> keyPresses (iter.commandManager->getKeyMappings()
|
||||
->getKeyPressesAssignedToCommand (iter.itemId));
|
||||
|
||||
if (keyPresses.size() > 0)
|
||||
{
|
||||
const KeyPress& kp = keyPresses.getReference(0);
|
||||
|
||||
juce_wchar key = kp.getTextCharacter();
|
||||
|
||||
if (kp.getKeyCode() == KeyPress::backspaceKey)
|
||||
key = NSBackspaceCharacter;
|
||||
else if (kp.getKeyCode() == KeyPress::deleteKey)
|
||||
key = NSDeleteCharacter;
|
||||
else if (key == 0)
|
||||
key = (juce_wchar) kp.getKeyCode();
|
||||
|
||||
unsigned int mods = 0;
|
||||
if (kp.getModifiers().isShiftDown())
|
||||
mods |= NSShiftKeyMask;
|
||||
if (kp.getModifiers().isCtrlDown())
|
||||
mods |= NSControlKeyMask;
|
||||
if (kp.getModifiers().isAltDown())
|
||||
mods |= NSAlternateKeyMask;
|
||||
if (kp.getModifiers().isCommandDown())
|
||||
mods |= NSCommandKeyMask;
|
||||
|
||||
[item setKeyEquivalent: juceStringToNS (String::charToString (key))];
|
||||
[item setKeyEquivalentModifierMask: mods];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[m update];
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
JuceMainMenuHandler* JuceMainMenuHandler::instance = 0;
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
@implementation JuceMenuCallback
|
||||
|
||||
- (JuceMenuCallback*) initWithOwner: (JuceMainMenuHandler*) owner_
|
||||
{
|
||||
[super init];
|
||||
owner = owner_;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) menuItemInvoked: (id) menu
|
||||
{
|
||||
NSMenuItem* item = (NSMenuItem*) menu;
|
||||
|
||||
if ([[item representedObject] isKindOfClass: [NSArray class]])
|
||||
{
|
||||
NSArray* info = (NSArray*) [item representedObject];
|
||||
|
||||
owner->invoke ([item tag],
|
||||
(ApplicationCommandManager*) (pointer_sized_int)
|
||||
[((NSNumber*) [info objectAtIndex: 0]) unsignedLongLongValue],
|
||||
(int) [((NSNumber*) [info objectAtIndex: 1]) intValue]);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
void MenuBarModel::setMacMainMenu (MenuBarModel* newMenuBarModel) throw()
|
||||
{
|
||||
if (getMacMainMenu() != newMenuBarModel)
|
||||
{
|
||||
if (newMenuBarModel == 0)
|
||||
{
|
||||
delete JuceMainMenuHandler::instance;
|
||||
jassert (JuceMainMenuHandler::instance == 0); // should be zeroed in the destructor
|
||||
}
|
||||
else
|
||||
{
|
||||
if (JuceMainMenuHandler::instance == 0)
|
||||
JuceMainMenuHandler::instance = new JuceMainMenuHandler();
|
||||
|
||||
JuceMainMenuHandler::instance->setMenu (newMenuBarModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MenuBarModel* MenuBarModel::getMacMainMenu() throw()
|
||||
{
|
||||
return JuceMainMenuHandler::instance != 0
|
||||
? JuceMainMenuHandler::instance->currentModel : 0;
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
static NSMenu* createStandardAppMenu (NSMenu* menu, const String& appName)
|
||||
{
|
||||
NSMenuItem* item;
|
||||
|
||||
// xxx should allow the 'about' and 'preferences' items to be turned on programatically...
|
||||
/* item = [menu addItemWithTitle: juceStringToNS ("About " + appName)]
|
||||
action: @selector(orderFrontStandardAboutPanel:) keyEquivalent: @""];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
*/
|
||||
|
||||
/* item = [menu addItemWithTitle: NSLocalizedString (@"Preferences...", nil)
|
||||
action: nil keyEquivalent: @","];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
*/
|
||||
|
||||
// Services...
|
||||
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (@"Services", nil)
|
||||
action: nil keyEquivalent: @""];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
NSMenu* servicesMenu = [[NSMenu alloc] initWithTitle: @"Services"];
|
||||
[menu setSubmenu: servicesMenu forItem: item];
|
||||
[NSApp setServicesMenu: servicesMenu];
|
||||
[servicesMenu release];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
|
||||
// Hide + Show stuff...
|
||||
item = [[NSMenuItem alloc] initWithTitle: juceStringToNS ("Hide " + appName)
|
||||
action: @selector (hide:) keyEquivalent: @"h"];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
|
||||
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (@"Hide Others", nil)
|
||||
action: @selector (hideOtherApplications:) keyEquivalent: @"h"];
|
||||
[item setKeyEquivalentModifierMask: NSCommandKeyMask | NSAlternateKeyMask];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
|
||||
item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString (@"Show All", nil)
|
||||
action: @selector (unhideAllApplications:) keyEquivalent: @""];
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
|
||||
// Quit item....
|
||||
item = [[NSMenuItem alloc] initWithTitle: juceStringToNS ("Quit " + appName)
|
||||
action: @selector (terminate:) keyEquivalent: @"q"];
|
||||
|
||||
[item setTarget: NSApp];
|
||||
[menu addItem: item];
|
||||
[item release];
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
// Since our app has no NIB, this initialises a standard app menu...
|
||||
void initialiseMainMenu()
|
||||
{
|
||||
if (JUCEApplication::getInstance() != 0) // only needed in an app
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
NSMenu* mainMenu = [[NSMenu alloc] initWithTitle: @"MainMenu"];
|
||||
NSMenuItem* item = [mainMenu addItemWithTitle: @"Apple" action: nil keyEquivalent: @""];
|
||||
|
||||
NSMenu* appMenu = [[NSMenu alloc] initWithTitle: @"Apple"];
|
||||
|
||||
[NSApp performSelector: @selector (setAppleMenu:) withObject: appMenu];
|
||||
[mainMenu setSubmenu: appMenu forItem: item];
|
||||
|
||||
[NSApp setMainMenu: mainMenu];
|
||||
createStandardAppMenu (appMenu, JUCEApplication::getInstance()->getApplicationName());
|
||||
|
||||
[appMenu release];
|
||||
[mainMenu release];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,285 +1,341 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
struct CallbackMessagePayload
|
||||
{
|
||||
MessageCallbackFunction* function;
|
||||
void* parameter;
|
||||
void* volatile result;
|
||||
bool volatile hasBeenExecuted;
|
||||
};
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
using namespace JUCE_NAMESPACE;
|
||||
|
||||
@interface JuceAppDelegate : NSObject
|
||||
{
|
||||
id oldDelegate;
|
||||
}
|
||||
|
||||
- (JuceAppDelegate*) init;
|
||||
- (void) dealloc;
|
||||
- (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename;
|
||||
- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames;
|
||||
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app;
|
||||
- (void) applicationDidBecomeActive: (NSNotification*) aNotification;
|
||||
- (void) applicationDidResignActive: (NSNotification*) aNotification;
|
||||
- (void) applicationWillUnhide: (NSNotification*) aNotification;
|
||||
- (void) customEvent: (id) data;
|
||||
- (void) performCallback: (id) info;
|
||||
- (void) dummyMethod;
|
||||
@end
|
||||
|
||||
@implementation JuceAppDelegate
|
||||
|
||||
- (JuceAppDelegate*) init
|
||||
{
|
||||
[super init];
|
||||
|
||||
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||
|
||||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
oldDelegate = [NSApp delegate];
|
||||
[NSApp setDelegate: self];
|
||||
}
|
||||
else
|
||||
{
|
||||
oldDelegate = 0;
|
||||
[center addObserver: self selector: @selector (applicationDidResignActive:)
|
||||
name: NSApplicationDidResignActiveNotification object: NSApp];
|
||||
|
||||
[center addObserver: self selector: @selector (applicationDidBecomeActive:)
|
||||
name: NSApplicationDidBecomeActiveNotification object: NSApp];
|
||||
|
||||
[center addObserver: self selector: @selector (applicationWillUnhide:)
|
||||
name: NSApplicationWillUnhideNotification object: NSApp];
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (oldDelegate != 0)
|
||||
[NSApp setDelegate: oldDelegate];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app
|
||||
{
|
||||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
JUCEApplication::getInstance()->systemRequestedQuit();
|
||||
|
||||
if (! MessageManager::getInstance()->hasStopMessageBeenSent())
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
return NSTerminateNow;
|
||||
}
|
||||
|
||||
- (BOOL) application: (NSApplication*) app openFile: (NSString*) filename
|
||||
{
|
||||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename));
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames
|
||||
{
|
||||
StringArray files;
|
||||
for (int i = 0; i < [filenames count]; ++i)
|
||||
files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i]));
|
||||
|
||||
if (files.size() > 0 && JUCEApplication::getInstance() != 0)
|
||||
JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" ")));
|
||||
}
|
||||
|
||||
- (void) applicationDidBecomeActive: (NSNotification*) aNotification
|
||||
{
|
||||
juce_HandleProcessFocusChange();
|
||||
}
|
||||
|
||||
- (void) applicationDidResignActive: (NSNotification*) aNotification
|
||||
{
|
||||
juce_HandleProcessFocusChange();
|
||||
}
|
||||
|
||||
- (void) applicationWillUnhide: (NSNotification*) aNotification
|
||||
{
|
||||
juce_HandleProcessFocusChange();
|
||||
}
|
||||
|
||||
- (void) customEvent: (id) n
|
||||
{
|
||||
NSData* data = (NSData*) n;
|
||||
void* message = 0;
|
||||
[data getBytes: &message length: sizeof (message)];
|
||||
|
||||
if (message != 0)
|
||||
MessageManager::getInstance()->deliverMessage (message);
|
||||
|
||||
[data release];
|
||||
}
|
||||
|
||||
- (void) performCallback: (id) info
|
||||
{
|
||||
CallbackMessagePayload* pl = (CallbackMessagePayload*) info;
|
||||
|
||||
if (pl != 0)
|
||||
{
|
||||
pl->result = (*pl->function) (pl->parameter);
|
||||
pl->hasBeenExecuted = true;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) dummyMethod {} // (used as a way of running a dummy thread)
|
||||
|
||||
@end
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
static JuceAppDelegate* juceAppDelegate = 0;
|
||||
|
||||
void MessageManager::runDispatchLoop()
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
MessageManagerLock mml;
|
||||
|
||||
// must only be called by the message thread!
|
||||
jassert (isThisTheMessageThread());
|
||||
|
||||
[NSApp run];
|
||||
}
|
||||
|
||||
void MessageManager::stopDispatchLoop()
|
||||
{
|
||||
quitMessagePosted = true;
|
||||
[NSApp stop: nil];
|
||||
}
|
||||
|
||||
bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
jassert (isThisTheMessageThread()); // must only be called by the message thread
|
||||
|
||||
uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor;
|
||||
NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow: millisecondsToRunFor * 0.001];
|
||||
|
||||
while (Time::getMillisecondCounter() < endTime)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
|
||||
beforeDate: endDate];
|
||||
|
||||
NSEvent* e = [NSApp nextEventMatchingMask: NSAnyEventMask
|
||||
untilDate: endDate
|
||||
inMode: NSDefaultRunLoopMode
|
||||
dequeue: YES];
|
||||
[NSApp sendEvent: e];
|
||||
}
|
||||
|
||||
return ! quitMessagePosted;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MessageManager::doPlatformSpecificInitialisation()
|
||||
{
|
||||
if (juceAppDelegate == 0)
|
||||
juceAppDelegate = [[JuceAppDelegate alloc] init];
|
||||
|
||||
// This launches a dummy thread, which forces Cocoa to initialise NSThreads
|
||||
// correctly (needed prior to 10.5)
|
||||
if (! [NSThread isMultiThreaded])
|
||||
[NSThread detachNewThreadSelector: @selector (dummyMethod)
|
||||
toTarget: juceAppDelegate
|
||||
withObject: nil];
|
||||
|
||||
initialiseMainMenu();
|
||||
}
|
||||
|
||||
void MessageManager::doPlatformSpecificShutdown()
|
||||
{
|
||||
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate];
|
||||
[juceAppDelegate release];
|
||||
juceAppDelegate = 0;
|
||||
}
|
||||
|
||||
bool juce_postMessageToSystemQueue (void* message)
|
||||
{
|
||||
[juceAppDelegate performSelectorOnMainThread: @selector (customEvent:)
|
||||
withObject: (id) [[NSData alloc] initWithBytes: &message
|
||||
length: (int) sizeof (message)]
|
||||
waitUntilDone: NO];
|
||||
return true;
|
||||
}
|
||||
|
||||
void MessageManager::broadcastMessage (const String& value) throw()
|
||||
{
|
||||
}
|
||||
|
||||
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback,
|
||||
void* data)
|
||||
{
|
||||
if (isThisTheMessageThread())
|
||||
{
|
||||
return (*callback) (data);
|
||||
}
|
||||
else
|
||||
{
|
||||
CallbackMessagePayload cmp;
|
||||
cmp.function = callback;
|
||||
cmp.parameter = data;
|
||||
cmp.result = 0;
|
||||
cmp.hasBeenExecuted = false;
|
||||
|
||||
[juceAppDelegate performSelectorOnMainThread: @selector (performCallback:)
|
||||
withObject: (id) &cmp
|
||||
waitUntilDone: YES];
|
||||
|
||||
return cmp.result;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#ifdef JUCE_INCLUDED_FILE
|
||||
|
||||
struct CallbackMessagePayload
|
||||
{
|
||||
MessageCallbackFunction* function;
|
||||
void* parameter;
|
||||
void* volatile result;
|
||||
bool volatile hasBeenExecuted;
|
||||
};
|
||||
|
||||
/* When you use multiple DLLs which share similarly-named obj-c classes - like
|
||||
for example having more than one juce plugin loaded into a host, then when a
|
||||
method is called, the actual code that runs might actually be in a different module
|
||||
than the one you expect... So any calls to library functions or statics that are
|
||||
made inside obj-c methods will probably end up getting executed in a different DLL's
|
||||
memory space. Not a great thing to happen - this obviously leads to bizarre crashes.
|
||||
|
||||
To work around this insanity, I'm only allowing obj-c methods to make calls to
|
||||
virtual methods of an object that's known to live inside the right module's space.
|
||||
*/
|
||||
class AppDelegateRedirector
|
||||
{
|
||||
public:
|
||||
AppDelegateRedirector() {}
|
||||
virtual ~AppDelegateRedirector() {}
|
||||
|
||||
virtual NSApplicationTerminateReply shouldTerminate()
|
||||
{
|
||||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
JUCEApplication::getInstance()->systemRequestedQuit();
|
||||
|
||||
if (! MessageManager::getInstance()->hasStopMessageBeenSent())
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
return NSTerminateNow;
|
||||
}
|
||||
|
||||
virtual BOOL openFile (const NSString* filename)
|
||||
{
|
||||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
JUCEApplication::getInstance()->anotherInstanceStarted (nsStringToJuce (filename));
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
virtual void openFiles (NSArray* filenames)
|
||||
{
|
||||
StringArray files;
|
||||
for (int i = 0; i < [filenames count]; ++i)
|
||||
files.add (nsStringToJuce ((NSString*) [filenames objectAtIndex: i]));
|
||||
|
||||
if (files.size() > 0 && JUCEApplication::getInstance() != 0)
|
||||
JUCEApplication::getInstance()->anotherInstanceStarted (files.joinIntoString (T(" ")));
|
||||
}
|
||||
|
||||
virtual void focusChanged()
|
||||
{
|
||||
juce_HandleProcessFocusChange();
|
||||
}
|
||||
|
||||
virtual void deliverMessage (void* message)
|
||||
{
|
||||
MessageManager::getInstance()->deliverMessage (message);
|
||||
}
|
||||
|
||||
virtual void deleteSelf()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
using namespace JUCE_NAMESPACE;
|
||||
|
||||
typedef void (*juce_HandleProcessFocusChangeFunction)();
|
||||
|
||||
#define JuceAppDelegate MakeObjCClassName(JuceAppDelegate)
|
||||
|
||||
@interface JuceAppDelegate : NSObject
|
||||
{
|
||||
@private
|
||||
id oldDelegate;
|
||||
AppDelegateRedirector* redirector;
|
||||
}
|
||||
|
||||
- (JuceAppDelegate*) init;
|
||||
- (void) dealloc;
|
||||
- (BOOL) application: (NSApplication*) theApplication openFile: (NSString*) filename;
|
||||
- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames;
|
||||
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app;
|
||||
- (void) applicationDidBecomeActive: (NSNotification*) aNotification;
|
||||
- (void) applicationDidResignActive: (NSNotification*) aNotification;
|
||||
- (void) applicationWillUnhide: (NSNotification*) aNotification;
|
||||
- (void) customEvent: (id) data;
|
||||
- (void) performCallback: (id) info;
|
||||
- (void) dummyMethod;
|
||||
@end
|
||||
|
||||
@implementation JuceAppDelegate
|
||||
|
||||
- (JuceAppDelegate*) init
|
||||
{
|
||||
[super init];
|
||||
|
||||
redirector = new AppDelegateRedirector();
|
||||
|
||||
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||
|
||||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
oldDelegate = [NSApp delegate];
|
||||
[NSApp setDelegate: self];
|
||||
}
|
||||
else
|
||||
{
|
||||
oldDelegate = 0;
|
||||
[center addObserver: self selector: @selector (applicationDidResignActive:)
|
||||
name: NSApplicationDidResignActiveNotification object: NSApp];
|
||||
|
||||
[center addObserver: self selector: @selector (applicationDidBecomeActive:)
|
||||
name: NSApplicationDidBecomeActiveNotification object: NSApp];
|
||||
|
||||
[center addObserver: self selector: @selector (applicationWillUnhide:)
|
||||
name: NSApplicationWillUnhideNotification object: NSApp];
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
if (oldDelegate != 0)
|
||||
[NSApp setDelegate: oldDelegate];
|
||||
|
||||
redirector->deleteSelf();
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSApplicationTerminateReply) applicationShouldTerminate: (NSApplication*) app
|
||||
{
|
||||
return redirector->shouldTerminate();
|
||||
}
|
||||
|
||||
- (BOOL) application: (NSApplication*) app openFile: (NSString*) filename
|
||||
{
|
||||
return redirector->openFile (filename);
|
||||
}
|
||||
|
||||
- (void) application: (NSApplication*) sender openFiles: (NSArray*) filenames
|
||||
{
|
||||
return redirector->openFiles (filenames);
|
||||
}
|
||||
|
||||
- (void) applicationDidBecomeActive: (NSNotification*) aNotification
|
||||
{
|
||||
redirector->focusChanged();
|
||||
}
|
||||
|
||||
- (void) applicationDidResignActive: (NSNotification*) aNotification
|
||||
{
|
||||
redirector->focusChanged();
|
||||
}
|
||||
|
||||
- (void) applicationWillUnhide: (NSNotification*) aNotification
|
||||
{
|
||||
redirector->focusChanged();
|
||||
}
|
||||
|
||||
- (void) customEvent: (id) n
|
||||
{
|
||||
NSData* data = (NSData*) n;
|
||||
void* message = 0;
|
||||
[data getBytes: &message length: sizeof (message)];
|
||||
|
||||
if (message != 0)
|
||||
redirector->deliverMessage (message);
|
||||
|
||||
[data release];
|
||||
}
|
||||
|
||||
- (void) performCallback: (id) info
|
||||
{
|
||||
CallbackMessagePayload* pl = (CallbackMessagePayload*) info;
|
||||
|
||||
if (pl != 0)
|
||||
{
|
||||
pl->result = (*pl->function) (pl->parameter);
|
||||
pl->hasBeenExecuted = true;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) dummyMethod {} // (used as a way of running a dummy thread)
|
||||
|
||||
@end
|
||||
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
|
||||
static JuceAppDelegate* juceAppDelegate = 0;
|
||||
|
||||
void MessageManager::runDispatchLoop()
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
MessageManagerLock mml;
|
||||
|
||||
// must only be called by the message thread!
|
||||
jassert (isThisTheMessageThread());
|
||||
|
||||
[NSApp run];
|
||||
}
|
||||
|
||||
void MessageManager::stopDispatchLoop()
|
||||
{
|
||||
quitMessagePosted = true;
|
||||
[NSApp stop: nil];
|
||||
}
|
||||
|
||||
bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
jassert (isThisTheMessageThread()); // must only be called by the message thread
|
||||
|
||||
uint32 endTime = Time::getMillisecondCounter() + millisecondsToRunFor;
|
||||
NSDate* endDate = [NSDate dateWithTimeIntervalSinceNow: millisecondsToRunFor * 0.001];
|
||||
|
||||
while (Time::getMillisecondCounter() < endTime)
|
||||
{
|
||||
const ScopedAutoReleasePool pool;
|
||||
|
||||
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
|
||||
beforeDate: endDate];
|
||||
|
||||
NSEvent* e = [NSApp nextEventMatchingMask: NSAnyEventMask
|
||||
untilDate: endDate
|
||||
inMode: NSDefaultRunLoopMode
|
||||
dequeue: YES];
|
||||
[NSApp sendEvent: e];
|
||||
}
|
||||
|
||||
return ! quitMessagePosted;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void MessageManager::doPlatformSpecificInitialisation()
|
||||
{
|
||||
if (juceAppDelegate == 0)
|
||||
juceAppDelegate = [[JuceAppDelegate alloc] init];
|
||||
|
||||
// This launches a dummy thread, which forces Cocoa to initialise NSThreads
|
||||
// correctly (needed prior to 10.5)
|
||||
if (! [NSThread isMultiThreaded])
|
||||
[NSThread detachNewThreadSelector: @selector (dummyMethod)
|
||||
toTarget: juceAppDelegate
|
||||
withObject: nil];
|
||||
|
||||
initialiseMainMenu();
|
||||
}
|
||||
|
||||
void MessageManager::doPlatformSpecificShutdown()
|
||||
{
|
||||
[[NSRunLoop currentRunLoop] cancelPerformSelectorsWithTarget: juceAppDelegate];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver: juceAppDelegate];
|
||||
[juceAppDelegate release];
|
||||
juceAppDelegate = 0;
|
||||
}
|
||||
|
||||
bool juce_postMessageToSystemQueue (void* message)
|
||||
{
|
||||
[juceAppDelegate performSelectorOnMainThread: @selector (customEvent:)
|
||||
withObject: (id) [[NSData alloc] initWithBytes: &message
|
||||
length: (int) sizeof (message)]
|
||||
waitUntilDone: NO];
|
||||
return true;
|
||||
}
|
||||
|
||||
void MessageManager::broadcastMessage (const String& value) throw()
|
||||
{
|
||||
}
|
||||
|
||||
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback,
|
||||
void* data)
|
||||
{
|
||||
if (isThisTheMessageThread())
|
||||
{
|
||||
return (*callback) (data);
|
||||
}
|
||||
else
|
||||
{
|
||||
CallbackMessagePayload cmp;
|
||||
cmp.function = callback;
|
||||
cmp.parameter = data;
|
||||
cmp.result = 0;
|
||||
cmp.hasBeenExecuted = false;
|
||||
|
||||
[juceAppDelegate performSelectorOnMainThread: @selector (performCallback:)
|
||||
withObject: (id) &cmp
|
||||
waitUntilDone: YES];
|
||||
|
||||
return cmp.result;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -77,6 +77,12 @@ BEGIN_JUCE_NAMESPACE
|
|||
#include "../../../src/juce_appframework/audio/devices/juce_MidiInput.h"
|
||||
#undef Point
|
||||
|
||||
//==============================================================================
|
||||
#define ObjCExtraSuffix 1
|
||||
#define appendMacro1(a, b, c, d) a ## _ ## b ## _ ## c ## _ ## d
|
||||
#define appendMacro2(a, b, c, d) appendMacro1(a, b, c, d)
|
||||
#define MakeObjCClassName(rootName) appendMacro2 (rootName, JUCE_MAJOR_VERSION, JUCE_MINOR_VERSION, ObjCExtraSuffix)
|
||||
|
||||
//==============================================================================
|
||||
#define JUCE_INCLUDED_FILE 1
|
||||
|
||||
|
|
|
|||
|
|
@ -166,6 +166,8 @@ END_JUCE_NAMESPACE
|
|||
using namespace JUCE_NAMESPACE;
|
||||
|
||||
//==============================================================================
|
||||
#define JuceURLConnection MakeObjCClassName(JuceURLConnection)
|
||||
|
||||
@interface JuceURLConnection : NSObject
|
||||
{
|
||||
NSURLRequest* request;
|
||||
|
|
|
|||
|
|
@ -1,235 +1,246 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#if JUCE_INCLUDED_FILE && JUCE_OPENGL
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class WindowedGLContext : public OpenGLContext
|
||||
{
|
||||
public:
|
||||
WindowedGLContext (Component* const component,
|
||||
const OpenGLPixelFormat& pixelFormat_,
|
||||
NSOpenGLContext* sharedContext)
|
||||
: renderContext (0),
|
||||
pixelFormat (pixelFormat_)
|
||||
{
|
||||
jassert (component != 0);
|
||||
|
||||
NSOpenGLPixelFormatAttribute attribs [64];
|
||||
int n = 0;
|
||||
attribs[n++] = NSOpenGLPFADoubleBuffer;
|
||||
attribs[n++] = NSOpenGLPFAAccelerated;
|
||||
attribs[n++] = NSOpenGLPFAColorSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.redBits,
|
||||
pixelFormat.greenBits,
|
||||
pixelFormat.blueBits);
|
||||
attribs[n++] = NSOpenGLPFAAlphaSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) pixelFormat.alphaBits;
|
||||
attribs[n++] = NSOpenGLPFADepthSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) pixelFormat.depthBufferBits;
|
||||
attribs[n++] = NSOpenGLPFAStencilSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) pixelFormat.stencilBufferBits;
|
||||
attribs[n++] = NSOpenGLPFAAccumSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.accumulationBufferRedBits,
|
||||
pixelFormat.accumulationBufferGreenBits,
|
||||
pixelFormat.accumulationBufferBlueBits,
|
||||
pixelFormat.accumulationBufferAlphaBits);
|
||||
|
||||
// xxx not sure how to do fullSceneAntiAliasingNumSamples..
|
||||
|
||||
attribs[n++] = NSOpenGLPFASampleBuffers;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) 1;
|
||||
attribs[n++] = NSOpenGLPFAClosestPolicy;
|
||||
attribs[n++] = NSOpenGLPFANoRecovery;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) 0;
|
||||
|
||||
NSOpenGLPixelFormat* format
|
||||
= [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs];
|
||||
|
||||
NSOpenGLView* view
|
||||
= [[NSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
|
||||
pixelFormat: format];
|
||||
|
||||
renderContext = [view openGLContext];
|
||||
[format release];
|
||||
|
||||
viewHolder = new NSViewComponentInternal (view, component);
|
||||
}
|
||||
|
||||
~WindowedGLContext()
|
||||
{
|
||||
makeInactive();
|
||||
[renderContext setView: nil];
|
||||
delete viewHolder;
|
||||
}
|
||||
|
||||
bool makeActive() const throw()
|
||||
{
|
||||
jassert (renderContext != 0);
|
||||
[renderContext makeCurrentContext];
|
||||
return renderContext != 0;
|
||||
}
|
||||
|
||||
bool makeInactive() const throw()
|
||||
{
|
||||
if (! isActive())
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isActive() const throw()
|
||||
{
|
||||
return [NSOpenGLContext currentContext] == renderContext;
|
||||
}
|
||||
|
||||
const OpenGLPixelFormat getPixelFormat() const { return pixelFormat; }
|
||||
void* getRawContext() const throw() { return renderContext; }
|
||||
|
||||
void updateWindowPosition (int x, int y, int w, int h, int outerWindowHeight)
|
||||
{
|
||||
}
|
||||
|
||||
void swapBuffers()
|
||||
{
|
||||
glFlush();
|
||||
[renderContext flushBuffer];
|
||||
}
|
||||
|
||||
bool setSwapInterval (const int numFramesPerSwap)
|
||||
{
|
||||
[renderContext setValues: (const GLint*) &numFramesPerSwap
|
||||
forParameter: NSOpenGLCPSwapInterval];
|
||||
return true;
|
||||
}
|
||||
|
||||
int getSwapInterval() const
|
||||
{
|
||||
GLint numFrames = 0;
|
||||
[renderContext getValues: &numFrames
|
||||
forParameter: NSOpenGLCPSwapInterval];
|
||||
return numFrames;
|
||||
}
|
||||
|
||||
void repaint()
|
||||
{
|
||||
// we need to invalidate the juce view that holds this gl view, to make it
|
||||
// cause a repaint callback
|
||||
NSView* v = (NSView*) viewHolder->view;
|
||||
NSRect r = [v frame];
|
||||
|
||||
// bit of a bodge here.. if we only invalidate the area of the gl component,
|
||||
// it's completely covered by the NSOpenGLView, so the OS throws away the
|
||||
// repaint message, thus never causing our paint() callback, and never repainting
|
||||
// the comp. So invalidating just a little bit around the edge helps..
|
||||
[[v superview] setNeedsDisplayInRect: NSInsetRect (r, -2.0f, -2.0f)];
|
||||
}
|
||||
|
||||
void* getNativeWindowHandle() const { return viewHolder->view; }
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
NSOpenGLContext* renderContext;
|
||||
|
||||
private:
|
||||
OpenGLPixelFormat pixelFormat;
|
||||
NSViewComponentInternal* viewHolder;
|
||||
|
||||
//==============================================================================
|
||||
WindowedGLContext (const WindowedGLContext&);
|
||||
const WindowedGLContext& operator= (const WindowedGLContext&);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
OpenGLContext* OpenGLContext::createContextForWindow (Component* const component,
|
||||
const OpenGLPixelFormat& pixelFormat,
|
||||
const OpenGLContext* const contextToShareWith)
|
||||
{
|
||||
WindowedGLContext* c = new WindowedGLContext (component, pixelFormat,
|
||||
contextToShareWith != 0 ? (NSOpenGLContext*) contextToShareWith->getRawContext() : 0);
|
||||
|
||||
if (c->renderContext == 0)
|
||||
deleteAndZero (c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void* OpenGLComponent::getNativeWindowHandle() const
|
||||
{
|
||||
return context != 0 ? ((WindowedGLContext*) context)->getNativeWindowHandle()
|
||||
: 0;
|
||||
}
|
||||
|
||||
void juce_glViewport (const int w, const int h)
|
||||
{
|
||||
glViewport (0, 0, w, h);
|
||||
}
|
||||
|
||||
void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/,
|
||||
OwnedArray <OpenGLPixelFormat>& results)
|
||||
{
|
||||
/* GLint attribs [64];
|
||||
int n = 0;
|
||||
attribs[n++] = AGL_RGBA;
|
||||
attribs[n++] = AGL_DOUBLEBUFFER;
|
||||
attribs[n++] = AGL_ACCELERATED;
|
||||
attribs[n++] = AGL_NO_RECOVERY;
|
||||
attribs[n++] = AGL_NONE;
|
||||
|
||||
AGLPixelFormat p = aglChoosePixelFormat (0, 0, attribs);
|
||||
|
||||
while (p != 0)
|
||||
{
|
||||
OpenGLPixelFormat* const pf = new OpenGLPixelFormat();
|
||||
pf->redBits = getAGLAttribute (p, AGL_RED_SIZE);
|
||||
pf->greenBits = getAGLAttribute (p, AGL_GREEN_SIZE);
|
||||
pf->blueBits = getAGLAttribute (p, AGL_BLUE_SIZE);
|
||||
pf->alphaBits = getAGLAttribute (p, AGL_ALPHA_SIZE);
|
||||
pf->depthBufferBits = getAGLAttribute (p, AGL_DEPTH_SIZE);
|
||||
pf->stencilBufferBits = getAGLAttribute (p, AGL_STENCIL_SIZE);
|
||||
pf->accumulationBufferRedBits = getAGLAttribute (p, AGL_ACCUM_RED_SIZE);
|
||||
pf->accumulationBufferGreenBits = getAGLAttribute (p, AGL_ACCUM_GREEN_SIZE);
|
||||
pf->accumulationBufferBlueBits = getAGLAttribute (p, AGL_ACCUM_BLUE_SIZE);
|
||||
pf->accumulationBufferAlphaBits = getAGLAttribute (p, AGL_ACCUM_ALPHA_SIZE);
|
||||
|
||||
results.add (pf);
|
||||
|
||||
p = aglNextPixelFormat (p);
|
||||
}*/
|
||||
|
||||
//jassertfalse //xxx can't see how you do this in cocoa!
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-7 by Raw Material Software ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the
|
||||
GNU General Public License, as published by the Free Software Foundation;
|
||||
either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
JUCE is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with JUCE; if not, visit www.gnu.org/licenses or write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
If you'd like to release a closed-source product which uses JUCE, commercial
|
||||
licenses are also available: visit www.rawmaterialsoftware.com/juce for
|
||||
more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
// (This file gets included by juce_mac_NativeCode.mm, rather than being
|
||||
// compiled on its own).
|
||||
#if JUCE_INCLUDED_FILE && JUCE_OPENGL
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class WindowedGLContext : public OpenGLContext
|
||||
{
|
||||
public:
|
||||
WindowedGLContext (Component* const component,
|
||||
const OpenGLPixelFormat& pixelFormat_,
|
||||
NSOpenGLContext* sharedContext)
|
||||
: renderContext (0),
|
||||
pixelFormat (pixelFormat_)
|
||||
{
|
||||
jassert (component != 0);
|
||||
|
||||
NSOpenGLPixelFormatAttribute attribs [64];
|
||||
int n = 0;
|
||||
attribs[n++] = NSOpenGLPFADoubleBuffer;
|
||||
attribs[n++] = NSOpenGLPFAAccelerated;
|
||||
attribs[n++] = NSOpenGLPFAColorSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.redBits,
|
||||
pixelFormat.greenBits,
|
||||
pixelFormat.blueBits);
|
||||
attribs[n++] = NSOpenGLPFAAlphaSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) pixelFormat.alphaBits;
|
||||
attribs[n++] = NSOpenGLPFADepthSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) pixelFormat.depthBufferBits;
|
||||
attribs[n++] = NSOpenGLPFAStencilSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) pixelFormat.stencilBufferBits;
|
||||
attribs[n++] = NSOpenGLPFAAccumSize;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) jmax (pixelFormat.accumulationBufferRedBits,
|
||||
pixelFormat.accumulationBufferGreenBits,
|
||||
pixelFormat.accumulationBufferBlueBits,
|
||||
pixelFormat.accumulationBufferAlphaBits);
|
||||
|
||||
// xxx not sure how to do fullSceneAntiAliasingNumSamples..
|
||||
|
||||
attribs[n++] = NSOpenGLPFASampleBuffers;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) 1;
|
||||
attribs[n++] = NSOpenGLPFAClosestPolicy;
|
||||
attribs[n++] = NSOpenGLPFANoRecovery;
|
||||
attribs[n++] = (NSOpenGLPixelFormatAttribute) 0;
|
||||
|
||||
NSOpenGLPixelFormat* format
|
||||
= [[NSOpenGLPixelFormat alloc] initWithAttributes: attribs];
|
||||
|
||||
NSOpenGLView* view
|
||||
= [[NSOpenGLView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
|
||||
pixelFormat: format];
|
||||
|
||||
if (sharedContext != 0)
|
||||
{
|
||||
renderContext = [[NSOpenGLContext alloc] initWithFormat: format
|
||||
shareContext: sharedContext];
|
||||
[view setOpenGLContext: renderContext];
|
||||
[renderContext setView: view];
|
||||
}
|
||||
else
|
||||
{
|
||||
renderContext = [view openGLContext];
|
||||
}
|
||||
|
||||
[format release];
|
||||
|
||||
viewHolder = new NSViewComponentInternal (view, component);
|
||||
}
|
||||
|
||||
~WindowedGLContext()
|
||||
{
|
||||
makeInactive();
|
||||
[renderContext setView: nil];
|
||||
delete viewHolder;
|
||||
}
|
||||
|
||||
bool makeActive() const throw()
|
||||
{
|
||||
jassert (renderContext != 0);
|
||||
[renderContext makeCurrentContext];
|
||||
return renderContext != 0;
|
||||
}
|
||||
|
||||
bool makeInactive() const throw()
|
||||
{
|
||||
if (! isActive())
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isActive() const throw()
|
||||
{
|
||||
return [NSOpenGLContext currentContext] == renderContext;
|
||||
}
|
||||
|
||||
const OpenGLPixelFormat getPixelFormat() const { return pixelFormat; }
|
||||
void* getRawContext() const throw() { return renderContext; }
|
||||
|
||||
void updateWindowPosition (int x, int y, int w, int h, int outerWindowHeight)
|
||||
{
|
||||
}
|
||||
|
||||
void swapBuffers()
|
||||
{
|
||||
glFlush();
|
||||
[renderContext flushBuffer];
|
||||
}
|
||||
|
||||
bool setSwapInterval (const int numFramesPerSwap)
|
||||
{
|
||||
[renderContext setValues: (const GLint*) &numFramesPerSwap
|
||||
forParameter: NSOpenGLCPSwapInterval];
|
||||
return true;
|
||||
}
|
||||
|
||||
int getSwapInterval() const
|
||||
{
|
||||
GLint numFrames = 0;
|
||||
[renderContext getValues: &numFrames
|
||||
forParameter: NSOpenGLCPSwapInterval];
|
||||
return numFrames;
|
||||
}
|
||||
|
||||
void repaint()
|
||||
{
|
||||
// we need to invalidate the juce view that holds this gl view, to make it
|
||||
// cause a repaint callback
|
||||
NSView* v = (NSView*) viewHolder->view;
|
||||
NSRect r = [v frame];
|
||||
|
||||
// bit of a bodge here.. if we only invalidate the area of the gl component,
|
||||
// it's completely covered by the NSOpenGLView, so the OS throws away the
|
||||
// repaint message, thus never causing our paint() callback, and never repainting
|
||||
// the comp. So invalidating just a little bit around the edge helps..
|
||||
[[v superview] setNeedsDisplayInRect: NSInsetRect (r, -2.0f, -2.0f)];
|
||||
}
|
||||
|
||||
void* getNativeWindowHandle() const { return viewHolder->view; }
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
NSOpenGLContext* renderContext;
|
||||
|
||||
private:
|
||||
OpenGLPixelFormat pixelFormat;
|
||||
NSViewComponentInternal* viewHolder;
|
||||
|
||||
//==============================================================================
|
||||
WindowedGLContext (const WindowedGLContext&);
|
||||
const WindowedGLContext& operator= (const WindowedGLContext&);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
OpenGLContext* OpenGLContext::createContextForWindow (Component* const component,
|
||||
const OpenGLPixelFormat& pixelFormat,
|
||||
const OpenGLContext* const contextToShareWith)
|
||||
{
|
||||
WindowedGLContext* c = new WindowedGLContext (component, pixelFormat,
|
||||
contextToShareWith != 0 ? (NSOpenGLContext*) contextToShareWith->getRawContext() : 0);
|
||||
|
||||
if (c->renderContext == 0)
|
||||
deleteAndZero (c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void* OpenGLComponent::getNativeWindowHandle() const
|
||||
{
|
||||
return context != 0 ? ((WindowedGLContext*) context)->getNativeWindowHandle()
|
||||
: 0;
|
||||
}
|
||||
|
||||
void juce_glViewport (const int w, const int h)
|
||||
{
|
||||
glViewport (0, 0, w, h);
|
||||
}
|
||||
|
||||
void OpenGLPixelFormat::getAvailablePixelFormats (Component* /*component*/,
|
||||
OwnedArray <OpenGLPixelFormat>& results)
|
||||
{
|
||||
/* GLint attribs [64];
|
||||
int n = 0;
|
||||
attribs[n++] = AGL_RGBA;
|
||||
attribs[n++] = AGL_DOUBLEBUFFER;
|
||||
attribs[n++] = AGL_ACCELERATED;
|
||||
attribs[n++] = AGL_NO_RECOVERY;
|
||||
attribs[n++] = AGL_NONE;
|
||||
|
||||
AGLPixelFormat p = aglChoosePixelFormat (0, 0, attribs);
|
||||
|
||||
while (p != 0)
|
||||
{
|
||||
OpenGLPixelFormat* const pf = new OpenGLPixelFormat();
|
||||
pf->redBits = getAGLAttribute (p, AGL_RED_SIZE);
|
||||
pf->greenBits = getAGLAttribute (p, AGL_GREEN_SIZE);
|
||||
pf->blueBits = getAGLAttribute (p, AGL_BLUE_SIZE);
|
||||
pf->alphaBits = getAGLAttribute (p, AGL_ALPHA_SIZE);
|
||||
pf->depthBufferBits = getAGLAttribute (p, AGL_DEPTH_SIZE);
|
||||
pf->stencilBufferBits = getAGLAttribute (p, AGL_STENCIL_SIZE);
|
||||
pf->accumulationBufferRedBits = getAGLAttribute (p, AGL_ACCUM_RED_SIZE);
|
||||
pf->accumulationBufferGreenBits = getAGLAttribute (p, AGL_ACCUM_GREEN_SIZE);
|
||||
pf->accumulationBufferBlueBits = getAGLAttribute (p, AGL_ACCUM_BLUE_SIZE);
|
||||
pf->accumulationBufferAlphaBits = getAGLAttribute (p, AGL_ACCUM_ALPHA_SIZE);
|
||||
|
||||
results.add (pf);
|
||||
|
||||
p = aglNextPixelFormat (p);
|
||||
}*/
|
||||
|
||||
//jassertfalse //xxx can't see how you do this in cocoa!
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -57,18 +57,9 @@ bool QuickTimeMovieComponent::isQuickTimeAvailable() throw()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool QuickTimeMovieComponent::loadMovie (InputStream* movieStream,
|
||||
const bool controllerVisible)
|
||||
static QTMovie* openMovieFromStream (InputStream* movieStream, File& movieFile)
|
||||
{
|
||||
closeMovie();
|
||||
|
||||
if (getPeer() == 0)
|
||||
{
|
||||
// To open a movie, this component must be visible inside a functioning window, so that
|
||||
// the QT control can be assigned to the window.
|
||||
jassertfalse
|
||||
return false;
|
||||
}
|
||||
QTMovie* movie = 0;
|
||||
|
||||
FileInputStream* const fin = dynamic_cast <FileInputStream*> (movieStream);
|
||||
|
||||
|
|
@ -82,11 +73,39 @@ bool QuickTimeMovieComponent::loadMovie (InputStream* movieStream,
|
|||
{
|
||||
MemoryBlock temp;
|
||||
movieStream->readIntoMemoryBlock (temp);
|
||||
|
||||
const char* const suffixesToTry[] = { ".mov", ".mp3", ".avi", ".m4a" };
|
||||
|
||||
for (int i = 0; i < numElementsInArray (suffixesToTry); ++i)
|
||||
{
|
||||
movie = [QTMovie movieWithDataReference: [QTDataReference dataReferenceWithReferenceToData: [NSData dataWithBytes: temp.getData()
|
||||
length: temp.getSize()]
|
||||
name: [NSString stringWithCString: suffixesToTry[i]]
|
||||
MIMEType: @""]
|
||||
error: nil];
|
||||
|
||||
movie = [QTMovie movieWithData: [NSData dataWithBytes: temp.getData()
|
||||
length: temp.getSize()]
|
||||
error: nil];
|
||||
if (movie != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return movie;
|
||||
}
|
||||
|
||||
bool QuickTimeMovieComponent::loadMovie (InputStream* movieStream,
|
||||
const bool controllerVisible)
|
||||
{
|
||||
closeMovie();
|
||||
|
||||
if (getPeer() == 0)
|
||||
{
|
||||
// To open a movie, this component must be visible inside a functioning window, so that
|
||||
// the QT control can be assigned to the window.
|
||||
jassertfalse
|
||||
return false;
|
||||
}
|
||||
|
||||
movie = openMovieFromStream (movieStream, movieFile);
|
||||
|
||||
[theMovie retain];
|
||||
QTMovieView* view = (QTMovieView*) getView();
|
||||
|
|
@ -264,24 +283,8 @@ bool juce_OpenQuickTimeMovieFromStream (InputStream* movieStream, Movie& result,
|
|||
if (movieStream == 0)
|
||||
return false;
|
||||
|
||||
QTMovie* movie = nil;
|
||||
|
||||
FileInputStream* const fin = dynamic_cast <FileInputStream*> (movieStream);
|
||||
|
||||
if (fin != 0)
|
||||
{
|
||||
movie = [QTMovie movieWithFile: juceStringToNS (fin->getFile().getFullPathName())
|
||||
error: nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
MemoryBlock temp;
|
||||
movieStream->readIntoMemoryBlock (temp);
|
||||
|
||||
movie = [QTMovie movieWithData: [NSData dataWithBytes: temp.getData()
|
||||
length: temp.getSize()]
|
||||
error: nil];
|
||||
}
|
||||
File file;
|
||||
QTMovie* movie = openMovieFromStream (movieStream, file);
|
||||
|
||||
if (movie != nil)
|
||||
result = [movie quickTimeMovie];
|
||||
|
|
|
|||
|
|
@ -89,7 +89,10 @@ void SystemStats::initialiseStats() throw()
|
|||
{
|
||||
initialised = true;
|
||||
|
||||
NSApplicationLoad();
|
||||
// etremely annoying: adding this line stops the apple menu items from working. Of
|
||||
// course, not adding it means that carbon windows (e.g. in plugins) won't get
|
||||
// any events.
|
||||
//NSApplicationLoad();
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
#if JUCE_INTEL
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@
|
|||
//==============================================================================
|
||||
END_JUCE_NAMESPACE
|
||||
|
||||
#define DownloadClickDetector MakeObjCClassName(DownloadClickDetector)
|
||||
|
||||
|
||||
@interface DownloadClickDetector : NSObject
|
||||
{
|
||||
JUCE_NAMESPACE::WebBrowserComponent* ownerComponent;
|
||||
|
|
@ -59,11 +62,14 @@ END_JUCE_NAMESPACE
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void) webView: (WebView*) sender decidePolicyForNavigationAction: (NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id < WebPolicyDecisionListener >)listener
|
||||
- (void) webView: (WebView*) sender decidePolicyForNavigationAction: (NSDictionary*) actionInformation
|
||||
request: (NSURLRequest*) request
|
||||
frame: (WebFrame*) frame
|
||||
decisionListener: (id <WebPolicyDecisionListener>) listener
|
||||
{
|
||||
NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"];
|
||||
|
||||
if (ownerComponent->pageAboutToLoad (JUCE_NAMESPACE::String::fromUTF8 ((const JUCE_NAMESPACE::uint8*) [[url absoluteString] UTF8String])))
|
||||
if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString])))
|
||||
[listener use];
|
||||
else
|
||||
[listener ignore];
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
//#define JUCE_USE_XSHM 1
|
||||
//#define JUCE_PLUGINHOST_VST 1
|
||||
//#define JUCE_PLUGINHOST_AU 1
|
||||
//#define JUCE_BUILD_GUI_CLASSES 1
|
||||
//#define JUCE_CHECK_MEMORY_LEAKS 1
|
||||
//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
|
||||
//#define JUCE_STRINGS_ARE_UNICODE 1
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
//#define JUCE_ENABLE_REPAINT_DEBUGGING 1
|
||||
//#define JUCE_USE_XINERAMA 1
|
||||
//#define JUCE_USE_XSHM 1
|
||||
//#define JUCE_BUILD_GUI_CLASSES 1
|
||||
//#define JUCE_CHECK_MEMORY_LEAKS 1
|
||||
//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
|
||||
//#define JUCE_STRINGS_ARE_UNICODE 1
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
//#define JUCE_USE_XSHM 1
|
||||
//#define JUCE_PLUGINHOST_VST 1
|
||||
//#define JUCE_PLUGINHOST_AU 1
|
||||
//#define JUCE_BUILD_GUI_CLASSES 1
|
||||
//#define JUCE_CHECK_MEMORY_LEAKS 1
|
||||
//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
|
||||
//#define JUCE_STRINGS_ARE_UNICODE 1
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
//#define JUCE_USE_XSHM 1
|
||||
//#define JUCE_PLUGINHOST_VST 1
|
||||
//#define JUCE_PLUGINHOST_AU 1
|
||||
//#define JUCE_BUILD_GUI_CLASSES 1
|
||||
//#define JUCE_CHECK_MEMORY_LEAKS 1
|
||||
//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
|
||||
//#define JUCE_STRINGS_ARE_UNICODE 1
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
//#define JUCE_USE_XSHM 1
|
||||
#define JUCE_PLUGINHOST_VST 0
|
||||
#define JUCE_PLUGINHOST_AU 0
|
||||
//#define JUCE_BUILD_GUI_CLASSES 1
|
||||
//#define JUCE_CHECK_MEMORY_LEAKS 1
|
||||
//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
|
||||
//#define JUCE_STRINGS_ARE_UNICODE 1
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
//#define JUCE_USE_XSHM 1
|
||||
#define JUCE_PLUGINHOST_VST 0
|
||||
#define JUCE_PLUGINHOST_AU 0
|
||||
//#define JUCE_BUILD_GUI_CLASSES 1
|
||||
//#define JUCE_CHECK_MEMORY_LEAKS 1
|
||||
//#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
|
||||
//#define JUCE_STRINGS_ARE_UNICODE 1
|
||||
|
|
|
|||
|
|
@ -171,14 +171,12 @@
|
|||
#endif
|
||||
|
||||
//=============================================================================
|
||||
/** Disabling this will avoid linking to any UI code. This is handy for
|
||||
/** Enabling this will avoid including any UI code in the build. This is handy for
|
||||
writing command-line utilities, e.g. on linux boxes which don't have some
|
||||
of the UI libraries installed.
|
||||
|
||||
(On mac and windows, this won't generally make much difference to the build).
|
||||
*/
|
||||
#ifndef JUCE_BUILD_GUI_CLASSES
|
||||
#define JUCE_BUILD_GUI_CLASSES 1
|
||||
#ifndef JUCE_ONLY_BUILD_CORE_LIBRARY
|
||||
//#define JUCE_ONLY_BUILD_CORE_LIBRARY 1
|
||||
#endif
|
||||
|
||||
/** This lets you disable building of the WebBrowserComponent, if it's not required.
|
||||
|
|
|
|||
1697
juce_amalgamated.cpp
1697
juce_amalgamated.cpp
File diff suppressed because it is too large
Load diff
|
|
@ -207,14 +207,12 @@
|
|||
// #define JUCE_PLUGINHOST_AU 1
|
||||
#endif
|
||||
|
||||
/** Disabling this will avoid linking to any UI code. This is handy for
|
||||
/** Enabling this will avoid including any UI code in the build. This is handy for
|
||||
writing command-line utilities, e.g. on linux boxes which don't have some
|
||||
of the UI libraries installed.
|
||||
|
||||
(On mac and windows, this won't generally make much difference to the build).
|
||||
*/
|
||||
#ifndef JUCE_BUILD_GUI_CLASSES
|
||||
#define JUCE_BUILD_GUI_CLASSES 1
|
||||
#ifndef JUCE_ONLY_BUILD_CORE_LIBRARY
|
||||
//#define JUCE_ONLY_BUILD_CORE_LIBRARY 1
|
||||
#endif
|
||||
|
||||
/** This lets you disable building of the WebBrowserComponent, if it's not required.
|
||||
|
|
|
|||
|
|
@ -367,27 +367,29 @@ const String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& ne
|
|||
return String::empty;
|
||||
}
|
||||
|
||||
if (currentSetup.inputDeviceName != newSetup.inputDeviceName
|
||||
|| currentSetup.outputDeviceName != newSetup.outputDeviceName
|
||||
const String newInputDeviceName (numInputChansNeeded == 0 ? String::empty : newSetup.inputDeviceName);
|
||||
const String newOutputDeviceName (numOutputChansNeeded == 0 ? String::empty : newSetup.outputDeviceName);
|
||||
|
||||
if (currentSetup.inputDeviceName != newInputDeviceName
|
||||
|| currentSetup.inputDeviceName != newOutputDeviceName
|
||||
|| currentAudioDevice == 0)
|
||||
{
|
||||
deleteCurrentDevice();
|
||||
scanDevicesIfNeeded();
|
||||
|
||||
if (newSetup.outputDeviceName.isNotEmpty()
|
||||
&& ! type->getDeviceNames (false).contains (newSetup.outputDeviceName))
|
||||
if (newOutputDeviceName.isNotEmpty()
|
||||
&& ! type->getDeviceNames (false).contains (newOutputDeviceName))
|
||||
{
|
||||
return "No such device: " + newSetup.outputDeviceName;
|
||||
return "No such device: " + newOutputDeviceName;
|
||||
}
|
||||
|
||||
if (newSetup.inputDeviceName.isNotEmpty()
|
||||
&& ! type->getDeviceNames (true).contains (newSetup.inputDeviceName))
|
||||
if (newInputDeviceName.isNotEmpty()
|
||||
&& ! type->getDeviceNames (true).contains (newInputDeviceName))
|
||||
{
|
||||
return "No such device: " + newSetup.outputDeviceName;
|
||||
return "No such device: " + newInputDeviceName;
|
||||
}
|
||||
|
||||
currentAudioDevice = type->createDevice (newSetup.outputDeviceName,
|
||||
newSetup.inputDeviceName);
|
||||
currentAudioDevice = type->createDevice (newOutputDeviceName, newInputDeviceName);
|
||||
|
||||
if (currentAudioDevice == 0)
|
||||
error = "Can't open the audio device!\n\nThis may be because another application is currently using the same device - if so, you should close any other applications and try again!";
|
||||
|
|
@ -412,10 +414,10 @@ const String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& ne
|
|||
outputChannels.setRange (0, numOutputChansNeeded, true);
|
||||
}
|
||||
|
||||
if (newSetup.inputDeviceName.isEmpty())
|
||||
if (newInputDeviceName.isEmpty())
|
||||
inputChannels.clear();
|
||||
|
||||
if (newSetup.outputDeviceName.isEmpty())
|
||||
if (newOutputDeviceName.isEmpty())
|
||||
outputChannels.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -359,6 +359,8 @@ void Slider::lookAndFeelChanged()
|
|||
|
||||
if (style == LinearBar)
|
||||
valueBox->addMouseListener (this, false);
|
||||
|
||||
valueBox->setTooltip (getTooltip());
|
||||
}
|
||||
|
||||
if (style == IncDecButtons)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue