mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
55169 lines
2 MiB
55169 lines
2 MiB
/*
|
|
==============================================================================
|
|
|
|
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
|
Copyright 2004-9 by Raw Material Software Ltd.
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
JUCE can be redistributed and/or modified under the terms of the GNU General
|
|
Public License (Version 2), as published by the Free Software Foundation.
|
|
A copy of the license is included in the JUCE distribution, or can be found
|
|
online at www.gnu.org/licenses.
|
|
|
|
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.
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
To release a closed-source product which uses JUCE, commercial licenses are
|
|
available: visit www.rawmaterialsoftware.com/juce for more information.
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
/*
|
|
==============================================================================
|
|
|
|
This header contains the entire Juce source tree, and can be #included in
|
|
all your source files.
|
|
|
|
As well as including this in your files, you should also add juce_inline.cpp
|
|
to your project (or juce_inline.mm on the Mac).
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
#ifndef __JUCE_AMALGAMATED_TEMPLATE_JUCEHEADER__
|
|
#define __JUCE_AMALGAMATED_TEMPLATE_JUCEHEADER__
|
|
|
|
#define DONT_AUTOLINK_TO_JUCE_LIBRARY 1
|
|
|
|
/********* Start of inlined file: juce.h *********/
|
|
#ifndef __JUCE_JUCEHEADER__
|
|
#define __JUCE_JUCEHEADER__
|
|
|
|
/*
|
|
This is the main JUCE header file that applications need to include.
|
|
|
|
*/
|
|
|
|
// (this includes things that need defining outside of the JUCE namespace)
|
|
|
|
/********* Start of inlined file: juce_StandardHeader.h *********/
|
|
#ifndef __JUCE_STANDARDHEADER_JUCEHEADER__
|
|
#define __JUCE_STANDARDHEADER_JUCEHEADER__
|
|
|
|
/** Current Juce version number.
|
|
|
|
See also SystemStats::getJUCEVersion() for a string version.
|
|
*/
|
|
#define JUCE_MAJOR_VERSION 1
|
|
#define JUCE_MINOR_VERSION 50
|
|
|
|
/** Current Juce version number.
|
|
|
|
Bits 16 to 32 = major version.
|
|
Bits 8 to 16 = minor version.
|
|
Bits 0 to 8 = point release (not currently used).
|
|
|
|
See also SystemStats::getJUCEVersion() for a string version.
|
|
*/
|
|
#define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8))
|
|
|
|
/********* Start of inlined file: juce_Config.h *********/
|
|
#ifndef __JUCE_CONFIG_JUCEHEADER__
|
|
#define __JUCE_CONFIG_JUCEHEADER__
|
|
|
|
/*
|
|
This file contains macros that enable/disable various JUCE features.
|
|
*/
|
|
|
|
/** The name of the namespace that all Juce classes and functions will be
|
|
put inside. If this is not defined, no namespace will be used.
|
|
*/
|
|
#ifndef JUCE_NAMESPACE
|
|
#define JUCE_NAMESPACE juce
|
|
#endif
|
|
|
|
/** Normally, JUCE_DEBUG is set to 1 or 0 based on compiler and project settings,
|
|
but if you define this value, you can override this can force it to be true or
|
|
false.
|
|
*/
|
|
#ifndef JUCE_FORCE_DEBUG
|
|
//#define JUCE_FORCE_DEBUG 1
|
|
#endif
|
|
|
|
/** If this flag is enabled, the the jassert and jassertfalse macros will
|
|
always use Logger::writeToLog() to write a message when an assertion happens.
|
|
|
|
Enabling it will also leave this turned on in release builds. When it's disabled,
|
|
however, the jassert and jassertfalse macros will not be compiled in a
|
|
release build.
|
|
|
|
@see jassert, jassertfalse, Logger
|
|
*/
|
|
#ifndef JUCE_LOG_ASSERTIONS
|
|
// #define JUCE_LOG_ASSERTIONS 1
|
|
#endif
|
|
|
|
/** Comment out this macro if you haven't got the Steinberg ASIO SDK, without
|
|
which the ASIOAudioIODevice class can't be built. See the comments in the
|
|
ASIOAudioIODevice class's header file for more info about this.
|
|
|
|
(This only affects a Win32 build)
|
|
*/
|
|
#ifndef JUCE_ASIO
|
|
#define JUCE_ASIO 1
|
|
#endif
|
|
|
|
/** Comment out this macro to disable the Windows WASAPI audio device type.
|
|
*/
|
|
#ifndef JUCE_WASAPI
|
|
// #define JUCE_WASAPI 1
|
|
#endif
|
|
|
|
/** Comment out this macro to disable the Windows WASAPI audio device type.
|
|
*/
|
|
#ifndef JUCE_DIRECTSOUND
|
|
#define JUCE_DIRECTSOUND 1
|
|
#endif
|
|
|
|
/** Comment out this macro to disable building of ALSA device support on Linux.
|
|
*/
|
|
#ifndef JUCE_ALSA
|
|
#define JUCE_ALSA 1
|
|
#endif
|
|
|
|
/** Comment out this macro if you don't want to enable QuickTime or if you don't
|
|
have the SDK installed.
|
|
|
|
If this flag is not enabled, the QuickTimeMovieComponent and QuickTimeAudioFormat
|
|
classes will be unavailable.
|
|
|
|
On Windows, if you enable this, you'll need to have the QuickTime SDK
|
|
installed, and its header files will need to be on your include path.
|
|
*/
|
|
#if ! (defined (JUCE_QUICKTIME) || defined (LINUX) || (defined (_WIN32) && ! defined (_MSC_VER)))
|
|
#define JUCE_QUICKTIME 1
|
|
#endif
|
|
|
|
/** Comment out this macro if you don't want to enable OpenGL or if you don't
|
|
have the appropriate headers and libraries available. If it's not enabled, the
|
|
OpenGLComponent class will be unavailable.
|
|
*/
|
|
#ifndef JUCE_OPENGL
|
|
#define JUCE_OPENGL 1
|
|
#endif
|
|
|
|
/** These flags enable the Ogg-Vorbis and Flac audio formats.
|
|
|
|
If you're not going to need either of these formats, turn off the flags to
|
|
avoid bloating your codebase with them.
|
|
*/
|
|
#ifndef JUCE_USE_FLAC
|
|
#define JUCE_USE_FLAC 1
|
|
#endif
|
|
|
|
#ifndef JUCE_USE_OGGVORBIS
|
|
#define JUCE_USE_OGGVORBIS 1
|
|
#endif
|
|
|
|
/** This flag lets you enable support for CD-burning. You might want to disable
|
|
it to build without the MS SDK under windows.
|
|
*/
|
|
#if (! defined (JUCE_USE_CDBURNER)) && ! (defined (_WIN32) && ! defined (_MSC_VER))
|
|
#define JUCE_USE_CDBURNER 1
|
|
#endif
|
|
|
|
/** Enabling this provides support for cameras, using the CameraDevice class
|
|
*/
|
|
#if JUCE_QUICKTIME && ! defined (JUCE_USE_CAMERA)
|
|
// #define JUCE_USE_CAMERA 1
|
|
#endif
|
|
|
|
/** Enabling this macro means that all regions that get repainted will have a coloured
|
|
line drawn around them.
|
|
|
|
This is handy if you're trying to optimise drawing, because it lets you easily see
|
|
when anything is being repainted unnecessarily.
|
|
*/
|
|
#ifndef JUCE_ENABLE_REPAINT_DEBUGGING
|
|
// #define JUCE_ENABLE_REPAINT_DEBUGGING 1
|
|
#endif
|
|
|
|
/** Enable this under Linux to use Xinerama for multi-monitor support.
|
|
*/
|
|
#ifndef JUCE_USE_XINERAMA
|
|
#define JUCE_USE_XINERAMA 1
|
|
#endif
|
|
|
|
/** Enable this under Linux to use XShm for faster shared-memory rendering.
|
|
*/
|
|
#ifndef JUCE_USE_XSHM
|
|
#define JUCE_USE_XSHM 1
|
|
#endif
|
|
|
|
/** Enabling this builds support for VST audio plugins.
|
|
@see VSTPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_AU
|
|
*/
|
|
#ifndef JUCE_PLUGINHOST_VST
|
|
// #define JUCE_PLUGINHOST_VST 1
|
|
#endif
|
|
|
|
/** Enabling this builds support for AudioUnit audio plugins.
|
|
@see AudioUnitPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_VST
|
|
*/
|
|
#ifndef JUCE_PLUGINHOST_AU
|
|
// #define JUCE_PLUGINHOST_AU 1
|
|
#endif
|
|
|
|
/** 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.
|
|
*/
|
|
#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.
|
|
*/
|
|
#ifndef JUCE_WEB_BROWSER
|
|
#define JUCE_WEB_BROWSER 1
|
|
#endif
|
|
|
|
/** Setting this allows the build to use old Carbon libraries that will be
|
|
deprecated in newer versions of OSX. This is handy for some backwards-compatibility
|
|
reasons.
|
|
*/
|
|
#ifndef JUCE_SUPPORT_CARBON
|
|
#define JUCE_SUPPORT_CARBON 1
|
|
#endif
|
|
|
|
/* These flags let you avoid the direct inclusion of some 3rd-party libs in the
|
|
codebase - you might need to use this if you're linking to some of these libraries
|
|
yourself.
|
|
*/
|
|
#ifndef JUCE_INCLUDE_ZLIB_CODE
|
|
#define JUCE_INCLUDE_ZLIB_CODE 1
|
|
#endif
|
|
|
|
#ifndef JUCE_INCLUDE_FLAC_CODE
|
|
#define JUCE_INCLUDE_FLAC_CODE 1
|
|
#endif
|
|
|
|
#ifndef JUCE_INCLUDE_OGGVORBIS_CODE
|
|
#define JUCE_INCLUDE_OGGVORBIS_CODE 1
|
|
#endif
|
|
|
|
#ifndef JUCE_INCLUDE_PNGLIB_CODE
|
|
#define JUCE_INCLUDE_PNGLIB_CODE 1
|
|
#endif
|
|
|
|
#ifndef JUCE_INCLUDE_JPEGLIB_CODE
|
|
#define JUCE_INCLUDE_JPEGLIB_CODE 1
|
|
#endif
|
|
|
|
/** Enable this to add extra memory-leak info to the new and delete operators.
|
|
|
|
(Currently, this only affects Windows builds in debug mode).
|
|
*/
|
|
#ifndef JUCE_CHECK_MEMORY_LEAKS
|
|
#define JUCE_CHECK_MEMORY_LEAKS 1
|
|
#endif
|
|
|
|
/** Enable this to turn on juce's internal catching of exceptions.
|
|
|
|
Turning it off will avoid any exception catching. With it on, all exceptions
|
|
are passed to the JUCEApplication::unhandledException() callback for logging.
|
|
*/
|
|
#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS
|
|
#define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
|
|
#endif
|
|
|
|
/** If this macro is set, the Juce String class will use unicode as its
|
|
internal representation. If it isn't set, it'll use ANSI.
|
|
*/
|
|
#ifndef JUCE_STRINGS_ARE_UNICODE
|
|
#define JUCE_STRINGS_ARE_UNICODE 1
|
|
#endif
|
|
|
|
#endif
|
|
/********* End of inlined file: juce_Config.h *********/
|
|
|
|
#ifdef JUCE_NAMESPACE
|
|
#define BEGIN_JUCE_NAMESPACE namespace JUCE_NAMESPACE {
|
|
#define END_JUCE_NAMESPACE }
|
|
#else
|
|
#define BEGIN_JUCE_NAMESPACE
|
|
#define END_JUCE_NAMESPACE
|
|
#endif
|
|
|
|
// This sets up the JUCE_WIN32, JUCE_MAC, or JUCE_LINUX macros
|
|
|
|
/********* Start of inlined file: juce_PlatformDefs.h *********/
|
|
#ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__
|
|
#define __JUCE_PLATFORMDEFS_JUCEHEADER__
|
|
|
|
/* This file figures out which platform is being built, and defines some macros
|
|
that the rest of the code can use for OS-specific compilation.
|
|
|
|
Macros that will be set here are:
|
|
|
|
- One of JUCE_WIN32, JUCE_MAC or JUCE_LINUX.
|
|
- Either JUCE_32BIT or JUCE_64BIT, depending on the architecture.
|
|
- Either JUCE_LITTLE_ENDIAN or JUCE_BIG_ENDIAN.
|
|
- Either JUCE_INTEL or JUCE_PPC
|
|
- Either JUCE_GCC or JUCE_MSVC
|
|
|
|
It also includes a set of macros for debug console output and assertions.
|
|
|
|
*/
|
|
|
|
#if (defined (_WIN32) || defined (_WIN64))
|
|
#define JUCE_WIN32 1
|
|
#else
|
|
#if defined (LINUX) || defined (__linux__)
|
|
#define JUCE_LINUX 1
|
|
#else
|
|
#define JUCE_MAC 1
|
|
#endif
|
|
#endif
|
|
|
|
#if JUCE_WIN32
|
|
#ifdef _MSC_VER
|
|
#ifdef _WIN64
|
|
#define JUCE_64BIT 1
|
|
#else
|
|
#define JUCE_32BIT 1
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#define JUCE_DEBUG 1
|
|
#endif
|
|
|
|
/** If defined, this indicates that the processor is little-endian. */
|
|
#define JUCE_LITTLE_ENDIAN 1
|
|
|
|
#define JUCE_INTEL 1
|
|
#endif
|
|
|
|
#if JUCE_MAC
|
|
|
|
#include <CoreFoundation/CoreFoundation.h>
|
|
|
|
#ifndef NDEBUG
|
|
#define JUCE_DEBUG 1
|
|
#endif
|
|
|
|
#ifdef __LITTLE_ENDIAN__
|
|
#define JUCE_LITTLE_ENDIAN 1
|
|
#else
|
|
#define JUCE_BIG_ENDIAN 1
|
|
#endif
|
|
|
|
#if defined (__ppc__) || defined (__ppc64__)
|
|
#define JUCE_PPC 1
|
|
#else
|
|
#define JUCE_INTEL 1
|
|
#endif
|
|
|
|
#ifdef __LP64__
|
|
#define JUCE_64BIT 1
|
|
#else
|
|
#define JUCE_32BIT 1
|
|
#endif
|
|
|
|
#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3)
|
|
#error "Building for OSX 10.2 is no longer supported!"
|
|
#endif
|
|
|
|
#if (! defined (MAC_OS_X_VERSION_10_4)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4)
|
|
#define MACOS_10_3_OR_EARLIER 1
|
|
#endif
|
|
|
|
#if (! defined (MAC_OS_X_VERSION_10_5)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
|
|
#define MACOS_10_4_OR_EARLIER 1
|
|
#endif
|
|
#endif
|
|
|
|
#if JUCE_LINUX
|
|
|
|
#ifdef _DEBUG
|
|
#define JUCE_DEBUG 1
|
|
#endif
|
|
|
|
// Allow override for big-endian Linux platforms
|
|
#ifndef JUCE_BIG_ENDIAN
|
|
#define JUCE_LITTLE_ENDIAN 1
|
|
#endif
|
|
|
|
#if defined (__LP64__) || defined (_LP64)
|
|
#define JUCE_64BIT 1
|
|
#else
|
|
#define JUCE_32BIT 1
|
|
#endif
|
|
|
|
#define JUCE_INTEL 1
|
|
#endif
|
|
|
|
#ifdef JUCE_FORCE_DEBUG
|
|
#undef JUCE_DEBUG
|
|
|
|
#if JUCE_FORCE_DEBUG
|
|
#define JUCE_DEBUG 1
|
|
#endif
|
|
#endif
|
|
|
|
// Compiler type macros.
|
|
|
|
#ifdef __GNUC__
|
|
#define JUCE_GCC 1
|
|
#elif defined (_MSC_VER)
|
|
#define JUCE_MSVC 1
|
|
|
|
#if _MSC_VER >= 1400
|
|
#define JUCE_USE_INTRINSICS 1
|
|
#endif
|
|
#else
|
|
#error unknown compiler
|
|
#endif
|
|
|
|
/** This macro defines the C calling convention used as the standard for Juce calls. */
|
|
#if JUCE_MSVC
|
|
#define JUCE_CALLTYPE __stdcall
|
|
#else
|
|
#define JUCE_CALLTYPE
|
|
#endif
|
|
|
|
// Debugging and assertion macros
|
|
|
|
// (For info about JUCE_LOG_ASSERTIONS, have a look in juce_Config.h)
|
|
#if JUCE_LOG_ASSERTIONS
|
|
#define juce_LogCurrentAssertion juce_LogAssertion (__FILE__, __LINE__);
|
|
#elif defined (JUCE_DEBUG)
|
|
#define juce_LogCurrentAssertion fprintf (stderr, "JUCE Assertion failure in %s, line %d\n", __FILE__, __LINE__);
|
|
#else
|
|
#define juce_LogCurrentAssertion
|
|
#endif
|
|
|
|
#ifdef JUCE_DEBUG
|
|
|
|
// If debugging is enabled..
|
|
|
|
/** Writes a string to the standard error stream.
|
|
|
|
This is only compiled in a debug build.
|
|
|
|
@see Logger::outputDebugString
|
|
*/
|
|
#define DBG(dbgtext) Logger::outputDebugString (dbgtext);
|
|
|
|
/** Printf's a string to the standard error stream.
|
|
|
|
This is only compiled in a debug build.
|
|
|
|
@see Logger::outputDebugString
|
|
*/
|
|
#define DBG_PRINTF(dbgprintf) Logger::outputDebugPrintf dbgprintf;
|
|
|
|
// Assertions..
|
|
|
|
#if JUCE_WIN32 || DOXYGEN
|
|
|
|
#if JUCE_USE_INTRINSICS
|
|
#pragma intrinsic (__debugbreak)
|
|
|
|
/** This will try to break the debugger if one is currently hosting this app.
|
|
@see jassert()
|
|
*/
|
|
#define juce_breakDebugger __debugbreak();
|
|
|
|
#elif JUCE_GCC
|
|
/** This will try to break the debugger if one is currently hosting this app.
|
|
@see jassert()
|
|
*/
|
|
#define juce_breakDebugger asm("int $3");
|
|
#else
|
|
/** This will try to break the debugger if one is currently hosting this app.
|
|
@see jassert()
|
|
*/
|
|
#define juce_breakDebugger { __asm int 3 }
|
|
#endif
|
|
#elif JUCE_MAC
|
|
#define juce_breakDebugger Debugger();
|
|
#elif JUCE_LINUX
|
|
#define juce_breakDebugger kill (0, SIGTRAP);
|
|
#endif
|
|
|
|
/** This will always cause an assertion failure.
|
|
|
|
It is only compiled in a debug build, (unless JUCE_LOG_ASSERTIONS is enabled
|
|
in juce_Config.h).
|
|
|
|
@see jassert()
|
|
*/
|
|
#define jassertfalse { juce_LogCurrentAssertion; if (JUCE_NAMESPACE::juce_isRunningUnderDebugger()) juce_breakDebugger; }
|
|
|
|
/** Platform-independent assertion macro.
|
|
|
|
This gets optimised out when not being built with debugging turned on.
|
|
|
|
Be careful not to call any functions within its arguments that are vital to
|
|
the behaviour of the program, because these won't get called in the release
|
|
build.
|
|
|
|
@see jassertfalse
|
|
*/
|
|
#define jassert(expression) { if (! (expression)) jassertfalse }
|
|
|
|
#else
|
|
|
|
// If debugging is disabled, these dummy debug and assertion macros are used..
|
|
|
|
#define DBG(dbgtext)
|
|
#define DBG_PRINTF(dbgprintf)
|
|
|
|
#define jassertfalse { juce_LogCurrentAssertion }
|
|
|
|
#if JUCE_LOG_ASSERTIONS
|
|
#define jassert(expression) { if (! (expression)) jassertfalse }
|
|
#else
|
|
#define jassert(a) { }
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#ifndef DOXYGEN
|
|
template <bool b> struct JuceStaticAssert;
|
|
template <> struct JuceStaticAssert <true> { static void dummy() {} };
|
|
#endif
|
|
|
|
/** A compile-time assertion macro.
|
|
|
|
If the expression parameter is false, the macro will cause a compile error.
|
|
*/
|
|
#define static_jassert(expression) JuceStaticAssert<expression>::dummy();
|
|
|
|
#if JUCE_CATCH_UNHANDLED_EXCEPTIONS
|
|
|
|
#define JUCE_TRY try
|
|
|
|
/** Used in try-catch blocks, this macro will send exceptions to the JUCEApplication
|
|
object so they can be logged by the application if it wants to.
|
|
*/
|
|
#define JUCE_CATCH_EXCEPTION \
|
|
catch (const std::exception& e) \
|
|
{ \
|
|
JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__); \
|
|
} \
|
|
catch (...) \
|
|
{ \
|
|
JUCEApplication::sendUnhandledException (0, __FILE__, __LINE__); \
|
|
}
|
|
|
|
#define JUCE_CATCH_ALL catch (...) {}
|
|
#define JUCE_CATCH_ALL_ASSERT catch (...) { jassertfalse }
|
|
|
|
#else
|
|
|
|
#define JUCE_TRY
|
|
#define JUCE_CATCH_EXCEPTION
|
|
#define JUCE_CATCH_ALL
|
|
#define JUCE_CATCH_ALL_ASSERT
|
|
|
|
#endif
|
|
|
|
// Macros for inlining.
|
|
|
|
#if JUCE_MSVC
|
|
/** A platform-independent way of forcing an inline function.
|
|
|
|
Use the syntax: @code
|
|
forcedinline void myfunction (int x)
|
|
@endcode
|
|
*/
|
|
#ifdef JUCE_DEBUG
|
|
#define forcedinline __forceinline
|
|
#else
|
|
#define forcedinline inline
|
|
#endif
|
|
|
|
/** A platform-independent way of stopping the compiler inlining a function.
|
|
|
|
Use the syntax: @code
|
|
juce_noinline void myfunction (int x)
|
|
@endcode
|
|
*/
|
|
#define juce_noinline
|
|
|
|
#else
|
|
/** A platform-independent way of forcing an inline function.
|
|
|
|
Use the syntax: @code
|
|
forcedinline void myfunction (int x)
|
|
@endcode
|
|
*/
|
|
#ifndef JUCE_DEBUG
|
|
#define forcedinline inline __attribute__((always_inline))
|
|
#else
|
|
#define forcedinline inline
|
|
#endif
|
|
|
|
/** A platform-independent way of stopping the compiler inlining a function.
|
|
|
|
Use the syntax: @code
|
|
juce_noinline void myfunction (int x)
|
|
@endcode
|
|
*/
|
|
#define juce_noinline __attribute__((noinline))
|
|
|
|
#endif
|
|
|
|
#endif // __JUCE_PLATFORMDEFS_JUCEHEADER__
|
|
/********* End of inlined file: juce_PlatformDefs.h *********/
|
|
|
|
// Now we'll include any OS headers we need.. (at this point we are outside the Juce namespace).
|
|
#if JUCE_MSVC
|
|
#pragma warning (push)
|
|
#pragma warning (disable: 4514 4245 4100)
|
|
#endif
|
|
|
|
#include <cstdlib>
|
|
#include <cstdarg>
|
|
#include <climits>
|
|
#include <cmath>
|
|
#include <cwchar>
|
|
#include <stdexcept>
|
|
#include <typeinfo>
|
|
#include <cstring>
|
|
#include <cstdio>
|
|
|
|
#if JUCE_USE_INTRINSICS
|
|
#include <intrin.h>
|
|
#endif
|
|
|
|
#if JUCE_MAC
|
|
#if MACOS_10_3_OR_EARLIER
|
|
#include <CoreServices/CoreServices.h>
|
|
#else
|
|
#include <libkern/OSAtomic.h>
|
|
#endif
|
|
#endif
|
|
|
|
#if JUCE_LINUX
|
|
#include <signal.h>
|
|
#endif
|
|
|
|
#if JUCE_MSVC && JUCE_DEBUG
|
|
#include <crtdbg.h>
|
|
#endif
|
|
|
|
#if JUCE_MSVC
|
|
#pragma warning (pop)
|
|
#endif
|
|
|
|
// DLL building settings on Win32
|
|
#if JUCE_MSVC
|
|
#ifdef JUCE_DLL_BUILD
|
|
#define JUCE_API __declspec (dllexport)
|
|
#pragma warning (disable: 4251)
|
|
#elif defined (JUCE_DLL)
|
|
#define JUCE_API __declspec (dllimport)
|
|
#pragma warning (disable: 4251)
|
|
#endif
|
|
#elif defined (__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
|
|
#ifdef JUCE_DLL_BUILD
|
|
#define JUCE_API __attribute__ ((visibility("default")))
|
|
#endif
|
|
#endif
|
|
|
|
#ifndef JUCE_API
|
|
/** This macro is added to all juce public class declarations. */
|
|
#define JUCE_API
|
|
#endif
|
|
|
|
/** This macro is added to all juce public function declarations. */
|
|
#define JUCE_PUBLIC_FUNCTION JUCE_API JUCE_CALLTYPE
|
|
|
|
// Now include some basics that are needed by most of the Juce classes...
|
|
BEGIN_JUCE_NAMESPACE
|
|
|
|
extern bool JUCE_API JUCE_CALLTYPE juce_isRunningUnderDebugger() throw();
|
|
|
|
#if JUCE_LOG_ASSERTIONS
|
|
extern void JUCE_API juce_LogAssertion (const char* filename, const int lineNum) throw();
|
|
#endif
|
|
|
|
/********* Start of inlined file: juce_Memory.h *********/
|
|
#ifndef __JUCE_MEMORY_JUCEHEADER__
|
|
#define __JUCE_MEMORY_JUCEHEADER__
|
|
|
|
/*
|
|
This file defines the various juce_malloc(), juce_free() macros that should be used in
|
|
preference to the standard calls.
|
|
*/
|
|
|
|
#if defined (JUCE_DEBUG) && JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS
|
|
#ifndef JUCE_DLL
|
|
|
|
// Win32 debug non-DLL versions..
|
|
|
|
/** This should be used instead of calling malloc directly. */
|
|
#define juce_malloc(numBytes) _malloc_dbg (numBytes, _NORMAL_BLOCK, __FILE__, __LINE__)
|
|
/** This should be used instead of calling calloc directly. */
|
|
#define juce_calloc(numBytes) _calloc_dbg (1, numBytes, _NORMAL_BLOCK, __FILE__, __LINE__)
|
|
/** This should be used instead of calling realloc directly. */
|
|
#define juce_realloc(location, numBytes) _realloc_dbg (location, numBytes, _NORMAL_BLOCK, __FILE__, __LINE__)
|
|
/** This should be used instead of calling free directly. */
|
|
#define juce_free(location) _free_dbg (location, _NORMAL_BLOCK)
|
|
|
|
#else
|
|
|
|
// Win32 debug DLL versions..
|
|
|
|
// For the DLL, we'll define some functions in the DLL that will be used for allocation - that
|
|
// way all juce calls in the DLL and in the host API will all use the same allocator.
|
|
extern JUCE_API void* juce_DebugMalloc (const int size, const char* file, const int line);
|
|
extern JUCE_API void* juce_DebugCalloc (const int size, const char* file, const int line);
|
|
extern JUCE_API void* juce_DebugRealloc (void* const block, const int size, const char* file, const int line);
|
|
extern JUCE_API void juce_DebugFree (void* const block);
|
|
|
|
/** This should be used instead of calling malloc directly. */
|
|
#define juce_malloc(numBytes) JUCE_NAMESPACE::juce_DebugMalloc (numBytes, __FILE__, __LINE__)
|
|
/** This should be used instead of calling calloc directly. */
|
|
#define juce_calloc(numBytes) JUCE_NAMESPACE::juce_DebugCalloc (numBytes, __FILE__, __LINE__)
|
|
/** This should be used instead of calling realloc directly. */
|
|
#define juce_realloc(location, numBytes) JUCE_NAMESPACE::juce_DebugRealloc (location, numBytes, __FILE__, __LINE__)
|
|
/** This should be used instead of calling free directly. */
|
|
#define juce_free(location) JUCE_NAMESPACE::juce_DebugFree (location)
|
|
#endif
|
|
|
|
#if ! defined (_AFXDLL)
|
|
/** This macro can be added to classes to add extra debugging information to the memory
|
|
allocated for them, so you can see the type of objects involved when there's a dump
|
|
of leaked objects at program shutdown. (Only works on win32 at the moment).
|
|
*/
|
|
#define juce_UseDebuggingNewOperator \
|
|
static void* operator new (size_t sz) { void* const p = juce_malloc ((int) sz); return (p != 0) ? p : ::operator new (sz); } \
|
|
static void* operator new (size_t sz, void* p) { return ::operator new (sz, p); } \
|
|
static void operator delete (void* p) { juce_free (p); }
|
|
#endif
|
|
|
|
#elif defined (JUCE_DLL)
|
|
|
|
// Win32 DLL (release) versions..
|
|
|
|
// For the DLL, we'll define some functions in the DLL that will be used for allocation - that
|
|
// way all juce calls in the DLL and in the host API will all use the same allocator.
|
|
extern JUCE_API void* juce_Malloc (const int size);
|
|
extern JUCE_API void* juce_Calloc (const int size);
|
|
extern JUCE_API void* juce_Realloc (void* const block, const int size);
|
|
extern JUCE_API void juce_Free (void* const block);
|
|
|
|
/** This should be used instead of calling malloc directly. */
|
|
#define juce_malloc(numBytes) JUCE_NAMESPACE::juce_Malloc (numBytes)
|
|
/** This should be used instead of calling calloc directly. */
|
|
#define juce_calloc(numBytes) JUCE_NAMESPACE::juce_Calloc (numBytes)
|
|
/** This should be used instead of calling realloc directly. */
|
|
#define juce_realloc(location, numBytes) JUCE_NAMESPACE::juce_Realloc (location, numBytes)
|
|
/** This should be used instead of calling free directly. */
|
|
#define juce_free(location) JUCE_NAMESPACE::juce_Free (location)
|
|
|
|
#define juce_UseDebuggingNewOperator \
|
|
static void* operator new (size_t sz) { void* const p = juce_malloc ((int) sz); return (p != 0) ? p : ::operator new (sz); } \
|
|
static void* operator new (size_t sz, void* p) { return ::operator new (sz, p); } \
|
|
static void operator delete (void* p) { juce_free (p); }
|
|
|
|
#else
|
|
|
|
// Mac, Linux and Win32 (release) versions..
|
|
|
|
/** This should be used instead of calling malloc directly. */
|
|
#define juce_malloc(numBytes) malloc (numBytes)
|
|
/** This should be used instead of calling calloc directly. */
|
|
#define juce_calloc(numBytes) calloc (1, numBytes)
|
|
/** This should be used instead of calling realloc directly. */
|
|
#define juce_realloc(location, numBytes) realloc (location, numBytes)
|
|
/** This should be used instead of calling free directly. */
|
|
#define juce_free(location) free (location)
|
|
|
|
#endif
|
|
|
|
/** This macro can be added to classes to add extra debugging information to the memory
|
|
allocated for them, so you can see the type of objects involved when there's a dump
|
|
of leaked objects at program shutdown. (Only works on win32 at the moment).
|
|
|
|
Note that if you create a class that inherits from a class that uses this macro,
|
|
your class must also use the macro, otherwise you'll probably get compile errors
|
|
because of ambiguous new operators.
|
|
|
|
Most of the JUCE classes use it, so see these for examples of where it should go.
|
|
*/
|
|
#ifndef juce_UseDebuggingNewOperator
|
|
#define juce_UseDebuggingNewOperator
|
|
#endif
|
|
|
|
#if JUCE_MSVC
|
|
/** This is a compiler-indenpendent way of declaring a variable as being thread-local.
|
|
|
|
E.g.
|
|
@code
|
|
juce_ThreadLocal int myVariable;
|
|
@endcode
|
|
*/
|
|
#define juce_ThreadLocal __declspec(thread)
|
|
#else
|
|
#define juce_ThreadLocal __thread
|
|
#endif
|
|
|
|
/** Clears a block of memory. */
|
|
#define zeromem(memory, numBytes) memset (memory, 0, numBytes)
|
|
|
|
/** Clears a reference to a local structure. */
|
|
#define zerostruct(structure) memset (&structure, 0, sizeof (structure))
|
|
|
|
/** A handy macro that calls delete on a pointer if it's non-zero, and
|
|
then sets the pointer to null.
|
|
*/
|
|
#define deleteAndZero(pointer) { delete (pointer); (pointer) = 0; }
|
|
|
|
#endif // __JUCE_MEMORY_JUCEHEADER__
|
|
/********* End of inlined file: juce_Memory.h *********/
|
|
|
|
/********* Start of inlined file: juce_MathsFunctions.h *********/
|
|
#ifndef __JUCE_MATHSFUNCTIONS_JUCEHEADER__
|
|
#define __JUCE_MATHSFUNCTIONS_JUCEHEADER__
|
|
|
|
/*
|
|
This file sets up some handy mathematical typdefs and functions.
|
|
*/
|
|
|
|
// Definitions for the int8, int16, int32, int64 and pointer_sized_int types.
|
|
|
|
/** A platform-independent 8-bit signed integer type. */
|
|
typedef signed char int8;
|
|
/** A platform-independent 8-bit unsigned integer type. */
|
|
typedef unsigned char uint8;
|
|
/** A platform-independent 16-bit signed integer type. */
|
|
typedef signed short int16;
|
|
/** A platform-independent 16-bit unsigned integer type. */
|
|
typedef unsigned short uint16;
|
|
/** A platform-independent 32-bit signed integer type. */
|
|
typedef signed int int32;
|
|
/** A platform-independent 32-bit unsigned integer type. */
|
|
typedef unsigned int uint32;
|
|
|
|
#if JUCE_MSVC
|
|
/** A platform-independent 64-bit integer type. */
|
|
typedef __int64 int64;
|
|
/** A platform-independent 64-bit unsigned integer type. */
|
|
typedef unsigned __int64 uint64;
|
|
/** A platform-independent macro for writing 64-bit literals, needed because
|
|
different compilers have different syntaxes for this.
|
|
|
|
E.g. writing literal64bit (0x1000000000) will translate to 0x1000000000LL for
|
|
GCC, or 0x1000000000 for MSVC.
|
|
*/
|
|
#define literal64bit(longLiteral) ((__int64) longLiteral)
|
|
#else
|
|
/** A platform-independent 64-bit integer type. */
|
|
typedef long long int64;
|
|
/** A platform-independent 64-bit unsigned integer type. */
|
|
typedef unsigned long long uint64;
|
|
/** A platform-independent macro for writing 64-bit literals, needed because
|
|
different compilers have different syntaxes for this.
|
|
|
|
E.g. writing literal64bit (0x1000000000) will translate to 0x1000000000LL for
|
|
GCC, or 0x1000000000 for MSVC.
|
|
*/
|
|
#define literal64bit(longLiteral) (longLiteral##LL)
|
|
#endif
|
|
|
|
#if JUCE_64BIT
|
|
/** A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
|
|
typedef int64 pointer_sized_int;
|
|
/** An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
|
|
typedef uint64 pointer_sized_uint;
|
|
#elif _MSC_VER >= 1300
|
|
/** A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
|
|
typedef _W64 int pointer_sized_int;
|
|
/** An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
|
|
typedef _W64 unsigned int pointer_sized_uint;
|
|
#else
|
|
/** A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
|
|
typedef int pointer_sized_int;
|
|
/** An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
|
|
typedef unsigned int pointer_sized_uint;
|
|
#endif
|
|
|
|
/** A platform-independent unicode character type. */
|
|
typedef wchar_t juce_wchar;
|
|
|
|
// Some indispensible min/max functions
|
|
|
|
/** Returns the larger of two values. */
|
|
forcedinline int jmax (const int a, const int b) throw() { return (a < b) ? b : a; }
|
|
/** Returns the larger of two values. */
|
|
forcedinline int64 jmax (const int64 a, const int64 b) throw() { return (a < b) ? b : a; }
|
|
/** Returns the larger of two values. */
|
|
forcedinline float jmax (const float a, const float b) throw() { return (a < b) ? b : a; }
|
|
/** Returns the larger of two values. */
|
|
forcedinline double jmax (const double a, const double b) throw() { return (a < b) ? b : a; }
|
|
|
|
/** Returns the larger of three values. */
|
|
inline int jmax (const int a, const int b, const int c) throw() { return (a < b) ? ((b < c) ? c : b) : ((a < c) ? c : a); }
|
|
/** Returns the larger of three values. */
|
|
inline int64 jmax (const int64 a, const int64 b, const int64 c) throw() { return (a < b) ? ((b < c) ? c : b) : ((a < c) ? c : a); }
|
|
/** Returns the larger of three values. */
|
|
inline float jmax (const float a, const float b, const float c) throw() { return (a < b) ? ((b < c) ? c : b) : ((a < c) ? c : a); }
|
|
/** Returns the larger of three values. */
|
|
inline double jmax (const double a, const double b, const double c) throw() { return (a < b) ? ((b < c) ? c : b) : ((a < c) ? c : a); }
|
|
|
|
/** Returns the larger of four values. */
|
|
inline int jmax (const int a, const int b, const int c, const int d) throw() { return jmax (a, jmax (b, c, d)); }
|
|
/** Returns the larger of four values. */
|
|
inline int64 jmax (const int64 a, const int64 b, const int64 c, const int64 d) throw() { return jmax (a, jmax (b, c, d)); }
|
|
/** Returns the larger of four values. */
|
|
inline float jmax (const float a, const float b, const float c, const float d) throw() { return jmax (a, jmax (b, c, d)); }
|
|
/** Returns the larger of four values. */
|
|
inline double jmax (const double a, const double b, const double c, const double d) throw() { return jmax (a, jmax (b, c, d)); }
|
|
|
|
/** Returns the smaller of two values. */
|
|
inline int jmin (const int a, const int b) throw() { return (a > b) ? b : a; }
|
|
/** Returns the smaller of two values. */
|
|
inline int64 jmin (const int64 a, const int64 b) throw() { return (a > b) ? b : a; }
|
|
/** Returns the smaller of two values. */
|
|
inline float jmin (const float a, const float b) throw() { return (a > b) ? b : a; }
|
|
/** Returns the smaller of two values. */
|
|
inline double jmin (const double a, const double b) throw() { return (a > b) ? b : a; }
|
|
|
|
/** Returns the smaller of three values. */
|
|
inline int jmin (const int a, const int b, const int c) throw() { return (a > b) ? ((b > c) ? c : b) : ((a > c) ? c : a); }
|
|
/** Returns the smaller of three values. */
|
|
inline int64 jmin (const int64 a, const int64 b, const int64 c) throw() { return (a > b) ? ((b > c) ? c : b) : ((a > c) ? c : a); }
|
|
/** Returns the smaller of three values. */
|
|
inline float jmin (const float a, const float b, const float c) throw() { return (a > b) ? ((b > c) ? c : b) : ((a > c) ? c : a); }
|
|
/** Returns the smaller of three values. */
|
|
inline double jmin (const double a, const double b, const double c) throw() { return (a > b) ? ((b > c) ? c : b) : ((a > c) ? c : a); }
|
|
|
|
/** Returns the smaller of four values. */
|
|
inline int jmin (const int a, const int b, const int c, const int d) throw() { return jmin (a, jmin (b, c, d)); }
|
|
/** Returns the smaller of four values. */
|
|
inline int64 jmin (const int64 a, const int64 b, const int64 c, const int64 d) throw() { return jmin (a, jmin (b, c, d)); }
|
|
/** Returns the smaller of four values. */
|
|
inline float jmin (const float a, const float b, const float c, const float d) throw() { return jmin (a, jmin (b, c, d)); }
|
|
/** Returns the smaller of four values. */
|
|
inline double jmin (const double a, const double b, const double c, const double d) throw() { return jmin (a, jmin (b, c, d)); }
|
|
|
|
/** Constrains a value to keep it within a given range.
|
|
|
|
This will check that the specified value lies between the lower and upper bounds
|
|
specified, and if not, will return the nearest value that would be in-range. Effectively,
|
|
it's like calling jmax (lowerLimit, jmin (upperLimit, value)).
|
|
|
|
Note that it expects that lowerLimit <= upperLimit. If this isn't true,
|
|
the results will be unpredictable.
|
|
|
|
@param lowerLimit the minimum value to return
|
|
@param upperLimit the maximum value to return
|
|
@param valueToConstrain the value to try to return
|
|
@returns the closest value to valueToConstrain which lies between lowerLimit
|
|
and upperLimit (inclusive)
|
|
@see jlimit0To, jmin, jmax
|
|
*/
|
|
template <class Type>
|
|
inline Type jlimit (const Type lowerLimit,
|
|
const Type upperLimit,
|
|
const Type valueToConstrain) throw()
|
|
{
|
|
jassert (lowerLimit <= upperLimit); // if these are in the wrong order, results are unpredictable..
|
|
|
|
return (valueToConstrain < lowerLimit) ? lowerLimit
|
|
: ((valueToConstrain > upperLimit) ? upperLimit
|
|
: valueToConstrain);
|
|
}
|
|
|
|
/** Handy function to swap two values over.
|
|
*/
|
|
template <class Type>
|
|
inline void swapVariables (Type& variable1, Type& variable2) throw()
|
|
{
|
|
const Type tempVal = variable1;
|
|
variable1 = variable2;
|
|
variable2 = tempVal;
|
|
}
|
|
|
|
/** Handy macro for getting the number of elements in a simple const C array.
|
|
|
|
E.g.
|
|
@code
|
|
static int myArray[] = { 1, 2, 3 };
|
|
|
|
int numElements = numElementsInArray (myArray) // returns 3
|
|
@endcode
|
|
*/
|
|
#define numElementsInArray(a) ((int) (sizeof (a) / sizeof ((a)[0])))
|
|
|
|
// Some useful maths functions that aren't always present with all compilers and build settings.
|
|
|
|
#if JUCE_WIN32 || defined (DOXYGEN)
|
|
/** Using juce_hypot and juce_hypotf is easier than dealing with all the different
|
|
versions of these functions of various platforms and compilers. */
|
|
forcedinline double juce_hypot (double a, double b) { return _hypot (a, b); }
|
|
|
|
/** Using juce_hypot and juce_hypotf is easier than dealing with all the different
|
|
versions of these functions of various platforms and compilers. */
|
|
forcedinline float juce_hypotf (float a, float b) { return (float) _hypot (a, b); }
|
|
#else
|
|
/** Using juce_hypot and juce_hypotf is easier than dealing with all the different
|
|
versions of these functions of various platforms and compilers. */
|
|
forcedinline double juce_hypot (double a, double b) { return hypot (a, b); }
|
|
|
|
/** Using juce_hypot and juce_hypotf is easier than dealing with all the different
|
|
versions of these functions of various platforms and compilers. */
|
|
forcedinline float juce_hypotf (float a, float b) { return hypotf (a, b); }
|
|
#endif
|
|
|
|
inline int64 abs64 (const int64 n) throw() { return (n >= 0) ? n : -n; }
|
|
|
|
/** A predefined value for Pi, at double-precision.
|
|
|
|
@see float_Pi
|
|
*/
|
|
const double double_Pi = 3.1415926535897932384626433832795;
|
|
|
|
/** A predefined value for Pi, at sngle-precision.
|
|
|
|
@see double_Pi
|
|
*/
|
|
const float float_Pi = 3.14159265358979323846f;
|
|
|
|
/** The isfinite() method seems to vary greatly between platforms, so this is a
|
|
platform-independent macro for it.
|
|
*/
|
|
#if JUCE_LINUX
|
|
#define juce_isfinite(v) std::isfinite(v)
|
|
#elif JUCE_MAC
|
|
#if MACOS_10_3_OR_EARLIER
|
|
#ifdef isfinite
|
|
#define juce_isfinite(v) isfinite(v)
|
|
#else
|
|
// no idea why the isfinite macro is sometimes impossible to include, so just copy the built-in one..
|
|
static __inline__ int juce_isfinite (double __x) { return __x == __x && __builtin_fabs (__x) != __builtin_inf(); }
|
|
#endif
|
|
#else
|
|
#define juce_isfinite(v) std::isfinite(v)
|
|
#endif
|
|
#elif JUCE_WIN32 && ! defined (isfinite)
|
|
#define juce_isfinite(v) _finite(v)
|
|
#else
|
|
#define juce_isfinite(v) isfinite(v)
|
|
#endif
|
|
|
|
#endif // __JUCE_MATHSFUNCTIONS_JUCEHEADER__
|
|
/********* End of inlined file: juce_MathsFunctions.h *********/
|
|
|
|
/********* Start of inlined file: juce_DataConversions.h *********/
|
|
#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__
|
|
#define __JUCE_DATACONVERSIONS_JUCEHEADER__
|
|
|
|
#if JUCE_USE_INTRINSICS
|
|
#pragma intrinsic (_byteswap_ulong)
|
|
#endif
|
|
|
|
// Endianness conversions..
|
|
|
|
/** Swaps the byte-order in an integer from little to big-endianness or vice-versa. */
|
|
forcedinline uint32 swapByteOrder (uint32 n) throw()
|
|
{
|
|
#if JUCE_MAC
|
|
// Mac version
|
|
return CFSwapInt32 (n);
|
|
#elif JUCE_GCC
|
|
// Inpenetrable GCC version..
|
|
asm("bswap %%eax" : "=a"(n) : "a"(n));
|
|
return n;
|
|
#elif JUCE_USE_INTRINSICS
|
|
// Win32 intrinsics version..
|
|
return _byteswap_ulong (n);
|
|
#else
|
|
// Win32 version..
|
|
__asm {
|
|
mov eax, n
|
|
bswap eax
|
|
mov n, eax
|
|
}
|
|
return n;
|
|
#endif
|
|
}
|
|
|
|
/** Swaps the byte-order of a 16-bit short. */
|
|
inline uint16 swapByteOrder (const uint16 n) throw()
|
|
{
|
|
#if JUCE_USE_INTRINSICSxxx // agh - the MS compiler has an internal error when you try to use this intrinsic!
|
|
// Win32 intrinsics version..
|
|
return (uint16) _byteswap_ushort (n);
|
|
#else
|
|
return (uint16) ((n << 8) | (n >> 8));
|
|
#endif
|
|
}
|
|
|
|
inline uint64 swapByteOrder (const uint64 value) throw()
|
|
{
|
|
#if JUCE_MAC
|
|
return CFSwapInt64 (value);
|
|
#elif JUCE_USE_INTRINSICS
|
|
return _byteswap_uint64 (value);
|
|
#else
|
|
return (((int64) swapByteOrder ((uint32) value)) << 32)
|
|
| swapByteOrder ((uint32) (value >> 32));
|
|
#endif
|
|
}
|
|
|
|
#if JUCE_LITTLE_ENDIAN
|
|
/** Swaps the byte order of a 16-bit int if the CPU is big-endian */
|
|
inline uint16 swapIfBigEndian (const uint16 v) throw() { return v; }
|
|
/** Swaps the byte order of a 32-bit int if the CPU is big-endian */
|
|
inline uint32 swapIfBigEndian (const uint32 v) throw() { return v; }
|
|
/** Swaps the byte order of a 64-bit int if the CPU is big-endian */
|
|
inline uint64 swapIfBigEndian (const uint64 v) throw() { return v; }
|
|
|
|
/** Swaps the byte order of a 16-bit int if the CPU is little-endian */
|
|
inline uint16 swapIfLittleEndian (const uint16 v) throw() { return swapByteOrder (v); }
|
|
/** Swaps the byte order of a 32-bit int if the CPU is little-endian */
|
|
inline uint32 swapIfLittleEndian (const uint32 v) throw() { return swapByteOrder (v); }
|
|
/** Swaps the byte order of a 64-bit int if the CPU is little-endian */
|
|
inline uint64 swapIfLittleEndian (const uint64 v) throw() { return swapByteOrder (v); }
|
|
|
|
/** Turns 4 bytes into a little-endian integer. */
|
|
inline uint32 littleEndianInt (const char* const bytes) throw() { return *(uint32*) bytes; }
|
|
/** Turns 2 bytes into a little-endian integer. */
|
|
inline uint16 littleEndianShort (const char* const bytes) throw() { return *(uint16*) bytes; }
|
|
|
|
/** Turns 4 bytes into a big-endian integer. */
|
|
inline uint32 bigEndianInt (const char* const bytes) throw() { return swapByteOrder (*(uint32*) bytes); }
|
|
/** Turns 2 bytes into a big-endian integer. */
|
|
inline uint16 bigEndianShort (const char* const bytes) throw() { return swapByteOrder (*(uint16*) bytes); }
|
|
|
|
#else
|
|
/** Swaps the byte order of a 16-bit int if the CPU is big-endian */
|
|
inline uint16 swapIfBigEndian (const uint16 v) throw() { return swapByteOrder (v); }
|
|
/** Swaps the byte order of a 32-bit int if the CPU is big-endian */
|
|
inline uint32 swapIfBigEndian (const uint32 v) throw() { return swapByteOrder (v); }
|
|
/** Swaps the byte order of a 64-bit int if the CPU is big-endian */
|
|
inline uint64 swapIfBigEndian (const uint64 v) throw() { return swapByteOrder (v); }
|
|
|
|
/** Swaps the byte order of a 16-bit int if the CPU is little-endian */
|
|
inline uint16 swapIfLittleEndian (const uint16 v) throw() { return v; }
|
|
/** Swaps the byte order of a 32-bit int if the CPU is little-endian */
|
|
inline uint32 swapIfLittleEndian (const uint32 v) throw() { return v; }
|
|
/** Swaps the byte order of a 64-bit int if the CPU is little-endian */
|
|
inline uint64 swapIfLittleEndian (const uint64 v) throw() { return v; }
|
|
|
|
/** Turns 4 bytes into a little-endian integer. */
|
|
inline uint32 littleEndianInt (const char* const bytes) throw() { return swapByteOrder (*(uint32*) bytes); }
|
|
/** Turns 2 bytes into a little-endian integer. */
|
|
inline uint16 littleEndianShort (const char* const bytes) throw() { return swapByteOrder (*(uint16*) bytes); }
|
|
|
|
/** Turns 4 bytes into a big-endian integer. */
|
|
inline uint32 bigEndianInt (const char* const bytes) throw() { return *(uint32*) bytes; }
|
|
/** Turns 2 bytes into a big-endian integer. */
|
|
inline uint16 bigEndianShort (const char* const bytes) throw() { return *(uint16*) bytes; }
|
|
#endif
|
|
|
|
/** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
|
|
inline int littleEndian24Bit (const char* const bytes) throw() { return (((int) bytes[2]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[0]); }
|
|
/** Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
|
|
inline int bigEndian24Bit (const char* const bytes) throw() { return (((int) bytes[0]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[2]); }
|
|
|
|
/** Copies a 24-bit number to 3 little-endian bytes. */
|
|
inline void littleEndian24BitToChars (const int value, char* const destBytes) throw() { destBytes[0] = (char)(value & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)((value >> 16) & 0xff); }
|
|
/** Copies a 24-bit number to 3 big-endian bytes. */
|
|
inline void bigEndian24BitToChars (const int value, char* const destBytes) throw() { destBytes[0] = (char)((value >> 16) & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)(value & 0xff); }
|
|
|
|
/** Fast floating-point-to-integer conversion.
|
|
|
|
This is faster than using the normal c++ cast to convert a double to an int, and
|
|
it will round the value to the nearest integer, rather than rounding it down
|
|
like the normal cast does.
|
|
|
|
Note that this routine gets its speed at the expense of some accuracy, and when
|
|
rounding values whose floating point component is exactly 0.5, odd numbers and
|
|
even numbers will be rounded up or down differently. For a more accurate conversion,
|
|
see roundDoubleToIntAccurate().
|
|
*/
|
|
inline int roundDoubleToInt (const double value) throw()
|
|
{
|
|
union { int asInt[2]; double asDouble; } n;
|
|
n.asDouble = value + 6755399441055744.0;
|
|
|
|
#if JUCE_BIG_ENDIAN
|
|
return n.asInt [1];
|
|
#else
|
|
return n.asInt [0];
|
|
#endif
|
|
}
|
|
|
|
/** Fast floating-point-to-integer conversion.
|
|
|
|
This is a slightly slower and slightly more accurate version of roundDoubleToInt(). It works
|
|
fine for values above zero, but negative numbers are rounded the wrong way.
|
|
*/
|
|
inline int roundDoubleToIntAccurate (const double value) throw()
|
|
{
|
|
return roundDoubleToInt (value + 1.5e-8);
|
|
}
|
|
|
|
/** Fast floating-point-to-integer conversion.
|
|
|
|
This is faster than using the normal c++ cast to convert a float to an int, and
|
|
it will round the value to the nearest integer, rather than rounding it down
|
|
like the normal cast does.
|
|
|
|
Note that this routine gets its speed at the expense of some accuracy, and when
|
|
rounding values whose floating point component is exactly 0.5, odd numbers and
|
|
even numbers will be rounded up or down differently.
|
|
*/
|
|
inline int roundFloatToInt (const float value) throw()
|
|
{
|
|
union { int asInt[2]; double asDouble; } n;
|
|
n.asDouble = value + 6755399441055744.0;
|
|
|
|
#if JUCE_BIG_ENDIAN
|
|
return n.asInt [1];
|
|
#else
|
|
return n.asInt [0];
|
|
#endif
|
|
}
|
|
|
|
#endif // __JUCE_DATACONVERSIONS_JUCEHEADER__
|
|
/********* End of inlined file: juce_DataConversions.h *********/
|
|
|
|
/********* Start of inlined file: juce_Logger.h *********/
|
|
#ifndef __JUCE_LOGGER_JUCEHEADER__
|
|
#define __JUCE_LOGGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_String.h *********/
|
|
#ifndef __JUCE_STRING_JUCEHEADER__
|
|
#define __JUCE_STRING_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_CharacterFunctions.h *********/
|
|
#ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__
|
|
#define __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__
|
|
|
|
/* The String class can either use wchar_t unicode characters, or 8-bit characters
|
|
(in the default system encoding) as its internal representation.
|
|
|
|
To use unicode, define the JUCE_STRINGS_ARE_UNICODE macro in juce_Config.h
|
|
|
|
Be sure to use "tchar" for characters rather than "char", and always wrap string
|
|
literals in the T("abcd") macro, so that it all works nicely either way round.
|
|
*/
|
|
#if JUCE_STRINGS_ARE_UNICODE
|
|
|
|
#define JUCE_T(stringLiteral) (L##stringLiteral)
|
|
typedef juce_wchar tchar;
|
|
#define juce_tcharToWideChar(c) (c)
|
|
|
|
#else
|
|
|
|
#define JUCE_T(stringLiteral) (stringLiteral)
|
|
typedef char tchar;
|
|
#define juce_tcharToWideChar(c) ((juce_wchar) (unsigned char) (c))
|
|
|
|
#endif
|
|
|
|
#if ! JUCE_DONT_DEFINE_MACROS
|
|
|
|
/** The 'T' macro allows a literal string to be compiled using either 8-bit characters
|
|
or unicode.
|
|
|
|
If you write your string literals in the form T("xyz"), this will either be compiled
|
|
as "xyz" for non-unicode builds, or L"xyz" for unicode builds, depending on whether the
|
|
JUCE_STRINGS_ARE_UNICODE macro has been set in juce_Config.h
|
|
|
|
Because the 'T' symbol is occasionally used inside 3rd-party library headers which you
|
|
may need to include after juce.h, you can use the juce_withoutMacros.h file (in
|
|
the juce/src directory) to avoid defining this macro. See the comments in
|
|
juce_withoutMacros.h for more info.
|
|
*/
|
|
#define T(stringLiteral) JUCE_T(stringLiteral)
|
|
|
|
#endif
|
|
|
|
/**
|
|
A set of methods for manipulating characters and character strings, with
|
|
duplicate methods to handle 8-bit and unicode characters.
|
|
|
|
These are defined as wrappers around the basic C string handlers, to provide
|
|
a clean, cross-platform layer, (because various platforms differ in the
|
|
range of C library calls that they provide).
|
|
|
|
@see String
|
|
*/
|
|
class JUCE_API CharacterFunctions
|
|
{
|
|
public:
|
|
static int length (const char* const s) throw();
|
|
static int length (const juce_wchar* const s) throw();
|
|
|
|
static void copy (char* dest, const char* src, const int maxBytes) throw();
|
|
static void copy (juce_wchar* dest, const juce_wchar* src, const int maxChars) throw();
|
|
|
|
static void copy (juce_wchar* dest, const char* src, const int maxChars) throw();
|
|
static void copy (char* dest, const juce_wchar* src, const int maxBytes) throw();
|
|
static int bytesRequiredForCopy (const juce_wchar* src) throw();
|
|
|
|
static void append (char* dest, const char* src) throw();
|
|
static void append (juce_wchar* dest, const juce_wchar* src) throw();
|
|
|
|
static int compare (const char* const s1, const char* const s2) throw();
|
|
static int compare (const juce_wchar* s1, const juce_wchar* s2) throw();
|
|
|
|
static int compare (const char* const s1, const char* const s2, const int maxChars) throw();
|
|
static int compare (const juce_wchar* s1, const juce_wchar* s2, int maxChars) throw();
|
|
|
|
static int compareIgnoreCase (const char* const s1, const char* const s2) throw();
|
|
static int compareIgnoreCase (const juce_wchar* s1, const juce_wchar* s2) throw();
|
|
|
|
static int compareIgnoreCase (const char* const s1, const char* const s2, const int maxChars) throw();
|
|
static int compareIgnoreCase (const juce_wchar* s1, const juce_wchar* s2, int maxChars) throw();
|
|
|
|
static const char* find (const char* const haystack, const char* const needle) throw();
|
|
static const juce_wchar* find (const juce_wchar* haystack, const juce_wchar* const needle) throw();
|
|
|
|
static int indexOfChar (const char* const haystack, const char needle, const bool ignoreCase) throw();
|
|
static int indexOfChar (const juce_wchar* const haystack, const juce_wchar needle, const bool ignoreCase) throw();
|
|
|
|
static int indexOfCharFast (const char* const haystack, const char needle) throw();
|
|
static int indexOfCharFast (const juce_wchar* const haystack, const juce_wchar needle) throw();
|
|
|
|
static int getIntialSectionContainingOnly (const char* const text, const char* const allowedChars) throw();
|
|
static int getIntialSectionContainingOnly (const juce_wchar* const text, const juce_wchar* const allowedChars) throw();
|
|
|
|
static int ftime (char* const dest, const int maxChars, const char* const format, const struct tm* const tm) throw();
|
|
static int ftime (juce_wchar* const dest, const int maxChars, const juce_wchar* const format, const struct tm* const tm) throw();
|
|
|
|
static int getIntValue (const char* const s) throw();
|
|
static int getIntValue (const juce_wchar* s) throw();
|
|
|
|
static int64 getInt64Value (const char* s) throw();
|
|
static int64 getInt64Value (const juce_wchar* s) throw();
|
|
|
|
static double getDoubleValue (const char* const s) throw();
|
|
static double getDoubleValue (const juce_wchar* const s) throw();
|
|
|
|
static char toUpperCase (const char character) throw();
|
|
static juce_wchar toUpperCase (const juce_wchar character) throw();
|
|
static void toUpperCase (char* s) throw();
|
|
|
|
static void toUpperCase (juce_wchar* s) throw();
|
|
static bool isUpperCase (const char character) throw();
|
|
static bool isUpperCase (const juce_wchar character) throw();
|
|
|
|
static char toLowerCase (const char character) throw();
|
|
static juce_wchar toLowerCase (const juce_wchar character) throw();
|
|
static void toLowerCase (char* s) throw();
|
|
static void toLowerCase (juce_wchar* s) throw();
|
|
static bool isLowerCase (const char character) throw();
|
|
static bool isLowerCase (const juce_wchar character) throw();
|
|
|
|
static bool isWhitespace (const char character) throw();
|
|
static bool isWhitespace (const juce_wchar character) throw();
|
|
|
|
static bool isDigit (const char character) throw();
|
|
static bool isDigit (const juce_wchar character) throw();
|
|
|
|
static bool isLetter (const char character) throw();
|
|
static bool isLetter (const juce_wchar character) throw();
|
|
|
|
static bool isLetterOrDigit (const char character) throw();
|
|
static bool isLetterOrDigit (const juce_wchar character) throw();
|
|
|
|
/** Returns 0 to 16 for '0' to 'F", or -1 for characters that aren't a legel
|
|
hex digit.
|
|
*/
|
|
static int getHexDigitValue (const tchar digit) throw();
|
|
|
|
static int printf (char* const dest, const int maxLength, const char* const format, ...) throw();
|
|
static int printf (juce_wchar* const dest, const int maxLength, const juce_wchar* const format, ...) throw();
|
|
|
|
static int vprintf (char* const dest, const int maxLength, const char* const format, va_list& args) throw();
|
|
static int vprintf (juce_wchar* const dest, const int maxLength, const juce_wchar* const format, va_list& args) throw();
|
|
};
|
|
|
|
#endif // __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__
|
|
/********* End of inlined file: juce_CharacterFunctions.h *********/
|
|
|
|
/**
|
|
The JUCE String class!
|
|
|
|
Using a reference-counted internal representation, these strings are fast
|
|
and efficient, and there are methods to do just about any operation you'll ever
|
|
dream of.
|
|
|
|
@see StringArray, StringPairArray
|
|
*/
|
|
class JUCE_API String
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty string.
|
|
|
|
@see empty
|
|
*/
|
|
String() throw();
|
|
|
|
/** Creates a copy of another string. */
|
|
String (const String& other) throw();
|
|
|
|
/** Creates a string from a zero-terminated text string.
|
|
|
|
The string is assumed to be stored in the default system encoding.
|
|
*/
|
|
String (const char* const text) throw();
|
|
|
|
/** Creates a string from an string of characters.
|
|
|
|
This will use up the the first maxChars characters of the string (or
|
|
less if the string is actually shorter)
|
|
*/
|
|
String (const char* const text,
|
|
const int maxChars) throw();
|
|
|
|
/** Creates a string from a zero-terminated unicode text string. */
|
|
String (const juce_wchar* const unicodeText) throw();
|
|
|
|
/** Creates a string from a unicode text string.
|
|
|
|
This will use up the the first maxChars characters of the string (or
|
|
less if the string is actually shorter)
|
|
*/
|
|
String (const juce_wchar* const unicodeText,
|
|
const int maxChars) throw();
|
|
|
|
/** Creates a string from a single character. */
|
|
static const String charToString (const tchar character) throw();
|
|
|
|
/** Destructor. */
|
|
~String() throw();
|
|
|
|
/** This is an empty string that can be used whenever one is needed.
|
|
|
|
It's better to use this than String() because it explains what's going on
|
|
and is more efficient.
|
|
*/
|
|
static const String empty;
|
|
|
|
/** Generates a probably-unique 32-bit hashcode from this string. */
|
|
int hashCode() const throw();
|
|
|
|
/** Generates a probably-unique 64-bit hashcode from this string. */
|
|
int64 hashCode64() const throw();
|
|
|
|
/** Returns the number of characters in the string. */
|
|
int length() const throw();
|
|
|
|
// Assignment and concatenation operators..
|
|
|
|
/** Replaces this string's contents with another string. */
|
|
const String& operator= (const tchar* const other) throw();
|
|
|
|
/** Replaces this string's contents with another string. */
|
|
const String& operator= (const String& other) throw();
|
|
|
|
/** Appends another string at the end of this one. */
|
|
const String& operator+= (const tchar* const textToAppend) throw();
|
|
/** Appends another string at the end of this one. */
|
|
const String& operator+= (const String& stringToAppend) throw();
|
|
/** Appends a character at the end of this string. */
|
|
const String& operator+= (const char characterToAppend) throw();
|
|
/** Appends a character at the end of this string. */
|
|
const String& operator+= (const juce_wchar characterToAppend) throw();
|
|
|
|
/** Appends a string at the end of this one.
|
|
|
|
@param textToAppend the string to add
|
|
@param maxCharsToTake the maximum number of characters to take from the string passed in
|
|
*/
|
|
void append (const tchar* const textToAppend,
|
|
const int maxCharsToTake) throw();
|
|
|
|
/** Appends a string at the end of this one.
|
|
@returns the concatenated string
|
|
*/
|
|
const String operator+ (const String& stringToAppend) const throw();
|
|
|
|
/** Appends a string at the end of this one.
|
|
@returns the concatenated string
|
|
*/
|
|
const String operator+ (const tchar* const textToAppend) const throw();
|
|
|
|
/** Appends a character at the end of this one.
|
|
@returns the concatenated string
|
|
*/
|
|
const String operator+ (const tchar characterToAppend) const throw();
|
|
|
|
/** Appends a character at the end of this string. */
|
|
String& operator<< (const char n) throw();
|
|
/** Appends a character at the end of this string. */
|
|
String& operator<< (const juce_wchar n) throw();
|
|
/** Appends another string at the end of this one. */
|
|
String& operator<< (const char* const text) throw();
|
|
/** Appends another string at the end of this one. */
|
|
String& operator<< (const juce_wchar* const text) throw();
|
|
/** Appends another string at the end of this one. */
|
|
String& operator<< (const String& text) throw();
|
|
|
|
/** Appends a decimal number at the end of this string. */
|
|
String& operator<< (const short number) throw();
|
|
/** Appends a decimal number at the end of this string. */
|
|
String& operator<< (const int number) throw();
|
|
/** Appends a decimal number at the end of this string. */
|
|
String& operator<< (const unsigned int number) throw();
|
|
/** Appends a decimal number at the end of this string. */
|
|
String& operator<< (const float number) throw();
|
|
/** Appends a decimal number at the end of this string. */
|
|
String& operator<< (const double number) throw();
|
|
|
|
// Comparison methods..
|
|
|
|
/** Returns true if the string contains no characters.
|
|
|
|
Note that there's also an isNotEmpty() method to help write readable code.
|
|
|
|
@see containsNonWhitespaceChars()
|
|
*/
|
|
inline bool isEmpty() const throw() { return text->text[0] == 0; }
|
|
|
|
/** Returns true if the string contains at least one character.
|
|
|
|
Note that there's also an isEmpty() method to help write readable code.
|
|
|
|
@see containsNonWhitespaceChars()
|
|
*/
|
|
inline bool isNotEmpty() const throw() { return text->text[0] != 0; }
|
|
|
|
/** Case-sensitive comparison with another string. */
|
|
bool operator== (const String& other) const throw();
|
|
/** Case-sensitive comparison with another string. */
|
|
bool operator== (const tchar* const other) const throw();
|
|
|
|
/** Case-sensitive comparison with another string. */
|
|
bool operator!= (const String& other) const throw();
|
|
/** Case-sensitive comparison with another string. */
|
|
bool operator!= (const tchar* const other) const throw();
|
|
|
|
/** Case-insensitive comparison with another string. */
|
|
bool equalsIgnoreCase (const String& other) const throw();
|
|
/** Case-insensitive comparison with another string. */
|
|
bool equalsIgnoreCase (const tchar* const other) const throw();
|
|
|
|
/** Case-sensitive comparison with another string. */
|
|
bool operator> (const String& other) const throw();
|
|
/** Case-sensitive comparison with another string. */
|
|
bool operator< (const tchar* const other) const throw();
|
|
|
|
/** Case-sensitive comparison with another string. */
|
|
bool operator>= (const String& other) const throw();
|
|
/** Case-sensitive comparison with another string. */
|
|
bool operator<= (const tchar* const other) const throw();
|
|
|
|
/** Case-sensitive comparison with another string.
|
|
@returns 0 if the two strings are identical; negative if this string
|
|
comes before the other one alphabetically, or positive if it
|
|
comes after it.
|
|
*/
|
|
int compare (const tchar* const other) const throw();
|
|
|
|
/** Case-insensitive comparison with another string.
|
|
@returns 0 if the two strings are identical; negative if this string
|
|
comes before the other one alphabetically, or positive if it
|
|
comes after it.
|
|
*/
|
|
int compareIgnoreCase (const tchar* const other) const throw();
|
|
|
|
/** Lexicographic comparison with another string.
|
|
|
|
The comparison used here is case-insensitive and ignores leading non-alphanumeric
|
|
characters, making it good for sorting human-readable strings.
|
|
|
|
@returns 0 if the two strings are identical; negative if this string
|
|
comes before the other one alphabetically, or positive if it
|
|
comes after it.
|
|
*/
|
|
int compareLexicographically (const tchar* const other) const throw();
|
|
|
|
/** Tests whether the string begins with another string.
|
|
|
|
Uses a case-sensitive comparison.
|
|
*/
|
|
bool startsWith (const tchar* const text) const throw();
|
|
|
|
/** Tests whether the string begins with a particular character.
|
|
|
|
Uses a case-sensitive comparison.
|
|
*/
|
|
bool startsWithChar (const tchar character) const throw();
|
|
|
|
/** Tests whether the string begins with another string.
|
|
|
|
Uses a case-insensitive comparison.
|
|
*/
|
|
bool startsWithIgnoreCase (const tchar* const text) const throw();
|
|
|
|
/** Tests whether the string ends with another string.
|
|
|
|
Uses a case-sensitive comparison.
|
|
*/
|
|
bool endsWith (const tchar* const text) const throw();
|
|
|
|
/** Tests whether the string ends with a particular character.
|
|
|
|
Uses a case-sensitive comparison.
|
|
*/
|
|
bool endsWithChar (const tchar character) const throw();
|
|
|
|
/** Tests whether the string ends with another string.
|
|
|
|
Uses a case-insensitive comparison.
|
|
*/
|
|
bool endsWithIgnoreCase (const tchar* const text) const throw();
|
|
|
|
/** Tests whether the string contains another substring.
|
|
|
|
Uses a case-sensitive comparison.
|
|
*/
|
|
bool contains (const tchar* const text) const throw();
|
|
|
|
/** Tests whether the string contains a particular character.
|
|
|
|
Uses a case-sensitive comparison.
|
|
*/
|
|
bool containsChar (const tchar character) const throw();
|
|
|
|
/** Tests whether the string contains another substring.
|
|
|
|
Uses a case-insensitive comparison.
|
|
*/
|
|
bool containsIgnoreCase (const tchar* const text) const throw();
|
|
|
|
/** Tests whether the string contains another substring as a distict word.
|
|
|
|
@returns true if the string contains this word, surrounded by
|
|
non-alphanumeric characters
|
|
@see indexOfWholeWord, containsWholeWordIgnoreCase
|
|
*/
|
|
bool containsWholeWord (const tchar* const wordToLookFor) const throw();
|
|
|
|
/** Tests whether the string contains another substring as a distict word.
|
|
|
|
@returns true if the string contains this word, surrounded by
|
|
non-alphanumeric characters
|
|
@see indexOfWholeWordIgnoreCase, containsWholeWord
|
|
*/
|
|
bool containsWholeWordIgnoreCase (const tchar* const wordToLookFor) const throw();
|
|
|
|
/** Finds an instance of another substring if it exists as a distict word.
|
|
|
|
@returns if the string contains this word, surrounded by non-alphanumeric characters,
|
|
then this will return the index of the start of the substring. If it isn't
|
|
found, then it will return -1
|
|
@see indexOfWholeWordIgnoreCase, containsWholeWord
|
|
*/
|
|
int indexOfWholeWord (const tchar* const wordToLookFor) const throw();
|
|
|
|
/** Finds an instance of another substring if it exists as a distict word.
|
|
|
|
@returns if the string contains this word, surrounded by non-alphanumeric characters,
|
|
then this will return the index of the start of the substring. If it isn't
|
|
found, then it will return -1
|
|
@see indexOfWholeWord, containsWholeWordIgnoreCase
|
|
*/
|
|
int indexOfWholeWordIgnoreCase (const tchar* const wordToLookFor) const throw();
|
|
|
|
/** Looks for any of a set of characters in the string.
|
|
|
|
Uses a case-sensitive comparison.
|
|
|
|
@returns true if the string contains any of the characters from
|
|
the string that is passed in.
|
|
*/
|
|
bool containsAnyOf (const tchar* const charactersItMightContain) const throw();
|
|
|
|
/** Looks for a set of characters in the string.
|
|
|
|
Uses a case-sensitive comparison.
|
|
|
|
@returns true if the all the characters in the string are also found in the
|
|
string that is passed in.
|
|
*/
|
|
bool containsOnly (const tchar* const charactersItMightContain) const throw();
|
|
|
|
/** Returns true if this string contains any non-whitespace characters.
|
|
|
|
This will return false if the string contains only whitespace characters, or
|
|
if it's empty.
|
|
|
|
It is equivalent to calling "myString.trim().isNotEmpty()".
|
|
*/
|
|
bool containsNonWhitespaceChars() const throw();
|
|
|
|
/** Returns true if the string matches this simple wildcard expression.
|
|
|
|
So for example String ("abcdef").matchesWildcard ("*DEF", true) would return true.
|
|
|
|
This isn't a full-blown regex though! The only wildcard characters supported
|
|
are "*" and "?". It's mainly intended for filename pattern matching.
|
|
*/
|
|
bool matchesWildcard (const tchar* wildcard, const bool ignoreCase) const throw();
|
|
|
|
// Substring location methods..
|
|
|
|
/** Searches for a character inside this string.
|
|
|
|
Uses a case-sensitive comparison.
|
|
|
|
@returns the index of the first occurrence of the character in this
|
|
string, or -1 if it's not found.
|
|
*/
|
|
int indexOfChar (const tchar characterToLookFor) const throw();
|
|
|
|
/** Searches for a character inside this string.
|
|
|
|
Uses a case-sensitive comparison.
|
|
|
|
@param startIndex the index from which the search should proceed
|
|
@param characterToLookFor the character to look for
|
|
@returns the index of the first occurrence of the character in this
|
|
string, or -1 if it's not found.
|
|
*/
|
|
int indexOfChar (const int startIndex, const tchar characterToLookFor) const throw();
|
|
|
|
/** Returns the index of the first character that matches one of the characters
|
|
passed-in to this method.
|
|
|
|
This scans the string, beginning from the startIndex supplied, and if it finds
|
|
a character that appears in the string charactersToLookFor, it returns its index.
|
|
|
|
If none of these characters are found, it returns -1.
|
|
|
|
If ignoreCase is true, the comparison will be case-insensitive.
|
|
|
|
@see indexOfChar, lastIndexOfAnyOf
|
|
*/
|
|
int indexOfAnyOf (const tchar* const charactersToLookFor,
|
|
const int startIndex = 0,
|
|
const bool ignoreCase = false) const throw();
|
|
|
|
/** Searches for a substring within this string.
|
|
|
|
Uses a case-sensitive comparison.
|
|
|
|
@returns the index of the first occurrence of this substring, or -1 if it's not found.
|
|
*/
|
|
int indexOf (const tchar* const text) const throw();
|
|
|
|
/** Searches for a substring within this string.
|
|
|
|
Uses a case-sensitive comparison.
|
|
|
|
@param startIndex the index from which the search should proceed
|
|
@param textToLookFor the string to search for
|
|
@returns the index of the first occurrence of this substring, or -1 if it's not found.
|
|
*/
|
|
int indexOf (const int startIndex,
|
|
const tchar* const textToLookFor) const throw();
|
|
|
|
/** Searches for a substring within this string.
|
|
|
|
Uses a case-insensitive comparison.
|
|
|
|
@returns the index of the first occurrence of this substring, or -1 if it's not found.
|
|
*/
|
|
int indexOfIgnoreCase (const tchar* const textToLookFor) const throw();
|
|
|
|
/** Searches for a substring within this string.
|
|
|
|
Uses a case-insensitive comparison.
|
|
|
|
@param startIndex the index from which the search should proceed
|
|
@param textToLookFor the string to search for
|
|
@returns the index of the first occurrence of this substring, or -1 if it's not found.
|
|
*/
|
|
int indexOfIgnoreCase (const int startIndex,
|
|
const tchar* const textToLookFor) const throw();
|
|
|
|
/** Searches for a character inside this string (working backwards from the end of the string).
|
|
|
|
Uses a case-sensitive comparison.
|
|
|
|
@returns the index of the last occurrence of the character in this
|
|
string, or -1 if it's not found.
|
|
*/
|
|
int lastIndexOfChar (const tchar character) const throw();
|
|
|
|
/** Searches for a substring inside this string (working backwards from the end of the string).
|
|
|
|
Uses a case-sensitive comparison.
|
|
|
|
@returns the index of the start of the last occurrence of the
|
|
substring within this string, or -1 if it's not found.
|
|
*/
|
|
int lastIndexOf (const tchar* const textToLookFor) const throw();
|
|
|
|
/** Searches for a substring inside this string (working backwards from the end of the string).
|
|
|
|
Uses a case-insensitive comparison.
|
|
|
|
@returns the index of the start of the last occurrence of the
|
|
substring within this string, or -1 if it's not found.
|
|
*/
|
|
int lastIndexOfIgnoreCase (const tchar* const textToLookFor) const throw();
|
|
|
|
/** Returns the index of the last character in this string that matches one of the
|
|
characters passed-in to this method.
|
|
|
|
This scans the string backwards, starting from its end, and if it finds
|
|
a character that appears in the string charactersToLookFor, it returns its index.
|
|
|
|
If none of these characters are found, it returns -1.
|
|
|
|
If ignoreCase is true, the comparison will be case-insensitive.
|
|
|
|
@see lastIndexOf, indexOfAnyOf
|
|
*/
|
|
int lastIndexOfAnyOf (const tchar* const charactersToLookFor,
|
|
const bool ignoreCase = false) const throw();
|
|
|
|
// Substring extraction and manipulation methods..
|
|
|
|
/** Returns the character at this index in the string.
|
|
|
|
No checks are made to see if the index is within a valid range, so be careful!
|
|
*/
|
|
inline const tchar& operator[] (const int index) const throw() { jassert (((unsigned int) index) <= (unsigned int) length()); return text->text [index]; }
|
|
|
|
/** Returns a character from the string such that it can also be altered.
|
|
|
|
This can be used as a way of easily changing characters in the string.
|
|
|
|
Note that the index passed-in is not checked to see whether it's in-range, so
|
|
be careful when using this.
|
|
*/
|
|
tchar& operator[] (const int index) throw();
|
|
|
|
/** Returns the final character of the string.
|
|
|
|
If the string is empty this will return 0.
|
|
*/
|
|
tchar getLastCharacter() const throw();
|
|
|
|
/** Returns a subsection of the string.
|
|
|
|
If the range specified is beyond the limits of the string, as much as
|
|
possible is returned.
|
|
|
|
@param startIndex the index of the start of the substring needed
|
|
@param endIndex all characters from startIndex up to (but not including)
|
|
this index are returned
|
|
@see fromFirstOccurrenceOf, dropLastCharacters, upToFirstOccurrenceOf
|
|
*/
|
|
const String substring (int startIndex,
|
|
int endIndex) const throw();
|
|
|
|
/** Returns a section of the string, starting from a given position.
|
|
|
|
@param startIndex the first character to include. If this is beyond the end
|
|
of the string, an empty string is returned. If it is zero or
|
|
less, the whole string is returned.
|
|
@returns the substring from startIndex up to the end of the string
|
|
@see dropLastCharacters, fromFirstOccurrenceOf, upToFirstOccurrenceOf, fromLastOccurrenceOf
|
|
*/
|
|
const String substring (const int startIndex) const throw();
|
|
|
|
/** Returns a version of this string with a number of characters removed
|
|
from the end.
|
|
|
|
@param numberToDrop the number of characters to drop from the end of the
|
|
string. If this is greater than the length of the string,
|
|
an empty string will be returned. If zero or less, the
|
|
original string will be returned.
|
|
@see substring, fromFirstOccurrenceOf, upToFirstOccurrenceOf, fromLastOccurrenceOf, getLastCharacter
|
|
*/
|
|
const String dropLastCharacters (const int numberToDrop) const throw();
|
|
|
|
/** Returns a section of the string starting from a given substring.
|
|
|
|
This will search for the first occurrence of the given substring, and
|
|
return the section of the string starting from the point where this is
|
|
found (optionally not including the substring itself).
|
|
|
|
e.g. for the string "123456", fromFirstOccurrenceOf ("34", true) would return "3456", and
|
|
fromFirstOccurrenceOf ("34", false) would return "56".
|
|
|
|
If the substring isn't found, the method will return an empty string.
|
|
|
|
If ignoreCase is true, the comparison will be case-insensitive.
|
|
|
|
@see upToFirstOccurrenceOf, fromLastOccurrenceOf
|
|
*/
|
|
const String fromFirstOccurrenceOf (const tchar* const substringToStartFrom,
|
|
const bool includeSubStringInResult,
|
|
const bool ignoreCase) const throw();
|
|
|
|
/** Returns a section of the string starting from the last occurrence of a given substring.
|
|
|
|
Similar to fromFirstOccurrenceOf(), but using the last occurrence of the substring, and
|
|
unlike fromFirstOccurrenceOf(), if the substring isn't found, this method will
|
|
return the whole of the original string.
|
|
|
|
@see fromFirstOccurrenceOf, upToLastOccurrenceOf
|
|
*/
|
|
const String fromLastOccurrenceOf (const tchar* const substringToFind,
|
|
const bool includeSubStringInResult,
|
|
const bool ignoreCase) const throw();
|
|
|
|
/** Returns the start of this string, up to the first occurrence of a substring.
|
|
|
|
This will search for the first occurrence of a given substring, and then
|
|
return a copy of the string, up to the position of this substring,
|
|
optionally including or excluding the substring itself in the result.
|
|
|
|
e.g. for the string "123456", upTo ("34", false) would return "12", and
|
|
upTo ("34", true) would return "1234".
|
|
|
|
If the substring isn't found, this will return the whole of the original string.
|
|
|
|
@see upToLastOccurrenceOf, fromFirstOccurrenceOf
|
|
*/
|
|
const String upToFirstOccurrenceOf (const tchar* const substringToEndWith,
|
|
const bool includeSubStringInResult,
|
|
const bool ignoreCase) const throw();
|
|
|
|
/** Returns the start of this string, up to the last occurrence of a substring.
|
|
|
|
Similar to upToFirstOccurrenceOf(), but this finds the last occurrence rather than the first.
|
|
|
|
@see upToFirstOccurrenceOf, fromFirstOccurrenceOf
|
|
*/
|
|
const String upToLastOccurrenceOf (const tchar* substringToFind,
|
|
const bool includeSubStringInResult,
|
|
const bool ignoreCase) const throw();
|
|
|
|
/** Returns a copy of this string with any whitespace characters removed from the start and end. */
|
|
const String trim() const throw();
|
|
/** Returns a copy of this string with any whitespace characters removed from the start. */
|
|
const String trimStart() const throw();
|
|
/** Returns a copy of this string with any whitespace characters removed from the end. */
|
|
const String trimEnd() const throw();
|
|
|
|
/** Returns an upper-case version of this string. */
|
|
const String toUpperCase() const throw();
|
|
|
|
/** Returns an lower-case version of this string. */
|
|
const String toLowerCase() const throw();
|
|
|
|
/** Replaces a sub-section of the string with another string.
|
|
|
|
This will return a copy of this string, with a set of characters
|
|
from startIndex to startIndex + numCharsToReplace removed, and with
|
|
a new string inserted in their place.
|
|
|
|
Note that this is a const method, and won't alter the string itself.
|
|
|
|
@param startIndex the first character to remove. If this is beyond the bounds of the string,
|
|
it will be constrained to a valid range.
|
|
@param numCharactersToReplace the number of characters to remove. If zero or less, no
|
|
characters will be taken out.
|
|
@param stringToInsert the new string to insert at startIndex after the characters have been
|
|
removed.
|
|
*/
|
|
const String replaceSection (int startIndex,
|
|
int numCharactersToReplace,
|
|
const tchar* const stringToInsert) const throw();
|
|
|
|
/** Replaces all occurrences of a substring with another string.
|
|
|
|
Returns a copy of this string, with any occurrences of stringToReplace
|
|
swapped for stringToInsertInstead.
|
|
|
|
Note that this is a const method, and won't alter the string itself.
|
|
*/
|
|
const String replace (const tchar* const stringToReplace,
|
|
const tchar* const stringToInsertInstead,
|
|
const bool ignoreCase = false) const throw();
|
|
|
|
/** Returns a string with all occurrences of a character replaced with a different one. */
|
|
const String replaceCharacter (const tchar characterToReplace,
|
|
const tchar characterToInsertInstead) const throw();
|
|
|
|
/** Replaces a set of characters with another set.
|
|
|
|
Returns a string in which each character from charactersToReplace has been replaced
|
|
by the character at the equivalent position in newCharacters (so the two strings
|
|
passed in must be the same length).
|
|
|
|
e.g. translate ("abc", "def") replaces 'a' with 'd', 'b' with 'e', etc.
|
|
|
|
Note that this is a const method, and won't affect the string itself.
|
|
*/
|
|
const String replaceCharacters (const String& charactersToReplace,
|
|
const tchar* const charactersToInsertInstead) const throw();
|
|
|
|
/** Returns a version of this string that only retains a fixed set of characters.
|
|
|
|
This will return a copy of this string, omitting any characters which are not
|
|
found in the string passed-in.
|
|
|
|
e.g. for "1122334455", retainCharacters ("432") would return "223344"
|
|
|
|
Note that this is a const method, and won't alter the string itself.
|
|
*/
|
|
const String retainCharacters (const tchar* const charactersToRetain) const throw();
|
|
|
|
/** Returns a version of this string with a set of characters removed.
|
|
|
|
This will return a copy of this string, omitting any characters which are
|
|
found in the string passed-in.
|
|
|
|
e.g. for "1122334455", removeCharacters ("432") would return "1155"
|
|
|
|
Note that this is a const method, and won't alter the string itself.
|
|
*/
|
|
const String removeCharacters (const tchar* const charactersToRemove) const throw();
|
|
|
|
/** Returns a section from the start of the string that only contains a certain set of characters.
|
|
|
|
This returns the leftmost section of the string, up to (and not including) the
|
|
first character that doesn't appear in the string passed in.
|
|
*/
|
|
const String initialSectionContainingOnly (const tchar* const permittedCharacters) const throw();
|
|
|
|
/** Returns a section from the start of the string that only contains a certain set of characters.
|
|
|
|
This returns the leftmost section of the string, up to (and not including) the
|
|
first character that occurs in the string passed in.
|
|
*/
|
|
const String initialSectionNotContaining (const tchar* const charactersToStopAt) const throw();
|
|
|
|
/** Checks whether the string might be in quotation marks.
|
|
|
|
@returns true if the string begins with a quote character (either a double or single quote).
|
|
It is also true if there is whitespace before the quote, but it doesn't check the end of the string.
|
|
@see unquoted, quoted
|
|
*/
|
|
bool isQuotedString() const throw();
|
|
|
|
/** Removes quotation marks from around the string, (if there are any).
|
|
|
|
Returns a copy of this string with any quotes removed from its ends. Quotes that aren't
|
|
at the ends of the string are not affected. If there aren't any quotes, the original string
|
|
is returned.
|
|
|
|
Note that this is a const method, and won't alter the string itself.
|
|
|
|
@see isQuotedString, quoted
|
|
*/
|
|
const String unquoted() const throw();
|
|
|
|
/** Adds quotation marks around a string.
|
|
|
|
This will return a copy of the string with a quote at the start and end, (but won't
|
|
add the quote if there's already one there, so it's safe to call this on strings that
|
|
may already have quotes around them).
|
|
|
|
Note that this is a const method, and won't alter the string itself.
|
|
|
|
@param quoteCharacter the character to add at the start and end
|
|
@see isQuotedString, unquoted
|
|
*/
|
|
const String quoted (const tchar quoteCharacter = JUCE_T('"')) const throw();
|
|
|
|
/** Writes text into this string, using printf style-arguments.
|
|
|
|
This will replace the contents of the string with the output of this
|
|
formatted printf.
|
|
|
|
Note that using the %s token with a juce string is probably a bad idea, as
|
|
this may expect differect encodings on different platforms.
|
|
|
|
@see formatted
|
|
*/
|
|
void printf (const tchar* const format, ...) throw();
|
|
|
|
/** Returns a string, created using arguments in the style of printf.
|
|
|
|
This will return a string which is the result of a sprintf using the
|
|
arguments passed-in.
|
|
|
|
Note that using the %s token with a juce string is probably a bad idea, as
|
|
this may expect differect encodings on different platforms.
|
|
|
|
@see printf, vprintf
|
|
*/
|
|
static const String formatted (const tchar* const format, ...) throw();
|
|
|
|
/** Writes text into this string, using a printf style, but taking a va_list argument.
|
|
|
|
This will replace the contents of the string with the output of this
|
|
formatted printf. Used by other methods, this is public in case it's
|
|
useful for other purposes where you want to pass a va_list through directly.
|
|
|
|
Note that using the %s token with a juce string is probably a bad idea, as
|
|
this may expect differect encodings on different platforms.
|
|
|
|
@see printf, formatted
|
|
*/
|
|
void vprintf (const tchar* const format, va_list& args) throw();
|
|
|
|
/** Creates a string which is a version of a string repeated and joined together.
|
|
|
|
@param stringToRepeat the string to repeat
|
|
@param numberOfTimesToRepeat how many times to repeat it
|
|
*/
|
|
static const String repeatedString (const tchar* const stringToRepeat,
|
|
int numberOfTimesToRepeat) throw();
|
|
|
|
/** Creates a string from data in an unknown format.
|
|
|
|
This looks at some binary data and tries to guess whether it's Unicode
|
|
or 8-bit characters, then returns a string that represents it correctly.
|
|
|
|
Should be able to handle Unicode endianness correctly, by looking at
|
|
the first two bytes.
|
|
*/
|
|
static const String createStringFromData (const void* const data,
|
|
const int size) throw();
|
|
|
|
// Numeric conversions..
|
|
|
|
/** Creates a string containing this signed 32-bit integer as a decimal number.
|
|
|
|
@see getIntValue, getFloatValue, getDoubleValue, toHexString
|
|
*/
|
|
explicit String (const int decimalInteger) throw();
|
|
|
|
/** Creates a string containing this unsigned 32-bit integer as a decimal number.
|
|
|
|
@see getIntValue, getFloatValue, getDoubleValue, toHexString
|
|
*/
|
|
explicit String (const unsigned int decimalInteger) throw();
|
|
|
|
/** Creates a string containing this signed 16-bit integer as a decimal number.
|
|
|
|
@see getIntValue, getFloatValue, getDoubleValue, toHexString
|
|
*/
|
|
explicit String (const short decimalInteger) throw();
|
|
|
|
/** Creates a string containing this unsigned 16-bit integer as a decimal number.
|
|
|
|
@see getIntValue, getFloatValue, getDoubleValue, toHexString
|
|
*/
|
|
explicit String (const unsigned short decimalInteger) throw();
|
|
|
|
/** Creates a string containing this signed 64-bit integer as a decimal number.
|
|
|
|
@see getLargeIntValue, getFloatValue, getDoubleValue, toHexString
|
|
*/
|
|
explicit String (const int64 largeIntegerValue) throw();
|
|
|
|
/** Creates a string containing this unsigned 64-bit integer as a decimal number.
|
|
|
|
@see getLargeIntValue, getFloatValue, getDoubleValue, toHexString
|
|
*/
|
|
explicit String (const uint64 largeIntegerValue) throw();
|
|
|
|
/** Creates a string representing this floating-point number.
|
|
|
|
@param floatValue the value to convert to a string
|
|
@param numberOfDecimalPlaces if this is > 0, it will format the number using that many
|
|
decimal places, and will not use exponent notation. If 0 or
|
|
less, it will use exponent notation if necessary.
|
|
@see getDoubleValue, getIntValue
|
|
*/
|
|
explicit String (const float floatValue,
|
|
const int numberOfDecimalPlaces = 0) throw();
|
|
|
|
/** Creates a string representing this floating-point number.
|
|
|
|
@param doubleValue the value to convert to a string
|
|
@param numberOfDecimalPlaces if this is > 0, it will format the number using that many
|
|
decimal places, and will not use exponent notation. If 0 or
|
|
less, it will use exponent notation if necessary.
|
|
|
|
@see getFloatValue, getIntValue
|
|
*/
|
|
explicit String (const double doubleValue,
|
|
const int numberOfDecimalPlaces = 0) throw();
|
|
|
|
/** Parses this string to find its numerical value (up to 32 bits in size).
|
|
|
|
@returns the value of the string as a 32 bit signed base-10 integer.
|
|
@see getTrailingIntValue, getHexValue32, getHexValue64
|
|
*/
|
|
int getIntValue() const throw();
|
|
|
|
/** Parses this string to find its numerical value (up to 64 bits in size).
|
|
|
|
@returns the value of the string as a 64 bit signed base-10 integer.
|
|
*/
|
|
int64 getLargeIntValue() const throw();
|
|
|
|
/** Parses a decimal number from the end of the string.
|
|
|
|
This will look for a value at the end of the string.
|
|
e.g. for "321 xyz654" it will return 654; for "2 3 4" it'll return 4.
|
|
|
|
Negative numbers are not handled, so "xyz-5" returns 5.
|
|
|
|
@see getIntValue
|
|
*/
|
|
int getTrailingIntValue() const throw();
|
|
|
|
/** Parses this string as a floating point number.
|
|
|
|
@returns the value of the string as a 32-bit floating point value.
|
|
@see getDoubleValue
|
|
*/
|
|
float getFloatValue() const throw();
|
|
|
|
/** Parses this string as a floating point number.
|
|
|
|
@returns the value of the string as a 64-bit floating point value.
|
|
@see getFloatValue
|
|
*/
|
|
double getDoubleValue() const throw();
|
|
|
|
/** Parses the string as a hexadecimal number.
|
|
|
|
Non-hexadecimal characters in the string are ignored.
|
|
|
|
If the string contains too many characters, then the lowest significant
|
|
digits are returned, e.g. "ffff12345678" would produce 0x12345678.
|
|
|
|
@returns a 32-bit number which is the value of the string in hex.
|
|
*/
|
|
int getHexValue32() const throw();
|
|
|
|
/** Parses the string as a hexadecimal number.
|
|
|
|
Non-hexadecimal characters in the string are ignored.
|
|
|
|
If the string contains too many characters, then the lowest significant
|
|
digits are returned, e.g. "ffff1234567812345678" would produce 0x1234567812345678.
|
|
|
|
@returns a 64-bit number which is the value of the string in hex.
|
|
*/
|
|
int64 getHexValue64() const throw();
|
|
|
|
/** Creates a string representing this 32-bit value in hexadecimal. */
|
|
static const String toHexString (const int number) throw();
|
|
|
|
/** Creates a string representing this 64-bit value in hexadecimal. */
|
|
static const String toHexString (const int64 number) throw();
|
|
|
|
/** Creates a string representing this 16-bit value in hexadecimal. */
|
|
static const String toHexString (const short number) throw();
|
|
|
|
/** Creates a string containing a hex dump of a block of binary data.
|
|
|
|
@param data the binary data to use as input
|
|
@param size how many bytes of data to use
|
|
@param groupSize how many bytes are grouped together before inserting a
|
|
space into the output. e.g. group size 0 has no spaces,
|
|
group size 1 looks like: "be a1 c2 ff", group size 2 looks
|
|
like "bea1 c2ff".
|
|
*/
|
|
static const String toHexString (const unsigned char* data,
|
|
const int size,
|
|
const int groupSize = 1) throw();
|
|
|
|
// Casting to character arrays..
|
|
|
|
#if JUCE_STRINGS_ARE_UNICODE
|
|
/** Returns a version of this string using the default 8-bit system encoding.
|
|
|
|
Because it returns a reference to the string's internal data, the pointer
|
|
that is returned must not be stored anywhere, as it can be deleted whenever the
|
|
string changes.
|
|
*/
|
|
operator const char*() const throw();
|
|
|
|
/** Returns a unicode version of this string.
|
|
|
|
Because it returns a reference to the string's internal data, the pointer
|
|
that is returned must not be stored anywhere, as it can be deleted whenever the
|
|
string changes.
|
|
*/
|
|
inline operator const juce_wchar*() const throw() { return text->text; }
|
|
#else
|
|
/** Returns a version of this string using the default 8-bit system encoding.
|
|
|
|
Because it returns a reference to the string's internal data, the pointer
|
|
that is returned must not be stored anywhere, as it can be deleted whenever the
|
|
string changes.
|
|
*/
|
|
inline operator const char*() const throw() { return text->text; }
|
|
|
|
/** Returns a unicode version of this string.
|
|
|
|
Because it returns a reference to the string's internal data, the pointer
|
|
that is returned must not be stored anywhere, as it can be deleted whenever the
|
|
string changes.
|
|
*/
|
|
operator const juce_wchar*() const throw();
|
|
#endif
|
|
|
|
/** Copies the string to a buffer.
|
|
|
|
@param destBuffer the place to copy it to
|
|
@param maxCharsToCopy the maximum number of characters to copy to the buffer,
|
|
not including the tailing zero, so this shouldn't be
|
|
larger than the size of your destination buffer - 1
|
|
*/
|
|
void copyToBuffer (char* const destBuffer,
|
|
const int maxCharsToCopy) const throw();
|
|
|
|
/** Copies the string to a unicode buffer.
|
|
|
|
@param destBuffer the place to copy it to
|
|
@param maxCharsToCopy the maximum number of characters to copy to the buffer,
|
|
not including the tailing zero, so this shouldn't be
|
|
larger than the size of your destination buffer - 1
|
|
*/
|
|
void copyToBuffer (juce_wchar* const destBuffer,
|
|
const int maxCharsToCopy) const throw();
|
|
|
|
/** Copies the string to a buffer as UTF-8 characters.
|
|
|
|
Returns the number of bytes copied to the buffer, including the terminating null
|
|
character.
|
|
|
|
@param destBuffer the place to copy it to; if this is a null pointer,
|
|
the method just returns the number of bytes required
|
|
(including the terminating null character).
|
|
@param maxBufferSizeBytes the size of the destination buffer, in bytes. If the
|
|
string won't fit, it'll put in as many as it can while
|
|
still allowing for a terminating null char at the end,
|
|
and will return the number of bytes that were actually
|
|
used. If this value is < 0, no limit is used.
|
|
*/
|
|
int copyToUTF8 (uint8* const destBuffer, const int maxBufferSizeBytes = 0x7fffffff) const throw();
|
|
|
|
/** Returns a pointer to a UTF-8 version of this string.
|
|
|
|
Because it returns a reference to the string's internal data, the pointer
|
|
that is returned must not be stored anywhere, as it can be deleted whenever the
|
|
string changes.
|
|
*/
|
|
const char* toUTF8() const throw();
|
|
|
|
/** Creates a String from a UTF-8 encoded buffer.
|
|
|
|
If the size is < 0, it'll keep reading until it hits a zero.
|
|
*/
|
|
static const String fromUTF8 (const uint8* const utf8buffer,
|
|
int bufferSizeBytes = -1) throw();
|
|
|
|
/** Increases the string's internally allocated storage.
|
|
|
|
Although the string's contents won't be affected by this call, it will
|
|
increase the amount of memory allocated internally for the string to grow into.
|
|
|
|
If you're about to make a large number of calls to methods such
|
|
as += or <<, it's more efficient to preallocate enough extra space
|
|
beforehand, so that these methods won't have to keep resizing the string
|
|
to append the extra characters.
|
|
|
|
@param numCharsNeeded the number of characters to allocate storage for. If this
|
|
value is less than the currently allocated size, it will
|
|
have no effect.
|
|
*/
|
|
void preallocateStorage (const int numCharsNeeded) throw();
|
|
|
|
juce_UseDebuggingNewOperator // (adds debugging info to find leaked objects)
|
|
|
|
private:
|
|
|
|
struct InternalRefCountedStringHolder
|
|
{
|
|
int refCount;
|
|
int allocatedNumChars;
|
|
|
|
#if JUCE_STRINGS_ARE_UNICODE
|
|
wchar_t text[1];
|
|
#else
|
|
char text[1];
|
|
#endif
|
|
};
|
|
|
|
InternalRefCountedStringHolder* text;
|
|
static InternalRefCountedStringHolder emptyString;
|
|
|
|
// internal constructor that preallocates a certain amount of memory
|
|
String (const int numChars, const int dummyVariable) throw();
|
|
|
|
void deleteInternal() throw();
|
|
void createInternal (const int numChars) throw();
|
|
void createInternal (const tchar* const text, const tchar* const textEnd) throw();
|
|
void appendInternal (const tchar* const text, const int numExtraChars) throw();
|
|
void doubleToStringWithDecPlaces (double n, int numDecPlaces) throw();
|
|
void dupeInternalIfMultiplyReferenced() throw();
|
|
};
|
|
|
|
/** Global operator to allow a String to be appended to a string literal.
|
|
|
|
This allows the use of expressions such as "abc" + String (x)
|
|
|
|
@see String
|
|
*/
|
|
const String JUCE_PUBLIC_FUNCTION operator+ (const char* const string1,
|
|
const String& string2) throw();
|
|
|
|
/** Global operator to allow a String to be appended to a string literal.
|
|
|
|
This allows the use of expressions such as "abc" + String (x)
|
|
|
|
@see String
|
|
*/
|
|
const String JUCE_PUBLIC_FUNCTION operator+ (const juce_wchar* const string1,
|
|
const String& string2) throw();
|
|
|
|
#endif // __JUCE_STRING_JUCEHEADER__
|
|
/********* End of inlined file: juce_String.h *********/
|
|
|
|
/**
|
|
Acts as an application-wide logging class.
|
|
|
|
A subclass of Logger can be created and passed into the Logger::setCurrentLogger
|
|
method and this will then be used by all calls to writeToLog.
|
|
|
|
The logger class also contains methods for writing messages to the debugger's
|
|
output stream.
|
|
|
|
@see FileLogger
|
|
*/
|
|
class JUCE_API Logger
|
|
{
|
|
public:
|
|
|
|
/** Destructor. */
|
|
virtual ~Logger();
|
|
|
|
/** Sets the current logging class to use.
|
|
|
|
Note that the object passed in won't be deleted when no longer needed.
|
|
A null pointer can be passed-in to disable any logging.
|
|
|
|
If deleteOldLogger is set to true, the existing logger will be
|
|
deleted (if there is one).
|
|
*/
|
|
static void JUCE_CALLTYPE setCurrentLogger (Logger* const newLogger,
|
|
const bool deleteOldLogger = false);
|
|
|
|
/** Writes a string to the current logger.
|
|
|
|
This will pass the string to the logger's logMessage() method if a logger
|
|
has been set.
|
|
|
|
@see logMessage
|
|
*/
|
|
static void JUCE_CALLTYPE writeToLog (const String& message);
|
|
|
|
/** Writes a message to the standard error stream.
|
|
|
|
This can be called directly, or by using the DBG() macro in
|
|
juce_PlatformDefs.h (which will avoid calling the method in non-debug builds).
|
|
*/
|
|
static void JUCE_CALLTYPE outputDebugString (const String& text) throw();
|
|
|
|
/** Writes a message to the standard error stream.
|
|
|
|
This can be called directly, or by using the DBG_PRINTF() macro in
|
|
juce_PlatformDefs.h (which will avoid calling the method in non-debug builds).
|
|
*/
|
|
static void JUCE_CALLTYPE outputDebugPrintf (const tchar* format, ...) throw();
|
|
|
|
protected:
|
|
|
|
Logger();
|
|
|
|
/** This is overloaded by subclasses to implement custom logging behaviour.
|
|
|
|
@see setCurrentLogger
|
|
*/
|
|
virtual void logMessage (const String& message) = 0;
|
|
};
|
|
|
|
#endif // __JUCE_LOGGER_JUCEHEADER__
|
|
/********* End of inlined file: juce_Logger.h *********/
|
|
|
|
END_JUCE_NAMESPACE
|
|
|
|
#endif // __JUCE_STANDARDHEADER_JUCEHEADER__
|
|
/********* End of inlined file: juce_StandardHeader.h *********/
|
|
|
|
BEGIN_JUCE_NAMESPACE
|
|
|
|
#if JUCE_MSVC
|
|
// this is set explicitly in case the app is using a different packing size.
|
|
#pragma pack (push, 8)
|
|
#pragma warning (push)
|
|
#pragma warning (disable: 4786) // (old vc6 warning about long class names)
|
|
#endif
|
|
|
|
#if JUCE_MAC
|
|
#pragma align=natural
|
|
#endif
|
|
|
|
#define JUCE_PUBLIC_INCLUDES
|
|
|
|
// this is where all the class header files get brought in..
|
|
|
|
/********* Start of inlined file: juce_core_includes.h *********/
|
|
#ifndef __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__
|
|
#define __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__
|
|
|
|
#ifndef __JUCE_ATOMIC_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Atomic.h *********/
|
|
#ifndef __JUCE_ATOMIC_JUCEHEADER__
|
|
#define __JUCE_ATOMIC_JUCEHEADER__
|
|
|
|
// Atomic increment/decrement operations..
|
|
|
|
#if JUCE_MAC && ! DOXYGEN
|
|
|
|
#if ! MACOS_10_3_OR_EARLIER
|
|
|
|
forcedinline void atomicIncrement (int& variable) throw() { OSAtomicIncrement32 ((int32_t*) &variable); }
|
|
forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OSAtomicIncrement32 ((int32_t*) &variable); }
|
|
forcedinline void atomicDecrement (int& variable) throw() { OSAtomicDecrement32 ((int32_t*) &variable); }
|
|
forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OSAtomicDecrement32 ((int32_t*) &variable); }
|
|
#else
|
|
|
|
forcedinline void atomicIncrement (int& variable) throw() { OTAtomicAdd32 (1, (SInt32*) &variable); }
|
|
forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OTAtomicAdd32 (1, (SInt32*) &variable); }
|
|
forcedinline void atomicDecrement (int& variable) throw() { OTAtomicAdd32 (-1, (SInt32*) &variable); }
|
|
forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OTAtomicAdd32 (-1, (SInt32*) &variable); }
|
|
#endif
|
|
|
|
#elif JUCE_GCC
|
|
|
|
#if JUCE_USE_GCC_ATOMIC_INTRINSICS
|
|
forcedinline void atomicIncrement (int& variable) throw() { __sync_add_and_fetch (&variable, 1); }
|
|
forcedinline int atomicIncrementAndReturn (int& variable) throw() { return __sync_add_and_fetch (&variable, 1); }
|
|
forcedinline void atomicDecrement (int& variable) throw() { __sync_add_and_fetch (&variable, -1); }
|
|
forcedinline int atomicDecrementAndReturn (int& variable) throw() { return __sync_add_and_fetch (&variable, -1); }
|
|
#else
|
|
|
|
/** Increments an integer in a thread-safe way. */
|
|
forcedinline void atomicIncrement (int& variable) throw()
|
|
{
|
|
__asm__ __volatile__ (
|
|
#if JUCE_64BIT
|
|
"lock incl (%%rax)"
|
|
:
|
|
: "a" (&variable)
|
|
: "cc", "memory");
|
|
#else
|
|
"lock incl %0"
|
|
: "=m" (variable)
|
|
: "m" (variable));
|
|
#endif
|
|
}
|
|
|
|
/** Increments an integer in a thread-safe way and returns the incremented value. */
|
|
forcedinline int atomicIncrementAndReturn (int& variable) throw()
|
|
{
|
|
int result;
|
|
|
|
__asm__ __volatile__ (
|
|
#if JUCE_64BIT
|
|
"lock xaddl %%ebx, (%%rax) \n\
|
|
incl %%ebx"
|
|
: "=b" (result)
|
|
: "a" (&variable), "b" (1)
|
|
: "cc", "memory");
|
|
#else
|
|
"lock xaddl %%eax, (%%ecx) \n\
|
|
incl %%eax"
|
|
: "=a" (result)
|
|
: "c" (&variable), "a" (1)
|
|
: "memory");
|
|
#endif
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Decrememts an integer in a thread-safe way. */
|
|
forcedinline void atomicDecrement (int& variable) throw()
|
|
{
|
|
__asm__ __volatile__ (
|
|
#if JUCE_64BIT
|
|
"lock decl (%%rax)"
|
|
:
|
|
: "a" (&variable)
|
|
: "cc", "memory");
|
|
#else
|
|
"lock decl %0"
|
|
: "=m" (variable)
|
|
: "m" (variable));
|
|
#endif
|
|
}
|
|
|
|
/** Decrememts an integer in a thread-safe way and returns the incremented value. */
|
|
forcedinline int atomicDecrementAndReturn (int& variable) throw()
|
|
{
|
|
int result;
|
|
|
|
__asm__ __volatile__ (
|
|
#if JUCE_64BIT
|
|
"lock xaddl %%ebx, (%%rax) \n\
|
|
decl %%ebx"
|
|
: "=b" (result)
|
|
: "a" (&variable), "b" (-1)
|
|
: "cc", "memory");
|
|
#else
|
|
"lock xaddl %%eax, (%%ecx) \n\
|
|
decl %%eax"
|
|
: "=a" (result)
|
|
: "c" (&variable), "a" (-1)
|
|
: "memory");
|
|
#endif
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
#elif JUCE_USE_INTRINSICS
|
|
|
|
#pragma intrinsic (_InterlockedIncrement)
|
|
#pragma intrinsic (_InterlockedDecrement)
|
|
|
|
/** Increments an integer in a thread-safe way. */
|
|
forcedinline void __fastcall atomicIncrement (int& variable) throw()
|
|
{
|
|
_InterlockedIncrement (reinterpret_cast <volatile long*> (&variable));
|
|
}
|
|
|
|
/** Increments an integer in a thread-safe way and returns the incremented value. */
|
|
forcedinline int __fastcall atomicIncrementAndReturn (int& variable) throw()
|
|
{
|
|
return _InterlockedIncrement (reinterpret_cast <volatile long*> (&variable));
|
|
}
|
|
|
|
/** Decrememts an integer in a thread-safe way. */
|
|
forcedinline void __fastcall atomicDecrement (int& variable) throw()
|
|
{
|
|
_InterlockedDecrement (reinterpret_cast <volatile long*> (&variable));
|
|
}
|
|
|
|
/** Decrememts an integer in a thread-safe way and returns the incremented value. */
|
|
forcedinline int __fastcall atomicDecrementAndReturn (int& variable) throw()
|
|
{
|
|
return _InterlockedDecrement (reinterpret_cast <volatile long*> (&variable));
|
|
}
|
|
#else
|
|
|
|
/** Increments an integer in a thread-safe way. */
|
|
forcedinline void __fastcall atomicIncrement (int& variable) throw()
|
|
{
|
|
__asm {
|
|
mov ecx, dword ptr [variable]
|
|
lock inc dword ptr [ecx]
|
|
}
|
|
}
|
|
|
|
/** Increments an integer in a thread-safe way and returns the incremented value. */
|
|
forcedinline int __fastcall atomicIncrementAndReturn (int& variable) throw()
|
|
{
|
|
int result;
|
|
|
|
__asm {
|
|
mov ecx, dword ptr [variable]
|
|
mov eax, 1
|
|
lock xadd dword ptr [ecx], eax
|
|
inc eax
|
|
mov result, eax
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Decrememts an integer in a thread-safe way. */
|
|
forcedinline void __fastcall atomicDecrement (int& variable) throw()
|
|
{
|
|
__asm {
|
|
mov ecx, dword ptr [variable]
|
|
lock dec dword ptr [ecx]
|
|
}
|
|
}
|
|
|
|
/** Decrememts an integer in a thread-safe way and returns the incremented value. */
|
|
forcedinline int __fastcall atomicDecrementAndReturn (int& variable) throw()
|
|
{
|
|
int result;
|
|
|
|
__asm {
|
|
mov ecx, dword ptr [variable]
|
|
mov eax, -1
|
|
lock xadd dword ptr [ecx], eax
|
|
dec eax
|
|
mov result, eax
|
|
}
|
|
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
#endif // __JUCE_ATOMIC_JUCEHEADER__
|
|
/********* End of inlined file: juce_Atomic.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILELOGGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileLogger.h *********/
|
|
#ifndef __JUCE_FILELOGGER_JUCEHEADER__
|
|
#define __JUCE_FILELOGGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_File.h *********/
|
|
#ifndef __JUCE_FILE_JUCEHEADER__
|
|
#define __JUCE_FILE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_OwnedArray.h *********/
|
|
#ifndef __JUCE_OWNEDARRAY_JUCEHEADER__
|
|
#define __JUCE_OWNEDARRAY_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ArrayAllocationBase.h *********/
|
|
#ifndef __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__
|
|
#define __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__
|
|
|
|
/** The default size of chunk in which arrays increase their storage.
|
|
|
|
Used by ArrayAllocationBase and its subclasses.
|
|
*/
|
|
const int juceDefaultArrayGranularity = 8;
|
|
|
|
/**
|
|
Implements some basic array storage allocation functions.
|
|
|
|
This class isn't really for public use - it's used by the other
|
|
array classes, but might come in handy for some purposes.
|
|
|
|
@see Array, OwnedArray, ReferenceCountedArray
|
|
*/
|
|
template <class ElementType>
|
|
class ArrayAllocationBase
|
|
{
|
|
protected:
|
|
|
|
/** Creates an empty array.
|
|
|
|
@param granularity_ this is the size of increment by which the internal storage
|
|
will be increased.
|
|
*/
|
|
ArrayAllocationBase (const int granularity_) throw()
|
|
: elements (0),
|
|
numAllocated (0),
|
|
granularity (granularity_)
|
|
{
|
|
jassert (granularity > 0);
|
|
}
|
|
|
|
/** Destructor. */
|
|
~ArrayAllocationBase() throw()
|
|
{
|
|
delete[] elements;
|
|
}
|
|
|
|
/** Changes the amount of storage allocated.
|
|
|
|
This will retain any data currently held in the array, and either add or
|
|
remove extra space at the end.
|
|
|
|
@param numElements the number of elements that are needed
|
|
*/
|
|
void setAllocatedSize (const int numElements) throw()
|
|
{
|
|
if (numAllocated != numElements)
|
|
{
|
|
if (numElements > 0)
|
|
{
|
|
ElementType* const newElements = new ElementType [numElements];
|
|
|
|
const int itemsToRetain = jmin (numElements, numAllocated);
|
|
|
|
for (int i = 0; i < itemsToRetain; ++i)
|
|
newElements[i] = elements[i];
|
|
|
|
delete[] elements;
|
|
elements = newElements;
|
|
|
|
}
|
|
else if (elements != 0)
|
|
{
|
|
delete[] elements;
|
|
elements = 0;
|
|
}
|
|
|
|
numAllocated = numElements;
|
|
}
|
|
}
|
|
|
|
/** Increases the amount of storage allocated if it is less than a given amount.
|
|
|
|
This will retain any data currently held in the array, but will add
|
|
extra space at the end to make sure there it's at least as big as the size
|
|
passed in. If it's already bigger, no action is taken.
|
|
|
|
@param minNumElements the minimum number of elements that are needed
|
|
*/
|
|
void ensureAllocatedSize (int minNumElements) throw()
|
|
{
|
|
if (minNumElements > numAllocated)
|
|
{
|
|
// for arrays with small granularity that get big, start
|
|
// increasing the size in bigger jumps
|
|
if (minNumElements > (granularity << 6))
|
|
{
|
|
minNumElements += (minNumElements / granularity);
|
|
if (minNumElements > (granularity << 8))
|
|
minNumElements += granularity << 6;
|
|
else
|
|
minNumElements += granularity << 5;
|
|
}
|
|
|
|
setAllocatedSize (granularity * (minNumElements / granularity + 1));
|
|
}
|
|
}
|
|
|
|
ElementType* elements;
|
|
int numAllocated, granularity;
|
|
|
|
private:
|
|
ArrayAllocationBase (const ArrayAllocationBase&);
|
|
const ArrayAllocationBase& operator= (const ArrayAllocationBase&);
|
|
};
|
|
|
|
#endif // __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__
|
|
/********* End of inlined file: juce_ArrayAllocationBase.h *********/
|
|
|
|
/********* Start of inlined file: juce_ElementComparator.h *********/
|
|
#ifndef __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__
|
|
#define __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__
|
|
|
|
/**
|
|
Sorts a range of elements in an array.
|
|
|
|
The comparator object that is passed-in must define a public method with the following
|
|
signature:
|
|
@code
|
|
int compareElements (ElementType first, ElementType second);
|
|
@endcode
|
|
|
|
..and this method must return:
|
|
- a value of < 0 if the first comes before the second
|
|
- a value of 0 if the two objects are equivalent
|
|
- a value of > 0 if the second comes before the first
|
|
|
|
To improve performance, the compareElements() method can be declared as static or const.
|
|
|
|
@param comparator an object which defines a compareElements() method
|
|
@param array the array to sort
|
|
@param firstElement the index of the first element of the range to be sorted
|
|
@param lastElement the index of the last element in the range that needs
|
|
sorting (this is inclusive)
|
|
@param retainOrderOfEquivalentItems if true, the order of items that the
|
|
comparator deems the same will be maintained - this will be
|
|
a slower algorithm than if they are allowed to be moved around.
|
|
|
|
@see sortArrayRetainingOrder
|
|
*/
|
|
template <class ElementType, class ElementComparator>
|
|
static void sortArray (ElementComparator& comparator,
|
|
ElementType* const array,
|
|
int firstElement,
|
|
int lastElement,
|
|
const bool retainOrderOfEquivalentItems)
|
|
{
|
|
(void) comparator; // if you pass in an object with a static compareElements() method, this
|
|
// avoids getting warning messages about the parameter being unused
|
|
|
|
if (lastElement > firstElement)
|
|
{
|
|
if (retainOrderOfEquivalentItems)
|
|
{
|
|
for (int i = firstElement; i < lastElement; ++i)
|
|
{
|
|
if (comparator.compareElements (array[i], array [i + 1]) > 0)
|
|
{
|
|
const ElementType temp = array [i];
|
|
array [i] = array[i + 1];
|
|
array [i + 1] = temp;
|
|
|
|
if (i > firstElement)
|
|
i -= 2;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int fromStack[30], toStack[30];
|
|
int stackIndex = 0;
|
|
|
|
for (;;)
|
|
{
|
|
const int size = (lastElement - firstElement) + 1;
|
|
|
|
if (size <= 8)
|
|
{
|
|
int j = lastElement;
|
|
int maxIndex;
|
|
|
|
while (j > firstElement)
|
|
{
|
|
maxIndex = firstElement;
|
|
for (int k = firstElement + 1; k <= j; ++k)
|
|
if (comparator.compareElements (array[k], array [maxIndex]) > 0)
|
|
maxIndex = k;
|
|
|
|
const ElementType temp = array [maxIndex];
|
|
array [maxIndex] = array[j];
|
|
array [j] = temp;
|
|
|
|
--j;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const int mid = firstElement + (size >> 1);
|
|
ElementType temp = array [mid];
|
|
array [mid] = array [firstElement];
|
|
array [firstElement] = temp;
|
|
|
|
int i = firstElement;
|
|
int j = lastElement + 1;
|
|
|
|
for (;;)
|
|
{
|
|
while (++i <= lastElement
|
|
&& comparator.compareElements (array[i], array [firstElement]) <= 0)
|
|
{}
|
|
|
|
while (--j > firstElement
|
|
&& comparator.compareElements (array[j], array [firstElement]) >= 0)
|
|
{}
|
|
|
|
if (j < i)
|
|
break;
|
|
|
|
temp = array[i];
|
|
array[i] = array[j];
|
|
array[j] = temp;
|
|
}
|
|
|
|
temp = array [firstElement];
|
|
array [firstElement] = array[j];
|
|
array [j] = temp;
|
|
|
|
if (j - 1 - firstElement >= lastElement - i)
|
|
{
|
|
if (firstElement + 1 < j)
|
|
{
|
|
fromStack [stackIndex] = firstElement;
|
|
toStack [stackIndex] = j - 1;
|
|
++stackIndex;
|
|
}
|
|
|
|
if (i < lastElement)
|
|
{
|
|
firstElement = i;
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (i < lastElement)
|
|
{
|
|
fromStack [stackIndex] = i;
|
|
toStack [stackIndex] = lastElement;
|
|
++stackIndex;
|
|
}
|
|
|
|
if (firstElement + 1 < j)
|
|
{
|
|
lastElement = j - 1;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (--stackIndex < 0)
|
|
break;
|
|
|
|
jassert (stackIndex < numElementsInArray (fromStack));
|
|
|
|
firstElement = fromStack [stackIndex];
|
|
lastElement = toStack [stackIndex];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
Searches a sorted array of elements, looking for the index at which a specified value
|
|
should be inserted for it to be in the correct order.
|
|
|
|
The comparator object that is passed-in must define a public method with the following
|
|
signature:
|
|
@code
|
|
int compareElements (ElementType first, ElementType second);
|
|
@endcode
|
|
|
|
..and this method must return:
|
|
- a value of < 0 if the first comes before the second
|
|
- a value of 0 if the two objects are equivalent
|
|
- a value of > 0 if the second comes before the first
|
|
|
|
To improve performance, the compareElements() method can be declared as static or const.
|
|
|
|
@param comparator an object which defines a compareElements() method
|
|
@param array the array to search
|
|
@param newElement the value that is going to be inserted
|
|
@param firstElement the index of the first element to search
|
|
@param lastElement the index of the last element in the range (this is non-inclusive)
|
|
*/
|
|
template <class ElementType, class ElementComparator>
|
|
static int findInsertIndexInSortedArray (ElementComparator& comparator,
|
|
ElementType* const array,
|
|
const ElementType newElement,
|
|
int firstElement,
|
|
int lastElement)
|
|
{
|
|
jassert (firstElement <= lastElement);
|
|
|
|
(void) comparator; // if you pass in an object with a static compareElements() method, this
|
|
// avoids getting warning messages about the parameter being unused
|
|
|
|
while (firstElement < lastElement)
|
|
{
|
|
if (comparator.compareElements (newElement, array [firstElement]) == 0)
|
|
{
|
|
++firstElement;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
const int halfway = (firstElement + lastElement) >> 1;
|
|
|
|
if (halfway == firstElement)
|
|
{
|
|
if (comparator.compareElements (newElement, array [halfway]) >= 0)
|
|
++firstElement;
|
|
|
|
break;
|
|
}
|
|
else if (comparator.compareElements (newElement, array [halfway]) >= 0)
|
|
{
|
|
firstElement = halfway;
|
|
}
|
|
else
|
|
{
|
|
lastElement = halfway;
|
|
}
|
|
}
|
|
}
|
|
|
|
return firstElement;
|
|
}
|
|
|
|
/**
|
|
A simple ElementComparator class that can be used to sort an array of
|
|
integer primitive objects.
|
|
|
|
Example: @code
|
|
Array <int> myArray;
|
|
|
|
IntegerElementComparator<int> sorter;
|
|
myArray.sort (sorter);
|
|
@endcode
|
|
|
|
For floating point values, see the FloatElementComparator class instead.
|
|
|
|
@see FloatElementComparator, ElementComparator
|
|
*/
|
|
template <class ElementType>
|
|
class IntegerElementComparator
|
|
{
|
|
public:
|
|
static int compareElements (const ElementType first,
|
|
const ElementType second) throw()
|
|
{
|
|
return (first < second) ? -1 : ((first == second) ? 0 : 1);
|
|
}
|
|
};
|
|
|
|
/**
|
|
A simple ElementComparator class that can be used to sort an array of numeric
|
|
double or floating point primitive objects.
|
|
|
|
Example: @code
|
|
Array <double> myArray;
|
|
|
|
FloatElementComparator<double> sorter;
|
|
myArray.sort (sorter);
|
|
@endcode
|
|
|
|
For integer values, see the IntegerElementComparator class instead.
|
|
|
|
@see IntegerElementComparator, ElementComparator
|
|
*/
|
|
template <class ElementType>
|
|
class FloatElementComparator
|
|
{
|
|
public:
|
|
static int compareElements (const ElementType first,
|
|
const ElementType second) throw()
|
|
{
|
|
return (first < second) ? -1 : ((first == second) ? 0 : 1);
|
|
}
|
|
};
|
|
|
|
#endif // __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__
|
|
/********* End of inlined file: juce_ElementComparator.h *********/
|
|
|
|
/********* Start of inlined file: juce_CriticalSection.h *********/
|
|
#ifndef __JUCE_CRITICALSECTION_JUCEHEADER__
|
|
#define __JUCE_CRITICALSECTION_JUCEHEADER__
|
|
|
|
/**
|
|
Prevents multiple threads from accessing shared objects at the same time.
|
|
|
|
@see ScopedLock, Thread, InterProcessLock
|
|
*/
|
|
class JUCE_API CriticalSection
|
|
{
|
|
public:
|
|
|
|
/**
|
|
Creates a CriticalSection object
|
|
*/
|
|
CriticalSection() throw();
|
|
|
|
/** Destroys a CriticalSection object.
|
|
|
|
If the critical section is deleted whilst locked, its subsequent behaviour
|
|
is unpredictable.
|
|
*/
|
|
~CriticalSection() throw();
|
|
|
|
/** Locks this critical section.
|
|
|
|
If the lock is currently held by another thread, this will wait until it
|
|
becomes free.
|
|
|
|
If the lock is already held by the caller thread, the method returns immediately.
|
|
|
|
@see exit, ScopedLock
|
|
*/
|
|
void enter() const throw();
|
|
|
|
/** Attempts to lock this critical section without blocking.
|
|
|
|
This method behaves identically to CriticalSection::enter, except that the caller thread
|
|
does not wait if the lock is currently held by another thread but returns false immediately.
|
|
|
|
@returns false if the lock is currently held by another thread, true otherwise.
|
|
@see enter
|
|
*/
|
|
bool tryEnter() const throw();
|
|
|
|
/** Releases the lock.
|
|
|
|
If the caller thread hasn't got the lock, this can have unpredictable results.
|
|
|
|
If the enter() method has been called multiple times by the thread, each
|
|
call must be matched by a call to exit() before other threads will be allowed
|
|
to take over the lock.
|
|
|
|
@see enter, ScopedLock
|
|
*/
|
|
void exit() const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
#if JUCE_WIN32
|
|
#if JUCE_64BIT
|
|
// To avoid including windows.h in the public Juce includes, we'll just allocate a
|
|
// block of memory here that's big enough to be used internally as a windows critical
|
|
// section object.
|
|
uint8 internal [44];
|
|
#else
|
|
uint8 internal [24];
|
|
#endif
|
|
#else
|
|
mutable pthread_mutex_t internal;
|
|
#endif
|
|
|
|
CriticalSection (const CriticalSection&);
|
|
const CriticalSection& operator= (const CriticalSection&);
|
|
};
|
|
|
|
/**
|
|
A class that can be used in place of a real CriticalSection object.
|
|
|
|
This is currently used by some templated array classes, and should get
|
|
optimised out by the compiler.
|
|
|
|
@see Array, OwnedArray, ReferenceCountedArray
|
|
*/
|
|
class JUCE_API DummyCriticalSection
|
|
{
|
|
public:
|
|
forcedinline DummyCriticalSection() throw() {}
|
|
forcedinline ~DummyCriticalSection() throw() {}
|
|
|
|
forcedinline void enter() const throw() {}
|
|
forcedinline void exit() const throw() {}
|
|
};
|
|
|
|
#endif // __JUCE_CRITICALSECTION_JUCEHEADER__
|
|
/********* End of inlined file: juce_CriticalSection.h *********/
|
|
|
|
/** An array designed for holding objects.
|
|
|
|
This holds a list of pointers to objects, and will automatically
|
|
delete the objects when they are removed from the array, or when the
|
|
array is itself deleted.
|
|
|
|
Declare it in the form: OwnedArray<MyObjectClass>
|
|
|
|
..and then add new objects, e.g. myOwnedArray.add (new MyObjectClass());
|
|
|
|
After adding objects, they are 'owned' by the array and will be deleted when
|
|
removed or replaced.
|
|
|
|
To make all the array's methods thread-safe, pass in "CriticalSection" as the templated
|
|
TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.
|
|
|
|
@see Array, ReferenceCountedArray, StringArray, CriticalSection
|
|
*/
|
|
template <class ObjectClass,
|
|
class TypeOfCriticalSectionToUse = DummyCriticalSection>
|
|
|
|
class OwnedArray : private ArrayAllocationBase <ObjectClass*>
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty array.
|
|
|
|
@param granularity this is the size of increment by which the internal storage
|
|
used by the array will grow. Only change it from the default if you know the
|
|
array is going to be very big and needs to be able to grow efficiently.
|
|
|
|
@see ArrayAllocationBase
|
|
*/
|
|
OwnedArray (const int granularity = juceDefaultArrayGranularity) throw()
|
|
: ArrayAllocationBase <ObjectClass*> (granularity),
|
|
numUsed (0)
|
|
{
|
|
}
|
|
|
|
/** Deletes the array and also deletes any objects inside it.
|
|
|
|
To get rid of the array without deleting its objects, use its
|
|
clear (false) method before deleting it.
|
|
*/
|
|
~OwnedArray()
|
|
{
|
|
clear (true);
|
|
}
|
|
|
|
/** Clears the array, optionally deleting the objects inside it first. */
|
|
void clear (const bool deleteObjects = true)
|
|
{
|
|
lock.enter();
|
|
|
|
if (deleteObjects)
|
|
{
|
|
while (numUsed > 0)
|
|
delete this->elements [--numUsed];
|
|
}
|
|
|
|
this->setAllocatedSize (0);
|
|
numUsed = 0;
|
|
lock.exit();
|
|
}
|
|
|
|
/** Returns the number of items currently in the array.
|
|
@see operator[]
|
|
*/
|
|
inline int size() const throw()
|
|
{
|
|
return numUsed;
|
|
}
|
|
|
|
/** Returns a pointer to the object at this index in the array.
|
|
|
|
If the index is out-of-range, this will return a null pointer, (and
|
|
it could be null anyway, because it's ok for the array to hold null
|
|
pointers as well as objects).
|
|
|
|
@see getUnchecked
|
|
*/
|
|
inline ObjectClass* operator[] (const int index) const throw()
|
|
{
|
|
lock.enter();
|
|
ObjectClass* const result = (((unsigned int) index) < (unsigned int) numUsed)
|
|
? this->elements [index]
|
|
: (ObjectClass*) 0;
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Returns a pointer to the object at this index in the array, without checking whether the index is in-range.
|
|
|
|
This is a faster and less safe version of operator[] which doesn't check the index passed in, so
|
|
it can be used when you're sure the index if always going to be legal.
|
|
*/
|
|
inline ObjectClass* getUnchecked (const int index) const throw()
|
|
{
|
|
lock.enter();
|
|
jassert (((unsigned int) index) < (unsigned int) numUsed);
|
|
ObjectClass* const result = this->elements [index];
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Returns a pointer to the first object in the array.
|
|
|
|
This will return a null pointer if the array's empty.
|
|
@see getLast
|
|
*/
|
|
inline ObjectClass* getFirst() const throw()
|
|
{
|
|
lock.enter();
|
|
ObjectClass* const result = (numUsed > 0) ? this->elements [0]
|
|
: (ObjectClass*) 0;
|
|
lock.exit();
|
|
return result;
|
|
}
|
|
|
|
/** Returns a pointer to the last object in the array.
|
|
|
|
This will return a null pointer if the array's empty.
|
|
@see getFirst
|
|
*/
|
|
inline ObjectClass* getLast() const throw()
|
|
{
|
|
lock.enter();
|
|
ObjectClass* const result = (numUsed > 0) ? this->elements [numUsed - 1]
|
|
: (ObjectClass*) 0;
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Finds the index of an object which might be in the array.
|
|
|
|
@param objectToLookFor the object to look for
|
|
@returns the index at which the object was found, or -1 if it's not found
|
|
*/
|
|
int indexOf (const ObjectClass* const objectToLookFor) const throw()
|
|
{
|
|
int result = -1;
|
|
|
|
lock.enter();
|
|
ObjectClass* const* e = this->elements;
|
|
|
|
for (int i = numUsed; --i >= 0;)
|
|
{
|
|
if (objectToLookFor == *e)
|
|
{
|
|
result = (int) (e - this->elements);
|
|
break;
|
|
}
|
|
|
|
++e;
|
|
}
|
|
|
|
lock.exit();
|
|
return result;
|
|
}
|
|
|
|
/** Returns true if the array contains a specified object.
|
|
|
|
@param objectToLookFor the object to look for
|
|
@returns true if the object is in the array
|
|
*/
|
|
bool contains (const ObjectClass* const objectToLookFor) const throw()
|
|
{
|
|
lock.enter();
|
|
|
|
ObjectClass* const* e = this->elements;
|
|
int i = numUsed;
|
|
|
|
while (i >= 4)
|
|
{
|
|
if (objectToLookFor == *e
|
|
|| objectToLookFor == *++e
|
|
|| objectToLookFor == *++e
|
|
|| objectToLookFor == *++e)
|
|
{
|
|
lock.exit();
|
|
return true;
|
|
}
|
|
|
|
i -= 4;
|
|
++e;
|
|
}
|
|
|
|
while (i > 0)
|
|
{
|
|
if (objectToLookFor == *e)
|
|
{
|
|
lock.exit();
|
|
return true;
|
|
}
|
|
|
|
--i;
|
|
++e;
|
|
}
|
|
|
|
lock.exit();
|
|
return false;
|
|
}
|
|
|
|
/** Appends a new object to the end of the array.
|
|
|
|
Note that the this object will be deleted by the OwnedArray when it
|
|
is removed, so be careful not to delete it somewhere else.
|
|
|
|
Also be careful not to add the same object to the array more than once,
|
|
as this will obviously cause deletion of dangling pointers.
|
|
|
|
@param newObject the new object to add to the array
|
|
@see set, insert, addIfNotAlreadyThere, addSorted
|
|
*/
|
|
void add (const ObjectClass* const newObject) throw()
|
|
{
|
|
lock.enter();
|
|
this->ensureAllocatedSize (numUsed + 1);
|
|
this->elements [numUsed++] = const_cast <ObjectClass*> (newObject);
|
|
lock.exit();
|
|
}
|
|
|
|
/** Inserts a new object into the array at the given index.
|
|
|
|
Note that the this object will be deleted by the OwnedArray when it
|
|
is removed, so be careful not to delete it somewhere else.
|
|
|
|
If the index is less than 0 or greater than the size of the array, the
|
|
element will be added to the end of the array.
|
|
Otherwise, it will be inserted into the array, moving all the later elements
|
|
along to make room.
|
|
|
|
Be careful not to add the same object to the array more than once,
|
|
as this will obviously cause deletion of dangling pointers.
|
|
|
|
@param indexToInsertAt the index at which the new element should be inserted
|
|
@param newObject the new object to add to the array
|
|
@see add, addSorted, addIfNotAlreadyThere, set
|
|
*/
|
|
void insert (int indexToInsertAt,
|
|
const ObjectClass* const newObject) throw()
|
|
{
|
|
if (indexToInsertAt >= 0)
|
|
{
|
|
lock.enter();
|
|
|
|
if (indexToInsertAt > numUsed)
|
|
indexToInsertAt = numUsed;
|
|
|
|
this->ensureAllocatedSize (numUsed + 1);
|
|
|
|
ObjectClass** const e = this->elements + indexToInsertAt;
|
|
const int numToMove = numUsed - indexToInsertAt;
|
|
|
|
if (numToMove > 0)
|
|
memmove (e + 1, e, numToMove * sizeof (ObjectClass*));
|
|
|
|
*e = const_cast <ObjectClass*> (newObject);
|
|
++numUsed;
|
|
|
|
lock.exit();
|
|
}
|
|
else
|
|
{
|
|
add (newObject);
|
|
}
|
|
}
|
|
|
|
/** Appends a new object at the end of the array as long as the array doesn't
|
|
already contain it.
|
|
|
|
If the array already contains a matching object, nothing will be done.
|
|
|
|
@param newObject the new object to add to the array
|
|
*/
|
|
void addIfNotAlreadyThere (const ObjectClass* const newObject) throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (! contains (newObject))
|
|
add (newObject);
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Replaces an object in the array with a different one.
|
|
|
|
If the index is less than zero, this method does nothing.
|
|
If the index is beyond the end of the array, the new object is added to the end of the array.
|
|
|
|
Be careful not to add the same object to the array more than once,
|
|
as this will obviously cause deletion of dangling pointers.
|
|
|
|
@param indexToChange the index whose value you want to change
|
|
@param newObject the new value to set for this index.
|
|
@param deleteOldElement whether to delete the object that's being replaced with the new one
|
|
@see add, insert, remove
|
|
*/
|
|
void set (const int indexToChange,
|
|
const ObjectClass* const newObject,
|
|
const bool deleteOldElement = true)
|
|
{
|
|
if (indexToChange >= 0)
|
|
{
|
|
ObjectClass* toDelete = 0;
|
|
lock.enter();
|
|
|
|
if (indexToChange < numUsed)
|
|
{
|
|
if (deleteOldElement)
|
|
{
|
|
toDelete = this->elements [indexToChange];
|
|
|
|
if (toDelete == newObject)
|
|
toDelete = 0;
|
|
}
|
|
|
|
this->elements [indexToChange] = const_cast <ObjectClass*> (newObject);
|
|
}
|
|
else
|
|
{
|
|
this->ensureAllocatedSize (numUsed + 1);
|
|
this->elements [numUsed++] = const_cast <ObjectClass*> (newObject);
|
|
}
|
|
|
|
lock.exit();
|
|
|
|
delete toDelete;
|
|
}
|
|
}
|
|
|
|
/** Inserts a new object into the array assuming that the array is sorted.
|
|
|
|
This will use a comparator to find the position at which the new object
|
|
should go. If the array isn't sorted, the behaviour of this
|
|
method will be unpredictable.
|
|
|
|
@param comparator the comparator to use to compare the elements - see the sort method
|
|
for details about this object's structure
|
|
@param newObject the new object to insert to the array
|
|
@see add, sort, indexOfSorted
|
|
*/
|
|
template <class ElementComparator>
|
|
void addSorted (ElementComparator& comparator,
|
|
ObjectClass* const newObject) throw()
|
|
{
|
|
(void) comparator; // if you pass in an object with a static compareElements() method, this
|
|
// avoids getting warning messages about the parameter being unused
|
|
lock.enter();
|
|
insert (findInsertIndexInSortedArray (comparator, this->elements, newObject, 0, numUsed), newObject);
|
|
lock.exit();
|
|
}
|
|
|
|
/** Finds the index of an object in the array, assuming that the array is sorted.
|
|
|
|
This will use a comparator to do a binary-chop to find the index of the given
|
|
element, if it exists. If the array isn't sorted, the behaviour of this
|
|
method will be unpredictable.
|
|
|
|
@param comparator the comparator to use to compare the elements - see the sort()
|
|
method for details about the form this object should take
|
|
@param objectToLookFor the object to search for
|
|
@returns the index of the element, or -1 if it's not found
|
|
@see addSorted, sort
|
|
*/
|
|
template <class ElementComparator>
|
|
int indexOfSorted (ElementComparator& comparator,
|
|
const ObjectClass* const objectToLookFor) const throw()
|
|
{
|
|
(void) comparator; // if you pass in an object with a static compareElements() method, this
|
|
// avoids getting warning messages about the parameter being unused
|
|
lock.enter();
|
|
|
|
int start = 0;
|
|
int end = numUsed;
|
|
|
|
for (;;)
|
|
{
|
|
if (start >= end)
|
|
{
|
|
lock.exit();
|
|
return -1;
|
|
}
|
|
else if (comparator.compareElements (objectToLookFor, this->elements [start]) == 0)
|
|
{
|
|
lock.exit();
|
|
return start;
|
|
}
|
|
else
|
|
{
|
|
const int halfway = (start + end) >> 1;
|
|
|
|
if (halfway == start)
|
|
{
|
|
lock.exit();
|
|
return -1;
|
|
}
|
|
else if (comparator.compareElements (objectToLookFor, this->elements [halfway]) >= 0)
|
|
start = halfway;
|
|
else
|
|
end = halfway;
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Removes an object from the array.
|
|
|
|
This will remove the object at a given index (optionally also
|
|
deleting it) and move back all the subsequent objects to close the gap.
|
|
If the index passed in is out-of-range, nothing will happen.
|
|
|
|
@param indexToRemove the index of the element to remove
|
|
@param deleteObject whether to delete the object that is removed
|
|
@see removeObject, removeRange
|
|
*/
|
|
void remove (const int indexToRemove,
|
|
const bool deleteObject = true)
|
|
{
|
|
lock.enter();
|
|
ObjectClass* toDelete = 0;
|
|
|
|
if (((unsigned int) indexToRemove) < (unsigned int) numUsed)
|
|
{
|
|
ObjectClass** const e = this->elements + indexToRemove;
|
|
|
|
if (deleteObject)
|
|
toDelete = *e;
|
|
|
|
--numUsed;
|
|
const int numToShift = numUsed - indexToRemove;
|
|
|
|
if (numToShift > 0)
|
|
memmove (e, e + 1, numToShift * sizeof (ObjectClass*));
|
|
|
|
if ((numUsed << 1) < this->numAllocated)
|
|
minimiseStorageOverheads();
|
|
}
|
|
|
|
lock.exit();
|
|
|
|
delete toDelete;
|
|
}
|
|
|
|
/** Removes a specified object from the array.
|
|
|
|
If the item isn't found, no action is taken.
|
|
|
|
@param objectToRemove the object to try to remove
|
|
@param deleteObject whether to delete the object (if it's found)
|
|
@see remove, removeRange
|
|
*/
|
|
void removeObject (const ObjectClass* const objectToRemove,
|
|
const bool deleteObject = true)
|
|
{
|
|
lock.enter();
|
|
ObjectClass** e = this->elements;
|
|
|
|
for (int i = numUsed; --i >= 0;)
|
|
{
|
|
if (objectToRemove == *e)
|
|
{
|
|
remove ((int) (e - this->elements), deleteObject);
|
|
break;
|
|
}
|
|
|
|
++e;
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Removes a range of objects from the array.
|
|
|
|
This will remove a set of objects, starting from the given index,
|
|
and move any subsequent elements down to close the gap.
|
|
|
|
If the range extends beyond the bounds of the array, it will
|
|
be safely clipped to the size of the array.
|
|
|
|
@param startIndex the index of the first object to remove
|
|
@param numberToRemove how many objects should be removed
|
|
@param deleteObjects whether to delete the objects that get removed
|
|
@see remove, removeObject
|
|
*/
|
|
void removeRange (int startIndex,
|
|
const int numberToRemove,
|
|
const bool deleteObjects = true)
|
|
{
|
|
lock.enter();
|
|
const int endIndex = jlimit (0, numUsed, startIndex + numberToRemove);
|
|
startIndex = jlimit (0, numUsed, startIndex);
|
|
|
|
if (endIndex > startIndex)
|
|
{
|
|
if (deleteObjects)
|
|
{
|
|
for (int i = startIndex; i < endIndex; ++i)
|
|
{
|
|
delete this->elements [i];
|
|
this->elements [i] = 0; // (in case one of the destructors accesses this array and hits a dangling pointer)
|
|
}
|
|
}
|
|
|
|
const int rangeSize = endIndex - startIndex;
|
|
ObjectClass** e = this->elements + startIndex;
|
|
int numToShift = numUsed - endIndex;
|
|
numUsed -= rangeSize;
|
|
|
|
while (--numToShift >= 0)
|
|
{
|
|
*e = e [rangeSize];
|
|
++e;
|
|
}
|
|
|
|
if ((numUsed << 1) < this->numAllocated)
|
|
minimiseStorageOverheads();
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Removes the last n objects from the array.
|
|
|
|
@param howManyToRemove how many objects to remove from the end of the array
|
|
@param deleteObjects whether to also delete the objects that are removed
|
|
@see remove, removeObject, removeRange
|
|
*/
|
|
void removeLast (int howManyToRemove = 1,
|
|
const bool deleteObjects = true)
|
|
{
|
|
lock.enter();
|
|
|
|
if (howManyToRemove >= numUsed)
|
|
{
|
|
clear (deleteObjects);
|
|
}
|
|
else
|
|
{
|
|
while (--howManyToRemove >= 0)
|
|
remove (numUsed - 1, deleteObjects);
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Swaps a pair of objects in the array.
|
|
|
|
If either of the indexes passed in is out-of-range, nothing will happen,
|
|
otherwise the two objects at these positions will be exchanged.
|
|
*/
|
|
void swap (const int index1,
|
|
const int index2) throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (((unsigned int) index1) < (unsigned int) numUsed
|
|
&& ((unsigned int) index2) < (unsigned int) numUsed)
|
|
{
|
|
swapVariables (this->elements [index1],
|
|
this->elements [index2]);
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Moves one of the objects to a different position.
|
|
|
|
This will move the object to a specified index, shuffling along
|
|
any intervening elements as required.
|
|
|
|
So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling
|
|
move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }.
|
|
|
|
@param currentIndex the index of the object to be moved. If this isn't a
|
|
valid index, then nothing will be done
|
|
@param newIndex the index at which you'd like this object to end up. If this
|
|
is less than zero, it will be moved to the end of the array
|
|
*/
|
|
void move (const int currentIndex,
|
|
int newIndex) throw()
|
|
{
|
|
if (currentIndex != newIndex)
|
|
{
|
|
lock.enter();
|
|
|
|
if (((unsigned int) currentIndex) < (unsigned int) numUsed)
|
|
{
|
|
if (((unsigned int) newIndex) >= (unsigned int) numUsed)
|
|
newIndex = numUsed - 1;
|
|
|
|
ObjectClass* const value = this->elements [currentIndex];
|
|
|
|
if (newIndex > currentIndex)
|
|
{
|
|
memmove (this->elements + currentIndex,
|
|
this->elements + currentIndex + 1,
|
|
(newIndex - currentIndex) * sizeof (ObjectClass*));
|
|
}
|
|
else
|
|
{
|
|
memmove (this->elements + newIndex + 1,
|
|
this->elements + newIndex,
|
|
(currentIndex - newIndex) * sizeof (ObjectClass*));
|
|
}
|
|
|
|
this->elements [newIndex] = value;
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
}
|
|
|
|
/** This swaps the contents of this array with those of another array.
|
|
|
|
If you need to exchange two arrays, this is vastly quicker than using copy-by-value
|
|
because it just swaps their internal pointers.
|
|
*/
|
|
template <class OtherArrayType>
|
|
void swapWithArray (OtherArrayType& otherArray) throw()
|
|
{
|
|
lock.enter();
|
|
otherArray.lock.enter();
|
|
swapVariables <int> (this->numUsed, otherArray.numUsed);
|
|
swapVariables <ObjectClass**> (this->elements, otherArray.elements);
|
|
swapVariables <int> (this->numAllocated, otherArray.numAllocated);
|
|
otherArray.lock.exit();
|
|
lock.exit();
|
|
}
|
|
|
|
/** Reduces the amount of storage being used by the array.
|
|
|
|
Arrays typically allocate slightly more storage than they need, and after
|
|
removing elements, they may have quite a lot of unused space allocated.
|
|
This method will reduce the amount of allocated storage to a minimum.
|
|
*/
|
|
void minimiseStorageOverheads() throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (numUsed == 0)
|
|
{
|
|
this->setAllocatedSize (0);
|
|
}
|
|
else
|
|
{
|
|
const int newAllocation = this->granularity * (numUsed / this->granularity + 1);
|
|
|
|
if (newAllocation < this->numAllocated)
|
|
this->setAllocatedSize (newAllocation);
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Increases the array's internal storage to hold a minimum number of elements.
|
|
|
|
Calling this before adding a large known number of elements means that
|
|
the array won't have to keep dynamically resizing itself as the elements
|
|
are added, and it'll therefore be more efficient.
|
|
*/
|
|
void ensureStorageAllocated (const int minNumElements) throw()
|
|
{
|
|
this->ensureAllocatedSize (minNumElements);
|
|
}
|
|
|
|
/** Sorts the elements in the array.
|
|
|
|
This will use a comparator object to sort the elements into order. The object
|
|
passed must have a method of the form:
|
|
@code
|
|
int compareElements (ElementType first, ElementType second);
|
|
@endcode
|
|
|
|
..and this method must return:
|
|
- a value of < 0 if the first comes before the second
|
|
- a value of 0 if the two objects are equivalent
|
|
- a value of > 0 if the second comes before the first
|
|
|
|
To improve performance, the compareElements() method can be declared as static or const.
|
|
|
|
@param comparator the comparator to use for comparing elements.
|
|
@param retainOrderOfEquivalentItems if this is true, then items
|
|
which the comparator says are equivalent will be
|
|
kept in the order in which they currently appear
|
|
in the array. This is slower to perform, but may
|
|
be important in some cases. If it's false, a faster
|
|
algorithm is used, but equivalent elements may be
|
|
rearranged.
|
|
@see sortArray, indexOfSorted
|
|
*/
|
|
template <class ElementComparator>
|
|
void sort (ElementComparator& comparator,
|
|
const bool retainOrderOfEquivalentItems = false) const throw()
|
|
{
|
|
(void) comparator; // if you pass in an object with a static compareElements() method, this
|
|
// avoids getting warning messages about the parameter being unused
|
|
|
|
lock.enter();
|
|
sortArray (comparator, this->elements, 0, size() - 1, retainOrderOfEquivalentItems);
|
|
lock.exit();
|
|
}
|
|
|
|
/** Locks the array's CriticalSection.
|
|
|
|
Of course if the type of section used is a DummyCriticalSection, this won't
|
|
have any effect.
|
|
|
|
@see unlockArray
|
|
*/
|
|
void lockArray() const throw()
|
|
{
|
|
lock.enter();
|
|
}
|
|
|
|
/** Unlocks the array's CriticalSection.
|
|
|
|
Of course if the type of section used is a DummyCriticalSection, this won't
|
|
have any effect.
|
|
|
|
@see lockArray
|
|
*/
|
|
void unlockArray() const throw()
|
|
{
|
|
lock.exit();
|
|
}
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int numUsed;
|
|
TypeOfCriticalSectionToUse lock;
|
|
|
|
// disallow copy constructor and assignment
|
|
OwnedArray (const OwnedArray&);
|
|
const OwnedArray& operator= (const OwnedArray&);
|
|
};
|
|
|
|
#endif // __JUCE_OWNEDARRAY_JUCEHEADER__
|
|
/********* End of inlined file: juce_OwnedArray.h *********/
|
|
|
|
/********* Start of inlined file: juce_Time.h *********/
|
|
#ifndef __JUCE_TIME_JUCEHEADER__
|
|
#define __JUCE_TIME_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_RelativeTime.h *********/
|
|
#ifndef __JUCE_RELATIVETIME_JUCEHEADER__
|
|
#define __JUCE_RELATIVETIME_JUCEHEADER__
|
|
|
|
/** A relative measure of time.
|
|
|
|
The time is stored as a number of seconds, at double-precision floating
|
|
point accuracy, and may be positive or negative.
|
|
|
|
If you need an absolute time, (i.e. a date + time), see the Time class.
|
|
*/
|
|
class JUCE_API RelativeTime
|
|
{
|
|
public:
|
|
|
|
/** Creates a RelativeTime.
|
|
|
|
@param seconds the number of seconds, which may be +ve or -ve.
|
|
@see milliseconds, minutes, hours, days, weeks
|
|
*/
|
|
explicit RelativeTime (const double seconds = 0.0) throw();
|
|
|
|
/** Copies another relative time. */
|
|
RelativeTime (const RelativeTime& other) throw();
|
|
|
|
/** Copies another relative time. */
|
|
const RelativeTime& operator= (const RelativeTime& other) throw();
|
|
|
|
/** Destructor. */
|
|
~RelativeTime() throw();
|
|
|
|
/** Creates a new RelativeTime object representing a number of milliseconds.
|
|
|
|
@see minutes, hours, days, weeks
|
|
*/
|
|
static const RelativeTime milliseconds (const int milliseconds) throw();
|
|
|
|
/** Creates a new RelativeTime object representing a number of milliseconds.
|
|
|
|
@see minutes, hours, days, weeks
|
|
*/
|
|
static const RelativeTime milliseconds (const int64 milliseconds) throw();
|
|
|
|
/** Creates a new RelativeTime object representing a number of minutes.
|
|
|
|
@see milliseconds, hours, days, weeks
|
|
*/
|
|
static const RelativeTime minutes (const double numberOfMinutes) throw();
|
|
|
|
/** Creates a new RelativeTime object representing a number of hours.
|
|
|
|
@see milliseconds, minutes, days, weeks
|
|
*/
|
|
static const RelativeTime hours (const double numberOfHours) throw();
|
|
|
|
/** Creates a new RelativeTime object representing a number of days.
|
|
|
|
@see milliseconds, minutes, hours, weeks
|
|
*/
|
|
static const RelativeTime days (const double numberOfDays) throw();
|
|
|
|
/** Creates a new RelativeTime object representing a number of weeks.
|
|
|
|
@see milliseconds, minutes, hours, days
|
|
*/
|
|
static const RelativeTime weeks (const double numberOfWeeks) throw();
|
|
|
|
/** Returns the number of milliseconds this time represents.
|
|
|
|
@see milliseconds, inSeconds, inMinutes, inHours, inDays, inWeeks
|
|
*/
|
|
int64 inMilliseconds() const throw();
|
|
|
|
/** Returns the number of seconds this time represents.
|
|
|
|
@see inMilliseconds, inMinutes, inHours, inDays, inWeeks
|
|
*/
|
|
double inSeconds() const throw() { return seconds; }
|
|
|
|
/** Returns the number of minutes this time represents.
|
|
|
|
@see inMilliseconds, inSeconds, inHours, inDays, inWeeks
|
|
*/
|
|
double inMinutes() const throw();
|
|
|
|
/** Returns the number of hours this time represents.
|
|
|
|
@see inMilliseconds, inSeconds, inMinutes, inDays, inWeeks
|
|
*/
|
|
double inHours() const throw();
|
|
|
|
/** Returns the number of days this time represents.
|
|
|
|
@see inMilliseconds, inSeconds, inMinutes, inHours, inWeeks
|
|
*/
|
|
double inDays() const throw();
|
|
|
|
/** Returns the number of weeks this time represents.
|
|
|
|
@see inMilliseconds, inSeconds, inMinutes, inHours, inDays
|
|
*/
|
|
double inWeeks() const throw();
|
|
|
|
/** Returns a readable textual description of the time.
|
|
|
|
The exact format of the string returned will depend on
|
|
the magnitude of the time - e.g.
|
|
|
|
"1 min 4 secs", "1 hr 45 mins", "2 weeks 5 days", "140 ms"
|
|
|
|
so that only the two most significant units are printed.
|
|
|
|
The returnValueForZeroTime value is the result that is returned if the
|
|
length is zero. Depending on your application you might want to use this
|
|
to return something more relevant like "empty" or "0 secs", etc.
|
|
|
|
@see inMilliseconds, inSeconds, inMinutes, inHours, inDays, inWeeks
|
|
*/
|
|
const String getDescription (const String& returnValueForZeroTime = JUCE_T("0")) const throw();
|
|
|
|
/** Compares two RelativeTimes. */
|
|
bool operator== (const RelativeTime& other) const throw();
|
|
/** Compares two RelativeTimes. */
|
|
bool operator!= (const RelativeTime& other) const throw();
|
|
|
|
/** Compares two RelativeTimes. */
|
|
bool operator> (const RelativeTime& other) const throw();
|
|
/** Compares two RelativeTimes. */
|
|
bool operator< (const RelativeTime& other) const throw();
|
|
/** Compares two RelativeTimes. */
|
|
bool operator>= (const RelativeTime& other) const throw();
|
|
/** Compares two RelativeTimes. */
|
|
bool operator<= (const RelativeTime& other) const throw();
|
|
|
|
/** Adds another RelativeTime to this one and returns the result. */
|
|
const RelativeTime operator+ (const RelativeTime& timeToAdd) const throw();
|
|
/** Subtracts another RelativeTime from this one and returns the result. */
|
|
const RelativeTime operator- (const RelativeTime& timeToSubtract) const throw();
|
|
|
|
/** Adds a number of seconds to this RelativeTime and returns the result. */
|
|
const RelativeTime operator+ (const double secondsToAdd) const throw();
|
|
/** Subtracts a number of seconds from this RelativeTime and returns the result. */
|
|
const RelativeTime operator- (const double secondsToSubtract) const throw();
|
|
|
|
/** Adds another RelativeTime to this one. */
|
|
const RelativeTime& operator+= (const RelativeTime& timeToAdd) throw();
|
|
/** Subtracts another RelativeTime from this one. */
|
|
const RelativeTime& operator-= (const RelativeTime& timeToSubtract) throw();
|
|
|
|
/** Adds a number of seconds to this time. */
|
|
const RelativeTime& operator+= (const double secondsToAdd) throw();
|
|
|
|
/** Subtracts a number of seconds from this time. */
|
|
const RelativeTime& operator-= (const double secondsToSubtract) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
double seconds;
|
|
};
|
|
|
|
#endif // __JUCE_RELATIVETIME_JUCEHEADER__
|
|
/********* End of inlined file: juce_RelativeTime.h *********/
|
|
|
|
/**
|
|
Holds an absolute date and time.
|
|
|
|
Internally, the time is stored at millisecond precision.
|
|
|
|
@see RelativeTime
|
|
*/
|
|
class JUCE_API Time
|
|
{
|
|
public:
|
|
|
|
/** Creates a Time object.
|
|
|
|
This default constructor creates a time of 1st January 1970, (which is
|
|
represented internally as 0ms).
|
|
|
|
To create a time object representing the current time, use getCurrentTime().
|
|
|
|
@see getCurrentTime
|
|
*/
|
|
Time() throw();
|
|
|
|
/** Creates a copy of another Time object. */
|
|
Time (const Time& other) throw();
|
|
|
|
/** Creates a time based on a number of milliseconds.
|
|
|
|
The internal millisecond count is set to 0 (1st January 1970). To create a
|
|
time object set to the current time, use getCurrentTime().
|
|
|
|
@param millisecondsSinceEpoch the number of milliseconds since the unix
|
|
'epoch' (midnight Jan 1st 1970).
|
|
@see getCurrentTime, currentTimeMillis
|
|
*/
|
|
Time (const int64 millisecondsSinceEpoch) throw();
|
|
|
|
/** Creates a time from a set of date components.
|
|
|
|
The timezone is assumed to be whatever the system is using as its locale.
|
|
|
|
@param year the year, in 4-digit format, e.g. 2004
|
|
@param month the month, in the range 0 to 11
|
|
@param day the day of the month, in the range 1 to 31
|
|
@param hours hours in 24-hour clock format, 0 to 23
|
|
@param minutes minutes 0 to 59
|
|
@param seconds seconds 0 to 59
|
|
@param milliseconds milliseconds 0 to 999
|
|
@param useLocalTime if true, encode using the current machine's local time; if
|
|
false, it will always work in GMT.
|
|
*/
|
|
Time (const int year,
|
|
const int month,
|
|
const int day,
|
|
const int hours,
|
|
const int minutes,
|
|
const int seconds = 0,
|
|
const int milliseconds = 0,
|
|
const bool useLocalTime = true) throw();
|
|
|
|
/** Destructor. */
|
|
~Time() throw();
|
|
|
|
/** Copies this time from another one. */
|
|
const Time& operator= (const Time& other) throw();
|
|
|
|
/** Returns a Time object that is set to the current system time.
|
|
|
|
@see currentTimeMillis
|
|
*/
|
|
static const Time JUCE_CALLTYPE getCurrentTime() throw();
|
|
|
|
/** Returns the time as a number of milliseconds.
|
|
|
|
@returns the number of milliseconds this Time object represents, since
|
|
midnight jan 1st 1970.
|
|
@see getMilliseconds
|
|
*/
|
|
int64 toMilliseconds() const throw() { return millisSinceEpoch; }
|
|
|
|
/** Returns the year.
|
|
|
|
A 4-digit format is used, e.g. 2004.
|
|
*/
|
|
int getYear() const throw();
|
|
|
|
/** Returns the number of the month.
|
|
|
|
The value returned is in the range 0 to 11.
|
|
@see getMonthName
|
|
*/
|
|
int getMonth() const throw();
|
|
|
|
/** Returns the name of the month.
|
|
|
|
@param threeLetterVersion if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false
|
|
it'll return the long form, e.g. "January"
|
|
@see getMonth
|
|
*/
|
|
const String getMonthName (const bool threeLetterVersion) const throw();
|
|
|
|
/** Returns the day of the month.
|
|
|
|
The value returned is in the range 1 to 31.
|
|
*/
|
|
int getDayOfMonth() const throw();
|
|
|
|
/** Returns the number of the day of the week.
|
|
|
|
The value returned is in the range 0 to 6 (0 = sunday, 1 = monday, etc).
|
|
*/
|
|
int getDayOfWeek() const throw();
|
|
|
|
/** Returns the name of the weekday.
|
|
|
|
@param threeLetterVersion if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if
|
|
false, it'll return the full version, e.g. "Tuesday".
|
|
*/
|
|
const String getWeekdayName (const bool threeLetterVersion) const throw();
|
|
|
|
/** Returns the number of hours since midnight.
|
|
|
|
This is in 24-hour clock format, in the range 0 to 23.
|
|
|
|
@see getHoursInAmPmFormat, isAfternoon
|
|
*/
|
|
int getHours() const throw();
|
|
|
|
/** Returns true if the time is in the afternoon.
|
|
|
|
So it returns true for "PM", false for "AM".
|
|
|
|
@see getHoursInAmPmFormat, getHours
|
|
*/
|
|
bool isAfternoon() const throw();
|
|
|
|
/** Returns the hours in 12-hour clock format.
|
|
|
|
This will return a value 1 to 12 - use isAfternoon() to find out
|
|
whether this is in the afternoon or morning.
|
|
|
|
@see getHours, isAfternoon
|
|
*/
|
|
int getHoursInAmPmFormat() const throw();
|
|
|
|
/** Returns the number of minutes, 0 to 59. */
|
|
int getMinutes() const throw();
|
|
|
|
/** Returns the number of seconds, 0 to 59. */
|
|
int getSeconds() const throw();
|
|
|
|
/** Returns the number of milliseconds, 0 to 999.
|
|
|
|
Unlike toMilliseconds(), this just returns the position within the
|
|
current second rather than the total number since the epoch.
|
|
|
|
@see toMilliseconds
|
|
*/
|
|
int getMilliseconds() const throw();
|
|
|
|
/** Returns true if the local timezone uses a daylight saving correction. */
|
|
bool isDaylightSavingTime() const throw();
|
|
|
|
/** Returns a 3-character string to indicate the local timezone. */
|
|
const String getTimeZone() const throw();
|
|
|
|
/** Quick way of getting a string version of a date and time.
|
|
|
|
For a more powerful way of formatting the date and time, see the formatted() method.
|
|
|
|
@param includeDate whether to include the date in the string
|
|
@param includeTime whether to include the time in the string
|
|
@param includeSeconds if the time is being included, this provides an option not to include
|
|
the seconds in it
|
|
@param use24HourClock if the time is being included, sets whether to use am/pm or 24
|
|
hour notation.
|
|
@see formatted
|
|
*/
|
|
const String toString (const bool includeDate,
|
|
const bool includeTime,
|
|
const bool includeSeconds = true,
|
|
const bool use24HourClock = false) const throw();
|
|
|
|
/** Converts this date/time to a string with a user-defined format.
|
|
|
|
This uses the C strftime() function to format this time as a string. To save you
|
|
looking it up, these are the escape codes that strftime uses (other codes might
|
|
work on some platforms and not others, but these are the common ones):
|
|
|
|
%a is replaced by the locale's abbreviated weekday name.
|
|
%A is replaced by the locale's full weekday name.
|
|
%b is replaced by the locale's abbreviated month name.
|
|
%B is replaced by the locale's full month name.
|
|
%c is replaced by the locale's appropriate date and time representation.
|
|
%d is replaced by the day of the month as a decimal number [01,31].
|
|
%H is replaced by the hour (24-hour clock) as a decimal number [00,23].
|
|
%I is replaced by the hour (12-hour clock) as a decimal number [01,12].
|
|
%j is replaced by the day of the year as a decimal number [001,366].
|
|
%m is replaced by the month as a decimal number [01,12].
|
|
%M is replaced by the minute as a decimal number [00,59].
|
|
%p is replaced by the locale's equivalent of either a.m. or p.m.
|
|
%S is replaced by the second as a decimal number [00,61].
|
|
%U is replaced by the week number of the year (Sunday as the first day of the week) as a decimal number [00,53].
|
|
%w is replaced by the weekday as a decimal number [0,6], with 0 representing Sunday.
|
|
%W is replaced by the week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0.
|
|
%x is replaced by the locale's appropriate date representation.
|
|
%X is replaced by the locale's appropriate time representation.
|
|
%y is replaced by the year without century as a decimal number [00,99].
|
|
%Y is replaced by the year with century as a decimal number.
|
|
%Z is replaced by the timezone name or abbreviation, or by no bytes if no timezone information exists.
|
|
%% is replaced by %.
|
|
|
|
@see toString
|
|
*/
|
|
const String formatted (const tchar* const format) const throw();
|
|
|
|
/** Adds a RelativeTime to this time and returns the result. */
|
|
const Time operator+ (const RelativeTime& delta) const throw() { return Time (millisSinceEpoch + delta.inMilliseconds()); }
|
|
|
|
/** Subtracts a RelativeTime from this time and returns the result. */
|
|
const Time operator- (const RelativeTime& delta) const throw() { return Time (millisSinceEpoch - delta.inMilliseconds()); }
|
|
|
|
/** Returns the relative time difference between this time and another one. */
|
|
const RelativeTime operator- (const Time& other) const throw() { return RelativeTime::milliseconds (millisSinceEpoch - other.millisSinceEpoch); }
|
|
|
|
/** Compares two Time objects. */
|
|
bool operator== (const Time& other) const throw() { return millisSinceEpoch == other.millisSinceEpoch; }
|
|
|
|
/** Compares two Time objects. */
|
|
bool operator!= (const Time& other) const throw() { return millisSinceEpoch != other.millisSinceEpoch; }
|
|
|
|
/** Compares two Time objects. */
|
|
bool operator< (const Time& other) const throw() { return millisSinceEpoch < other.millisSinceEpoch; }
|
|
|
|
/** Compares two Time objects. */
|
|
bool operator<= (const Time& other) const throw() { return millisSinceEpoch <= other.millisSinceEpoch; }
|
|
|
|
/** Compares two Time objects. */
|
|
bool operator> (const Time& other) const throw() { return millisSinceEpoch > other.millisSinceEpoch; }
|
|
|
|
/** Compares two Time objects. */
|
|
bool operator>= (const Time& other) const throw() { return millisSinceEpoch >= other.millisSinceEpoch; }
|
|
|
|
/** Tries to set the computer's clock.
|
|
|
|
@returns true if this succeeds, although depending on the system, the
|
|
application might not have sufficient privileges to do this.
|
|
*/
|
|
bool setSystemTimeToThisTime() const throw();
|
|
|
|
/** Returns the name of a day of the week.
|
|
|
|
@param dayNumber the day, 0 to 6 (0 = sunday, 1 = monday, etc)
|
|
@param threeLetterVersion if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if
|
|
false, it'll return the full version, e.g. "Tuesday".
|
|
*/
|
|
static const String getWeekdayName (int dayNumber,
|
|
const bool threeLetterVersion) throw();
|
|
|
|
/** Returns the name of one of the months.
|
|
|
|
@param monthNumber the month, 0 to 11
|
|
@param threeLetterVersion if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false
|
|
it'll return the long form, e.g. "January"
|
|
*/
|
|
static const String getMonthName (int monthNumber,
|
|
const bool threeLetterVersion) throw();
|
|
|
|
// Static methods for getting system timers directly..
|
|
|
|
/** Returns the current system time.
|
|
|
|
Returns the number of milliseconds since midnight jan 1st 1970.
|
|
|
|
Should be accurate to within a few millisecs, depending on platform,
|
|
hardware, etc.
|
|
*/
|
|
static int64 currentTimeMillis() throw();
|
|
|
|
/** Returns the number of millisecs since system startup.
|
|
|
|
Should be accurate to within a few millisecs, depending on platform,
|
|
hardware, etc.
|
|
|
|
@see getApproximateMillisecondCounter
|
|
*/
|
|
static uint32 getMillisecondCounter() throw();
|
|
|
|
/** Returns the number of millisecs since system startup.
|
|
|
|
Same as getMillisecondCounter(), but returns a more accurate value, using
|
|
the high-res timer.
|
|
|
|
@see getMillisecondCounter
|
|
*/
|
|
static double getMillisecondCounterHiRes() throw();
|
|
|
|
/** Waits until the getMillisecondCounter() reaches a given value.
|
|
|
|
This will make the thread sleep as efficiently as it can while it's waiting.
|
|
*/
|
|
static void waitForMillisecondCounter (const uint32 targetTime) throw();
|
|
|
|
/** Less-accurate but faster version of getMillisecondCounter().
|
|
|
|
This will return the last value that getMillisecondCounter() returned, so doesn't
|
|
need to make a system call, but is less accurate - it shouldn't be more than
|
|
100ms away from the correct time, though, so is still accurate enough for a
|
|
lot of purposes.
|
|
|
|
@see getMillisecondCounter
|
|
*/
|
|
static uint32 getApproximateMillisecondCounter() throw();
|
|
|
|
// High-resolution timers..
|
|
|
|
/** Returns the current high-resolution counter's tick-count.
|
|
|
|
This is a similar idea to getMillisecondCounter(), but with a higher
|
|
resolution.
|
|
|
|
@see getHighResolutionTicksPerSecond, highResolutionTicksToSeconds,
|
|
secondsToHighResolutionTicks
|
|
*/
|
|
static int64 getHighResolutionTicks() throw();
|
|
|
|
/** Returns the resolution of the high-resolution counter in ticks per second.
|
|
|
|
@see getHighResolutionTicks, highResolutionTicksToSeconds,
|
|
secondsToHighResolutionTicks
|
|
*/
|
|
static int64 getHighResolutionTicksPerSecond() throw();
|
|
|
|
/** Converts a number of high-resolution ticks into seconds.
|
|
|
|
@see getHighResolutionTicks, getHighResolutionTicksPerSecond,
|
|
secondsToHighResolutionTicks
|
|
*/
|
|
static double highResolutionTicksToSeconds (const int64 ticks) throw();
|
|
|
|
/** Converts a number seconds into high-resolution ticks.
|
|
|
|
@see getHighResolutionTicks, getHighResolutionTicksPerSecond,
|
|
highResolutionTicksToSeconds
|
|
*/
|
|
static int64 secondsToHighResolutionTicks (const double seconds) throw();
|
|
|
|
private:
|
|
|
|
int64 millisSinceEpoch;
|
|
};
|
|
|
|
#endif // __JUCE_TIME_JUCEHEADER__
|
|
/********* End of inlined file: juce_Time.h *********/
|
|
|
|
/********* Start of inlined file: juce_StringArray.h *********/
|
|
#ifndef __JUCE_STRINGARRAY_JUCEHEADER__
|
|
#define __JUCE_STRINGARRAY_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_VoidArray.h *********/
|
|
#ifndef __JUCE_VOIDARRAY_JUCEHEADER__
|
|
#define __JUCE_VOIDARRAY_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Array.h *********/
|
|
#ifndef __JUCE_ARRAY_JUCEHEADER__
|
|
#define __JUCE_ARRAY_JUCEHEADER__
|
|
|
|
/**
|
|
Holds a list of primitive objects, such as ints, doubles, or pointers.
|
|
|
|
Examples of arrays are: Array<int> or Array<MyClass*>
|
|
|
|
Note that when holding pointers to objects, the array doesn't take any ownership
|
|
of the objects - for doing this, see the OwnedArray class or the ReferenceCountedArray class.
|
|
|
|
If you're using a class or struct as the element type, it must be
|
|
capable of being copied or moved with a straightforward memcpy, rather than
|
|
needing construction and destruction code.
|
|
|
|
For holding lists of strings, use the specialised class StringArray.
|
|
|
|
To make all the array's methods thread-safe, pass in "CriticalSection" as the templated
|
|
TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.
|
|
|
|
@see OwnedArray, ReferenceCountedArray, StringArray, CriticalSection
|
|
*/
|
|
template <class ElementType, class TypeOfCriticalSectionToUse = DummyCriticalSection>
|
|
class Array : private ArrayAllocationBase <ElementType>
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty array.
|
|
|
|
@param granularity this is the size of increment by which the internal storage
|
|
used by the array will grow. Only change it from the default if you know the
|
|
array is going to be very big and needs to be able to grow efficiently.
|
|
|
|
@see ArrayAllocationBase
|
|
*/
|
|
Array (const int granularity = juceDefaultArrayGranularity) throw()
|
|
: ArrayAllocationBase <ElementType> (granularity),
|
|
numUsed (0)
|
|
{
|
|
}
|
|
|
|
/** Creates a copy of another array.
|
|
@param other the array to copy
|
|
*/
|
|
Array (const Array<ElementType, TypeOfCriticalSectionToUse>& other) throw()
|
|
: ArrayAllocationBase <ElementType> (other.granularity)
|
|
{
|
|
other.lockArray();
|
|
numUsed = other.numUsed;
|
|
this->setAllocatedSize (other.numUsed);
|
|
memcpy (this->elements, other.elements, numUsed * sizeof (ElementType));
|
|
other.unlockArray();
|
|
}
|
|
|
|
/** Initalises from a null-terminated C array of values.
|
|
|
|
@param values the array to copy from
|
|
*/
|
|
Array (const ElementType* values) throw()
|
|
: ArrayAllocationBase <ElementType> (juceDefaultArrayGranularity),
|
|
numUsed (0)
|
|
{
|
|
while (*values != 0)
|
|
add (*values++);
|
|
}
|
|
|
|
/** Initalises from a C array of values.
|
|
|
|
@param values the array to copy from
|
|
@param numValues the number of values in the array
|
|
*/
|
|
Array (const ElementType* values, int numValues) throw()
|
|
: ArrayAllocationBase <ElementType> (juceDefaultArrayGranularity),
|
|
numUsed (numValues)
|
|
{
|
|
this->setAllocatedSize (numValues);
|
|
memcpy (this->elements, values, numValues * sizeof (ElementType));
|
|
}
|
|
|
|
/** Destructor. */
|
|
~Array() throw()
|
|
{
|
|
}
|
|
|
|
/** Copies another array.
|
|
@param other the array to copy
|
|
*/
|
|
const Array <ElementType, TypeOfCriticalSectionToUse>& operator= (const Array <ElementType, TypeOfCriticalSectionToUse>& other) throw()
|
|
{
|
|
if (this != &other)
|
|
{
|
|
other.lockArray();
|
|
lock.enter();
|
|
|
|
this->granularity = other.granularity;
|
|
this->ensureAllocatedSize (other.size());
|
|
numUsed = other.numUsed;
|
|
memcpy (this->elements, other.elements, this->numUsed * sizeof (ElementType));
|
|
minimiseStorageOverheads();
|
|
|
|
lock.exit();
|
|
other.unlockArray();
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
/** Compares this array to another one.
|
|
Two arrays are considered equal if they both contain the same set of
|
|
elements, in the same order.
|
|
@param other the other array to compare with
|
|
*/
|
|
template <class OtherArrayType>
|
|
bool operator== (const OtherArrayType& other) const throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (this->numUsed != other.numUsed)
|
|
{
|
|
lock.exit();
|
|
return false;
|
|
}
|
|
|
|
for (int i = numUsed; --i >= 0;)
|
|
{
|
|
if (this->elements [i] != other.elements [i])
|
|
{
|
|
lock.exit();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
lock.exit();
|
|
return true;
|
|
}
|
|
|
|
/** Compares this array to another one.
|
|
Two arrays are considered equal if they both contain the same set of
|
|
elements, in the same order.
|
|
@param other the other array to compare with
|
|
*/
|
|
template <class OtherArrayType>
|
|
bool operator!= (const OtherArrayType& other) const throw()
|
|
{
|
|
return ! operator== (other);
|
|
}
|
|
|
|
/** Removes all elements from the array.
|
|
This will remove all the elements, and free any storage that the array is
|
|
using. To clear the array without freeing the storage, use the clearQuick()
|
|
method instead.
|
|
|
|
@see clearQuick
|
|
*/
|
|
void clear() throw()
|
|
{
|
|
lock.enter();
|
|
this->setAllocatedSize (0);
|
|
numUsed = 0;
|
|
lock.exit();
|
|
}
|
|
|
|
/** Removes all elements from the array without freeing the array's allocated storage.
|
|
|
|
@see clear
|
|
*/
|
|
void clearQuick() throw()
|
|
{
|
|
lock.enter();
|
|
numUsed = 0;
|
|
lock.exit();
|
|
}
|
|
|
|
/** Returns the current number of elements in the array.
|
|
*/
|
|
inline int size() const throw()
|
|
{
|
|
return numUsed;
|
|
}
|
|
|
|
/** Returns one of the elements in the array.
|
|
If the index passed in is beyond the range of valid elements, this
|
|
will return zero.
|
|
|
|
If you're certain that the index will always be a valid element, you
|
|
can call getUnchecked() instead, which is faster.
|
|
|
|
@param index the index of the element being requested (0 is the first element in the array)
|
|
@see getUnchecked, getFirst, getLast
|
|
*/
|
|
inline ElementType operator[] (const int index) const throw()
|
|
{
|
|
lock.enter();
|
|
const ElementType result = (((unsigned int) index) < (unsigned int) numUsed)
|
|
? this->elements [index]
|
|
: ElementType();
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Returns one of the elements in the array, without checking the index passed in.
|
|
|
|
Unlike the operator[] method, this will try to return an element without
|
|
checking that the index is within the bounds of the array, so should only
|
|
be used when you're confident that it will always be a valid index.
|
|
|
|
@param index the index of the element being requested (0 is the first element in the array)
|
|
@see operator[], getFirst, getLast
|
|
*/
|
|
inline ElementType getUnchecked (const int index) const throw()
|
|
{
|
|
lock.enter();
|
|
jassert (((unsigned int) index) < (unsigned int) numUsed);
|
|
const ElementType result = this->elements [index];
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Returns a direct reference to one of the elements in the array, without checking the index passed in.
|
|
|
|
This is like getUnchecked, but returns a direct reference to the element, so that
|
|
you can alter it directly. Obviously this can be dangerous, so only use it when
|
|
absolutely necessary.
|
|
|
|
@param index the index of the element being requested (0 is the first element in the array)
|
|
@see operator[], getFirst, getLast
|
|
*/
|
|
inline ElementType& getReference (const int index) const throw()
|
|
{
|
|
lock.enter();
|
|
jassert (((unsigned int) index) < (unsigned int) numUsed);
|
|
ElementType& result = this->elements [index];
|
|
lock.exit();
|
|
return result;
|
|
}
|
|
|
|
/** Returns the first element in the array, or 0 if the array is empty.
|
|
|
|
@see operator[], getUnchecked, getLast
|
|
*/
|
|
inline ElementType getFirst() const throw()
|
|
{
|
|
lock.enter();
|
|
const ElementType result = (numUsed > 0) ? this->elements [0]
|
|
: ElementType();
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Returns the last element in the array, or 0 if the array is empty.
|
|
|
|
@see operator[], getUnchecked, getFirst
|
|
*/
|
|
inline ElementType getLast() const throw()
|
|
{
|
|
lock.enter();
|
|
const ElementType result = (numUsed > 0) ? this->elements [numUsed - 1]
|
|
: ElementType();
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Finds the index of the first element which matches the value passed in.
|
|
|
|
This will search the array for the given object, and return the index
|
|
of its first occurrence. If the object isn't found, the method will return -1.
|
|
|
|
@param elementToLookFor the value or object to look for
|
|
@returns the index of the object, or -1 if it's not found
|
|
*/
|
|
int indexOf (const ElementType elementToLookFor) const throw()
|
|
{
|
|
int result = -1;
|
|
|
|
lock.enter();
|
|
const ElementType* e = this->elements;
|
|
|
|
for (int i = numUsed; --i >= 0;)
|
|
{
|
|
if (elementToLookFor == *e)
|
|
{
|
|
result = (int) (e - this->elements);
|
|
break;
|
|
}
|
|
|
|
++e;
|
|
}
|
|
|
|
lock.exit();
|
|
return result;
|
|
}
|
|
|
|
/** Returns true if the array contains at least one occurrence of an object.
|
|
|
|
@param elementToLookFor the value or object to look for
|
|
@returns true if the item is found
|
|
*/
|
|
bool contains (const ElementType elementToLookFor) const throw()
|
|
{
|
|
lock.enter();
|
|
|
|
const ElementType* e = this->elements;
|
|
int num = numUsed;
|
|
|
|
while (num >= 4)
|
|
{
|
|
if (*e == elementToLookFor
|
|
|| *++e == elementToLookFor
|
|
|| *++e == elementToLookFor
|
|
|| *++e == elementToLookFor)
|
|
{
|
|
lock.exit();
|
|
return true;
|
|
}
|
|
|
|
num -= 4;
|
|
++e;
|
|
}
|
|
|
|
while (num > 0)
|
|
{
|
|
if (elementToLookFor == *e)
|
|
{
|
|
lock.exit();
|
|
return true;
|
|
}
|
|
|
|
--num;
|
|
++e;
|
|
}
|
|
|
|
lock.exit();
|
|
return false;
|
|
}
|
|
|
|
/** Appends a new element at the end of the array.
|
|
|
|
@param newElement the new object to add to the array
|
|
@see set, insert, addIfNotAlreadyThere, addSorted, addArray
|
|
*/
|
|
void add (const ElementType newElement) throw()
|
|
{
|
|
lock.enter();
|
|
this->ensureAllocatedSize (numUsed + 1);
|
|
this->elements [numUsed++] = newElement;
|
|
lock.exit();
|
|
}
|
|
|
|
/** Inserts a new element into the array at a given position.
|
|
|
|
If the index is less than 0 or greater than the size of the array, the
|
|
element will be added to the end of the array.
|
|
Otherwise, it will be inserted into the array, moving all the later elements
|
|
along to make room.
|
|
|
|
@param indexToInsertAt the index at which the new element should be
|
|
inserted (pass in -1 to add it to the end)
|
|
@param newElement the new object to add to the array
|
|
@see add, addSorted, set
|
|
*/
|
|
void insert (int indexToInsertAt, const ElementType newElement) throw()
|
|
{
|
|
lock.enter();
|
|
this->ensureAllocatedSize (numUsed + 1);
|
|
|
|
if (((unsigned int) indexToInsertAt) < (unsigned int) numUsed)
|
|
{
|
|
ElementType* const insertPos = this->elements + indexToInsertAt;
|
|
const int numberToMove = numUsed - indexToInsertAt;
|
|
|
|
if (numberToMove > 0)
|
|
memmove (insertPos + 1, insertPos, numberToMove * sizeof (ElementType));
|
|
|
|
*insertPos = newElement;
|
|
++numUsed;
|
|
}
|
|
else
|
|
{
|
|
this->elements [numUsed++] = newElement;
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Inserts multiple copies of an element into the array at a given position.
|
|
|
|
If the index is less than 0 or greater than the size of the array, the
|
|
element will be added to the end of the array.
|
|
Otherwise, it will be inserted into the array, moving all the later elements
|
|
along to make room.
|
|
|
|
@param indexToInsertAt the index at which the new element should be inserted
|
|
@param newElement the new object to add to the array
|
|
@param numberOfTimesToInsertIt how many copies of the value to insert
|
|
@see insert, add, addSorted, set
|
|
*/
|
|
void insertMultiple (int indexToInsertAt, const ElementType newElement,
|
|
int numberOfTimesToInsertIt) throw()
|
|
{
|
|
if (numberOfTimesToInsertIt > 0)
|
|
{
|
|
lock.enter();
|
|
this->ensureAllocatedSize (numUsed + numberOfTimesToInsertIt);
|
|
|
|
if (((unsigned int) indexToInsertAt) < (unsigned int) numUsed)
|
|
{
|
|
ElementType* insertPos = this->elements + indexToInsertAt;
|
|
const int numberToMove = numUsed - indexToInsertAt;
|
|
|
|
memmove (insertPos + numberOfTimesToInsertIt, insertPos, numberToMove * sizeof (ElementType));
|
|
numUsed += numberOfTimesToInsertIt;
|
|
|
|
while (--numberOfTimesToInsertIt >= 0)
|
|
*insertPos++ = newElement;
|
|
}
|
|
else
|
|
{
|
|
while (--numberOfTimesToInsertIt >= 0)
|
|
this->elements [numUsed++] = newElement;
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
}
|
|
|
|
/** Inserts an array of values into this array at a given position.
|
|
|
|
If the index is less than 0 or greater than the size of the array, the
|
|
new elements will be added to the end of the array.
|
|
Otherwise, they will be inserted into the array, moving all the later elements
|
|
along to make room.
|
|
|
|
@param indexToInsertAt the index at which the first new element should be inserted
|
|
@param newElements the new values to add to the array
|
|
@param numberOfElements how many items are in the array
|
|
@see insert, add, addSorted, set
|
|
*/
|
|
void insertArray (int indexToInsertAt,
|
|
const ElementType* newElements,
|
|
int numberOfElements) throw()
|
|
{
|
|
if (numberOfElements > 0)
|
|
{
|
|
lock.enter();
|
|
this->ensureAllocatedSize (numUsed + numberOfElements);
|
|
|
|
if (((unsigned int) indexToInsertAt) < (unsigned int) numUsed)
|
|
{
|
|
ElementType* insertPos = this->elements + indexToInsertAt;
|
|
const int numberToMove = numUsed - indexToInsertAt;
|
|
|
|
memmove (insertPos + numberOfElements, insertPos, numberToMove * sizeof (ElementType));
|
|
numUsed += numberOfElements;
|
|
|
|
while (--numberOfElements >= 0)
|
|
*insertPos++ = *newElements++;
|
|
}
|
|
else
|
|
{
|
|
while (--numberOfElements >= 0)
|
|
this->elements [numUsed++] = *newElements++;
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
}
|
|
|
|
/** Appends a new element at the end of the array as long as the array doesn't
|
|
already contain it.
|
|
|
|
If the array already contains an element that matches the one passed in, nothing
|
|
will be done.
|
|
|
|
@param newElement the new object to add to the array
|
|
*/
|
|
void addIfNotAlreadyThere (const ElementType newElement) throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (! contains (newElement))
|
|
add (newElement);
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Replaces an element with a new value.
|
|
|
|
If the index is less than zero, this method does nothing.
|
|
If the index is beyond the end of the array, the item is added to the end of the array.
|
|
|
|
@param indexToChange the index whose value you want to change
|
|
@param newValue the new value to set for this index.
|
|
@see add, insert
|
|
*/
|
|
void set (const int indexToChange,
|
|
const ElementType newValue) throw()
|
|
{
|
|
jassert (indexToChange >= 0);
|
|
|
|
if (indexToChange >= 0)
|
|
{
|
|
lock.enter();
|
|
|
|
if (indexToChange < numUsed)
|
|
{
|
|
this->elements [indexToChange] = newValue;
|
|
}
|
|
else
|
|
{
|
|
this->ensureAllocatedSize (numUsed + 1);
|
|
this->elements [numUsed++] = newValue;
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
}
|
|
|
|
/** Replaces an element with a new value without doing any bounds-checking.
|
|
|
|
This just sets a value directly in the array's internal storage, so you'd
|
|
better make sure it's in range!
|
|
|
|
@param indexToChange the index whose value you want to change
|
|
@param newValue the new value to set for this index.
|
|
@see set, getUnchecked
|
|
*/
|
|
void setUnchecked (const int indexToChange,
|
|
const ElementType newValue) throw()
|
|
{
|
|
lock.enter();
|
|
jassert (((unsigned int) indexToChange) < (unsigned int) numUsed);
|
|
this->elements [indexToChange] = newValue;
|
|
lock.exit();
|
|
}
|
|
|
|
/** Adds elements from an array to the end of this array.
|
|
|
|
@param elementsToAdd the array of elements to add
|
|
@param numElementsToAdd how many elements are in this other array
|
|
@see add
|
|
*/
|
|
void addArray (const ElementType* elementsToAdd,
|
|
int numElementsToAdd) throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (numElementsToAdd > 0)
|
|
{
|
|
this->ensureAllocatedSize (numUsed + numElementsToAdd);
|
|
|
|
while (--numElementsToAdd >= 0)
|
|
this->elements [numUsed++] = *elementsToAdd++;
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** This swaps the contents of this array with those of another array.
|
|
|
|
If you need to exchange two arrays, this is vastly quicker than using copy-by-value
|
|
because it just swaps their internal pointers.
|
|
*/
|
|
template <class OtherArrayType>
|
|
void swapWithArray (OtherArrayType& otherArray) throw()
|
|
{
|
|
lock.enter();
|
|
otherArray.lock.enter();
|
|
swapVariables <int> (this->numUsed, otherArray.numUsed);
|
|
swapVariables <ElementType*> (this->elements, otherArray.elements);
|
|
swapVariables <int> (this->numAllocated, otherArray.numAllocated);
|
|
otherArray.lock.exit();
|
|
lock.exit();
|
|
}
|
|
|
|
/** Adds elements from another array to the end of this array.
|
|
|
|
@param arrayToAddFrom the array from which to copy the elements
|
|
@param startIndex the first element of the other array to start copying from
|
|
@param numElementsToAdd how many elements to add from the other array. If this
|
|
value is negative or greater than the number of available elements,
|
|
all available elements will be copied.
|
|
@see add
|
|
*/
|
|
template <class OtherArrayType>
|
|
void addArray (const OtherArrayType& arrayToAddFrom,
|
|
int startIndex = 0,
|
|
int numElementsToAdd = -1) throw()
|
|
{
|
|
arrayToAddFrom.lockArray();
|
|
lock.enter();
|
|
jassert (this != &arrayToAddFrom);
|
|
|
|
if (startIndex < 0)
|
|
{
|
|
jassertfalse
|
|
startIndex = 0;
|
|
}
|
|
|
|
if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size())
|
|
numElementsToAdd = arrayToAddFrom.size() - startIndex;
|
|
|
|
this->addArray ((const ElementType*) (arrayToAddFrom.elements + startIndex), numElementsToAdd);
|
|
|
|
lock.exit();
|
|
arrayToAddFrom.unlockArray();
|
|
}
|
|
|
|
/** Inserts a new element into the array, assuming that the array is sorted.
|
|
|
|
This will use a comparator to find the position at which the new element
|
|
should go. If the array isn't sorted, the behaviour of this
|
|
method will be unpredictable.
|
|
|
|
@param comparator the comparator to use to compare the elements - see the sort()
|
|
method for details about the form this object should take
|
|
@param newElement the new element to insert to the array
|
|
@see add, sort
|
|
*/
|
|
template <class ElementComparator>
|
|
void addSorted (ElementComparator& comparator,
|
|
const ElementType newElement) throw()
|
|
{
|
|
lock.enter();
|
|
insert (findInsertIndexInSortedArray (comparator, this->elements, newElement, 0, numUsed), newElement);
|
|
lock.exit();
|
|
}
|
|
|
|
/** Finds the index of an element in the array, assuming that the array is sorted.
|
|
|
|
This will use a comparator to do a binary-chop to find the index of the given
|
|
element, if it exists. If the array isn't sorted, the behaviour of this
|
|
method will be unpredictable.
|
|
|
|
@param comparator the comparator to use to compare the elements - see the sort()
|
|
method for details about the form this object should take
|
|
@param elementToLookFor the element to search for
|
|
@returns the index of the element, or -1 if it's not found
|
|
@see addSorted, sort
|
|
*/
|
|
template <class ElementComparator>
|
|
int indexOfSorted (ElementComparator& comparator,
|
|
const ElementType elementToLookFor) const throw()
|
|
{
|
|
(void) comparator; // if you pass in an object with a static compareElements() method, this
|
|
// avoids getting warning messages about the parameter being unused
|
|
lock.enter();
|
|
|
|
int start = 0;
|
|
int end = numUsed;
|
|
|
|
for (;;)
|
|
{
|
|
if (start >= end)
|
|
{
|
|
lock.exit();
|
|
return -1;
|
|
}
|
|
else if (comparator.compareElements (elementToLookFor, this->elements [start]) == 0)
|
|
{
|
|
lock.exit();
|
|
return start;
|
|
}
|
|
else
|
|
{
|
|
const int halfway = (start + end) >> 1;
|
|
|
|
if (halfway == start)
|
|
{
|
|
lock.exit();
|
|
return -1;
|
|
}
|
|
else if (comparator.compareElements (elementToLookFor, this->elements [halfway]) >= 0)
|
|
start = halfway;
|
|
else
|
|
end = halfway;
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Removes an element from the array.
|
|
|
|
This will remove the element at a given index, and move back
|
|
all the subsequent elements to close the gap.
|
|
If the index passed in is out-of-range, nothing will happen.
|
|
|
|
@param indexToRemove the index of the element to remove
|
|
@returns the element that has been removed
|
|
@see removeValue, removeRange
|
|
*/
|
|
ElementType remove (const int indexToRemove) throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (((unsigned int) indexToRemove) < (unsigned int) numUsed)
|
|
{
|
|
--numUsed;
|
|
|
|
ElementType* const e = this->elements + indexToRemove;
|
|
ElementType const removed = *e;
|
|
const int numberToShift = numUsed - indexToRemove;
|
|
|
|
if (numberToShift > 0)
|
|
memmove (e, e + 1, numberToShift * sizeof (ElementType));
|
|
|
|
if ((numUsed << 1) < this->numAllocated)
|
|
minimiseStorageOverheads();
|
|
|
|
lock.exit();
|
|
return removed;
|
|
}
|
|
else
|
|
{
|
|
lock.exit();
|
|
return ElementType();
|
|
}
|
|
}
|
|
|
|
/** Removes an item from the array.
|
|
|
|
This will remove the first occurrence of the given element from the array.
|
|
If the item isn't found, no action is taken.
|
|
|
|
@param valueToRemove the object to try to remove
|
|
@see remove, removeRange
|
|
*/
|
|
void removeValue (const ElementType valueToRemove) throw()
|
|
{
|
|
lock.enter();
|
|
ElementType* e = this->elements;
|
|
|
|
for (int i = numUsed; --i >= 0;)
|
|
{
|
|
if (valueToRemove == *e)
|
|
{
|
|
remove ((int) (e - this->elements));
|
|
break;
|
|
}
|
|
|
|
++e;
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Removes a range of elements from the array.
|
|
|
|
This will remove a set of elements, starting from the given index,
|
|
and move subsequent elements down to close the gap.
|
|
|
|
If the range extends beyond the bounds of the array, it will
|
|
be safely clipped to the size of the array.
|
|
|
|
@param startIndex the index of the first element to remove
|
|
@param numberToRemove how many elements should be removed
|
|
@see remove, removeValue
|
|
*/
|
|
void removeRange (int startIndex,
|
|
const int numberToRemove) throw()
|
|
{
|
|
lock.enter();
|
|
const int endIndex = jlimit (0, numUsed, startIndex + numberToRemove);
|
|
startIndex = jlimit (0, numUsed, startIndex);
|
|
|
|
if (endIndex > startIndex)
|
|
{
|
|
const int rangeSize = endIndex - startIndex;
|
|
ElementType* e = this->elements + startIndex;
|
|
int numToShift = numUsed - endIndex;
|
|
numUsed -= rangeSize;
|
|
|
|
while (--numToShift >= 0)
|
|
{
|
|
*e = e [rangeSize];
|
|
++e;
|
|
}
|
|
|
|
if ((numUsed << 1) < this->numAllocated)
|
|
minimiseStorageOverheads();
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Removes the last n elements from the array.
|
|
|
|
@param howManyToRemove how many elements to remove from the end of the array
|
|
@see remove, removeValue, removeRange
|
|
*/
|
|
void removeLast (const int howManyToRemove = 1) throw()
|
|
{
|
|
lock.enter();
|
|
numUsed = jmax (0, numUsed - howManyToRemove);
|
|
|
|
if ((numUsed << 1) < this->numAllocated)
|
|
minimiseStorageOverheads();
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Removes any elements which are also in another array.
|
|
|
|
@param otherArray the other array in which to look for elements to remove
|
|
@see removeValuesNotIn, remove, removeValue, removeRange
|
|
*/
|
|
template <class OtherArrayType>
|
|
void removeValuesIn (const OtherArrayType& otherArray) throw()
|
|
{
|
|
otherArray.lockArray();
|
|
lock.enter();
|
|
|
|
if (this == &otherArray)
|
|
{
|
|
clear();
|
|
}
|
|
else
|
|
{
|
|
if (otherArray.size() > 0)
|
|
{
|
|
for (int i = numUsed; --i >= 0;)
|
|
if (otherArray.contains (this->elements [i]))
|
|
remove (i);
|
|
}
|
|
}
|
|
|
|
lock.exit();
|
|
otherArray.unlockArray();
|
|
}
|
|
|
|
/** Removes any elements which are not found in another array.
|
|
|
|
Only elements which occur in this other array will be retained.
|
|
|
|
@param otherArray the array in which to look for elements NOT to remove
|
|
@see removeValuesIn, remove, removeValue, removeRange
|
|
*/
|
|
template <class OtherArrayType>
|
|
void removeValuesNotIn (const OtherArrayType& otherArray) throw()
|
|
{
|
|
otherArray.lockArray();
|
|
lock.enter();
|
|
|
|
if (this != &otherArray)
|
|
{
|
|
if (otherArray.size() <= 0)
|
|
{
|
|
clear();
|
|
}
|
|
else
|
|
{
|
|
for (int i = numUsed; --i >= 0;)
|
|
if (! otherArray.contains (this->elements [i]))
|
|
remove (i);
|
|
}
|
|
}
|
|
|
|
lock.exit();
|
|
otherArray.unlockArray();
|
|
}
|
|
|
|
/** Swaps over two elements in the array.
|
|
|
|
This swaps over the elements found at the two indexes passed in.
|
|
If either index is out-of-range, this method will do nothing.
|
|
|
|
@param index1 index of one of the elements to swap
|
|
@param index2 index of the other element to swap
|
|
*/
|
|
void swap (const int index1,
|
|
const int index2) throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (((unsigned int) index1) < (unsigned int) numUsed
|
|
&& ((unsigned int) index2) < (unsigned int) numUsed)
|
|
{
|
|
swapVariables (this->elements [index1],
|
|
this->elements [index2]);
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Moves one of the values to a different position.
|
|
|
|
This will move the value to a specified index, shuffling along
|
|
any intervening elements as required.
|
|
|
|
So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling
|
|
move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }.
|
|
|
|
@param currentIndex the index of the value to be moved. If this isn't a
|
|
valid index, then nothing will be done
|
|
@param newIndex the index at which you'd like this value to end up. If this
|
|
is less than zero, the value will be moved to the end
|
|
of the array
|
|
*/
|
|
void move (const int currentIndex,
|
|
int newIndex) throw()
|
|
{
|
|
if (currentIndex != newIndex)
|
|
{
|
|
lock.enter();
|
|
|
|
if (((unsigned int) currentIndex) < (unsigned int) numUsed)
|
|
{
|
|
if (((unsigned int) newIndex) >= (unsigned int) numUsed)
|
|
newIndex = numUsed - 1;
|
|
|
|
const ElementType value = this->elements [currentIndex];
|
|
|
|
if (newIndex > currentIndex)
|
|
{
|
|
memmove (this->elements + currentIndex,
|
|
this->elements + currentIndex + 1,
|
|
(newIndex - currentIndex) * sizeof (ElementType));
|
|
}
|
|
else
|
|
{
|
|
memmove (this->elements + newIndex + 1,
|
|
this->elements + newIndex,
|
|
(currentIndex - newIndex) * sizeof (ElementType));
|
|
}
|
|
|
|
this->elements [newIndex] = value;
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
}
|
|
|
|
/** Reduces the amount of storage being used by the array.
|
|
|
|
Arrays typically allocate slightly more storage than they need, and after
|
|
removing elements, they may have quite a lot of unused space allocated.
|
|
This method will reduce the amount of allocated storage to a minimum.
|
|
*/
|
|
void minimiseStorageOverheads() throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (numUsed == 0)
|
|
{
|
|
this->setAllocatedSize (0);
|
|
}
|
|
else
|
|
{
|
|
const int newAllocation = this->granularity * (numUsed / this->granularity + 1);
|
|
|
|
if (newAllocation < this->numAllocated)
|
|
this->setAllocatedSize (newAllocation);
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Increases the array's internal storage to hold a minimum number of elements.
|
|
|
|
Calling this before adding a large known number of elements means that
|
|
the array won't have to keep dynamically resizing itself as the elements
|
|
are added, and it'll therefore be more efficient.
|
|
*/
|
|
void ensureStorageAllocated (const int minNumElements) throw()
|
|
{
|
|
this->ensureAllocatedSize (minNumElements);
|
|
}
|
|
|
|
/** Sorts the elements in the array.
|
|
|
|
This will use a comparator object to sort the elements into order. The object
|
|
passed must have a method of the form:
|
|
@code
|
|
int compareElements (ElementType first, ElementType second);
|
|
@endcode
|
|
|
|
..and this method must return:
|
|
- a value of < 0 if the first comes before the second
|
|
- a value of 0 if the two objects are equivalent
|
|
- a value of > 0 if the second comes before the first
|
|
|
|
To improve performance, the compareElements() method can be declared as static or const.
|
|
|
|
@param comparator the comparator to use for comparing elements.
|
|
@param retainOrderOfEquivalentItems if this is true, then items
|
|
which the comparator says are equivalent will be
|
|
kept in the order in which they currently appear
|
|
in the array. This is slower to perform, but may
|
|
be important in some cases. If it's false, a faster
|
|
algorithm is used, but equivalent elements may be
|
|
rearranged.
|
|
|
|
@see addSorted, indexOfSorted, sortArray
|
|
*/
|
|
template <class ElementComparator>
|
|
void sort (ElementComparator& comparator,
|
|
const bool retainOrderOfEquivalentItems = false) const throw()
|
|
{
|
|
(void) comparator; // if you pass in an object with a static compareElements() method, this
|
|
// avoids getting warning messages about the parameter being unused
|
|
lock.enter();
|
|
sortArray (comparator, this->elements, 0, size() - 1, retainOrderOfEquivalentItems);
|
|
lock.exit();
|
|
}
|
|
|
|
/** Locks the array's CriticalSection.
|
|
|
|
Of course if the type of section used is a DummyCriticalSection, this won't
|
|
have any effect.
|
|
|
|
@see unlockArray
|
|
*/
|
|
void lockArray() const throw()
|
|
{
|
|
lock.enter();
|
|
}
|
|
|
|
/** Unlocks the array's CriticalSection.
|
|
|
|
Of course if the type of section used is a DummyCriticalSection, this won't
|
|
have any effect.
|
|
|
|
@see lockArray
|
|
*/
|
|
void unlockArray() const throw()
|
|
{
|
|
lock.exit();
|
|
}
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int numUsed;
|
|
TypeOfCriticalSectionToUse lock;
|
|
};
|
|
|
|
#endif // __JUCE_ARRAY_JUCEHEADER__
|
|
/********* End of inlined file: juce_Array.h *********/
|
|
|
|
/**
|
|
A typedef for an Array of void*'s.
|
|
|
|
VoidArrays are used in various places throughout the library instead of
|
|
more strongly-typed arrays, to keep code-size low.
|
|
*/
|
|
typedef Array <void*> VoidArray;
|
|
|
|
#endif // __JUCE_VOIDARRAY_JUCEHEADER__
|
|
/********* End of inlined file: juce_VoidArray.h *********/
|
|
|
|
#ifndef DOXYGEN
|
|
// (used in StringArray::appendNumbersToDuplicates)
|
|
static const tchar* const defaultPreNumberString = JUCE_T(" (");
|
|
static const tchar* const defaultPostNumberString = JUCE_T(")");
|
|
#endif
|
|
|
|
/**
|
|
A special array for holding a list of strings.
|
|
|
|
@see String, StringPairArray
|
|
*/
|
|
class JUCE_API StringArray
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty string array */
|
|
StringArray() throw();
|
|
|
|
/** Creates a copy of another string array */
|
|
StringArray (const StringArray& other) throw();
|
|
|
|
/** Creates a copy of an array of string literals.
|
|
|
|
@param strings an array of strings to add. Null pointers in the array will be
|
|
treated as empty strings
|
|
@param numberOfStrings how many items there are in the array
|
|
*/
|
|
StringArray (const juce_wchar** const strings,
|
|
const int numberOfStrings) throw();
|
|
|
|
/** Creates a copy of an array of string literals.
|
|
|
|
@param strings an array of strings to add. Null pointers in the array will be
|
|
treated as empty strings
|
|
@param numberOfStrings how many items there are in the array
|
|
*/
|
|
StringArray (const char** const strings,
|
|
const int numberOfStrings) throw();
|
|
|
|
/** Creates a copy of a null-terminated array of string literals.
|
|
|
|
Each item from the array passed-in is added, until it encounters a null pointer,
|
|
at which point it stops.
|
|
*/
|
|
StringArray (const juce_wchar** const strings) throw();
|
|
|
|
/** Creates a copy of a null-terminated array of string literals.
|
|
|
|
Each item from the array passed-in is added, until it encounters a null pointer,
|
|
at which point it stops.
|
|
*/
|
|
StringArray (const char** const strings) throw();
|
|
|
|
/** Destructor. */
|
|
virtual ~StringArray() throw();
|
|
|
|
/** Copies the contents of another string array into this one */
|
|
const StringArray& operator= (const StringArray& other) throw();
|
|
|
|
/** Compares two arrays.
|
|
|
|
Comparisons are case-sensitive.
|
|
|
|
@returns true only if the other array contains exactly the same strings in the same order
|
|
*/
|
|
bool operator== (const StringArray& other) const throw();
|
|
|
|
/** Compares two arrays.
|
|
|
|
Comparisons are case-sensitive.
|
|
|
|
@returns false if the other array contains exactly the same strings in the same order
|
|
*/
|
|
bool operator!= (const StringArray& other) const throw();
|
|
|
|
/** Returns the number of strings in the array */
|
|
inline int size() const throw() { return strings.size(); };
|
|
|
|
/** Returns one of the strings from the array.
|
|
|
|
If the index is out-of-range, an empty string is returned.
|
|
|
|
Obviously the reference returned shouldn't be stored for later use, as the
|
|
string it refers to may disappear when the array changes.
|
|
*/
|
|
const String& operator[] (const int index) const throw();
|
|
|
|
/** Searches for a string in the array.
|
|
|
|
The comparison will be case-insensitive if the ignoreCase parameter is true.
|
|
|
|
@returns true if the string is found inside the array
|
|
*/
|
|
bool contains (const String& stringToLookFor,
|
|
const bool ignoreCase = false) const throw();
|
|
|
|
/** Searches for a string in the array.
|
|
|
|
The comparison will be case-insensitive if the ignoreCase parameter is true.
|
|
|
|
@param stringToLookFor the string to try to find
|
|
@param ignoreCase whether the comparison should be case-insensitive
|
|
@param startIndex the first index to start searching from
|
|
@returns the index of the first occurrence of the string in this array,
|
|
or -1 if it isn't found.
|
|
*/
|
|
int indexOf (const String& stringToLookFor,
|
|
const bool ignoreCase = false,
|
|
int startIndex = 0) const throw();
|
|
|
|
/** Appends a string at the end of the array. */
|
|
void add (const String& stringToAdd) throw();
|
|
|
|
/** Inserts a string into the array.
|
|
|
|
This will insert a string into the array at the given index, moving
|
|
up the other elements to make room for it.
|
|
If the index is less than zero or greater than the size of the array,
|
|
the new string will be added to the end of the array.
|
|
*/
|
|
void insert (const int index,
|
|
const String& stringToAdd) throw();
|
|
|
|
/** Adds a string to the array as long as it's not already in there.
|
|
|
|
The search can optionally be case-insensitive.
|
|
*/
|
|
void addIfNotAlreadyThere (const String& stringToAdd,
|
|
const bool ignoreCase = false) throw();
|
|
|
|
/** Replaces one of the strings in the array with another one.
|
|
|
|
If the index is higher than the array's size, the new string will be
|
|
added to the end of the array; if it's less than zero nothing happens.
|
|
*/
|
|
void set (const int index,
|
|
const String& newString) throw();
|
|
|
|
/** Appends some strings from another array to the end of this one.
|
|
|
|
@param other the array to add
|
|
@param startIndex the first element of the other array to add
|
|
@param numElementsToAdd the maximum number of elements to add (if this is
|
|
less than zero, they are all added)
|
|
*/
|
|
void addArray (const StringArray& other,
|
|
int startIndex = 0,
|
|
int numElementsToAdd = -1) throw();
|
|
|
|
/** Breaks up a string into tokens and adds them to this array.
|
|
|
|
This will tokenise the given string using whitespace characters as the
|
|
token delimiters, and will add these tokens to the end of the array.
|
|
|
|
@returns the number of tokens added
|
|
*/
|
|
int addTokens (const tchar* const stringToTokenise,
|
|
const bool preserveQuotedStrings) throw();
|
|
|
|
/** Breaks up a string into tokens and adds them to this array.
|
|
|
|
This will tokenise the given string (using the string passed in to define the
|
|
token delimiters), and will add these tokens to the end of the array.
|
|
|
|
@param stringToTokenise the string to tokenise
|
|
@param breakCharacters a string of characters, any of which will be considered
|
|
to be a token delimiter.
|
|
@param quoteCharacters if this string isn't empty, it defines a set of characters
|
|
which are treated as quotes. Any text occurring
|
|
between quotes is not broken up into tokens.
|
|
@returns the number of tokens added
|
|
*/
|
|
int addTokens (const tchar* const stringToTokenise,
|
|
const tchar* breakCharacters,
|
|
const tchar* quoteCharacters) throw();
|
|
|
|
/** Breaks up a string into lines and adds them to this array.
|
|
|
|
This breaks a string down into lines separated by \\n or \\r\\n, and adds each line
|
|
to the array. Line-break characters are omitted from the strings that are added to
|
|
the array.
|
|
*/
|
|
int addLines (const tchar* stringToBreakUp) throw();
|
|
|
|
/** Removes all elements from the array. */
|
|
void clear() throw();
|
|
|
|
/** Removes a string from the array.
|
|
|
|
If the index is out-of-range, no action will be taken.
|
|
*/
|
|
void remove (const int index) throw();
|
|
|
|
/** Finds a string in the array and removes it.
|
|
|
|
This will remove the first occurrence of the given string from the array. The
|
|
comparison may be case-insensitive depending on the ignoreCase parameter.
|
|
*/
|
|
void removeString (const String& stringToRemove,
|
|
const bool ignoreCase = false) throw();
|
|
|
|
/** Removes any duplicated elements from the array.
|
|
|
|
If any string appears in the array more than once, only the first occurrence of
|
|
it will be retained.
|
|
|
|
@param ignoreCase whether to use a case-insensitive comparison
|
|
*/
|
|
void removeDuplicates (const bool ignoreCase) throw();
|
|
|
|
/** Removes empty strings from the array.
|
|
|
|
@param removeWhitespaceStrings if true, strings that only contain whitespace
|
|
characters will also be removed
|
|
*/
|
|
void removeEmptyStrings (const bool removeWhitespaceStrings = true) throw();
|
|
|
|
/** Moves one of the strings to a different position.
|
|
|
|
This will move the string to a specified index, shuffling along
|
|
any intervening elements as required.
|
|
|
|
So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling
|
|
move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }.
|
|
|
|
@param currentIndex the index of the value to be moved. If this isn't a
|
|
valid index, then nothing will be done
|
|
@param newIndex the index at which you'd like this value to end up. If this
|
|
is less than zero, the value will be moved to the end
|
|
of the array
|
|
*/
|
|
void move (const int currentIndex, int newIndex) throw();
|
|
|
|
/** Deletes any whitespace characters from the starts and ends of all the strings. */
|
|
void trim() throw();
|
|
|
|
/** Adds numbers to the strings in the array, to make each string unique.
|
|
|
|
This will add numbers to the ends of groups of similar strings.
|
|
e.g. if there are two "moose" strings, they will become "moose (1)" and "moose (2)"
|
|
|
|
@param ignoreCaseWhenComparing whether the comparison used is case-insensitive
|
|
@param appendNumberToFirstInstance whether the first of a group of similar strings
|
|
also has a number appended to it.
|
|
@param preNumberString when adding a number, this string is added before the number
|
|
@param postNumberString this string is appended after any numbers that are added
|
|
*/
|
|
void appendNumbersToDuplicates (const bool ignoreCaseWhenComparing,
|
|
const bool appendNumberToFirstInstance,
|
|
const tchar* const preNumberString = defaultPreNumberString,
|
|
const tchar* const postNumberString = defaultPostNumberString) throw();
|
|
|
|
/** Joins the strings in the array together into one string.
|
|
|
|
This will join a range of elements from the array into a string, separating
|
|
them with a given string.
|
|
|
|
e.g. joinIntoString (",") will turn an array of "a" "b" and "c" into "a,b,c".
|
|
|
|
@param separatorString the string to insert between all the strings
|
|
@param startIndex the first element to join
|
|
@param numberOfElements how many elements to join together. If this is less
|
|
than zero, all available elements will be used.
|
|
*/
|
|
const String joinIntoString (const String& separatorString,
|
|
int startIndex = 0,
|
|
int numberOfElements = -1) const throw();
|
|
|
|
/** Sorts the array into alphabetical order.
|
|
|
|
@param ignoreCase if true, the comparisons used will be case-sensitive.
|
|
*/
|
|
void sort (const bool ignoreCase) throw();
|
|
|
|
/** Reduces the amount of storage being used by the array.
|
|
|
|
Arrays typically allocate slightly more storage than they need, and after
|
|
removing elements, they may have quite a lot of unused space allocated.
|
|
This method will reduce the amount of allocated storage to a minimum.
|
|
*/
|
|
void minimiseStorageOverheads() throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
VoidArray strings;
|
|
};
|
|
|
|
#endif // __JUCE_STRINGARRAY_JUCEHEADER__
|
|
/********* End of inlined file: juce_StringArray.h *********/
|
|
|
|
/********* Start of inlined file: juce_MemoryBlock.h *********/
|
|
#ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__
|
|
#define __JUCE_MEMORYBLOCK_JUCEHEADER__
|
|
|
|
/**
|
|
A class to hold a resizable block of raw data.
|
|
|
|
*/
|
|
class JUCE_API MemoryBlock
|
|
{
|
|
public:
|
|
|
|
/** Create an uninitialised block with 0 size. */
|
|
MemoryBlock() throw();
|
|
|
|
/** Creates a memory block with a given initial size.
|
|
|
|
@param initialSize the size of block to create
|
|
@param initialiseToZero whether to clear the memory or just leave it uninitialised
|
|
*/
|
|
MemoryBlock (const int initialSize,
|
|
const bool initialiseToZero = false) throw();
|
|
|
|
/** Creates a copy of another memory block. */
|
|
MemoryBlock (const MemoryBlock& other) throw();
|
|
|
|
/** Creates a memory block using a copy of a block of data.
|
|
|
|
@param dataToInitialiseFrom some data to copy into this block
|
|
@param sizeInBytes how much space to use
|
|
*/
|
|
MemoryBlock (const void* const dataToInitialiseFrom,
|
|
const int sizeInBytes) throw();
|
|
|
|
/** Destructor. */
|
|
~MemoryBlock() throw();
|
|
|
|
/** Copies another memory block onto this one.
|
|
|
|
This block will be resized and copied to exactly match the other one.
|
|
*/
|
|
const MemoryBlock& operator= (const MemoryBlock& other) throw();
|
|
|
|
/** Compares two memory blocks.
|
|
|
|
@returns true only if the two blocks are the same size and have identical contents.
|
|
*/
|
|
bool operator== (const MemoryBlock& other) const throw();
|
|
|
|
/** Compares two memory blocks.
|
|
|
|
@returns true if the two blocks are different sizes or have different contents.
|
|
*/
|
|
bool operator!= (const MemoryBlock& other) const throw();
|
|
|
|
/** Returns a pointer to the data, casting it to any type of primitive data required.
|
|
|
|
Note that the pointer returned will probably become invalid when the
|
|
block is resized.
|
|
*/
|
|
template <class DataType>
|
|
operator DataType*() const throw() { return (DataType*) data; }
|
|
|
|
/** Returns a void pointer to the data.
|
|
|
|
Note that the pointer returned will probably become invalid when the
|
|
block is resized.
|
|
*/
|
|
void* getData() const throw() { return data; }
|
|
|
|
/** Returns a byte from the memory block.
|
|
|
|
This returns a reference, so you can also use it to set a byte.
|
|
*/
|
|
char& operator[] (const int offset) const throw() { return data [offset]; }
|
|
|
|
/** Returns the block's current allocated size, in bytes. */
|
|
int getSize() const throw() { return size; }
|
|
|
|
/** Resizes the memory block.
|
|
|
|
This will try to keep as much of the block's current content as it can,
|
|
and can optionally be made to clear any new space that gets allocated at
|
|
the end of the block.
|
|
|
|
@param newSize the new desired size for the block
|
|
@param initialiseNewSpaceToZero if the block gets enlarged, this determines
|
|
whether to clear the new section or just leave it
|
|
uninitialised
|
|
@see ensureSize
|
|
*/
|
|
void setSize (const int newSize,
|
|
const bool initialiseNewSpaceToZero = false) throw();
|
|
|
|
/** Increases the block's size only if it's smaller than a given size.
|
|
|
|
@param minimumSize if the block is already bigger than this size, no action
|
|
will be taken; otherwise it will be increased to this size
|
|
@param initialiseNewSpaceToZero if the block gets enlarged, this determines
|
|
whether to clear the new section or just leave it
|
|
uninitialised
|
|
@see setSize
|
|
*/
|
|
void ensureSize (const int minimumSize,
|
|
const bool initialiseNewSpaceToZero = false) throw();
|
|
|
|
/** Fills the entire memory block with a repeated byte value.
|
|
|
|
This is handy for clearing a block of memory to zero.
|
|
*/
|
|
void fillWith (const uint8 valueToUse) throw();
|
|
|
|
/** Adds another block of data to the end of this one.
|
|
|
|
This block's size will be increased accordingly.
|
|
*/
|
|
void append (const void* const data,
|
|
const int numBytes) throw();
|
|
|
|
/** Copies data into this MemoryBlock from a memory address.
|
|
|
|
@param srcData the memory location of the data to copy into this block
|
|
@param destinationOffset the offset in this block at which the data being copied should begin
|
|
@param numBytes how much to copy in (if this goes beyond the size of the memory block,
|
|
it will be clipped so not to do anything nasty)
|
|
*/
|
|
void copyFrom (const void* srcData,
|
|
int destinationOffset,
|
|
int numBytes) throw();
|
|
|
|
/** Copies data from this MemoryBlock to a memory address.
|
|
|
|
@param destData the memory location to write to
|
|
@param sourceOffset the offset within this block from which the copied data will be read
|
|
@param numBytes how much to copy (if this extends beyond the limits of the memory block,
|
|
zeros will be used for that portion of the data)
|
|
*/
|
|
void copyTo (void* destData,
|
|
int sourceOffset,
|
|
int numBytes) const throw();
|
|
|
|
/** Chops out a section of the block.
|
|
|
|
This will remove a section of the memory block and close the gap around it,
|
|
shifting any subsequent data downwards and reducing the size of the block.
|
|
|
|
If the range specified goes beyond the size of the block, it will be clipped.
|
|
*/
|
|
void removeSection (int startByte, int numBytesToRemove) throw();
|
|
|
|
/** Attempts to parse the contents of the block as a zero-terminated string of 8-bit
|
|
characters in the system's default encoding. */
|
|
const String toString() const throw();
|
|
|
|
/** Parses a string of hexadecimal numbers and writes this data into the memory block.
|
|
|
|
The block will be resized to the number of valid bytes read from the string.
|
|
Non-hex characters in the string will be ignored.
|
|
|
|
@see String::toHexString()
|
|
*/
|
|
void loadFromHexString (const String& sourceHexString) throw();
|
|
|
|
/** Sets a number of bits in the memory block, treating it as a long binary sequence. */
|
|
void setBitRange (int bitRangeStart,
|
|
int numBits,
|
|
int binaryNumberToApply) throw();
|
|
|
|
/** Reads a number of bits from the memory block, treating it as one long binary sequence */
|
|
int getBitRange (int bitRangeStart,
|
|
int numBitsToRead) const throw();
|
|
|
|
/** Returns a string of characters that represent the binary contents of this block.
|
|
|
|
Uses a 64-bit encoding system to allow binary data to be turned into a string
|
|
of simple non-extended characters, e.g. for storage in XML.
|
|
|
|
@see fromBase64Encoding
|
|
*/
|
|
const String toBase64Encoding() const throw();
|
|
|
|
/** Takes a string of encoded characters and turns it into binary data.
|
|
|
|
The string passed in must have been created by to64BitEncoding(), and this
|
|
block will be resized to recreate the original data block.
|
|
|
|
@see toBase64Encoding
|
|
*/
|
|
bool fromBase64Encoding (const String& encodedString) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
char* data;
|
|
int size;
|
|
};
|
|
|
|
#endif // __JUCE_MEMORYBLOCK_JUCEHEADER__
|
|
/********* End of inlined file: juce_MemoryBlock.h *********/
|
|
|
|
class FileInputStream;
|
|
class FileOutputStream;
|
|
|
|
/**
|
|
Represents a local file or directory.
|
|
|
|
This class encapsulates the absolute pathname of a file or directory, and
|
|
has methods for finding out about the file and changing its properties.
|
|
|
|
To read or write to the file, there are methods for returning an input or
|
|
output stream.
|
|
|
|
@see FileInputStream, FileOutputStream
|
|
*/
|
|
class JUCE_API File
|
|
{
|
|
public:
|
|
|
|
/** Creates an (invalid) file object.
|
|
|
|
The file is initially set to an empty path, so getFullPath() will return
|
|
an empty string, and comparing the file to File::nonexistent will return
|
|
true.
|
|
|
|
You can use its operator= method to point it at a proper file.
|
|
*/
|
|
File() throw() {}
|
|
|
|
/** Creates a file from an absolute path.
|
|
|
|
If the path supplied is a relative path, it is taken to be relative
|
|
to the current working directory (see File::getCurrentWorkingDirectory()),
|
|
but this isn't a recommended way of creating a file, because you
|
|
never know what the CWD is going to be.
|
|
|
|
On the Mac/Linux, the path can include "~" notation for referring to
|
|
user home directories.
|
|
*/
|
|
File (const String& path) throw();
|
|
|
|
/** Creates a copy of another file object. */
|
|
File (const File& other) throw();
|
|
|
|
/** Destructor. */
|
|
~File() throw() {}
|
|
|
|
/** Sets the file based on an absolute pathname.
|
|
|
|
If the path supplied is a relative path, it is taken to be relative
|
|
to the current working directory (see File::getCurrentWorkingDirectory()),
|
|
but this isn't a recommended way of creating a file, because you
|
|
never know what the CWD is going to be.
|
|
|
|
On the Mac/Linux, the path can include "~" notation for referring to
|
|
user home directories.
|
|
*/
|
|
const File& operator= (const String& newFilePath) throw();
|
|
|
|
/** Copies from another file object. */
|
|
const File& operator= (const File& otherFile) throw();
|
|
|
|
/** This static constant is used for referring to an 'invalid' file. */
|
|
static const File nonexistent;
|
|
|
|
/** Checks whether the file actually exists.
|
|
|
|
@returns true if the file exists, either as a file or a directory.
|
|
@see existsAsFile, isDirectory
|
|
*/
|
|
bool exists() const throw();
|
|
|
|
/** Checks whether the file exists and is a file rather than a directory.
|
|
|
|
@returns true only if this is a real file, false if it's a directory
|
|
or doesn't exist
|
|
@see exists, isDirectory
|
|
*/
|
|
bool existsAsFile() const throw();
|
|
|
|
/** Checks whether the file is a directory that exists.
|
|
|
|
@returns true only if the file is a directory which actually exists, so
|
|
false if it's a file or doesn't exist at all
|
|
@see exists, existsAsFile
|
|
*/
|
|
bool isDirectory() const throw();
|
|
|
|
/** Returns the size of the file in bytes.
|
|
|
|
@returns the number of bytes in the file, or 0 if it doesn't exist.
|
|
*/
|
|
int64 getSize() const throw();
|
|
|
|
/** Utility function to convert a file size in bytes to a neat string description.
|
|
|
|
So for example 100 would return "100 bytes", 2000 would return "2 KB",
|
|
2000000 would produce "2 MB", etc.
|
|
*/
|
|
static const String descriptionOfSizeInBytes (const int64 bytes);
|
|
|
|
/** Returns the complete, absolute path of this file.
|
|
|
|
This includes the filename and all its parent folders. On Windows it'll
|
|
also include the drive letter prefix; on Mac or Linux it'll be a complete
|
|
path starting from the root folder.
|
|
|
|
If you just want the file's name, you should use getFileName() or
|
|
getFileNameWithoutExtension().
|
|
|
|
@see getFileName, getRelativePathFrom
|
|
*/
|
|
const String& getFullPathName() const throw() { return fullPath; }
|
|
|
|
/** Returns the last section of the pathname.
|
|
|
|
Returns just the final part of the path - e.g. if the whole path
|
|
is "/moose/fish/foo.txt" this will return "foo.txt".
|
|
|
|
For a directory, it returns the final part of the path - e.g. for the
|
|
directory "/moose/fish" it'll return "fish".
|
|
|
|
If the filename begins with a dot, it'll return the whole filename, e.g. for
|
|
"/moose/.fish", it'll return ".fish"
|
|
|
|
@see getFullPathName, getFileNameWithoutExtension
|
|
*/
|
|
const String getFileName() const throw();
|
|
|
|
/** Creates a relative path that refers to a file relatively to a given directory.
|
|
|
|
e.g. File ("/moose/foo.txt").getRelativePathFrom ("/moose/fish/haddock")
|
|
would return "../../foo.txt".
|
|
|
|
If it's not possible to navigate from one file to the other, an absolute
|
|
path is returned. If the paths are invalid, an empty string may also be
|
|
returned.
|
|
|
|
@param directoryToBeRelativeTo the directory which the resultant string will
|
|
be relative to. If this is actually a file rather than
|
|
a directory, its parent directory will be used instead.
|
|
If it doesn't exist, it's assumed to be a directory.
|
|
@see getChildFile, isAbsolutePath
|
|
*/
|
|
const String getRelativePathFrom (const File& directoryToBeRelativeTo) const throw();
|
|
|
|
/** Returns the file's extension.
|
|
|
|
Returns the file extension of this file, also including the dot.
|
|
|
|
e.g. "/moose/fish/foo.txt" would return ".txt"
|
|
|
|
@see hasFileExtension, withFileExtension, getFileNameWithoutExtension
|
|
*/
|
|
const String getFileExtension() const throw();
|
|
|
|
/** Checks whether the file has a given extension.
|
|
|
|
@param extensionToTest the extension to look for - it doesn't matter whether or
|
|
not this string has a dot at the start, so ".wav" and "wav"
|
|
will have the same effect. The comparison used is
|
|
case-insensitve.
|
|
|
|
@see getFileExtension, withFileExtension, getFileNameWithoutExtension
|
|
*/
|
|
bool hasFileExtension (const String& extensionToTest) const throw();
|
|
|
|
/** Returns a version of this file with a different file extension.
|
|
|
|
e.g. File ("/moose/fish/foo.txt").withFileExtension ("html") returns "/moose/fish/foo.html"
|
|
|
|
@param newExtension the new extension, either with or without a dot at the start (this
|
|
doesn't make any difference). To get remove a file's extension altogether,
|
|
pass an empty string into this function.
|
|
|
|
@see getFileName, getFileExtension, hasFileExtension, getFileNameWithoutExtension
|
|
*/
|
|
const File withFileExtension (const String& newExtension) const throw();
|
|
|
|
/** Returns the last part of the filename, without its file extension.
|
|
|
|
e.g. for "/moose/fish/foo.txt" this will return "foo".
|
|
|
|
@see getFileName, getFileExtension, hasFileExtension, withFileExtension
|
|
*/
|
|
const String getFileNameWithoutExtension() const throw();
|
|
|
|
/** Returns a 32-bit hash-code that identifies this file.
|
|
|
|
This is based on the filename. Obviously it's possible, although unlikely, that
|
|
two files will have the same hash-code.
|
|
*/
|
|
int hashCode() const throw();
|
|
|
|
/** Returns a 64-bit hash-code that identifies this file.
|
|
|
|
This is based on the filename. Obviously it's possible, although unlikely, that
|
|
two files will have the same hash-code.
|
|
*/
|
|
int64 hashCode64() const throw();
|
|
|
|
/** Returns a file based on a relative path.
|
|
|
|
This will find a child file or directory of the current object.
|
|
|
|
e.g.
|
|
File ("/moose/fish").getChildFile ("foo.txt") will produce "/moose/fish/foo.txt".
|
|
File ("/moose/fish").getChildFile ("../foo.txt") will produce "/moose/foo.txt".
|
|
|
|
If the string is actually an absolute path, it will be treated as such, e.g.
|
|
File ("/moose/fish").getChildFile ("/foo.txt") will produce "/foo.txt"
|
|
|
|
@see getSiblingFile, getParentDirectory, getRelativePathFrom, isAChildOf
|
|
*/
|
|
const File getChildFile (String relativePath) const throw();
|
|
|
|
/** Returns a file which is in the same directory as this one.
|
|
|
|
This is equivalent to getParentDirectory().getChildFile (name).
|
|
|
|
@see getChildFile, getParentDirectory
|
|
*/
|
|
const File getSiblingFile (const String& siblingFileName) const throw();
|
|
|
|
/** Returns the directory that contains this file or directory.
|
|
|
|
e.g. for "/moose/fish/foo.txt" this will return "/moose/fish".
|
|
*/
|
|
const File getParentDirectory() const throw();
|
|
|
|
/** Checks whether a file is somewhere inside a directory.
|
|
|
|
Returns true if this file is somewhere inside a subdirectory of the directory
|
|
that is passed in. Neither file actually has to exist, because the function
|
|
just checks the paths for similarities.
|
|
|
|
e.g. File ("/moose/fish/foo.txt").isAChildOf ("/moose") is true.
|
|
File ("/moose/fish/foo.txt").isAChildOf ("/moose/fish") is also true.
|
|
*/
|
|
bool isAChildOf (const File& potentialParentDirectory) const throw();
|
|
|
|
/** Chooses a filename relative to this one that doesn't already exist.
|
|
|
|
If this file is a directory, this will return a child file of this
|
|
directory that doesn't exist, by adding numbers to a prefix and suffix until
|
|
it finds one that isn't already there.
|
|
|
|
If the prefix + the suffix doesn't exist, it won't bother adding a number.
|
|
|
|
e.g. File ("/moose/fish").getNonexistentChildFile ("foo", ".txt", true) might
|
|
return "/moose/fish/foo(2).txt" if there's already a file called "foo.txt".
|
|
|
|
@param prefix the string to use for the filename before the number
|
|
@param suffix the string to add to the filename after the number
|
|
@param putNumbersInBrackets if true, this will create filenames in the
|
|
format "prefix(number)suffix", if false, it will leave the
|
|
brackets out.
|
|
*/
|
|
const File getNonexistentChildFile (const String& prefix,
|
|
const String& suffix,
|
|
bool putNumbersInBrackets = true) const throw();
|
|
|
|
/** Chooses a filename for a sibling file to this one that doesn't already exist.
|
|
|
|
If this file doesn't exist, this will just return itself, otherwise it
|
|
will return an appropriate sibling that doesn't exist, e.g. if a file
|
|
"/moose/fish/foo.txt" exists, this might return "/moose/fish/foo(2).txt".
|
|
|
|
@param putNumbersInBrackets whether to add brackets around the numbers that
|
|
get appended to the new filename.
|
|
*/
|
|
const File getNonexistentSibling (const bool putNumbersInBrackets = true) const throw();
|
|
|
|
/** Compares the pathnames for two files. */
|
|
bool operator== (const File& otherFile) const throw();
|
|
/** Compares the pathnames for two files. */
|
|
bool operator!= (const File& otherFile) const throw();
|
|
|
|
/** Checks whether a file can be created or written to.
|
|
|
|
@returns true if it's possible to create and write to this file. If the file
|
|
doesn't already exist, this will check its parent directory to
|
|
see if writing is allowed.
|
|
@see setReadOnly
|
|
*/
|
|
bool hasWriteAccess() const throw();
|
|
|
|
/** Changes the write-permission of a file or directory.
|
|
|
|
@param shouldBeReadOnly whether to add or remove write-permission
|
|
@param applyRecursively if the file is a directory and this is true, it will
|
|
recurse through all the subfolders changing the permissions
|
|
of all files
|
|
@returns true if it manages to change the file's permissions.
|
|
@see hasWriteAccess
|
|
*/
|
|
bool setReadOnly (const bool shouldBeReadOnly,
|
|
const bool applyRecursively = false) const throw();
|
|
|
|
/** Returns true if this file is a hidden or system file.
|
|
|
|
The criteria for deciding whether a file is hidden are platform-dependent.
|
|
*/
|
|
bool isHidden() const throw();
|
|
|
|
/** If this file is a link, this returns the file that it points to.
|
|
|
|
If this file isn't actually link, it'll just return itself.
|
|
*/
|
|
const File getLinkedTarget() const throw();
|
|
|
|
/** Returns the last modification time of this file.
|
|
|
|
@returns the time, or an invalid time if the file doesn't exist.
|
|
@see setLastModificationTime, getLastAccessTime, getCreationTime
|
|
*/
|
|
const Time getLastModificationTime() const throw();
|
|
|
|
/** Returns the last time this file was accessed.
|
|
|
|
@returns the time, or an invalid time if the file doesn't exist.
|
|
@see setLastAccessTime, getLastModificationTime, getCreationTime
|
|
*/
|
|
const Time getLastAccessTime() const throw();
|
|
|
|
/** Returns the time that this file was created.
|
|
|
|
@returns the time, or an invalid time if the file doesn't exist.
|
|
@see getLastModificationTime, getLastAccessTime
|
|
*/
|
|
const Time getCreationTime() const throw();
|
|
|
|
/** Changes the modification time for this file.
|
|
|
|
@param newTime the time to apply to the file
|
|
@returns true if it manages to change the file's time.
|
|
@see getLastModificationTime, setLastAccessTime, setCreationTime
|
|
*/
|
|
bool setLastModificationTime (const Time& newTime) const throw();
|
|
|
|
/** Changes the last-access time for this file.
|
|
|
|
@param newTime the time to apply to the file
|
|
@returns true if it manages to change the file's time.
|
|
@see getLastAccessTime, setLastModificationTime, setCreationTime
|
|
*/
|
|
bool setLastAccessTime (const Time& newTime) const throw();
|
|
|
|
/** Changes the creation date for this file.
|
|
|
|
@param newTime the time to apply to the file
|
|
@returns true if it manages to change the file's time.
|
|
@see getCreationTime, setLastModificationTime, setLastAccessTime
|
|
*/
|
|
bool setCreationTime (const Time& newTime) const throw();
|
|
|
|
/** If possible, this will try to create a version string for the given file.
|
|
|
|
The OS may be able to look at the file and give a version for it - e.g. with
|
|
executables, bundles, dlls, etc. If no version is available, this will
|
|
return an empty string.
|
|
*/
|
|
const String getVersion() const throw();
|
|
|
|
/** Creates an empty file if it doesn't already exist.
|
|
|
|
If the file that this object refers to doesn't exist, this will create a file
|
|
of zero size.
|
|
|
|
If it already exists or is a directory, this method will do nothing.
|
|
|
|
@returns true if the file has been created (or if it already existed).
|
|
@see createDirectory
|
|
*/
|
|
bool create() const throw();
|
|
|
|
/** Creates a new directory for this filename.
|
|
|
|
This will try to create the file as a directory, and fill also create
|
|
any parent directories it needs in order to complete the operation.
|
|
|
|
@returns true if the directory has been created successfully, (or if it
|
|
already existed beforehand).
|
|
@see create
|
|
*/
|
|
bool createDirectory() const throw();
|
|
|
|
/** Deletes a file.
|
|
|
|
If this file is actually a directory, it may not be deleted correctly if it
|
|
contains files. See deleteRecursively() as a better way of deleting directories.
|
|
|
|
@returns true if the file has been successfully deleted (or if it didn't exist to
|
|
begin with).
|
|
@see deleteRecursively
|
|
*/
|
|
bool deleteFile() const throw();
|
|
|
|
/** Deletes a file or directory and all its subdirectories.
|
|
|
|
If this file is a directory, this will try to delete it and all its subfolders. If
|
|
it's just a file, it will just try to delete the file.
|
|
|
|
@returns true if the file and all its subfolders have been successfully deleted
|
|
(or if it didn't exist to begin with).
|
|
@see deleteFile
|
|
*/
|
|
bool deleteRecursively() const throw();
|
|
|
|
/** Moves this file or folder to the trash.
|
|
|
|
@returns true if the operation succeeded. It could fail if the trash is full, or
|
|
if the file is write-protected, so you should check the return value
|
|
and act appropriately.
|
|
*/
|
|
bool moveToTrash() const throw();
|
|
|
|
/** Moves or renames a file.
|
|
|
|
Tries to move a file to a different location.
|
|
If the target file already exists, this will attempt to delete it first, and
|
|
will fail if this can't be done.
|
|
|
|
Note that the destination file isn't the directory to put it in, it's the actual
|
|
filename that you want the new file to have.
|
|
|
|
@returns true if the operation succeeds
|
|
*/
|
|
bool moveFileTo (const File& targetLocation) const throw();
|
|
|
|
/** Copies a file.
|
|
|
|
Tries to copy a file to a different location.
|
|
If the target file already exists, this will attempt to delete it first, and
|
|
will fail if this can't be done.
|
|
|
|
@returns true if the operation succeeds
|
|
*/
|
|
bool copyFileTo (const File& targetLocation) const throw();
|
|
|
|
/** Copies a directory.
|
|
|
|
Tries to copy an entire directory, recursively.
|
|
|
|
If this file isn't a directory or if any target files can't be created, this
|
|
will return false.
|
|
|
|
@param newDirectory the directory that this one should be copied to. Note that this
|
|
is the name of the actual directory to create, not the directory
|
|
into which the new one should be placed, so there must be enough
|
|
write privileges to create it if it doesn't exist. Any files inside
|
|
it will be overwritten by similarly named ones that are copied.
|
|
*/
|
|
bool copyDirectoryTo (const File& newDirectory) const throw();
|
|
|
|
/** Used in file searching, to specify whether to return files, directories, or both.
|
|
*/
|
|
enum TypesOfFileToFind
|
|
{
|
|
findDirectories = 1, /**< Use this flag to indicate that you want to find directories. */
|
|
findFiles = 2, /**< Use this flag to indicate that you want to find files. */
|
|
findFilesAndDirectories = 3, /**< Use this flag to indicate that you want to find both files and directories. */
|
|
ignoreHiddenFiles = 4 /**< Add this flag to avoid returning any hidden files in the results. */
|
|
};
|
|
|
|
/** Searches inside a directory for files matching a wildcard pattern.
|
|
|
|
Assuming that this file is a directory, this method will search it
|
|
for either files or subdirectories whose names match a filename pattern.
|
|
|
|
@param results an array to which File objects will be added for the
|
|
files that the search comes up with
|
|
@param whatToLookFor a value from the TypesOfFileToFind enum, specifying whether to
|
|
return files, directories, or both. If the ignoreHiddenFiles flag
|
|
is also added to this value, hidden files won't be returned
|
|
@param searchRecursively if true, all subdirectories will be recursed into to do
|
|
an exhaustive search
|
|
@param wildCardPattern the filename pattern to search for, e.g. "*.txt"
|
|
@returns the number of results that have been found
|
|
|
|
@see getNumberOfChildFiles, DirectoryIterator
|
|
*/
|
|
int findChildFiles (OwnedArray<File>& results,
|
|
const int whatToLookFor,
|
|
const bool searchRecursively,
|
|
const String& wildCardPattern = JUCE_T("*")) const throw();
|
|
|
|
/** Searches inside a directory and counts how many files match a wildcard pattern.
|
|
|
|
Assuming that this file is a directory, this method will search it
|
|
for either files or subdirectories whose names match a filename pattern,
|
|
and will return the number of matches found.
|
|
|
|
This isn't a recursive call, and will only search this directory, not
|
|
its children.
|
|
|
|
@param whatToLookFor a value from the TypesOfFileToFind enum, specifying whether to
|
|
count files, directories, or both. If the ignoreHiddenFiles flag
|
|
is also added to this value, hidden files won't be counted
|
|
@param wildCardPattern the filename pattern to search for, e.g. "*.txt"
|
|
@returns the number of matches found
|
|
@see findChildFiles, DirectoryIterator
|
|
*/
|
|
int getNumberOfChildFiles (const int whatToLookFor,
|
|
const String& wildCardPattern = JUCE_T("*")) const throw();
|
|
|
|
/** Returns true if this file is a directory that contains one or more subdirectories.
|
|
@see isDirectory, findChildFiles
|
|
*/
|
|
bool containsSubDirectories() const throw();
|
|
|
|
/** Creates a stream to read from this file.
|
|
|
|
@returns a stream that will read from this file (initially positioned at the
|
|
start of the file), or 0 if the file can't be opened for some reason
|
|
@see createOutputStream, loadFileAsData
|
|
*/
|
|
FileInputStream* createInputStream() const throw();
|
|
|
|
/** Creates a stream to write to this file.
|
|
|
|
If the file exists, the stream that is returned will be positioned ready for
|
|
writing at the end of the file, so you might want to use deleteFile() first
|
|
to write to an empty file.
|
|
|
|
@returns a stream that will write to this file (initially positioned at the
|
|
end of the file), or 0 if the file can't be opened for some reason
|
|
@see createInputStream, printf, appendData, appendText
|
|
*/
|
|
FileOutputStream* createOutputStream (const int bufferSize = 0x8000) const throw();
|
|
|
|
/** Loads a file's contents into memory as a block of binary data.
|
|
|
|
Of course, trying to load a very large file into memory will blow up, so
|
|
it's better to check first.
|
|
|
|
@param result the data block to which the file's contents should be appended - note
|
|
that if the memory block might already contain some data, you
|
|
might want to clear it first
|
|
@returns true if the file could all be read into memory
|
|
*/
|
|
bool loadFileAsData (MemoryBlock& result) const throw();
|
|
|
|
/** Reads a file into memory as a string.
|
|
|
|
Attempts to load the entire file as a zero-terminated string.
|
|
|
|
This makes use of InputStream::readEntireStreamAsString, which should
|
|
automatically cope with unicode/acsii file formats.
|
|
*/
|
|
const String loadFileAsString() const throw();
|
|
|
|
/** Writes text to the end of the file.
|
|
|
|
This will try to do a printf to the file.
|
|
|
|
@returns false if it can't write to the file for some reason
|
|
*/
|
|
bool printf (const tchar* format, ...) const throw();
|
|
|
|
/** Appends a block of binary data to the end of the file.
|
|
|
|
This will try to write the given buffer to the end of the file.
|
|
|
|
@returns false if it can't write to the file for some reason
|
|
*/
|
|
bool appendData (const void* const dataToAppend,
|
|
const int numberOfBytes) const throw();
|
|
|
|
/** Replaces this file's contents with a given block of data.
|
|
|
|
This will delete the file and replace it with the given data.
|
|
|
|
A nice feature of this method is that it's safe - instead of deleting
|
|
the file first and then re-writing it, it creates a new temporary file,
|
|
writes the data to that, and then moves the new file to replace the existing
|
|
file. This means that if the power gets pulled out or something crashes,
|
|
you're a lot less likely to end up with an empty file..
|
|
|
|
Returns true if the operation succeeds, or false if it fails.
|
|
|
|
@see appendText
|
|
*/
|
|
bool replaceWithData (const void* const dataToWrite,
|
|
const int numberOfBytes) const throw();
|
|
|
|
/** Appends a string to the end of the file.
|
|
|
|
This will try to append a text string to the file, as either 16-bit unicode
|
|
or 8-bit characters in the default system encoding.
|
|
|
|
It can also write the 'ff fe' unicode header bytes before the text to indicate
|
|
the endianness of the file.
|
|
|
|
Any single \\n characters in the string are replaced with \\r\\n before it is written.
|
|
|
|
@see replaceWithText
|
|
*/
|
|
bool appendText (const String& textToAppend,
|
|
const bool asUnicode = false,
|
|
const bool writeUnicodeHeaderBytes = false) const throw();
|
|
|
|
/** Replaces this file's contents with a given text string.
|
|
|
|
This will delete the file and replace it with the given text.
|
|
|
|
A nice feature of this method is that it's safe - instead of deleting
|
|
the file first and then re-writing it, it creates a new temporary file,
|
|
writes the text to that, and then moves the new file to replace the existing
|
|
file. This means that if the power gets pulled out or something crashes,
|
|
you're a lot less likely to end up with an empty file..
|
|
|
|
For an explanation of the parameters here, see the appendText() method.
|
|
|
|
Returns true if the operation succeeds, or false if it fails.
|
|
|
|
@see appendText
|
|
*/
|
|
bool replaceWithText (const String& textToWrite,
|
|
const bool asUnicode = false,
|
|
const bool writeUnicodeHeaderBytes = false) const throw();
|
|
|
|
/** Creates a set of files to represent each file root.
|
|
|
|
e.g. on Windows this will create files for "c:\", "d:\" etc according
|
|
to which ones are available. On the Mac/Linux, this will probably
|
|
just add a single entry for "/".
|
|
*/
|
|
static void findFileSystemRoots (OwnedArray<File>& results) throw();
|
|
|
|
/** Finds the name of the drive on which this file lives.
|
|
|
|
@returns the volume label of the drive, or an empty string if this isn't possible
|
|
*/
|
|
const String getVolumeLabel() const throw();
|
|
|
|
/** Returns the serial number of the volume on which this file lives.
|
|
|
|
@returns the serial number, or zero if there's a problem doing this
|
|
*/
|
|
int getVolumeSerialNumber() const throw();
|
|
|
|
/** Returns the number of bytes free on the drive that this file lives on.
|
|
|
|
@returns the number of bytes free, or 0 if there's a problem finding this out
|
|
@see getVolumeTotalSize
|
|
*/
|
|
int64 getBytesFreeOnVolume() const throw();
|
|
|
|
/** Returns the total size of the drive that contains this file.
|
|
|
|
@returns the total number of bytes that the volume can hold
|
|
@see getBytesFreeOnVolume
|
|
*/
|
|
int64 getVolumeTotalSize() const throw();
|
|
|
|
/** Returns true if this file is on a CD or DVD drive. */
|
|
bool isOnCDRomDrive() const throw();
|
|
|
|
/** Returns true if this file is on a hard disk.
|
|
|
|
This will fail if it's a network drive, but will still be true for
|
|
removable hard-disks.
|
|
*/
|
|
bool isOnHardDisk() const throw();
|
|
|
|
/** Returns true if this file is on a removable disk drive.
|
|
|
|
This might be a usb-drive, a CD-rom, or maybe a network drive.
|
|
*/
|
|
bool isOnRemovableDrive() const throw();
|
|
|
|
/** Launches the file as a process.
|
|
|
|
- if the file is executable, this will run it.
|
|
|
|
- if it's a document of some kind, it will launch the document with its
|
|
default viewer application.
|
|
|
|
- if it's a folder, it will be opened in Explorer, Finder, or equivalent.
|
|
*/
|
|
bool startAsProcess (const String& parameters = String::empty) const throw();
|
|
|
|
/** A set of types of location that can be passed to the getSpecialLocation() method.
|
|
*/
|
|
enum SpecialLocationType
|
|
{
|
|
/** The user's home folder. This is the same as using File ("~"). */
|
|
userHomeDirectory,
|
|
|
|
/** The user's default documents folder. On Windows, this might be the user's
|
|
"My Documents" folder. On the Mac it'll be their "Documents" folder. Linux
|
|
doesn't tend to have one of these, so it might just return their home folder.
|
|
*/
|
|
userDocumentsDirectory,
|
|
|
|
/** The folder that contains the user's desktop objects. */
|
|
userDesktopDirectory,
|
|
|
|
/** The folder in which applications store their persistent user-specific settings.
|
|
On Windows, this might be "\Documents and Settings\username\Application Data".
|
|
On the Mac, it might be "~/Library". If you're going to store your settings in here,
|
|
always create your own sub-folder to put them in, to avoid making a mess.
|
|
*/
|
|
userApplicationDataDirectory,
|
|
|
|
/** An equivalent of the userApplicationDataDirectory folder that is shared by all users
|
|
of the computer, rather than just the current user.
|
|
|
|
On the Mac it'll be "/Library", on Windows, it could be something like
|
|
"\Documents and Settings\All Users\Application Data".
|
|
|
|
Depending on the setup, this folder may be read-only.
|
|
*/
|
|
commonApplicationDataDirectory,
|
|
|
|
/** The folder that should be used for temporary files.
|
|
|
|
Always delete them when you're finished, to keep the user's computer tidy!
|
|
*/
|
|
tempDirectory,
|
|
|
|
/** Returns this application's executable file.
|
|
|
|
If running as a plug-in or DLL, this will (where possible) be the DLL rather than the
|
|
host app.
|
|
|
|
On the mac this will return the unix binary, not the package folder - see
|
|
currentApplicationFile for that.
|
|
*/
|
|
currentExecutableFile,
|
|
|
|
/** Returns this application's location.
|
|
|
|
If running as a plug-in or DLL, this will (where possible) be the DLL rather than the
|
|
host app.
|
|
|
|
On the mac this will return the package folder (if it's in one), not the unix binary
|
|
that's inside it - compare with currentExecutableFile.
|
|
*/
|
|
currentApplicationFile,
|
|
|
|
/** The directory in which applications normally get installed.
|
|
|
|
So on windows, this would be something like "c:\program files", on the
|
|
Mac "/Applications", or "/usr" on linux.
|
|
*/
|
|
globalApplicationsDirectory,
|
|
|
|
/** The most likely place where a user might store their music files.
|
|
*/
|
|
userMusicDirectory,
|
|
|
|
/** The most likely place where a user might store their movie files.
|
|
*/
|
|
userMoviesDirectory,
|
|
};
|
|
|
|
/** Finds the location of a special type of file or directory, such as a home folder or
|
|
documents folder.
|
|
|
|
@see SpecialLocationType
|
|
*/
|
|
static const File JUCE_CALLTYPE getSpecialLocation (const SpecialLocationType type);
|
|
|
|
/** Returns a temporary file in the system's temp directory.
|
|
|
|
This will try to return the name of a non-existent temp file.
|
|
|
|
To get the temp folder, you can use getSpecialLocation (File::tempDirectory).
|
|
*/
|
|
static const File createTempFile (const String& fileNameEnding) throw();
|
|
|
|
/** Returns the current working directory.
|
|
|
|
@see setAsCurrentWorkingDirectory
|
|
*/
|
|
static const File getCurrentWorkingDirectory() throw();
|
|
|
|
/** Sets the current working directory to be this file.
|
|
|
|
For this to work the file must point to a valid directory.
|
|
|
|
@returns true if the current directory has been changed.
|
|
@see getCurrentWorkingDirectory
|
|
*/
|
|
bool setAsCurrentWorkingDirectory() const throw();
|
|
|
|
/** The system-specific file separator character.
|
|
|
|
On Windows, this will be '\', on Mac/Linux, it'll be '/'
|
|
*/
|
|
static const tchar separator;
|
|
|
|
/** The system-specific file separator character, as a string.
|
|
|
|
On Windows, this will be '\', on Mac/Linux, it'll be '/'
|
|
*/
|
|
static const tchar* separatorString;
|
|
|
|
/** Removes illegal characters from a filename.
|
|
|
|
This will return a copy of the given string after removing characters
|
|
that are not allowed in a legal filename, and possibly shortening the
|
|
string if it's too long.
|
|
|
|
Because this will remove slashes, don't use it on an absolute pathname.
|
|
|
|
@see createLegalPathName
|
|
*/
|
|
static const String createLegalFileName (const String& fileNameToFix) throw();
|
|
|
|
/** Removes illegal characters from a pathname.
|
|
|
|
Similar to createLegalFileName(), but this won't remove slashes, so can
|
|
be used on a complete pathname.
|
|
|
|
@see createLegalFileName
|
|
*/
|
|
static const String createLegalPathName (const String& pathNameToFix) throw();
|
|
|
|
/** Indicates whether filenames are case-sensitive on the current operating system.
|
|
*/
|
|
static bool areFileNamesCaseSensitive();
|
|
|
|
/** Returns true if the string seems to be a fully-specified absolute path.
|
|
*/
|
|
static bool isAbsolutePath (const String& path) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
String fullPath;
|
|
|
|
// internal way of contructing a file without checking the path
|
|
friend class DirectoryIterator;
|
|
File (const String&, int) throw();
|
|
const String getPathUpToLastSlash() const throw();
|
|
};
|
|
|
|
#endif // __JUCE_FILE_JUCEHEADER__
|
|
/********* End of inlined file: juce_File.h *********/
|
|
|
|
/**
|
|
A simple implemenation of a Logger that writes to a file.
|
|
|
|
@see Logger
|
|
*/
|
|
class JUCE_API FileLogger : public Logger
|
|
{
|
|
public:
|
|
|
|
/** Creates a FileLogger for a given file.
|
|
|
|
@param fileToWriteTo the file that to use - new messages will be appended
|
|
to the file. If the file doesn't exist, it will be created,
|
|
along with any parent directories that are needed.
|
|
@param welcomeMessage when opened, the logger will write a header to the log, along
|
|
with the current date and time, and this welcome message
|
|
@param maxInitialFileSizeBytes if this is zero or greater, then if the file already exists
|
|
but is larger than this number of bytes, then the start of the
|
|
file will be truncated to keep the size down. This prevents a log
|
|
file getting ridiculously large over time. The file will be truncated
|
|
at a new-line boundary. If this value is less than zero, no size limit
|
|
will be imposed; if it's zero, the file will always be deleted. Note that
|
|
the size is only checked once when this object is created - any logging
|
|
that is done later will be appended without any checking
|
|
*/
|
|
FileLogger (const File& fileToWriteTo,
|
|
const String& welcomeMessage,
|
|
const int maxInitialFileSizeBytes = 128 * 1024);
|
|
|
|
/** Destructor. */
|
|
~FileLogger();
|
|
|
|
void logMessage (const String& message);
|
|
|
|
/** Helper function to create a log file in the correct place for this platform.
|
|
|
|
On Windows this will return a logger with a path such as:
|
|
c:\\Documents and Settings\\username\\Application Data\\[logFileSubDirectoryName]\\[logFileName]
|
|
|
|
On the Mac it'll create something like:
|
|
~/Library/Logs/[logFileName]
|
|
|
|
The method might return 0 if the file can't be created for some reason.
|
|
|
|
@param logFileSubDirectoryName if a subdirectory is needed, this is what it will be called -
|
|
it's best to use the something like the name of your application here.
|
|
@param logFileName the name of the file to create, e.g. "MyAppLog.txt". Don't just
|
|
call it "log.txt" because if it goes in a directory with logs
|
|
from other applications (as it will do on the Mac) then no-one
|
|
will know which one is yours!
|
|
@param welcomeMessage a message that will be written to the log when it's opened.
|
|
@param maxInitialFileSizeBytes (see the FileLogger constructor for more info on this)
|
|
*/
|
|
static FileLogger* createDefaultAppLogger (const String& logFileSubDirectoryName,
|
|
const String& logFileName,
|
|
const String& welcomeMessage,
|
|
const int maxInitialFileSizeBytes = 128 * 1024);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
File logFile;
|
|
CriticalSection logLock;
|
|
FileOutputStream* logStream;
|
|
|
|
void trimFileSize (int maxFileSizeBytes) const;
|
|
|
|
FileLogger (const FileLogger&);
|
|
const FileLogger& operator= (const FileLogger&);
|
|
};
|
|
|
|
#endif // __JUCE_FILELOGGER_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileLogger.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_INITIALISATION_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Initialisation.h *********/
|
|
#ifndef __JUCE_INITIALISATION_JUCEHEADER__
|
|
#define __JUCE_INITIALISATION_JUCEHEADER__
|
|
|
|
/** Initialises Juce's GUI classes.
|
|
|
|
If you're embedding Juce into an application that uses its own event-loop rather
|
|
than using the START_JUCE_APPLICATION macro, call this function before making any
|
|
Juce calls, to make sure things are initialised correctly.
|
|
|
|
Note that if you're creating a Juce DLL for Windows, you may also need to call the
|
|
PlatformUtilities::setCurrentModuleInstanceHandle() method.
|
|
|
|
@see shutdownJuce_GUI(), initialiseJuce_NonGUI()
|
|
*/
|
|
void JUCE_PUBLIC_FUNCTION initialiseJuce_GUI();
|
|
|
|
/** Clears up any static data being used by Juce's GUI classes.
|
|
|
|
If you're embedding Juce into an application that uses its own event-loop rather
|
|
than using the START_JUCE_APPLICATION macro, call this function in your shutdown
|
|
code to clean up any juce objects that might be lying around.
|
|
|
|
@see initialiseJuce_GUI(), initialiseJuce_NonGUI()
|
|
*/
|
|
void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI();
|
|
|
|
/** Initialises the core parts of Juce.
|
|
|
|
If you're embedding Juce into either a command-line program, call this function
|
|
at the start of your main() function to make sure that Juce is initialised correctly.
|
|
|
|
Note that if you're creating a Juce DLL for Windows, you may also need to call the
|
|
PlatformUtilities::setCurrentModuleInstanceHandle() method.
|
|
|
|
@see shutdownJuce_NonGUI, initialiseJuce_GUI
|
|
*/
|
|
void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI();
|
|
|
|
/** Clears up any static data being used by Juce's non-gui core classes.
|
|
|
|
If you're embedding Juce into either a command-line program, call this function
|
|
at the end of your main() function if you want to make sure any Juce objects are
|
|
cleaned up correctly.
|
|
|
|
@see initialiseJuce_NonGUI, initialiseJuce_GUI
|
|
*/
|
|
void JUCE_PUBLIC_FUNCTION shutdownJuce_NonGUI();
|
|
|
|
#endif // __JUCE_INITIALISATION_JUCEHEADER__
|
|
/********* End of inlined file: juce_Initialisation.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_LOGGER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MATHSFUNCTIONS_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MEMORY_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_PERFORMANCECOUNTER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PerformanceCounter.h *********/
|
|
#ifndef __JUCE_PERFORMANCECOUNTER_JUCEHEADER__
|
|
#define __JUCE_PERFORMANCECOUNTER_JUCEHEADER__
|
|
|
|
/** A timer for measuring performance of code and dumping the results to a file.
|
|
|
|
e.g. @code
|
|
|
|
PerformanceCounter pc ("fish", 50, "/temp/myfishlog.txt");
|
|
|
|
for (;;)
|
|
{
|
|
pc.start();
|
|
|
|
doSomethingFishy();
|
|
|
|
pc.stop();
|
|
}
|
|
@endcode
|
|
|
|
In this example, the time of each period between calling start/stop will be
|
|
measured and averaged over 50 runs, and the results printed to a file
|
|
every 50 times round the loop.
|
|
*/
|
|
class JUCE_API PerformanceCounter
|
|
{
|
|
public:
|
|
|
|
/** Creates a PerformanceCounter object.
|
|
|
|
@param counterName the name used when printing out the statistics
|
|
@param runsPerPrintout the number of start/stop iterations before calling
|
|
printStatistics()
|
|
@param loggingFile a file to dump the results to - if this is File::nonexistent,
|
|
the results are just written to the debugger output
|
|
*/
|
|
PerformanceCounter (const String& counterName,
|
|
int runsPerPrintout = 100,
|
|
const File& loggingFile = File::nonexistent);
|
|
|
|
/** Destructor. */
|
|
~PerformanceCounter();
|
|
|
|
/** Starts timing.
|
|
|
|
@see stop
|
|
*/
|
|
void start();
|
|
|
|
/** Stops timing and prints out the results.
|
|
|
|
The number of iterations before doing a printout of the
|
|
results is set in the constructor.
|
|
|
|
@see start
|
|
*/
|
|
void stop();
|
|
|
|
/** Dumps the current metrics to the debugger output and to a file.
|
|
|
|
As well as using Logger::outputDebugString to print the results,
|
|
this will write then to the file specified in the constructor (if
|
|
this was valid).
|
|
*/
|
|
void printStatistics();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
String name;
|
|
int numRuns, runsPerPrint;
|
|
double totalTime;
|
|
int64 started;
|
|
File outputFile;
|
|
};
|
|
|
|
#endif // __JUCE_PERFORMANCECOUNTER_JUCEHEADER__
|
|
/********* End of inlined file: juce_PerformanceCounter.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_PLATFORMUTILITIES_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PlatformUtilities.h *********/
|
|
#ifndef __JUCE_PLATFORMUTILITIES_JUCEHEADER__
|
|
#define __JUCE_PLATFORMUTILITIES_JUCEHEADER__
|
|
|
|
/**
|
|
A collection of miscellaneous platform-specific utilities.
|
|
|
|
*/
|
|
class JUCE_API PlatformUtilities
|
|
{
|
|
public:
|
|
|
|
/** Plays the operating system's default alert 'beep' sound. */
|
|
static void beep();
|
|
|
|
static bool launchEmailWithAttachments (const String& targetEmailAddress,
|
|
const String& emailSubject,
|
|
const String& bodyText,
|
|
const StringArray& filesToAttach);
|
|
|
|
#if JUCE_MAC || DOXYGEN
|
|
|
|
/** MAC ONLY - Turns a Core CF String into a juce one. */
|
|
static const String cfStringToJuceString (CFStringRef cfString);
|
|
|
|
/** MAC ONLY - Turns a juce string into a Core CF one. */
|
|
static CFStringRef juceStringToCFString (const String& s);
|
|
|
|
/** MAC ONLY - Turns a file path into an FSRef, returning true if it succeeds. */
|
|
static bool makeFSRefFromPath (FSRef* destFSRef, const String& path);
|
|
|
|
/** MAC ONLY - Turns an FSRef into a juce string path. */
|
|
static const String makePathFromFSRef (FSRef* file);
|
|
|
|
/** MAC ONLY - Converts any decomposed unicode characters in a string into
|
|
their precomposed equivalents.
|
|
*/
|
|
static const String convertToPrecomposedUnicode (const String& s);
|
|
|
|
/** MAC ONLY - Gets the type of a file from the file's resources. */
|
|
static OSType getTypeOfFile (const String& filename);
|
|
|
|
/** MAC ONLY - Returns true if this file is actually a bundle. */
|
|
static bool isBundle (const String& filename);
|
|
|
|
/** MAC ONLY - Adds an item to the dock */
|
|
static void addItemToDock (const File& file);
|
|
#endif
|
|
|
|
#if JUCE_WIN32 || DOXYGEN
|
|
|
|
// Some registry helper functions:
|
|
|
|
/** WIN32 ONLY - Returns a string from the registry.
|
|
|
|
The path is a string for the entire path of a value in the registry,
|
|
e.g. "HKEY_CURRENT_USER\Software\foo\bar"
|
|
*/
|
|
static const String getRegistryValue (const String& regValuePath,
|
|
const String& defaultValue = String::empty);
|
|
|
|
/** WIN32 ONLY - Sets a registry value as a string.
|
|
|
|
This will take care of creating any groups needed to get to the given
|
|
registry value.
|
|
*/
|
|
static void setRegistryValue (const String& regValuePath,
|
|
const String& value);
|
|
|
|
/** WIN32 ONLY - Returns true if the given value exists in the registry. */
|
|
static bool registryValueExists (const String& regValuePath);
|
|
|
|
/** WIN32 ONLY - Deletes a registry value. */
|
|
static void deleteRegistryValue (const String& regValuePath);
|
|
|
|
/** WIN32 ONLY - Deletes a registry key (which is registry-talk for 'folder'). */
|
|
static void deleteRegistryKey (const String& regKeyPath);
|
|
|
|
/** WIN32 ONLY - Creates a file association in the registry.
|
|
|
|
This lets you set the exe that should be launched by a given file extension.
|
|
@param fileExtension the file extension to associate, including the
|
|
initial dot, e.g. ".txt"
|
|
@param symbolicDescription a space-free short token to identify the file type
|
|
@param fullDescription a human-readable description of the file type
|
|
@param targetExecutable the executable that should be launched
|
|
@param iconResourceNumber the icon that gets displayed for the file type will be
|
|
found by looking up this resource number in the
|
|
executable. Pass 0 here to not use an icon
|
|
*/
|
|
static void registerFileAssociation (const String& fileExtension,
|
|
const String& symbolicDescription,
|
|
const String& fullDescription,
|
|
const File& targetExecutable,
|
|
int iconResourceNumber);
|
|
|
|
/** WIN32 ONLY - This returns the HINSTANCE of the current module.
|
|
|
|
In a normal Juce application this will be set to the module handle
|
|
of the application executable.
|
|
|
|
If you're writing a DLL using Juce and plan to use any Juce messaging or
|
|
windows, you'll need to make sure you use the setCurrentModuleInstanceHandle()
|
|
to set the correct module handle in your DllMain() function, because
|
|
the win32 system relies on the correct instance handle when opening windows.
|
|
*/
|
|
static void* JUCE_CALLTYPE getCurrentModuleInstanceHandle() throw();
|
|
|
|
/** WIN32 ONLY - Sets a new module handle to be used by the library.
|
|
|
|
@see getCurrentModuleInstanceHandle()
|
|
*/
|
|
static void JUCE_CALLTYPE setCurrentModuleInstanceHandle (void* newHandle) throw();
|
|
|
|
/** WIN32 ONLY - Gets the command-line params as a string.
|
|
|
|
This is needed to avoid unicode problems with the argc type params.
|
|
*/
|
|
static const String JUCE_CALLTYPE getCurrentCommandLineParams() throw();
|
|
#endif
|
|
|
|
/** Clears the floating point unit's flags.
|
|
|
|
Only has an effect under win32, currently.
|
|
*/
|
|
static void fpuReset();
|
|
|
|
#if JUCE_LINUX || JUCE_WIN32
|
|
|
|
/** Loads a dynamically-linked library into the process's address space.
|
|
|
|
@param pathOrFilename the platform-dependent name and search path
|
|
@returns a handle which can be used by getProcedureEntryPoint(), or
|
|
zero if it fails.
|
|
@see freeDynamicLibrary, getProcedureEntryPoint
|
|
*/
|
|
static void* loadDynamicLibrary (const String& pathOrFilename);
|
|
|
|
/** Frees a dynamically-linked library.
|
|
|
|
@param libraryHandle a handle created by loadDynamicLibrary
|
|
@see loadDynamicLibrary, getProcedureEntryPoint
|
|
*/
|
|
static void freeDynamicLibrary (void* libraryHandle);
|
|
|
|
/** Finds a procedure call in a dynamically-linked library.
|
|
|
|
@param libraryHandle a library handle returned by loadDynamicLibrary
|
|
@param procedureName the name of the procedure call to try to load
|
|
@returns a pointer to the function if found, or 0 if it fails
|
|
@see loadDynamicLibrary
|
|
*/
|
|
static void* getProcedureEntryPoint (void* libraryHandle,
|
|
const String& procedureName);
|
|
#endif
|
|
|
|
#if JUCE_LINUX || DOXYGEN
|
|
|
|
#endif
|
|
};
|
|
|
|
#if JUCE_MAC
|
|
|
|
/** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object
|
|
using RAII.
|
|
*/
|
|
class ScopedAutoReleasePool
|
|
{
|
|
public:
|
|
ScopedAutoReleasePool();
|
|
~ScopedAutoReleasePool();
|
|
|
|
private:
|
|
void* pool;
|
|
};
|
|
|
|
/**
|
|
A wrapper class for picking up events from an Apple IR remote control device.
|
|
|
|
To use it, just create a subclass of this class, implementing the buttonPressed()
|
|
callback, then call start() and stop() to start or stop receiving events.
|
|
*/
|
|
class JUCE_API AppleRemoteDevice
|
|
{
|
|
public:
|
|
|
|
AppleRemoteDevice();
|
|
virtual ~AppleRemoteDevice();
|
|
|
|
/** The set of buttons that may be pressed.
|
|
@see buttonPressed
|
|
*/
|
|
enum ButtonType
|
|
{
|
|
menuButton = 0, /**< The menu button (if it's held for a short time). */
|
|
playButton, /**< The play button. */
|
|
plusButton, /**< The plus or volume-up button. */
|
|
minusButton, /**< The minus or volume-down button. */
|
|
rightButton, /**< The right button (if it's held for a short time). */
|
|
leftButton, /**< The left button (if it's held for a short time). */
|
|
rightButton_Long, /**< The right button (if it's held for a long time). */
|
|
leftButton_Long, /**< The menu button (if it's held for a long time). */
|
|
menuButton_Long, /**< The menu button (if it's held for a long time). */
|
|
playButtonSleepMode,
|
|
switched
|
|
};
|
|
|
|
/** Override this method to receive the callback about a button press.
|
|
|
|
The callback will happen on the application's message thread.
|
|
|
|
Some buttons trigger matching up and down events, in which the isDown parameter
|
|
will be true and then false. Others only send a single event when the
|
|
button is pressed.
|
|
*/
|
|
virtual void buttonPressed (const ButtonType buttonId, const bool isDown) = 0;
|
|
|
|
/** Starts the device running and responding to events.
|
|
|
|
Returns true if it managed to open the device.
|
|
|
|
@param inExclusiveMode if true, the remote will be grabbed exclusively for this app,
|
|
and will not be available to any other part of the system. If
|
|
false, it will be shared with other apps.
|
|
@see stop
|
|
*/
|
|
bool start (const bool inExclusiveMode) throw();
|
|
|
|
/** Stops the device running.
|
|
@see start
|
|
*/
|
|
void stop() throw();
|
|
|
|
/** Returns true if the device has been started successfully.
|
|
*/
|
|
bool isActive() const throw();
|
|
|
|
/** Returns the ID number of the remote, if it has sent one.
|
|
*/
|
|
int getRemoteId() const throw() { return remoteId; }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
/** @internal */
|
|
void handleCallbackInternal();
|
|
|
|
private:
|
|
void* device;
|
|
void* queue;
|
|
int remoteId;
|
|
|
|
bool open (const bool openInExclusiveMode) throw();
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif // __JUCE_PLATFORMUTILITIES_JUCEHEADER__
|
|
/********* End of inlined file: juce_PlatformUtilities.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_RANDOM_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Random.h *********/
|
|
#ifndef __JUCE_RANDOM_JUCEHEADER__
|
|
#define __JUCE_RANDOM_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_BitArray.h *********/
|
|
#ifndef __JUCE_BITARRAY_JUCEHEADER__
|
|
#define __JUCE_BITARRAY_JUCEHEADER__
|
|
|
|
class MemoryBlock;
|
|
|
|
/**
|
|
An array of on/off bits, also usable to store large binary integers.
|
|
|
|
A BitArray acts like an arbitrarily large integer whose bits can be set or
|
|
cleared, and some basic mathematical operations can be done on the number as
|
|
a whole.
|
|
*/
|
|
class JUCE_API BitArray
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty BitArray */
|
|
BitArray() throw();
|
|
|
|
/** Creates a BitArray containing an integer value in its low bits.
|
|
|
|
The low 32 bits of the array are initialised with this value.
|
|
*/
|
|
BitArray (const unsigned int value) throw();
|
|
|
|
/** Creates a BitArray containing an integer value in its low bits.
|
|
|
|
The low 32 bits of the array are initialised with the absolute value
|
|
passed in, and its sign is set to reflect the sign of the number.
|
|
*/
|
|
BitArray (const int value) throw();
|
|
|
|
/** Creates a BitArray containing an integer value in its low bits.
|
|
|
|
The low 64 bits of the array are initialised with the absolute value
|
|
passed in, and its sign is set to reflect the sign of the number.
|
|
*/
|
|
BitArray (int64 value) throw();
|
|
|
|
/** Creates a copy of another BitArray. */
|
|
BitArray (const BitArray& other) throw();
|
|
|
|
/** Destructor. */
|
|
~BitArray() throw();
|
|
|
|
/** Copies another BitArray onto this one. */
|
|
const BitArray& operator= (const BitArray& other) throw();
|
|
|
|
/** Two arrays are the same if the same bits are set. */
|
|
bool operator== (const BitArray& other) const throw();
|
|
/** Two arrays are the same if the same bits are set. */
|
|
bool operator!= (const BitArray& other) const throw();
|
|
|
|
/** Clears all bits in the BitArray to 0. */
|
|
void clear() throw();
|
|
|
|
/** Clears a particular bit in the array. */
|
|
void clearBit (const int bitNumber) throw();
|
|
|
|
/** Sets a specified bit to 1.
|
|
|
|
If the bit number is high, this will grow the array to accomodate it.
|
|
*/
|
|
void setBit (const int bitNumber) throw();
|
|
|
|
/** Sets or clears a specified bit. */
|
|
void setBit (const int bitNumber,
|
|
const bool shouldBeSet) throw();
|
|
|
|
/** Sets a range of bits to be either on or off.
|
|
|
|
@param startBit the first bit to change
|
|
@param numBits the number of bits to change
|
|
@param shouldBeSet whether to turn these bits on or off
|
|
*/
|
|
void setRange (int startBit,
|
|
int numBits,
|
|
const bool shouldBeSet) throw();
|
|
|
|
/** Inserts a bit an a given position, shifting up any bits above it. */
|
|
void insertBit (const int bitNumber,
|
|
const bool shouldBeSet) throw();
|
|
|
|
/** Returns the value of a specified bit in the array.
|
|
|
|
If the index is out-of-range, the result will be false.
|
|
*/
|
|
bool operator[] (const int bit) const throw();
|
|
|
|
/** Returns true if no bits are set. */
|
|
bool isEmpty() const throw();
|
|
|
|
/** Returns a range of bits in the array as a new BitArray.
|
|
|
|
e.g. getBitRangeAsInt (0, 64) would return the lowest 64 bits.
|
|
@see getBitRangeAsInt
|
|
*/
|
|
const BitArray getBitRange (int startBit, int numBits) const throw();
|
|
|
|
/** Returns a range of bits in the array as an integer value.
|
|
|
|
e.g. getBitRangeAsInt (0, 32) would return the lowest 32 bits.
|
|
|
|
Asking for more than 32 bits isn't allowed (obviously) - for that, use
|
|
getBitRange().
|
|
*/
|
|
int getBitRangeAsInt (int startBit, int numBits) const throw();
|
|
|
|
/** Sets a range of bits in the array based on an integer value.
|
|
|
|
Copies the given integer into the array, starting at startBit,
|
|
and only using up to numBits of the available bits.
|
|
*/
|
|
void setBitRangeAsInt (int startBit, int numBits,
|
|
unsigned int valueToSet) throw();
|
|
|
|
/** Performs a bitwise OR with another BitArray.
|
|
|
|
The result ends up in this array.
|
|
*/
|
|
void orWith (const BitArray& other) throw();
|
|
|
|
/** Performs a bitwise AND with another BitArray.
|
|
|
|
The result ends up in this array.
|
|
*/
|
|
void andWith (const BitArray& other) throw();
|
|
|
|
/** Performs a bitwise XOR with another BitArray.
|
|
|
|
The result ends up in this array.
|
|
*/
|
|
void xorWith (const BitArray& other) throw();
|
|
|
|
/** Adds another BitArray's value to this one.
|
|
|
|
Treating the two arrays as large positive integers, this
|
|
adds them up and puts the result in this array.
|
|
*/
|
|
void add (const BitArray& other) throw();
|
|
|
|
/** Subtracts another BitArray's value from this one.
|
|
|
|
Treating the two arrays as large positive integers, this
|
|
subtracts them and puts the result in this array.
|
|
|
|
Note that if the result should be negative, this won't be
|
|
handled correctly.
|
|
*/
|
|
void subtract (const BitArray& other) throw();
|
|
|
|
/** Multiplies another BitArray's value with this one.
|
|
|
|
Treating the two arrays as large positive integers, this
|
|
multiplies them and puts the result in this array.
|
|
*/
|
|
void multiplyBy (const BitArray& other) throw();
|
|
|
|
/** Divides another BitArray's value into this one and also produces a remainder.
|
|
|
|
Treating the two arrays as large positive integers, this
|
|
divides this value by the other, leaving the quotient in this
|
|
array, and the remainder is copied into the other BitArray passed in.
|
|
*/
|
|
void divideBy (const BitArray& divisor, BitArray& remainder) throw();
|
|
|
|
/** Returns the largest value that will divide both this value and the one
|
|
passed-in.
|
|
*/
|
|
const BitArray findGreatestCommonDivisor (BitArray other) const throw();
|
|
|
|
/** Performs a modulo operation on this value.
|
|
|
|
The result is stored in this value.
|
|
*/
|
|
void modulo (const BitArray& divisor) throw();
|
|
|
|
/** Performs a combined exponent and modulo operation.
|
|
|
|
This BitArray's value becomes (this ^ exponent) % modulus.
|
|
*/
|
|
void exponentModulo (const BitArray& exponent, const BitArray& modulus) throw();
|
|
|
|
/** Performs an inverse modulo on the value.
|
|
|
|
i.e. the result is (this ^ -1) mod (modulus).
|
|
*/
|
|
void inverseModulo (const BitArray& modulus) throw();
|
|
|
|
/** Shifts a section of bits left or right.
|
|
|
|
@param howManyBitsLeft how far to move the bits (+ve numbers shift it left, -ve numbers shift it right).
|
|
@param startBit the first bit to affect - if this is > 0, only bits above that index will be affected.
|
|
*/
|
|
void shiftBits (int howManyBitsLeft,
|
|
int startBit = 0) throw();
|
|
|
|
/** Does a signed comparison of two BitArrays.
|
|
|
|
Return values are:
|
|
- 0 if the numbers are the same
|
|
- < 0 if this number is smaller than the other
|
|
- > 0 if this number is bigger than the other
|
|
*/
|
|
int compare (const BitArray& other) const throw();
|
|
|
|
/** Compares the magnitudes of two BitArrays, ignoring their signs.
|
|
|
|
Return values are:
|
|
- 0 if the numbers are the same
|
|
- < 0 if this number is smaller than the other
|
|
- > 0 if this number is bigger than the other
|
|
*/
|
|
int compareAbsolute (const BitArray& other) const throw();
|
|
|
|
/** Returns true if the value is less than zero.
|
|
|
|
@see setNegative, negate
|
|
*/
|
|
bool isNegative() const throw();
|
|
|
|
/** Changes the sign of the number to be positive or negative.
|
|
|
|
@see isNegative, negate
|
|
*/
|
|
void setNegative (const bool shouldBeNegative) throw();
|
|
|
|
/** Inverts the sign of the number.
|
|
|
|
@see isNegative, setNegative
|
|
*/
|
|
void negate() throw();
|
|
|
|
/** Counts the total number of set bits in the array. */
|
|
int countNumberOfSetBits() const throw();
|
|
|
|
/** Looks for the index of the next set bit after a given starting point.
|
|
|
|
searches from startIndex (inclusive) upwards for the first set bit,
|
|
and returns its index.
|
|
|
|
If no set bits are found, it returns -1.
|
|
*/
|
|
int findNextSetBit (int startIndex = 0) const throw();
|
|
|
|
/** Looks for the index of the next clear bit after a given starting point.
|
|
|
|
searches from startIndex (inclusive) upwards for the first clear bit,
|
|
and returns its index.
|
|
*/
|
|
int findNextClearBit (int startIndex = 0) const throw();
|
|
|
|
/** Returns the index of the highest set bit in the array.
|
|
|
|
If the array is empty, this will return -1.
|
|
*/
|
|
int getHighestBit() const throw();
|
|
|
|
/** Converts the array to a number string.
|
|
|
|
Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex).
|
|
|
|
If minuimumNumCharacters is greater than 0, the returned string will be
|
|
padded with leading zeros to reach at least that length.
|
|
*/
|
|
const String toString (const int base, const int minimumNumCharacters = 1) const throw();
|
|
|
|
/** Converts a number string to an array.
|
|
|
|
Any non-valid characters will be ignored.
|
|
|
|
Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex).
|
|
*/
|
|
void parseString (const String& text,
|
|
const int base) throw();
|
|
|
|
/** Turns the array into a block of binary data.
|
|
|
|
The data is arranged as little-endian, so the first byte of data is the low 8 bits
|
|
of the array, and so on.
|
|
|
|
@see loadFromMemoryBlock
|
|
*/
|
|
const MemoryBlock toMemoryBlock() const throw();
|
|
|
|
/** Copies a block of raw data onto this array.
|
|
|
|
The data is arranged as little-endian, so the first byte of data is the low 8 bits
|
|
of the array, and so on.
|
|
|
|
@see toMemoryBlock
|
|
*/
|
|
void loadFromMemoryBlock (const MemoryBlock& data) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
void ensureSize (const int numVals) throw();
|
|
unsigned int* values;
|
|
int numValues, highestBit;
|
|
bool negative;
|
|
};
|
|
|
|
#endif // __JUCE_BITARRAY_JUCEHEADER__
|
|
/********* End of inlined file: juce_BitArray.h *********/
|
|
|
|
/**
|
|
A simple pseudo-random number generator.
|
|
*/
|
|
class JUCE_API Random
|
|
{
|
|
public:
|
|
|
|
/** Creates a Random object based on a seed value.
|
|
|
|
For a given seed value, the subsequent numbers generated by this object
|
|
will be predictable, so a good idea is to set this value based
|
|
on the time, e.g.
|
|
|
|
new Random (Time::currentTimeMillis())
|
|
*/
|
|
Random (const int64 seedValue) throw();
|
|
|
|
/** Destructor. */
|
|
~Random() throw();
|
|
|
|
/** Returns the next random 32 bit integer.
|
|
|
|
@returns a random integer from the full range 0x80000000 to 0x7fffffff
|
|
*/
|
|
int nextInt() throw();
|
|
|
|
/** Returns the next random number, limited to a given range.
|
|
|
|
@returns a random integer between 0 (inclusive) and maxValue (exclusive).
|
|
*/
|
|
int nextInt (const int maxValue) throw();
|
|
|
|
/** Returns the next 64-bit random number.
|
|
|
|
@returns a random integer from the full range 0x8000000000000000 to 0x7fffffffffffffff
|
|
*/
|
|
int64 nextInt64() throw();
|
|
|
|
/** Returns the next random floating-point number.
|
|
|
|
@returns a random value in the range 0 to 1.0
|
|
*/
|
|
float nextFloat() throw();
|
|
|
|
/** Returns the next random floating-point number.
|
|
|
|
@returns a random value in the range 0 to 1.0
|
|
*/
|
|
double nextDouble() throw();
|
|
|
|
/** Returns the next random boolean value.
|
|
*/
|
|
bool nextBool() throw();
|
|
|
|
/** Returns a BitArray containing a random number.
|
|
|
|
@returns a random value in the range 0 to (maximumValue - 1).
|
|
*/
|
|
const BitArray nextLargeNumber (const BitArray& maximumValue) throw();
|
|
|
|
/** Sets a range of bits in a BitArray to random values. */
|
|
void fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw();
|
|
|
|
/** To avoid the overhead of having to create a new Random object whenever
|
|
you need a number, this is a shared application-wide object that
|
|
can be used.
|
|
|
|
It's not thread-safe though, so threads should use their own Random object.
|
|
*/
|
|
static Random& getSystemRandom() throw();
|
|
|
|
/** Resets this Random object to a given seed value. */
|
|
void setSeed (const int64 newSeed) throw();
|
|
|
|
/** Reseeds this generator using a value generated from various semi-random system
|
|
properties like the current time, etc.
|
|
|
|
Because this function convolves the time with the last seed value, calling
|
|
it repeatedly will increase the randomness of the final result.
|
|
*/
|
|
void setSeedRandomly();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int64 seed;
|
|
};
|
|
|
|
#endif // __JUCE_RANDOM_JUCEHEADER__
|
|
/********* End of inlined file: juce_Random.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_RELATIVETIME_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_SINGLETON_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Singleton.h *********/
|
|
#ifndef __JUCE_SINGLETON_JUCEHEADER__
|
|
#define __JUCE_SINGLETON_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ScopedLock.h *********/
|
|
#ifndef __JUCE_SCOPEDLOCK_JUCEHEADER__
|
|
#define __JUCE_SCOPEDLOCK_JUCEHEADER__
|
|
|
|
/**
|
|
Automatically locks and unlocks a CriticalSection object.
|
|
|
|
Use one of these as a local variable to control access to a CriticalSection.
|
|
|
|
e.g. @code
|
|
|
|
CriticalSection myCriticalSection;
|
|
|
|
for (;;)
|
|
{
|
|
const ScopedLock myScopedLock (myCriticalSection);
|
|
// myCriticalSection is now locked
|
|
|
|
...do some stuff...
|
|
|
|
// myCriticalSection gets unlocked here.
|
|
}
|
|
@endcode
|
|
|
|
@see CriticalSection, ScopedUnlock
|
|
*/
|
|
class JUCE_API ScopedLock
|
|
{
|
|
public:
|
|
|
|
/** Creates a ScopedLock.
|
|
|
|
As soon as it is created, this will lock the CriticalSection, and
|
|
when the ScopedLock object is deleted, the CriticalSection will
|
|
be unlocked.
|
|
|
|
Make sure this object is created and deleted by the same thread,
|
|
otherwise there are no guarantees what will happen! Best just to use it
|
|
as a local stack object, rather than creating one with the new() operator.
|
|
*/
|
|
inline ScopedLock (const CriticalSection& lock) throw() : lock_ (lock) { lock.enter(); }
|
|
|
|
/** Destructor.
|
|
|
|
The CriticalSection will be unlocked when the destructor is called.
|
|
|
|
Make sure this object is created and deleted by the same thread,
|
|
otherwise there are no guarantees what will happen!
|
|
*/
|
|
inline ~ScopedLock() throw() { lock_.exit(); }
|
|
|
|
private:
|
|
|
|
const CriticalSection& lock_;
|
|
|
|
ScopedLock (const ScopedLock&);
|
|
const ScopedLock& operator= (const ScopedLock&);
|
|
};
|
|
|
|
/**
|
|
Automatically unlocks and re-locks a CriticalSection object.
|
|
|
|
This is the reverse of a ScopedLock object - instead of locking the critical
|
|
section for the lifetime of this object, it unlocks it.
|
|
|
|
Make sure you don't try to unlock critical sections that aren't actually locked!
|
|
|
|
e.g. @code
|
|
|
|
CriticalSection myCriticalSection;
|
|
|
|
for (;;)
|
|
{
|
|
const ScopedLock myScopedLock (myCriticalSection);
|
|
// myCriticalSection is now locked
|
|
|
|
... do some stuff with it locked ..
|
|
|
|
while (xyz)
|
|
{
|
|
... do some stuff with it locked ..
|
|
|
|
const ScopedUnlock unlocker (myCriticalSection);
|
|
|
|
// myCriticalSection is now unlocked for the remainder of this block,
|
|
// and re-locked at the end.
|
|
|
|
...do some stuff with it unlocked ...
|
|
}
|
|
|
|
// myCriticalSection gets unlocked here.
|
|
}
|
|
@endcode
|
|
|
|
@see CriticalSection, ScopedLock
|
|
*/
|
|
class ScopedUnlock
|
|
{
|
|
public:
|
|
|
|
/** Creates a ScopedUnlock.
|
|
|
|
As soon as it is created, this will unlock the CriticalSection, and
|
|
when the ScopedLock object is deleted, the CriticalSection will
|
|
be re-locked.
|
|
|
|
Make sure this object is created and deleted by the same thread,
|
|
otherwise there are no guarantees what will happen! Best just to use it
|
|
as a local stack object, rather than creating one with the new() operator.
|
|
*/
|
|
inline ScopedUnlock (const CriticalSection& lock) throw() : lock_ (lock) { lock.exit(); }
|
|
|
|
/** Destructor.
|
|
|
|
The CriticalSection will be unlocked when the destructor is called.
|
|
|
|
Make sure this object is created and deleted by the same thread,
|
|
otherwise there are no guarantees what will happen!
|
|
*/
|
|
inline ~ScopedUnlock() throw() { lock_.enter(); }
|
|
|
|
private:
|
|
|
|
const CriticalSection& lock_;
|
|
|
|
ScopedUnlock (const ScopedLock&);
|
|
const ScopedUnlock& operator= (const ScopedUnlock&);
|
|
};
|
|
|
|
#endif // __JUCE_SCOPEDLOCK_JUCEHEADER__
|
|
/********* End of inlined file: juce_ScopedLock.h *********/
|
|
|
|
/**
|
|
Macro to declare member variables and methods for a singleton class.
|
|
|
|
To use this, add the line juce_DeclareSingleton (MyClass, allowOnlyOneInstance)
|
|
to the class's definition.
|
|
|
|
If allowOnlyOneInstance == true, it won't allow the object to be created
|
|
more than once in the process's lifetime.
|
|
|
|
Then put a macro juce_ImplementSingleton (MyClass) along with the class's
|
|
implementation code.
|
|
|
|
Clients can then call the static MyClass::getInstance() to get a pointer to the
|
|
singleton, or MyClass::getInstanceWithoutCreating() which may return 0 if no instance
|
|
is currently extant
|
|
|
|
it's a very good idea to also add the call clearSingletonInstance() to the
|
|
destructor of the class, in case it is deleted by other means than deleteInstance()
|
|
|
|
e.g. @code
|
|
|
|
class MySingleton
|
|
{
|
|
public:
|
|
MySingleton()
|
|
{
|
|
}
|
|
|
|
~MySingleton()
|
|
{
|
|
// this ensures that no dangling pointers are left when the
|
|
// singleton is deleted.
|
|
clearSingletonInstance();
|
|
}
|
|
|
|
juce_DeclareSingleton (MySingleton, false)
|
|
};
|
|
|
|
juce_ImplementSingleton (MySingleton)
|
|
|
|
// example of usage:
|
|
MySingleton* m = MySingleton::getInstance(); // creates the singleton if there isn't already one.
|
|
|
|
...
|
|
|
|
MySingleton::deleteInstance(); // safely deletes the singleton (if it's been created).
|
|
|
|
@endcode
|
|
|
|
If you know that your object will only be created and deleted by a single thread, you
|
|
can use the slightly more efficient juce_DeclareSingleton_SingleThreaded() macro instead
|
|
of this one.
|
|
|
|
@see juce_ImplementSingleton, juce_DeclareSingleton_SingleThreaded
|
|
*/
|
|
#define juce_DeclareSingleton(classname, allowOnlyOneInstance) \
|
|
\
|
|
static classname* _singletonInstance; \
|
|
static JUCE_NAMESPACE::CriticalSection _singletonLock; \
|
|
\
|
|
static classname* getInstance() \
|
|
{ \
|
|
if (_singletonInstance == 0) \
|
|
{\
|
|
const JUCE_NAMESPACE::ScopedLock sl (_singletonLock); \
|
|
\
|
|
if (_singletonInstance == 0) \
|
|
{ \
|
|
static bool alreadyInside = false; \
|
|
static bool createdOnceAlready = false; \
|
|
\
|
|
const bool problem = alreadyInside || ((allowOnlyOneInstance) && createdOnceAlready); \
|
|
jassert (! problem); \
|
|
if (! problem) \
|
|
{ \
|
|
createdOnceAlready = true; \
|
|
alreadyInside = true; \
|
|
classname* newObject = new classname(); /* (use a stack variable to avoid setting the newObject value before the class has finished its constructor) */ \
|
|
alreadyInside = false; \
|
|
\
|
|
_singletonInstance = newObject; \
|
|
} \
|
|
} \
|
|
} \
|
|
\
|
|
return _singletonInstance; \
|
|
} \
|
|
\
|
|
static inline classname* getInstanceWithoutCreating() throw() \
|
|
{ \
|
|
return _singletonInstance; \
|
|
} \
|
|
\
|
|
static void deleteInstance() \
|
|
{ \
|
|
const JUCE_NAMESPACE::ScopedLock sl (_singletonLock); \
|
|
if (_singletonInstance != 0) \
|
|
{ \
|
|
classname* const old = _singletonInstance; \
|
|
_singletonInstance = 0; \
|
|
delete old; \
|
|
} \
|
|
} \
|
|
\
|
|
void clearSingletonInstance() throw() \
|
|
{ \
|
|
if (_singletonInstance == this) \
|
|
_singletonInstance = 0; \
|
|
}
|
|
|
|
/** This is a counterpart to the juce_DeclareSingleton macro.
|
|
|
|
After adding the juce_DeclareSingleton to the class definition, this macro has
|
|
to be used in the cpp file.
|
|
*/
|
|
#define juce_ImplementSingleton(classname) \
|
|
\
|
|
classname* classname::_singletonInstance = 0; \
|
|
JUCE_NAMESPACE::CriticalSection classname::_singletonLock;
|
|
|
|
/**
|
|
Macro to declare member variables and methods for a singleton class.
|
|
|
|
This is exactly the same as juce_DeclareSingleton, but doesn't use a critical
|
|
section to make access to it thread-safe. If you know that your object will
|
|
only ever be created or deleted by a single thread, then this is a
|
|
more efficient version to use.
|
|
|
|
See the documentation for juce_DeclareSingleton for more information about
|
|
how to use it, the only difference being that you have to use
|
|
juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton.
|
|
|
|
@see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton, juce_DeclareSingleton_SingleThreaded_Minimal
|
|
*/
|
|
#define juce_DeclareSingleton_SingleThreaded(classname, allowOnlyOneInstance) \
|
|
\
|
|
static classname* _singletonInstance; \
|
|
\
|
|
static classname* getInstance() \
|
|
{ \
|
|
if (_singletonInstance == 0) \
|
|
{ \
|
|
static bool alreadyInside = false; \
|
|
static bool createdOnceAlready = false; \
|
|
\
|
|
const bool problem = alreadyInside || ((allowOnlyOneInstance) && createdOnceAlready); \
|
|
jassert (! problem); \
|
|
if (! problem) \
|
|
{ \
|
|
createdOnceAlready = true; \
|
|
alreadyInside = true; \
|
|
classname* newObject = new classname(); /* (use a stack variable to avoid setting the newObject value before the class has finished its constructor) */ \
|
|
alreadyInside = false; \
|
|
\
|
|
_singletonInstance = newObject; \
|
|
} \
|
|
} \
|
|
\
|
|
return _singletonInstance; \
|
|
} \
|
|
\
|
|
static inline classname* getInstanceWithoutCreating() throw() \
|
|
{ \
|
|
return _singletonInstance; \
|
|
} \
|
|
\
|
|
static void deleteInstance() \
|
|
{ \
|
|
if (_singletonInstance != 0) \
|
|
{ \
|
|
classname* const old = _singletonInstance; \
|
|
_singletonInstance = 0; \
|
|
delete old; \
|
|
} \
|
|
} \
|
|
\
|
|
void clearSingletonInstance() throw() \
|
|
{ \
|
|
if (_singletonInstance == this) \
|
|
_singletonInstance = 0; \
|
|
}
|
|
|
|
/**
|
|
Macro to declare member variables and methods for a singleton class.
|
|
|
|
This is like juce_DeclareSingleton_SingleThreaded, but doesn't do any checking
|
|
for recursion or repeated instantiation. It's intended for use as a lightweight
|
|
version of a singleton, where you're using it in very straightforward
|
|
circumstances and don't need the extra checking.
|
|
|
|
Juce use the normal juce_ImplementSingleton_SingleThreaded as the counterpart
|
|
to this declaration, as you would with juce_DeclareSingleton_SingleThreaded.
|
|
|
|
See the documentation for juce_DeclareSingleton for more information about
|
|
how to use it, the only difference being that you have to use
|
|
juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton.
|
|
|
|
@see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton
|
|
*/
|
|
#define juce_DeclareSingleton_SingleThreaded_Minimal(classname) \
|
|
\
|
|
static classname* _singletonInstance; \
|
|
\
|
|
static classname* getInstance() \
|
|
{ \
|
|
if (_singletonInstance == 0) \
|
|
_singletonInstance = new classname(); \
|
|
\
|
|
return _singletonInstance; \
|
|
} \
|
|
\
|
|
static inline classname* getInstanceWithoutCreating() throw() \
|
|
{ \
|
|
return _singletonInstance; \
|
|
} \
|
|
\
|
|
static void deleteInstance() \
|
|
{ \
|
|
if (_singletonInstance != 0) \
|
|
{ \
|
|
classname* const old = _singletonInstance; \
|
|
_singletonInstance = 0; \
|
|
delete old; \
|
|
} \
|
|
} \
|
|
\
|
|
void clearSingletonInstance() throw() \
|
|
{ \
|
|
if (_singletonInstance == this) \
|
|
_singletonInstance = 0; \
|
|
}
|
|
|
|
/** This is a counterpart to the juce_DeclareSingleton_SingleThreaded macro.
|
|
|
|
After adding juce_DeclareSingleton_SingleThreaded or juce_DeclareSingleton_SingleThreaded_Minimal
|
|
to the class definition, this macro has to be used somewhere in the cpp file.
|
|
*/
|
|
#define juce_ImplementSingleton_SingleThreaded(classname) \
|
|
\
|
|
classname* classname::_singletonInstance = 0;
|
|
|
|
#endif // __JUCE_SINGLETON_JUCEHEADER__
|
|
/********* End of inlined file: juce_Singleton.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_STANDARDHEADER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_SystemStats.h *********/
|
|
#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__
|
|
#define __JUCE_SYSTEMSTATS_JUCEHEADER__
|
|
|
|
/**
|
|
Contains methods for finding out about the current hardware and OS configuration.
|
|
*/
|
|
class JUCE_API SystemStats
|
|
{
|
|
public:
|
|
|
|
/** Returns the current version of JUCE,
|
|
|
|
(just in case you didn't already know at compile-time.)
|
|
|
|
See also the JUCE_VERSION, JUCE_MAJOR_VERSION and JUCE_MINOR_VERSION macros.
|
|
*/
|
|
static const String getJUCEVersion() throw();
|
|
|
|
/** The set of possible results of the getOperatingSystemType() method.
|
|
*/
|
|
enum OperatingSystemType
|
|
{
|
|
UnknownOS = 0,
|
|
|
|
MacOSX = 0x1000,
|
|
Linux = 0x2000,
|
|
|
|
Win95 = 0x4001,
|
|
Win98 = 0x4002,
|
|
WinNT351 = 0x4103,
|
|
WinNT40 = 0x4104,
|
|
Win2000 = 0x4105,
|
|
WinXP = 0x4106,
|
|
WinVista = 0x4107,
|
|
Windows7 = 0x4108,
|
|
|
|
Windows = 0x4000, /**< To test whether any version of Windows is running,
|
|
you can use the expression ((getOperatingSystemType() & Windows) != 0). */
|
|
WindowsNT = 0x0100, /**< To test whether the platform is Windows NT or later (i.e. not Win95 or 98),
|
|
you can use the expression ((getOperatingSystemType() & WindowsNT) != 0). */
|
|
};
|
|
|
|
/** Returns the type of operating system we're running on.
|
|
|
|
@returns one of the values from the OperatingSystemType enum.
|
|
@see getOperatingSystemName
|
|
*/
|
|
static OperatingSystemType getOperatingSystemType() throw();
|
|
|
|
/** Returns the name of the type of operating system we're running on.
|
|
|
|
@returns a string describing the OS type.
|
|
@see getOperatingSystemType
|
|
*/
|
|
static const String getOperatingSystemName() throw();
|
|
|
|
/** Returns true if the OS is 64-bit, or false for a 32-bit OS.
|
|
*/
|
|
static bool isOperatingSystem64Bit() throw();
|
|
|
|
// CPU and memory information..
|
|
|
|
/** Returns the approximate CPU speed.
|
|
|
|
@returns the speed in megahertz, e.g. 1500, 2500, 32000 (depending on
|
|
what year you're reading this...)
|
|
*/
|
|
static int getCpuSpeedInMegaherz() throw();
|
|
|
|
/** Returns a string to indicate the CPU vendor.
|
|
|
|
Might not be known on some systems.
|
|
*/
|
|
static const String getCpuVendor() throw();
|
|
|
|
/** Checks whether Intel MMX instructions are available. */
|
|
static bool hasMMX() throw();
|
|
|
|
/** Checks whether Intel SSE instructions are available. */
|
|
static bool hasSSE() throw();
|
|
|
|
/** Checks whether Intel SSE2 instructions are available. */
|
|
static bool hasSSE2() throw();
|
|
|
|
/** Checks whether AMD 3DNOW instructions are available. */
|
|
static bool has3DNow() throw();
|
|
|
|
/** Returns the number of CPUs.
|
|
*/
|
|
static int getNumCpus() throw();
|
|
|
|
/** Returns a clock-cycle tick counter, if available.
|
|
|
|
If the machine can do it, this will return a tick-count
|
|
where each tick is one cpu clock cycle - used for profiling
|
|
code.
|
|
|
|
@returns the tick count, or zero if not available.
|
|
*/
|
|
static int64 getClockCycleCounter() throw();
|
|
|
|
/** Finds out how much RAM is in the machine.
|
|
|
|
@returns the approximate number of megabytes of memory, or zero if
|
|
something goes wrong when finding out.
|
|
*/
|
|
static int getMemorySizeInMegabytes() throw();
|
|
|
|
/** Returns the system page-size.
|
|
|
|
This is only used by programmers with beards.
|
|
*/
|
|
static int getPageSize() throw();
|
|
|
|
/** Returns a list of MAC addresses found on this machine.
|
|
|
|
@param addresses an array into which the MAC addresses should be copied
|
|
@param maxNum the number of elements in this array
|
|
@param littleEndian the endianness of the numbers to return. Note that
|
|
the default values of this parameter are different on
|
|
Mac/PC to avoid breaking old software that was written
|
|
before this parameter was added (when the two systems
|
|
defaulted to using different endiannesses). In newer
|
|
software you probably want to specify an explicit value
|
|
for this.
|
|
@returns the number of MAC addresses that were found
|
|
*/
|
|
static int getMACAddresses (int64* addresses, int maxNum,
|
|
#if JUCE_MAC
|
|
const bool littleEndian = true) throw();
|
|
#else
|
|
const bool littleEndian = false) throw();
|
|
#endif
|
|
|
|
// not-for-public-use platform-specific method gets called at startup to initialise things.
|
|
static void initialiseStats() throw();
|
|
};
|
|
|
|
#endif // __JUCE_SYSTEMSTATS_JUCEHEADER__
|
|
/********* End of inlined file: juce_SystemStats.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TIME_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_UUID_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Uuid.h *********/
|
|
#ifndef __JUCE_UUID_JUCEHEADER__
|
|
#define __JUCE_UUID_JUCEHEADER__
|
|
|
|
/**
|
|
A universally unique 128-bit identifier.
|
|
|
|
This class generates very random unique numbers based on the system time
|
|
and MAC addresses if any are available. It's extremely unlikely that two identical
|
|
UUIDs would ever be created by chance.
|
|
|
|
The class includes methods for saving the ID as a string or as raw binary data.
|
|
*/
|
|
class JUCE_API Uuid
|
|
{
|
|
public:
|
|
|
|
/** Creates a new unique ID. */
|
|
Uuid();
|
|
|
|
/** Destructor. */
|
|
~Uuid() throw();
|
|
|
|
/** Creates a copy of another UUID. */
|
|
Uuid (const Uuid& other);
|
|
|
|
/** Copies another UUID. */
|
|
Uuid& operator= (const Uuid& other);
|
|
|
|
/** Returns true if the ID is zero. */
|
|
bool isNull() const throw();
|
|
|
|
/** Compares two UUIDs. */
|
|
bool operator== (const Uuid& other) const;
|
|
|
|
/** Compares two UUIDs. */
|
|
bool operator!= (const Uuid& other) const;
|
|
|
|
/** Returns a stringified version of this UUID.
|
|
|
|
A Uuid object can later be reconstructed from this string using operator= or
|
|
the constructor that takes a string parameter.
|
|
|
|
@returns a 32 character hex string.
|
|
*/
|
|
const String toString() const;
|
|
|
|
/** Creates an ID from an encoded string version.
|
|
|
|
@see toString
|
|
*/
|
|
Uuid (const String& uuidString);
|
|
|
|
/** Copies from a stringified UUID.
|
|
|
|
The string passed in should be one that was created with the toString() method.
|
|
*/
|
|
Uuid& operator= (const String& uuidString);
|
|
|
|
/** Returns a pointer to the internal binary representation of the ID.
|
|
|
|
This is an array of 16 bytes. To reconstruct a Uuid from its data, use
|
|
the constructor or operator= method that takes an array of uint8s.
|
|
*/
|
|
const uint8* getRawData() const throw() { return value.asBytes; }
|
|
|
|
/** Creates a UUID from a 16-byte array.
|
|
|
|
@see getRawData
|
|
*/
|
|
Uuid (const uint8* const rawData);
|
|
|
|
/** Sets this UUID from 16-bytes of raw data. */
|
|
Uuid& operator= (const uint8* const rawData);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
union
|
|
{
|
|
uint8 asBytes [16];
|
|
int asInt[4];
|
|
int64 asInt64[2];
|
|
|
|
} value;
|
|
};
|
|
|
|
#endif // __JUCE_UUID_JUCEHEADER__
|
|
/********* End of inlined file: juce_Uuid.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_ARRAY_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_BITARRAY_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_OWNEDARRAY_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_PROPERTYSET_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PropertySet.h *********/
|
|
#ifndef __JUCE_PROPERTYSET_JUCEHEADER__
|
|
#define __JUCE_PROPERTYSET_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_StringPairArray.h *********/
|
|
#ifndef __JUCE_STRINGPAIRARRAY_JUCEHEADER__
|
|
#define __JUCE_STRINGPAIRARRAY_JUCEHEADER__
|
|
|
|
/**
|
|
A container for holding a set of strings which are keyed by another string.
|
|
|
|
@see StringArray
|
|
*/
|
|
class JUCE_API StringPairArray
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty array */
|
|
StringPairArray (const bool ignoreCaseWhenComparingKeys = true) throw();
|
|
|
|
/** Creates a copy of another array */
|
|
StringPairArray (const StringPairArray& other) throw();
|
|
|
|
/** Destructor. */
|
|
~StringPairArray() throw();
|
|
|
|
/** Copies the contents of another string array into this one */
|
|
const StringPairArray& operator= (const StringPairArray& other) throw();
|
|
|
|
/** Compares two arrays.
|
|
|
|
Comparisons are case-sensitive.
|
|
|
|
@returns true only if the other array contains exactly the same strings with the same keys
|
|
*/
|
|
bool operator== (const StringPairArray& other) const throw();
|
|
|
|
/** Compares two arrays.
|
|
|
|
Comparisons are case-sensitive.
|
|
|
|
@returns false if the other array contains exactly the same strings with the same keys
|
|
*/
|
|
bool operator!= (const StringPairArray& other) const throw();
|
|
|
|
/** Finds the value corresponding to a key string.
|
|
|
|
If no such key is found, this will just return an empty string. To check whether
|
|
a given key actually exists (because it might actually be paired with an empty string), use
|
|
the getAllKeys() method to obtain a list.
|
|
|
|
Obviously the reference returned shouldn't be stored for later use, as the
|
|
string it refers to may disappear when the array changes.
|
|
|
|
@see getValue
|
|
*/
|
|
const String& operator[] (const String& key) const throw();
|
|
|
|
/** Finds the value corresponding to a key string.
|
|
|
|
If no such key is found, this will just return the value provided as a default.
|
|
|
|
@see operator[]
|
|
*/
|
|
const String getValue (const String& key, const String& defaultReturnValue) const;
|
|
|
|
/** Returns a list of all keys in the array. */
|
|
const StringArray& getAllKeys() const throw() { return keys; }
|
|
|
|
/** Returns a list of all values in the array. */
|
|
const StringArray& getAllValues() const throw() { return values; }
|
|
|
|
/** Returns the number of strings in the array */
|
|
inline int size() const throw() { return keys.size(); };
|
|
|
|
/** Adds or amends a key/value pair.
|
|
|
|
If a value already exists with this key, its value will be overwritten,
|
|
otherwise the key/value pair will be added to the array.
|
|
*/
|
|
void set (const String& key,
|
|
const String& value) throw();
|
|
|
|
/** Adds the items from another array to this one.
|
|
|
|
This is equivalent to using set() to add each of the pairs from the other array.
|
|
*/
|
|
void addArray (const StringPairArray& other);
|
|
|
|
/** Removes all elements from the array. */
|
|
void clear() throw();
|
|
|
|
/** Removes a string from the array based on its key.
|
|
|
|
If the key isn't found, nothing will happen.
|
|
*/
|
|
void remove (const String& key) throw();
|
|
|
|
/** Removes a string from the array based on its index.
|
|
|
|
If the index is out-of-range, no action will be taken.
|
|
*/
|
|
void remove (const int index) throw();
|
|
|
|
/** Indicates whether to use a case-insensitive search when looking up a key string.
|
|
*/
|
|
void setIgnoresCase (const bool shouldIgnoreCase) throw();
|
|
|
|
/** Returns a descriptive string containing the items.
|
|
|
|
This is handy for dumping the contents of an array.
|
|
*/
|
|
const String getDescription() const;
|
|
|
|
/** Reduces the amount of storage being used by the array.
|
|
|
|
Arrays typically allocate slightly more storage than they need, and after
|
|
removing elements, they may have quite a lot of unused space allocated.
|
|
This method will reduce the amount of allocated storage to a minimum.
|
|
*/
|
|
void minimiseStorageOverheads() throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
StringArray keys, values;
|
|
bool ignoreCase;
|
|
};
|
|
|
|
#endif // __JUCE_STRINGPAIRARRAY_JUCEHEADER__
|
|
/********* End of inlined file: juce_StringPairArray.h *********/
|
|
|
|
/********* Start of inlined file: juce_XmlElement.h *********/
|
|
#ifndef __JUCE_XMLELEMENT_JUCEHEADER__
|
|
#define __JUCE_XMLELEMENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_OutputStream.h *********/
|
|
#ifndef __JUCE_OUTPUTSTREAM_JUCEHEADER__
|
|
#define __JUCE_OUTPUTSTREAM_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_InputStream.h *********/
|
|
#ifndef __JUCE_INPUTSTREAM_JUCEHEADER__
|
|
#define __JUCE_INPUTSTREAM_JUCEHEADER__
|
|
|
|
/** The base class for streams that read data.
|
|
|
|
Input and output streams are used throughout the library - subclasses can override
|
|
some or all of the virtual functions to implement their behaviour.
|
|
|
|
@see OutputStream, MemoryInputStream, BufferedInputStream, FileInputStream
|
|
*/
|
|
class JUCE_API InputStream
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~InputStream() {}
|
|
|
|
/** Returns the total number of bytes available for reading in this stream.
|
|
|
|
Note that this is the number of bytes available from the start of the
|
|
stream, not from the current position.
|
|
|
|
If the size of the stream isn't actually known, this may return -1.
|
|
*/
|
|
virtual int64 getTotalLength() = 0;
|
|
|
|
/** Returns true if the stream has no more data to read. */
|
|
virtual bool isExhausted() = 0;
|
|
|
|
/** Reads a set of bytes from the stream into a memory buffer.
|
|
|
|
This is the only read method that subclasses actually need to implement, as the
|
|
InputStream base class implements the other read methods in terms of this one (although
|
|
it's often more efficient for subclasses to implement them directly).
|
|
|
|
@param destBuffer the destination buffer for the data
|
|
@param maxBytesToRead the maximum number of bytes to read - make sure the
|
|
memory block passed in is big enough to contain this
|
|
many bytes.
|
|
|
|
@returns the actual number of bytes that were read, which may be less than
|
|
maxBytesToRead if the stream is exhausted before it gets that far
|
|
*/
|
|
virtual int read (void* destBuffer,
|
|
int maxBytesToRead) = 0;
|
|
|
|
/** Reads a byte from the stream.
|
|
|
|
If the stream is exhausted, this will return zero.
|
|
|
|
@see OutputStream::writeByte
|
|
*/
|
|
virtual char readByte();
|
|
|
|
/** Reads a boolean from the stream.
|
|
|
|
The bool is encoded as a single byte - 1 for true, 0 for false.
|
|
|
|
If the stream is exhausted, this will return false.
|
|
|
|
@see OutputStream::writeBool
|
|
*/
|
|
virtual bool readBool();
|
|
|
|
/** Reads two bytes from the stream as a little-endian 16-bit value.
|
|
|
|
If the next two bytes read are byte1 and byte2, this returns
|
|
(byte1 | (byte2 << 8)).
|
|
|
|
If the stream is exhausted partway through reading the bytes, this will return zero.
|
|
|
|
@see OutputStream::writeShort, readShortBigEndian
|
|
*/
|
|
virtual short readShort();
|
|
|
|
/** Reads two bytes from the stream as a little-endian 16-bit value.
|
|
|
|
If the next two bytes read are byte1 and byte2, this returns
|
|
(byte2 | (byte1 << 8)).
|
|
|
|
If the stream is exhausted partway through reading the bytes, this will return zero.
|
|
|
|
@see OutputStream::writeShortBigEndian, readShort
|
|
*/
|
|
virtual short readShortBigEndian();
|
|
|
|
/** Reads four bytes from the stream as a little-endian 32-bit value.
|
|
|
|
If the next four bytes are byte1 to byte4, this returns
|
|
(byte1 | (byte2 << 8) | (byte3 << 16) | (byte4 << 24)).
|
|
|
|
If the stream is exhausted partway through reading the bytes, this will return zero.
|
|
|
|
@see OutputStream::writeInt, readIntBigEndian
|
|
*/
|
|
virtual int readInt();
|
|
|
|
/** Reads four bytes from the stream as a big-endian 32-bit value.
|
|
|
|
If the next four bytes are byte1 to byte4, this returns
|
|
(byte4 | (byte3 << 8) | (byte2 << 16) | (byte1 << 24)).
|
|
|
|
If the stream is exhausted partway through reading the bytes, this will return zero.
|
|
|
|
@see OutputStream::writeIntBigEndian, readInt
|
|
*/
|
|
virtual int readIntBigEndian();
|
|
|
|
/** Reads eight bytes from the stream as a little-endian 64-bit value.
|
|
|
|
If the next eight bytes are byte1 to byte8, this returns
|
|
(byte1 | (byte2 << 8) | (byte3 << 16) | (byte4 << 24) | (byte5 << 32) | (byte6 << 40) | (byte7 << 48) | (byte8 << 56)).
|
|
|
|
If the stream is exhausted partway through reading the bytes, this will return zero.
|
|
|
|
@see OutputStream::writeInt64, readInt64BigEndian
|
|
*/
|
|
virtual int64 readInt64();
|
|
|
|
/** Reads eight bytes from the stream as a big-endian 64-bit value.
|
|
|
|
If the next eight bytes are byte1 to byte8, this returns
|
|
(byte8 | (byte7 << 8) | (byte6 << 16) | (byte5 << 24) | (byte4 << 32) | (byte3 << 40) | (byte2 << 48) | (byte1 << 56)).
|
|
|
|
If the stream is exhausted partway through reading the bytes, this will return zero.
|
|
|
|
@see OutputStream::writeInt64BigEndian, readInt64
|
|
*/
|
|
virtual int64 readInt64BigEndian();
|
|
|
|
/** Reads four bytes as a 32-bit floating point value.
|
|
|
|
The raw 32-bit encoding of the float is read from the stream as a little-endian int.
|
|
|
|
If the stream is exhausted partway through reading the bytes, this will return zero.
|
|
|
|
@see OutputStream::writeFloat, readDouble
|
|
*/
|
|
virtual float readFloat();
|
|
|
|
/** Reads four bytes as a 32-bit floating point value.
|
|
|
|
The raw 32-bit encoding of the float is read from the stream as a big-endian int.
|
|
|
|
If the stream is exhausted partway through reading the bytes, this will return zero.
|
|
|
|
@see OutputStream::writeFloatBigEndian, readDoubleBigEndian
|
|
*/
|
|
virtual float readFloatBigEndian();
|
|
|
|
/** Reads eight bytes as a 64-bit floating point value.
|
|
|
|
The raw 64-bit encoding of the double is read from the stream as a little-endian int64.
|
|
|
|
If the stream is exhausted partway through reading the bytes, this will return zero.
|
|
|
|
@see OutputStream::writeDouble, readFloat
|
|
*/
|
|
virtual double readDouble();
|
|
|
|
/** Reads eight bytes as a 64-bit floating point value.
|
|
|
|
The raw 64-bit encoding of the double is read from the stream as a big-endian int64.
|
|
|
|
If the stream is exhausted partway through reading the bytes, this will return zero.
|
|
|
|
@see OutputStream::writeDoubleBigEndian, readFloatBigEndian
|
|
*/
|
|
virtual double readDoubleBigEndian();
|
|
|
|
/** Reads an encoded 32-bit number from the stream using a space-saving compressed format.
|
|
|
|
For small values, this is more space-efficient than using readInt() and OutputStream::writeInt()
|
|
|
|
The format used is: number of significant bytes + up to 4 bytes in little-endian order.
|
|
|
|
@see OutputStream::writeCompressedInt()
|
|
*/
|
|
virtual int readCompressedInt();
|
|
|
|
/** Reads a string from the stream, up to the next linefeed or carriage return.
|
|
|
|
The stream is treated as 8-bit characters encoded with the system's default encoding,
|
|
and this will read up to the next "\n" or "\r\n" or end-of-stream.
|
|
|
|
After this call, the stream's position will be left pointing to the character
|
|
following the line-feed, but the linefeeds aren't included in the string that
|
|
is returned.
|
|
*/
|
|
virtual const String readNextLine();
|
|
|
|
/** Reads a zero-terminated string from the stream.
|
|
|
|
This will read characters from the stream until it hits a zero character or
|
|
end-of-stream.
|
|
|
|
@see OutputStream::writeString, readEntireStreamAsString
|
|
*/
|
|
virtual const String readString();
|
|
|
|
/** Tries to read the whole stream and turn it into a string.
|
|
|
|
This will read from the stream's current position until the end-of-stream, and
|
|
will try to make an educated guess about whether it's unicode or an 8-bit encoding.
|
|
*/
|
|
virtual const String readEntireStreamAsString();
|
|
|
|
/** Reads from the stream and appends the data to a MemoryBlock.
|
|
|
|
@param destBlock the block to append the data onto
|
|
@param maxNumBytesToRead if this is a positive value, it sets a limit to the number
|
|
of bytes that will be read - if it's negative, data
|
|
will be read until the stream is exhausted.
|
|
@returns the number of bytes that were added to the memory block
|
|
*/
|
|
virtual int readIntoMemoryBlock (MemoryBlock& destBlock,
|
|
int maxNumBytesToRead = -1);
|
|
|
|
/** Returns the offset of the next byte that will be read from the stream.
|
|
|
|
@see setPosition
|
|
*/
|
|
virtual int64 getPosition() = 0;
|
|
|
|
/** Tries to move the current read position of the stream.
|
|
|
|
The position is an absolute number of bytes from the stream's start.
|
|
|
|
Some streams might not be able to do this, in which case they should do
|
|
nothing and return false. Others might be able to manage it by resetting
|
|
themselves and skipping to the correct position, although this is
|
|
obviously a bit slow.
|
|
|
|
@returns true if the stream manages to reposition itself correctly
|
|
@see getPosition
|
|
*/
|
|
virtual bool setPosition (int64 newPosition) = 0;
|
|
|
|
/** Reads and discards a number of bytes from the stream.
|
|
|
|
Some input streams might implement this efficiently, but the base
|
|
class will just keep reading data until the requisite number of bytes
|
|
have been done.
|
|
*/
|
|
virtual void skipNextBytes (int64 numBytesToSkip);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
InputStream() throw() {}
|
|
};
|
|
|
|
#endif // __JUCE_INPUTSTREAM_JUCEHEADER__
|
|
/********* End of inlined file: juce_InputStream.h *********/
|
|
|
|
/**
|
|
The base class for streams that write data to some kind of destination.
|
|
|
|
Input and output streams are used throughout the library - subclasses can override
|
|
some or all of the virtual functions to implement their behaviour.
|
|
|
|
@see InputStream, MemoryOutputStream, FileOutputStream
|
|
*/
|
|
class JUCE_API OutputStream
|
|
{
|
|
public:
|
|
/** Destructor.
|
|
|
|
Some subclasses might want to do things like call flush() during their
|
|
destructors.
|
|
*/
|
|
virtual ~OutputStream();
|
|
|
|
/** If the stream is using a buffer, this will ensure it gets written
|
|
out to the destination. */
|
|
virtual void flush() = 0;
|
|
|
|
/** Tries to move the stream's output position.
|
|
|
|
Not all streams will be able to seek to a new position - this will return
|
|
false if it fails to work.
|
|
|
|
@see getPosition
|
|
*/
|
|
virtual bool setPosition (int64 newPosition) = 0;
|
|
|
|
/** Returns the stream's current position.
|
|
|
|
@see setPosition
|
|
*/
|
|
virtual int64 getPosition() = 0;
|
|
|
|
/** Writes a block of data to the stream.
|
|
|
|
When creating a subclass of OutputStream, this is the only write method
|
|
that needs to be overloaded - the base class has methods for writing other
|
|
types of data which use this to do the work.
|
|
|
|
@returns false if the write operation fails for some reason
|
|
*/
|
|
virtual bool write (const void* dataToWrite,
|
|
int howManyBytes) = 0;
|
|
|
|
/** Writes a single byte to the stream.
|
|
|
|
@see InputStream::readByte
|
|
*/
|
|
virtual void writeByte (char byte);
|
|
|
|
/** Writes a boolean to the stream.
|
|
|
|
This is encoded as a byte - either 1 or 0.
|
|
|
|
@see InputStream::readBool
|
|
*/
|
|
virtual void writeBool (bool boolValue);
|
|
|
|
/** Writes a 16-bit integer to the stream in a little-endian byte order.
|
|
|
|
This will write two bytes to the stream: (value & 0xff), then (value >> 8).
|
|
|
|
@see InputStream::readShort
|
|
*/
|
|
virtual void writeShort (short value);
|
|
|
|
/** Writes a 16-bit integer to the stream in a big-endian byte order.
|
|
|
|
This will write two bytes to the stream: (value >> 8), then (value & 0xff).
|
|
|
|
@see InputStream::readShortBigEndian
|
|
*/
|
|
virtual void writeShortBigEndian (short value);
|
|
|
|
/** Writes a 32-bit integer to the stream in a little-endian byte order.
|
|
|
|
@see InputStream::readInt
|
|
*/
|
|
virtual void writeInt (int value);
|
|
|
|
/** Writes a 32-bit integer to the stream in a big-endian byte order.
|
|
|
|
@see InputStream::readIntBigEndian
|
|
*/
|
|
virtual void writeIntBigEndian (int value);
|
|
|
|
/** Writes a 64-bit integer to the stream in a little-endian byte order.
|
|
|
|
@see InputStream::readInt64
|
|
*/
|
|
virtual void writeInt64 (int64 value);
|
|
|
|
/** Writes a 64-bit integer to the stream in a big-endian byte order.
|
|
|
|
@see InputStream::readInt64BigEndian
|
|
*/
|
|
virtual void writeInt64BigEndian (int64 value);
|
|
|
|
/** Writes a 32-bit floating point value to the stream.
|
|
|
|
The binary 32-bit encoding of the float is written as a little-endian int.
|
|
|
|
@see InputStream::readFloat
|
|
*/
|
|
virtual void writeFloat (float value);
|
|
|
|
/** Writes a 32-bit floating point value to the stream.
|
|
|
|
The binary 32-bit encoding of the float is written as a big-endian int.
|
|
|
|
@see InputStream::readFloatBigEndian
|
|
*/
|
|
virtual void writeFloatBigEndian (float value);
|
|
|
|
/** Writes a 64-bit floating point value to the stream.
|
|
|
|
The eight raw bytes of the double value are written out as a little-endian 64-bit int.
|
|
|
|
@see InputStream::readDouble
|
|
*/
|
|
virtual void writeDouble (double value);
|
|
|
|
/** Writes a 64-bit floating point value to the stream.
|
|
|
|
The eight raw bytes of the double value are written out as a big-endian 64-bit int.
|
|
|
|
@see InputStream::readDoubleBigEndian
|
|
*/
|
|
virtual void writeDoubleBigEndian (double value);
|
|
|
|
/** Writes a condensed encoding of a 32-bit integer.
|
|
|
|
If you're storing a lot of integers which are unlikely to have very large values,
|
|
this can save a lot of space, because values under 0xff will only take up 2 bytes,
|
|
under 0xffff only 3 bytes, etc.
|
|
|
|
The format used is: number of significant bytes + up to 4 bytes in little-endian order.
|
|
|
|
@see InputStream::readCompressedInt
|
|
*/
|
|
virtual void writeCompressedInt (int value);
|
|
|
|
/** Stores a string in the stream.
|
|
|
|
This isn't the method to use if you're trying to append text to the end of a
|
|
text-file! It's intended for storing a string for later retrieval
|
|
by InputStream::readString.
|
|
|
|
For appending text to a file, instead use writeText, printf, or operator<<
|
|
|
|
@see InputStream::readString, writeText, printf, operator<<
|
|
*/
|
|
virtual void writeString (const String& text);
|
|
|
|
/** Writes a string of text to the stream.
|
|
|
|
It can either write it as 8-bit system-encoded characters, or as unicode, and
|
|
can also add unicode header bytes (0xff, 0xfe) to indicate the endianness (this
|
|
should only be done at the start of a file).
|
|
|
|
The method also replaces '\\n' characters in the text with '\\r\\n'.
|
|
*/
|
|
virtual void writeText (const String& text,
|
|
const bool asUnicode,
|
|
const bool writeUnicodeHeaderBytes);
|
|
|
|
/** Writes a string of text to the stream.
|
|
|
|
@see writeText
|
|
*/
|
|
virtual void printf (const char* format, ...);
|
|
|
|
/** Reads data from an input stream and writes it to this stream.
|
|
|
|
@param source the stream to read from
|
|
@param maxNumBytesToWrite the number of bytes to read from the stream (if this is
|
|
less than zero, it will keep reading until the input
|
|
is exhausted)
|
|
*/
|
|
virtual int writeFromInputStream (InputStream& source,
|
|
int maxNumBytesToWrite);
|
|
|
|
/** Writes a number to the stream as 8-bit characters in the default system encoding. */
|
|
virtual OutputStream& operator<< (const int number);
|
|
|
|
/** Writes a number to the stream as 8-bit characters in the default system encoding. */
|
|
virtual OutputStream& operator<< (const double number);
|
|
|
|
/** Writes a character to the stream. */
|
|
virtual OutputStream& operator<< (const char character);
|
|
|
|
/** Writes a null-terminated string to the stream. */
|
|
virtual OutputStream& operator<< (const char* const text);
|
|
|
|
/** Writes a null-terminated unicode text string to the stream, converting it
|
|
to 8-bit characters in the default system encoding. */
|
|
virtual OutputStream& operator<< (const juce_wchar* const text);
|
|
|
|
/** Writes a string to the stream as 8-bit characters in the default system encoding. */
|
|
virtual OutputStream& operator<< (const String& text);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
OutputStream() throw();
|
|
};
|
|
|
|
#endif // __JUCE_OUTPUTSTREAM_JUCEHEADER__
|
|
/********* End of inlined file: juce_OutputStream.h *********/
|
|
|
|
/** A handy macro to make it easy to iterate all the child elements in an XmlElement.
|
|
|
|
The parentXmlElement should be a reference to the parent XML, and the childElementVariableName
|
|
will be the name of a pointer to each child element.
|
|
|
|
E.g. @code
|
|
XmlElement* myParentXml = createSomeKindOfXmlDocument();
|
|
|
|
forEachXmlChildElement (*myParentXml, child)
|
|
{
|
|
if (child->hasTagName ("FOO"))
|
|
doSomethingWithXmlElement (child);
|
|
}
|
|
|
|
@endcode
|
|
|
|
@see forEachXmlChildElementWithTagName
|
|
*/
|
|
#define forEachXmlChildElement(parentXmlElement, childElementVariableName) \
|
|
\
|
|
for (XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \
|
|
childElementVariableName != 0; \
|
|
childElementVariableName = childElementVariableName->getNextElement())
|
|
|
|
/** A macro that makes it easy to iterate all the child elements of an XmlElement
|
|
which have a specified tag.
|
|
|
|
This does the same job as the forEachXmlChildElement macro, but only for those
|
|
elements that have a particular tag name.
|
|
|
|
The parentXmlElement should be a reference to the parent XML, and the childElementVariableName
|
|
will be the name of a pointer to each child element. The requiredTagName is the
|
|
tag name to match.
|
|
|
|
E.g. @code
|
|
XmlElement* myParentXml = createSomeKindOfXmlDocument();
|
|
|
|
forEachXmlChildElementWithTagName (*myParentXml, child, T("MYTAG"))
|
|
{
|
|
// the child object is now guaranteed to be a <MYTAG> element..
|
|
doSomethingWithMYTAGElement (child);
|
|
}
|
|
|
|
@endcode
|
|
|
|
@see forEachXmlChildElement
|
|
*/
|
|
#define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \
|
|
\
|
|
for (XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \
|
|
childElementVariableName != 0; \
|
|
childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName))
|
|
|
|
/** Used to build a tree of elements representing an XML document.
|
|
|
|
An XML document can be parsed into a tree of XmlElements, each of which
|
|
represents an XML tag structure, and which may itself contain other
|
|
nested elements.
|
|
|
|
An XmlElement can also be converted back into a text document, and has
|
|
lots of useful methods for manipulating its attributes and sub-elements,
|
|
so XmlElements can actually be used as a handy general-purpose data
|
|
structure.
|
|
|
|
Here's an example of parsing some elements: @code
|
|
// check we're looking at the right kind of document..
|
|
if (myElement->hasTagName ("ANIMALS"))
|
|
{
|
|
// now we'll iterate its sub-elements looking for 'giraffe' elements..
|
|
forEachXmlChildElement (*myElement, e)
|
|
{
|
|
if (e->hasTagName ("GIRAFFE"))
|
|
{
|
|
// found a giraffe, so use some of its attributes..
|
|
|
|
String giraffeName = e->getStringAttribute ("name");
|
|
int giraffeAge = e->getIntAttribute ("age");
|
|
bool isFriendly = e->getBoolAttribute ("friendly");
|
|
}
|
|
}
|
|
}
|
|
@endcode
|
|
|
|
And here's an example of how to create an XML document from scratch: @code
|
|
// create an outer node called "ANIMALS"
|
|
XmlElement animalsList ("ANIMALS");
|
|
|
|
for (int i = 0; i < numAnimals; ++i)
|
|
{
|
|
// create an inner element..
|
|
XmlElement* giraffe = new XmlElement ("GIRAFFE");
|
|
|
|
giraffe->setAttribute ("name", "nigel");
|
|
giraffe->setAttribute ("age", 10);
|
|
giraffe->setAttribute ("friendly", true);
|
|
|
|
// ..and add our new element to the parent node
|
|
animalsList.addChildElement (giraffe);
|
|
}
|
|
|
|
// now we can turn the whole thing into a text document..
|
|
String myXmlDoc = animalsList.createDocument (String::empty);
|
|
@endcode
|
|
|
|
@see XmlDocument
|
|
*/
|
|
class JUCE_API XmlElement
|
|
{
|
|
public:
|
|
|
|
/** Creates an XmlElement with this tag name. */
|
|
XmlElement (const String& tagName) throw();
|
|
|
|
/** Creates a (deep) copy of another element. */
|
|
XmlElement (const XmlElement& other) throw();
|
|
|
|
/** Creates a (deep) copy of another element. */
|
|
const XmlElement& operator= (const XmlElement& other) throw();
|
|
|
|
/** Deleting an XmlElement will also delete all its child elements. */
|
|
~XmlElement() throw();
|
|
|
|
/** Compares two XmlElements to see if they contain the same text and attiributes.
|
|
|
|
The elements are only considered equivalent if they contain the same attiributes
|
|
with the same values, and have the same sub-nodes.
|
|
|
|
@param other the other element to compare to
|
|
@param ignoreOrderOfAttributes if true, this means that two elements with the
|
|
same attributes in a different order will be
|
|
considered the same; if false, the attributes must
|
|
be in the same order as well
|
|
*/
|
|
bool isEquivalentTo (const XmlElement* const other,
|
|
const bool ignoreOrderOfAttributes) const throw();
|
|
|
|
/** Returns an XML text document that represents this element.
|
|
|
|
The string returned can be parsed to recreate the same XmlElement that
|
|
was used to create it.
|
|
|
|
@param dtdToUse the DTD to add to the document
|
|
@param allOnOneLine if true, this means that the document will not contain any
|
|
linefeeds, so it'll be smaller but not very easy to read.
|
|
@param includeXmlHeader whether to add the "<?xml version..etc" line at the start of the
|
|
document
|
|
@param encodingType the character encoding format string to put into the xml
|
|
header
|
|
@param lineWrapLength the line length that will be used before items get placed on
|
|
a new line. This isn't an absolute maximum length, it just
|
|
determines how lists of attributes get broken up
|
|
@see writeToFile
|
|
*/
|
|
const String createDocument (const String& dtdToUse,
|
|
const bool allOnOneLine = false,
|
|
const bool includeXmlHeader = true,
|
|
const tchar* const encodingType = JUCE_T("UTF-8"),
|
|
const int lineWrapLength = 60) const throw();
|
|
|
|
/** Writes the element to a file as an XML document.
|
|
|
|
To improve safety in case something goes wrong while writing the file, this
|
|
will actually write the document to a new temporary file in the same
|
|
directory as the destination file, and if this succeeds, it will rename this
|
|
new file as the destination file (overwriting any existing file that was there).
|
|
|
|
@param destinationFile the file to write to. If this already exists, it will be
|
|
overwritten.
|
|
@param dtdToUse the DTD to add to the document
|
|
@param encodingType the character encoding format string to put into the xml
|
|
header
|
|
@param lineWrapLength the line length that will be used before items get placed on
|
|
a new line. This isn't an absolute maximum length, it just
|
|
determines how lists of attributes get broken up
|
|
@returns true if the file is written successfully; false if something goes wrong
|
|
in the process
|
|
@see createDocument
|
|
*/
|
|
bool writeToFile (const File& destinationFile,
|
|
const String& dtdToUse,
|
|
const tchar* const encodingType = JUCE_T("UTF-8"),
|
|
const int lineWrapLength = 60) const throw();
|
|
|
|
/** Returns this element's tag type name.
|
|
|
|
E.g. for an element such as \<MOOSE legs="4" antlers="2">, this would return
|
|
"MOOSE".
|
|
|
|
@see hasTagName
|
|
*/
|
|
inline const String& getTagName() const throw() { return tagName; }
|
|
|
|
/** Tests whether this element has a particular tag name.
|
|
|
|
@param possibleTagName the tag name you're comparing it with
|
|
|
|
@see getTagName
|
|
*/
|
|
bool hasTagName (const tchar* const possibleTagName) const throw();
|
|
|
|
/** Returns the number of XML attributes this element contains.
|
|
|
|
E.g. for an element such as \<MOOSE legs="4" antlers="2">, this would
|
|
return 2.
|
|
*/
|
|
int getNumAttributes() const throw();
|
|
|
|
/** Returns the name of one of the elements attributes.
|
|
|
|
E.g. for an element such as \<MOOSE legs="4" antlers="2">, then
|
|
getAttributeName(1) would return "antlers".
|
|
|
|
@see getAttributeValue, getStringAttribute
|
|
*/
|
|
const String& getAttributeName (const int attributeIndex) const throw();
|
|
|
|
/** Returns the value of one of the elements attributes.
|
|
|
|
E.g. for an element such as \<MOOSE legs="4" antlers="2">, then
|
|
getAttributeName(1) would return "2".
|
|
|
|
@see getAttributeName, getStringAttribute
|
|
*/
|
|
const String& getAttributeValue (const int attributeIndex) const throw();
|
|
|
|
// Attribute-handling methods..
|
|
|
|
/** Checks whether the element contains an attribute with a certain name. */
|
|
bool hasAttribute (const tchar* const attributeName) const throw();
|
|
|
|
/** Returns the value of a named attribute.
|
|
|
|
@param attributeName the name of the attribute to look up
|
|
@param defaultReturnValue a value to return if the element doesn't have an attribute
|
|
with this name
|
|
*/
|
|
const String getStringAttribute (const tchar* const attributeName,
|
|
const tchar* const defaultReturnValue = 0) const throw();
|
|
|
|
/** Compares the value of a named attribute with a value passed-in.
|
|
|
|
@param attributeName the name of the attribute to look up
|
|
@param stringToCompareAgainst the value to compare it with
|
|
@param ignoreCase whether the comparison should be case-insensitive
|
|
@returns true if the value of the attribute is the same as the string passed-in;
|
|
false if it's different (or if no such attribute exists)
|
|
*/
|
|
bool compareAttribute (const tchar* const attributeName,
|
|
const tchar* const stringToCompareAgainst,
|
|
const bool ignoreCase = false) const throw();
|
|
|
|
/** Returns the value of a named attribute as an integer.
|
|
|
|
This will try to find the attribute and convert it to an integer (using
|
|
the String::getIntValue() method).
|
|
|
|
@param attributeName the name of the attribute to look up
|
|
@param defaultReturnValue a value to return if the element doesn't have an attribute
|
|
with this name
|
|
@see setAttribute (const tchar* const, int)
|
|
*/
|
|
int getIntAttribute (const tchar* const attributeName,
|
|
const int defaultReturnValue = 0) const throw();
|
|
|
|
/** Returns the value of a named attribute as floating-point.
|
|
|
|
This will try to find the attribute and convert it to an integer (using
|
|
the String::getDoubleValue() method).
|
|
|
|
@param attributeName the name of the attribute to look up
|
|
@param defaultReturnValue a value to return if the element doesn't have an attribute
|
|
with this name
|
|
@see setAttribute (const tchar* const, double)
|
|
*/
|
|
double getDoubleAttribute (const tchar* const attributeName,
|
|
const double defaultReturnValue = 0.0) const throw();
|
|
|
|
/** Returns the value of a named attribute as a boolean.
|
|
|
|
This will try to find the attribute and interpret it as a boolean. To do this,
|
|
it'll return true if the value is "1", "true", "y", etc, or false for other
|
|
values.
|
|
|
|
@param attributeName the name of the attribute to look up
|
|
@param defaultReturnValue a value to return if the element doesn't have an attribute
|
|
with this name
|
|
*/
|
|
bool getBoolAttribute (const tchar* const attributeName,
|
|
const bool defaultReturnValue = false) const throw();
|
|
|
|
/** Adds a named attribute to the element.
|
|
|
|
If the element already contains an attribute with this name, it's value will
|
|
be updated to the new value. If there's no such attribute yet, a new one will
|
|
be added.
|
|
|
|
Note that there are other setAttribute() methods that take integers,
|
|
doubles, etc. to make it easy to store numbers.
|
|
|
|
@param attributeName the name of the attribute to set
|
|
@param newValue the value to set it to
|
|
@see removeAttribute
|
|
*/
|
|
void setAttribute (const tchar* const attributeName,
|
|
const String& newValue) throw();
|
|
|
|
/** Adds a named attribute to the element.
|
|
|
|
If the element already contains an attribute with this name, it's value will
|
|
be updated to the new value. If there's no such attribute yet, a new one will
|
|
be added.
|
|
|
|
Note that there are other setAttribute() methods that take integers,
|
|
doubles, etc. to make it easy to store numbers.
|
|
|
|
@param attributeName the name of the attribute to set
|
|
@param newValue the value to set it to
|
|
*/
|
|
void setAttribute (const tchar* const attributeName,
|
|
const tchar* const newValue) throw();
|
|
|
|
/** Adds a named attribute to the element, setting it to an integer value.
|
|
|
|
If the element already contains an attribute with this name, it's value will
|
|
be updated to the new value. If there's no such attribute yet, a new one will
|
|
be added.
|
|
|
|
Note that there are other setAttribute() methods that take integers,
|
|
doubles, etc. to make it easy to store numbers.
|
|
|
|
@param attributeName the name of the attribute to set
|
|
@param newValue the value to set it to
|
|
*/
|
|
void setAttribute (const tchar* const attributeName,
|
|
const int newValue) throw();
|
|
|
|
/** Adds a named attribute to the element, setting it to a floating-point value.
|
|
|
|
If the element already contains an attribute with this name, it's value will
|
|
be updated to the new value. If there's no such attribute yet, a new one will
|
|
be added.
|
|
|
|
Note that there are other setAttribute() methods that take integers,
|
|
doubles, etc. to make it easy to store numbers.
|
|
|
|
@param attributeName the name of the attribute to set
|
|
@param newValue the value to set it to
|
|
*/
|
|
void setAttribute (const tchar* const attributeName,
|
|
const double newValue) throw();
|
|
|
|
/** Removes a named attribute from the element.
|
|
|
|
@param attributeName the name of the attribute to remove
|
|
@see removeAllAttributes
|
|
*/
|
|
void removeAttribute (const tchar* const attributeName) throw();
|
|
|
|
/** Removes all attributes from this element.
|
|
*/
|
|
void removeAllAttributes() throw();
|
|
|
|
// Child element methods..
|
|
|
|
/** Returns the first of this element's sub-elements.
|
|
|
|
see getNextElement() for an example of how to iterate the sub-elements.
|
|
|
|
@see forEachXmlChildElement
|
|
*/
|
|
XmlElement* getFirstChildElement() const throw() { return firstChildElement; }
|
|
|
|
/** Returns the next of this element's siblings.
|
|
|
|
This can be used for iterating an element's sub-elements, e.g.
|
|
@code
|
|
XmlElement* child = myXmlDocument->getFirstChildElement();
|
|
|
|
while (child != 0)
|
|
{
|
|
...do stuff with this child..
|
|
|
|
child = child->getNextElement();
|
|
}
|
|
@endcode
|
|
|
|
Note that when iterating the child elements, some of them might be
|
|
text elements as well as XML tags - use isTextElement() to work this
|
|
out.
|
|
|
|
Also, it's much easier and neater to use this method indirectly via the
|
|
forEachXmlChildElement macro.
|
|
|
|
@returns the sibling element that follows this one, or zero if this is the last
|
|
element in its parent
|
|
|
|
@see getNextElement, isTextElement, forEachXmlChildElement
|
|
*/
|
|
inline XmlElement* getNextElement() const throw() { return nextElement; }
|
|
|
|
/** Returns the next of this element's siblings which has the specified tag
|
|
name.
|
|
|
|
This is like getNextElement(), but will scan through the list until it
|
|
finds an element with the given tag name.
|
|
|
|
@see getNextElement, forEachXmlChildElementWithTagName
|
|
*/
|
|
XmlElement* getNextElementWithTagName (const tchar* const requiredTagName) const;
|
|
|
|
/** Returns the number of sub-elements in this element.
|
|
|
|
@see getChildElement
|
|
*/
|
|
int getNumChildElements() const throw();
|
|
|
|
/** Returns the sub-element at a certain index.
|
|
|
|
It's not very efficient to iterate the sub-elements by index - see
|
|
getNextElement() for an example of how best to iterate.
|
|
|
|
@returns the n'th child of this element, or 0 if the index is out-of-range
|
|
@see getNextElement, isTextElement, getChildByName
|
|
*/
|
|
XmlElement* getChildElement (const int index) const throw();
|
|
|
|
/** Returns the first sub-element with a given tag-name.
|
|
|
|
@param tagNameToLookFor the tag name of the element you want to find
|
|
@returns the first element with this tag name, or 0 if none is found
|
|
@see getNextElement, isTextElement, getChildElement
|
|
*/
|
|
XmlElement* getChildByName (const tchar* const tagNameToLookFor) const throw();
|
|
|
|
/** Appends an element to this element's list of children.
|
|
|
|
Child elements are deleted automatically when their parent is deleted, so
|
|
make sure the object that you pass in will not be deleted by anything else,
|
|
and make sure it's not already the child of another element.
|
|
|
|
@see getFirstChildElement, getNextElement, getNumChildElements,
|
|
getChildElement, removeChildElement
|
|
*/
|
|
void addChildElement (XmlElement* const newChildElement) throw();
|
|
|
|
/** Inserts an element into this element's list of children.
|
|
|
|
Child elements are deleted automatically when their parent is deleted, so
|
|
make sure the object that you pass in will not be deleted by anything else,
|
|
and make sure it's not already the child of another element.
|
|
|
|
@param newChildNode the element to add
|
|
@param indexToInsertAt the index at which to insert the new element - if this is
|
|
below zero, it will be added to the end of the list
|
|
@see addChildElement, insertChildElement
|
|
*/
|
|
void insertChildElement (XmlElement* const newChildNode,
|
|
int indexToInsertAt) throw();
|
|
|
|
/** Replaces one of this element's children with another node.
|
|
|
|
If the current element passed-in isn't actually a child of this element,
|
|
this will return false and the new one won't be added. Otherwise, the
|
|
existing element will be deleted, replaced with the new one, and it
|
|
will return true.
|
|
*/
|
|
bool replaceChildElement (XmlElement* const currentChildElement,
|
|
XmlElement* const newChildNode) throw();
|
|
|
|
/** Removes a child element.
|
|
|
|
@param childToRemove the child to look for and remove
|
|
@param shouldDeleteTheChild if true, the child will be deleted, if false it'll
|
|
just remove it
|
|
*/
|
|
void removeChildElement (XmlElement* const childToRemove,
|
|
const bool shouldDeleteTheChild) throw();
|
|
|
|
/** Deletes all the child elements in the element.
|
|
|
|
@see removeChildElement, deleteAllChildElementsWithTagName
|
|
*/
|
|
void deleteAllChildElements() throw();
|
|
|
|
/** Deletes all the child elements with a given tag name.
|
|
|
|
@see removeChildElement
|
|
*/
|
|
void deleteAllChildElementsWithTagName (const tchar* const tagName) throw();
|
|
|
|
/** Returns true if the given element is a child of this one. */
|
|
bool containsChildElement (const XmlElement* const possibleChild) const throw();
|
|
|
|
/** Recursively searches all sub-elements to find one that contains the specified
|
|
child element.
|
|
*/
|
|
XmlElement* findParentElementOf (const XmlElement* const elementToLookFor) throw();
|
|
|
|
/** Sorts the child elements using a comparator.
|
|
|
|
This will use a comparator object to sort the elements into order. The object
|
|
passed must have a method of the form:
|
|
@code
|
|
int compareElements (const XmlElement* first, const XmlElement* second);
|
|
@endcode
|
|
|
|
..and this method must return:
|
|
- a value of < 0 if the first comes before the second
|
|
- a value of 0 if the two objects are equivalent
|
|
- a value of > 0 if the second comes before the first
|
|
|
|
To improve performance, the compareElements() method can be declared as static or const.
|
|
|
|
@param comparator the comparator to use for comparing elements.
|
|
@param retainOrderOfEquivalentItems if this is true, then items
|
|
which the comparator says are equivalent will be
|
|
kept in the order in which they currently appear
|
|
in the array. This is slower to perform, but may
|
|
be important in some cases. If it's false, a faster
|
|
algorithm is used, but equivalent elements may be
|
|
rearranged.
|
|
*/
|
|
template <class ElementComparator>
|
|
void sortChildElements (ElementComparator& comparator,
|
|
const bool retainOrderOfEquivalentItems = false) throw()
|
|
{
|
|
const int num = getNumChildElements();
|
|
|
|
if (num > 1)
|
|
{
|
|
XmlElement** const elems = getChildElementsAsArray (num);
|
|
sortArray (comparator, elems, 0, num - 1, retainOrderOfEquivalentItems);
|
|
reorderChildElements (elems, num);
|
|
delete[] elems;
|
|
}
|
|
}
|
|
|
|
/** Returns true if this element is a section of text.
|
|
|
|
Elements can either be an XML tag element or a secton of text, so this
|
|
is used to find out what kind of element this one is.
|
|
|
|
@see getAllText, addTextElement, deleteAllTextElements
|
|
*/
|
|
bool isTextElement() const throw();
|
|
|
|
/** Returns the text for a text element.
|
|
|
|
Note that if you have an element like this:
|
|
|
|
@code<xyz>hello</xyz>@endcode
|
|
|
|
then calling getText on the "xyz" element won't return "hello", because that is
|
|
actually stored in a special text sub-element inside the xyz element. To get the
|
|
"hello" string, you could either call getText on the (unnamed) sub-element, or
|
|
use getAllSubText() to do this automatically.
|
|
|
|
@see isTextElement, getAllSubText, getChildElementAllSubText
|
|
*/
|
|
const String getText() const throw();
|
|
|
|
/** Sets the text in a text element.
|
|
|
|
Note that this is only a valid call if this element is a text element. If it's
|
|
not, then no action will be performed.
|
|
*/
|
|
void setText (const String& newText) throw();
|
|
|
|
/** Returns all the text from this element's child nodes.
|
|
|
|
This iterates all the child elements and when it finds text elements,
|
|
it concatenates their text into a big string which it returns.
|
|
|
|
E.g. @code<xyz> hello <x></x> there </xyz>@endcode
|
|
if you called getAllSubText on the "xyz" element, it'd return "hello there".
|
|
|
|
@see isTextElement, getChildElementAllSubText, getText, addTextElement
|
|
*/
|
|
const String getAllSubText() const throw();
|
|
|
|
/** Returns all the sub-text of a named child element.
|
|
|
|
If there is a child element with the given tag name, this will return
|
|
all of its sub-text (by calling getAllSubText() on it). If there is
|
|
no such child element, this will return the default string passed-in.
|
|
|
|
@see getAllSubText
|
|
*/
|
|
const String getChildElementAllSubText (const tchar* const childTagName,
|
|
const String& defaultReturnValue) const throw();
|
|
|
|
/** Appends a section of text to this element.
|
|
|
|
@see isTextElement, getText, getAllSubText
|
|
*/
|
|
void addTextElement (const String& text) throw();
|
|
|
|
/** Removes all the text elements from this element.
|
|
|
|
@see isTextElement, getText, getAllSubText, addTextElement
|
|
*/
|
|
void deleteAllTextElements() throw();
|
|
|
|
/** Creates a text element that can be added to a parent element.
|
|
*/
|
|
static XmlElement* createTextElement (const String& text) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class XmlDocument;
|
|
|
|
String tagName;
|
|
XmlElement* firstChildElement;
|
|
XmlElement* nextElement;
|
|
|
|
struct XmlAttributeNode
|
|
{
|
|
XmlAttributeNode (const XmlAttributeNode& other) throw();
|
|
XmlAttributeNode (const String& name, const String& value) throw();
|
|
|
|
String name, value;
|
|
XmlAttributeNode* next;
|
|
};
|
|
|
|
XmlAttributeNode* attributes;
|
|
|
|
XmlElement (int) throw(); // for internal use
|
|
XmlElement (const tchar* const tagNameText, const int nameLen) throw();
|
|
|
|
void copyChildrenAndAttributesFrom (const XmlElement& other) throw();
|
|
|
|
void writeElementAsText (OutputStream& out,
|
|
const int indentationLevel,
|
|
const int lineWrapLength) const throw();
|
|
|
|
XmlElement** getChildElementsAsArray (const int) const throw();
|
|
void reorderChildElements (XmlElement** const, const int) throw();
|
|
};
|
|
|
|
#endif // __JUCE_XMLELEMENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_XmlElement.h *********/
|
|
|
|
/**
|
|
A set of named property values, which can be strings, integers, floating point, etc.
|
|
|
|
Effectively, this just wraps a StringPairArray in an interface that makes it easier
|
|
to load and save types other than strings.
|
|
|
|
See the PropertiesFile class for a subclass of this, which automatically broadcasts change
|
|
messages and saves/loads the list from a file.
|
|
*/
|
|
class JUCE_API PropertySet
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty PropertySet.
|
|
|
|
@param ignoreCaseOfKeyNames if true, the names of properties are compared in a
|
|
case-insensitive way
|
|
*/
|
|
PropertySet (const bool ignoreCaseOfKeyNames = false) throw();
|
|
|
|
/** Creates a copy of another PropertySet.
|
|
*/
|
|
PropertySet (const PropertySet& other) throw();
|
|
|
|
/** Copies another PropertySet over this one.
|
|
*/
|
|
const PropertySet& operator= (const PropertySet& other) throw();
|
|
|
|
/** Destructor. */
|
|
virtual ~PropertySet();
|
|
|
|
/** Returns one of the properties as a string.
|
|
|
|
If the value isn't found in this set, then this will look for it in a fallback
|
|
property set (if you've specified one with the setFallbackPropertySet() method),
|
|
and if it can't find one there, it'll return the default value passed-in.
|
|
|
|
@param keyName the name of the property to retrieve
|
|
@param defaultReturnValue a value to return if the named property doesn't actually exist
|
|
*/
|
|
const String getValue (const String& keyName,
|
|
const String& defaultReturnValue = String::empty) const throw();
|
|
|
|
/** Returns one of the properties as an integer.
|
|
|
|
If the value isn't found in this set, then this will look for it in a fallback
|
|
property set (if you've specified one with the setFallbackPropertySet() method),
|
|
and if it can't find one there, it'll return the default value passed-in.
|
|
|
|
@param keyName the name of the property to retrieve
|
|
@param defaultReturnValue a value to return if the named property doesn't actually exist
|
|
*/
|
|
int getIntValue (const String& keyName,
|
|
const int defaultReturnValue = 0) const throw();
|
|
|
|
/** Returns one of the properties as an double.
|
|
|
|
If the value isn't found in this set, then this will look for it in a fallback
|
|
property set (if you've specified one with the setFallbackPropertySet() method),
|
|
and if it can't find one there, it'll return the default value passed-in.
|
|
|
|
@param keyName the name of the property to retrieve
|
|
@param defaultReturnValue a value to return if the named property doesn't actually exist
|
|
*/
|
|
double getDoubleValue (const String& keyName,
|
|
const double defaultReturnValue = 0.0) const throw();
|
|
|
|
/** Returns one of the properties as an boolean.
|
|
|
|
The result will be true if the string found for this key name can be parsed as a non-zero
|
|
integer.
|
|
|
|
If the value isn't found in this set, then this will look for it in a fallback
|
|
property set (if you've specified one with the setFallbackPropertySet() method),
|
|
and if it can't find one there, it'll return the default value passed-in.
|
|
|
|
@param keyName the name of the property to retrieve
|
|
@param defaultReturnValue a value to return if the named property doesn't actually exist
|
|
*/
|
|
bool getBoolValue (const String& keyName,
|
|
const bool defaultReturnValue = false) const throw();
|
|
|
|
/** Returns one of the properties as an XML element.
|
|
|
|
The result will a new XMLElement object that the caller must delete. If may return 0 if the
|
|
key isn't found, or if the entry contains an string that isn't valid XML.
|
|
|
|
If the value isn't found in this set, then this will look for it in a fallback
|
|
property set (if you've specified one with the setFallbackPropertySet() method),
|
|
and if it can't find one there, it'll return the default value passed-in.
|
|
|
|
@param keyName the name of the property to retrieve
|
|
*/
|
|
XmlElement* getXmlValue (const String& keyName) const;
|
|
|
|
/** Sets a named property as a string.
|
|
|
|
@param keyName the name of the property to set. (This mustn't be an empty string)
|
|
@param value the new value to set it to
|
|
*/
|
|
void setValue (const String& keyName, const String& value) throw();
|
|
|
|
/** Sets a named property as a string.
|
|
|
|
@param keyName the name of the property to set. (This mustn't be an empty string)
|
|
@param value the new value to set it to
|
|
*/
|
|
void setValue (const String& keyName, const tchar* const value) throw();
|
|
|
|
/** Sets a named property to an integer.
|
|
|
|
@param keyName the name of the property to set. (This mustn't be an empty string)
|
|
@param value the new value to set it to
|
|
*/
|
|
void setValue (const String& keyName, const int value) throw();
|
|
|
|
/** Sets a named property to a double.
|
|
|
|
@param keyName the name of the property to set. (This mustn't be an empty string)
|
|
@param value the new value to set it to
|
|
*/
|
|
void setValue (const String& keyName, const double value) throw();
|
|
|
|
/** Sets a named property to a boolean.
|
|
|
|
@param keyName the name of the property to set. (This mustn't be an empty string)
|
|
@param value the new value to set it to
|
|
*/
|
|
void setValue (const String& keyName, const bool value) throw();
|
|
|
|
/** Sets a named property to an XML element.
|
|
|
|
@param keyName the name of the property to set. (This mustn't be an empty string)
|
|
@param xml the new element to set it to. If this is zero, the value will be set to
|
|
an empty string
|
|
@see getXmlValue
|
|
*/
|
|
void setValue (const String& keyName, const XmlElement* const xml);
|
|
|
|
/** Deletes a property.
|
|
|
|
@param keyName the name of the property to delete. (This mustn't be an empty string)
|
|
*/
|
|
void removeValue (const String& keyName) throw();
|
|
|
|
/** Returns true if the properies include the given key. */
|
|
bool containsKey (const String& keyName) const throw();
|
|
|
|
/** Removes all values. */
|
|
void clear();
|
|
|
|
/** Returns the keys/value pair array containing all the properties. */
|
|
StringPairArray& getAllProperties() throw() { return properties; }
|
|
|
|
/** Returns the lock used when reading or writing to this set */
|
|
const CriticalSection& getLock() const throw() { return lock; }
|
|
|
|
/** Returns an XML element which encapsulates all the items in this property set.
|
|
|
|
The string parameter is the tag name that should be used for the node.
|
|
|
|
@see restoreFromXml
|
|
*/
|
|
XmlElement* createXml (const String& nodeName) const throw();
|
|
|
|
/** Reloads a set of properties that were previously stored as XML.
|
|
|
|
The node passed in must have been created by the createXml() method.
|
|
|
|
@see createXml
|
|
*/
|
|
void restoreFromXml (const XmlElement& xml) throw();
|
|
|
|
/** Sets up a second PopertySet that will be used to look up any values that aren't
|
|
set in this one.
|
|
|
|
If you set this up to be a pointer to a second property set, then whenever one
|
|
of the getValue() methods fails to find an entry in this set, it will look up that
|
|
value in the fallback set, and if it finds it, it will return that.
|
|
|
|
Make sure that you don't delete the fallback set while it's still being used by
|
|
another set! To remove the fallback set, just call this method with a null pointer.
|
|
|
|
@see getFallbackPropertySet
|
|
*/
|
|
void setFallbackPropertySet (PropertySet* fallbackProperties) throw();
|
|
|
|
/** Returns the fallback property set.
|
|
@see setFallbackPropertySet
|
|
*/
|
|
PropertySet* getFallbackPropertySet() const throw() { return fallbackProperties; }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
/** Subclasses can override this to be told when one of the properies has been changed.
|
|
*/
|
|
virtual void propertyChanged();
|
|
|
|
private:
|
|
|
|
StringPairArray properties;
|
|
PropertySet* fallbackProperties;
|
|
CriticalSection lock;
|
|
bool ignoreCaseOfKeys;
|
|
};
|
|
|
|
#endif // __JUCE_PROPERTYSET_JUCEHEADER__
|
|
/********* End of inlined file: juce_PropertySet.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ReferenceCountedArray.h *********/
|
|
#ifndef __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__
|
|
#define __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ReferenceCountedObject.h *********/
|
|
#ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__
|
|
#define __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__
|
|
|
|
/**
|
|
Adds reference-counting to an object.
|
|
|
|
To add reference-counting to a class, derive it from this class, and
|
|
use the ReferenceCountedObjectPtr class to point to it.
|
|
|
|
e.g. @code
|
|
class MyClass : public ReferenceCountedObject
|
|
{
|
|
void foo();
|
|
|
|
// This is a neat way of declaring a typedef for a pointer class,
|
|
// rather than typing out the full templated name each time..
|
|
typedef ReferenceCountedObjectPtr<MyClass> Ptr;
|
|
};
|
|
|
|
MyClass::Ptr p = new MyClass();
|
|
MyClass::Ptr p2 = p;
|
|
p = 0;
|
|
p2->foo();
|
|
@endcode
|
|
|
|
Once a new ReferenceCountedObject has been assigned to a pointer, be
|
|
careful not to delete the object manually.
|
|
|
|
@see ReferenceCountedObjectPtr, ReferenceCountedArray
|
|
*/
|
|
class JUCE_API ReferenceCountedObject
|
|
{
|
|
public:
|
|
|
|
/** Increments the object's reference count.
|
|
|
|
This is done automatically by the smart pointer, but is public just
|
|
in case it's needed for nefarious purposes.
|
|
*/
|
|
inline void incReferenceCount() throw()
|
|
{
|
|
atomicIncrement (refCounts);
|
|
|
|
jassert (refCounts > 0);
|
|
}
|
|
|
|
/** Decreases the object's reference count.
|
|
|
|
If the count gets to zero, the object will be deleted.
|
|
*/
|
|
inline void decReferenceCount() throw()
|
|
{
|
|
jassert (refCounts > 0);
|
|
|
|
if (atomicDecrementAndReturn (refCounts) == 0)
|
|
delete this;
|
|
}
|
|
|
|
/** Returns the object's current reference count. */
|
|
inline int getReferenceCount() const throw()
|
|
{
|
|
return refCounts;
|
|
}
|
|
|
|
protected:
|
|
|
|
/** Creates the reference-counted object (with an initial ref count of zero). */
|
|
ReferenceCountedObject()
|
|
: refCounts (0)
|
|
{
|
|
}
|
|
|
|
/** Destructor. */
|
|
virtual ~ReferenceCountedObject()
|
|
{
|
|
// it's dangerous to delete an object that's still referenced by something else!
|
|
jassert (refCounts == 0);
|
|
}
|
|
|
|
private:
|
|
|
|
int refCounts;
|
|
};
|
|
|
|
/**
|
|
Used to point to an object of type ReferenceCountedObject.
|
|
|
|
It's wise to use a typedef instead of typing out the templated name
|
|
each time - e.g.
|
|
|
|
typedef ReferenceCountedObjectPtr<MyClass> MyClassPtr;
|
|
|
|
@see ReferenceCountedObject, ReferenceCountedObjectArray
|
|
*/
|
|
template <class ReferenceCountedObjectClass>
|
|
class ReferenceCountedObjectPtr
|
|
{
|
|
public:
|
|
|
|
/** Creates a pointer to a null object. */
|
|
inline ReferenceCountedObjectPtr() throw()
|
|
: referencedObject (0)
|
|
{
|
|
}
|
|
|
|
/** Creates a pointer to an object.
|
|
|
|
This will increment the object's reference-count if it is non-null.
|
|
*/
|
|
inline ReferenceCountedObjectPtr (ReferenceCountedObjectClass* const refCountedObject) throw()
|
|
: referencedObject (refCountedObject)
|
|
{
|
|
if (refCountedObject != 0)
|
|
refCountedObject->incReferenceCount();
|
|
}
|
|
|
|
/** Copies another pointer.
|
|
|
|
This will increment the object's reference-count (if it is non-null).
|
|
*/
|
|
inline ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& other) throw()
|
|
: referencedObject (other.referencedObject)
|
|
{
|
|
if (referencedObject != 0)
|
|
referencedObject->incReferenceCount();
|
|
}
|
|
|
|
/** Changes this pointer to point at a different object.
|
|
|
|
The reference count of the old object is decremented, and it might be
|
|
deleted if it hits zero. The new object's count is incremented.
|
|
*/
|
|
const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& operator= (const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& other)
|
|
{
|
|
ReferenceCountedObjectClass* const newObject = other.referencedObject;
|
|
|
|
if (newObject != referencedObject)
|
|
{
|
|
if (newObject != 0)
|
|
newObject->incReferenceCount();
|
|
|
|
ReferenceCountedObjectClass* const oldObject = referencedObject;
|
|
referencedObject = newObject;
|
|
|
|
if (oldObject != 0)
|
|
oldObject->decReferenceCount();
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
/** Changes this pointer to point at a different object.
|
|
|
|
The reference count of the old object is decremented, and it might be
|
|
deleted if it hits zero. The new object's count is incremented.
|
|
*/
|
|
const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& operator= (ReferenceCountedObjectClass* const newObject)
|
|
{
|
|
if (referencedObject != newObject)
|
|
{
|
|
if (newObject != 0)
|
|
newObject->incReferenceCount();
|
|
|
|
ReferenceCountedObjectClass* const oldObject = referencedObject;
|
|
referencedObject = newObject;
|
|
|
|
if (oldObject != 0)
|
|
oldObject->decReferenceCount();
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
/** Destructor.
|
|
|
|
This will decrement the object's reference-count, and may delete it if it
|
|
gets to zero.
|
|
*/
|
|
inline ~ReferenceCountedObjectPtr()
|
|
{
|
|
if (referencedObject != 0)
|
|
referencedObject->decReferenceCount();
|
|
}
|
|
|
|
/** Returns the object that this pointer references.
|
|
|
|
The pointer returned may be zero, of course.
|
|
*/
|
|
inline operator ReferenceCountedObjectClass*() const throw()
|
|
{
|
|
return referencedObject;
|
|
}
|
|
|
|
/** Returns true if this pointer refers to the given object. */
|
|
inline bool operator== (ReferenceCountedObjectClass* const object) const throw()
|
|
{
|
|
return referencedObject == object;
|
|
}
|
|
|
|
/** Returns true if this pointer doesn't refer to the given object. */
|
|
inline bool operator!= (ReferenceCountedObjectClass* const object) const throw()
|
|
{
|
|
return referencedObject != object;
|
|
}
|
|
|
|
// the -> operator is called on the referenced object
|
|
inline ReferenceCountedObjectClass* operator->() const throw()
|
|
{
|
|
return referencedObject;
|
|
}
|
|
|
|
private:
|
|
|
|
ReferenceCountedObjectClass* referencedObject;
|
|
};
|
|
|
|
#endif // __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__
|
|
/********* End of inlined file: juce_ReferenceCountedObject.h *********/
|
|
|
|
/**
|
|
Holds a list of objects derived from ReferenceCountedObject.
|
|
|
|
A ReferenceCountedArray holds objects derived from ReferenceCountedObject,
|
|
and takes care of incrementing and decrementing their ref counts when they
|
|
are added and removed from the array.
|
|
|
|
To make all the array's methods thread-safe, pass in "CriticalSection" as the templated
|
|
TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.
|
|
|
|
@see Array, OwnedArray, StringArray
|
|
*/
|
|
template <class ObjectClass, class TypeOfCriticalSectionToUse = DummyCriticalSection>
|
|
class ReferenceCountedArray : private ArrayAllocationBase <ObjectClass*>
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty array.
|
|
|
|
@param granularity this is the size of increment by which the internal storage
|
|
used by the array will grow. Only change it from the default if you know the
|
|
array is going to be very big and needs to be able to grow efficiently.
|
|
|
|
@see ReferenceCountedObject, ArrayAllocationBase, Array, OwnedArray
|
|
*/
|
|
ReferenceCountedArray (const int granularity = juceDefaultArrayGranularity) throw()
|
|
: ArrayAllocationBase <ObjectClass*> (granularity),
|
|
numUsed (0)
|
|
{
|
|
}
|
|
|
|
/** Creates a copy of another array */
|
|
ReferenceCountedArray (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) throw()
|
|
: ArrayAllocationBase <ObjectClass*> (other.granularity)
|
|
{
|
|
other.lockArray();
|
|
numUsed = other.numUsed;
|
|
this->setAllocatedSize (numUsed);
|
|
memcpy (this->elements, other.elements, numUsed * sizeof (ObjectClass*));
|
|
|
|
for (int i = numUsed; --i >= 0;)
|
|
if (this->elements[i] != 0)
|
|
this->elements[i]->incReferenceCount();
|
|
|
|
other.unlockArray();
|
|
}
|
|
|
|
/** Copies another array into this one.
|
|
|
|
Any existing objects in this array will first be released.
|
|
*/
|
|
const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& operator= (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) throw()
|
|
{
|
|
if (this != &other)
|
|
{
|
|
other.lockArray();
|
|
lock.enter();
|
|
|
|
clear();
|
|
|
|
this->granularity = other.granularity;
|
|
this->ensureAllocatedSize (other.numUsed);
|
|
numUsed = other.numUsed;
|
|
memcpy (this->elements, other.elements, numUsed * sizeof (ObjectClass*));
|
|
minimiseStorageOverheads();
|
|
|
|
for (int i = numUsed; --i >= 0;)
|
|
if (this->elements[i] != 0)
|
|
this->elements[i]->incReferenceCount();
|
|
|
|
lock.exit();
|
|
other.unlockArray();
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
/** Destructor.
|
|
|
|
Any objects in the array will be released, and may be deleted if not referenced from elsewhere.
|
|
*/
|
|
~ReferenceCountedArray()
|
|
{
|
|
clear();
|
|
}
|
|
|
|
/** Removes all objects from the array.
|
|
|
|
Any objects in the array that are not referenced from elsewhere will be deleted.
|
|
*/
|
|
void clear()
|
|
{
|
|
lock.enter();
|
|
|
|
while (numUsed > 0)
|
|
if (this->elements [--numUsed] != 0)
|
|
this->elements [numUsed]->decReferenceCount();
|
|
|
|
jassert (numUsed == 0);
|
|
this->setAllocatedSize (0);
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Returns the current number of objects in the array. */
|
|
inline int size() const throw()
|
|
{
|
|
return numUsed;
|
|
}
|
|
|
|
/** Returns a pointer to the object at this index in the array.
|
|
|
|
If the index is out-of-range, this will return a null pointer, (and
|
|
it could be null anyway, because it's ok for the array to hold null
|
|
pointers as well as objects).
|
|
|
|
@see getUnchecked
|
|
*/
|
|
inline const ReferenceCountedObjectPtr<ObjectClass> operator[] (const int index) const throw()
|
|
{
|
|
lock.enter();
|
|
const ReferenceCountedObjectPtr<ObjectClass> result ((((unsigned int) index) < (unsigned int) numUsed)
|
|
? this->elements [index]
|
|
: (ObjectClass*) 0);
|
|
lock.exit();
|
|
return result;
|
|
}
|
|
|
|
/** Returns a pointer to the object at this index in the array, without checking whether the index is in-range.
|
|
|
|
This is a faster and less safe version of operator[] which doesn't check the index passed in, so
|
|
it can be used when you're sure the index if always going to be legal.
|
|
*/
|
|
inline const ReferenceCountedObjectPtr<ObjectClass> getUnchecked (const int index) const throw()
|
|
{
|
|
lock.enter();
|
|
jassert (((unsigned int) index) < (unsigned int) numUsed);
|
|
const ReferenceCountedObjectPtr<ObjectClass> result (this->elements [index]);
|
|
lock.exit();
|
|
return result;
|
|
}
|
|
|
|
/** Returns a pointer to the first object in the array.
|
|
|
|
This will return a null pointer if the array's empty.
|
|
@see getLast
|
|
*/
|
|
inline const ReferenceCountedObjectPtr<ObjectClass> getFirst() const throw()
|
|
{
|
|
lock.enter();
|
|
const ReferenceCountedObjectPtr<ObjectClass> result ((numUsed > 0) ? this->elements [0]
|
|
: (ObjectClass*) 0);
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Returns a pointer to the last object in the array.
|
|
|
|
This will return a null pointer if the array's empty.
|
|
@see getFirst
|
|
*/
|
|
inline const ReferenceCountedObjectPtr<ObjectClass> getLast() const throw()
|
|
{
|
|
lock.enter();
|
|
const ReferenceCountedObjectPtr<ObjectClass> result ((numUsed > 0) ? this->elements [numUsed - 1]
|
|
: (ObjectClass*) 0);
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Finds the index of the first occurrence of an object in the array.
|
|
|
|
@param objectToLookFor the object to look for
|
|
@returns the index at which the object was found, or -1 if it's not found
|
|
*/
|
|
int indexOf (const ObjectClass* const objectToLookFor) const throw()
|
|
{
|
|
int result = -1;
|
|
|
|
lock.enter();
|
|
ObjectClass** e = this->elements;
|
|
|
|
for (int i = numUsed; --i >= 0;)
|
|
{
|
|
if (objectToLookFor == *e)
|
|
{
|
|
result = (int) (e - this->elements);
|
|
break;
|
|
}
|
|
|
|
++e;
|
|
}
|
|
|
|
lock.exit();
|
|
return result;
|
|
}
|
|
|
|
/** Returns true if the array contains a specified object.
|
|
|
|
@param objectToLookFor the object to look for
|
|
@returns true if the object is in the array
|
|
*/
|
|
bool contains (const ObjectClass* const objectToLookFor) const throw()
|
|
{
|
|
lock.enter();
|
|
ObjectClass** e = this->elements;
|
|
|
|
for (int i = numUsed; --i >= 0;)
|
|
{
|
|
if (objectToLookFor == *e)
|
|
{
|
|
lock.exit();
|
|
return true;
|
|
}
|
|
|
|
++e;
|
|
}
|
|
|
|
lock.exit();
|
|
return false;
|
|
}
|
|
|
|
/** Appends a new object to the end of the array.
|
|
|
|
This will increase the new object's reference count.
|
|
|
|
@param newObject the new object to add to the array
|
|
@see set, insert, addIfNotAlreadyThere, addSorted, addArray
|
|
*/
|
|
void add (ObjectClass* const newObject) throw()
|
|
{
|
|
lock.enter();
|
|
this->ensureAllocatedSize (numUsed + 1);
|
|
this->elements [numUsed++] = newObject;
|
|
|
|
if (newObject != 0)
|
|
newObject->incReferenceCount();
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Inserts a new object into the array at the given index.
|
|
|
|
If the index is less than 0 or greater than the size of the array, the
|
|
element will be added to the end of the array.
|
|
Otherwise, it will be inserted into the array, moving all the later elements
|
|
along to make room.
|
|
|
|
This will increase the new object's reference count.
|
|
|
|
@param indexToInsertAt the index at which the new element should be inserted
|
|
@param newObject the new object to add to the array
|
|
@see add, addSorted, addIfNotAlreadyThere, set
|
|
*/
|
|
void insert (int indexToInsertAt,
|
|
ObjectClass* const newObject) throw()
|
|
{
|
|
if (indexToInsertAt >= 0)
|
|
{
|
|
lock.enter();
|
|
|
|
if (indexToInsertAt > numUsed)
|
|
indexToInsertAt = numUsed;
|
|
|
|
this->ensureAllocatedSize (numUsed + 1);
|
|
|
|
ObjectClass** const e = this->elements + indexToInsertAt;
|
|
const int numToMove = numUsed - indexToInsertAt;
|
|
|
|
if (numToMove > 0)
|
|
memmove (e + 1, e, numToMove * sizeof (ObjectClass*));
|
|
|
|
*e = newObject;
|
|
|
|
if (newObject != 0)
|
|
newObject->incReferenceCount();
|
|
|
|
++numUsed;
|
|
lock.exit();
|
|
}
|
|
else
|
|
{
|
|
add (newObject);
|
|
}
|
|
}
|
|
|
|
/** Appends a new object at the end of the array as long as the array doesn't
|
|
already contain it.
|
|
|
|
If the array already contains a matching object, nothing will be done.
|
|
|
|
@param newObject the new object to add to the array
|
|
*/
|
|
void addIfNotAlreadyThere (ObjectClass* const newObject) throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (! contains (newObject))
|
|
add (newObject);
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Replaces an object in the array with a different one.
|
|
|
|
If the index is less than zero, this method does nothing.
|
|
If the index is beyond the end of the array, the new object is added to the end of the array.
|
|
|
|
The object being added has its reference count increased, and if it's replacing
|
|
another object, then that one has its reference count decreased, and may be deleted.
|
|
|
|
@param indexToChange the index whose value you want to change
|
|
@param newObject the new value to set for this index.
|
|
@see add, insert, remove
|
|
*/
|
|
void set (const int indexToChange,
|
|
ObjectClass* const newObject)
|
|
{
|
|
if (indexToChange >= 0)
|
|
{
|
|
lock.enter();
|
|
|
|
if (newObject != 0)
|
|
newObject->incReferenceCount();
|
|
|
|
if (indexToChange < numUsed)
|
|
{
|
|
if (this->elements [indexToChange] != 0)
|
|
this->elements [indexToChange]->decReferenceCount();
|
|
|
|
this->elements [indexToChange] = newObject;
|
|
}
|
|
else
|
|
{
|
|
this->ensureAllocatedSize (numUsed + 1);
|
|
this->elements [numUsed++] = newObject;
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
}
|
|
|
|
/** Adds elements from another array to the end of this array.
|
|
|
|
@param arrayToAddFrom the array from which to copy the elements
|
|
@param startIndex the first element of the other array to start copying from
|
|
@param numElementsToAdd how many elements to add from the other array. If this
|
|
value is negative or greater than the number of available elements,
|
|
all available elements will be copied.
|
|
@see add
|
|
*/
|
|
void addArray (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& arrayToAddFrom,
|
|
int startIndex = 0,
|
|
int numElementsToAdd = -1) throw()
|
|
{
|
|
arrayToAddFrom.lockArray();
|
|
lock.enter();
|
|
|
|
if (startIndex < 0)
|
|
{
|
|
jassertfalse
|
|
startIndex = 0;
|
|
}
|
|
|
|
if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size())
|
|
numElementsToAdd = arrayToAddFrom.size() - startIndex;
|
|
|
|
if (numElementsToAdd > 0)
|
|
{
|
|
this->ensureAllocatedSize (numUsed + numElementsToAdd);
|
|
|
|
while (--numElementsToAdd >= 0)
|
|
add (arrayToAddFrom.getUnchecked (startIndex++));
|
|
}
|
|
|
|
lock.exit();
|
|
arrayToAddFrom.unlockArray();
|
|
}
|
|
|
|
/** Inserts a new object into the array assuming that the array is sorted.
|
|
|
|
This will use a comparator to find the position at which the new object
|
|
should go. If the array isn't sorted, the behaviour of this
|
|
method will be unpredictable.
|
|
|
|
@param comparator the comparator object to use to compare the elements - see the
|
|
sort() method for details about this object's form
|
|
@param newObject the new object to insert to the array
|
|
@see add, sort
|
|
*/
|
|
template <class ElementComparator>
|
|
void addSorted (ElementComparator& comparator,
|
|
ObjectClass* newObject) throw()
|
|
{
|
|
lock.enter();
|
|
insert (findInsertIndexInSortedArray (comparator, this->elements, newObject, 0, numUsed), newObject);
|
|
lock.exit();
|
|
}
|
|
|
|
/** Inserts or replaces an object in the array, assuming it is sorted.
|
|
|
|
This is similar to addSorted, but if a matching element already exists, then it will be
|
|
replaced by the new one, rather than the new one being added as well.
|
|
*/
|
|
template <class ElementComparator>
|
|
void addOrReplaceSorted (ElementComparator& comparator,
|
|
ObjectClass* newObject) throw()
|
|
{
|
|
lock.enter();
|
|
const int index = findInsertIndexInSortedArray (comparator, this->elements, newObject, 0, numUsed);
|
|
|
|
if (index > 0 && comparator.compareElements (newObject, this->elements [index - 1]) == 0)
|
|
set (index - 1, newObject); // replace an existing object that matches
|
|
else
|
|
insert (index, newObject); // no match, so insert the new one
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Removes an object from the array.
|
|
|
|
This will remove the object at a given index and move back all the
|
|
subsequent objects to close the gap.
|
|
|
|
If the index passed in is out-of-range, nothing will happen.
|
|
|
|
The object that is removed will have its reference count decreased,
|
|
and may be deleted if not referenced from elsewhere.
|
|
|
|
@param indexToRemove the index of the element to remove
|
|
@see removeObject, removeRange
|
|
*/
|
|
void remove (const int indexToRemove)
|
|
{
|
|
lock.enter();
|
|
|
|
if (((unsigned int) indexToRemove) < (unsigned int) numUsed)
|
|
{
|
|
ObjectClass** const e = this->elements + indexToRemove;
|
|
|
|
if (*e != 0)
|
|
(*e)->decReferenceCount();
|
|
|
|
--numUsed;
|
|
const int numberToShift = numUsed - indexToRemove;
|
|
|
|
if (numberToShift > 0)
|
|
memmove (e, e + 1, numberToShift * sizeof (ObjectClass*));
|
|
|
|
if ((numUsed << 1) < this->numAllocated)
|
|
minimiseStorageOverheads();
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Removes the first occurrence of a specified object from the array.
|
|
|
|
If the item isn't found, no action is taken. If it is found, it is
|
|
removed and has its reference count decreased.
|
|
|
|
@param objectToRemove the object to try to remove
|
|
@see remove, removeRange
|
|
*/
|
|
void removeObject (ObjectClass* const objectToRemove)
|
|
{
|
|
lock.enter();
|
|
remove (indexOf (objectToRemove));
|
|
lock.exit();
|
|
}
|
|
|
|
/** Removes a range of objects from the array.
|
|
|
|
This will remove a set of objects, starting from the given index,
|
|
and move any subsequent elements down to close the gap.
|
|
|
|
If the range extends beyond the bounds of the array, it will
|
|
be safely clipped to the size of the array.
|
|
|
|
The objects that are removed will have their reference counts decreased,
|
|
and may be deleted if not referenced from elsewhere.
|
|
|
|
@param startIndex the index of the first object to remove
|
|
@param numberToRemove how many objects should be removed
|
|
@see remove, removeObject
|
|
*/
|
|
void removeRange (const int startIndex,
|
|
const int numberToRemove)
|
|
{
|
|
lock.enter();
|
|
|
|
const int start = jlimit (0, numUsed, startIndex);
|
|
const int end = jlimit (0, numUsed, startIndex + numberToRemove);
|
|
|
|
if (end > start)
|
|
{
|
|
int i;
|
|
for (i = start; i < end; ++i)
|
|
{
|
|
if (this->elements[i] != 0)
|
|
{
|
|
this->elements[i]->decReferenceCount();
|
|
this->elements[i] = 0; // (in case one of the destructors accesses this array and hits a dangling pointer)
|
|
}
|
|
}
|
|
|
|
const int rangeSize = end - start;
|
|
ObjectClass** e = this->elements + start;
|
|
i = numUsed - end;
|
|
numUsed -= rangeSize;
|
|
|
|
while (--i >= 0)
|
|
{
|
|
*e = e [rangeSize];
|
|
++e;
|
|
}
|
|
|
|
if ((numUsed << 1) < this->numAllocated)
|
|
minimiseStorageOverheads();
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Removes the last n objects from the array.
|
|
|
|
The objects that are removed will have their reference counts decreased,
|
|
and may be deleted if not referenced from elsewhere.
|
|
|
|
@param howManyToRemove how many objects to remove from the end of the array
|
|
@see remove, removeObject, removeRange
|
|
*/
|
|
void removeLast (int howManyToRemove = 1)
|
|
{
|
|
lock.enter();
|
|
|
|
if (howManyToRemove > numUsed)
|
|
howManyToRemove = numUsed;
|
|
|
|
while (--howManyToRemove >= 0)
|
|
remove (numUsed - 1);
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Swaps a pair of objects in the array.
|
|
|
|
If either of the indexes passed in is out-of-range, nothing will happen,
|
|
otherwise the two objects at these positions will be exchanged.
|
|
*/
|
|
void swap (const int index1,
|
|
const int index2) throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (((unsigned int) index1) < (unsigned int) numUsed
|
|
&& ((unsigned int) index2) < (unsigned int) numUsed)
|
|
{
|
|
swapVariables (this->elements [index1],
|
|
this->elements [index2]);
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Moves one of the objects to a different position.
|
|
|
|
This will move the object to a specified index, shuffling along
|
|
any intervening elements as required.
|
|
|
|
So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling
|
|
move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }.
|
|
|
|
@param currentIndex the index of the object to be moved. If this isn't a
|
|
valid index, then nothing will be done
|
|
@param newIndex the index at which you'd like this object to end up. If this
|
|
is less than zero, it will be moved to the end of the array
|
|
*/
|
|
void move (const int currentIndex,
|
|
int newIndex) throw()
|
|
{
|
|
if (currentIndex != newIndex)
|
|
{
|
|
lock.enter();
|
|
|
|
if (((unsigned int) currentIndex) < (unsigned int) numUsed)
|
|
{
|
|
if (((unsigned int) newIndex) >= (unsigned int) numUsed)
|
|
newIndex = numUsed - 1;
|
|
|
|
ObjectClass* const value = this->elements [currentIndex];
|
|
|
|
if (newIndex > currentIndex)
|
|
{
|
|
memmove (this->elements + currentIndex,
|
|
this->elements + currentIndex + 1,
|
|
(newIndex - currentIndex) * sizeof (ObjectClass*));
|
|
}
|
|
else
|
|
{
|
|
memmove (this->elements + newIndex + 1,
|
|
this->elements + newIndex,
|
|
(currentIndex - newIndex) * sizeof (ObjectClass*));
|
|
}
|
|
|
|
this->elements [newIndex] = value;
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
}
|
|
|
|
/** Compares this array to another one.
|
|
|
|
@returns true only if the other array contains the same objects in the same order
|
|
*/
|
|
bool operator== (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) const throw()
|
|
{
|
|
other.lockArray();
|
|
lock.enter();
|
|
|
|
bool result = numUsed == other.numUsed;
|
|
|
|
if (result)
|
|
{
|
|
for (int i = numUsed; --i >= 0;)
|
|
{
|
|
if (this->elements [i] != other.elements [i])
|
|
{
|
|
result = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
lock.exit();
|
|
other.unlockArray();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Compares this array to another one.
|
|
|
|
@see operator==
|
|
*/
|
|
bool operator!= (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) const throw()
|
|
{
|
|
return ! operator== (other);
|
|
}
|
|
|
|
/** Sorts the elements in the array.
|
|
|
|
This will use a comparator object to sort the elements into order. The object
|
|
passed must have a method of the form:
|
|
@code
|
|
int compareElements (ElementType first, ElementType second);
|
|
@endcode
|
|
|
|
..and this method must return:
|
|
- a value of < 0 if the first comes before the second
|
|
- a value of 0 if the two objects are equivalent
|
|
- a value of > 0 if the second comes before the first
|
|
|
|
To improve performance, the compareElements() method can be declared as static or const.
|
|
|
|
@param comparator the comparator to use for comparing elements.
|
|
@param retainOrderOfEquivalentItems if this is true, then items
|
|
which the comparator says are equivalent will be
|
|
kept in the order in which they currently appear
|
|
in the array. This is slower to perform, but may
|
|
be important in some cases. If it's false, a faster
|
|
algorithm is used, but equivalent elements may be
|
|
rearranged.
|
|
|
|
@see sortArray
|
|
*/
|
|
template <class ElementComparator>
|
|
void sort (ElementComparator& comparator,
|
|
const bool retainOrderOfEquivalentItems = false) const throw()
|
|
{
|
|
(void) comparator; // if you pass in an object with a static compareElements() method, this
|
|
// avoids getting warning messages about the parameter being unused
|
|
|
|
lock.enter();
|
|
sortArray (comparator, this->elements, 0, size() - 1, retainOrderOfEquivalentItems);
|
|
lock.exit();
|
|
}
|
|
|
|
/** Reduces the amount of storage being used by the array.
|
|
|
|
Arrays typically allocate slightly more storage than they need, and after
|
|
removing elements, they may have quite a lot of unused space allocated.
|
|
This method will reduce the amount of allocated storage to a minimum.
|
|
*/
|
|
void minimiseStorageOverheads() throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (numUsed == 0)
|
|
{
|
|
this->setAllocatedSize (0);
|
|
}
|
|
else
|
|
{
|
|
const int newAllocation = this->granularity * (numUsed / this->granularity + 1);
|
|
|
|
if (newAllocation < this->numAllocated)
|
|
this->setAllocatedSize (newAllocation);
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Locks the array's CriticalSection.
|
|
|
|
Of course if the type of section used is a DummyCriticalSection, this won't
|
|
have any effect.
|
|
|
|
@see unlockArray
|
|
*/
|
|
void lockArray() const throw()
|
|
{
|
|
lock.enter();
|
|
}
|
|
|
|
/** Unlocks the array's CriticalSection.
|
|
|
|
Of course if the type of section used is a DummyCriticalSection, this won't
|
|
have any effect.
|
|
|
|
@see lockArray
|
|
*/
|
|
void unlockArray() const throw()
|
|
{
|
|
lock.exit();
|
|
}
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int numUsed;
|
|
TypeOfCriticalSectionToUse lock;
|
|
};
|
|
|
|
#endif // __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__
|
|
/********* End of inlined file: juce_ReferenceCountedArray.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_SORTEDSET_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_SortedSet.h *********/
|
|
#ifndef __JUCE_SORTEDSET_JUCEHEADER__
|
|
#define __JUCE_SORTEDSET_JUCEHEADER__
|
|
|
|
#if JUCE_MSVC
|
|
#pragma warning (push)
|
|
#pragma warning (disable: 4512)
|
|
#endif
|
|
|
|
/**
|
|
Holds a set of unique primitive objects, such as ints or doubles.
|
|
|
|
A set can only hold one item with a given value, so if for example it's a
|
|
set of integers, attempting to add the same integer twice will do nothing
|
|
the second time.
|
|
|
|
Internally, the list of items is kept sorted (which means that whatever
|
|
kind of primitive type is used must support the ==, <, >, <= and >= operators
|
|
to determine the order), and searching the set for known values is very fast
|
|
because it uses a binary-chop method.
|
|
|
|
Note that if you're using a class or struct as the element type, it must be
|
|
capable of being copied or moved with a straightforward memcpy, rather than
|
|
needing construction and destruction code.
|
|
|
|
To make all the set's methods thread-safe, pass in "CriticalSection" as the templated
|
|
TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.
|
|
|
|
@see Array, OwnedArray, ReferenceCountedArray, StringArray, CriticalSection
|
|
*/
|
|
template <class ElementType, class TypeOfCriticalSectionToUse = DummyCriticalSection>
|
|
class SortedSet : private ArrayAllocationBase <ElementType>
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty set.
|
|
|
|
@param granularity this is the size of increment by which the internal storage
|
|
used by the array will grow. Only change it from the default if you know the
|
|
array is going to be very big and needs to be able to grow efficiently.
|
|
|
|
@see ArrayAllocationBase
|
|
*/
|
|
SortedSet (const int granularity = juceDefaultArrayGranularity) throw()
|
|
: ArrayAllocationBase <ElementType> (granularity),
|
|
numUsed (0)
|
|
{
|
|
}
|
|
|
|
/** Creates a copy of another set.
|
|
@param other the set to copy
|
|
*/
|
|
SortedSet (const SortedSet<ElementType, TypeOfCriticalSectionToUse>& other) throw()
|
|
: ArrayAllocationBase <ElementType> (other.granularity)
|
|
{
|
|
other.lockSet();
|
|
numUsed = other.numUsed;
|
|
setAllocatedSize (other.numUsed);
|
|
memcpy (this->elements, other.elements, numUsed * sizeof (ElementType));
|
|
other.unlockSet();
|
|
}
|
|
|
|
/** Destructor. */
|
|
~SortedSet() throw()
|
|
{
|
|
}
|
|
|
|
/** Copies another set over this one.
|
|
@param other the set to copy
|
|
*/
|
|
const SortedSet <ElementType, TypeOfCriticalSectionToUse>& operator= (const SortedSet <ElementType, TypeOfCriticalSectionToUse>& other) throw()
|
|
{
|
|
if (this != &other)
|
|
{
|
|
other.lockSet();
|
|
lock.enter();
|
|
|
|
this->granularity = other.granularity;
|
|
ensureAllocatedSize (other.size());
|
|
numUsed = other.numUsed;
|
|
memcpy (this->elements, other.elements, numUsed * sizeof (ElementType));
|
|
minimiseStorageOverheads();
|
|
|
|
lock.exit();
|
|
other.unlockSet();
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
/** Compares this set to another one.
|
|
|
|
Two sets are considered equal if they both contain the same set of
|
|
elements.
|
|
|
|
@param other the other set to compare with
|
|
*/
|
|
bool operator== (const SortedSet<ElementType>& other) const throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (numUsed != other.numUsed)
|
|
{
|
|
lock.exit();
|
|
return false;
|
|
}
|
|
|
|
for (int i = numUsed; --i >= 0;)
|
|
{
|
|
if (this->elements [i] != other.elements [i])
|
|
{
|
|
lock.exit();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
lock.exit();
|
|
return true;
|
|
}
|
|
|
|
/** Compares this set to another one.
|
|
|
|
Two sets are considered equal if they both contain the same set of
|
|
elements.
|
|
|
|
@param other the other set to compare with
|
|
*/
|
|
bool operator!= (const SortedSet<ElementType>& other) const throw()
|
|
{
|
|
return ! operator== (other);
|
|
}
|
|
|
|
/** Removes all elements from the set.
|
|
|
|
This will remove all the elements, and free any storage that the set is
|
|
using. To clear it without freeing the storage, use the clearQuick()
|
|
method instead.
|
|
|
|
@see clearQuick
|
|
*/
|
|
void clear() throw()
|
|
{
|
|
lock.enter();
|
|
this->setAllocatedSize (0);
|
|
numUsed = 0;
|
|
lock.exit();
|
|
}
|
|
|
|
/** Removes all elements from the set without freeing the array's allocated storage.
|
|
|
|
@see clear
|
|
*/
|
|
void clearQuick() throw()
|
|
{
|
|
lock.enter();
|
|
numUsed = 0;
|
|
lock.exit();
|
|
}
|
|
|
|
/** Returns the current number of elements in the set.
|
|
*/
|
|
inline int size() const throw()
|
|
{
|
|
return numUsed;
|
|
}
|
|
|
|
/** Returns one of the elements in the set.
|
|
|
|
If the index passed in is beyond the range of valid elements, this
|
|
will return zero.
|
|
|
|
If you're certain that the index will always be a valid element, you
|
|
can call getUnchecked() instead, which is faster.
|
|
|
|
@param index the index of the element being requested (0 is the first element in the set)
|
|
@see getUnchecked, getFirst, getLast
|
|
*/
|
|
inline ElementType operator[] (const int index) const throw()
|
|
{
|
|
lock.enter();
|
|
const ElementType result = (((unsigned int) index) < (unsigned int) numUsed)
|
|
? this->elements [index]
|
|
: (ElementType) 0;
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Returns one of the elements in the set, without checking the index passed in.
|
|
Unlike the operator[] method, this will try to return an element without
|
|
checking that the index is within the bounds of the set, so should only
|
|
be used when you're confident that it will always be a valid index.
|
|
|
|
@param index the index of the element being requested (0 is the first element in the set)
|
|
@see operator[], getFirst, getLast
|
|
*/
|
|
inline ElementType getUnchecked (const int index) const throw()
|
|
{
|
|
lock.enter();
|
|
jassert (((unsigned int) index) < (unsigned int) numUsed);
|
|
const ElementType result = this->elements [index];
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Returns the first element in the set, or 0 if the set is empty.
|
|
|
|
@see operator[], getUnchecked, getLast
|
|
*/
|
|
inline ElementType getFirst() const throw()
|
|
{
|
|
lock.enter();
|
|
const ElementType result = (numUsed > 0) ? this->elements [0]
|
|
: (ElementType) 0;
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Returns the last element in the set, or 0 if the set is empty.
|
|
|
|
@see operator[], getUnchecked, getFirst
|
|
*/
|
|
inline ElementType getLast() const throw()
|
|
{
|
|
lock.enter();
|
|
const ElementType result = (numUsed > 0) ? this->elements [numUsed - 1]
|
|
: (ElementType) 0;
|
|
lock.exit();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** Finds the index of the first element which matches the value passed in.
|
|
|
|
This will search the set for the given object, and return the index
|
|
of its first occurrence. If the object isn't found, the method will return -1.
|
|
|
|
@param elementToLookFor the value or object to look for
|
|
@returns the index of the object, or -1 if it's not found
|
|
*/
|
|
int indexOf (const ElementType elementToLookFor) const throw()
|
|
{
|
|
lock.enter();
|
|
|
|
int start = 0;
|
|
int end = numUsed;
|
|
|
|
for (;;)
|
|
{
|
|
if (start >= end)
|
|
{
|
|
lock.exit();
|
|
return -1;
|
|
}
|
|
else if (elementToLookFor == this->elements [start])
|
|
{
|
|
lock.exit();
|
|
return start;
|
|
}
|
|
else
|
|
{
|
|
const int halfway = (start + end) >> 1;
|
|
|
|
if (halfway == start)
|
|
{
|
|
lock.exit();
|
|
return -1;
|
|
}
|
|
else if (elementToLookFor >= this->elements [halfway])
|
|
start = halfway;
|
|
else
|
|
end = halfway;
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Returns true if the set contains at least one occurrence of an object.
|
|
|
|
@param elementToLookFor the value or object to look for
|
|
@returns true if the item is found
|
|
*/
|
|
bool contains (const ElementType elementToLookFor) const throw()
|
|
{
|
|
lock.enter();
|
|
|
|
int start = 0;
|
|
int end = numUsed;
|
|
|
|
for (;;)
|
|
{
|
|
if (start >= end)
|
|
{
|
|
lock.exit();
|
|
return false;
|
|
}
|
|
else if (elementToLookFor == this->elements [start])
|
|
{
|
|
lock.exit();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
const int halfway = (start + end) >> 1;
|
|
|
|
if (halfway == start)
|
|
{
|
|
lock.exit();
|
|
return false;
|
|
}
|
|
else if (elementToLookFor >= this->elements [halfway])
|
|
start = halfway;
|
|
else
|
|
end = halfway;
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Adds a new element to the set, (as long as it's not already in there).
|
|
|
|
@param newElement the new object to add to the set
|
|
@see set, insert, addIfNotAlreadyThere, addSorted, addSet, addArray
|
|
*/
|
|
void add (const ElementType newElement) throw()
|
|
{
|
|
lock.enter();
|
|
|
|
int start = 0;
|
|
int end = numUsed;
|
|
|
|
for (;;)
|
|
{
|
|
if (start >= end)
|
|
{
|
|
jassert (start <= end);
|
|
insertInternal (start, newElement);
|
|
break;
|
|
}
|
|
else if (newElement == this->elements [start])
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
const int halfway = (start + end) >> 1;
|
|
|
|
if (halfway == start)
|
|
{
|
|
if (newElement >= this->elements [halfway])
|
|
insertInternal (start + 1, newElement);
|
|
else
|
|
insertInternal (start, newElement);
|
|
|
|
break;
|
|
}
|
|
else if (newElement >= this->elements [halfway])
|
|
start = halfway;
|
|
else
|
|
end = halfway;
|
|
}
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Adds elements from an array to this set.
|
|
|
|
@param elementsToAdd the array of elements to add
|
|
@param numElementsToAdd how many elements are in this other array
|
|
@see add
|
|
*/
|
|
void addArray (const ElementType* elementsToAdd,
|
|
int numElementsToAdd) throw()
|
|
{
|
|
lock.enter();
|
|
|
|
while (--numElementsToAdd >= 0)
|
|
add (*elementsToAdd++);
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Adds elements from another set to this one.
|
|
|
|
@param setToAddFrom the set from which to copy the elements
|
|
@param startIndex the first element of the other set to start copying from
|
|
@param numElementsToAdd how many elements to add from the other set. If this
|
|
value is negative or greater than the number of available elements,
|
|
all available elements will be copied.
|
|
@see add
|
|
*/
|
|
template <class OtherSetType>
|
|
void addSet (const OtherSetType& setToAddFrom,
|
|
int startIndex = 0,
|
|
int numElementsToAdd = -1) throw()
|
|
{
|
|
setToAddFrom.lockSet();
|
|
lock.enter();
|
|
jassert (this != &setToAddFrom);
|
|
|
|
if (this != &setToAddFrom)
|
|
{
|
|
if (startIndex < 0)
|
|
{
|
|
jassertfalse
|
|
startIndex = 0;
|
|
}
|
|
|
|
if (numElementsToAdd < 0 || startIndex + numElementsToAdd > setToAddFrom.size())
|
|
numElementsToAdd = setToAddFrom.size() - startIndex;
|
|
|
|
addArray (setToAddFrom.elements + startIndex, numElementsToAdd);
|
|
}
|
|
|
|
lock.exit();
|
|
setToAddFrom.unlockSet();
|
|
}
|
|
|
|
/** Removes an element from the set.
|
|
|
|
This will remove the element at a given index.
|
|
If the index passed in is out-of-range, nothing will happen.
|
|
|
|
@param indexToRemove the index of the element to remove
|
|
@returns the element that has been removed
|
|
@see removeValue, removeRange
|
|
*/
|
|
ElementType remove (const int indexToRemove) throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (((unsigned int) indexToRemove) < (unsigned int) numUsed)
|
|
{
|
|
--numUsed;
|
|
|
|
ElementType* const e = this->elements + indexToRemove;
|
|
ElementType const removed = *e;
|
|
const int numberToShift = numUsed - indexToRemove;
|
|
|
|
if (numberToShift > 0)
|
|
memmove (e, e + 1, numberToShift * sizeof (ElementType));
|
|
|
|
if ((numUsed << 1) < this->numAllocated)
|
|
minimiseStorageOverheads();
|
|
|
|
lock.exit();
|
|
return removed;
|
|
}
|
|
else
|
|
{
|
|
lock.exit();
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/** Removes an item from the set.
|
|
|
|
This will remove the given element from the set, if it's there.
|
|
|
|
@param valueToRemove the object to try to remove
|
|
@see remove, removeRange
|
|
*/
|
|
void removeValue (const ElementType valueToRemove) throw()
|
|
{
|
|
lock.enter();
|
|
remove (indexOf (valueToRemove));
|
|
lock.exit();
|
|
}
|
|
|
|
/** Removes any elements which are also in another set.
|
|
|
|
@param otherSet the other set in which to look for elements to remove
|
|
@see removeValuesNotIn, remove, removeValue, removeRange
|
|
*/
|
|
template <class OtherSetType>
|
|
void removeValuesIn (const OtherSetType& otherSet) throw()
|
|
{
|
|
otherSet.lockSet();
|
|
lock.enter();
|
|
|
|
if (this == &otherSet)
|
|
{
|
|
clear();
|
|
}
|
|
else
|
|
{
|
|
if (otherSet.size() > 0)
|
|
{
|
|
for (int i = numUsed; --i >= 0;)
|
|
if (otherSet.contains (this->elements [i]))
|
|
remove (i);
|
|
}
|
|
}
|
|
|
|
lock.exit();
|
|
otherSet.unlockSet();
|
|
}
|
|
|
|
/** Removes any elements which are not found in another set.
|
|
|
|
Only elements which occur in this other set will be retained.
|
|
|
|
@param otherSet the set in which to look for elements NOT to remove
|
|
@see removeValuesIn, remove, removeValue, removeRange
|
|
*/
|
|
template <class OtherSetType>
|
|
void removeValuesNotIn (const OtherSetType& otherSet) throw()
|
|
{
|
|
otherSet.lockSet();
|
|
lock.enter();
|
|
|
|
if (this != &otherSet)
|
|
{
|
|
if (otherSet.size() <= 0)
|
|
{
|
|
clear();
|
|
}
|
|
else
|
|
{
|
|
for (int i = numUsed; --i >= 0;)
|
|
if (! otherSet.contains (this->elements [i]))
|
|
remove (i);
|
|
}
|
|
}
|
|
|
|
lock.exit();
|
|
otherSet.lockSet();
|
|
}
|
|
|
|
/** Reduces the amount of storage being used by the set.
|
|
|
|
Sets typically allocate slightly more storage than they need, and after
|
|
removing elements, they may have quite a lot of unused space allocated.
|
|
This method will reduce the amount of allocated storage to a minimum.
|
|
*/
|
|
void minimiseStorageOverheads() throw()
|
|
{
|
|
lock.enter();
|
|
|
|
if (numUsed == 0)
|
|
{
|
|
this->setAllocatedSize (0);
|
|
}
|
|
else
|
|
{
|
|
const int newAllocation = this->granularity * (numUsed / this->granularity + 1);
|
|
|
|
if (newAllocation < this->numAllocated)
|
|
this->setAllocatedSize (newAllocation);
|
|
}
|
|
|
|
lock.exit();
|
|
}
|
|
|
|
/** Locks the set's CriticalSection.
|
|
|
|
Of course if the type of section used is a DummyCriticalSection, this won't
|
|
have any effect.
|
|
|
|
@see unlockSet
|
|
*/
|
|
void lockSet() const throw()
|
|
{
|
|
lock.enter();
|
|
}
|
|
|
|
/** Unlocks the set's CriticalSection.
|
|
|
|
Of course if the type of section used is a DummyCriticalSection, this won't
|
|
have any effect.
|
|
|
|
@see lockSet
|
|
*/
|
|
void unlockSet() const throw()
|
|
{
|
|
lock.exit();
|
|
}
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int numUsed;
|
|
TypeOfCriticalSectionToUse lock;
|
|
|
|
void insertInternal (const int indexToInsertAt, const ElementType newElement) throw()
|
|
{
|
|
this->ensureAllocatedSize (numUsed + 1);
|
|
|
|
ElementType* const insertPos = this->elements + indexToInsertAt;
|
|
const int numberToMove = numUsed - indexToInsertAt;
|
|
|
|
if (numberToMove > 0)
|
|
memmove (insertPos + 1, insertPos, numberToMove * sizeof (ElementType));
|
|
|
|
*insertPos = newElement;
|
|
++numUsed;
|
|
}
|
|
};
|
|
|
|
#if JUCE_MSVC
|
|
#pragma warning (pop)
|
|
#endif
|
|
|
|
#endif // __JUCE_SORTEDSET_JUCEHEADER__
|
|
/********* End of inlined file: juce_SortedSet.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_SPARSESET_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_SparseSet.h *********/
|
|
#ifndef __JUCE_SPARSESET_JUCEHEADER__
|
|
#define __JUCE_SPARSESET_JUCEHEADER__
|
|
|
|
/**
|
|
Holds a set of primitive values, storing them as a set of ranges.
|
|
|
|
This container acts like a simple BitArray, but can efficiently hold large
|
|
continguous ranges of values. It's quite a specialised class, mostly useful
|
|
for things like keeping the set of selected rows in a listbox.
|
|
|
|
The type used as a template paramter must be an integer type, such as int, short,
|
|
int64, etc.
|
|
*/
|
|
template <class Type>
|
|
class SparseSet
|
|
{
|
|
public:
|
|
|
|
/** Creates a new empty set. */
|
|
SparseSet() throw()
|
|
{
|
|
}
|
|
|
|
/** Creates a copy of another SparseSet. */
|
|
SparseSet (const SparseSet<Type>& other) throw()
|
|
: values (other.values)
|
|
{
|
|
}
|
|
|
|
/** Destructor. */
|
|
~SparseSet() throw()
|
|
{
|
|
}
|
|
|
|
/** Clears the set. */
|
|
void clear() throw()
|
|
{
|
|
values.clear();
|
|
}
|
|
|
|
/** Checks whether the set is empty.
|
|
|
|
This is much quicker than using (size() == 0).
|
|
*/
|
|
bool isEmpty() const throw()
|
|
{
|
|
return values.size() == 0;
|
|
}
|
|
|
|
/** Returns the number of values in the set.
|
|
|
|
Because of the way the data is stored, this method can take longer if there
|
|
are a lot of items in the set. Use isEmpty() for a quick test of whether there
|
|
are any items.
|
|
*/
|
|
Type size() const throw()
|
|
{
|
|
Type num = 0;
|
|
|
|
for (int i = 0; i < values.size(); i += 2)
|
|
num += values[i + 1] - values[i];
|
|
|
|
return num;
|
|
}
|
|
|
|
/** Returns one of the values in the set.
|
|
|
|
@param index the index of the value to retrieve, in the range 0 to (size() - 1).
|
|
@returns the value at this index, or 0 if it's out-of-range
|
|
*/
|
|
Type operator[] (int index) const throw()
|
|
{
|
|
for (int i = 0; i < values.size(); i += 2)
|
|
{
|
|
const Type s = values.getUnchecked(i);
|
|
const Type e = values.getUnchecked(i + 1);
|
|
|
|
if (index < e - s)
|
|
return s + index;
|
|
|
|
index -= e - s;
|
|
}
|
|
|
|
return (Type) 0;
|
|
}
|
|
|
|
/** Checks whether a particular value is in the set. */
|
|
bool contains (const Type valueToLookFor) const throw()
|
|
{
|
|
bool on = false;
|
|
|
|
for (int i = 0; i < values.size(); ++i)
|
|
{
|
|
if (values.getUnchecked(i) > valueToLookFor)
|
|
return on;
|
|
|
|
on = ! on;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/** Returns the number of contiguous blocks of values.
|
|
|
|
@see getRange
|
|
*/
|
|
int getNumRanges() const throw()
|
|
{
|
|
return values.size() >> 1;
|
|
}
|
|
|
|
/** Returns one of the contiguous ranges of values stored.
|
|
|
|
@param rangeIndex the index of the range to look up, between 0
|
|
and (getNumRanges() - 1)
|
|
@param startValue on return, the value at the start of the range
|
|
@param numValues on return, the number of values in the range
|
|
|
|
@see getTotalRange
|
|
*/
|
|
bool getRange (const int rangeIndex,
|
|
Type& startValue,
|
|
Type& numValues) const throw()
|
|
{
|
|
if (((unsigned int) rangeIndex) < (unsigned int) getNumRanges())
|
|
{
|
|
startValue = values [rangeIndex << 1];
|
|
numValues = values [(rangeIndex << 1) + 1] - startValue;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/** Returns the lowest and highest values in the set.
|
|
|
|
@see getRange
|
|
*/
|
|
bool getTotalRange (Type& lowestValue,
|
|
Type& highestValue) const throw()
|
|
{
|
|
if (values.size() > 0)
|
|
{
|
|
lowestValue = values.getUnchecked (0);
|
|
highestValue = values.getUnchecked (values.size() - 1);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/** Adds a range of contiguous values to the set.
|
|
|
|
e.g. addRange (10, 4) will add (10, 11, 12, 13) to the set.
|
|
|
|
@param firstValue the start of the range of values to add
|
|
@param numValuesToAdd how many values to add
|
|
*/
|
|
void addRange (const Type firstValue,
|
|
const Type numValuesToAdd) throw()
|
|
{
|
|
jassert (numValuesToAdd >= 0);
|
|
|
|
if (numValuesToAdd > 0)
|
|
{
|
|
removeRange (firstValue, numValuesToAdd);
|
|
|
|
IntegerElementComparator<Type> sorter;
|
|
values.addSorted (sorter, firstValue);
|
|
values.addSorted (sorter, firstValue + numValuesToAdd);
|
|
|
|
simplify();
|
|
}
|
|
}
|
|
|
|
/** Removes a range of values from the set.
|
|
|
|
e.g. removeRange (10, 4) will remove (10, 11, 12, 13) from the set.
|
|
|
|
@param firstValue the start of the range of values to remove
|
|
@param numValuesToRemove how many values to remove
|
|
*/
|
|
void removeRange (const Type firstValue,
|
|
const Type numValuesToRemove) throw()
|
|
{
|
|
jassert (numValuesToRemove >= 0);
|
|
|
|
if (numValuesToRemove >= 0
|
|
&& firstValue < values.getLast())
|
|
{
|
|
const bool onAtStart = contains (firstValue - 1);
|
|
const Type lastValue = firstValue + jmin (numValuesToRemove, values.getLast() - firstValue);
|
|
const bool onAtEnd = contains (lastValue);
|
|
|
|
for (int i = values.size(); --i >= 0;)
|
|
{
|
|
if (values.getUnchecked(i) <= lastValue)
|
|
{
|
|
while (values.getUnchecked(i) >= firstValue)
|
|
{
|
|
values.remove (i);
|
|
|
|
if (--i < 0)
|
|
break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
IntegerElementComparator<Type> sorter;
|
|
|
|
if (onAtStart)
|
|
values.addSorted (sorter, firstValue);
|
|
|
|
if (onAtEnd)
|
|
values.addSorted (sorter, lastValue);
|
|
|
|
simplify();
|
|
}
|
|
}
|
|
|
|
/** Does an XOR of the values in a given range. */
|
|
void invertRange (const Type firstValue,
|
|
const Type numValues)
|
|
{
|
|
SparseSet newItems;
|
|
newItems.addRange (firstValue, numValues);
|
|
|
|
int i;
|
|
for (i = getNumRanges(); --i >= 0;)
|
|
{
|
|
const int start = values [i << 1];
|
|
const int end = values [(i << 1) + 1];
|
|
|
|
newItems.removeRange (start, end);
|
|
}
|
|
|
|
removeRange (firstValue, numValues);
|
|
|
|
for (i = newItems.getNumRanges(); --i >= 0;)
|
|
{
|
|
const int start = newItems.values [i << 1];
|
|
const int end = newItems.values [(i << 1) + 1];
|
|
|
|
addRange (start, end);
|
|
}
|
|
}
|
|
|
|
/** Checks whether any part of a given range overlaps any part of this one. */
|
|
bool overlapsRange (const Type firstValue,
|
|
const Type numValues) throw()
|
|
{
|
|
jassert (numValues >= 0);
|
|
|
|
if (numValues > 0)
|
|
{
|
|
for (int i = getNumRanges(); --i >= 0;)
|
|
{
|
|
if (firstValue >= values.getUnchecked ((i << 1) + 1))
|
|
return false;
|
|
|
|
if (firstValue + numValues > values.getUnchecked (i << 1))
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/** Checks whether the whole of a given range is contained within this one. */
|
|
bool containsRange (const Type firstValue,
|
|
const Type numValues) throw()
|
|
{
|
|
jassert (numValues >= 0);
|
|
|
|
if (numValues > 0)
|
|
{
|
|
for (int i = getNumRanges(); --i >= 0;)
|
|
{
|
|
if (firstValue >= values.getUnchecked ((i << 1) + 1))
|
|
return false;
|
|
|
|
if (firstValue >= values.getUnchecked (i << 1)
|
|
&& firstValue + numValues <= values.getUnchecked ((i << 1) + 1))
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool operator== (const SparseSet<Type>& other) throw()
|
|
{
|
|
return values == other.values;
|
|
}
|
|
|
|
bool operator!= (const SparseSet<Type>& other) throw()
|
|
{
|
|
return values != other.values;
|
|
}
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
// alternating start/end values of ranges of values that are present.
|
|
Array<Type> values;
|
|
|
|
void simplify() throw()
|
|
{
|
|
jassert ((values.size() & 1) == 0);
|
|
|
|
for (int i = values.size(); --i > 0;)
|
|
if (values.getUnchecked(i) == values.getUnchecked (i - 1))
|
|
values.removeRange (i - 1, 2);
|
|
}
|
|
};
|
|
|
|
#endif // __JUCE_SPARSESET_JUCEHEADER__
|
|
/********* End of inlined file: juce_SparseSet.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_VARIANT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Variant.h *********/
|
|
#ifndef __JUCE_VARIANT_JUCEHEADER__
|
|
#define __JUCE_VARIANT_JUCEHEADER__
|
|
|
|
class JUCE_API DynamicObject;
|
|
|
|
/**
|
|
A variant class, that can be used to hold a range of primitive values.
|
|
|
|
A var object can hold a range of simple primitive values, strings, or
|
|
a reference-counted pointer to a DynamicObject. The var class is intended
|
|
to act like the values used in dynamic scripting languages.
|
|
|
|
@see DynamicObject
|
|
*/
|
|
class JUCE_API var
|
|
{
|
|
public:
|
|
|
|
typedef const var (DynamicObject::*MethodFunction) (const var* arguments, int numArguments);
|
|
|
|
/** Creates a void variant. */
|
|
var() throw();
|
|
|
|
/** Destructor. */
|
|
~var();
|
|
|
|
var (const var& valueToCopy) throw();
|
|
var (const int value) throw();
|
|
var (const bool value) throw();
|
|
var (const double value) throw();
|
|
var (const char* const value) throw();
|
|
var (const juce_wchar* const value) throw();
|
|
var (const String& value) throw();
|
|
var (DynamicObject* const object) throw();
|
|
var (MethodFunction method) throw();
|
|
|
|
const var& operator= (const var& valueToCopy) throw();
|
|
const var& operator= (const int value) throw();
|
|
const var& operator= (const bool value) throw();
|
|
const var& operator= (const double value) throw();
|
|
const var& operator= (const char* const value) throw();
|
|
const var& operator= (const juce_wchar* const value) throw();
|
|
const var& operator= (const String& value) throw();
|
|
const var& operator= (DynamicObject* const object) throw();
|
|
const var& operator= (MethodFunction method) throw();
|
|
|
|
operator int() const throw();
|
|
operator bool() const throw();
|
|
operator double() const throw();
|
|
operator const String() const throw();
|
|
const String toString() const throw();
|
|
DynamicObject* getObject() const throw();
|
|
|
|
bool isVoid() const throw() { return type == voidType; }
|
|
bool isInt() const throw() { return type == intType; }
|
|
bool isBool() const throw() { return type == boolType; }
|
|
bool isDouble() const throw() { return type == doubleType; }
|
|
bool isString() const throw() { return type == stringType; }
|
|
bool isObject() const throw() { return type == objectType; }
|
|
bool isMethod() const throw() { return type == methodType; }
|
|
|
|
class JUCE_API identifier
|
|
{
|
|
public:
|
|
identifier (const char* const name) throw();
|
|
identifier (const String& name) throw();
|
|
~identifier() throw();
|
|
|
|
bool operator== (const identifier& other) const throw() { return hashCode == other.hashCode; }
|
|
|
|
String name;
|
|
int hashCode;
|
|
};
|
|
|
|
/** If this variant is an object, this returns one of its properties. */
|
|
const var operator[] (const identifier& propertyName) const throw();
|
|
|
|
/** If this variant is an object, this invokes one of its methods with no arguments. */
|
|
const var call (const identifier& method) const;
|
|
/** If this variant is an object, this invokes one of its methods with one argument. */
|
|
const var call (const identifier& method, const var& arg1) const;
|
|
/** If this variant is an object, this invokes one of its methods with 2 arguments. */
|
|
const var call (const identifier& method, const var& arg1, const var& arg2) const;
|
|
/** If this variant is an object, this invokes one of its methods with 3 arguments. */
|
|
const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3);
|
|
/** If this variant is an object, this invokes one of its methods with 4 arguments. */
|
|
const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
|
|
/** If this variant is an object, this invokes one of its methods with 5 arguments. */
|
|
const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;
|
|
|
|
/** If this variant is an object, this invokes one of its methods with a list of arguments. */
|
|
const var invoke (const identifier& method, const var* arguments, int numArguments) const;
|
|
|
|
/** If this variant is a method pointer, this invokes it on a target object. */
|
|
const var invoke (const var& targetObject, const var* arguments, int numArguments) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
enum Type
|
|
{
|
|
voidType = 0,
|
|
intType,
|
|
boolType,
|
|
doubleType,
|
|
stringType,
|
|
objectType,
|
|
methodType
|
|
};
|
|
|
|
Type type;
|
|
|
|
union
|
|
{
|
|
int intValue;
|
|
bool boolValue;
|
|
double doubleValue;
|
|
String* stringValue;
|
|
DynamicObject* objectValue;
|
|
MethodFunction methodValue;
|
|
} value;
|
|
|
|
void releaseValue() throw();
|
|
};
|
|
|
|
/**
|
|
Represents a dynamically implemented object.
|
|
|
|
An instance of this class can be used to store named properties, and
|
|
by subclassing hasMethod() and invokeMethod(), you can give your object
|
|
methods.
|
|
|
|
This is intended for use as a wrapper for scripting language objects.
|
|
*/
|
|
class JUCE_API DynamicObject : public ReferenceCountedObject
|
|
{
|
|
public:
|
|
|
|
DynamicObject();
|
|
|
|
/** Destructor. */
|
|
virtual ~DynamicObject();
|
|
|
|
/** Returns true if the object has a property with this name.
|
|
Note that if the property is actually a method, this will return false.
|
|
*/
|
|
virtual bool hasProperty (const var::identifier& propertyName) const;
|
|
|
|
/** Returns a named property.
|
|
|
|
This returns a void if no such property exists.
|
|
*/
|
|
virtual const var getProperty (const var::identifier& propertyName) const;
|
|
|
|
/** Sets a named property. */
|
|
virtual void setProperty (const var::identifier& propertyName, const var& newValue);
|
|
|
|
/** Removes a named property. */
|
|
virtual void removeProperty (const var::identifier& propertyName);
|
|
|
|
/** Checks whether this object has the specified method.
|
|
|
|
The default implementation of this just checks whether there's a property
|
|
with this name that's actually a method, but this can be overridden for
|
|
building objects with dynamic invocation.
|
|
*/
|
|
virtual bool hasMethod (const var::identifier& methodName) const;
|
|
|
|
/** Invokes a named method on this object.
|
|
|
|
The default implementation looks up the named property, and if it's a method
|
|
call, then it invokes it.
|
|
|
|
This method is virtual to allow more dynamic invocation to used for objects
|
|
where the methods may not already be set as properies.
|
|
*/
|
|
virtual const var invokeMethod (const var::identifier& methodName,
|
|
const var* parameters,
|
|
int numParameters);
|
|
|
|
/** Sets up a method.
|
|
|
|
This is basically the same as calling setProperty (methodName, (var::MethodFunction) myFunction), but
|
|
helps to avoid accidentally invoking the wrong type of var constructor. It also makes
|
|
the code easier to read,
|
|
|
|
The compiler will probably force you to use an explicit cast your method to a (var::MethodFunction), e.g.
|
|
@code
|
|
setMethod ("doSomething", (var::MethodFunction) &MyClass::doSomething);
|
|
@endcode
|
|
*/
|
|
void setMethod (const var::identifier& methodName,
|
|
var::MethodFunction methodFunction);
|
|
|
|
/** Removes all properties and methods from the object. */
|
|
void clear();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Array <int> propertyIds;
|
|
OwnedArray <var> propertyValues;
|
|
};
|
|
|
|
#endif // __JUCE_VARIANT_JUCEHEADER__
|
|
/********* End of inlined file: juce_Variant.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_VOIDARRAY_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_DIRECTORYITERATOR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DirectoryIterator.h *********/
|
|
#ifndef __JUCE_DIRECTORYITERATOR_JUCEHEADER__
|
|
#define __JUCE_DIRECTORYITERATOR_JUCEHEADER__
|
|
|
|
/**
|
|
Searches through a the files in a directory, returning each file that is found.
|
|
|
|
A DirectoryIterator will search through a directory and its subdirectories using
|
|
a wildcard filepattern match.
|
|
|
|
If you may be finding a large number of files, this is better than
|
|
using File::findChildFiles() because it doesn't block while it finds them
|
|
all, and this is more memory-efficient.
|
|
|
|
It can also guess how far it's got using a wildly inaccurate algorithm.
|
|
*/
|
|
class JUCE_API DirectoryIterator
|
|
{
|
|
public:
|
|
|
|
/** Creates a DirectoryIterator for a given directory.
|
|
|
|
After creating one of these, call its next() method to get the
|
|
first file - e.g. @code
|
|
|
|
DirectoryIterator iter (File ("/animals/mooses"), true, "*.moose");
|
|
|
|
while (iter.next())
|
|
{
|
|
File theFileItFound (iter.getFile());
|
|
|
|
... etc
|
|
}
|
|
@endcode
|
|
|
|
@param directory the directory to search in
|
|
@param isRecursive whether all the subdirectories should also be searched
|
|
@param wildCard the file pattern to match
|
|
@param whatToLookFor a value from the File::TypesOfFileToFind enum, specifying
|
|
whether to look for files, directories, or both.
|
|
*/
|
|
DirectoryIterator (const File& directory,
|
|
bool isRecursive,
|
|
const String& wildCard = JUCE_T("*"),
|
|
const int whatToLookFor = File::findFiles) throw();
|
|
|
|
/** Destructor. */
|
|
~DirectoryIterator() throw();
|
|
|
|
/** Call this to move the iterator along to the next file.
|
|
|
|
@returns true if a file was found (you can then use getFile() to see what it was) - or
|
|
false if there are no more matching files.
|
|
*/
|
|
bool next() throw();
|
|
|
|
/** Returns the file that the iterator is currently pointing at.
|
|
|
|
The result of this call is only valid after a call to next() has returned true.
|
|
*/
|
|
const File getFile() const throw();
|
|
|
|
/** Returns a guess of how far through the search the iterator has got.
|
|
|
|
@returns a value 0.0 to 1.0 to show the progress, although this won't be
|
|
very accurate.
|
|
*/
|
|
float getEstimatedProgress() const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
OwnedArray <File> filesFound;
|
|
OwnedArray <File> dirsFound;
|
|
String wildCard;
|
|
int index;
|
|
const int whatToLookFor;
|
|
DirectoryIterator* subIterator;
|
|
|
|
DirectoryIterator (const DirectoryIterator&);
|
|
const DirectoryIterator& operator= (const DirectoryIterator&);
|
|
};
|
|
|
|
#endif // __JUCE_DIRECTORYITERATOR_JUCEHEADER__
|
|
/********* End of inlined file: juce_DirectoryIterator.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILEINPUTSTREAM_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileInputStream.h *********/
|
|
#ifndef __JUCE_FILEINPUTSTREAM_JUCEHEADER__
|
|
#define __JUCE_FILEINPUTSTREAM_JUCEHEADER__
|
|
|
|
/**
|
|
An input stream that reads from a local file.
|
|
|
|
@see InputStream, FileOutputStream, File::createInputStream
|
|
*/
|
|
class JUCE_API FileInputStream : public InputStream
|
|
{
|
|
public:
|
|
|
|
/** Creates a FileInputStream.
|
|
|
|
@param fileToRead the file to read from - if the file can't be accessed for some
|
|
reason, then the stream will just contain no data
|
|
*/
|
|
FileInputStream (const File& fileToRead);
|
|
|
|
/** Destructor. */
|
|
~FileInputStream();
|
|
|
|
const File& getFile() const throw() { return file; }
|
|
|
|
int64 getTotalLength();
|
|
int read (void* destBuffer, int maxBytesToRead);
|
|
bool isExhausted();
|
|
int64 getPosition();
|
|
bool setPosition (int64 pos);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
File file;
|
|
void* fileHandle;
|
|
int64 currentPosition, totalSize;
|
|
bool needToSeek;
|
|
};
|
|
|
|
#endif // __JUCE_FILEINPUTSTREAM_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileInputStream.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILEOUTPUTSTREAM_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileOutputStream.h *********/
|
|
#ifndef __JUCE_FILEOUTPUTSTREAM_JUCEHEADER__
|
|
#define __JUCE_FILEOUTPUTSTREAM_JUCEHEADER__
|
|
|
|
/**
|
|
An output stream that writes into a local file.
|
|
|
|
@see OutputStream, FileInputStream, File::createOutputStream
|
|
*/
|
|
class JUCE_API FileOutputStream : public OutputStream
|
|
{
|
|
public:
|
|
|
|
/** Creates a FileOutputStream.
|
|
|
|
If the file doesn't exist, it will first be created. If the file can't be
|
|
created or opened, the failedToOpen() method will return
|
|
true.
|
|
|
|
If the file already exists when opened, the stream's write-postion will
|
|
be set to the end of the file. To overwrite an existing file,
|
|
use File::deleteFile() before opening the stream, or use setPosition(0)
|
|
after it's opened (although this won't truncate the file).
|
|
|
|
It's better to use File::createOutputStream() to create one of these, rather
|
|
than using the class directly.
|
|
*/
|
|
FileOutputStream (const File& fileToWriteTo,
|
|
const int bufferSizeToUse = 16384);
|
|
|
|
/** Destructor. */
|
|
~FileOutputStream();
|
|
|
|
/** Returns the file that this stream is writing to.
|
|
*/
|
|
const File& getFile() const throw() { return file; }
|
|
|
|
/** Returns true if the stream couldn't be opened for some reason.
|
|
*/
|
|
bool failedToOpen() const throw() { return fileHandle == 0; }
|
|
|
|
void flush();
|
|
int64 getPosition();
|
|
bool setPosition (int64 pos);
|
|
bool write (const void* data, int numBytes);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
File file;
|
|
void* fileHandle;
|
|
int64 currentPosition;
|
|
int bufferSize, bytesInBuffer;
|
|
char* buffer;
|
|
};
|
|
|
|
#endif // __JUCE_FILEOUTPUTSTREAM_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileOutputStream.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILESEARCHPATH_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileSearchPath.h *********/
|
|
#ifndef __JUCE_FILESEARCHPATH_JUCEHEADER__
|
|
#define __JUCE_FILESEARCHPATH_JUCEHEADER__
|
|
|
|
/**
|
|
Encapsulates a set of folders that make up a search path.
|
|
|
|
@see File
|
|
*/
|
|
class JUCE_API FileSearchPath
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty search path. */
|
|
FileSearchPath();
|
|
|
|
/** Creates a search path from a string of pathnames.
|
|
|
|
The path can be semicolon- or comma-separated, e.g.
|
|
"/foo/bar;/foo/moose;/fish/moose"
|
|
|
|
The separate folders are tokenised and added to the search path.
|
|
*/
|
|
FileSearchPath (const String& path);
|
|
|
|
/** Creates a copy of another search path. */
|
|
FileSearchPath (const FileSearchPath& other);
|
|
|
|
/** Destructor. */
|
|
~FileSearchPath();
|
|
|
|
/** Uses a string containing a list of pathnames to re-initialise this list.
|
|
|
|
This search path is cleared and the semicolon- or comma-separated folders
|
|
in this string are added instead. e.g. "/foo/bar;/foo/moose;/fish/moose"
|
|
*/
|
|
const FileSearchPath& operator= (const String& path);
|
|
|
|
/** Returns the number of folders in this search path.
|
|
|
|
@see operator[]
|
|
*/
|
|
int getNumPaths() const;
|
|
|
|
/** Returns one of the folders in this search path.
|
|
|
|
The file returned isn't guaranteed to actually be a valid directory.
|
|
|
|
@see getNumPaths
|
|
*/
|
|
const File operator[] (const int index) const;
|
|
|
|
/** Returns the search path as a semicolon-separated list of directories. */
|
|
const String toString() const;
|
|
|
|
/** Adds a new directory to the search path.
|
|
|
|
The new directory is added to the end of the list if the insertIndex parameter is
|
|
less than zero, otherwise it is inserted at the given index.
|
|
*/
|
|
void add (const File& directoryToAdd,
|
|
const int insertIndex = -1);
|
|
|
|
/** Adds a new directory to the search path if it's not already in there. */
|
|
void addIfNotAlreadyThere (const File& directoryToAdd);
|
|
|
|
/** Removes a directory from the search path. */
|
|
void remove (const int indexToRemove);
|
|
|
|
/** Merges another search path into this one.
|
|
|
|
This will remove any duplicate directories.
|
|
*/
|
|
void addPath (const FileSearchPath& other);
|
|
|
|
/** Removes any directories that are actually subdirectories of one of the other directories in the search path.
|
|
|
|
If the search is intended to be recursive, there's no point having nested folders in the search
|
|
path, because they'll just get searched twice and you'll get duplicate results.
|
|
|
|
e.g. if the path is "c:\abc\de;c:\abc", this method will simplify it to "c:\abc"
|
|
*/
|
|
void removeRedundantPaths();
|
|
|
|
/** Removes any directories that don't actually exist. */
|
|
void removeNonExistentPaths();
|
|
|
|
/** Searches the path for a wildcard.
|
|
|
|
This will search all the directories in the search path in order, adding any
|
|
matching files to the results array.
|
|
|
|
@param results an array to append the results to
|
|
@param whatToLookFor a value from the File::TypesOfFileToFind enum, specifying whether to
|
|
return files, directories, or both.
|
|
@param searchRecursively whether to recursively search the subdirectories too
|
|
@param wildCardPattern a pattern to match against the filenames
|
|
@returns the number of files added to the array
|
|
@see File::findChildFiles
|
|
*/
|
|
int findChildFiles (OwnedArray<File>& results,
|
|
const int whatToLookFor,
|
|
const bool searchRecursively,
|
|
const String& wildCardPattern = JUCE_T("*")) const;
|
|
|
|
/** Finds out whether a file is inside one of the path's directories.
|
|
|
|
This will return true if the specified file is a child of one of the
|
|
directories specified by this path. Note that this doesn't actually do any
|
|
searching or check that the files exist - it just looks at the pathnames
|
|
to work out whether the file would be inside a directory.
|
|
|
|
@param fileToCheck the file to look for
|
|
@param checkRecursively if true, then this will return true if the file is inside a
|
|
subfolder of one of the path's directories (at any depth). If false
|
|
it will only return true if the file is actually a direct child
|
|
of one of the directories.
|
|
@see File::isAChildOf
|
|
|
|
*/
|
|
bool isFileInPath (const File& fileToCheck,
|
|
const bool checkRecursively) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
StringArray directories;
|
|
|
|
void init (const String& path);
|
|
};
|
|
|
|
#endif // __JUCE_FILESEARCHPATH_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileSearchPath.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_NAMEDPIPE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_NamedPipe.h *********/
|
|
#ifndef __JUCE_NAMEDPIPE_JUCEHEADER__
|
|
#define __JUCE_NAMEDPIPE_JUCEHEADER__
|
|
|
|
/**
|
|
A cross-process pipe that can have data written to and read from it.
|
|
|
|
Two or more processes can use these for inter-process communication.
|
|
|
|
@see InterprocessConnection
|
|
*/
|
|
class JUCE_API NamedPipe
|
|
{
|
|
public:
|
|
|
|
/** Creates a NamedPipe. */
|
|
NamedPipe();
|
|
|
|
/** Destructor. */
|
|
~NamedPipe();
|
|
|
|
/** Tries to open a pipe that already exists.
|
|
|
|
Returns true if it succeeds.
|
|
*/
|
|
bool openExisting (const String& pipeName);
|
|
|
|
/** Tries to create a new pipe.
|
|
|
|
Returns true if it succeeds.
|
|
*/
|
|
bool createNewPipe (const String& pipeName);
|
|
|
|
/** Closes the pipe, if it's open. */
|
|
void close();
|
|
|
|
/** True if the pipe is currently open. */
|
|
bool isOpen() const throw();
|
|
|
|
/** Returns the last name that was used to try to open this pipe. */
|
|
const String getName() const throw();
|
|
|
|
/** Reads data from the pipe.
|
|
|
|
This will block until another thread has written enough data into the pipe to fill
|
|
the number of bytes specified, or until another thread calls the cancelPendingReads()
|
|
method.
|
|
|
|
If the operation fails, it returns -1, otherwise, it will return the number of
|
|
bytes read.
|
|
|
|
If timeOutMilliseconds is less than zero, it will wait indefinitely, otherwise
|
|
this is a maximum timeout for reading from the pipe.
|
|
*/
|
|
int read (void* destBuffer, int maxBytesToRead, int timeOutMilliseconds = 5000);
|
|
|
|
/** Writes some data to the pipe.
|
|
|
|
If the operation fails, it returns -1, otherwise, it will return the number of
|
|
bytes written.
|
|
*/
|
|
int write (const void* sourceBuffer, int numBytesToWrite,
|
|
int timeOutMilliseconds = 2000);
|
|
|
|
/** If any threads are currently blocked on a read operation, this tells them to abort.
|
|
*/
|
|
void cancelPendingReads();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
void* internal;
|
|
String currentPipeName;
|
|
|
|
NamedPipe (const NamedPipe&);
|
|
const NamedPipe& operator= (const NamedPipe&);
|
|
|
|
bool openInternal (const String& pipeName, const bool createPipe);
|
|
};
|
|
|
|
#endif // __JUCE_NAMEDPIPE_JUCEHEADER__
|
|
/********* End of inlined file: juce_NamedPipe.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_ZIPFILE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ZipFile.h *********/
|
|
#ifndef __JUCE_ZIPFILE_JUCEHEADER__
|
|
#define __JUCE_ZIPFILE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_InputSource.h *********/
|
|
#ifndef __JUCE_INPUTSOURCE_JUCEHEADER__
|
|
#define __JUCE_INPUTSOURCE_JUCEHEADER__
|
|
|
|
/**
|
|
A lightweight object that can create a stream to read some kind of resource.
|
|
|
|
This may be used to refer to a file, or some other kind of source, allowing a
|
|
caller to create an input stream that can read from it when required.
|
|
|
|
@see FileInputSource
|
|
*/
|
|
class JUCE_API InputSource
|
|
{
|
|
public:
|
|
|
|
InputSource() throw() {}
|
|
|
|
/** Destructor. */
|
|
virtual ~InputSource() {}
|
|
|
|
/** Returns a new InputStream to read this item.
|
|
|
|
@returns an inputstream that the caller will delete, or 0 if
|
|
the filename isn't found.
|
|
*/
|
|
virtual InputStream* createInputStream() = 0;
|
|
|
|
/** Returns a new InputStream to read an item, relative.
|
|
|
|
@param relatedItemPath the relative pathname of the resource that is required
|
|
@returns an inputstream that the caller will delete, or 0 if
|
|
the item isn't found.
|
|
*/
|
|
virtual InputStream* createInputStreamFor (const String& relatedItemPath) = 0;
|
|
|
|
/** Returns a hash code that uniquely represents this item.
|
|
*/
|
|
virtual int64 hashCode() const = 0;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
};
|
|
|
|
#endif // __JUCE_INPUTSOURCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_InputSource.h *********/
|
|
|
|
/**
|
|
Decodes a ZIP file from a stream.
|
|
|
|
This can enumerate the items in a ZIP file and can create suitable stream objects
|
|
to read each one.
|
|
*/
|
|
class JUCE_API ZipFile
|
|
{
|
|
public:
|
|
|
|
/** Creates a ZipFile for a given stream.
|
|
|
|
@param inputStream the stream to read from
|
|
@param deleteStreamWhenDestroyed if set to true, the object passed-in
|
|
will be deleted when this ZipFile object is deleted
|
|
*/
|
|
ZipFile (InputStream* const inputStream,
|
|
const bool deleteStreamWhenDestroyed) throw();
|
|
|
|
/** Creates a ZipFile based for a file. */
|
|
ZipFile (const File& file);
|
|
|
|
/** Creates a ZipFile for an input source.
|
|
|
|
The inputSource object will be owned by the zip file, which will delete
|
|
it later when not needed.
|
|
*/
|
|
ZipFile (InputSource* const inputSource);
|
|
|
|
/** Destructor. */
|
|
~ZipFile() throw();
|
|
|
|
/**
|
|
Contains information about one of the entries in a ZipFile.
|
|
|
|
@see ZipFile::getEntry
|
|
*/
|
|
struct ZipEntry
|
|
{
|
|
/** The name of the file, which may also include a partial pathname. */
|
|
String filename;
|
|
|
|
/** The file's original size. */
|
|
unsigned int uncompressedSize;
|
|
|
|
/** The last time the file was modified. */
|
|
Time fileTime;
|
|
};
|
|
|
|
/** Returns the number of items in the zip file. */
|
|
int getNumEntries() const throw();
|
|
|
|
/** Returns a structure that describes one of the entries in the zip file.
|
|
|
|
This may return zero if the index is out of range.
|
|
|
|
@see ZipFile::ZipEntry
|
|
*/
|
|
const ZipEntry* getEntry (const int index) const throw();
|
|
|
|
/** Returns the index of the first entry with a given filename.
|
|
|
|
This uses a case-sensitive comparison to look for a filename in the
|
|
list of entries. It might return -1 if no match is found.
|
|
|
|
@see ZipFile::ZipEntry
|
|
*/
|
|
int getIndexOfFileName (const String& fileName) const throw();
|
|
|
|
/** Returns a structure that describes one of the entries in the zip file.
|
|
|
|
This uses a case-sensitive comparison to look for a filename in the
|
|
list of entries. It might return 0 if no match is found.
|
|
|
|
@see ZipFile::ZipEntry
|
|
*/
|
|
const ZipEntry* getEntry (const String& fileName) const throw();
|
|
|
|
/** Sorts the list of entries, based on the filename.
|
|
*/
|
|
void sortEntriesByFilename();
|
|
|
|
/** Creates a stream that can read from one of the zip file's entries.
|
|
|
|
The stream that is returned must be deleted by the caller (and
|
|
zero might be returned if a stream can't be opened for some reason).
|
|
|
|
The stream must not be used after the ZipFile object that created
|
|
has been deleted.
|
|
*/
|
|
InputStream* createStreamForEntry (const int index);
|
|
|
|
/** Uncompresses all of the files in the zip file.
|
|
|
|
This will expand all the entires into a target directory. The relative
|
|
paths of the entries are used.
|
|
|
|
@param targetDirectory the root folder to uncompress to
|
|
@param shouldOverwriteFiles whether to overwrite existing files with similarly-named ones
|
|
*/
|
|
void uncompressTo (const File& targetDirectory,
|
|
const bool shouldOverwriteFiles = true);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
VoidArray entries;
|
|
friend class ZipInputStream;
|
|
CriticalSection lock;
|
|
InputStream* inputStream;
|
|
InputSource* inputSource;
|
|
|
|
bool deleteStreamWhenDestroyed;
|
|
int numEntries, centralRecStart;
|
|
|
|
#ifdef JUCE_DEBUG
|
|
int numOpenStreams;
|
|
#endif
|
|
|
|
void init();
|
|
int findEndOfZipEntryTable (InputStream* in);
|
|
|
|
ZipFile (const ZipFile&);
|
|
const ZipFile& operator= (const ZipFile&);
|
|
};
|
|
|
|
#endif // __JUCE_ZIPFILE_JUCEHEADER__
|
|
/********* End of inlined file: juce_ZipFile.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_BLOWFISH_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_BlowFish.h *********/
|
|
#ifndef __JUCE_BLOWFISH_JUCEHEADER__
|
|
#define __JUCE_BLOWFISH_JUCEHEADER__
|
|
|
|
/**
|
|
BlowFish encryption class.
|
|
|
|
*/
|
|
class JUCE_API BlowFish
|
|
{
|
|
public:
|
|
|
|
/** Creates an object that can encode/decode based on the specified key.
|
|
|
|
The key data can be up to 72 bytes long.
|
|
*/
|
|
BlowFish (const uint8* keyData, int keyBytes);
|
|
|
|
/** Creates a copy of another blowfish object. */
|
|
BlowFish (const BlowFish& other);
|
|
|
|
/** Copies another blowfish object. */
|
|
const BlowFish& operator= (const BlowFish& other);
|
|
|
|
/** Destructor. */
|
|
~BlowFish();
|
|
|
|
/** Encrypts a pair of 32-bit integers. */
|
|
void encrypt (uint32& data1, uint32& data2) const;
|
|
|
|
/** Decrypts a pair of 32-bit integers. */
|
|
void decrypt (uint32& data1, uint32& data2) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
uint32 p[18];
|
|
uint32* s[4];
|
|
|
|
uint32 F (uint32 x) const;
|
|
};
|
|
|
|
#endif // __JUCE_BLOWFISH_JUCEHEADER__
|
|
/********* End of inlined file: juce_BlowFish.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MD5_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MD5.h *********/
|
|
#ifndef __JUCE_MD5_JUCEHEADER__
|
|
#define __JUCE_MD5_JUCEHEADER__
|
|
|
|
/**
|
|
MD5 checksum class.
|
|
|
|
Create one of these with a block of source data or a string, and it calculates the
|
|
MD5 checksum of that data.
|
|
|
|
You can then retrieve this checksum as a 16-byte block, or as a hex string.
|
|
*/
|
|
class JUCE_API MD5
|
|
{
|
|
public:
|
|
|
|
/** Creates a null MD5 object. */
|
|
MD5();
|
|
|
|
/** Creates a copy of another MD5. */
|
|
MD5 (const MD5& other);
|
|
|
|
/** Copies another MD5. */
|
|
const MD5& operator= (const MD5& other);
|
|
|
|
/** Creates a checksum for a block of binary data. */
|
|
MD5 (const MemoryBlock& data);
|
|
|
|
/** Creates a checksum for a block of binary data. */
|
|
MD5 (const char* data, const int numBytes);
|
|
|
|
/** Creates a checksum for a string.
|
|
|
|
Note that this operates on the string as a block of unicode characters, so the
|
|
result you get will differ from the value you'd get if the string was treated
|
|
as a block of utf8 or ascii. Bear this in mind if you're comparing the result
|
|
of this method with a checksum created by a different framework, which may have
|
|
used a different encoding.
|
|
*/
|
|
MD5 (const String& text);
|
|
|
|
/** Creates a checksum for the input from a stream.
|
|
|
|
This will read up to the given number of bytes from the stream, and produce the
|
|
checksum of that. If the number of bytes to read is negative, it'll read
|
|
until the stream is exhausted.
|
|
*/
|
|
MD5 (InputStream& input, int numBytesToRead = -1);
|
|
|
|
/** Creates a checksum for a file. */
|
|
MD5 (const File& file);
|
|
|
|
/** Destructor. */
|
|
~MD5();
|
|
|
|
/** Returns the checksum as a 16-byte block of data. */
|
|
const MemoryBlock getRawChecksumData() const;
|
|
|
|
/** Returns the checksum as a 32-digit hex string. */
|
|
const String toHexString() const;
|
|
|
|
/** Compares this to another MD5. */
|
|
bool operator== (const MD5& other) const;
|
|
|
|
/** Compares this to another MD5. */
|
|
bool operator!= (const MD5& other) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
uint8 result [16];
|
|
|
|
struct ProcessContext
|
|
{
|
|
uint8 buffer [64];
|
|
uint32 state [4];
|
|
uint32 count [2];
|
|
|
|
ProcessContext();
|
|
|
|
void processBlock (const uint8* const data, int dataSize);
|
|
void transform (const uint8* const buffer);
|
|
void finish (uint8* const result);
|
|
};
|
|
|
|
void processStream (InputStream& input, int numBytesToRead);
|
|
};
|
|
|
|
#endif // __JUCE_MD5_JUCEHEADER__
|
|
/********* End of inlined file: juce_MD5.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_PRIMES_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Primes.h *********/
|
|
#ifndef __JUCE_PRIMES_JUCEHEADER__
|
|
#define __JUCE_PRIMES_JUCEHEADER__
|
|
|
|
/**
|
|
Prime number creation class.
|
|
|
|
This class contains static methods for generating and testing prime numbers.
|
|
|
|
@see BitArray
|
|
*/
|
|
class JUCE_API Primes
|
|
{
|
|
public:
|
|
|
|
/** Creates a random prime number with a given bit-length.
|
|
|
|
The certainty parameter specifies how many iterations to use when testing
|
|
for primality. A safe value might be anything over about 20-30.
|
|
|
|
The randomSeeds parameter lets you optionally pass it a set of values with
|
|
which to seed the random number generation, improving the security of the
|
|
keys generated.
|
|
*/
|
|
static const BitArray createProbablePrime (int bitLength,
|
|
int certainty,
|
|
const int* randomSeeds = 0,
|
|
int numRandomSeeds = 0) throw();
|
|
|
|
/** Tests a number to see if it's prime.
|
|
|
|
This isn't a bulletproof test, it uses a Miller-Rabin test to determine
|
|
whether the number is prime.
|
|
|
|
The certainty parameter specifies how many iterations to use when testing - a
|
|
safe value might be anything over about 20-30.
|
|
*/
|
|
static bool isProbablyPrime (const BitArray& number,
|
|
int certainty) throw();
|
|
};
|
|
|
|
#endif // __JUCE_PRIMES_JUCEHEADER__
|
|
/********* End of inlined file: juce_Primes.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_RSAKEY_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_RSAKey.h *********/
|
|
#ifndef __JUCE_RSAKEY_JUCEHEADER__
|
|
#define __JUCE_RSAKEY_JUCEHEADER__
|
|
|
|
/**
|
|
RSA public/private key-pair encryption class.
|
|
|
|
An object of this type makes up one half of a public/private RSA key pair. Use the
|
|
createKeyPair() method to create a matching pair for encoding/decoding.
|
|
*/
|
|
class JUCE_API RSAKey
|
|
{
|
|
public:
|
|
|
|
/** Creates a null key object.
|
|
|
|
Initialise a pair of objects for use with the createKeyPair() method.
|
|
*/
|
|
RSAKey() throw();
|
|
|
|
/** Loads a key from an encoded string representation.
|
|
|
|
This reloads a key from a string created by the toString() method.
|
|
*/
|
|
RSAKey (const String& stringRepresentation) throw();
|
|
|
|
/** Destructor. */
|
|
~RSAKey() throw();
|
|
|
|
/** Turns the key into a string representation.
|
|
|
|
This can be reloaded using the constructor that takes a string.
|
|
*/
|
|
const String toString() const throw();
|
|
|
|
/** Encodes or decodes a value.
|
|
|
|
Call this on the public key object to encode some data, then use the matching
|
|
private key object to decode it.
|
|
|
|
Returns false if the operation failed, e.g. if this object isn't a valid key.
|
|
*/
|
|
bool applyToValue (BitArray& value) const throw();
|
|
|
|
/** Creates a public/private key-pair.
|
|
|
|
Each key will perform one-way encryption that can only be reversed by
|
|
using the other key.
|
|
|
|
The numBits parameter specifies the size of key, e.g. 128, 256, 512 bit. Bigger
|
|
sizes are more secure, but this method will take longer to execute.
|
|
|
|
The randomSeeds parameter lets you optionally pass it a set of values with
|
|
which to seed the random number generation, improving the security of the
|
|
keys generated.
|
|
*/
|
|
static void createKeyPair (RSAKey& publicKey,
|
|
RSAKey& privateKey,
|
|
const int numBits,
|
|
const int* randomSeeds = 0,
|
|
const int numRandomSeeds = 0) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
BitArray part1, part2;
|
|
};
|
|
|
|
#endif // __JUCE_RSAKEY_JUCEHEADER__
|
|
/********* End of inlined file: juce_RSAKey.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_SOCKET_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Socket.h *********/
|
|
#ifndef __JUCE_SOCKET_JUCEHEADER__
|
|
#define __JUCE_SOCKET_JUCEHEADER__
|
|
|
|
/**
|
|
A wrapper for a streaming (TCP) socket.
|
|
|
|
This allows low-level use of sockets; for an easier-to-use messaging layer on top of
|
|
sockets, you could also try the InterprocessConnection class.
|
|
|
|
@see DatagramSocket, InterprocessConnection, InterprocessConnectionServer
|
|
*/
|
|
class JUCE_API StreamingSocket
|
|
{
|
|
public:
|
|
|
|
/** Creates an uninitialised socket.
|
|
|
|
To connect it, use the connect() method, after which you can read() or write()
|
|
to it.
|
|
|
|
To wait for other sockets to connect to this one, the createListener() method
|
|
enters "listener" mode, and can be used to spawn new sockets for each connection
|
|
that comes along.
|
|
*/
|
|
StreamingSocket();
|
|
|
|
/** Destructor. */
|
|
~StreamingSocket();
|
|
|
|
/** Binds the socket to the specified local port.
|
|
|
|
@returns true on success; false may indicate that another socket is already bound
|
|
on the same port
|
|
*/
|
|
bool bindToPort (const int localPortNumber);
|
|
|
|
/** Tries to connect the socket to hostname:port.
|
|
|
|
If timeOutMillisecs is 0, then this method will block until the operating system
|
|
rejects the connection (which could take a long time).
|
|
|
|
@returns true if it succeeds.
|
|
@see isConnected
|
|
*/
|
|
bool connect (const String& remoteHostname,
|
|
const int remotePortNumber,
|
|
const int timeOutMillisecs = 3000);
|
|
|
|
/** True if the socket is currently connected. */
|
|
bool isConnected() const throw() { return connected; }
|
|
|
|
/** Closes the connection. */
|
|
void close();
|
|
|
|
/** Returns the name of the currently connected host. */
|
|
const String& getHostName() const throw() { return hostName; }
|
|
|
|
/** Returns the port number that's currently open. */
|
|
int getPort() const throw() { return portNumber; }
|
|
|
|
/** True if the socket is connected to this machine rather than over the network. */
|
|
bool isLocal() const throw();
|
|
|
|
/** Waits until the socket is ready for reading or writing.
|
|
|
|
If readyForReading is true, it will wait until the socket is ready for
|
|
reading; if false, it will wait until it's ready for writing.
|
|
|
|
If the timeout is < 0, it will wait forever, or else will give up after
|
|
the specified time.
|
|
|
|
If the socket is ready on return, this returns 1. If it times-out before
|
|
the socket becomes ready, it returns 0. If an error occurs, it returns -1.
|
|
*/
|
|
int waitUntilReady (const bool readyForReading,
|
|
const int timeoutMsecs) const;
|
|
|
|
/** Reads bytes from the socket.
|
|
|
|
If blockUntilSpecifiedAmountHasArrived is true, the method will block until
|
|
maxBytesToRead bytes have been read, (or until an error occurs). If this
|
|
flag is false, the method will return as much data as is currently available
|
|
without blocking.
|
|
|
|
@returns the number of bytes read, or -1 if there was an error.
|
|
@see waitUntilReady
|
|
*/
|
|
int read (void* destBuffer, const int maxBytesToRead,
|
|
const bool blockUntilSpecifiedAmountHasArrived);
|
|
|
|
/** Writes bytes to the socket from a buffer.
|
|
|
|
Note that this method will block unless you have checked the socket is ready
|
|
for writing before calling it (see the waitUntilReady() method).
|
|
|
|
@returns the number of bytes written, or -1 if there was an error.
|
|
*/
|
|
int write (const void* sourceBuffer, const int numBytesToWrite);
|
|
|
|
/** Puts this socket into "listener" mode.
|
|
|
|
When in this mode, your thread can call waitForNextConnection() repeatedly,
|
|
which will spawn new sockets for each new connection, so that these can
|
|
be handled in parallel by other threads.
|
|
|
|
This returns true if it manages to open the socket successfully.
|
|
|
|
@see waitForNextConnection
|
|
*/
|
|
bool createListener (const int portNumber);
|
|
|
|
/** When in "listener" mode, this waits for a connection and spawns it as a new
|
|
socket.
|
|
|
|
The object that gets returned will be owned by the caller.
|
|
|
|
This method can only be called after using createListener().
|
|
|
|
@see createListener
|
|
*/
|
|
StreamingSocket* waitForNextConnection() const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
String hostName;
|
|
int volatile portNumber, handle;
|
|
bool connected, isListener;
|
|
|
|
StreamingSocket (const String& hostname, const int portNumber, const int handle);
|
|
StreamingSocket (const StreamingSocket&);
|
|
const StreamingSocket& operator= (const StreamingSocket&);
|
|
};
|
|
|
|
/**
|
|
A wrapper for a datagram (UDP) socket.
|
|
|
|
This allows low-level use of sockets; for an easier-to-use messaging layer on top of
|
|
sockets, you could also try the InterprocessConnection class.
|
|
|
|
@see StreamingSocket, InterprocessConnection, InterprocessConnectionServer
|
|
*/
|
|
class JUCE_API DatagramSocket
|
|
{
|
|
public:
|
|
|
|
/**
|
|
Creates an (uninitialised) datagram socket.
|
|
|
|
The localPortNumber is the port on which to bind this socket. If this value is 0,
|
|
the port number is assigned by the operating system.
|
|
|
|
To use the socket for sending, call the connect() method. This will not immediately
|
|
make a connection, but will save the destination you've provided. After this, you can
|
|
call read() or write().
|
|
|
|
If enableBroadcasting is true, the socket will be allowed to send broadcast messages
|
|
(may require extra privileges on linux)
|
|
|
|
To wait for other sockets to connect to this one, call waitForNextConnection().
|
|
*/
|
|
DatagramSocket (const int localPortNumber,
|
|
const bool enableBroadcasting = false);
|
|
|
|
/** Destructor. */
|
|
~DatagramSocket();
|
|
|
|
/** Binds the socket to the specified local port.
|
|
|
|
@returns true on success; false may indicate that another socket is already bound
|
|
on the same port
|
|
*/
|
|
bool bindToPort (const int localPortNumber);
|
|
|
|
/** Tries to connect the socket to hostname:port.
|
|
|
|
If timeOutMillisecs is 0, then this method will block until the operating system
|
|
rejects the connection (which could take a long time).
|
|
|
|
@returns true if it succeeds.
|
|
@see isConnected
|
|
*/
|
|
bool connect (const String& remoteHostname,
|
|
const int remotePortNumber,
|
|
const int timeOutMillisecs = 3000);
|
|
|
|
/** True if the socket is currently connected. */
|
|
bool isConnected() const throw() { return connected; }
|
|
|
|
/** Closes the connection. */
|
|
void close();
|
|
|
|
/** Returns the name of the currently connected host. */
|
|
const String& getHostName() const throw() { return hostName; }
|
|
|
|
/** Returns the port number that's currently open. */
|
|
int getPort() const throw() { return portNumber; }
|
|
|
|
/** True if the socket is connected to this machine rather than over the network. */
|
|
bool isLocal() const throw();
|
|
|
|
/** Waits until the socket is ready for reading or writing.
|
|
|
|
If readyForReading is true, it will wait until the socket is ready for
|
|
reading; if false, it will wait until it's ready for writing.
|
|
|
|
If the timeout is < 0, it will wait forever, or else will give up after
|
|
the specified time.
|
|
|
|
If the socket is ready on return, this returns 1. If it times-out before
|
|
the socket becomes ready, it returns 0. If an error occurs, it returns -1.
|
|
*/
|
|
int waitUntilReady (const bool readyForReading,
|
|
const int timeoutMsecs) const;
|
|
|
|
/** Reads bytes from the socket.
|
|
|
|
If blockUntilSpecifiedAmountHasArrived is true, the method will block until
|
|
maxBytesToRead bytes have been read, (or until an error occurs). If this
|
|
flag is false, the method will return as much data as is currently available
|
|
without blocking.
|
|
|
|
@returns the number of bytes read, or -1 if there was an error.
|
|
@see waitUntilReady
|
|
*/
|
|
int read (void* destBuffer, const int maxBytesToRead,
|
|
const bool blockUntilSpecifiedAmountHasArrived);
|
|
|
|
/** Writes bytes to the socket from a buffer.
|
|
|
|
Note that this method will block unless you have checked the socket is ready
|
|
for writing before calling it (see the waitUntilReady() method).
|
|
|
|
@returns the number of bytes written, or -1 if there was an error.
|
|
*/
|
|
int write (const void* sourceBuffer, const int numBytesToWrite);
|
|
|
|
/** This waits for incoming data to be sent, and returns a socket that can be used
|
|
to read it.
|
|
|
|
The object that gets returned is owned by the caller, and can't be used for
|
|
sending, but can be used to read the data.
|
|
*/
|
|
DatagramSocket* waitForNextConnection() const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
String hostName;
|
|
int volatile portNumber, handle;
|
|
bool connected, allowBroadcast;
|
|
void* serverAddress;
|
|
|
|
DatagramSocket (const String& hostname, const int portNumber, const int handle, const int localPortNumber);
|
|
DatagramSocket (const DatagramSocket&);
|
|
const DatagramSocket& operator= (const DatagramSocket&);
|
|
};
|
|
|
|
#endif // __JUCE_SOCKET_JUCEHEADER__
|
|
/********* End of inlined file: juce_Socket.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_URL_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_URL.h *********/
|
|
#ifndef __JUCE_URL_JUCEHEADER__
|
|
#define __JUCE_URL_JUCEHEADER__
|
|
|
|
/**
|
|
Represents a URL and has a bunch of useful functions to manipulate it.
|
|
|
|
This class can be used to launch URLs in browsers, and also to create
|
|
InputStreams that can read from remote http or ftp sources.
|
|
*/
|
|
class JUCE_API URL
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty URL. */
|
|
URL() throw();
|
|
|
|
/** Creates a URL from a string. */
|
|
URL (const String& url);
|
|
|
|
/** Creates a copy of another URL. */
|
|
URL (const URL& other);
|
|
|
|
/** Destructor. */
|
|
~URL() throw();
|
|
|
|
/** Copies this URL from another one. */
|
|
const URL& operator= (const URL& other);
|
|
|
|
/** Returns a string version of the URL.
|
|
|
|
If includeGetParameters is true and any parameters have been set with the
|
|
withParameter() method, then the string will have these appended on the
|
|
end and url-encoded.
|
|
*/
|
|
const String toString (const bool includeGetParameters) const;
|
|
|
|
/** True if it seems to be valid. */
|
|
bool isWellFormed() const;
|
|
|
|
/** Returns just the domain part of the URL.
|
|
|
|
E.g. for "http://www.xyz.com/foobar", this will return "www.xyz.com".
|
|
*/
|
|
const String getDomain() const;
|
|
|
|
/** Returns the path part of the URL.
|
|
|
|
E.g. for "http://www.xyz.com/foo/bar?x=1", this will return "foo/bar".
|
|
*/
|
|
const String getSubPath() const;
|
|
|
|
/** Returns the scheme of the URL.
|
|
|
|
E.g. for "http://www.xyz.com/foobar", this will return "http". (It won't
|
|
include the colon).
|
|
*/
|
|
const String getScheme() const;
|
|
|
|
/** Returns a new version of this URL that uses a different sub-path.
|
|
|
|
E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with
|
|
"bar", it'll return "http://www.xyz.com/bar?x=1".
|
|
*/
|
|
const URL withNewSubPath (const String& newPath) const;
|
|
|
|
/** Returns a copy of this URL, with a GET parameter added to the end.
|
|
|
|
Any control characters in the value will be encoded.
|
|
|
|
e.g. calling "withParameter ("amount", "some fish") for the url "www.fish.com"
|
|
would produce a new url whose toString(true) method would return
|
|
"www.fish.com?amount=some+fish".
|
|
*/
|
|
const URL withParameter (const String& parameterName,
|
|
const String& parameterValue) const;
|
|
|
|
/** Returns a copy of this URl, with a file-upload type parameter added to it.
|
|
|
|
When performing a POST where one of your parameters is a binary file, this
|
|
lets you specify the file.
|
|
|
|
Note that the filename is stored, but the file itself won't actually be read
|
|
until this URL is later used to create a network input stream.
|
|
*/
|
|
const URL withFileToUpload (const String& parameterName,
|
|
const File& fileToUpload,
|
|
const String& mimeType) const;
|
|
|
|
/** Returns a set of all the parameters encoded into the url.
|
|
|
|
E.g. for the url "www.fish.com?type=haddock&amount=some+fish", this array would
|
|
contain two pairs: "type" => "haddock" and "amount" => "some fish".
|
|
|
|
The values returned will have been cleaned up to remove any escape characters.
|
|
|
|
@see getNamedParameter, withParameter
|
|
*/
|
|
const StringPairArray& getParameters() const throw();
|
|
|
|
/** Returns the set of files that should be uploaded as part of a POST operation.
|
|
|
|
This is the set of files that were added to the URL with the withFileToUpload()
|
|
method.
|
|
*/
|
|
const StringPairArray& getFilesToUpload() const throw();
|
|
|
|
/** Returns the set of mime types associated with each of the upload files.
|
|
*/
|
|
const StringPairArray& getMimeTypesOfUploadFiles() const throw();
|
|
|
|
/** Returns a copy of this URL, with a block of data to send as the POST data.
|
|
|
|
If you're setting the POST data, be careful not to have any parameters set
|
|
as well, otherwise it'll all get thrown in together, and might not have the
|
|
desired effect.
|
|
|
|
If the URL already contains some POST data, this will replace it, rather
|
|
than being appended to it.
|
|
|
|
This data will only be used if you specify a post operation when you call
|
|
createInputStream().
|
|
*/
|
|
const URL withPOSTData (const String& postData) const;
|
|
|
|
/** Returns the data that was set using withPOSTData().
|
|
*/
|
|
const String getPostData() const throw() { return postData; }
|
|
|
|
/** Tries to launch the system's default browser to open the URL.
|
|
|
|
Returns true if this seems to have worked.
|
|
*/
|
|
bool launchInDefaultBrowser() const;
|
|
|
|
/** Takes a guess as to whether a string might be a valid website address.
|
|
|
|
This isn't foolproof!
|
|
*/
|
|
static bool isProbablyAWebsiteURL (const String& possibleURL);
|
|
|
|
/** Takes a guess as to whether a string might be a valid email address.
|
|
|
|
This isn't foolproof!
|
|
*/
|
|
static bool isProbablyAnEmailAddress (const String& possibleEmailAddress);
|
|
|
|
/** This callback function can be used by the createInputStream() method.
|
|
|
|
It allows your app to receive progress updates during a lengthy POST operation. If you
|
|
want to continue the operation, this should return true, or false to abort.
|
|
*/
|
|
typedef bool (OpenStreamProgressCallback) (void* context, int bytesSent, int totalBytes);
|
|
|
|
/** Attempts to open a stream that can read from this URL.
|
|
|
|
@param usePostCommand if true, it will try to do use a http 'POST' to pass
|
|
the paramters, otherwise it'll encode them into the
|
|
URL and do a 'GET'.
|
|
@param progressCallback if this is non-zero, it lets you supply a callback function
|
|
to keep track of the operation's progress. This can be useful
|
|
for lengthy POST operations, so that you can provide user feedback.
|
|
@param progressCallbackContext if a callback is specified, this value will be passed to
|
|
the function
|
|
@param extraHeaders if not empty, this string is appended onto the headers that
|
|
are used for the request. It must therefore be a valid set of HTML
|
|
header directives, separated by newlines.
|
|
@param connectionTimeOutMs if 0, this will use whatever default setting the OS chooses. If
|
|
a negative number, it will be infinite. Otherwise it specifies a
|
|
time in milliseconds.
|
|
*/
|
|
InputStream* createInputStream (const bool usePostCommand,
|
|
OpenStreamProgressCallback* const progressCallback = 0,
|
|
void* const progressCallbackContext = 0,
|
|
const String& extraHeaders = String::empty,
|
|
const int connectionTimeOutMs = 0) const;
|
|
|
|
/** Tries to download the entire contents of this URL into a binary data block.
|
|
|
|
If it succeeds, this will return true and append the data it read onto the end
|
|
of the memory block.
|
|
|
|
@param destData the memory block to append the new data to
|
|
@param usePostCommand whether to use a POST command to get the data (uses
|
|
a GET command if this is false)
|
|
@see readEntireTextStream, readEntireXmlStream
|
|
*/
|
|
bool readEntireBinaryStream (MemoryBlock& destData,
|
|
const bool usePostCommand = false) const;
|
|
|
|
/** Tries to download the entire contents of this URL as a string.
|
|
|
|
If it fails, this will return an empty string, otherwise it will return the
|
|
contents of the downloaded file. If you need to distinguish between a read
|
|
operation that fails and one that returns an empty string, you'll need to use
|
|
a different method, such as readEntireBinaryStream().
|
|
|
|
@param usePostCommand whether to use a POST command to get the data (uses
|
|
a GET command if this is false)
|
|
@see readEntireBinaryStream, readEntireXmlStream
|
|
*/
|
|
const String readEntireTextStream (const bool usePostCommand = false) const;
|
|
|
|
/** Tries to download the entire contents of this URL and parse it as XML.
|
|
|
|
If it fails, or if the text that it reads can't be parsed as XML, this will
|
|
return 0.
|
|
|
|
When it returns a valid XmlElement object, the caller is responsibile for deleting
|
|
this object when no longer needed.
|
|
|
|
@param usePostCommand whether to use a POST command to get the data (uses
|
|
a GET command if this is false)
|
|
|
|
@see readEntireBinaryStream, readEntireTextStream
|
|
*/
|
|
XmlElement* readEntireXmlStream (const bool usePostCommand = false) const;
|
|
|
|
/** Adds escape sequences to a string to encode any characters that aren't
|
|
legal in a URL.
|
|
|
|
E.g. any spaces will be replaced with "%20".
|
|
|
|
This is the opposite of removeEscapeChars().
|
|
|
|
If isParameter is true, it means that the string is going to be used
|
|
as a parameter, so it also encodes '$' and ',' (which would otherwise
|
|
be legal in a URL.
|
|
|
|
@see removeEscapeChars
|
|
*/
|
|
static const String addEscapeChars (const String& stringToAddEscapeCharsTo,
|
|
const bool isParameter);
|
|
|
|
/** Replaces any escape character sequences in a string with their original
|
|
character codes.
|
|
|
|
E.g. any instances of "%20" will be replaced by a space.
|
|
|
|
This is the opposite of addEscapeChars().
|
|
|
|
@see addEscapeChars
|
|
*/
|
|
static const String removeEscapeChars (const String& stringToRemoveEscapeCharsFrom);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
String url, postData;
|
|
StringPairArray parameters, filesToUpload, mimeTypes;
|
|
};
|
|
|
|
#endif // __JUCE_URL_JUCEHEADER__
|
|
/********* End of inlined file: juce_URL.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_BufferedInputStream.h *********/
|
|
#ifndef __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__
|
|
#define __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__
|
|
|
|
/** Wraps another input stream, and reads from it using an intermediate buffer
|
|
|
|
If you're using an input stream such as a file input stream, and making lots of
|
|
small read accesses to it, it's probably sensible to wrap it in one of these,
|
|
so that the source stream gets accessed in larger chunk sizes, meaning less
|
|
work for the underlying stream.
|
|
*/
|
|
class JUCE_API BufferedInputStream : public InputStream
|
|
{
|
|
public:
|
|
|
|
/** Creates a BufferedInputStream from an input source.
|
|
|
|
@param sourceStream the source stream to read from
|
|
@param bufferSize the size of reservoir to use to buffer the source
|
|
@param deleteSourceWhenDestroyed whether the sourceStream that is passed in should be
|
|
deleted by this object when it is itself deleted.
|
|
*/
|
|
BufferedInputStream (InputStream* const sourceStream,
|
|
const int bufferSize,
|
|
const bool deleteSourceWhenDestroyed) throw();
|
|
|
|
/** Destructor.
|
|
|
|
This may also delete the source stream, if that option was chosen when the
|
|
buffered stream was created.
|
|
*/
|
|
~BufferedInputStream() throw();
|
|
|
|
int64 getTotalLength();
|
|
int64 getPosition();
|
|
bool setPosition (int64 newPosition);
|
|
int read (void* destBuffer, int maxBytesToRead);
|
|
const String readString();
|
|
bool isExhausted();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
InputStream* const source;
|
|
const bool deleteSourceWhenDestroyed;
|
|
int bufferSize;
|
|
int64 position, lastReadPos, bufferStart, bufferOverlap;
|
|
char* buffer;
|
|
void ensureBuffered();
|
|
|
|
BufferedInputStream (const BufferedInputStream&);
|
|
const BufferedInputStream& operator= (const BufferedInputStream&);
|
|
};
|
|
|
|
#endif // __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__
|
|
/********* End of inlined file: juce_BufferedInputStream.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILEINPUTSOURCE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileInputSource.h *********/
|
|
#ifndef __JUCE_FILEINPUTSOURCE_JUCEHEADER__
|
|
#define __JUCE_FILEINPUTSOURCE_JUCEHEADER__
|
|
|
|
/**
|
|
A type of InputSource that represents a normal file.
|
|
|
|
@see InputSource
|
|
*/
|
|
class JUCE_API FileInputSource : public InputSource
|
|
{
|
|
public:
|
|
|
|
FileInputSource (const File& file) throw();
|
|
~FileInputSource();
|
|
|
|
InputStream* createInputStream();
|
|
InputStream* createInputStreamFor (const String& relatedItemPath);
|
|
int64 hashCode() const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
const File file;
|
|
|
|
FileInputSource (const FileInputSource&);
|
|
const FileInputSource& operator= (const FileInputSource&);
|
|
};
|
|
|
|
#endif // __JUCE_FILEINPUTSOURCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileInputSource.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_GZIPCOMPRESSOROUTPUTSTREAM_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_GZIPCompressorOutputStream.h *********/
|
|
#ifndef __JUCE_GZIPCOMPRESSOROUTPUTSTREAM_JUCEHEADER__
|
|
#define __JUCE_GZIPCOMPRESSOROUTPUTSTREAM_JUCEHEADER__
|
|
|
|
/**
|
|
A stream which uses zlib to compress the data written into it.
|
|
|
|
@see GZIPDecompressorInputStream
|
|
*/
|
|
class JUCE_API GZIPCompressorOutputStream : public OutputStream
|
|
{
|
|
public:
|
|
|
|
/** Creates a compression stream.
|
|
|
|
@param destStream the stream into which the compressed data should
|
|
be written
|
|
@param compressionLevel how much to compress the data, between 1 and 9, where
|
|
1 is the fastest/lowest compression, and 9 is the
|
|
slowest/highest compression. Any value outside this range
|
|
indicates that a default compression level should be used.
|
|
@param deleteDestStreamWhenDestroyed whether or not to delete the destStream object when
|
|
this stream is destroyed
|
|
@param noWrap this is used internally by the ZipFile class
|
|
and should be ignored by user applications
|
|
*/
|
|
GZIPCompressorOutputStream (OutputStream* const destStream,
|
|
int compressionLevel = 0,
|
|
const bool deleteDestStreamWhenDestroyed = false,
|
|
const bool noWrap = false);
|
|
|
|
/** Destructor. */
|
|
~GZIPCompressorOutputStream();
|
|
|
|
void flush();
|
|
int64 getPosition();
|
|
bool setPosition (int64 newPosition);
|
|
bool write (const void* destBuffer, int howMany);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
OutputStream* const destStream;
|
|
const bool deleteDestStream;
|
|
uint8* buffer;
|
|
void* helper;
|
|
bool doNextBlock();
|
|
|
|
GZIPCompressorOutputStream (const GZIPCompressorOutputStream&);
|
|
const GZIPCompressorOutputStream& operator= (const GZIPCompressorOutputStream&);
|
|
};
|
|
|
|
#endif // __JUCE_GZIPCOMPRESSOROUTPUTSTREAM_JUCEHEADER__
|
|
/********* End of inlined file: juce_GZIPCompressorOutputStream.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_GZIPDECOMPRESSORINPUTSTREAM_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_GZIPDecompressorInputStream.h *********/
|
|
#ifndef __JUCE_GZIPDECOMPRESSORINPUTSTREAM_JUCEHEADER__
|
|
#define __JUCE_GZIPDECOMPRESSORINPUTSTREAM_JUCEHEADER__
|
|
|
|
/**
|
|
This stream will decompress a source-stream using zlib.
|
|
|
|
Tip: if you're reading lots of small items from one of these streams, you
|
|
can increase the performance enormously by passing it through a
|
|
BufferedInputStream, so that it has to read larger blocks less often.
|
|
|
|
@see GZIPCompressorOutputStream
|
|
*/
|
|
class JUCE_API GZIPDecompressorInputStream : public InputStream
|
|
{
|
|
public:
|
|
|
|
/** Creates a decompressor stream.
|
|
|
|
@param sourceStream the stream to read from
|
|
@param deleteSourceWhenDestroyed whether or not to delete the source stream
|
|
when this object is destroyed
|
|
@param noWrap this is used internally by the ZipFile class
|
|
and should be ignored by user applications
|
|
@param uncompressedStreamLength if the creator knows the length that the
|
|
uncompressed stream will be, then it can supply this
|
|
value, which will be returned by getTotalLength()
|
|
*/
|
|
GZIPDecompressorInputStream (InputStream* const sourceStream,
|
|
const bool deleteSourceWhenDestroyed,
|
|
const bool noWrap = false,
|
|
const int64 uncompressedStreamLength = -1);
|
|
|
|
/** Destructor. */
|
|
~GZIPDecompressorInputStream();
|
|
|
|
int64 getPosition();
|
|
bool setPosition (int64 pos);
|
|
int64 getTotalLength();
|
|
bool isExhausted();
|
|
int read (void* destBuffer, int maxBytesToRead);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
InputStream* const sourceStream;
|
|
const int64 uncompressedStreamLength;
|
|
const bool deleteSourceWhenDestroyed, noWrap;
|
|
bool isEof;
|
|
int activeBufferSize;
|
|
int64 originalSourcePos, currentPos;
|
|
uint8* buffer;
|
|
void* helper;
|
|
|
|
GZIPDecompressorInputStream (const GZIPDecompressorInputStream&);
|
|
const GZIPDecompressorInputStream& operator= (const GZIPDecompressorInputStream&);
|
|
};
|
|
|
|
#endif // __JUCE_GZIPDECOMPRESSORINPUTSTREAM_JUCEHEADER__
|
|
/********* End of inlined file: juce_GZIPDecompressorInputStream.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_INPUTSOURCE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_INPUTSTREAM_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MEMORYINPUTSTREAM_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MemoryInputStream.h *********/
|
|
#ifndef __JUCE_MEMORYINPUTSTREAM_JUCEHEADER__
|
|
#define __JUCE_MEMORYINPUTSTREAM_JUCEHEADER__
|
|
|
|
/**
|
|
Allows a block of data and to be accessed as a stream.
|
|
|
|
This can either be used to refer to a shared block of memory, or can make its
|
|
own internal copy of the data when the MemoryInputStream is created.
|
|
*/
|
|
class JUCE_API MemoryInputStream : public InputStream
|
|
{
|
|
public:
|
|
|
|
/** Creates a MemoryInputStream.
|
|
|
|
@param sourceData the block of data to use as the stream's source
|
|
@param sourceDataSize the number of bytes in the source data block
|
|
@param keepInternalCopyOfData if false, the stream will just keep a pointer to
|
|
the source data, so this data shouldn't be changed
|
|
for the lifetime of the stream; if this parameter is
|
|
true, the stream will make its own copy of the
|
|
data and use that.
|
|
*/
|
|
MemoryInputStream (const void* const sourceData,
|
|
const int sourceDataSize,
|
|
const bool keepInternalCopyOfData) throw();
|
|
|
|
/** Destructor. */
|
|
~MemoryInputStream() throw();
|
|
|
|
int64 getPosition();
|
|
bool setPosition (int64 pos);
|
|
int64 getTotalLength();
|
|
bool isExhausted();
|
|
int read (void* destBuffer, int maxBytesToRead);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
const char* data;
|
|
int dataSize, position;
|
|
MemoryBlock internalCopy;
|
|
};
|
|
|
|
#endif // __JUCE_MEMORYINPUTSTREAM_JUCEHEADER__
|
|
/********* End of inlined file: juce_MemoryInputStream.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MEMORYOUTPUTSTREAM_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MemoryOutputStream.h *********/
|
|
#ifndef __JUCE_MEMORYOUTPUTSTREAM_JUCEHEADER__
|
|
#define __JUCE_MEMORYOUTPUTSTREAM_JUCEHEADER__
|
|
|
|
/** Writes data to an internal memory buffer, which grows as required.
|
|
|
|
The data that was written into the stream can then be accessed later as
|
|
a contiguous block of memory.
|
|
*/
|
|
class JUCE_API MemoryOutputStream : public OutputStream
|
|
{
|
|
public:
|
|
|
|
/** Creates a memory stream ready for writing into.
|
|
|
|
@param initialSize the intial amount of space to allocate for writing into
|
|
@param granularity the increments by which the internal storage will be increased
|
|
@param memoryBlockToWriteTo if this is non-zero, then this block will be used as the
|
|
place that the data gets stored. If it's zero, the stream
|
|
will allocate its own storage internally, which you can
|
|
access using getData() and getDataSize()
|
|
*/
|
|
MemoryOutputStream (const int initialSize = 256,
|
|
const int granularity = 256,
|
|
MemoryBlock* const memoryBlockToWriteTo = 0) throw();
|
|
|
|
/** Destructor.
|
|
|
|
This will free any data that was written to it.
|
|
*/
|
|
~MemoryOutputStream() throw();
|
|
|
|
/** Returns a pointer to the data that has been written to the stream.
|
|
|
|
@see getDataSize
|
|
*/
|
|
const char* getData() throw();
|
|
|
|
/** Returns the number of bytes of data that have been written to the stream.
|
|
|
|
@see getData
|
|
*/
|
|
int getDataSize() const throw();
|
|
|
|
/** Resets the stream, clearing any data that has been written to it so far. */
|
|
void reset() throw();
|
|
|
|
void flush();
|
|
bool write (const void* buffer, int howMany);
|
|
int64 getPosition();
|
|
bool setPosition (int64 newPosition);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
MemoryBlock* data;
|
|
int position, size, blockSize;
|
|
bool ownsMemoryBlock;
|
|
};
|
|
|
|
#endif // __JUCE_MEMORYOUTPUTSTREAM_JUCEHEADER__
|
|
/********* End of inlined file: juce_MemoryOutputStream.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_OUTPUTSTREAM_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_SUBREGIONSTREAM_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_SubregionStream.h *********/
|
|
#ifndef __JUCE_SUBREGIONSTREAM_JUCEHEADER__
|
|
#define __JUCE_SUBREGIONSTREAM_JUCEHEADER__
|
|
|
|
/** Wraps another input stream, and reads from a specific part of it.
|
|
|
|
This lets you take a subsection of a stream and present it as an entire
|
|
stream in its own right.
|
|
*/
|
|
class JUCE_API SubregionStream : public InputStream
|
|
{
|
|
public:
|
|
|
|
/** Creates a SubregionStream from an input source.
|
|
|
|
@param sourceStream the source stream to read from
|
|
@param startPositionInSourceStream this is the position in the source stream that
|
|
corresponds to position 0 in this stream
|
|
@param lengthOfSourceStream this specifies the maximum number of bytes
|
|
from the source stream that will be passed through
|
|
by this stream. When the position of this stream
|
|
exceeds lengthOfSourceStream, it will cause an end-of-stream.
|
|
If the length passed in here is greater than the length
|
|
of the source stream (as returned by getTotalLength()),
|
|
then the smaller value will be used.
|
|
Passing a negative value for this parameter means it
|
|
will keep reading until the source's end-of-stream.
|
|
@param deleteSourceWhenDestroyed whether the sourceStream that is passed in should be
|
|
deleted by this object when it is itself deleted.
|
|
*/
|
|
SubregionStream (InputStream* const sourceStream,
|
|
const int64 startPositionInSourceStream,
|
|
const int64 lengthOfSourceStream,
|
|
const bool deleteSourceWhenDestroyed) throw();
|
|
|
|
/** Destructor.
|
|
|
|
This may also delete the source stream, if that option was chosen when the
|
|
buffered stream was created.
|
|
*/
|
|
~SubregionStream() throw();
|
|
|
|
int64 getTotalLength();
|
|
int64 getPosition();
|
|
bool setPosition (int64 newPosition);
|
|
int read (void* destBuffer, int maxBytesToRead);
|
|
bool isExhausted();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
InputStream* const source;
|
|
const bool deleteSourceWhenDestroyed;
|
|
const int64 startPositionInSourceStream, lengthOfSourceStream;
|
|
|
|
SubregionStream (const SubregionStream&);
|
|
const SubregionStream& operator= (const SubregionStream&);
|
|
};
|
|
|
|
#endif // __JUCE_SUBREGIONSTREAM_JUCEHEADER__
|
|
/********* End of inlined file: juce_SubregionStream.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_LOCALISEDSTRINGS_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_LocalisedStrings.h *********/
|
|
#ifndef __JUCE_LOCALISEDSTRINGS_JUCEHEADER__
|
|
#define __JUCE_LOCALISEDSTRINGS_JUCEHEADER__
|
|
|
|
/** Used in the same way as the T(text) macro, this will attempt to translate a
|
|
string into a localised version using the LocalisedStrings class.
|
|
|
|
@see LocalisedStrings
|
|
*/
|
|
#define TRANS(stringLiteral) \
|
|
LocalisedStrings::translateWithCurrentMappings (stringLiteral)
|
|
|
|
/**
|
|
Used to convert strings to localised foreign-language versions.
|
|
|
|
This is basically a look-up table of strings and their translated equivalents.
|
|
It can be loaded from a text file, so that you can supply a set of localised
|
|
versions of strings that you use in your app.
|
|
|
|
To use it in your code, simply call the translate() method on each string that
|
|
might have foreign versions, and if none is found, the method will just return
|
|
the original string.
|
|
|
|
The translation file should start with some lines specifying a description of
|
|
the language it contains, and also a list of ISO country codes where it might
|
|
be appropriate to use the file. After that, each line of the file should contain
|
|
a pair of quoted strings with an '=' sign.
|
|
|
|
E.g. for a french translation, the file might be:
|
|
|
|
@code
|
|
language: French
|
|
countries: fr be mc ch lu
|
|
|
|
"hello" = "bonjour"
|
|
"goodbye" = "au revoir"
|
|
@endcode
|
|
|
|
If the strings need to contain a quote character, they can use '\"' instead, and
|
|
if the first non-whitespace character on a line isn't a quote, then it's ignored,
|
|
(you can use this to add comments).
|
|
|
|
Note that this is a singleton class, so don't create or destroy the object directly.
|
|
There's also a TRANS(text) macro defined to make it easy to use the this.
|
|
|
|
E.g. @code
|
|
printSomething (TRANS("hello"));
|
|
@endcode
|
|
|
|
This macro is used in the Juce classes themselves, so your application has a chance to
|
|
intercept and translate any internal Juce text strings that might be shown. (You can easily
|
|
get a list of all the messages by searching for the TRANS() macro in the Juce source
|
|
code).
|
|
*/
|
|
class JUCE_API LocalisedStrings
|
|
{
|
|
public:
|
|
|
|
/** Creates a set of translations from the text of a translation file.
|
|
|
|
When you create one of these, you can call setCurrentMappings() to make it
|
|
the set of mappings that the system's using.
|
|
*/
|
|
LocalisedStrings (const String& fileContents) throw();
|
|
|
|
/** Creates a set of translations from a file.
|
|
|
|
When you create one of these, you can call setCurrentMappings() to make it
|
|
the set of mappings that the system's using.
|
|
*/
|
|
LocalisedStrings (const File& fileToLoad) throw();
|
|
|
|
/** Destructor. */
|
|
~LocalisedStrings() throw();
|
|
|
|
/** Selects the current set of mappings to be used by the system.
|
|
|
|
The object you pass in will be automatically deleted when no longer needed, so
|
|
don't keep a pointer to it. You can also pass in zero to remove the current
|
|
mappings.
|
|
|
|
See also the TRANS() macro, which uses the current set to do its translation.
|
|
|
|
@see translateWithCurrentMappings
|
|
*/
|
|
static void setCurrentMappings (LocalisedStrings* newTranslations) throw();
|
|
|
|
/** Returns the currently selected set of mappings.
|
|
|
|
This is the object that was last passed to setCurrentMappings(). It may
|
|
be 0 if none has been created.
|
|
*/
|
|
static LocalisedStrings* getCurrentMappings() throw();
|
|
|
|
/** Tries to translate a string using the currently selected set of mappings.
|
|
|
|
If no mapping has been set, or if the mapping doesn't contain a translation
|
|
for the string, this will just return the original string.
|
|
|
|
See also the TRANS() macro, which uses this method to do its translation.
|
|
|
|
@see setCurrentMappings, getCurrentMappings
|
|
*/
|
|
static const String translateWithCurrentMappings (const String& text) throw();
|
|
|
|
/** Tries to translate a string using the currently selected set of mappings.
|
|
|
|
If no mapping has been set, or if the mapping doesn't contain a translation
|
|
for the string, this will just return the original string.
|
|
|
|
See also the TRANS() macro, which uses this method to do its translation.
|
|
|
|
@see setCurrentMappings, getCurrentMappings
|
|
*/
|
|
static const String translateWithCurrentMappings (const char* text) throw();
|
|
|
|
/** Attempts to look up a string and return its localised version.
|
|
|
|
If the string isn't found in the list, the original string will be returned.
|
|
*/
|
|
const String translate (const String& text) const throw();
|
|
|
|
/** Returns the name of the language specified in the translation file.
|
|
|
|
This is specified in the file using a line starting with "language:", e.g.
|
|
@code
|
|
language: german
|
|
@endcode
|
|
*/
|
|
const String getLanguageName() const throw() { return languageName; }
|
|
|
|
/** Returns the list of suitable country codes listed in the translation file.
|
|
|
|
These is specified in the file using a line starting with "countries:", e.g.
|
|
@code
|
|
countries: fr be mc ch lu
|
|
@endcode
|
|
|
|
The country codes are supposed to be 2-character ISO complient codes.
|
|
*/
|
|
const StringArray getCountryCodes() const throw() { return countryCodes; }
|
|
|
|
/** Indicates whether to use a case-insensitive search when looking up a string.
|
|
This defaults to true.
|
|
*/
|
|
void setIgnoresCase (const bool shouldIgnoreCase) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
String languageName;
|
|
StringArray countryCodes;
|
|
StringPairArray translations;
|
|
|
|
void loadFromText (const String& fileContents) throw();
|
|
};
|
|
|
|
#endif // __JUCE_LOCALISEDSTRINGS_JUCEHEADER__
|
|
/********* End of inlined file: juce_LocalisedStrings.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_STRING_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_STRINGARRAY_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_STRINGPAIRARRAY_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_XMLDOCUMENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_XmlDocument.h *********/
|
|
#ifndef __JUCE_XMLDOCUMENT_JUCEHEADER__
|
|
#define __JUCE_XMLDOCUMENT_JUCEHEADER__
|
|
|
|
/**
|
|
Parses a text-based XML document and creates an XmlElement object from it.
|
|
|
|
The parser will parse DTDs to load external entities but won't
|
|
check the document for validity against the DTD.
|
|
|
|
e.g.
|
|
@code
|
|
|
|
XmlDocument myDocument (File ("myfile.xml"));
|
|
XmlElement* mainElement = myDocument.getDocumentElement();
|
|
|
|
if (mainElement == 0)
|
|
{
|
|
String error = myDocument.getLastParseError();
|
|
}
|
|
else
|
|
{
|
|
..use the element
|
|
}
|
|
|
|
@endcode
|
|
|
|
@see XmlElement
|
|
*/
|
|
class JUCE_API XmlDocument
|
|
{
|
|
public:
|
|
|
|
/** Creates an XmlDocument from the xml text.
|
|
|
|
The text doesn't actually get parsed until the getDocumentElement() method is
|
|
called.
|
|
*/
|
|
XmlDocument (const String& documentText) throw();
|
|
|
|
/** Creates an XmlDocument from a file.
|
|
|
|
The text doesn't actually get parsed until the getDocumentElement() method is
|
|
called.
|
|
*/
|
|
XmlDocument (const File& file);
|
|
|
|
/** Destructor. */
|
|
~XmlDocument() throw();
|
|
|
|
/** Creates an XmlElement object to represent the main document node.
|
|
|
|
This method will do the actual parsing of the text, and if there's a
|
|
parse error, it may returns 0 (and you can find out the error using
|
|
the getLastParseError() method).
|
|
|
|
@param onlyReadOuterDocumentElement if true, the parser will only read the
|
|
first section of the file, and will only
|
|
return the outer document element - this
|
|
allows quick checking of large files to
|
|
see if they contain the correct type of
|
|
tag, without having to parse the entire file
|
|
@returns a new XmlElement which the caller will need to delete, or null if
|
|
there was an error.
|
|
@see getLastParseError
|
|
*/
|
|
XmlElement* getDocumentElement (const bool onlyReadOuterDocumentElement = false);
|
|
|
|
/** Returns the parsing error that occurred the last time getDocumentElement was called.
|
|
|
|
@returns the error, or an empty string if there was no error.
|
|
*/
|
|
const String& getLastParseError() const throw();
|
|
|
|
/** Sets an input source object to use for parsing documents that reference external entities.
|
|
|
|
If the document has been created from a file, this probably won't be needed, but
|
|
if you're parsing some text and there might be a DTD that references external
|
|
files, you may need to create a custom input source that can retrieve the
|
|
other files it needs.
|
|
|
|
The object that is passed-in will be deleted automatically when no longer needed.
|
|
|
|
@see InputSource
|
|
*/
|
|
void setInputSource (InputSource* const newSource) throw();
|
|
|
|
/** Sets a flag to change the treatment of empty text elements.
|
|
|
|
If this is true (the default state), then any text elements that contain only
|
|
whitespace characters will be ingored during parsing. If you need to catch
|
|
whitespace-only text, then you should set this to false before calling the
|
|
getDocumentElement() method.
|
|
*/
|
|
void setEmptyTextElementsIgnored (const bool shouldBeIgnored) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
String originalText;
|
|
const tchar* input;
|
|
bool outOfData, errorOccurred;
|
|
|
|
bool identifierLookupTable [128];
|
|
String lastError, dtdText;
|
|
StringArray tokenisedDTD;
|
|
bool needToLoadDTD, ignoreEmptyTextElements;
|
|
InputSource* inputSource;
|
|
|
|
void setLastError (const String& desc, const bool carryOn) throw();
|
|
void skipHeader() throw();
|
|
void skipNextWhiteSpace() throw();
|
|
tchar readNextChar() throw();
|
|
XmlElement* readNextElement (const bool alsoParseSubElements) throw();
|
|
void readChildElements (XmlElement* parent) throw();
|
|
int findNextTokenLength() throw();
|
|
void readQuotedString (String& result) throw();
|
|
void readEntity (String& result) throw();
|
|
|
|
const String getFileContents (const String& filename) const;
|
|
const String expandEntity (const String& entity);
|
|
const String expandExternalEntity (const String& entity);
|
|
const String getParameterEntity (const String& entity);
|
|
};
|
|
|
|
#endif // __JUCE_XMLDOCUMENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_XmlDocument.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_XMLELEMENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_CRITICALSECTION_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_INTERPROCESSLOCK_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_InterProcessLock.h *********/
|
|
#ifndef __JUCE_INTERPROCESSLOCK_JUCEHEADER__
|
|
#define __JUCE_INTERPROCESSLOCK_JUCEHEADER__
|
|
|
|
/**
|
|
Acts as a critical section which processes can use to block each other.
|
|
|
|
@see CriticalSection
|
|
*/
|
|
class JUCE_API InterProcessLock
|
|
{
|
|
public:
|
|
|
|
/** Creates a lock object.
|
|
|
|
@param name a name that processes will use to identify this lock object
|
|
*/
|
|
InterProcessLock (const String& name) throw();
|
|
|
|
/** Destructor.
|
|
|
|
This will also release the lock if it's currently held by this process.
|
|
*/
|
|
~InterProcessLock() throw();
|
|
|
|
/** Attempts to lock the critical section.
|
|
|
|
@param timeOutMillisecs how many milliseconds to wait if the lock
|
|
is already held by another process - a value of
|
|
0 will return immediately, negative values will wait
|
|
forever
|
|
@returns true if the lock could be gained within the timeout period, or
|
|
false if the timeout expired.
|
|
*/
|
|
bool enter (int timeOutMillisecs = -1) throw();
|
|
|
|
/** Releases the lock if it's currently held by this process.
|
|
*/
|
|
void exit() throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
void* internal;
|
|
String name;
|
|
int reentrancyLevel;
|
|
|
|
InterProcessLock (const InterProcessLock&);
|
|
const InterProcessLock& operator= (const InterProcessLock&);
|
|
};
|
|
|
|
#endif // __JUCE_INTERPROCESSLOCK_JUCEHEADER__
|
|
/********* End of inlined file: juce_InterProcessLock.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_PROCESS_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Process.h *********/
|
|
#ifndef __JUCE_PROCESS_JUCEHEADER__
|
|
#define __JUCE_PROCESS_JUCEHEADER__
|
|
|
|
/** Represents the current executable's process.
|
|
|
|
This contains methods for controlling the current application at the
|
|
process-level.
|
|
|
|
@see Thread, JUCEApplication
|
|
*/
|
|
class JUCE_API Process
|
|
{
|
|
public:
|
|
|
|
enum ProcessPriority
|
|
{
|
|
LowPriority = 0,
|
|
NormalPriority = 1,
|
|
HighPriority = 2,
|
|
RealtimePriority = 3
|
|
};
|
|
|
|
/** Changes the current process's priority.
|
|
|
|
@param priority the process priority, where
|
|
0=low, 1=normal, 2=high, 3=realtime
|
|
*/
|
|
static void setPriority (const ProcessPriority priority);
|
|
|
|
/** Kills the current process immediately.
|
|
|
|
This is an emergency process terminator that kills the application
|
|
immediately - it's intended only for use only when something goes
|
|
horribly wrong.
|
|
|
|
@see JUCEApplication::quit
|
|
*/
|
|
static void terminate();
|
|
|
|
/** Returns true if this application process is the one that the user is
|
|
currently using.
|
|
*/
|
|
static bool isForegroundProcess() throw();
|
|
|
|
/** Raises the current process's privilege level.
|
|
|
|
Does nothing if this isn't supported by the current OS, or if process
|
|
privilege level is fixed.
|
|
*/
|
|
static void raisePrivilege();
|
|
|
|
/** Lowers the current process's privilege level.
|
|
|
|
Does nothing if this isn't supported by the current OS, or if process
|
|
privilege level is fixed.
|
|
*/
|
|
static void lowerPrivilege();
|
|
|
|
/** Returns true if this process is being hosted by a debugger.
|
|
*/
|
|
static bool JUCE_CALLTYPE isRunningUnderDebugger() throw();
|
|
};
|
|
|
|
#endif // __JUCE_PROCESS_JUCEHEADER__
|
|
/********* End of inlined file: juce_Process.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_READWRITELOCK_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ReadWriteLock.h *********/
|
|
#ifndef __JUCE_READWRITELOCK_JUCEHEADER__
|
|
#define __JUCE_READWRITELOCK_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_WaitableEvent.h *********/
|
|
#ifndef __JUCE_WAITABLEEVENT_JUCEHEADER__
|
|
#define __JUCE_WAITABLEEVENT_JUCEHEADER__
|
|
|
|
/**
|
|
Allows threads to wait for events triggered by other threads.
|
|
|
|
A thread can call wait() on a WaitableObject, and this will suspend the
|
|
calling thread until another thread wakes it up by calling the signal()
|
|
method.
|
|
*/
|
|
class JUCE_API WaitableEvent
|
|
{
|
|
public:
|
|
|
|
/** Creates a WaitableEvent object. */
|
|
WaitableEvent() throw();
|
|
|
|
/** Destructor.
|
|
|
|
If other threads are waiting on this object when it gets deleted, this
|
|
can cause nasty errors, so be careful!
|
|
*/
|
|
~WaitableEvent() throw();
|
|
|
|
/** Suspends the calling thread until the event has been signalled.
|
|
|
|
This will wait until the object's signal() method is called by another thread,
|
|
or until the timeout expires.
|
|
|
|
After the event has been signalled, this method will return true and reset
|
|
the event.
|
|
|
|
@param timeOutMilliseconds the maximum time to wait, in milliseconds. A negative
|
|
value will cause it to wait forever.
|
|
|
|
@returns true if the object has been signalled, false if the timeout expires first.
|
|
@see signal, reset
|
|
*/
|
|
bool wait (const int timeOutMilliseconds = -1) const throw();
|
|
|
|
/** Wakes up any threads that are currently waiting on this object.
|
|
|
|
If signal() is called when nothing is waiting, the next thread to call wait()
|
|
will return immediately and reset the signal.
|
|
|
|
@see wait, reset
|
|
*/
|
|
void signal() const throw();
|
|
|
|
/** Resets the event to an unsignalled state.
|
|
|
|
If it's not already signalled, this does nothing.
|
|
*/
|
|
void reset() const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
void* internal;
|
|
|
|
WaitableEvent (const WaitableEvent&);
|
|
const WaitableEvent& operator= (const WaitableEvent&);
|
|
};
|
|
|
|
#endif // __JUCE_WAITABLEEVENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_WaitableEvent.h *********/
|
|
|
|
/********* Start of inlined file: juce_Thread.h *********/
|
|
#ifndef __JUCE_THREAD_JUCEHEADER__
|
|
#define __JUCE_THREAD_JUCEHEADER__
|
|
|
|
/**
|
|
Encapsulates a thread.
|
|
|
|
Subclasses derive from Thread and implement the run() method, in which they
|
|
do their business. The thread can then be started with the startThread() method
|
|
and controlled with various other methods.
|
|
|
|
This class also contains some thread-related static methods, such
|
|
as sleep(), yield(), getCurrentThreadId() etc.
|
|
|
|
@see CriticalSection, WaitableEvent, Process, ThreadWithProgressWindow,
|
|
MessageManagerLock
|
|
*/
|
|
class JUCE_API Thread
|
|
{
|
|
public:
|
|
|
|
/**
|
|
Creates a thread.
|
|
|
|
When first created, the thread is not running. Use the startThread()
|
|
method to start it.
|
|
*/
|
|
Thread (const String& threadName);
|
|
|
|
/** Destructor.
|
|
|
|
Deleting a Thread object that is running will only give the thread a
|
|
brief opportunity to stop itself cleanly, so it's recommended that you
|
|
should always call stopThread() with a decent timeout before deleting,
|
|
to avoid the thread being forcibly killed (which is a Bad Thing).
|
|
*/
|
|
virtual ~Thread();
|
|
|
|
/** Must be implemented to perform the thread's actual code.
|
|
|
|
Remember that the thread must regularly check the threadShouldExit()
|
|
method whilst running, and if this returns true it should return from
|
|
the run() method as soon as possible to avoid being forcibly killed.
|
|
|
|
@see threadShouldExit, startThread
|
|
*/
|
|
virtual void run() = 0;
|
|
|
|
// Thread control functions..
|
|
|
|
/** Starts the thread running.
|
|
|
|
This will start the thread's run() method.
|
|
(if it's already started, startThread() won't do anything).
|
|
|
|
@see stopThread
|
|
*/
|
|
void startThread() throw();
|
|
|
|
/** Starts the thread with a given priority.
|
|
|
|
Launches the thread with a given priority, where 0 = lowest, 10 = highest.
|
|
If the thread is already running, its priority will be changed.
|
|
|
|
@see startThread, setPriority
|
|
*/
|
|
void startThread (const int priority) throw();
|
|
|
|
/** Attempts to stop the thread running.
|
|
|
|
This method will cause the threadShouldExit() method to return true
|
|
and call notify() in case the thread is currently waiting.
|
|
|
|
Hopefully the thread will then respond to this by exiting cleanly, and
|
|
the stopThread method will wait for a given time-period for this to
|
|
happen.
|
|
|
|
If the thread is stuck and fails to respond after the time-out, it gets
|
|
forcibly killed, which is a very bad thing to happen, as it could still
|
|
be holding locks, etc. which are needed by other parts of your program.
|
|
|
|
@param timeOutMilliseconds The number of milliseconds to wait for the
|
|
thread to finish before killing it by force. A negative
|
|
value in here will wait forever.
|
|
@see signalThreadShouldExit, threadShouldExit, waitForThreadToExit, isThreadRunning
|
|
*/
|
|
void stopThread (const int timeOutMilliseconds) throw();
|
|
|
|
/** Returns true if the thread is currently active */
|
|
bool isThreadRunning() const throw();
|
|
|
|
/** Sets a flag to tell the thread it should stop.
|
|
|
|
Calling this means that the threadShouldExit() method will then return true.
|
|
The thread should be regularly checking this to see whether it should exit.
|
|
|
|
@see threadShouldExit
|
|
@see waitForThreadToExit
|
|
*/
|
|
void signalThreadShouldExit() throw();
|
|
|
|
/** Checks whether the thread has been told to stop running.
|
|
|
|
Threads need to check this regularly, and if it returns true, they should
|
|
return from their run() method at the first possible opportunity.
|
|
|
|
@see signalThreadShouldExit
|
|
*/
|
|
inline bool threadShouldExit() const throw() { return threadShouldExit_; }
|
|
|
|
/** Waits for the thread to stop.
|
|
|
|
This will waits until isThreadRunning() is false or until a timeout expires.
|
|
|
|
@param timeOutMilliseconds the time to wait, in milliseconds. If this value
|
|
is less than zero, it will wait forever.
|
|
@returns true if the thread exits, or false if the timeout expires first.
|
|
*/
|
|
bool waitForThreadToExit (const int timeOutMilliseconds) const throw();
|
|
|
|
/** Changes the thread's priority.
|
|
May return false if for some reason the priority can't be changed.
|
|
|
|
@param priority the new priority, in the range 0 (lowest) to 10 (highest). A priority
|
|
of 5 is normal.
|
|
*/
|
|
bool setPriority (const int priority) throw();
|
|
|
|
/** Changes the priority of the caller thread.
|
|
|
|
Similar to setPriority(), but this static method acts on the caller thread.
|
|
May return false if for some reason the priority can't be changed.
|
|
|
|
@see setPriority
|
|
*/
|
|
static bool setCurrentThreadPriority (const int priority) throw();
|
|
|
|
/** Sets the affinity mask for the thread.
|
|
|
|
This will only have an effect next time the thread is started - i.e. if the
|
|
thread is already running when called, it'll have no effect.
|
|
|
|
@see setCurrentThreadAffinityMask
|
|
*/
|
|
void setAffinityMask (const uint32 affinityMask) throw();
|
|
|
|
/** Changes the affinity mask for the caller thread.
|
|
|
|
This will change the affinity mask for the thread that calls this static method.
|
|
|
|
@see setAffinityMask
|
|
*/
|
|
static void setCurrentThreadAffinityMask (const uint32 affinityMask) throw();
|
|
|
|
// this can be called from any thread that needs to pause..
|
|
static void JUCE_CALLTYPE sleep (int milliseconds) throw();
|
|
|
|
/** Yields the calling thread's current time-slot. */
|
|
static void JUCE_CALLTYPE yield() throw();
|
|
|
|
/** Makes the thread wait for a notification.
|
|
|
|
This puts the thread to sleep until either the timeout period expires, or
|
|
another thread calls the notify() method to wake it up.
|
|
|
|
@returns true if the event has been signalled, false if the timeout expires.
|
|
*/
|
|
bool wait (const int timeOutMilliseconds) const throw();
|
|
|
|
/** Wakes up the thread.
|
|
|
|
If the thread has called the wait() method, this will wake it up.
|
|
|
|
@see wait
|
|
*/
|
|
void notify() const throw();
|
|
|
|
/** A value type used for thread IDs.
|
|
@see getCurrentThreadId(), getThreadId()
|
|
*/
|
|
typedef void* ThreadID;
|
|
|
|
/** Returns an id that identifies the caller thread.
|
|
|
|
To find the ID of a particular thread object, use getThreadId().
|
|
|
|
@returns a unique identifier that identifies the calling thread.
|
|
@see getThreadId
|
|
*/
|
|
static ThreadID getCurrentThreadId() throw();
|
|
|
|
/** Finds the thread object that is currently running.
|
|
|
|
Note that the main UI thread (or other non-Juce threads) don't have a Thread
|
|
object associated with them, so this will return 0.
|
|
*/
|
|
static Thread* getCurrentThread() throw();
|
|
|
|
/** Returns the ID of this thread.
|
|
|
|
That means the ID of this thread object - not of the thread that's calling the method.
|
|
|
|
This can change when the thread is started and stopped, and will be invalid if the
|
|
thread's not actually running.
|
|
|
|
@see getCurrentThreadId
|
|
*/
|
|
ThreadID getThreadId() const throw();
|
|
|
|
/** Returns the name of the thread.
|
|
|
|
This is the name that gets set in the constructor.
|
|
*/
|
|
const String getThreadName() const throw() { return threadName_; }
|
|
|
|
/** Returns the number of currently-running threads.
|
|
|
|
@returns the number of Thread objects known to be currently running.
|
|
@see stopAllThreads
|
|
*/
|
|
static int getNumRunningThreads() throw();
|
|
|
|
/** Tries to stop all currently-running threads.
|
|
|
|
This will attempt to stop all the threads known to be running at the moment.
|
|
*/
|
|
static void stopAllThreads (const int timeoutInMillisecs) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
const String threadName_;
|
|
void* volatile threadHandle_;
|
|
CriticalSection startStopLock;
|
|
WaitableEvent startSuspensionEvent_, defaultEvent_;
|
|
|
|
int threadPriority_;
|
|
ThreadID threadId_;
|
|
uint32 affinityMask_;
|
|
bool volatile threadShouldExit_;
|
|
|
|
friend void JUCE_API juce_threadEntryPoint (void*);
|
|
static void threadEntryPoint (Thread* thread) throw();
|
|
|
|
Thread (const Thread&);
|
|
const Thread& operator= (const Thread&);
|
|
};
|
|
|
|
#endif // __JUCE_THREAD_JUCEHEADER__
|
|
/********* End of inlined file: juce_Thread.h *********/
|
|
|
|
/**
|
|
A critical section that allows multiple simultaneous readers.
|
|
|
|
Features of this type of lock are:
|
|
|
|
- Multiple readers can hold the lock at the same time, but only one writer
|
|
can hold it at once.
|
|
- Writers trying to gain the lock will be blocked until all readers and writers
|
|
have released it
|
|
- Readers trying to gain the lock while a writer is waiting to acquire it will be
|
|
blocked until the writer has obtained and released it
|
|
- If a thread already has a read lock and tries to obtain a write lock, it will succeed if
|
|
there are no other readers
|
|
- If a thread already has the write lock and tries to obtain a read lock, this will succeed.
|
|
- Recursive locking is supported.
|
|
|
|
@see ScopedReadLock, ScopedWriteLock, CriticalSection
|
|
*/
|
|
class JUCE_API ReadWriteLock
|
|
{
|
|
public:
|
|
|
|
/**
|
|
Creates a ReadWriteLock object.
|
|
*/
|
|
ReadWriteLock() throw();
|
|
|
|
/** Destructor.
|
|
|
|
If the object is deleted whilst locked, any subsequent behaviour
|
|
is unpredictable.
|
|
*/
|
|
~ReadWriteLock() throw();
|
|
|
|
/** Locks this object for reading.
|
|
|
|
Multiple threads can simulaneously lock the object for reading, but if another
|
|
thread has it locked for writing, then this will block until it releases the
|
|
lock.
|
|
|
|
@see exitRead, ScopedReadLock
|
|
*/
|
|
void enterRead() const throw();
|
|
|
|
/** Releases the read-lock.
|
|
|
|
If the caller thread hasn't got the lock, this can have unpredictable results.
|
|
|
|
If the enterRead() method has been called multiple times by the thread, each
|
|
call must be matched by a call to exitRead() before other threads will be allowed
|
|
to take over the lock.
|
|
|
|
@see enterRead, ScopedReadLock
|
|
*/
|
|
void exitRead() const throw();
|
|
|
|
/** Locks this object for writing.
|
|
|
|
This will block until any other threads that have it locked for reading or
|
|
writing have released their lock.
|
|
|
|
@see exitWrite, ScopedWriteLock
|
|
*/
|
|
void enterWrite() const throw();
|
|
|
|
/** Tries to lock this object for writing.
|
|
|
|
This is like enterWrite(), but doesn't block - it returns true if it manages
|
|
to obtain the lock.
|
|
|
|
@see enterWrite
|
|
*/
|
|
bool tryEnterWrite() const throw();
|
|
|
|
/** Releases the write-lock.
|
|
|
|
If the caller thread hasn't got the lock, this can have unpredictable results.
|
|
|
|
If the enterWrite() method has been called multiple times by the thread, each
|
|
call must be matched by a call to exit() before other threads will be allowed
|
|
to take over the lock.
|
|
|
|
@see enterWrite, ScopedWriteLock
|
|
*/
|
|
void exitWrite() const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
CriticalSection accessLock;
|
|
WaitableEvent waitEvent;
|
|
mutable int numWaitingWriters, numWriters;
|
|
mutable Thread::ThreadID writerThreadId;
|
|
mutable Array <Thread::ThreadID> readerThreads;
|
|
|
|
ReadWriteLock (const ReadWriteLock&);
|
|
const ReadWriteLock& operator= (const ReadWriteLock&);
|
|
};
|
|
|
|
#endif // __JUCE_READWRITELOCK_JUCEHEADER__
|
|
/********* End of inlined file: juce_ReadWriteLock.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_SCOPEDLOCK_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_SCOPEDREADLOCK_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ScopedReadLock.h *********/
|
|
#ifndef __JUCE_SCOPEDREADLOCK_JUCEHEADER__
|
|
#define __JUCE_SCOPEDREADLOCK_JUCEHEADER__
|
|
|
|
/**
|
|
Automatically locks and unlocks a ReadWriteLock object.
|
|
|
|
Use one of these as a local variable to control access to a ReadWriteLock.
|
|
|
|
e.g. @code
|
|
|
|
ReadWriteLock myLock;
|
|
|
|
for (;;)
|
|
{
|
|
const ScopedReadLock myScopedLock (myLock);
|
|
// myLock is now locked
|
|
|
|
...do some stuff...
|
|
|
|
// myLock gets unlocked here.
|
|
}
|
|
@endcode
|
|
|
|
@see ReadWriteLock, ScopedWriteLock
|
|
*/
|
|
class JUCE_API ScopedReadLock
|
|
{
|
|
public:
|
|
|
|
/** Creates a ScopedReadLock.
|
|
|
|
As soon as it is created, this will call ReadWriteLock::enterRead(), and
|
|
when the ScopedReadLock object is deleted, the ReadWriteLock will
|
|
be unlocked.
|
|
|
|
Make sure this object is created and deleted by the same thread,
|
|
otherwise there are no guarantees what will happen! Best just to use it
|
|
as a local stack object, rather than creating one with the new() operator.
|
|
*/
|
|
inline ScopedReadLock (const ReadWriteLock& lock) throw() : lock_ (lock) { lock.enterRead(); }
|
|
|
|
/** Destructor.
|
|
|
|
The ReadWriteLock's exitRead() method will be called when the destructor is called.
|
|
|
|
Make sure this object is created and deleted by the same thread,
|
|
otherwise there are no guarantees what will happen!
|
|
*/
|
|
inline ~ScopedReadLock() throw() { lock_.exitRead(); }
|
|
|
|
private:
|
|
|
|
const ReadWriteLock& lock_;
|
|
|
|
ScopedReadLock (const ScopedReadLock&);
|
|
const ScopedReadLock& operator= (const ScopedReadLock&);
|
|
};
|
|
|
|
#endif // __JUCE_SCOPEDREADLOCK_JUCEHEADER__
|
|
/********* End of inlined file: juce_ScopedReadLock.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_SCOPEDTRYLOCK_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ScopedTryLock.h *********/
|
|
#ifndef __JUCE_SCOPEDTRYLOCK_JUCEHEADER__
|
|
#define __JUCE_SCOPEDTRYLOCK_JUCEHEADER__
|
|
|
|
/**
|
|
Automatically tries to lock and unlock a CriticalSection object.
|
|
|
|
Use one of these as a local variable to control access to a CriticalSection.
|
|
|
|
e.g. @code
|
|
|
|
CriticalSection myCriticalSection;
|
|
|
|
for (;;)
|
|
{
|
|
const ScopedTryLock myScopedTryLock (myCriticalSection);
|
|
|
|
// Unlike using a ScopedLock, this may fail to actually get the lock, so you
|
|
// should test this with the isLocked() method before doing your thread-unsafe
|
|
// action..
|
|
if (myScopedTryLock.isLocked())
|
|
{
|
|
...do some stuff...
|
|
}
|
|
else
|
|
{
|
|
..our attempt at locking failed because another thread had already locked it..
|
|
}
|
|
|
|
// myCriticalSection gets unlocked here (if it was locked)
|
|
}
|
|
@endcode
|
|
|
|
@see CriticalSection::tryEnter, ScopedLock, ScopedUnlock, ScopedReadLock
|
|
*/
|
|
class JUCE_API ScopedTryLock
|
|
{
|
|
public:
|
|
|
|
/** Creates a ScopedTryLock.
|
|
|
|
As soon as it is created, this will try to lock the CriticalSection, and
|
|
when the ScopedTryLock object is deleted, the CriticalSection will
|
|
be unlocked if the lock was successful.
|
|
|
|
Make sure this object is created and deleted by the same thread,
|
|
otherwise there are no guarantees what will happen! Best just to use it
|
|
as a local stack object, rather than creating one with the new() operator.
|
|
*/
|
|
inline ScopedTryLock (const CriticalSection& lock) throw() : lock_ (lock), lockWasSuccessful (lock.tryEnter()) {}
|
|
|
|
/** Destructor.
|
|
|
|
The CriticalSection will be unlocked (if locked) when the destructor is called.
|
|
|
|
Make sure this object is created and deleted by the same thread,
|
|
otherwise there are no guarantees what will happen!
|
|
*/
|
|
inline ~ScopedTryLock() throw() { if (lockWasSuccessful) lock_.exit(); }
|
|
|
|
/** Lock state
|
|
|
|
@return True if the CriticalSection is locked.
|
|
*/
|
|
bool isLocked() const throw() { return lockWasSuccessful; }
|
|
|
|
private:
|
|
|
|
const CriticalSection& lock_;
|
|
const bool lockWasSuccessful;
|
|
|
|
ScopedTryLock (const ScopedTryLock&);
|
|
const ScopedTryLock& operator= (const ScopedTryLock&);
|
|
};
|
|
|
|
#endif // __JUCE_SCOPEDTRYLOCK_JUCEHEADER__
|
|
/********* End of inlined file: juce_ScopedTryLock.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_SCOPEDWRITELOCK_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ScopedWriteLock.h *********/
|
|
#ifndef __JUCE_SCOPEDWRITELOCK_JUCEHEADER__
|
|
#define __JUCE_SCOPEDWRITELOCK_JUCEHEADER__
|
|
|
|
/**
|
|
Automatically locks and unlocks a ReadWriteLock object.
|
|
|
|
Use one of these as a local variable to control access to a ReadWriteLock.
|
|
|
|
e.g. @code
|
|
|
|
ReadWriteLock myLock;
|
|
|
|
for (;;)
|
|
{
|
|
const ScopedWriteLock myScopedLock (myLock);
|
|
// myLock is now locked
|
|
|
|
...do some stuff...
|
|
|
|
// myLock gets unlocked here.
|
|
}
|
|
@endcode
|
|
|
|
@see ReadWriteLock, ScopedReadLock
|
|
*/
|
|
class JUCE_API ScopedWriteLock
|
|
{
|
|
public:
|
|
|
|
/** Creates a ScopedWriteLock.
|
|
|
|
As soon as it is created, this will call ReadWriteLock::enterWrite(), and
|
|
when the ScopedWriteLock object is deleted, the ReadWriteLock will
|
|
be unlocked.
|
|
|
|
Make sure this object is created and deleted by the same thread,
|
|
otherwise there are no guarantees what will happen! Best just to use it
|
|
as a local stack object, rather than creating one with the new() operator.
|
|
*/
|
|
inline ScopedWriteLock (const ReadWriteLock& lock) throw() : lock_ (lock) { lock.enterWrite(); }
|
|
|
|
/** Destructor.
|
|
|
|
The ReadWriteLock's exitWrite() method will be called when the destructor is called.
|
|
|
|
Make sure this object is created and deleted by the same thread,
|
|
otherwise there are no guarantees what will happen!
|
|
*/
|
|
inline ~ScopedWriteLock() throw() { lock_.exitWrite(); }
|
|
|
|
private:
|
|
|
|
const ReadWriteLock& lock_;
|
|
|
|
ScopedWriteLock (const ScopedWriteLock&);
|
|
const ScopedWriteLock& operator= (const ScopedWriteLock&);
|
|
};
|
|
|
|
#endif // __JUCE_SCOPEDWRITELOCK_JUCEHEADER__
|
|
/********* End of inlined file: juce_ScopedWriteLock.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_THREAD_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_THREADPOOL_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ThreadPool.h *********/
|
|
#ifndef __JUCE_THREADPOOL_JUCEHEADER__
|
|
#define __JUCE_THREADPOOL_JUCEHEADER__
|
|
|
|
class ThreadPool;
|
|
class ThreadPoolThread;
|
|
|
|
/**
|
|
A task that is executed by a ThreadPool object.
|
|
|
|
A ThreadPool keeps a list of ThreadPoolJob objects which are executed by
|
|
its threads.
|
|
|
|
The runJob() method needs to be implemented to do the task, and if the code that
|
|
does the work takes a significant time to run, it must keep checking the shouldExit()
|
|
method to see if something is trying to interrupt the job. If shouldExit() returns
|
|
true, the runJob() method must return immediately.
|
|
|
|
@see ThreadPool, Thread
|
|
*/
|
|
class JUCE_API ThreadPoolJob
|
|
{
|
|
public:
|
|
|
|
/** Creates a thread pool job object.
|
|
|
|
After creating your job, add it to a thread pool with ThreadPool::addJob().
|
|
*/
|
|
ThreadPoolJob (const String& name);
|
|
|
|
/** Destructor. */
|
|
virtual ~ThreadPoolJob();
|
|
|
|
/** Returns the name of this job.
|
|
@see setJobName
|
|
*/
|
|
const String getJobName() const;
|
|
|
|
/** Changes the job's name.
|
|
@see getJobName
|
|
*/
|
|
void setJobName (const String& newName);
|
|
|
|
/** These are the values that can be returned by the runJob() method.
|
|
*/
|
|
enum JobStatus
|
|
{
|
|
jobHasFinished = 0, /**< indicates that the job has finished and can be
|
|
removed from the pool. */
|
|
|
|
jobHasFinishedAndShouldBeDeleted, /**< indicates that the job has finished and that it
|
|
should be automatically deleted by the pool. */
|
|
|
|
jobNeedsRunningAgain /**< indicates that the job would like to be called
|
|
again when a thread is free. */
|
|
};
|
|
|
|
/** Peforms the actual work that this job needs to do.
|
|
|
|
Your subclass must implement this method, in which is does its work.
|
|
|
|
If the code in this method takes a significant time to run, it must repeatedly check
|
|
the shouldExit() method to see if something is trying to interrupt the job.
|
|
If shouldExit() ever returns true, the runJob() method must return immediately.
|
|
|
|
If this method returns jobHasFinished, then the job will be removed from the pool
|
|
immediately. If it returns jobNeedsRunningAgain, then the job will be left in the
|
|
pool and will get a chance to run again as soon as a thread is free.
|
|
|
|
@see shouldExit()
|
|
*/
|
|
virtual JobStatus runJob() = 0;
|
|
|
|
/** Returns true if this job is currently running its runJob() method. */
|
|
bool isRunning() const throw() { return isActive; }
|
|
|
|
/** Returns true if something is trying to interrupt this job and make it stop.
|
|
|
|
Your runJob() method must call this whenever it gets a chance, and if it ever
|
|
returns true, the runJob() method must return immediately.
|
|
|
|
@see signalJobShouldExit()
|
|
*/
|
|
bool shouldExit() const throw() { return shouldStop; }
|
|
|
|
/** Calling this will cause the shouldExit() method to return true, and the job
|
|
should (if it's been implemented correctly) stop as soon as possible.
|
|
|
|
@see shouldExit()
|
|
*/
|
|
void signalJobShouldExit();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class ThreadPool;
|
|
friend class ThreadPoolThread;
|
|
String jobName;
|
|
ThreadPool* pool;
|
|
bool shouldStop, isActive, shouldBeDeleted;
|
|
};
|
|
|
|
/**
|
|
A set of threads that will run a list of jobs.
|
|
|
|
When a ThreadPoolJob object is added to the ThreadPool's list, its run() method
|
|
will be called by the next pooled thread that becomes free.
|
|
|
|
@see ThreadPoolJob, Thread
|
|
*/
|
|
class JUCE_API ThreadPool
|
|
{
|
|
public:
|
|
|
|
/** Creates a thread pool.
|
|
|
|
Once you've created a pool, you can give it some things to do with the addJob()
|
|
method.
|
|
|
|
@param numberOfThreads the maximum number of actual threads to run.
|
|
@param startThreadsOnlyWhenNeeded if this is true, then no threads will be started
|
|
until there are some jobs to run. If false, then
|
|
all the threads will be fired-up immediately so that
|
|
they're ready for action
|
|
@param stopThreadsWhenNotUsedTimeoutMs if this timeout is > 0, then if any threads have been
|
|
inactive for this length of time, they will automatically
|
|
be stopped until more jobs come along and they're needed
|
|
*/
|
|
ThreadPool (const int numberOfThreads,
|
|
const bool startThreadsOnlyWhenNeeded = true,
|
|
const int stopThreadsWhenNotUsedTimeoutMs = 5000);
|
|
|
|
/** Destructor.
|
|
|
|
This will attempt to remove all the jobs before deleting, but if you want to
|
|
specify a timeout, you should call removeAllJobs() explicitly before deleting
|
|
the pool.
|
|
*/
|
|
~ThreadPool();
|
|
|
|
/** Adds a job to the queue.
|
|
|
|
Once a job has been added, then the next time a thread is free, it will run
|
|
the job's ThreadPoolJob::runJob() method. Depending on the return value of the
|
|
runJob() method, the pool will either remove the job from the pool or add it to
|
|
the back of the queue to be run again.
|
|
*/
|
|
void addJob (ThreadPoolJob* const job);
|
|
|
|
/** Tries to remove a job from the pool.
|
|
|
|
If the job isn't yet running, this will simply remove it. If it is running, it
|
|
will wait for it to finish.
|
|
|
|
If the timeout period expires before the job finishes running, then the job will be
|
|
left in the pool and this will return false. It returns true if the job is sucessfully
|
|
stopped and removed.
|
|
|
|
@param job the job to remove
|
|
@param interruptIfRunning if true, then if the job is currently busy, its
|
|
ThreadPoolJob::signalJobShouldExit() method will be called to try
|
|
to interrupt it. If false, then if the job will be allowed to run
|
|
until it stops normally (or the timeout expires)
|
|
@param timeOutMilliseconds the length of time this method should wait for the job to finish
|
|
before giving up and returning false
|
|
*/
|
|
bool removeJob (ThreadPoolJob* const job,
|
|
const bool interruptIfRunning,
|
|
const int timeOutMilliseconds);
|
|
|
|
/** Tries clear all jobs from the pool.
|
|
|
|
@param interruptRunningJobs if true, then all running jobs will have their ThreadPoolJob::signalJobShouldExit()
|
|
methods called to try to interrupt them
|
|
@param timeOutMilliseconds the length of time this method should wait for all the jobs to finish
|
|
before giving up and returning false
|
|
@param deleteInactiveJobs if true, any jobs that aren't currently running will be deleted. If false,
|
|
they will simply be removed from the pool. Jobs that are already running when
|
|
this method is called can choose whether they should be deleted by
|
|
returning jobHasFinishedAndShouldBeDeleted from their runJob() method.
|
|
@returns true if all jobs are successfully stopped and removed; false if the timeout period
|
|
expires while waiting for them to stop
|
|
*/
|
|
bool removeAllJobs (const bool interruptRunningJobs,
|
|
const int timeOutMilliseconds,
|
|
const bool deleteInactiveJobs = false);
|
|
|
|
/** Returns the number of jobs currently running or queued.
|
|
*/
|
|
int getNumJobs() const throw();
|
|
|
|
/** Returns one of the jobs in the queue.
|
|
|
|
Note that this can be a very volatile list as jobs might be continuously getting shifted
|
|
around in the list, and this method may return 0 if the index is currently out-of-range.
|
|
*/
|
|
ThreadPoolJob* getJob (const int index) const;
|
|
|
|
/** Returns true if the given job is currently queued or running.
|
|
|
|
@see isJobRunning()
|
|
*/
|
|
bool contains (const ThreadPoolJob* const job) const throw();
|
|
|
|
/** Returns true if the given job is currently being run by a thread.
|
|
*/
|
|
bool isJobRunning (const ThreadPoolJob* const job) const;
|
|
|
|
/** Waits until a job has finished running and has been removed from the pool.
|
|
|
|
This will wait until the job is no longer in the pool - i.e. until its
|
|
runJob() method returns ThreadPoolJob::jobHasFinished.
|
|
|
|
If the timeout period expires before the job finishes, this will return false;
|
|
it returns true if the job has finished successfully.
|
|
*/
|
|
bool waitForJobToFinish (const ThreadPoolJob* const job,
|
|
const int timeOutMilliseconds) const;
|
|
|
|
/** Returns a list of the names of all the jobs currently running or queued.
|
|
|
|
If onlyReturnActiveJobs is true, only the ones currently running are returned.
|
|
*/
|
|
const StringArray getNamesOfAllJobs (const bool onlyReturnActiveJobs) const;
|
|
|
|
/** Changes the priority of all the threads.
|
|
|
|
This will call Thread::setPriority() for each thread in the pool.
|
|
May return false if for some reason the priority can't be changed.
|
|
*/
|
|
bool setThreadPriorities (const int newPriority);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
const int numThreads, threadStopTimeout;
|
|
int priority;
|
|
Thread** threads;
|
|
VoidArray jobs;
|
|
|
|
CriticalSection lock;
|
|
uint32 lastJobEndTime;
|
|
|
|
friend class ThreadPoolThread;
|
|
bool runNextJob();
|
|
|
|
ThreadPool (const ThreadPool&);
|
|
const ThreadPool& operator= (const ThreadPool&);
|
|
};
|
|
|
|
#endif // __JUCE_THREADPOOL_JUCEHEADER__
|
|
/********* End of inlined file: juce_ThreadPool.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TIMESLICETHREAD_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_TimeSliceThread.h *********/
|
|
#ifndef __JUCE_TIMESLICETHREAD_JUCEHEADER__
|
|
#define __JUCE_TIMESLICETHREAD_JUCEHEADER__
|
|
|
|
/**
|
|
Used by the TimeSliceThread class.
|
|
|
|
To register your class with a TimeSliceThread, derive from this class and
|
|
use the TimeSliceThread::addTimeSliceClient() method to add it to the list.
|
|
|
|
Make sure you always call TimeSliceThread::removeTimeSliceClient() before
|
|
deleting your client!
|
|
|
|
@see TimeSliceThread
|
|
*/
|
|
class JUCE_API TimeSliceClient
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~TimeSliceClient() {}
|
|
|
|
/** Called back by a TimeSliceThread.
|
|
|
|
When you register this class with it, a TimeSliceThread will repeatedly call
|
|
this method.
|
|
|
|
The implementation of this method should use its time-slice to do something that's
|
|
quick - never block for longer than absolutely necessary.
|
|
|
|
@returns Your method should return true if it needs more time, or false if it's
|
|
not too busy and doesn't need calling back urgently. If all the thread's
|
|
clients indicate that they're not busy, then it'll save CPU by sleeping for
|
|
up to half a second in between callbacks. You can force the TimeSliceThread
|
|
to wake up and poll again immediately by calling its notify() method.
|
|
*/
|
|
virtual bool useTimeSlice() = 0;
|
|
};
|
|
|
|
/**
|
|
A thread that keeps a list of clients, and calls each one in turn, giving them
|
|
all a chance to run some sort of short task.
|
|
|
|
@see TimeSliceClient, Thread
|
|
*/
|
|
class JUCE_API TimeSliceThread : public Thread
|
|
{
|
|
public:
|
|
|
|
/**
|
|
Creates a TimeSliceThread.
|
|
|
|
When first created, the thread is not running. Use the startThread()
|
|
method to start it.
|
|
*/
|
|
TimeSliceThread (const String& threadName);
|
|
|
|
/** Destructor.
|
|
|
|
Deleting a Thread object that is running will only give the thread a
|
|
brief opportunity to stop itself cleanly, so it's recommended that you
|
|
should always call stopThread() with a decent timeout before deleting,
|
|
to avoid the thread being forcibly killed (which is a Bad Thing).
|
|
*/
|
|
~TimeSliceThread();
|
|
|
|
/** Adds a client to the list.
|
|
|
|
The client's callbacks will start immediately (possibly before the method
|
|
has returned).
|
|
*/
|
|
void addTimeSliceClient (TimeSliceClient* const client);
|
|
|
|
/** Removes a client from the list.
|
|
|
|
This method will make sure that all callbacks to the client have completely
|
|
finished before the method returns.
|
|
*/
|
|
void removeTimeSliceClient (TimeSliceClient* const client);
|
|
|
|
/** Returns the number of registered clients. */
|
|
int getNumClients() const throw();
|
|
|
|
/** Returns one of the registered clients. */
|
|
TimeSliceClient* getClient (const int index) const throw();
|
|
|
|
/** @internal */
|
|
void run();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
CriticalSection callbackLock, listLock;
|
|
Array <TimeSliceClient*> clients;
|
|
int index;
|
|
TimeSliceClient* clientBeingCalled;
|
|
bool clientsChanged;
|
|
|
|
TimeSliceThread (const TimeSliceThread&);
|
|
const TimeSliceThread& operator= (const TimeSliceThread&);
|
|
};
|
|
|
|
#endif // __JUCE_TIMESLICETHREAD_JUCEHEADER__
|
|
/********* End of inlined file: juce_TimeSliceThread.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_WAITABLEEVENT_JUCEHEADER__
|
|
|
|
#endif
|
|
|
|
#endif
|
|
/********* End of inlined file: juce_core_includes.h *********/
|
|
|
|
// if you're compiling a command-line app, you might want to just include the core headers,
|
|
// so you can set this macro before including juce.h
|
|
#if ! JUCE_ONLY_BUILD_CORE_LIBRARY
|
|
|
|
/********* Start of inlined file: juce_app_includes.h *********/
|
|
#ifndef __JUCE_JUCE_APP_INCLUDES_INCLUDEFILES__
|
|
#define __JUCE_JUCE_APP_INCLUDES_INCLUDEFILES__
|
|
|
|
#ifndef __JUCE_APPLICATION_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Application.h *********/
|
|
#ifndef __JUCE_APPLICATION_JUCEHEADER__
|
|
#define __JUCE_APPLICATION_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ApplicationCommandTarget.h *********/
|
|
#ifndef __JUCE_APPLICATIONCOMMANDTARGET_JUCEHEADER__
|
|
#define __JUCE_APPLICATIONCOMMANDTARGET_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Component.h *********/
|
|
#ifndef __JUCE_COMPONENT_JUCEHEADER__
|
|
#define __JUCE_COMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MouseCursor.h *********/
|
|
#ifndef __JUCE_MOUSECURSOR_JUCEHEADER__
|
|
#define __JUCE_MOUSECURSOR_JUCEHEADER__
|
|
|
|
class Image;
|
|
class RefCountedMouseCursor;
|
|
class ComponentPeer;
|
|
class Component;
|
|
|
|
/**
|
|
Represents a mouse cursor image.
|
|
|
|
This object can either be used to represent one of the standard mouse
|
|
cursor shapes, or a custom one generated from an image.
|
|
*/
|
|
class JUCE_API MouseCursor
|
|
{
|
|
public:
|
|
|
|
/** The set of available standard mouse cursors. */
|
|
enum StandardCursorType
|
|
{
|
|
NoCursor = 0, /**< An invisible cursor. */
|
|
NormalCursor, /**< The stardard arrow cursor. */
|
|
|
|
WaitCursor, /**< The normal hourglass or spinning-beachball 'busy' cursor. */
|
|
IBeamCursor, /**< A vertical I-beam for positioning within text. */
|
|
CrosshairCursor, /**< A pair of crosshairs. */
|
|
CopyingCursor, /**< The normal arrow cursor, but with a "+" on it to indicate
|
|
that you're dragging a copy of something. */
|
|
|
|
PointingHandCursor, /**< A hand with a pointing finger, for clicking on web-links. */
|
|
DraggingHandCursor, /**< An open flat hand for dragging heavy objects around. */
|
|
|
|
LeftRightResizeCursor, /**< An arrow pointing left and right. */
|
|
UpDownResizeCursor, /**< an arrow pointing up and down. */
|
|
UpDownLeftRightResizeCursor, /**< An arrow pointing up, down, left and right. */
|
|
|
|
TopEdgeResizeCursor, /**< A platform-specific cursor for resizing the top-edge of a window. */
|
|
BottomEdgeResizeCursor, /**< A platform-specific cursor for resizing the bottom-edge of a window. */
|
|
LeftEdgeResizeCursor, /**< A platform-specific cursor for resizing the left-edge of a window. */
|
|
RightEdgeResizeCursor, /**< A platform-specific cursor for resizing the right-edge of a window. */
|
|
TopLeftCornerResizeCursor, /**< A platform-specific cursor for resizing the top-left-corner of a window. */
|
|
TopRightCornerResizeCursor, /**< A platform-specific cursor for resizing the top-right-corner of a window. */
|
|
BottomLeftCornerResizeCursor, /**< A platform-specific cursor for resizing the bottom-left-corner of a window. */
|
|
BottomRightCornerResizeCursor /**< A platform-specific cursor for resizing the bottom-right-corner of a window. */
|
|
};
|
|
|
|
/** Creates the standard arrow cursor. */
|
|
MouseCursor() throw();
|
|
|
|
/** Creates one of the standard mouse cursor */
|
|
MouseCursor (const StandardCursorType type) throw();
|
|
|
|
/** Creates a custom cursor from an image.
|
|
|
|
@param image the image to use for the cursor - if this is bigger than the
|
|
system can manage, it might get scaled down first, and might
|
|
also have to be turned to black-and-white if it can't do colour
|
|
cursors.
|
|
@param hotSpotX the x position of the cursor's hotspot within the image
|
|
@param hotSpotY the y position of the cursor's hotspot within the image
|
|
*/
|
|
MouseCursor (Image& image,
|
|
const int hotSpotX,
|
|
const int hotSpotY) throw();
|
|
|
|
/** Creates a copy of another cursor object. */
|
|
MouseCursor (const MouseCursor& other) throw();
|
|
|
|
/** Copies this cursor from another object. */
|
|
const MouseCursor& operator= (const MouseCursor& other) throw();
|
|
|
|
/** Destructor. */
|
|
~MouseCursor() throw();
|
|
|
|
/** Checks whether two mouse cursors are the same.
|
|
|
|
For custom cursors, two cursors created from the same image won't be
|
|
recognised as the same, only MouseCursor objects that have been
|
|
copied from the same object.
|
|
*/
|
|
bool operator== (const MouseCursor& other) const throw();
|
|
|
|
/** Checks whether two mouse cursors are the same.
|
|
|
|
For custom cursors, two cursors created from the same image won't be
|
|
recognised as the same, only MouseCursor objects that have been
|
|
copied from the same object.
|
|
*/
|
|
bool operator!= (const MouseCursor& other) const throw();
|
|
|
|
/** Makes the system show its default 'busy' cursor.
|
|
|
|
This will turn the system cursor to an hourglass or spinning beachball
|
|
until the next time the mouse is moved, or hideWaitCursor() is called.
|
|
|
|
This is handy if the message loop is about to block for a couple of
|
|
seconds while busy and you want to give the user feedback about this.
|
|
|
|
@see MessageManager::setTimeBeforeShowingWaitCursor
|
|
*/
|
|
static void showWaitCursor() throw();
|
|
|
|
/** If showWaitCursor has been called, this will return the mouse to its
|
|
normal state.
|
|
|
|
This will look at what component is under the mouse, and update the
|
|
cursor to be the correct one for that component.
|
|
|
|
@see showWaitCursor
|
|
*/
|
|
static void hideWaitCursor() throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
RefCountedMouseCursor* cursorHandle;
|
|
|
|
friend class Component;
|
|
|
|
void showInWindow (ComponentPeer* window) const throw();
|
|
void showInAllWindows() const throw();
|
|
|
|
void* getHandle() const throw();
|
|
};
|
|
|
|
#endif // __JUCE_MOUSECURSOR_JUCEHEADER__
|
|
/********* End of inlined file: juce_MouseCursor.h *********/
|
|
|
|
/********* Start of inlined file: juce_MouseListener.h *********/
|
|
#ifndef __JUCE_MOUSELISTENER_JUCEHEADER__
|
|
#define __JUCE_MOUSELISTENER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MouseEvent.h *********/
|
|
#ifndef __JUCE_MOUSEEVENT_JUCEHEADER__
|
|
#define __JUCE_MOUSEEVENT_JUCEHEADER__
|
|
|
|
class Component;
|
|
|
|
/********* Start of inlined file: juce_ModifierKeys.h *********/
|
|
#ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__
|
|
#define __JUCE_MODIFIERKEYS_JUCEHEADER__
|
|
|
|
/**
|
|
Represents the state of the mouse buttons and modifier keys.
|
|
|
|
This is used both by mouse events and by KeyPress objects to describe
|
|
the state of keys such as shift, control, alt, etc.
|
|
|
|
@see KeyPress, MouseEvent::mods
|
|
*/
|
|
class JUCE_API ModifierKeys
|
|
{
|
|
public:
|
|
|
|
/** Creates a ModifierKeys object from a raw set of flags.
|
|
|
|
@param flags to represent the keys that are down
|
|
@see shiftModifier, ctrlModifier, altModifier, leftButtonModifier,
|
|
rightButtonModifier, commandModifier, popupMenuClickModifier
|
|
*/
|
|
ModifierKeys (const int flags = 0) throw();
|
|
|
|
/** Creates a copy of another object. */
|
|
ModifierKeys (const ModifierKeys& other) throw();
|
|
|
|
/** Copies this object from another one. */
|
|
const ModifierKeys& operator= (const ModifierKeys& other) throw();
|
|
|
|
/** Checks whether the 'command' key flag is set (or 'ctrl' on Windows/Linux).
|
|
|
|
This is a platform-agnostic way of checking for the operating system's
|
|
preferred command-key modifier - so on the Mac it tests for the Apple key, on
|
|
Windows/Linux, it's actually checking for the CTRL key.
|
|
*/
|
|
inline bool isCommandDown() const throw() { return (flags & commandModifier) != 0; }
|
|
|
|
/** Checks whether the user is trying to launch a pop-up menu.
|
|
|
|
This checks for platform-specific modifiers that might indicate that the user
|
|
is following the operating system's normal method of showing a pop-up menu.
|
|
|
|
So on Windows/Linux, this method is really testing for a right-click.
|
|
On the Mac, it tests for either the CTRL key being down, or a right-click.
|
|
*/
|
|
inline bool isPopupMenu() const throw() { return (flags & popupMenuClickModifier) != 0; }
|
|
|
|
/** Checks whether the flag is set for the left mouse-button. */
|
|
inline bool isLeftButtonDown() const throw() { return (flags & leftButtonModifier) != 0; }
|
|
|
|
/** Checks whether the flag is set for the right mouse-button.
|
|
|
|
Note that for detecting popup-menu clicks, you should be using isPopupMenu() instead, as
|
|
this is platform-independent (and makes your code more explanatory too).
|
|
*/
|
|
inline bool isRightButtonDown() const throw() { return (flags & rightButtonModifier) != 0; }
|
|
|
|
inline bool isMiddleButtonDown() const throw() { return (flags & middleButtonModifier) != 0; }
|
|
|
|
/** Tests for any of the mouse-button flags. */
|
|
inline bool isAnyMouseButtonDown() const throw() { return (flags & allMouseButtonModifiers) != 0; }
|
|
|
|
/** Tests for any of the modifier key flags. */
|
|
inline bool isAnyModifierKeyDown() const throw() { return (flags & (shiftModifier | ctrlModifier | altModifier | commandModifier)) != 0; }
|
|
|
|
/** Checks whether the shift key's flag is set. */
|
|
inline bool isShiftDown() const throw() { return (flags & shiftModifier) != 0; }
|
|
|
|
/** Checks whether the CTRL key's flag is set.
|
|
|
|
Remember that it's better to use the platform-agnostic routines to test for command-key and
|
|
popup-menu modifiers.
|
|
|
|
@see isCommandDown, isPopupMenu
|
|
*/
|
|
inline bool isCtrlDown() const throw() { return (flags & ctrlModifier) != 0; }
|
|
|
|
/** Checks whether the shift key's flag is set. */
|
|
inline bool isAltDown() const throw() { return (flags & altModifier) != 0; }
|
|
|
|
/** Flags that represent the different keys. */
|
|
enum Flags
|
|
{
|
|
/** Shift key flag. */
|
|
shiftModifier = 1,
|
|
|
|
/** CTRL key flag. */
|
|
ctrlModifier = 2,
|
|
|
|
/** ALT key flag. */
|
|
altModifier = 4,
|
|
|
|
/** Left mouse button flag. */
|
|
leftButtonModifier = 16,
|
|
|
|
/** Right mouse button flag. */
|
|
rightButtonModifier = 32,
|
|
|
|
/** Middle mouse button flag. */
|
|
middleButtonModifier = 64,
|
|
|
|
#if JUCE_MAC
|
|
/** Command key flag - on windows this is the same as the CTRL key flag. */
|
|
commandModifier = 8,
|
|
|
|
/** Popup menu flag - on windows this is the same as rightButtonModifier, on the
|
|
Mac it's the same as (rightButtonModifier | ctrlModifier). */
|
|
popupMenuClickModifier = rightButtonModifier | ctrlModifier,
|
|
#else
|
|
/** Command key flag - on windows this is the same as the CTRL key flag. */
|
|
commandModifier = ctrlModifier,
|
|
|
|
/** Popup menu flag - on windows this is the same as rightButtonModifier, on the
|
|
Mac it's the same as (rightButtonModifier | ctrlModifier). */
|
|
popupMenuClickModifier = rightButtonModifier,
|
|
#endif
|
|
|
|
/** Represents a combination of all the shift, alt, ctrl and command key modifiers. */
|
|
allKeyboardModifiers = shiftModifier | ctrlModifier | altModifier | commandModifier,
|
|
|
|
/** Represents a combination of all the mouse buttons at once. */
|
|
allMouseButtonModifiers = leftButtonModifier | rightButtonModifier | middleButtonModifier,
|
|
};
|
|
|
|
/** Returns the raw flags for direct testing. */
|
|
inline int getRawFlags() const throw() { return flags; }
|
|
|
|
/** Tests a combination of flags and returns true if any of them are set. */
|
|
inline bool testFlags (const int flagsToTest) const throw() { return (flags & flagsToTest) != 0; }
|
|
|
|
/** Creates a ModifierKeys object to represent the last-known state of the
|
|
keyboard and mouse buttons.
|
|
|
|
@see getCurrentModifiersRealtime
|
|
*/
|
|
static const ModifierKeys getCurrentModifiers() throw();
|
|
|
|
/** Creates a ModifierKeys object to represent the current state of the
|
|
keyboard and mouse buttons.
|
|
|
|
This isn't often needed and isn't recommended, but will actively check all the
|
|
mouse and key states rather than just returning their last-known state like
|
|
getCurrentModifiers() does.
|
|
|
|
This is only needed in special circumstances for up-to-date modifier information
|
|
at times when the app's event loop isn't running normally.
|
|
*/
|
|
static const ModifierKeys getCurrentModifiersRealtime() throw();
|
|
|
|
private:
|
|
|
|
int flags;
|
|
|
|
static int currentModifierFlags;
|
|
|
|
friend class ComponentPeer;
|
|
static void updateCurrentModifiers() throw();
|
|
};
|
|
|
|
#endif // __JUCE_MODIFIERKEYS_JUCEHEADER__
|
|
/********* End of inlined file: juce_ModifierKeys.h *********/
|
|
|
|
/**
|
|
Contains position and status information about a mouse event.
|
|
|
|
@see MouseListener, Component::mouseMove, Component::mouseEnter, Component::mouseExit,
|
|
Component::mouseDown, Component::mouseUp, Component::mouseDrag
|
|
*/
|
|
class JUCE_API MouseEvent
|
|
{
|
|
public:
|
|
|
|
/** Creates a MouseEvent.
|
|
|
|
Normally an application will never need to use this.
|
|
|
|
@param x the x position of the mouse, relative to the component that is passed-in
|
|
@param y the y position of the mouse, relative to the component that is passed-in
|
|
@param modifiers the key modifiers at the time of the event
|
|
@param originator the component that the mouse event applies to
|
|
@param eventTime the time the event happened
|
|
@param mouseDownX the x position of the corresponding mouse-down event (relative to the component that is passed-in).
|
|
If there isn't a corresponding mouse-down (e.g. for a mouse-move), this will just be
|
|
the same as the current mouse-x position.
|
|
@param mouseDownY the y position of the corresponding mouse-down event (relative to the component that is passed-in)
|
|
If there isn't a corresponding mouse-down (e.g. for a mouse-move), this will just be
|
|
the same as the current mouse-y position.
|
|
@param mouseDownTime the time at which the corresponding mouse-down event happened
|
|
If there isn't a corresponding mouse-down (e.g. for a mouse-move), this will just be
|
|
the same as the current mouse-event time.
|
|
@param numberOfClicks how many clicks, e.g. a double-click event will be 2, a triple-click will be 3, etc
|
|
@param mouseWasDragged whether the mouse has been dragged significantly since the previous mouse-down
|
|
*/
|
|
MouseEvent (const int x, const int y,
|
|
const ModifierKeys& modifiers,
|
|
Component* const originator,
|
|
const Time& eventTime,
|
|
const int mouseDownX,
|
|
const int mouseDownY,
|
|
const Time& mouseDownTime,
|
|
const int numberOfClicks,
|
|
const bool mouseWasDragged) throw();
|
|
|
|
/** Destructor. */
|
|
~MouseEvent() throw();
|
|
|
|
/** The x-position of the mouse when the event occurred.
|
|
|
|
This value is relative to the top-left of the component to which the
|
|
event applies (as indicated by the MouseEvent::eventComponent field).
|
|
*/
|
|
int x;
|
|
|
|
/** The y-position of the mouse when the event occurred.
|
|
|
|
This value is relative to the top-left of the component to which the
|
|
event applies (as indicated by the MouseEvent::eventComponent field).
|
|
*/
|
|
int y;
|
|
|
|
/** The key modifiers associated with the event.
|
|
|
|
This will let you find out which mouse buttons were down, as well as which
|
|
modifier keys were held down.
|
|
|
|
When used for mouse-up events, this will indicate the state of the mouse buttons
|
|
just before they were released, so that you can tell which button they let go of.
|
|
*/
|
|
ModifierKeys mods;
|
|
|
|
/** The component that this event applies to.
|
|
|
|
This is usually the component that the mouse was over at the time, but for mouse-drag
|
|
events the mouse could actually be over a different component and the events are
|
|
still sent to the component that the button was originally pressed on.
|
|
|
|
The x and y member variables are relative to this component's position.
|
|
|
|
If you use getEventRelativeTo() to retarget this object to be relative to a different
|
|
component, this pointer will be updated, but originalComponent remains unchanged.
|
|
|
|
@see originalComponent
|
|
*/
|
|
Component* eventComponent;
|
|
|
|
/** The component that the event first occurred on.
|
|
|
|
If you use getEventRelativeTo() to retarget this object to be relative to a different
|
|
component, this value remains unchanged to indicate the first component that received it.
|
|
|
|
@see eventComponent
|
|
*/
|
|
Component* originalComponent;
|
|
|
|
/** The time that this mouse-event occurred.
|
|
*/
|
|
Time eventTime;
|
|
|
|
/** Returns the x co-ordinate of the last place that a mouse was pressed.
|
|
|
|
The co-ordinate is relative to the component specified in MouseEvent::component.
|
|
|
|
@see getDistanceFromDragStart, getDistanceFromDragStartX, mouseWasClicked
|
|
*/
|
|
int getMouseDownX() const throw();
|
|
|
|
/** Returns the y co-ordinate of the last place that a mouse was pressed.
|
|
|
|
The co-ordinate is relative to the component specified in MouseEvent::component.
|
|
|
|
@see getDistanceFromDragStart, getDistanceFromDragStartX, mouseWasClicked
|
|
*/
|
|
int getMouseDownY() const throw();
|
|
|
|
/** Returns the straight-line distance between where the mouse is now and where it
|
|
was the last time the button was pressed.
|
|
|
|
This is quite handy for things like deciding whether the user has moved far enough
|
|
for it to be considered a drag operation.
|
|
|
|
@see getDistanceFromDragStartX
|
|
*/
|
|
int getDistanceFromDragStart() const throw();
|
|
|
|
/** Returns the difference between the mouse's current x postion and where it was
|
|
when the button was last pressed.
|
|
|
|
@see getDistanceFromDragStart
|
|
*/
|
|
int getDistanceFromDragStartX() const throw();
|
|
|
|
/** Returns the difference between the mouse's current y postion and where it was
|
|
when the button was last pressed.
|
|
|
|
@see getDistanceFromDragStart
|
|
*/
|
|
int getDistanceFromDragStartY() const throw();
|
|
|
|
/** Returns true if the mouse has just been clicked.
|
|
|
|
Used in either your mouseUp() or mouseDrag() methods, this will tell you whether
|
|
the user has dragged the mouse more than a few pixels from the place where the
|
|
mouse-down occurred.
|
|
|
|
Once they have dragged it far enough for this method to return false, it will continue
|
|
to return false until the mouse-up, even if they move the mouse back to the same
|
|
position where they originally pressed it. This means that it's very handy for
|
|
objects that can either be clicked on or dragged, as you can use it in the mouseDrag()
|
|
callback to ignore any small movements they might make while clicking.
|
|
|
|
@returns true if the mouse wasn't dragged by more than a few pixels between
|
|
the last time the button was pressed and released.
|
|
*/
|
|
bool mouseWasClicked() const throw();
|
|
|
|
/** For a click event, the number of times the mouse was clicked in succession.
|
|
|
|
So for example a double-click event will return 2, a triple-click 3, etc.
|
|
*/
|
|
int getNumberOfClicks() const throw() { return numberOfClicks; }
|
|
|
|
/** Returns the time that the mouse button has been held down for.
|
|
|
|
If called from a mouseDrag or mouseUp callback, this will return the
|
|
number of milliseconds since the corresponding mouseDown event occurred.
|
|
If called in other contexts, e.g. a mouseMove, then the returned value
|
|
may be 0 or an undefined value.
|
|
*/
|
|
int getLengthOfMousePress() const throw();
|
|
|
|
/** Returns the mouse x position of this event, in global screen co-ordinates.
|
|
|
|
The co-ordinates are relative to the top-left of the main monitor.
|
|
|
|
@see getMouseDownScreenX, Desktop::getMousePosition
|
|
*/
|
|
int getScreenX() const throw();
|
|
|
|
/** Returns the mouse y position of this event, in global screen co-ordinates.
|
|
|
|
The co-ordinates are relative to the top-left of the main monitor.
|
|
|
|
@see getMouseDownScreenY, Desktop::getMousePosition
|
|
*/
|
|
int getScreenY() const throw();
|
|
|
|
/** Returns the x co-ordinate at which the mouse button was last pressed.
|
|
|
|
The co-ordinates are relative to the top-left of the main monitor.
|
|
|
|
@see getScreenX, Desktop::getMousePosition
|
|
*/
|
|
int getMouseDownScreenX() const throw();
|
|
|
|
/** Returns the y co-ordinate at which the mouse button was last pressed.
|
|
|
|
The co-ordinates are relative to the top-left of the main monitor.
|
|
|
|
@see getScreenY, Desktop::getMousePosition
|
|
*/
|
|
int getMouseDownScreenY() const throw();
|
|
|
|
/** Creates a version of this event that is relative to a different component.
|
|
|
|
The x and y positions of the event that is returned will have been
|
|
adjusted to be relative to the new component.
|
|
*/
|
|
const MouseEvent getEventRelativeTo (Component* const otherComponent) const throw();
|
|
|
|
/** Changes the application-wide setting for the double-click time limit.
|
|
|
|
This is the maximum length of time between mouse-clicks for it to be
|
|
considered a double-click. It's used by the Component class.
|
|
|
|
@see getDoubleClickTimeout, MouseListener::mouseDoubleClick
|
|
*/
|
|
static void setDoubleClickTimeout (const int timeOutMilliseconds) throw();
|
|
|
|
/** Returns the application-wide setting for the double-click time limit.
|
|
|
|
This is the maximum length of time between mouse-clicks for it to be
|
|
considered a double-click. It's used by the Component class.
|
|
|
|
@see setDoubleClickTimeout, MouseListener::mouseDoubleClick
|
|
*/
|
|
static int getDoubleClickTimeout() throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int mouseDownX, mouseDownY;
|
|
Time mouseDownTime;
|
|
int numberOfClicks;
|
|
bool wasMovedSinceMouseDown;
|
|
};
|
|
|
|
#endif // __JUCE_MOUSEEVENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_MouseEvent.h *********/
|
|
|
|
/**
|
|
A MouseListener can be registered with a component to receive callbacks
|
|
about mouse events that happen to that component.
|
|
|
|
@see Component::addMouseListener, Component::removeMouseListener
|
|
*/
|
|
class JUCE_API MouseListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~MouseListener() {}
|
|
|
|
/** Called when the mouse moves inside a component.
|
|
|
|
If the mouse button isn't pressed and the mouse moves over a component,
|
|
this will be called to let the component react to this.
|
|
|
|
A component will always get a mouseEnter callback before a mouseMove.
|
|
|
|
@param e details about the position and status of the mouse event, including
|
|
the source component in which it occurred
|
|
@see mouseEnter, mouseExit, mouseDrag, contains
|
|
*/
|
|
virtual void mouseMove (const MouseEvent& e);
|
|
|
|
/** Called when the mouse first enters a component.
|
|
|
|
If the mouse button isn't pressed and the mouse moves into a component,
|
|
this will be called to let the component react to this.
|
|
|
|
When the mouse button is pressed and held down while being moved in
|
|
or out of a component, no mouseEnter or mouseExit callbacks are made - only
|
|
mouseDrag messages are sent to the component that the mouse was originally
|
|
clicked on, until the button is released.
|
|
|
|
@param e details about the position and status of the mouse event, including
|
|
the source component in which it occurred
|
|
@see mouseExit, mouseDrag, mouseMove, contains
|
|
*/
|
|
virtual void mouseEnter (const MouseEvent& e);
|
|
|
|
/** Called when the mouse moves out of a component.
|
|
|
|
This will be called when the mouse moves off the edge of this
|
|
component.
|
|
|
|
If the mouse button was pressed, and it was then dragged off the
|
|
edge of the component and released, then this callback will happen
|
|
when the button is released, after the mouseUp callback.
|
|
|
|
@param e details about the position and status of the mouse event, including
|
|
the source component in which it occurred
|
|
@see mouseEnter, mouseDrag, mouseMove, contains
|
|
*/
|
|
virtual void mouseExit (const MouseEvent& e);
|
|
|
|
/** Called when a mouse button is pressed.
|
|
|
|
The MouseEvent object passed in contains lots of methods for finding out
|
|
which button was pressed, as well as which modifier keys (e.g. shift, ctrl)
|
|
were held down at the time.
|
|
|
|
Once a button is held down, the mouseDrag method will be called when the
|
|
mouse moves, until the button is released.
|
|
|
|
@param e details about the position and status of the mouse event, including
|
|
the source component in which it occurred
|
|
@see mouseUp, mouseDrag, mouseDoubleClick, contains
|
|
*/
|
|
virtual void mouseDown (const MouseEvent& e);
|
|
|
|
/** Called when the mouse is moved while a button is held down.
|
|
|
|
When a mouse button is pressed inside a component, that component
|
|
receives mouseDrag callbacks each time the mouse moves, even if the
|
|
mouse strays outside the component's bounds.
|
|
|
|
@param e details about the position and status of the mouse event, including
|
|
the source component in which it occurred
|
|
@see mouseDown, mouseUp, mouseMove, contains, setDragRepeatInterval
|
|
*/
|
|
virtual void mouseDrag (const MouseEvent& e);
|
|
|
|
/** Called when a mouse button is released.
|
|
|
|
A mouseUp callback is sent to the component in which a button was pressed
|
|
even if the mouse is actually over a different component when the
|
|
button is released.
|
|
|
|
The MouseEvent object passed in contains lots of methods for finding out
|
|
which buttons were down just before they were released.
|
|
|
|
@param e details about the position and status of the mouse event, including
|
|
the source component in which it occurred
|
|
@see mouseDown, mouseDrag, mouseDoubleClick, contains
|
|
*/
|
|
virtual void mouseUp (const MouseEvent& e);
|
|
|
|
/** Called when a mouse button has been double-clicked on a component.
|
|
|
|
The MouseEvent object passed in contains lots of methods for finding out
|
|
which button was pressed, as well as which modifier keys (e.g. shift, ctrl)
|
|
were held down at the time.
|
|
|
|
@param e details about the position and status of the mouse event, including
|
|
the source component in which it occurred
|
|
@see mouseDown, mouseUp
|
|
*/
|
|
virtual void mouseDoubleClick (const MouseEvent& e);
|
|
|
|
/** Called when the mouse-wheel is moved.
|
|
|
|
This callback is sent to the component that the mouse is over when the
|
|
wheel is moved.
|
|
|
|
If not overridden, the component will forward this message to its parent, so
|
|
that parent components can collect mouse-wheel messages that happen to
|
|
child components which aren't interested in them.
|
|
|
|
@param e details about the position and status of the mouse event, including
|
|
the source component in which it occurred
|
|
@param wheelIncrementX the speed and direction of the horizontal scroll-wheel - a positive
|
|
value means the wheel has been pushed to the right, negative means it
|
|
was pushed to the left
|
|
@param wheelIncrementY the speed and direction of the vertical scroll-wheel - a positive
|
|
value means the wheel has been pushed upwards, negative means it
|
|
was pushed downwards
|
|
*/
|
|
virtual void mouseWheelMove (const MouseEvent& e,
|
|
float wheelIncrementX,
|
|
float wheelIncrementY);
|
|
|
|
private:
|
|
// XXX Deprecated! The parameters for this method have changed to accommodate horizonatal scroll-wheels.
|
|
// This line is here to cause a syntax error if you're trying to use the old-style definition, so
|
|
// if that happens, update your code to use the new one above.
|
|
virtual int mouseWheelMove (const MouseEvent&, float) { return 0; }
|
|
};
|
|
|
|
#endif // __JUCE_MOUSELISTENER_JUCEHEADER__
|
|
/********* End of inlined file: juce_MouseListener.h *********/
|
|
|
|
/********* Start of inlined file: juce_ComponentListener.h *********/
|
|
#ifndef __JUCE_COMPONENTLISTENER_JUCEHEADER__
|
|
#define __JUCE_COMPONENTLISTENER_JUCEHEADER__
|
|
|
|
class Component;
|
|
|
|
/**
|
|
Gets informed about changes to a component's hierarchy or position.
|
|
|
|
To monitor a component for changes, register a subclass of ComponentListener
|
|
with the component using Component::addComponentListener().
|
|
|
|
Be sure to deregister listeners before you delete them!
|
|
|
|
@see Component::addComponentListener, Component::removeComponentListener
|
|
*/
|
|
class JUCE_API ComponentListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~ComponentListener() {}
|
|
|
|
/** Called when the component's position or size changes.
|
|
|
|
@param component the component that was moved or resized
|
|
@param wasMoved true if the component's top-left corner has just moved
|
|
@param wasResized true if the component's width or height has just changed
|
|
@see Component::setBounds, Component::resized, Component::moved
|
|
*/
|
|
virtual void componentMovedOrResized (Component& component,
|
|
bool wasMoved,
|
|
bool wasResized);
|
|
|
|
/** Called when the component is brought to the top of the z-order.
|
|
|
|
@param component the component that was moved
|
|
@see Component::toFront, Component::broughtToFront
|
|
*/
|
|
virtual void componentBroughtToFront (Component& component);
|
|
|
|
/** Called when the component is made visible or invisible.
|
|
|
|
@param component the component that changed
|
|
@see Component::setVisible
|
|
*/
|
|
virtual void componentVisibilityChanged (Component& component);
|
|
|
|
/** Called when the component has children added or removed.
|
|
|
|
@param component the component whose children were changed
|
|
@see Component::childrenChanged, Component::addChildComponent,
|
|
Component::removeChildComponent
|
|
*/
|
|
virtual void componentChildrenChanged (Component& component);
|
|
|
|
/** Called to indicate that the component's parents have changed.
|
|
|
|
When a component is added or removed from its parent, all of its children
|
|
will produce this notification (recursively - so all children of its
|
|
children will also be called as well).
|
|
|
|
@param component the component that this listener is registered with
|
|
@see Component::parentHierarchyChanged
|
|
*/
|
|
virtual void componentParentHierarchyChanged (Component& component);
|
|
|
|
/** Called when the component's name is changed.
|
|
|
|
@see Component::setName, Component::getName
|
|
*/
|
|
virtual void componentNameChanged (Component& component);
|
|
};
|
|
|
|
#endif // __JUCE_COMPONENTLISTENER_JUCEHEADER__
|
|
/********* End of inlined file: juce_ComponentListener.h *********/
|
|
|
|
/********* Start of inlined file: juce_KeyListener.h *********/
|
|
#ifndef __JUCE_KEYLISTENER_JUCEHEADER__
|
|
#define __JUCE_KEYLISTENER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_KeyPress.h *********/
|
|
#ifndef __JUCE_KEYPRESS_JUCEHEADER__
|
|
#define __JUCE_KEYPRESS_JUCEHEADER__
|
|
|
|
/**
|
|
Represents a key press, including any modifier keys that are needed.
|
|
|
|
E.g. a KeyPress might represent CTRL+C, SHIFT+ALT+H, Spacebar, Escape, etc.
|
|
|
|
@see Component, KeyListener, Button::addShortcut, KeyPressMappingManager
|
|
*/
|
|
class JUCE_API KeyPress
|
|
{
|
|
public:
|
|
|
|
/** Creates an (invalid) KeyPress.
|
|
|
|
@see isValid
|
|
*/
|
|
KeyPress() throw();
|
|
|
|
/** Creates a KeyPress for a key and some modifiers.
|
|
|
|
e.g.
|
|
CTRL+C would be: KeyPress ('c', ModifierKeys::ctrlModifier)
|
|
SHIFT+Escape would be: KeyPress (KeyPress::escapeKey, ModifierKeys::shiftModifier)
|
|
|
|
@param keyCode a code that represents the key - this value must be
|
|
one of special constants listed in this class, or an
|
|
8-bit character code such as a letter (case is ignored),
|
|
digit or a simple key like "," or ".". Note that this
|
|
isn't the same as the textCharacter parameter, so for example
|
|
a keyCode of 'a' and a shift-key modifier should have a
|
|
textCharacter value of 'A'.
|
|
@param modifiers the modifiers to associate with the keystroke
|
|
@param textCharacter the character that would be printed if someone typed
|
|
this keypress into a text editor. This value may be
|
|
null if the keypress is a non-printing character
|
|
@see getKeyCode, isKeyCode, getModifiers
|
|
*/
|
|
KeyPress (const int keyCode,
|
|
const ModifierKeys& modifiers,
|
|
const juce_wchar textCharacter) throw();
|
|
|
|
/** Creates a keypress with a keyCode but no modifiers or text character.
|
|
*/
|
|
KeyPress (const int keyCode) throw();
|
|
|
|
/** Creates a copy of another KeyPress. */
|
|
KeyPress (const KeyPress& other) throw();
|
|
|
|
/** Copies this KeyPress from another one. */
|
|
const KeyPress& operator= (const KeyPress& other) throw();
|
|
|
|
/** Compares two KeyPress objects. */
|
|
bool operator== (const KeyPress& other) const throw();
|
|
|
|
/** Compares two KeyPress objects. */
|
|
bool operator!= (const KeyPress& other) const throw();
|
|
|
|
/** Returns true if this is a valid KeyPress.
|
|
|
|
A null keypress can be created by the default constructor, in case it's
|
|
needed.
|
|
*/
|
|
bool isValid() const throw() { return keyCode != 0; }
|
|
|
|
/** Returns the key code itself.
|
|
|
|
This will either be one of the special constants defined in this class,
|
|
or an 8-bit character code.
|
|
*/
|
|
int getKeyCode() const throw() { return keyCode; }
|
|
|
|
/** Returns the key modifiers.
|
|
|
|
@see ModifierKeys
|
|
*/
|
|
const ModifierKeys getModifiers() const throw() { return mods; }
|
|
|
|
/** Returns the character that is associated with this keypress.
|
|
|
|
This is the character that you'd expect to see printed if you press this
|
|
keypress in a text editor or similar component.
|
|
*/
|
|
juce_wchar getTextCharacter() const throw() { return textCharacter; }
|
|
|
|
/** Checks whether the KeyPress's key is the same as the one provided, without checking
|
|
the modifiers.
|
|
|
|
The values for key codes can either be one of the special constants defined in
|
|
this class, or an 8-bit character code.
|
|
|
|
@see getKeyCode
|
|
*/
|
|
bool isKeyCode (const int keyCodeToCompare) const throw() { return keyCode == keyCodeToCompare; }
|
|
|
|
/** Converts a textual key description to a KeyPress.
|
|
|
|
This attempts to decode a textual version of a keypress, e.g. "CTRL + C" or "SPACE".
|
|
|
|
This isn't designed to cope with any kind of input, but should be given the
|
|
strings that are created by the getTextDescription() method.
|
|
|
|
If the string can't be parsed, the object returned will be invalid.
|
|
|
|
@see getTextDescription
|
|
*/
|
|
static const KeyPress createFromDescription (const String& textVersion) throw();
|
|
|
|
/** Creates a textual description of the key combination.
|
|
|
|
e.g. "CTRL + C" or "DELETE".
|
|
|
|
To store a keypress in a file, use this method, along with createFromDescription()
|
|
to retrieve it later.
|
|
*/
|
|
const String getTextDescription() const throw();
|
|
|
|
/** Checks whether the user is currently holding down the keys that make up this
|
|
KeyPress.
|
|
|
|
Note that this will return false if any extra modifier keys are
|
|
down - e.g. if the keypress is CTRL+X and the user is actually holding CTRL+ALT+x
|
|
then it will be false.
|
|
*/
|
|
bool isCurrentlyDown() const throw();
|
|
|
|
/** Checks whether a particular key is held down, irrespective of modifiers.
|
|
|
|
The values for key codes can either be one of the special constants defined in
|
|
this class, or an 8-bit character code.
|
|
*/
|
|
static bool isKeyCurrentlyDown (int keyCode) throw();
|
|
|
|
// Key codes
|
|
//
|
|
// Note that the actual values of these are platform-specific and may change
|
|
// without warning, so don't store them anywhere as constants. For persisting/retrieving
|
|
// KeyPress objects, use getTextDescription() and createFromDescription() instead.
|
|
//
|
|
|
|
static const int spaceKey; /**< key-code for the space bar */
|
|
static const int escapeKey; /**< key-code for the escape key */
|
|
static const int returnKey; /**< key-code for the return key*/
|
|
static const int tabKey; /**< key-code for the tab key*/
|
|
|
|
static const int deleteKey; /**< key-code for the delete key (not backspace) */
|
|
static const int backspaceKey; /**< key-code for the backspace key */
|
|
static const int insertKey; /**< key-code for the insert key */
|
|
|
|
static const int upKey; /**< key-code for the cursor-up key */
|
|
static const int downKey; /**< key-code for the cursor-down key */
|
|
static const int leftKey; /**< key-code for the cursor-left key */
|
|
static const int rightKey; /**< key-code for the cursor-right key */
|
|
static const int pageUpKey; /**< key-code for the page-up key */
|
|
static const int pageDownKey; /**< key-code for the page-down key */
|
|
static const int homeKey; /**< key-code for the home key */
|
|
static const int endKey; /**< key-code for the end key */
|
|
|
|
static const int F1Key; /**< key-code for the F1 key */
|
|
static const int F2Key; /**< key-code for the F2 key */
|
|
static const int F3Key; /**< key-code for the F3 key */
|
|
static const int F4Key; /**< key-code for the F4 key */
|
|
static const int F5Key; /**< key-code for the F5 key */
|
|
static const int F6Key; /**< key-code for the F6 key */
|
|
static const int F7Key; /**< key-code for the F7 key */
|
|
static const int F8Key; /**< key-code for the F8 key */
|
|
static const int F9Key; /**< key-code for the F9 key */
|
|
static const int F10Key; /**< key-code for the F10 key */
|
|
static const int F11Key; /**< key-code for the F11 key */
|
|
static const int F12Key; /**< key-code for the F12 key */
|
|
static const int F13Key; /**< key-code for the F13 key */
|
|
static const int F14Key; /**< key-code for the F14 key */
|
|
static const int F15Key; /**< key-code for the F15 key */
|
|
static const int F16Key; /**< key-code for the F16 key */
|
|
|
|
static const int numberPad0; /**< key-code for the 0 on the numeric keypad. */
|
|
static const int numberPad1; /**< key-code for the 1 on the numeric keypad. */
|
|
static const int numberPad2; /**< key-code for the 2 on the numeric keypad. */
|
|
static const int numberPad3; /**< key-code for the 3 on the numeric keypad. */
|
|
static const int numberPad4; /**< key-code for the 4 on the numeric keypad. */
|
|
static const int numberPad5; /**< key-code for the 5 on the numeric keypad. */
|
|
static const int numberPad6; /**< key-code for the 6 on the numeric keypad. */
|
|
static const int numberPad7; /**< key-code for the 7 on the numeric keypad. */
|
|
static const int numberPad8; /**< key-code for the 8 on the numeric keypad. */
|
|
static const int numberPad9; /**< key-code for the 9 on the numeric keypad. */
|
|
|
|
static const int numberPadAdd; /**< key-code for the add sign on the numeric keypad. */
|
|
static const int numberPadSubtract; /**< key-code for the subtract sign on the numeric keypad. */
|
|
static const int numberPadMultiply; /**< key-code for the multiply sign on the numeric keypad. */
|
|
static const int numberPadDivide; /**< key-code for the divide sign on the numeric keypad. */
|
|
static const int numberPadSeparator; /**< key-code for the comma on the numeric keypad. */
|
|
static const int numberPadDecimalPoint; /**< key-code for the decimal point sign on the numeric keypad. */
|
|
static const int numberPadEquals; /**< key-code for the equals key on the numeric keypad. */
|
|
static const int numberPadDelete; /**< key-code for the delete key on the numeric keypad. */
|
|
|
|
static const int playKey; /**< key-code for a multimedia 'play' key, (not all keyboards will have one) */
|
|
static const int stopKey; /**< key-code for a multimedia 'stop' key, (not all keyboards will have one) */
|
|
static const int fastForwardKey; /**< key-code for a multimedia 'fast-forward' key, (not all keyboards will have one) */
|
|
static const int rewindKey; /**< key-code for a multimedia 'rewind' key, (not all keyboards will have one) */
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
int keyCode;
|
|
ModifierKeys mods;
|
|
juce_wchar textCharacter;
|
|
};
|
|
|
|
#endif // __JUCE_KEYPRESS_JUCEHEADER__
|
|
/********* End of inlined file: juce_KeyPress.h *********/
|
|
|
|
class Component;
|
|
|
|
/**
|
|
Receives callbacks when keys are pressed.
|
|
|
|
You can add a key listener to a component to be informed when that component
|
|
gets key events. See the Component::addListener method for more details.
|
|
|
|
@see KeyPress, Component::addKeyListener, KeyPressMappingManager
|
|
*/
|
|
class JUCE_API KeyListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~KeyListener() {}
|
|
|
|
/** Called to indicate that a key has been pressed.
|
|
|
|
If your implementation returns true, then the key event is considered to have
|
|
been consumed, and will not be passed on to any other components. If it returns
|
|
false, then the key will be passed to other components that might want to use it.
|
|
|
|
@param key the keystroke, including modifier keys
|
|
@param originatingComponent the component that received the key event
|
|
@see keyStateChanged, Component::keyPressed
|
|
*/
|
|
virtual bool keyPressed (const KeyPress& key,
|
|
Component* originatingComponent) = 0;
|
|
|
|
/** Called when any key is pressed or released.
|
|
|
|
When this is called, classes that might be interested in
|
|
the state of one or more keys can use KeyPress::isKeyCurrentlyDown() to
|
|
check whether their key has changed.
|
|
|
|
If your implementation returns true, then the key event is considered to have
|
|
been consumed, and will not be passed on to any other components. If it returns
|
|
false, then the key will be passed to other components that might want to use it.
|
|
|
|
@param originatingComponent the component that received the key event
|
|
@param isKeyDown true if a key is being pressed, false if one is being released
|
|
@see KeyPress, Component::keyStateChanged
|
|
*/
|
|
virtual bool keyStateChanged (const bool isKeyDown, Component* originatingComponent);
|
|
|
|
private:
|
|
// (dummy method to cause a deliberate compile error - if you hit this, you need to update your
|
|
// subclass to use the new parameters to keyStateChanged)
|
|
virtual void keyStateChanged (Component*) {};
|
|
};
|
|
|
|
#endif // __JUCE_KEYLISTENER_JUCEHEADER__
|
|
/********* End of inlined file: juce_KeyListener.h *********/
|
|
|
|
/********* Start of inlined file: juce_KeyboardFocusTraverser.h *********/
|
|
#ifndef __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__
|
|
#define __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__
|
|
|
|
class Component;
|
|
|
|
/**
|
|
Controls the order in which focus moves between components.
|
|
|
|
The default algorithm used by this class to work out the order of traversal
|
|
is as follows:
|
|
- if two components both have an explicit focus order specified, then the
|
|
one with the lowest number comes first (see the Component::setExplicitFocusOrder()
|
|
method).
|
|
- any component with an explicit focus order greater than 0 comes before ones
|
|
that don't have an order specified.
|
|
- any unspecified components are traversed in a left-to-right, then top-to-bottom
|
|
order.
|
|
|
|
If you need traversal in a more customised way, you can create a subclass
|
|
of KeyboardFocusTraverser that uses your own algorithm, and use
|
|
Component::createFocusTraverser() to create it.
|
|
|
|
@see Component::setExplicitFocusOrder, Component::createFocusTraverser
|
|
*/
|
|
class JUCE_API KeyboardFocusTraverser
|
|
{
|
|
public:
|
|
KeyboardFocusTraverser();
|
|
|
|
/** Destructor. */
|
|
virtual ~KeyboardFocusTraverser();
|
|
|
|
/** Returns the component that should be given focus after the specified one
|
|
when moving "forwards".
|
|
|
|
The default implementation will return the next component which is to the
|
|
right of or below this one.
|
|
|
|
This may return 0 if there's no suitable candidate.
|
|
*/
|
|
virtual Component* getNextComponent (Component* current);
|
|
|
|
/** Returns the component that should be given focus after the specified one
|
|
when moving "backwards".
|
|
|
|
The default implementation will return the next component which is to the
|
|
left of or above this one.
|
|
|
|
This may return 0 if there's no suitable candidate.
|
|
*/
|
|
virtual Component* getPreviousComponent (Component* current);
|
|
|
|
/** Returns the component that should receive focus be default within the given
|
|
parent component.
|
|
|
|
The default implementation will just return the foremost child component that
|
|
wants focus.
|
|
|
|
This may return 0 if there's no suitable candidate.
|
|
*/
|
|
virtual Component* getDefaultComponent (Component* parentComponent);
|
|
};
|
|
|
|
#endif // __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__
|
|
/********* End of inlined file: juce_KeyboardFocusTraverser.h *********/
|
|
|
|
/********* Start of inlined file: juce_ImageEffectFilter.h *********/
|
|
#ifndef __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__
|
|
#define __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Graphics.h *********/
|
|
#ifndef __JUCE_GRAPHICS_JUCEHEADER__
|
|
#define __JUCE_GRAPHICS_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Font.h *********/
|
|
#ifndef __JUCE_FONT_JUCEHEADER__
|
|
#define __JUCE_FONT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Typeface.h *********/
|
|
#ifndef __JUCE_TYPEFACE_JUCEHEADER__
|
|
#define __JUCE_TYPEFACE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Path.h *********/
|
|
#ifndef __JUCE_PATH_JUCEHEADER__
|
|
#define __JUCE_PATH_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AffineTransform.h *********/
|
|
#ifndef __JUCE_AFFINETRANSFORM_JUCEHEADER__
|
|
#define __JUCE_AFFINETRANSFORM_JUCEHEADER__
|
|
|
|
/**
|
|
Represents a 2D affine-transformation matrix.
|
|
|
|
An affine transformation is a transformation such as a rotation, scale, shear,
|
|
resize or translation.
|
|
|
|
These are used for various 2D transformation tasks, e.g. with Path objects.
|
|
|
|
@see Path, Point, Line
|
|
*/
|
|
class JUCE_API AffineTransform
|
|
{
|
|
public:
|
|
|
|
/** Creates an identity transform. */
|
|
AffineTransform() throw();
|
|
|
|
/** Creates a copy of another transform. */
|
|
AffineTransform (const AffineTransform& other) throw();
|
|
|
|
/** Creates a transform from a set of raw matrix values.
|
|
|
|
The resulting matrix is:
|
|
|
|
(mat00 mat01 mat02)
|
|
(mat10 mat11 mat12)
|
|
( 0 0 1 )
|
|
*/
|
|
AffineTransform (const float mat00, const float mat01, const float mat02,
|
|
const float mat10, const float mat11, const float mat12) throw();
|
|
|
|
/** Copies from another AffineTransform object */
|
|
const AffineTransform& operator= (const AffineTransform& other) throw();
|
|
|
|
/** Compares two transforms. */
|
|
bool operator== (const AffineTransform& other) const throw();
|
|
|
|
/** Compares two transforms. */
|
|
bool operator!= (const AffineTransform& other) const throw();
|
|
|
|
/** A ready-to-use identity transform, which you can use to append other
|
|
transformations to.
|
|
|
|
e.g. @code
|
|
AffineTransform myTransform = AffineTransform::identity.rotated (.5f)
|
|
.scaled (2.0f);
|
|
|
|
@endcode
|
|
*/
|
|
static const AffineTransform identity;
|
|
|
|
/** Transforms a 2D co-ordinate using this matrix. */
|
|
void transformPoint (float& x,
|
|
float& y) const throw();
|
|
|
|
/** Transforms a 2D co-ordinate using this matrix. */
|
|
void transformPoint (double& x,
|
|
double& y) const throw();
|
|
|
|
/** Returns a new transform which is the same as this one followed by a translation. */
|
|
const AffineTransform translated (const float deltaX,
|
|
const float deltaY) const throw();
|
|
|
|
/** Returns a new transform which is a translation. */
|
|
static const AffineTransform translation (const float deltaX,
|
|
const float deltaY) throw();
|
|
|
|
/** Returns a transform which is the same as this one followed by a rotation.
|
|
|
|
The rotation is specified by a number of radians to rotate clockwise, centred around
|
|
the origin (0, 0).
|
|
*/
|
|
const AffineTransform rotated (const float angleInRadians) const throw();
|
|
|
|
/** Returns a transform which is the same as this one followed by a rotation about a given point.
|
|
|
|
The rotation is specified by a number of radians to rotate clockwise, centred around
|
|
the co-ordinates passed in.
|
|
*/
|
|
const AffineTransform rotated (const float angleInRadians,
|
|
const float pivotX,
|
|
const float pivotY) const throw();
|
|
|
|
/** Returns a new transform which is a rotation about (0, 0). */
|
|
static const AffineTransform rotation (const float angleInRadians) throw();
|
|
|
|
/** Returns a new transform which is a rotation about a given point. */
|
|
static const AffineTransform rotation (const float angleInRadians,
|
|
const float pivotX,
|
|
const float pivotY) throw();
|
|
|
|
/** Returns a transform which is the same as this one followed by a re-scaling.
|
|
|
|
The scaling is centred around the origin (0, 0).
|
|
*/
|
|
const AffineTransform scaled (const float factorX,
|
|
const float factorY) const throw();
|
|
|
|
/** Returns a new transform which is a re-scale about the origin. */
|
|
static const AffineTransform scale (const float factorX,
|
|
const float factorY) throw();
|
|
|
|
/** Returns a transform which is the same as this one followed by a shear.
|
|
|
|
The shear is centred around the origin (0, 0).
|
|
*/
|
|
const AffineTransform sheared (const float shearX,
|
|
const float shearY) const throw();
|
|
|
|
/** Returns a matrix which is the inverse operation of this one.
|
|
|
|
Some matrices don't have an inverse - in this case, the method will just return
|
|
an identity transform.
|
|
*/
|
|
const AffineTransform inverted() const throw();
|
|
|
|
/** Returns the result of concatenating another transformation after this one. */
|
|
const AffineTransform followedBy (const AffineTransform& other) const throw();
|
|
|
|
/** Returns true if this transform has no effect on points. */
|
|
bool isIdentity() const throw();
|
|
|
|
/** Returns true if this transform maps to a singularity - i.e. if it has no inverse. */
|
|
bool isSingularity() const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
/* The transform matrix is:
|
|
|
|
(mat00 mat01 mat02)
|
|
(mat10 mat11 mat12)
|
|
( 0 0 1 )
|
|
*/
|
|
float mat00, mat01, mat02;
|
|
float mat10, mat11, mat12;
|
|
|
|
private:
|
|
|
|
const AffineTransform followedBy (const float mat00, const float mat01, const float mat02,
|
|
const float mat10, const float mat11, const float mat12) const throw();
|
|
};
|
|
|
|
#endif // __JUCE_AFFINETRANSFORM_JUCEHEADER__
|
|
/********* End of inlined file: juce_AffineTransform.h *********/
|
|
|
|
/********* Start of inlined file: juce_Point.h *********/
|
|
#ifndef __JUCE_POINT_JUCEHEADER__
|
|
#define __JUCE_POINT_JUCEHEADER__
|
|
|
|
/**
|
|
A pair of (x, y) co-ordinates.
|
|
|
|
Uses 32-bit floating point accuracy.
|
|
|
|
@see Line, Path, AffineTransform
|
|
*/
|
|
class JUCE_API Point
|
|
{
|
|
public:
|
|
|
|
/** Creates a point with co-ordinates (0, 0). */
|
|
Point() throw();
|
|
|
|
/** Creates a copy of another point. */
|
|
Point (const Point& other) throw();
|
|
|
|
/** Creates a point from an (x, y) position. */
|
|
Point (const float x, const float y) throw();
|
|
|
|
/** Copies this point from another one.
|
|
@see setXY
|
|
*/
|
|
const Point& operator= (const Point& other) throw();
|
|
|
|
/** Destructor. */
|
|
~Point() throw();
|
|
|
|
/** Returns the point's x co-ordinate. */
|
|
inline float getX() const throw() { return x; }
|
|
|
|
/** Returns the point's y co-ordinate. */
|
|
inline float getY() const throw() { return y; }
|
|
|
|
/** Changes the point's x and y co-ordinates. */
|
|
void setXY (const float x,
|
|
const float y) throw();
|
|
|
|
/** Uses a transform to change the point's co-ordinates.
|
|
|
|
@see AffineTransform::transformPoint
|
|
*/
|
|
void applyTransform (const AffineTransform& transform) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
float x, y;
|
|
};
|
|
|
|
#endif // __JUCE_POINT_JUCEHEADER__
|
|
/********* End of inlined file: juce_Point.h *********/
|
|
|
|
/********* Start of inlined file: juce_Justification.h *********/
|
|
#ifndef __JUCE_JUSTIFICATION_JUCEHEADER__
|
|
#define __JUCE_JUSTIFICATION_JUCEHEADER__
|
|
|
|
/**
|
|
Represents a type of justification to be used when positioning graphical items.
|
|
|
|
e.g. it indicates whether something should be placed top-left, top-right,
|
|
centred, etc.
|
|
|
|
It is used in various places wherever this kind of information is needed.
|
|
*/
|
|
class JUCE_API Justification
|
|
{
|
|
public:
|
|
|
|
/** Creates a Justification object using a combination of flags. */
|
|
inline Justification (const int flags_) throw() : flags (flags_) {}
|
|
|
|
/** Creates a copy of another Justification object. */
|
|
Justification (const Justification& other) throw();
|
|
|
|
/** Copies another Justification object. */
|
|
const Justification& operator= (const Justification& other) throw();
|
|
|
|
/** Returns the raw flags that are set for this Justification object. */
|
|
inline int getFlags() const throw() { return flags; }
|
|
|
|
/** Tests a set of flags for this object.
|
|
|
|
@returns true if any of the flags passed in are set on this object.
|
|
*/
|
|
inline bool testFlags (const int flagsToTest) const throw() { return (flags & flagsToTest) != 0; }
|
|
|
|
/** Returns just the flags from this object that deal with vertical layout. */
|
|
int getOnlyVerticalFlags() const throw();
|
|
|
|
/** Returns just the flags from this object that deal with horizontal layout. */
|
|
int getOnlyHorizontalFlags() const throw();
|
|
|
|
/** Adjusts the position of a rectangle to fit it into a space.
|
|
|
|
The (x, y) position of the rectangle will be updated to position it inside the
|
|
given space according to the justification flags.
|
|
*/
|
|
void applyToRectangle (int& x, int& y,
|
|
const int w, const int h,
|
|
const int spaceX, const int spaceY,
|
|
const int spaceW, const int spaceH) const throw();
|
|
|
|
/** Flag values that can be combined and used in the constructor. */
|
|
enum
|
|
{
|
|
|
|
/** Indicates that the item should be aligned against the left edge of the available space. */
|
|
left = 1,
|
|
|
|
/** Indicates that the item should be aligned against the right edge of the available space. */
|
|
right = 2,
|
|
|
|
/** Indicates that the item should be placed in the centre between the left and right
|
|
sides of the available space. */
|
|
horizontallyCentred = 4,
|
|
|
|
/** Indicates that the item should be aligned against the top edge of the available space. */
|
|
top = 8,
|
|
|
|
/** Indicates that the item should be aligned against the bottom edge of the available space. */
|
|
bottom = 16,
|
|
|
|
/** Indicates that the item should be placed in the centre between the top and bottom
|
|
sides of the available space. */
|
|
verticallyCentred = 32,
|
|
|
|
/** Indicates that lines of text should be spread out to fill the maximum width
|
|
available, so that both margins are aligned vertically.
|
|
*/
|
|
horizontallyJustified = 64,
|
|
|
|
/** Indicates that the item should be centred vertically and horizontally.
|
|
|
|
This is equivalent to (horizontallyCentred | verticallyCentred)
|
|
*/
|
|
centred = 36,
|
|
|
|
/** Indicates that the item should be centred vertically but placed on the left hand side.
|
|
|
|
This is equivalent to (left | verticallyCentred)
|
|
*/
|
|
centredLeft = 33,
|
|
|
|
/** Indicates that the item should be centred vertically but placed on the right hand side.
|
|
|
|
This is equivalent to (right | verticallyCentred)
|
|
*/
|
|
centredRight = 34,
|
|
|
|
/** Indicates that the item should be centred horizontally and placed at the top.
|
|
|
|
This is equivalent to (horizontallyCentred | top)
|
|
*/
|
|
centredTop = 12,
|
|
|
|
/** Indicates that the item should be centred horizontally and placed at the bottom.
|
|
|
|
This is equivalent to (horizontallyCentred | bottom)
|
|
*/
|
|
centredBottom = 20,
|
|
|
|
/** Indicates that the item should be placed in the top-left corner.
|
|
|
|
This is equivalent to (left | top)
|
|
*/
|
|
topLeft = 9,
|
|
|
|
/** Indicates that the item should be placed in the top-right corner.
|
|
|
|
This is equivalent to (right | top)
|
|
*/
|
|
topRight = 10,
|
|
|
|
/** Indicates that the item should be placed in the bottom-left corner.
|
|
|
|
This is equivalent to (left | bottom)
|
|
*/
|
|
bottomLeft = 17,
|
|
|
|
/** Indicates that the item should be placed in the bottom-left corner.
|
|
|
|
This is equivalent to (right | bottom)
|
|
*/
|
|
bottomRight = 18
|
|
};
|
|
|
|
private:
|
|
|
|
int flags;
|
|
};
|
|
|
|
#endif // __JUCE_JUSTIFICATION_JUCEHEADER__
|
|
/********* End of inlined file: juce_Justification.h *********/
|
|
|
|
/**
|
|
A path is a sequence of lines and curves that may either form a closed shape
|
|
or be open-ended.
|
|
|
|
To use a path, you can create an empty one, then add lines and curves to it
|
|
to create shapes, then it can be rendered by a Graphics context or used
|
|
for geometric operations.
|
|
|
|
e.g. @code
|
|
Path myPath;
|
|
|
|
myPath.startNewSubPath (10.0f, 10.0f); // move the current position to (10, 10)
|
|
myPath.lineTo (100.0f, 200.0f); // draw a line from here to (100, 200)
|
|
myPath.quadraticTo (0.0f, 150.0f, 5.0f, 50.0f); // draw a curve that ends at (5, 50)
|
|
myPath.closeSubPath(); // close the subpath with a line back to (10, 10)
|
|
|
|
// add an ellipse as well, which will form a second sub-path within the path..
|
|
myPath.addEllipse (50.0f, 50.0f, 40.0f, 30.0f);
|
|
|
|
// double the width of the whole thing..
|
|
myPath.applyTransform (AffineTransform::scale (2.0f, 1.0f));
|
|
|
|
// and draw it to a graphics context with a 5-pixel thick outline.
|
|
g.strokePath (myPath, PathStrokeType (5.0f));
|
|
|
|
@endcode
|
|
|
|
A path object can actually contain multiple sub-paths, which may themselves
|
|
be open or closed.
|
|
|
|
@see PathFlatteningIterator, PathStrokeType, Graphics
|
|
*/
|
|
class JUCE_API Path : private ArrayAllocationBase <float>
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty path. */
|
|
Path() throw();
|
|
|
|
/** Creates a copy of another path. */
|
|
Path (const Path& other) throw();
|
|
|
|
/** Destructor. */
|
|
~Path() throw();
|
|
|
|
/** Copies this path from another one. */
|
|
const Path& operator= (const Path& other) throw();
|
|
|
|
/** Returns true if the path doesn't contain any lines or curves. */
|
|
bool isEmpty() const throw();
|
|
|
|
/** Returns the smallest rectangle that contains all points within the path.
|
|
*/
|
|
void getBounds (float& x, float& y,
|
|
float& w, float& h) const throw();
|
|
|
|
/** Returns the smallest rectangle that contains all points within the path
|
|
after it's been transformed with the given tranasform matrix.
|
|
*/
|
|
void getBoundsTransformed (const AffineTransform& transform,
|
|
float& x, float& y,
|
|
float& w, float& h) const throw();
|
|
|
|
/** Checks whether a point lies within the path.
|
|
|
|
This is only relevent for closed paths (see closeSubPath()), and
|
|
may produce false results if used on a path which has open sub-paths.
|
|
|
|
The path's winding rule is taken into account by this method.
|
|
|
|
The tolerence parameter is passed to the PathFlatteningIterator that
|
|
is used to trace the path - for more info about it, see the notes for
|
|
the PathFlatteningIterator constructor.
|
|
|
|
@see closeSubPath, setUsingNonZeroWinding
|
|
*/
|
|
bool contains (const float x,
|
|
const float y,
|
|
const float tolerence = 10.0f) const throw();
|
|
|
|
/** Checks whether a line crosses the path.
|
|
|
|
This will return positive if the line crosses any of the paths constituent
|
|
lines or curves. It doesn't take into account whether the line is inside
|
|
or outside the path, or whether the path is open or closed.
|
|
|
|
The tolerence parameter is passed to the PathFlatteningIterator that
|
|
is used to trace the path - for more info about it, see the notes for
|
|
the PathFlatteningIterator constructor.
|
|
*/
|
|
bool intersectsLine (const float x1, const float y1,
|
|
const float x2, const float y2,
|
|
const float tolerence = 10.0f) throw();
|
|
|
|
/** Removes all lines and curves, resetting the path completely. */
|
|
void clear() throw();
|
|
|
|
/** Begins a new subpath with a given starting position.
|
|
|
|
This will move the path's current position to the co-ordinates passed in and
|
|
make it ready to draw lines or curves starting from this position.
|
|
|
|
After adding whatever lines and curves are needed, you can either
|
|
close the current sub-path using closeSubPath() or call startNewSubPath()
|
|
to move to a new sub-path, leaving the old one open-ended.
|
|
|
|
@see lineTo, quadraticTo, cubicTo, closeSubPath
|
|
*/
|
|
void startNewSubPath (const float startX,
|
|
const float startY) throw();
|
|
|
|
/** Closes a the current sub-path with a line back to its start-point.
|
|
|
|
When creating a closed shape such as a triangle, don't use 3 lineTo()
|
|
calls - instead use two lineTo() calls, followed by a closeSubPath()
|
|
to join the final point back to the start.
|
|
|
|
This ensures that closes shapes are recognised as such, and this is
|
|
important for tasks like drawing strokes, which needs to know whether to
|
|
draw end-caps or not.
|
|
|
|
@see startNewSubPath, lineTo, quadraticTo, cubicTo, closeSubPath
|
|
*/
|
|
void closeSubPath() throw();
|
|
|
|
/** Adds a line from the shape's last position to a new end-point.
|
|
|
|
This will connect the end-point of the last line or curve that was added
|
|
to a new point, using a straight line.
|
|
|
|
See the class description for an example of how to add lines and curves to a path.
|
|
|
|
@see startNewSubPath, quadraticTo, cubicTo, closeSubPath
|
|
*/
|
|
void lineTo (const float endX,
|
|
const float endY) throw();
|
|
|
|
/** Adds a quadratic bezier curve from the shape's last position to a new position.
|
|
|
|
This will connect the end-point of the last line or curve that was added
|
|
to a new point, using a quadratic spline with one control-point.
|
|
|
|
See the class description for an example of how to add lines and curves to a path.
|
|
|
|
@see startNewSubPath, lineTo, cubicTo, closeSubPath
|
|
*/
|
|
void quadraticTo (const float controlPointX,
|
|
const float controlPointY,
|
|
const float endPointX,
|
|
const float endPointY) throw();
|
|
|
|
/** Adds a cubic bezier curve from the shape's last position to a new position.
|
|
|
|
This will connect the end-point of the last line or curve that was added
|
|
to a new point, using a cubic spline with two control-points.
|
|
|
|
See the class description for an example of how to add lines and curves to a path.
|
|
|
|
@see startNewSubPath, lineTo, quadraticTo, closeSubPath
|
|
*/
|
|
void cubicTo (const float controlPoint1X,
|
|
const float controlPoint1Y,
|
|
const float controlPoint2X,
|
|
const float controlPoint2Y,
|
|
const float endPointX,
|
|
const float endPointY) throw();
|
|
|
|
/** Returns the last point that was added to the path by one of the drawing methods.
|
|
*/
|
|
const Point getCurrentPosition() const;
|
|
|
|
/** Adds a rectangle to the path.
|
|
|
|
The rectangle is added as a new sub-path. (Any currently open paths will be
|
|
left open).
|
|
|
|
@see addRoundedRectangle, addTriangle
|
|
*/
|
|
void addRectangle (const float x, const float y,
|
|
const float w, const float h) throw();
|
|
|
|
/** Adds a rectangle with rounded corners to the path.
|
|
|
|
The rectangle is added as a new sub-path. (Any currently open paths will be
|
|
left open).
|
|
|
|
@see addRectangle, addTriangle
|
|
*/
|
|
void addRoundedRectangle (const float x, const float y,
|
|
const float w, const float h,
|
|
float cornerSize) throw();
|
|
|
|
/** Adds a rectangle with rounded corners to the path.
|
|
|
|
The rectangle is added as a new sub-path. (Any currently open paths will be
|
|
left open).
|
|
|
|
@see addRectangle, addTriangle
|
|
*/
|
|
void addRoundedRectangle (const float x, const float y,
|
|
const float w, const float h,
|
|
float cornerSizeX,
|
|
float cornerSizeY) throw();
|
|
|
|
/** Adds a triangle to the path.
|
|
|
|
The triangle is added as a new closed sub-path. (Any currently open paths will be
|
|
left open).
|
|
|
|
Note that whether the vertices are specified in clockwise or anticlockwise
|
|
order will affect how the triangle is filled when it overlaps other
|
|
shapes (the winding order setting will affect this of course).
|
|
*/
|
|
void addTriangle (const float x1, const float y1,
|
|
const float x2, const float y2,
|
|
const float x3, const float y3) throw();
|
|
|
|
/** Adds a quadrilateral to the path.
|
|
|
|
The quad is added as a new closed sub-path. (Any currently open paths will be
|
|
left open).
|
|
|
|
Note that whether the vertices are specified in clockwise or anticlockwise
|
|
order will affect how the quad is filled when it overlaps other
|
|
shapes (the winding order setting will affect this of course).
|
|
*/
|
|
void addQuadrilateral (const float x1, const float y1,
|
|
const float x2, const float y2,
|
|
const float x3, const float y3,
|
|
const float x4, const float y4) throw();
|
|
|
|
/** Adds an ellipse to the path.
|
|
|
|
The shape is added as a new sub-path. (Any currently open paths will be
|
|
left open).
|
|
|
|
@see addArc
|
|
*/
|
|
void addEllipse (const float x, const float y,
|
|
const float width, const float height) throw();
|
|
|
|
/** Adds an elliptical arc to the current path.
|
|
|
|
Note that when specifying the start and end angles, the curve will be drawn either clockwise
|
|
or anti-clockwise according to whether the end angle is greater than the start. This means
|
|
that sometimes you may need to use values greater than 2*Pi for the end angle.
|
|
|
|
@param x the left-hand edge of the rectangle in which the elliptical outline fits
|
|
@param y the top edge of the rectangle in which the elliptical outline fits
|
|
@param width the width of the rectangle in which the elliptical outline fits
|
|
@param height the height of the rectangle in which the elliptical outline fits
|
|
@param fromRadians the angle (clockwise) in radians at which to start the arc segment (where 0 is the
|
|
top-centre of the ellipse)
|
|
@param toRadians the angle (clockwise) in radians at which to end the arc segment (where 0 is the
|
|
top-centre of the ellipse). This angle can be greater than 2*Pi, so for example to
|
|
draw a curve clockwise from the 9 o'clock position to the 3 o'clock position via
|
|
12 o'clock, you'd use 1.5*Pi and 2.5*Pi as the start and finish points.
|
|
@param startAsNewSubPath if true, the arc will begin a new subpath from its starting point; if false,
|
|
it will be added to the current sub-path, continuing from the current postition
|
|
|
|
@see addCentredArc, arcTo, addPieSegment, addEllipse
|
|
*/
|
|
void addArc (const float x, const float y,
|
|
const float width, const float height,
|
|
const float fromRadians,
|
|
const float toRadians,
|
|
const bool startAsNewSubPath = false) throw();
|
|
|
|
/** Adds an arc which is centred at a given point, and can have a rotation specified.
|
|
|
|
Note that when specifying the start and end angles, the curve will be drawn either clockwise
|
|
or anti-clockwise according to whether the end angle is greater than the start. This means
|
|
that sometimes you may need to use values greater than 2*Pi for the end angle.
|
|
|
|
@param centreX the centre x of the ellipse
|
|
@param centreY the centre y of the ellipse
|
|
@param radiusX the horizontal radius of the ellipse
|
|
@param radiusY the vertical radius of the ellipse
|
|
@param rotationOfEllipse an angle by which the whole ellipse should be rotated about its centre, in radians (clockwise)
|
|
@param fromRadians the angle (clockwise) in radians at which to start the arc segment (where 0 is the
|
|
top-centre of the ellipse)
|
|
@param toRadians the angle (clockwise) in radians at which to end the arc segment (where 0 is the
|
|
top-centre of the ellipse). This angle can be greater than 2*Pi, so for example to
|
|
draw a curve clockwise from the 9 o'clock position to the 3 o'clock position via
|
|
12 o'clock, you'd use 1.5*Pi and 2.5*Pi as the start and finish points.
|
|
@param startAsNewSubPath if true, the arc will begin a new subpath from its starting point; if false,
|
|
it will be added to the current sub-path, continuing from the current postition
|
|
|
|
@see addArc, arcTo
|
|
*/
|
|
void addCentredArc (const float centreX, const float centreY,
|
|
const float radiusX, const float radiusY,
|
|
const float rotationOfEllipse,
|
|
const float fromRadians,
|
|
const float toRadians,
|
|
const bool startAsNewSubPath = false) throw();
|
|
|
|
/** Adds a "pie-chart" shape to the path.
|
|
|
|
The shape is added as a new sub-path. (Any currently open paths will be
|
|
left open).
|
|
|
|
Note that when specifying the start and end angles, the curve will be drawn either clockwise
|
|
or anti-clockwise according to whether the end angle is greater than the start. This means
|
|
that sometimes you may need to use values greater than 2*Pi for the end angle.
|
|
|
|
@param x the left-hand edge of the rectangle in which the elliptical outline fits
|
|
@param y the top edge of the rectangle in which the elliptical outline fits
|
|
@param width the width of the rectangle in which the elliptical outline fits
|
|
@param height the height of the rectangle in which the elliptical outline fits
|
|
@param fromRadians the angle (clockwise) in radians at which to start the arc segment (where 0 is the
|
|
top-centre of the ellipse)
|
|
@param toRadians the angle (clockwise) in radians at which to end the arc segment (where 0 is the
|
|
top-centre of the ellipse)
|
|
@param innerCircleProportionalSize if this is > 0, then the pie will be drawn as a curved band around a hollow
|
|
ellipse at its centre, where this value indicates the inner ellipse's size with
|
|
respect to the outer one.
|
|
|
|
@see addArc
|
|
*/
|
|
void addPieSegment (const float x, const float y,
|
|
const float width, const float height,
|
|
const float fromRadians,
|
|
const float toRadians,
|
|
const float innerCircleProportionalSize);
|
|
|
|
/** Adds a line with a specified thickness.
|
|
|
|
The line is added as a new closed sub-path. (Any currently open paths will be
|
|
left open).
|
|
|
|
@see addArrow
|
|
*/
|
|
void addLineSegment (const float startX, const float startY,
|
|
const float endX, const float endY,
|
|
float lineThickness) throw();
|
|
|
|
/** Adds a line with an arrowhead on the end.
|
|
|
|
The arrow is added as a new closed sub-path. (Any currently open paths will be
|
|
left open).
|
|
*/
|
|
void addArrow (const float startX, const float startY,
|
|
const float endX, const float endY,
|
|
float lineThickness,
|
|
float arrowheadWidth,
|
|
float arrowheadLength) throw();
|
|
|
|
/** Adds a star shape to the path.
|
|
|
|
*/
|
|
void addStar (const float centreX,
|
|
const float centreY,
|
|
const int numberOfPoints,
|
|
const float innerRadius,
|
|
const float outerRadius,
|
|
const float startAngle = 0.0f);
|
|
|
|
/** Adds a speech-bubble shape to the path.
|
|
|
|
@param bodyX the left of the main body area of the bubble
|
|
@param bodyY the top of the main body area of the bubble
|
|
@param bodyW the width of the main body area of the bubble
|
|
@param bodyH the height of the main body area of the bubble
|
|
@param cornerSize the amount by which to round off the corners of the main body rectangle
|
|
@param arrowTipX the x position that the tip of the arrow should connect to
|
|
@param arrowTipY the y position that the tip of the arrow should connect to
|
|
@param whichSide the side to connect the arrow to: 0 = top, 1 = left, 2 = bottom, 3 = right
|
|
@param arrowPositionAlongEdgeProportional how far along the edge of the main rectangle the
|
|
arrow's base should be - this is a proportional distance between 0 and 1.0
|
|
@param arrowWidth how wide the base of the arrow should be where it joins the main rectangle
|
|
*/
|
|
void addBubble (float bodyX, float bodyY,
|
|
float bodyW, float bodyH,
|
|
float cornerSize,
|
|
float arrowTipX,
|
|
float arrowTipY,
|
|
int whichSide,
|
|
float arrowPositionAlongEdgeProportional,
|
|
float arrowWidth);
|
|
|
|
/** Adds another path to this one.
|
|
|
|
The new path is added as a new sub-path. (Any currently open paths in this
|
|
path will be left open).
|
|
|
|
@param pathToAppend the path to add
|
|
*/
|
|
void addPath (const Path& pathToAppend) throw();
|
|
|
|
/** Adds another path to this one, transforming it on the way in.
|
|
|
|
The new path is added as a new sub-path, its points being transformed by the given
|
|
matrix before being added.
|
|
|
|
@param pathToAppend the path to add
|
|
@param transformToApply an optional transform to apply to the incoming vertices
|
|
*/
|
|
void addPath (const Path& pathToAppend,
|
|
const AffineTransform& transformToApply) throw();
|
|
|
|
/** Swaps the contents of this path with another one.
|
|
|
|
The internal data of the two paths is swapped over, so this is much faster than
|
|
copying it to a temp variable and back.
|
|
*/
|
|
void swapWithPath (Path& other);
|
|
|
|
/** Applies a 2D transform to all the vertices in the path.
|
|
|
|
@see AffineTransform, scaleToFit, getTransformToScaleToFit
|
|
*/
|
|
void applyTransform (const AffineTransform& transform) throw();
|
|
|
|
/** Rescales this path to make it fit neatly into a given space.
|
|
|
|
This is effectively a quick way of calling
|
|
applyTransform (getTransformToScaleToFit (x, y, w, h, preserveProportions))
|
|
|
|
@param x the x position of the rectangle to fit the path inside
|
|
@param y the y position of the rectangle to fit the path inside
|
|
@param width the width of the rectangle to fit the path inside
|
|
@param height the height of the rectangle to fit the path inside
|
|
@param preserveProportions if true, it will fit the path into the space without altering its
|
|
horizontal/vertical scale ratio; if false, it will distort the
|
|
path to fill the specified ratio both horizontally and vertically
|
|
|
|
@see applyTransform, getTransformToScaleToFit
|
|
*/
|
|
void scaleToFit (const float x, const float y,
|
|
const float width, const float height,
|
|
const bool preserveProportions) throw();
|
|
|
|
/** Returns a transform that can be used to rescale the path to fit into a given space.
|
|
|
|
@param x the x position of the rectangle to fit the path inside
|
|
@param y the y position of the rectangle to fit the path inside
|
|
@param width the width of the rectangle to fit the path inside
|
|
@param height the height of the rectangle to fit the path inside
|
|
@param preserveProportions if true, it will fit the path into the space without altering its
|
|
horizontal/vertical scale ratio; if false, it will distort the
|
|
path to fill the specified ratio both horizontally and vertically
|
|
@param justificationType if the proportions are preseved, the resultant path may be smaller
|
|
than the available rectangle, so this describes how it should be
|
|
positioned within the space.
|
|
@returns an appropriate transformation
|
|
|
|
@see applyTransform, scaleToFit
|
|
|
|
*/
|
|
const AffineTransform getTransformToScaleToFit (const float x, const float y,
|
|
const float width, const float height,
|
|
const bool preserveProportions,
|
|
const Justification& justificationType = Justification::centred) const throw();
|
|
|
|
/** Creates a version of this path where all sharp corners have been replaced by curves.
|
|
|
|
Wherever two lines meet at an angle, this will replace the corner with a curve
|
|
of the given radius.
|
|
*/
|
|
const Path createPathWithRoundedCorners (const float cornerRadius) const throw();
|
|
|
|
/** Changes the winding-rule to be used when filling the path.
|
|
|
|
If set to true (which is the default), then the path uses a non-zero-winding rule
|
|
to determine which points are inside the path. If set to false, it uses an
|
|
alternate-winding rule.
|
|
|
|
The winding-rule comes into play when areas of the shape overlap other
|
|
areas, and determines whether the overlapping regions are considered to be
|
|
inside or outside.
|
|
|
|
Changing this value just sets a flag - it doesn't affect the contents of the
|
|
path.
|
|
|
|
@see isUsingNonZeroWinding
|
|
*/
|
|
void setUsingNonZeroWinding (const bool isNonZeroWinding) throw();
|
|
|
|
/** Returns the flag that indicates whether the path should use a non-zero winding rule.
|
|
|
|
The default for a new path is true.
|
|
|
|
@see setUsingNonZeroWinding
|
|
*/
|
|
bool isUsingNonZeroWinding() const throw() { return useNonZeroWinding; }
|
|
|
|
/** Iterates the lines and curves that a path contains.
|
|
|
|
@see Path, PathFlatteningIterator
|
|
*/
|
|
class JUCE_API Iterator
|
|
{
|
|
public:
|
|
|
|
Iterator (const Path& path);
|
|
~Iterator();
|
|
|
|
/** Moves onto the next element in the path.
|
|
|
|
If this returns false, there are no more elements. If it returns true,
|
|
the elementType variable will be set to the type of the current element,
|
|
and some of the x and y variables will be filled in with values.
|
|
*/
|
|
bool next();
|
|
|
|
enum PathElementType
|
|
{
|
|
startNewSubPath, /**< For this type, x1 and y1 will be set to indicate the first point in the subpath. */
|
|
lineTo, /**< For this type, x1 and y1 indicate the end point of the line. */
|
|
quadraticTo, /**< For this type, x1, y1, x2, y2 indicate the control point and endpoint of a quadratic curve. */
|
|
cubicTo, /**< For this type, x1, y1, x2, y2, x3, y3 indicate the two control points and the endpoint of a cubic curve. */
|
|
closePath /**< Indicates that the sub-path is being closed. None of the x or y values are valid in this case. */
|
|
};
|
|
|
|
PathElementType elementType;
|
|
|
|
float x1, y1, x2, y2, x3, y3;
|
|
|
|
private:
|
|
const Path& path;
|
|
int index;
|
|
|
|
Iterator (const Iterator&);
|
|
const Iterator& operator= (const Iterator&);
|
|
};
|
|
|
|
/** Loads a stored path from a data stream.
|
|
|
|
The data in the stream must have been written using writePathToStream().
|
|
|
|
Note that this will append the stored path to whatever is currently in
|
|
this path, so you might need to call clear() beforehand.
|
|
|
|
@see loadPathFromData, writePathToStream
|
|
*/
|
|
void loadPathFromStream (InputStream& source);
|
|
|
|
/** Loads a stored path from a block of data.
|
|
|
|
This is similar to loadPathFromStream(), but just reads from a block
|
|
of data. Useful if you're including stored shapes in your code as a
|
|
block of static data.
|
|
|
|
@see loadPathFromStream, writePathToStream
|
|
*/
|
|
void loadPathFromData (const unsigned char* const data,
|
|
const int numberOfBytes) throw();
|
|
|
|
/** Stores the path by writing it out to a stream.
|
|
|
|
After writing out a path, you can reload it using loadPathFromStream().
|
|
|
|
@see loadPathFromStream, loadPathFromData
|
|
*/
|
|
void writePathToStream (OutputStream& destination) const;
|
|
|
|
/** Creates a string containing a textual representation of this path.
|
|
@see restoreFromString
|
|
*/
|
|
const String toString() const;
|
|
|
|
/** Restores this path from a string that was created with the toString() method.
|
|
@see toString()
|
|
*/
|
|
void restoreFromString (const String& stringVersion);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class PathFlatteningIterator;
|
|
friend class Path::Iterator;
|
|
int numElements;
|
|
float pathXMin, pathXMax, pathYMin, pathYMax;
|
|
bool useNonZeroWinding;
|
|
|
|
static const float lineMarker;
|
|
static const float moveMarker;
|
|
static const float quadMarker;
|
|
static const float cubicMarker;
|
|
static const float closeSubPathMarker;
|
|
};
|
|
|
|
#endif // __JUCE_PATH_JUCEHEADER__
|
|
/********* End of inlined file: juce_Path.h *********/
|
|
|
|
class Font;
|
|
class Typeface;
|
|
|
|
/**
|
|
Stores information about the shape and kerning of one of the glyphs in a Typeface.
|
|
|
|
@see Typeface, PositionedGlyph, GlyphArrangement
|
|
*/
|
|
class JUCE_API TypefaceGlyphInfo
|
|
{
|
|
public:
|
|
|
|
/** Returns the path that describes the glyph's outline.
|
|
|
|
This is normalised to a height of 1.0, and its origin is the
|
|
left-hand edge of the glyph's baseline.
|
|
*/
|
|
const Path& getPath() const throw() { return path; }
|
|
|
|
/** Returns the unicode character that this glyph represents. */
|
|
juce_wchar getCharacter() const throw() { return character; }
|
|
|
|
bool isWhitespace() const throw() { return CharacterFunctions::isWhitespace (character); }
|
|
|
|
/** Returns the distance to leave between this and a following character.
|
|
|
|
The value returned is expressed as a proportion of the font's height.
|
|
*/
|
|
float getHorizontalSpacing (const juce_wchar subsequentCharacter) const throw();
|
|
|
|
/** Returns the typeface that this glyph belongs to. */
|
|
Typeface* getTypeface() const throw() { return typeface; }
|
|
|
|
private:
|
|
|
|
friend class Typeface;
|
|
|
|
struct KerningPair
|
|
{
|
|
juce_wchar character2;
|
|
float kerningAmount;
|
|
};
|
|
|
|
const juce_wchar character;
|
|
const Path path;
|
|
float width;
|
|
MemoryBlock kerningPairs;
|
|
Typeface* const typeface;
|
|
|
|
TypefaceGlyphInfo (const juce_wchar character,
|
|
const Path& shape,
|
|
const float horizontalSeparation,
|
|
Typeface* const typeface) throw();
|
|
~TypefaceGlyphInfo() throw();
|
|
|
|
KerningPair& getKerningPair (const int index) const throw();
|
|
int getNumKerningPairs() const throw();
|
|
|
|
void addKerningPair (const juce_wchar subsequentCharacter,
|
|
const float extraKerningAmount) throw();
|
|
|
|
const TypefaceGlyphInfo& operator= (const TypefaceGlyphInfo&);
|
|
};
|
|
|
|
/**
|
|
Represents a size-independent system font.
|
|
|
|
A Font object represents a particular Typeface along with a specific size,
|
|
style, kerning, scale, etc, wheras the Typeface is just a generalised description
|
|
of the shapes of the glyphs and their properties.
|
|
|
|
*/
|
|
class JUCE_API Typeface : public ReferenceCountedObject
|
|
{
|
|
public:
|
|
|
|
/** Tries to load a named system font and to initialise all the glyphs
|
|
appropriately from it.
|
|
|
|
@param faceName the name of the typeface, e.g. "Times"
|
|
@param bold whether to try to find a bold version of the font (may not always be available)
|
|
@param italic whether to try to find an italicised version of the font (may not always be available)
|
|
*/
|
|
Typeface (const String& faceName,
|
|
const bool bold,
|
|
const bool italic);
|
|
|
|
/** Creates a copy of another typeface */
|
|
Typeface (const Typeface& other);
|
|
|
|
/** Destructor. */
|
|
~Typeface();
|
|
|
|
/** Copies another typeface over this one. */
|
|
const Typeface& operator= (const Typeface& other) throw();
|
|
|
|
/** Returns a unique ID for the typeface.
|
|
|
|
This is based on the name and style, so can be used to compare two Typeface objects.
|
|
*/
|
|
int hashCode() const throw() { return hash; }
|
|
|
|
/** Returns the name of the typeface, e.g. "Times", "Verdana", etc */
|
|
const String& getName() const throw() { return typefaceName; }
|
|
|
|
/** Returns the font's ascent as a proportion of its height. */
|
|
float getAscent() const throw() { return ascent; }
|
|
|
|
/** Returns true if the font is flagged as being bold. */
|
|
bool isBold() const throw() { return bold; }
|
|
|
|
/** Returns true if the typeface's 'italic' flag is set. */
|
|
bool isItalic() const throw() { return italic; }
|
|
|
|
/** Finds the Path that describes the outline shape of a character.
|
|
|
|
The height of the path is normalised to 1.0 (i.e. a distance of 1.0 is the
|
|
height of the font).
|
|
|
|
This may return 0 if the typeface has no characters, but if the character
|
|
that is asked for is not found, it will first try to return a default
|
|
character instead.
|
|
*/
|
|
const Path* getOutlineForGlyph (const juce_wchar character) throw();
|
|
|
|
/** Tries to find the information describing a glyph for this character.
|
|
|
|
If there isn't a glyph specifically for the character it will return
|
|
a default glyph instead; if the typeface is empty, it may return a null
|
|
pointer.
|
|
*/
|
|
const TypefaceGlyphInfo* getGlyph (const juce_wchar character) throw();
|
|
|
|
/** Deletes all the glyphs and kerning data fom the typeface. */
|
|
void clear() throw();
|
|
|
|
/** Adds a glyph to the typeface.
|
|
|
|
This is typically only called by the platform-specific code that generates
|
|
the typeface from a system font.
|
|
*/
|
|
void addGlyph (const juce_wchar character,
|
|
const Path& path,
|
|
const float horizontalSpacing) throw();
|
|
|
|
/** Adds a kerning distance to the typeface.
|
|
|
|
The extra amount passed in is expressed as a proportion of the font's
|
|
height, normalised to 1.0.
|
|
|
|
This is typically only called by the platform-specific code that generates
|
|
the typeface from a system font.
|
|
*/
|
|
void addKerningPair (const juce_wchar firstChar,
|
|
const juce_wchar secondChar,
|
|
const float extraAmount) throw();
|
|
|
|
/** Sets the typeface's name.
|
|
|
|
This is typically only called by the platform-specific code that generates
|
|
the typeface from a system font. Calling this method won't actually affect
|
|
the underlying font being used.
|
|
*/
|
|
void setName (const String& name) throw();
|
|
|
|
/** Sets the font's ascent value, as a proportion of the font height.
|
|
|
|
This is typically only called by the platform-specific code that generates
|
|
the typeface from a system font.
|
|
*/
|
|
void setAscent (const float newAscent) throw();
|
|
|
|
/** Sets the typeface's 'bold' flag.
|
|
|
|
This is typically only called by the platform-specific code that generates
|
|
the typeface from a system font.
|
|
*/
|
|
void setBold (const bool shouldBeBold) throw();
|
|
|
|
/** Sets the typeface's 'italic' flag.
|
|
|
|
This is typically only called by the platform-specific code that generates
|
|
the typeface from a system font.
|
|
*/
|
|
void setItalic (const bool shouldBeItalic) throw();
|
|
|
|
/** Changes the character index to use as the default character.
|
|
|
|
This is the character that gets returned for characters which don't have a
|
|
glyph set for them.
|
|
*/
|
|
void setDefaultCharacter (const juce_wchar newDefaultCharacter) throw();
|
|
|
|
/** Creates a typeface from data created using Typeface::serialise().
|
|
|
|
This will attempt to load a compressed typeface that was created using
|
|
the Typeface::serialise() method. This is handy if you want to store
|
|
a typeface in your application as a binary blob, and use it without
|
|
having to actually install it on the computer.
|
|
|
|
@see Typeface::serialise()
|
|
*/
|
|
Typeface (InputStream& serialisedTypefaceStream);
|
|
|
|
/** Writes the typeface to a stream (using a proprietary format).
|
|
|
|
This lets you save a typeface and reload it using the
|
|
Typeface::Typeface (InputStream&) constructor. The data's saved in
|
|
a compressed format.
|
|
|
|
@see Typeface::Typeface (InputStream&)
|
|
*/
|
|
void serialise (OutputStream& outputStream);
|
|
|
|
/** A name that represents the default sans-serif typeface name.
|
|
|
|
Note that this is NOT the platform-specific typeface name (e.g. "Times"), but
|
|
is a generic string that represents whatever that font is, such as "DefaultSans".
|
|
|
|
If you try to create a typeface with this name, the global default LookAndFeel
|
|
object will be asked to provide an appropriate typeface.
|
|
*/
|
|
static const tchar* defaultTypefaceNameSans;
|
|
|
|
/** A name that represents the default serif typeface name.
|
|
|
|
Note that this is NOT the platform-specific typeface name (e.g. "Times"), but
|
|
is a generic string that represents it, such as "DefaultSans".
|
|
|
|
If you try to create a typeface with this name, the global default LookAndFeel
|
|
object will be asked to provide an appropriate typeface.
|
|
*/
|
|
static const tchar* defaultTypefaceNameSerif;
|
|
|
|
/** A name that represents the default monospaced typeface name.
|
|
|
|
Note that this is NOT the platform-specific typeface name (e.g. "Times"), but
|
|
is a generic string that represents it, such as "DefaultSans".
|
|
|
|
If you try to create a typeface with this name, the global default LookAndFeel
|
|
object will be asked to provide an appropriate typeface.
|
|
*/
|
|
static const tchar* defaultTypefaceNameMono;
|
|
|
|
/** A handy typedef to make it easy to use ref counted pointers to this class. */
|
|
typedef ReferenceCountedObjectPtr <Typeface> Ptr;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
VoidArray glyphs;
|
|
short lookupTable [128];
|
|
|
|
String typefaceName;
|
|
int hash;
|
|
float ascent; // as a proportion of the height
|
|
bool bold, italic, isFullyPopulated;
|
|
juce_wchar defaultCharacter; // the char to use if a matching glyph can't be found.
|
|
|
|
Typeface() throw();
|
|
void addGlyphCopy (const TypefaceGlyphInfo* const glyphInfoToCopy) throw();
|
|
|
|
friend class Font;
|
|
friend class TypefaceCache;
|
|
friend class FontGlyphAlphaMap;
|
|
|
|
static const Ptr getTypefaceFor (const Font& font) throw();
|
|
|
|
// this is a platform-dependent method that will look for the given typeface
|
|
// and set up its kerning tables, etc. accordingly.
|
|
// If addAllGlyphsToFont is true, it should also add all the glyphs in the font
|
|
// to the typeface immediately, rather than having to add them later on-demand.
|
|
void initialiseTypefaceCharacteristics (const String& fontName,
|
|
bool bold, bool italic,
|
|
bool addAllGlyphsToFont) throw();
|
|
|
|
// platform-specific routine to look up and add a glyph to this typeface
|
|
bool findAndAddSystemGlyph (juce_wchar character) throw();
|
|
|
|
void updateHashCode() throw();
|
|
|
|
friend class LookAndFeel;
|
|
static void getDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed) throw();
|
|
};
|
|
|
|
#endif // __JUCE_TYPEFACE_JUCEHEADER__
|
|
/********* End of inlined file: juce_Typeface.h *********/
|
|
|
|
/**
|
|
Represents a particular font, including its size, style, etc.
|
|
|
|
Apart from the typeface to be used, a Font object also dictates whether
|
|
the font is bold, italic, underlined, how big it is, and its kerning and
|
|
horizontal scale factor.
|
|
|
|
@see Typeface
|
|
*/
|
|
class JUCE_API Font
|
|
{
|
|
public:
|
|
|
|
/** A combination of these values is used by the constructor to specify the
|
|
style of font to use.
|
|
*/
|
|
enum FontStyleFlags
|
|
{
|
|
plain = 0, /**< indicates a plain, non-bold, non-italic version of the font. @see setStyleFlags */
|
|
bold = 1, /**< boldens the font. @see setStyleFlags */
|
|
italic = 2, /**< finds an italic version of the font. @see setStyleFlags */
|
|
underlined = 4 /**< underlines the font. @see setStyleFlags */
|
|
};
|
|
|
|
/** Creates a sans-serif font in a given size.
|
|
|
|
@param fontHeight the height in pixels (can be fractional)
|
|
@param styleFlags the style to use - this can be a combination of the
|
|
Font::bold, Font::italic and Font::underlined, or
|
|
just Font::plain for the normal style.
|
|
@see FontStyleFlags, getDefaultSansSerifFontName
|
|
*/
|
|
Font (const float fontHeight,
|
|
const int styleFlags = plain) throw();
|
|
|
|
/** Creates a font with a given typeface and parameters.
|
|
|
|
@param typefaceName the name of the typeface to use
|
|
@param fontHeight the height in pixels (can be fractional)
|
|
@param styleFlags the style to use - this can be a combination of the
|
|
Font::bold, Font::italic and Font::underlined, or
|
|
just Font::plain for the normal style.
|
|
@see FontStyleFlags, getDefaultSansSerifFontName
|
|
*/
|
|
Font (const String& typefaceName,
|
|
const float fontHeight,
|
|
const int styleFlags) throw();
|
|
|
|
/** Creates a copy of another Font object. */
|
|
Font (const Font& other) throw();
|
|
|
|
/** Creates a font based on a typeface.
|
|
|
|
The font object stores its own internal copy of the typeface, so you can safely
|
|
delete the one passed in after calling this.
|
|
*/
|
|
Font (const Typeface& typeface) throw();
|
|
|
|
/** Creates a basic sans-serif font at a default height.
|
|
|
|
You should use one of the other constructors for creating a font that you're planning
|
|
on drawing with - this constructor is here to help initialise objects before changing
|
|
the font's settings later.
|
|
*/
|
|
Font() throw();
|
|
|
|
/** Copies this font from another one. */
|
|
const Font& operator= (const Font& other) throw();
|
|
|
|
bool operator== (const Font& other) const throw();
|
|
bool operator!= (const Font& other) const throw();
|
|
|
|
/** Destructor. */
|
|
~Font() throw();
|
|
|
|
/** Changes the name of the typeface family.
|
|
|
|
e.g. "Arial", "Courier", etc.
|
|
|
|
This may also be set to Typeface::defaultTypefaceNameSans, Typeface::defaultTypefaceNameSerif,
|
|
or Typeface::defaultTypefaceNameMono, which are not actual platform-specific font names, but
|
|
are generic names that are used to represent the various default fonts.
|
|
|
|
If a suitable font isn't found on the machine, it'll just use a default instead.
|
|
*/
|
|
void setTypefaceName (const String& faceName) throw();
|
|
|
|
/** Returns the name of the typeface family that this font uses.
|
|
|
|
e.g. "Arial", "Courier", etc.
|
|
|
|
Note that this may also be one of the values: Typeface::defaultTypefaceNameSans,
|
|
Typeface::defaultTypefaceNameSerif, or Typeface::defaultTypefaceNameMono, which are not actual
|
|
platform-specific font names, but are generic names that are used to represent the various
|
|
default fonts. If you need to know the exact typeface name being used, you can call
|
|
Font::getTypeface()->getTypefaceName(), which will give you the platform-specific name.
|
|
*/
|
|
const String& getTypefaceName() const throw() { return typefaceName; }
|
|
|
|
/** Returns a typeface name that represents the default sans-serif font.
|
|
|
|
This is also the typeface that will be used when a font is created without
|
|
specifying any typeface details.
|
|
|
|
Note that this method just returns the same value as Typeface::defaultTypefaceNameSans,
|
|
which is a generic placeholder string, and not a platform-specific font name.
|
|
|
|
@see Typeface::defaultTypefaceNameSans, setTypefaceName, getDefaultSerifFontName, getDefaultMonospacedFontName,
|
|
*/
|
|
static const String getDefaultSansSerifFontName() throw() { return Typeface::defaultTypefaceNameSans; }
|
|
|
|
/** Returns a typeface name that represents the default sans-serif font.
|
|
|
|
Note that this method just returns the same value as Typeface::defaultTypefaceNameSerif,
|
|
which is a generic placeholder string, and not a platform-specific font name.
|
|
|
|
@see Typeface::defaultTypefaceNameSerif, setTypefaceName, getDefaultSansSerifFontName, getDefaultMonospacedFontName
|
|
*/
|
|
static const String getDefaultSerifFontName() throw() { return Typeface::defaultTypefaceNameSerif; }
|
|
|
|
/** Returns a typeface name that represents the default sans-serif font.
|
|
|
|
Note that this method just returns the same value as Typeface::defaultTypefaceNameMono,
|
|
which is a generic placeholder string, and not a platform-specific font name.
|
|
|
|
@see Typeface::defaultTypefaceNameMono, setTypefaceName, getDefaultSansSerifFontName, getDefaultSerifFontName
|
|
*/
|
|
static const String getDefaultMonospacedFontName() throw() { return Typeface::defaultTypefaceNameMono; }
|
|
|
|
/** Returns the total height of this font.
|
|
|
|
This is the maximum height, from the top of the ascent to the bottom of the
|
|
descenders.
|
|
|
|
@see setHeight, setHeightWithoutChangingWidth, getAscent
|
|
*/
|
|
float getHeight() const throw() { return height; }
|
|
|
|
/** Changes the font's height.
|
|
|
|
@see getHeight, setHeightWithoutChangingWidth
|
|
*/
|
|
void setHeight (float newHeight) throw();
|
|
|
|
/** Changes the font's height without changing its width.
|
|
|
|
This alters the horizontal scale to compensate for the change in height.
|
|
*/
|
|
void setHeightWithoutChangingWidth (float newHeight) throw();
|
|
|
|
/** Returns the height of the font above its baseline.
|
|
|
|
This is the maximum height from the baseline to the top.
|
|
|
|
@see getHeight, getDescent
|
|
*/
|
|
float getAscent() const throw();
|
|
|
|
/** Returns the amount that the font descends below its baseline.
|
|
|
|
This is calculated as (getHeight() - getAscent()).
|
|
|
|
@see getAscent, getHeight
|
|
*/
|
|
float getDescent() const throw();
|
|
|
|
/** Returns the font's style flags.
|
|
|
|
This will return a bitwise-or'ed combination of values from the FontStyleFlags
|
|
enum, to describe whether the font is bold, italic, etc.
|
|
|
|
@see FontStyleFlags
|
|
*/
|
|
int getStyleFlags() const throw() { return styleFlags; }
|
|
|
|
/** Changes the font's style.
|
|
|
|
@param newFlags a bitwise-or'ed combination of values from the FontStyleFlags
|
|
enum, to set the font's properties
|
|
@see FontStyleFlags
|
|
*/
|
|
void setStyleFlags (const int newFlags) throw();
|
|
|
|
/** Makes the font bold or non-bold. */
|
|
void setBold (const bool shouldBeBold) throw();
|
|
/** Returns true if the font is bold. */
|
|
bool isBold() const throw();
|
|
|
|
/** Makes the font italic or non-italic. */
|
|
void setItalic (const bool shouldBeItalic) throw();
|
|
/** Returns true if the font is italic. */
|
|
bool isItalic() const throw();
|
|
|
|
/** Makes the font underlined or non-underlined. */
|
|
void setUnderline (const bool shouldBeUnderlined) throw();
|
|
/** Returns true if the font is underlined. */
|
|
bool isUnderlined() const throw();
|
|
|
|
/** Changes the font's horizontal scale factor.
|
|
|
|
@param scaleFactor a value of 1.0 is the normal scale, less than this will be
|
|
narrower, greater than 1.0 will be stretched out.
|
|
*/
|
|
void setHorizontalScale (const float scaleFactor) throw();
|
|
|
|
/** Returns the font's horizontal scale.
|
|
|
|
A value of 1.0 is the normal scale, less than this will be narrower, greater
|
|
than 1.0 will be stretched out.
|
|
|
|
@see setHorizontalScale
|
|
*/
|
|
float getHorizontalScale() const throw() { return horizontalScale; }
|
|
|
|
/** Changes the font's kerning.
|
|
|
|
@param extraKerning a multiple of the font's height that will be added
|
|
to space between the characters. So a value of zero is
|
|
normal spacing, positive values spread the letters out,
|
|
negative values make them closer together.
|
|
*/
|
|
void setExtraKerningFactor (const float extraKerning) throw();
|
|
|
|
/** Returns the font's kerning.
|
|
|
|
This is the extra space added between adjacent characters, as a proportion
|
|
of the font's height.
|
|
|
|
A value of zero is normal spacing, positive values will spread the letters
|
|
out more, and negative values make them closer together.
|
|
*/
|
|
float getExtraKerningFactor() const throw() { return kerning; }
|
|
|
|
/** Changes all the font's characteristics with one call. */
|
|
void setSizeAndStyle (const float newHeight,
|
|
const int newStyleFlags,
|
|
const float newHorizontalScale,
|
|
const float newKerningAmount) throw();
|
|
|
|
/** Resets this font's characteristics.
|
|
|
|
This is basically like saying "myFont = Font();", because it resets the
|
|
typeface, size, style, etc to a default state. Not very useful to most
|
|
people, its raison d'etre is to help the Graphics class be more efficient.
|
|
*/
|
|
void resetToDefaultState() throw();
|
|
|
|
/** Returns the total width of a string as it would be drawn using this font.
|
|
|
|
For a more accurate floating-point result, use getStringWidthFloat().
|
|
*/
|
|
int getStringWidth (const String& text) const throw();
|
|
|
|
/** Returns the total width of a string as it would be drawn using this font.
|
|
|
|
@see getStringWidth
|
|
*/
|
|
float getStringWidthFloat (const String& text) const throw();
|
|
|
|
/** Returns the typeface used by this font.
|
|
|
|
Note that the object returned may go out of scope if this font is deleted
|
|
or has its style changed.
|
|
*/
|
|
Typeface* getTypeface() const throw();
|
|
|
|
/** Creates an array of Font objects to represent all the fonts on the system.
|
|
|
|
If you just need the names of the typefaces, you can also use
|
|
findAllTypefaceNames() instead.
|
|
|
|
@param results the array to which new Font objects will be added.
|
|
*/
|
|
static void findFonts (OwnedArray<Font>& results) throw();
|
|
|
|
/** Returns a list of all the available typeface names.
|
|
|
|
The names returned can be passed into setTypefaceName().
|
|
|
|
You can use this instead of findFonts() if you only need their names, and not
|
|
font objects.
|
|
*/
|
|
static const StringArray findAllTypefaceNames() throw();
|
|
|
|
/** Returns the name of the typeface to be used for rendering glyphs that aren't found
|
|
in the requested typeface.
|
|
*/
|
|
static const String getFallbackFontName() throw();
|
|
|
|
/** Sets the (platform-specific) name of the typeface to use to find glyphs that aren't
|
|
available in whatever font you're trying to use.
|
|
*/
|
|
static void setFallbackFontName (const String& name) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
friend class FontGlyphAlphaMap;
|
|
friend class TypefaceCache;
|
|
|
|
String typefaceName;
|
|
float height, horizontalScale, kerning;
|
|
mutable float ascent;
|
|
int styleFlags;
|
|
mutable Typeface::Ptr typeface;
|
|
};
|
|
|
|
#endif // __JUCE_FONT_JUCEHEADER__
|
|
/********* End of inlined file: juce_Font.h *********/
|
|
|
|
/********* Start of inlined file: juce_Rectangle.h *********/
|
|
#ifndef __JUCE_RECTANGLE_JUCEHEADER__
|
|
#define __JUCE_RECTANGLE_JUCEHEADER__
|
|
|
|
/**
|
|
A rectangle, specified using integer co-ordinates.
|
|
|
|
@see RectangleList, Path, Line, Point
|
|
*/
|
|
class JUCE_API Rectangle
|
|
{
|
|
public:
|
|
|
|
/** Creates a rectangle of zero size.
|
|
|
|
The default co-ordinates will be (0, 0, 0, 0).
|
|
*/
|
|
Rectangle() throw();
|
|
|
|
/** Creates a copy of another rectangle. */
|
|
Rectangle (const Rectangle& other) throw();
|
|
|
|
/** Creates a rectangle with a given position and size. */
|
|
Rectangle (const int x, const int y,
|
|
const int width, const int height) throw();
|
|
|
|
/** Creates a rectangle with a given size, and a position of (0, 0). */
|
|
Rectangle (const int width, const int height) throw();
|
|
|
|
/** Destructor. */
|
|
~Rectangle() throw();
|
|
|
|
/** Returns the x co-ordinate of the rectangle's left-hand-side. */
|
|
inline int getX() const throw() { return x; }
|
|
|
|
/** Returns the y co-ordinate of the rectangle's top edge. */
|
|
inline int getY() const throw() { return y; }
|
|
|
|
/** Returns the width of the rectangle. */
|
|
inline int getWidth() const throw() { return w; }
|
|
|
|
/** Returns the height of the rectangle. */
|
|
inline int getHeight() const throw() { return h; }
|
|
|
|
/** Returns the x co-ordinate of the rectangle's right-hand-side. */
|
|
inline int getRight() const throw() { return x + w; }
|
|
|
|
/** Returns the y co-ordinate of the rectangle's bottom edge. */
|
|
inline int getBottom() const throw() { return y + h; }
|
|
|
|
/** Returns the x co-ordinate of the rectangle's centre. */
|
|
inline int getCentreX() const throw() { return x + (w >> 1); }
|
|
|
|
/** Returns the y co-ordinate of the rectangle's centre. */
|
|
inline int getCentreY() const throw() { return y + (h >> 1); }
|
|
|
|
/** Returns true if the rectangle's width and height are both zero or less */
|
|
bool isEmpty() const throw();
|
|
|
|
/** Changes the position of the rectangle's top-left corner (leaving its size unchanged). */
|
|
void setPosition (const int x, const int y) throw();
|
|
|
|
/** Changes the rectangle's size, leaving the position of its top-left corner unchanged. */
|
|
void setSize (const int w, const int h) throw();
|
|
|
|
/** Changes all the rectangle's co-ordinates. */
|
|
void setBounds (const int newX, const int newY,
|
|
const int newWidth, const int newHeight) throw();
|
|
|
|
/** Moves the x position, adjusting the width so that the right-hand edge remains in the same place.
|
|
If the x is moved to be on the right of the current right-hand edge, the width will be set to zero.
|
|
*/
|
|
void setLeft (const int newLeft) throw();
|
|
|
|
/** Moves the y position, adjusting the height so that the bottom edge remains in the same place.
|
|
If the y is moved to be below the current bottom edge, the height will be set to zero.
|
|
*/
|
|
void setTop (const int newTop) throw();
|
|
|
|
/** Adjusts the width so that the right-hand edge of the rectangle has this new value.
|
|
If the new right is below the current X value, the X will be pushed down to match it.
|
|
@see getRight
|
|
*/
|
|
void setRight (const int newRight) throw();
|
|
|
|
/** Adjusts the height so that the bottom edge of the rectangle has this new value.
|
|
If the new bottom is lower than the current Y value, the Y will be pushed down to match it.
|
|
@see getBottom
|
|
*/
|
|
void setBottom (const int newBottom) throw();
|
|
|
|
/** Moves the rectangle's position by adding amount to its x and y co-ordinates. */
|
|
void translate (const int deltaX,
|
|
const int deltaY) throw();
|
|
|
|
/** Returns a rectangle which is the same as this one moved by a given amount. */
|
|
const Rectangle translated (const int deltaX,
|
|
const int deltaY) const throw();
|
|
|
|
/** Expands the rectangle by a given amount.
|
|
|
|
Effectively, its new size is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2).
|
|
@see expanded, reduce, reduced
|
|
*/
|
|
void expand (const int deltaX,
|
|
const int deltaY) throw();
|
|
|
|
/** Returns a rectangle that is larger than this one by a given amount.
|
|
|
|
Effectively, the rectangle returned is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2).
|
|
@see expand, reduce, reduced
|
|
*/
|
|
const Rectangle expanded (const int deltaX,
|
|
const int deltaY) const throw();
|
|
|
|
/** Shrinks the rectangle by a given amount.
|
|
|
|
Effectively, its new size is (x + deltaX, y + deltaY, w - deltaX * 2, h - deltaY * 2).
|
|
@see reduced, expand, expanded
|
|
*/
|
|
void reduce (const int deltaX,
|
|
const int deltaY) throw();
|
|
|
|
/** Returns a rectangle that is smaller than this one by a given amount.
|
|
|
|
Effectively, the rectangle returned is (x + deltaX, y + deltaY, w - deltaX * 2, h - deltaY * 2).
|
|
@see reduce, expand, expanded
|
|
*/
|
|
const Rectangle reduced (const int deltaX,
|
|
const int deltaY) const throw();
|
|
|
|
/** Returns true if the two rectangles are identical. */
|
|
bool operator== (const Rectangle& other) const throw();
|
|
|
|
/** Returns true if the two rectangles are not identical. */
|
|
bool operator!= (const Rectangle& other) const throw();
|
|
|
|
/** Returns true if this co-ordinate is inside the rectangle. */
|
|
bool contains (const int x, const int y) const throw();
|
|
|
|
/** Returns true if this other rectangle is completely inside this one. */
|
|
bool contains (const Rectangle& other) const throw();
|
|
|
|
/** Returns true if any part of another rectangle overlaps this one. */
|
|
bool intersects (const Rectangle& other) const throw();
|
|
|
|
/** Returns the region that is the overlap between this and another rectangle.
|
|
|
|
If the two rectangles don't overlap, the rectangle returned will be empty.
|
|
*/
|
|
const Rectangle getIntersection (const Rectangle& other) const throw();
|
|
|
|
/** Clips a rectangle so that it lies only within this one.
|
|
|
|
This is a non-static version of intersectRectangles().
|
|
|
|
Returns false if the two regions didn't overlap.
|
|
*/
|
|
bool intersectRectangle (int& x, int& y, int& w, int& h) const throw();
|
|
|
|
/** Returns the smallest rectangle that contains both this one and the one
|
|
passed-in.
|
|
*/
|
|
const Rectangle getUnion (const Rectangle& other) const throw();
|
|
|
|
/** If this rectangle merged with another one results in a simple rectangle, this
|
|
will set this rectangle to the result, and return true.
|
|
|
|
Returns false and does nothing to this rectangle if the two rectangles don't overlap,
|
|
or if they form a complex region.
|
|
*/
|
|
bool enlargeIfAdjacent (const Rectangle& other) throw();
|
|
|
|
/** If after removing another rectangle from this one the result is a simple rectangle,
|
|
this will set this object's bounds to be the result, and return true.
|
|
|
|
Returns false and does nothing to this rectangle if the two rectangles don't overlap,
|
|
or if removing the other one would form a complex region.
|
|
*/
|
|
bool reduceIfPartlyContainedIn (const Rectangle& other) throw();
|
|
|
|
/** Static utility to intersect two sets of rectangular co-ordinates.
|
|
|
|
Returns false if the two regions didn't overlap.
|
|
|
|
@see intersectRectangle
|
|
*/
|
|
static bool intersectRectangles (int& x1, int& y1, int& w1, int& h1,
|
|
int x2, int y2, int w2, int h2) throw();
|
|
|
|
/** Creates a string describing this rectangle.
|
|
|
|
The string will be of the form "x y width height", e.g. "100 100 400 200".
|
|
|
|
Coupled with the fromString() method, this is very handy for things like
|
|
storing rectangles (particularly component positions) in XML attributes.
|
|
|
|
@see fromString
|
|
*/
|
|
const String toString() const throw();
|
|
|
|
/** Parses a string containing a rectangle's details.
|
|
|
|
The string should contain 4 integer tokens, in the form "x y width height". They
|
|
can be comma or whitespace separated.
|
|
|
|
This method is intended to go with the toString() method, to form an easy way
|
|
of saving/loading rectangles as strings.
|
|
|
|
@see toString
|
|
*/
|
|
static const Rectangle fromString (const String& stringVersion);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class RectangleList;
|
|
int x, y, w, h;
|
|
};
|
|
|
|
#endif // __JUCE_RECTANGLE_JUCEHEADER__
|
|
/********* End of inlined file: juce_Rectangle.h *********/
|
|
|
|
/********* Start of inlined file: juce_PathStrokeType.h *********/
|
|
#ifndef __JUCE_PATHSTROKETYPE_JUCEHEADER__
|
|
#define __JUCE_PATHSTROKETYPE_JUCEHEADER__
|
|
|
|
/**
|
|
Describes a type of stroke used to render a solid outline along a path.
|
|
|
|
A PathStrokeType object can be used directly to create the shape of an outline
|
|
around a path, and is used by Graphics::strokePath to specify the type of
|
|
stroke to draw.
|
|
|
|
@see Path, Graphics::strokePath
|
|
*/
|
|
class JUCE_API PathStrokeType
|
|
{
|
|
public:
|
|
|
|
/** The type of shape to use for the corners between two adjacent line segments. */
|
|
enum JointStyle
|
|
{
|
|
mitered, /**< Indicates that corners should be drawn with sharp joints.
|
|
Note that for angles that curve back on themselves, drawing a
|
|
mitre could require extending the point too far away from the
|
|
path, so a mitre limit is imposed and any corners that exceed it
|
|
are drawn as bevelled instead. */
|
|
curved, /**< Indicates that corners should be drawn as rounded-off. */
|
|
beveled /**< Indicates that corners should be drawn with a line flattening their
|
|
outside edge. */
|
|
};
|
|
|
|
/** The type shape to use for the ends of lines. */
|
|
enum EndCapStyle
|
|
{
|
|
butt, /**< Ends of lines are flat and don't extend beyond the end point. */
|
|
square, /**< Ends of lines are flat, but stick out beyond the end point for half
|
|
the thickness of the stroke. */
|
|
rounded /**< Ends of lines are rounded-off with a circular shape. */
|
|
};
|
|
|
|
/** Creates a stroke type.
|
|
|
|
@param strokeThickness the width of the line to use
|
|
@param jointStyle the type of joints to use for corners
|
|
@param endStyle the type of end-caps to use for the ends of open paths.
|
|
*/
|
|
PathStrokeType (const float strokeThickness,
|
|
const JointStyle jointStyle = mitered,
|
|
const EndCapStyle endStyle = butt) throw();
|
|
|
|
/** Createes a copy of another stroke type. */
|
|
PathStrokeType (const PathStrokeType& other) throw();
|
|
|
|
/** Copies another stroke onto this one. */
|
|
const PathStrokeType& operator= (const PathStrokeType& other) throw();
|
|
|
|
/** Destructor. */
|
|
~PathStrokeType() throw();
|
|
|
|
/** Applies this stroke type to a path and returns the resultant stroke as another Path.
|
|
|
|
@param destPath the resultant stroked outline shape will be copied into this path.
|
|
Note that it's ok for the source and destination Paths to be
|
|
the same object, so you can easily turn a path into a stroked version
|
|
of itself.
|
|
@param sourcePath the path to use as the source
|
|
@param transform an optional transform to apply to the points from the source path
|
|
as they are being used
|
|
@param extraAccuracy if this is greater than 1.0, it will subdivide the path to
|
|
a higher resolution, which improved the quality if you'll later want
|
|
to enlarge the stroked path
|
|
|
|
@see createDashedStroke
|
|
*/
|
|
void createStrokedPath (Path& destPath,
|
|
const Path& sourcePath,
|
|
const AffineTransform& transform = AffineTransform::identity,
|
|
const float extraAccuracy = 1.0f) const throw();
|
|
|
|
/** Applies this stroke type to a path, creating a dashed line.
|
|
|
|
This is similar to createStrokedPath, but uses the array passed in to
|
|
break the stroke up into a series of dashes.
|
|
|
|
@param destPath the resultant stroked outline shape will be copied into this path.
|
|
Note that it's ok for the source and destination Paths to be
|
|
the same object, so you can easily turn a path into a stroked version
|
|
of itself.
|
|
@param sourcePath the path to use as the source
|
|
@param dashLengths An array of alternating on/off lengths. E.g. { 2, 3, 4, 5 } will create
|
|
a line of length 2, then skip a length of 3, then add a line of length 4,
|
|
skip 5, and keep repeating this pattern.
|
|
@param numDashLengths The number of lengths in the dashLengths array. This should really be
|
|
an even number, otherwise the pattern will get out of step as it
|
|
repeats.
|
|
@param transform an optional transform to apply to the points from the source path
|
|
as they are being used
|
|
@param extraAccuracy if this is greater than 1.0, it will subdivide the path to
|
|
a higher resolution, which improved the quality if you'll later want
|
|
to enlarge the stroked path
|
|
*/
|
|
void createDashedStroke (Path& destPath,
|
|
const Path& sourcePath,
|
|
const float* dashLengths,
|
|
int numDashLengths,
|
|
const AffineTransform& transform = AffineTransform::identity,
|
|
const float extraAccuracy = 1.0f) const throw();
|
|
|
|
/** Returns the stroke thickness. */
|
|
float getStrokeThickness() const throw() { return thickness; }
|
|
|
|
/** Returns the joint style. */
|
|
JointStyle getJointStyle() const throw() { return jointStyle; }
|
|
|
|
/** Returns the end-cap style. */
|
|
EndCapStyle getEndStyle() const throw() { return endStyle; }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
/** Compares the stroke thickness, joint and end styles of two stroke types. */
|
|
bool operator== (const PathStrokeType& other) const throw();
|
|
|
|
/** Compares the stroke thickness, joint and end styles of two stroke types. */
|
|
bool operator!= (const PathStrokeType& other) const throw();
|
|
|
|
private:
|
|
|
|
float thickness;
|
|
JointStyle jointStyle;
|
|
EndCapStyle endStyle;
|
|
};
|
|
|
|
#endif // __JUCE_PATHSTROKETYPE_JUCEHEADER__
|
|
/********* End of inlined file: juce_PathStrokeType.h *********/
|
|
|
|
/********* Start of inlined file: juce_Line.h *********/
|
|
#ifndef __JUCE_LINE_JUCEHEADER__
|
|
#define __JUCE_LINE_JUCEHEADER__
|
|
|
|
/**
|
|
Represents a line, using 32-bit float co-ordinates.
|
|
|
|
This class contains a bunch of useful methods for various geometric
|
|
tasks.
|
|
|
|
@see Point, Rectangle, Path, Graphics::drawLine
|
|
*/
|
|
class JUCE_API Line
|
|
{
|
|
public:
|
|
|
|
/** Creates a line, using (0, 0) as its start and end points. */
|
|
Line() throw();
|
|
|
|
/** Creates a copy of another line. */
|
|
Line (const Line& other) throw();
|
|
|
|
/** Creates a line based on the co-ordinates of its start and end points. */
|
|
Line (const float startX,
|
|
const float startY,
|
|
const float endX,
|
|
const float endY) throw();
|
|
|
|
/** Creates a line from its start and end points. */
|
|
Line (const Point& start,
|
|
const Point& end) throw();
|
|
|
|
/** Copies a line from another one. */
|
|
const Line& operator= (const Line& other) throw();
|
|
|
|
/** Destructor. */
|
|
~Line() throw();
|
|
|
|
/** Returns the x co-ordinate of the line's start point. */
|
|
inline float getStartX() const throw() { return startX; }
|
|
|
|
/** Returns the y co-ordinate of the line's start point. */
|
|
inline float getStartY() const throw() { return startY; }
|
|
|
|
/** Returns the x co-ordinate of the line's end point. */
|
|
inline float getEndX() const throw() { return endX; }
|
|
|
|
/** Returns the y co-ordinate of the line's end point. */
|
|
inline float getEndY() const throw() { return endY; }
|
|
|
|
/** Returns the line's start point. */
|
|
const Point getStart() const throw();
|
|
|
|
/** Returns the line's end point. */
|
|
const Point getEnd() const throw();
|
|
|
|
/** Changes this line's start point */
|
|
void setStart (const float newStartX,
|
|
const float newStartY) throw();
|
|
|
|
/** Changes this line's end point */
|
|
void setEnd (const float newEndX,
|
|
const float newEndY) throw();
|
|
|
|
/** Changes this line's start point */
|
|
void setStart (const Point& newStart) throw();
|
|
|
|
/** Changes this line's end point */
|
|
void setEnd (const Point& newEnd) throw();
|
|
|
|
/** Applies an affine transform to the line's start and end points. */
|
|
void applyTransform (const AffineTransform& transform) throw();
|
|
|
|
/** Returns the length of the line. */
|
|
float getLength() const throw();
|
|
|
|
/** Returns true if the line's start and end x co-ordinates are the same. */
|
|
bool isVertical() const throw();
|
|
|
|
/** Returns true if the line's start and end y co-ordinates are the same. */
|
|
bool isHorizontal() const throw();
|
|
|
|
/** Returns the line's angle.
|
|
|
|
This value is the number of radians clockwise from the 3 o'clock direction,
|
|
where the line's start point is considered to be at the centre.
|
|
*/
|
|
float getAngle() const throw();
|
|
|
|
/** Compares two lines. */
|
|
bool operator== (const Line& other) const throw();
|
|
|
|
/** Compares two lines. */
|
|
bool operator!= (const Line& other) const throw();
|
|
|
|
/** Finds the intersection between two lines.
|
|
|
|
@param line the other line
|
|
@param intersectionX the x co-ordinate of the point where the lines meet (or
|
|
where they would meet if they were infinitely long)
|
|
the intersection (if the lines intersect). If the lines
|
|
are parallel, this will just be set to the position
|
|
of one of the line's endpoints.
|
|
@param intersectionY the y co-ordinate of the point where the lines meet
|
|
@returns true if the line segments intersect; false if they dont. Even if they
|
|
don't intersect, the intersection co-ordinates returned will still
|
|
be valid
|
|
*/
|
|
bool intersects (const Line& line,
|
|
float& intersectionX,
|
|
float& intersectionY) const throw();
|
|
|
|
/** Returns the location of the point which is a given distance along this line.
|
|
|
|
@param distanceFromStart the distance to move along the line from its
|
|
start point. This value can be negative or longer
|
|
than the line itself
|
|
@see getPointAlongLineProportionally
|
|
*/
|
|
const Point getPointAlongLine (const float distanceFromStart) const throw();
|
|
|
|
/** Returns a point which is a certain distance along and to the side of this line.
|
|
|
|
This effectively moves a given distance along the line, then another distance
|
|
perpendicularly to this, and returns the resulting position.
|
|
|
|
@param distanceFromStart the distance to move along the line from its
|
|
start point. This value can be negative or longer
|
|
than the line itself
|
|
@param perpendicularDistance how far to move sideways from the line. If you're
|
|
looking along the line from its start towards its
|
|
end, then a positive value here will move to the
|
|
right, negative value move to the left.
|
|
*/
|
|
const Point getPointAlongLine (const float distanceFromStart,
|
|
const float perpendicularDistance) const throw();
|
|
|
|
/** Returns the location of the point which is a given distance along this line
|
|
proportional to the line's length.
|
|
|
|
@param proportionOfLength the distance to move along the line from its
|
|
start point, in multiples of the line's length.
|
|
So a value of 0.0 will return the line's start point
|
|
and a value of 1.0 will return its end point. (This value
|
|
can be negative or greater than 1.0).
|
|
@see getPointAlongLine
|
|
*/
|
|
const Point getPointAlongLineProportionally (const float proportionOfLength) const throw();
|
|
|
|
/** Returns the smallest distance between this line segment and a given point.
|
|
|
|
So if the point is close to the line, this will return the perpendicular
|
|
distance from the line; if the point is a long way beyond one of the line's
|
|
end-point's, it'll return the straight-line distance to the nearest end-point.
|
|
|
|
@param x x position of the point to test
|
|
@param y y position of the point to test
|
|
@returns the point's distance from the line
|
|
@see getPositionAlongLineOfNearestPoint
|
|
*/
|
|
float getDistanceFromLine (const float x,
|
|
const float y) const throw();
|
|
|
|
/** Finds the point on this line which is nearest to a given point, and
|
|
returns its position as a proportional position along the line.
|
|
|
|
@param x x position of the point to test
|
|
@param y y position of the point to test
|
|
@returns a value 0 to 1.0 which is the distance along this line from the
|
|
line's start to the point which is nearest to the point passed-in. To
|
|
turn this number into a position, use getPointAlongLineProportionally().
|
|
@see getDistanceFromLine, getPointAlongLineProportionally
|
|
*/
|
|
float findNearestPointTo (const float x,
|
|
const float y) const throw();
|
|
|
|
/** Returns true if the given point lies above this line.
|
|
|
|
The return value is true if the point's y coordinate is less than the y
|
|
coordinate of this line at the given x (assuming the line extends infinitely
|
|
in both directions).
|
|
*/
|
|
bool isPointAbove (const float x, const float y) const throw();
|
|
|
|
/** Returns a shortened copy of this line.
|
|
|
|
This will chop off part of the start of this line by a certain amount, (leaving the
|
|
end-point the same), and return the new line.
|
|
*/
|
|
const Line withShortenedStart (const float distanceToShortenBy) const throw();
|
|
|
|
/** Returns a shortened copy of this line.
|
|
|
|
This will chop off part of the end of this line by a certain amount, (leaving the
|
|
start-point the same), and return the new line.
|
|
*/
|
|
const Line withShortenedEnd (const float distanceToShortenBy) const throw();
|
|
|
|
/** Cuts off parts of this line to keep the parts that are either inside or
|
|
outside a path.
|
|
|
|
Note that this isn't smart enough to cope with situations where the
|
|
line would need to be cut into multiple pieces to correctly clip against
|
|
a re-entrant shape.
|
|
|
|
@param path the path to clip against
|
|
@param keepSectionOutsidePath if true, it's the section outside the path
|
|
that will be kept; if false its the section inside
|
|
the path
|
|
@returns true if the line was changed.
|
|
*/
|
|
bool clipToPath (const Path& path,
|
|
const bool keepSectionOutsidePath) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
float startX, startY, endX, endY;
|
|
};
|
|
|
|
#endif // __JUCE_LINE_JUCEHEADER__
|
|
/********* End of inlined file: juce_Line.h *********/
|
|
|
|
/********* Start of inlined file: juce_Colours.h *********/
|
|
#ifndef __JUCE_COLOURS_JUCEHEADER__
|
|
#define __JUCE_COLOURS_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Colour.h *********/
|
|
#ifndef __JUCE_COLOUR_JUCEHEADER__
|
|
#define __JUCE_COLOUR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PixelFormats.h *********/
|
|
#ifndef __JUCE_PIXELFORMATS_JUCEHEADER__
|
|
#define __JUCE_PIXELFORMATS_JUCEHEADER__
|
|
|
|
#if JUCE_MSVC
|
|
#pragma pack (push, 1)
|
|
#define PACKED
|
|
#elif JUCE_GCC
|
|
#define PACKED __attribute__((packed))
|
|
#else
|
|
#define PACKED
|
|
#endif
|
|
|
|
/**
|
|
Represents a 32-bit ARGB pixel with premultiplied alpha, and can perform compositing
|
|
operations with it.
|
|
|
|
This is used internally by the imaging classes.
|
|
|
|
@see PixelRGB
|
|
*/
|
|
class JUCE_API PixelARGB
|
|
{
|
|
public:
|
|
/** Creates a pixel without defining its colour. */
|
|
PixelARGB() throw() {}
|
|
~PixelARGB() throw() {}
|
|
|
|
/** Creates a pixel from a 32-bit argb value.
|
|
*/
|
|
PixelARGB (const uint32 argb_) throw()
|
|
: argb (argb_)
|
|
{
|
|
}
|
|
|
|
forcedinline uint32 getARGB() const throw() { return argb; }
|
|
forcedinline uint32 getRB() const throw() { return 0x00ff00ff & argb; }
|
|
forcedinline uint32 getAG() const throw() { return 0x00ff00ff & (argb >> 8); }
|
|
|
|
forcedinline uint8 getAlpha() const throw() { return components.a; }
|
|
forcedinline uint8 getRed() const throw() { return components.r; }
|
|
forcedinline uint8 getGreen() const throw() { return components.g; }
|
|
forcedinline uint8 getBlue() const throw() { return components.b; }
|
|
|
|
/** Blends another pixel onto this one.
|
|
|
|
This takes into account the opacity of the pixel being overlaid, and blends
|
|
it accordingly.
|
|
*/
|
|
template <class Pixel>
|
|
forcedinline void blend (const Pixel& src) throw()
|
|
{
|
|
uint32 sargb = src.getARGB();
|
|
const uint32 alpha = 0x100 - (sargb >> 24);
|
|
|
|
sargb += 0x00ff00ff & ((getRB() * alpha) >> 8);
|
|
sargb += 0xff00ff00 & (getAG() * alpha);
|
|
|
|
argb = sargb;
|
|
}
|
|
|
|
/** Blends another pixel onto this one, applying an extra multiplier to its opacity.
|
|
|
|
The opacity of the pixel being overlaid is scaled by the extraAlpha factor before
|
|
being used, so this can blend semi-transparently from a PixelRGB argument.
|
|
*/
|
|
template <class Pixel>
|
|
forcedinline void blend (const Pixel& src, uint32 extraAlpha) throw()
|
|
{
|
|
++extraAlpha;
|
|
|
|
uint32 sargb = ((extraAlpha * src.getAG()) & 0xff00ff00)
|
|
| (((extraAlpha * src.getRB()) >> 8) & 0x00ff00ff);
|
|
|
|
const uint32 alpha = 0x100 - (sargb >> 24);
|
|
|
|
sargb += 0x00ff00ff & ((getRB() * alpha) >> 8);
|
|
sargb += 0xff00ff00 & (getAG() * alpha);
|
|
|
|
argb = sargb;
|
|
}
|
|
|
|
/** Blends another pixel with this one, creating a colour that is somewhere
|
|
between the two, as specified by the amount.
|
|
*/
|
|
template <class Pixel>
|
|
forcedinline void tween (const Pixel& src, const uint32 amount) throw()
|
|
{
|
|
uint32 drb = getRB();
|
|
drb += (((src.getRB() - drb) * amount) >> 8);
|
|
drb &= 0x00ff00ff;
|
|
|
|
uint32 dag = getAG();
|
|
dag += (((src.getAG() - dag) * amount) >> 8);
|
|
dag &= 0x00ff00ff;
|
|
dag <<= 8;
|
|
|
|
dag |= drb;
|
|
argb = dag;
|
|
}
|
|
|
|
/** Copies another pixel colour over this one.
|
|
|
|
This doesn't blend it - this colour is simply replaced by the other one.
|
|
*/
|
|
template <class Pixel>
|
|
forcedinline void set (const Pixel& src) throw()
|
|
{
|
|
argb = src.getARGB();
|
|
}
|
|
|
|
/** Replaces the colour's alpha value with another one. */
|
|
forcedinline void setAlpha (const uint8 newAlpha) throw()
|
|
{
|
|
components.a = newAlpha;
|
|
}
|
|
|
|
/** Multiplies the colour's alpha value with another one. */
|
|
forcedinline void multiplyAlpha (int multiplier) throw()
|
|
{
|
|
++multiplier;
|
|
|
|
argb = ((multiplier * getAG()) & 0xff00ff00)
|
|
| (((multiplier * getRB()) >> 8) & 0x00ff00ff);
|
|
}
|
|
|
|
forcedinline void multiplyAlpha (const float multiplier) throw()
|
|
{
|
|
multiplyAlpha ((int) (multiplier * 256.0f));
|
|
}
|
|
|
|
/** Sets the pixel's colour from individual components. */
|
|
void setARGB (const uint8 a, const uint8 r, const uint8 g, const uint8 b) throw()
|
|
{
|
|
components.b = b;
|
|
components.g = g;
|
|
components.r = r;
|
|
components.a = a;
|
|
}
|
|
|
|
/** Premultiplies the pixel's RGB values by its alpha. */
|
|
forcedinline void premultiply() throw()
|
|
{
|
|
const uint32 alpha = components.a;
|
|
|
|
if (alpha < 0xff)
|
|
{
|
|
if (alpha == 0)
|
|
{
|
|
components.b = 0;
|
|
components.g = 0;
|
|
components.r = 0;
|
|
}
|
|
else
|
|
{
|
|
components.b = (uint8) ((components.b * alpha + 0x7f) >> 8);
|
|
components.g = (uint8) ((components.g * alpha + 0x7f) >> 8);
|
|
components.r = (uint8) ((components.r * alpha + 0x7f) >> 8);
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Unpremultiplies the pixel's RGB values. */
|
|
forcedinline void unpremultiply() throw()
|
|
{
|
|
const uint32 alpha = components.a;
|
|
|
|
if (alpha < 0xff)
|
|
{
|
|
if (alpha == 0)
|
|
{
|
|
components.b = 0;
|
|
components.g = 0;
|
|
components.r = 0;
|
|
}
|
|
else
|
|
{
|
|
components.b = (uint8) jmin (0xff, (components.b * 0xff) / alpha);
|
|
components.g = (uint8) jmin (0xff, (components.g * 0xff) / alpha);
|
|
components.r = (uint8) jmin (0xff, (components.r * 0xff) / alpha);
|
|
}
|
|
}
|
|
}
|
|
|
|
forcedinline void desaturate() throw()
|
|
{
|
|
if (components.a < 0xff && components.a > 0)
|
|
{
|
|
const int newUnpremultipliedLevel = (0xff * ((int) components.r + (int) components.g + (int) components.b) / (3 * components.a));
|
|
|
|
components.r = components.g = components.b
|
|
= (uint8) ((newUnpremultipliedLevel * components.a + 0x7f) >> 8);
|
|
}
|
|
else
|
|
{
|
|
components.r = components.g = components.b
|
|
= (uint8) (((int) components.r + (int) components.g + (int) components.b) / 3);
|
|
}
|
|
}
|
|
|
|
private:
|
|
|
|
union
|
|
{
|
|
uint32 argb;
|
|
|
|
struct
|
|
{
|
|
#if JUCE_BIG_ENDIAN
|
|
uint8 a : 8, r : 8, g : 8, b : 8;
|
|
#else
|
|
uint8 b, g, r, a;
|
|
#endif
|
|
} PACKED components;
|
|
};
|
|
|
|
} PACKED;
|
|
|
|
/**
|
|
Represents a 24-bit RGB pixel, and can perform compositing operations on it.
|
|
|
|
This is used internally by the imaging classes.
|
|
|
|
@see PixelARGB
|
|
*/
|
|
class JUCE_API PixelRGB
|
|
{
|
|
public:
|
|
/** Creates a pixel without defining its colour. */
|
|
PixelRGB() throw() {}
|
|
~PixelRGB() throw() {}
|
|
|
|
/** Creates a pixel from a 32-bit argb value.
|
|
|
|
(The argb format is that used by PixelARGB)
|
|
*/
|
|
PixelRGB (const uint32 argb) throw()
|
|
{
|
|
r = (uint8) (argb >> 16);
|
|
g = (uint8) (argb >> 8);
|
|
b = (uint8) (argb);
|
|
}
|
|
|
|
forcedinline uint32 getARGB() const throw() { return 0xff000000 | b | (g << 8) | (r << 16); }
|
|
forcedinline uint32 getRB() const throw() { return b | (uint32) (r << 16); }
|
|
forcedinline uint32 getAG() const throw() { return 0xff0000 | g; }
|
|
|
|
forcedinline uint8 getAlpha() const throw() { return 0xff; }
|
|
forcedinline uint8 getRed() const throw() { return r; }
|
|
forcedinline uint8 getGreen() const throw() { return g; }
|
|
forcedinline uint8 getBlue() const throw() { return b; }
|
|
|
|
/** Blends another pixel onto this one.
|
|
|
|
This takes into account the opacity of the pixel being overlaid, and blends
|
|
it accordingly.
|
|
*/
|
|
forcedinline void blend (const PixelARGB& src) throw()
|
|
{
|
|
uint32 sargb = src.getARGB();
|
|
const uint32 alpha = 0x100 - (sargb >> 24);
|
|
|
|
sargb += 0x00ff00ff & ((getRB() * alpha) >> 8);
|
|
sargb += 0x0000ff00 & (g * alpha);
|
|
|
|
r = (uint8) (sargb >> 16);
|
|
g = (uint8) (sargb >> 8);
|
|
b = (uint8) sargb;
|
|
}
|
|
|
|
forcedinline void blend (const PixelRGB& src) throw()
|
|
{
|
|
set (src);
|
|
}
|
|
|
|
/** Blends another pixel onto this one, applying an extra multiplier to its opacity.
|
|
|
|
The opacity of the pixel being overlaid is scaled by the extraAlpha factor before
|
|
being used, so this can blend semi-transparently from a PixelRGB argument.
|
|
*/
|
|
template <class Pixel>
|
|
forcedinline void blend (const Pixel& src, uint32 extraAlpha) throw()
|
|
{
|
|
++extraAlpha;
|
|
const uint32 srb = (extraAlpha * src.getRB()) >> 8;
|
|
const uint32 sag = extraAlpha * src.getAG();
|
|
uint32 sargb = (sag & 0xff00ff00) | (srb & 0x00ff00ff);
|
|
|
|
const uint32 alpha = 0x100 - (sargb >> 24);
|
|
|
|
sargb += 0x00ff00ff & ((getRB() * alpha) >> 8);
|
|
sargb += 0x0000ff00 & (g * alpha);
|
|
|
|
b = (uint8) sargb;
|
|
g = (uint8) (sargb >> 8);
|
|
r = (uint8) (sargb >> 16);
|
|
}
|
|
|
|
/** Blends another pixel with this one, creating a colour that is somewhere
|
|
between the two, as specified by the amount.
|
|
*/
|
|
template <class Pixel>
|
|
forcedinline void tween (const Pixel& src, const uint32 amount) throw()
|
|
{
|
|
uint32 drb = getRB();
|
|
drb += (((src.getRB() - drb) * amount) >> 8);
|
|
|
|
uint32 dag = getAG();
|
|
dag += (((src.getAG() - dag) * amount) >> 8);
|
|
|
|
b = (uint8) drb;
|
|
g = (uint8) dag;
|
|
r = (uint8) (drb >> 16);
|
|
}
|
|
|
|
/** Copies another pixel colour over this one.
|
|
|
|
This doesn't blend it - this colour is simply replaced by the other one.
|
|
Because PixelRGB has no alpha channel, any alpha value in the source pixel
|
|
is thrown away.
|
|
*/
|
|
template <class Pixel>
|
|
forcedinline void set (const Pixel& src) throw()
|
|
{
|
|
b = src.getBlue();
|
|
g = src.getGreen();
|
|
r = src.getRed();
|
|
}
|
|
|
|
/** This method is included for compatibility with the PixelARGB class. */
|
|
forcedinline void setAlpha (const uint8) throw() {}
|
|
|
|
/** Multiplies the colour's alpha value with another one. */
|
|
forcedinline void multiplyAlpha (int) throw() {}
|
|
|
|
/** Sets the pixel's colour from individual components. */
|
|
void setARGB (const uint8, const uint8 r_, const uint8 g_, const uint8 b_) throw()
|
|
{
|
|
r = r_;
|
|
g = g_;
|
|
b = b_;
|
|
}
|
|
|
|
/** Premultiplies the pixel's RGB values by its alpha. */
|
|
forcedinline void premultiply() throw() {}
|
|
|
|
/** Unpremultiplies the pixel's RGB values. */
|
|
forcedinline void unpremultiply() throw() {}
|
|
|
|
forcedinline void desaturate() throw()
|
|
{
|
|
r = g = b = (uint8) (((int) r + (int) g + (int) b) / 3);
|
|
}
|
|
|
|
private:
|
|
|
|
#if JUCE_MAC
|
|
uint8 r, g, b;
|
|
#else
|
|
uint8 b, g, r;
|
|
#endif
|
|
|
|
} PACKED;
|
|
|
|
#if JUCE_MSVC
|
|
#pragma pack (pop)
|
|
#endif
|
|
|
|
#undef PACKED
|
|
|
|
#endif // __JUCE_PIXELFORMATS_JUCEHEADER__
|
|
/********* End of inlined file: juce_PixelFormats.h *********/
|
|
|
|
/**
|
|
Represents a colour, also including a transparency value.
|
|
|
|
The colour is stored internally as unsigned 8-bit red, green, blue and alpha values.
|
|
*/
|
|
class JUCE_API Colour
|
|
{
|
|
public:
|
|
|
|
/** Creates a transparent black colour. */
|
|
Colour() throw();
|
|
|
|
/** Creates a copy of another Colour object. */
|
|
Colour (const Colour& other) throw();
|
|
|
|
/** Creates a colour from a 32-bit ARGB value.
|
|
|
|
The format of this number is:
|
|
((alpha << 24) | (red << 16) | (green << 8) | blue).
|
|
|
|
All components in the range 0x00 to 0xff.
|
|
An alpha of 0x00 is completely transparent, alpha of 0xff is opaque.
|
|
|
|
@see getPixelARGB
|
|
*/
|
|
explicit Colour (const uint32 argb) throw();
|
|
|
|
/** Creates an opaque colour using 8-bit red, green and blue values */
|
|
Colour (const uint8 red,
|
|
const uint8 green,
|
|
const uint8 blue) throw();
|
|
|
|
/** Creates an opaque colour using 8-bit red, green and blue values */
|
|
static const Colour fromRGB (const uint8 red,
|
|
const uint8 green,
|
|
const uint8 blue) throw();
|
|
|
|
/** Creates a colour using 8-bit red, green, blue and alpha values. */
|
|
Colour (const uint8 red,
|
|
const uint8 green,
|
|
const uint8 blue,
|
|
const uint8 alpha) throw();
|
|
|
|
/** Creates a colour using 8-bit red, green, blue and alpha values. */
|
|
static const Colour fromRGBA (const uint8 red,
|
|
const uint8 green,
|
|
const uint8 blue,
|
|
const uint8 alpha) throw();
|
|
|
|
/** Creates a colour from 8-bit red, green, and blue values, and a floating-point alpha.
|
|
|
|
Alpha of 0.0 is transparent, alpha of 1.0f is opaque.
|
|
Values outside the valid range will be clipped.
|
|
*/
|
|
Colour (const uint8 red,
|
|
const uint8 green,
|
|
const uint8 blue,
|
|
const float alpha) throw();
|
|
|
|
/** Creates a colour using 8-bit red, green, blue and float alpha values. */
|
|
static const Colour fromRGBAFloat (const uint8 red,
|
|
const uint8 green,
|
|
const uint8 blue,
|
|
const float alpha) throw();
|
|
|
|
/** Creates a colour using floating point hue, saturation and brightness values, and an 8-bit alpha.
|
|
|
|
The floating point values must be between 0.0 and 1.0.
|
|
An alpha of 0x00 is completely transparent, alpha of 0xff is opaque.
|
|
Values outside the valid range will be clipped.
|
|
*/
|
|
Colour (const float hue,
|
|
const float saturation,
|
|
const float brightness,
|
|
const uint8 alpha) throw();
|
|
|
|
/** Creates a colour using floating point hue, saturation, brightness and alpha values.
|
|
|
|
All values must be between 0.0 and 1.0.
|
|
Numbers outside the valid range will be clipped.
|
|
*/
|
|
Colour (const float hue,
|
|
const float saturation,
|
|
const float brightness,
|
|
const float alpha) throw();
|
|
|
|
/** Creates a colour using floating point hue, saturation and brightness values, and an 8-bit alpha.
|
|
|
|
The floating point values must be between 0.0 and 1.0.
|
|
An alpha of 0x00 is completely transparent, alpha of 0xff is opaque.
|
|
Values outside the valid range will be clipped.
|
|
*/
|
|
static const Colour fromHSV (const float hue,
|
|
const float saturation,
|
|
const float brightness,
|
|
const float alpha) throw();
|
|
|
|
/** Destructor. */
|
|
~Colour() throw();
|
|
|
|
/** Copies another Colour object. */
|
|
const Colour& operator= (const Colour& other) throw();
|
|
|
|
/** Compares two colours. */
|
|
bool operator== (const Colour& other) const throw();
|
|
/** Compares two colours. */
|
|
bool operator!= (const Colour& other) const throw();
|
|
|
|
/** Returns the red component of this colour.
|
|
|
|
@returns a value between 0x00 and 0xff.
|
|
*/
|
|
uint8 getRed() const throw() { return argb.getRed(); }
|
|
|
|
/** Returns the green component of this colour.
|
|
|
|
@returns a value between 0x00 and 0xff.
|
|
*/
|
|
uint8 getGreen() const throw() { return argb.getGreen(); }
|
|
|
|
/** Returns the blue component of this colour.
|
|
|
|
@returns a value between 0x00 and 0xff.
|
|
*/
|
|
uint8 getBlue() const throw() { return argb.getBlue(); }
|
|
|
|
/** Returns the red component of this colour as a floating point value.
|
|
|
|
@returns a value between 0.0 and 1.0
|
|
*/
|
|
float getFloatRed() const throw();
|
|
|
|
/** Returns the green component of this colour as a floating point value.
|
|
|
|
@returns a value between 0.0 and 1.0
|
|
*/
|
|
float getFloatGreen() const throw();
|
|
|
|
/** Returns the blue component of this colour as a floating point value.
|
|
|
|
@returns a value between 0.0 and 1.0
|
|
*/
|
|
float getFloatBlue() const throw();
|
|
|
|
/** Returns a premultiplied ARGB pixel object that represents this colour.
|
|
*/
|
|
const PixelARGB getPixelARGB() const throw();
|
|
|
|
/** Returns a 32-bit integer that represents this colour.
|
|
|
|
The format of this number is:
|
|
((alpha << 24) | (red << 16) | (green << 16) | blue).
|
|
*/
|
|
uint32 getARGB() const throw();
|
|
|
|
/** Returns the colour's alpha (opacity).
|
|
|
|
Alpha of 0x00 is completely transparent, 0xff is completely opaque.
|
|
*/
|
|
uint8 getAlpha() const throw() { return argb.getAlpha(); }
|
|
|
|
/** Returns the colour's alpha (opacity) as a floating point value.
|
|
|
|
Alpha of 0.0 is completely transparent, 1.0 is completely opaque.
|
|
*/
|
|
float getFloatAlpha() const throw();
|
|
|
|
/** Returns true if this colour is completely opaque.
|
|
|
|
Equivalent to (getAlpha() == 0xff).
|
|
*/
|
|
bool isOpaque() const throw();
|
|
|
|
/** Returns true if this colour is completely transparent.
|
|
|
|
Equivalent to (getAlpha() == 0x00).
|
|
*/
|
|
bool isTransparent() const throw();
|
|
|
|
/** Returns a colour that's the same colour as this one, but with a new alpha value. */
|
|
const Colour withAlpha (const uint8 newAlpha) const throw();
|
|
|
|
/** Returns a colour that's the same colour as this one, but with a new alpha value. */
|
|
const Colour withAlpha (const float newAlpha) const throw();
|
|
|
|
/** Returns a colour that's the same colour as this one, but with a modified alpha value.
|
|
|
|
The new colour's alpha will be this object's alpha multiplied by the value passed-in.
|
|
*/
|
|
const Colour withMultipliedAlpha (const float alphaMultiplier) const throw();
|
|
|
|
/** Returns a colour that is the result of alpha-compositing a new colour over this one.
|
|
|
|
If the foreground colour is semi-transparent, it is blended onto this colour
|
|
accordingly.
|
|
*/
|
|
const Colour overlaidWith (const Colour& foregroundColour) const throw();
|
|
|
|
/** Returns the colour's hue component.
|
|
The value returned is in the range 0.0 to 1.0
|
|
*/
|
|
float getHue() const throw();
|
|
|
|
/** Returns the colour's saturation component.
|
|
The value returned is in the range 0.0 to 1.0
|
|
*/
|
|
float getSaturation() const throw();
|
|
|
|
/** Returns the colour's brightness component.
|
|
The value returned is in the range 0.0 to 1.0
|
|
*/
|
|
float getBrightness() const throw();
|
|
|
|
/** Returns the colour's hue, saturation and brightness components all at once.
|
|
The values returned are in the range 0.0 to 1.0
|
|
*/
|
|
void getHSB (float& hue,
|
|
float& saturation,
|
|
float& brightness) const throw();
|
|
|
|
/** Returns a copy of this colour with a different hue. */
|
|
const Colour withHue (const float newHue) const throw();
|
|
|
|
/** Returns a copy of this colour with a different saturation. */
|
|
const Colour withSaturation (const float newSaturation) const throw();
|
|
|
|
/** Returns a copy of this colour with a different brightness.
|
|
@see brighter, darker, withMultipliedBrightness
|
|
*/
|
|
const Colour withBrightness (const float newBrightness) const throw();
|
|
|
|
/** Returns a copy of this colour with it hue rotated.
|
|
|
|
The new colour's hue is ((this->getHue() + amountToRotate) % 1.0)
|
|
|
|
@see brighter, darker, withMultipliedBrightness
|
|
*/
|
|
const Colour withRotatedHue (const float amountToRotate) const throw();
|
|
|
|
/** Returns a copy of this colour with its saturation multiplied by the given value.
|
|
|
|
The new colour's saturation is (this->getSaturation() * multiplier)
|
|
(the result is clipped to legal limits).
|
|
*/
|
|
const Colour withMultipliedSaturation (const float multiplier) const throw();
|
|
|
|
/** Returns a copy of this colour with its brightness multiplied by the given value.
|
|
|
|
The new colour's saturation is (this->getBrightness() * multiplier)
|
|
(the result is clipped to legal limits).
|
|
*/
|
|
const Colour withMultipliedBrightness (const float amount) const throw();
|
|
|
|
/** Returns a brighter version of this colour.
|
|
|
|
@param amountBrighter how much brighter to make it - a value from 0 to 1.0 where 0 is
|
|
unchanged, and higher values make it brighter
|
|
@see withMultipliedBrightness
|
|
*/
|
|
const Colour brighter (float amountBrighter = 0.4f) const throw();
|
|
|
|
/** Returns a darker version of this colour.
|
|
|
|
@param amountDarker how much darker to make it - a value from 0 to 1.0 where 0 is
|
|
unchanged, and higher values make it darker
|
|
@see withMultipliedBrightness
|
|
*/
|
|
const Colour darker (float amountDarker = 0.4f) const throw();
|
|
|
|
/** Returns a colour that will be clearly visible against this colour.
|
|
|
|
The amount parameter indicates how contrasting the new colour should
|
|
be, so e.g. Colours::black.contrasting (0.1f) will return a colour
|
|
that's just a little bit lighter; Colours::black.contrasting (1.0f) will
|
|
return white; Colours::white.contrasting (1.0f) will return black, etc.
|
|
*/
|
|
const Colour contrasting (const float amount = 1.0f) const throw();
|
|
|
|
/** Returns a colour that contrasts against two colours.
|
|
|
|
Looks for a colour that contrasts with both of the colours passed-in.
|
|
|
|
Handy for things like choosing a highlight colour in text editors, etc.
|
|
*/
|
|
static const Colour contrasting (const Colour& colour1,
|
|
const Colour& colour2) throw();
|
|
|
|
/** Returns an opaque shade of grey.
|
|
|
|
@param brightness the level of grey to return - 0 is black, 1.0 is white
|
|
*/
|
|
static const Colour greyLevel (const float brightness) throw();
|
|
|
|
/** Returns a stringified version of this colour.
|
|
|
|
The string can be turned back into a colour using the fromString() method.
|
|
*/
|
|
const String toString() const throw();
|
|
|
|
/** Reads the colour from a string that was created with toString().
|
|
*/
|
|
static const Colour fromString (const String& encodedColourString);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
PixelARGB argb;
|
|
};
|
|
|
|
#endif // __JUCE_COLOUR_JUCEHEADER__
|
|
/********* End of inlined file: juce_Colour.h *********/
|
|
|
|
/**
|
|
Contains a set of predefined named colours (mostly standard HTML colours)
|
|
|
|
@see Colour, Colours::greyLevel
|
|
*/
|
|
class Colours
|
|
{
|
|
public:
|
|
static JUCE_API const Colour
|
|
|
|
transparentBlack, /**< ARGB = 0x00000000 */
|
|
transparentWhite, /**< ARGB = 0x00ffffff */
|
|
|
|
black, /**< ARGB = 0xff000000 */
|
|
white, /**< ARGB = 0xffffffff */
|
|
blue, /**< ARGB = 0xff0000ff */
|
|
grey, /**< ARGB = 0xff808080 */
|
|
green, /**< ARGB = 0xff008000 */
|
|
red, /**< ARGB = 0xffff0000 */
|
|
yellow, /**< ARGB = 0xffffff00 */
|
|
|
|
aliceblue, antiquewhite, aqua, aquamarine,
|
|
azure, beige, bisque, blanchedalmond,
|
|
blueviolet, brown, burlywood, cadetblue,
|
|
chartreuse, chocolate, coral, cornflowerblue,
|
|
cornsilk, crimson, cyan, darkblue,
|
|
darkcyan, darkgoldenrod, darkgrey, darkgreen,
|
|
darkkhaki, darkmagenta, darkolivegreen, darkorange,
|
|
darkorchid, darkred, darksalmon, darkseagreen,
|
|
darkslateblue, darkslategrey, darkturquoise, darkviolet,
|
|
deeppink, deepskyblue, dimgrey, dodgerblue,
|
|
firebrick, floralwhite, forestgreen, fuchsia,
|
|
gainsboro, gold, goldenrod, greenyellow,
|
|
honeydew, hotpink, indianred, indigo,
|
|
ivory, khaki, lavender, lavenderblush,
|
|
lemonchiffon, lightblue, lightcoral, lightcyan,
|
|
lightgoldenrodyellow, lightgreen, lightgrey, lightpink,
|
|
lightsalmon, lightseagreen, lightskyblue, lightslategrey,
|
|
lightsteelblue, lightyellow, lime, limegreen,
|
|
linen, magenta, maroon, mediumaquamarine,
|
|
mediumblue, mediumorchid, mediumpurple, mediumseagreen,
|
|
mediumslateblue, mediumspringgreen, mediumturquoise, mediumvioletred,
|
|
midnightblue, mintcream, mistyrose, navajowhite,
|
|
navy, oldlace, olive, olivedrab,
|
|
orange, orangered, orchid, palegoldenrod,
|
|
palegreen, paleturquoise, palevioletred, papayawhip,
|
|
peachpuff, peru, pink, plum,
|
|
powderblue, purple, rosybrown, royalblue,
|
|
saddlebrown, salmon, sandybrown, seagreen,
|
|
seashell, sienna, silver, skyblue,
|
|
slateblue, slategrey, snow, springgreen,
|
|
steelblue, tan, teal, thistle,
|
|
tomato, turquoise, violet, wheat,
|
|
whitesmoke, yellowgreen;
|
|
|
|
/** Attempts to look up a string in the list of known colour names, and return
|
|
the appropriate colour.
|
|
|
|
A non-case-sensitive search is made of the list of predefined colours, and
|
|
if a match is found, that colour is returned. If no match is found, the
|
|
colour passed in as the defaultColour parameter is returned.
|
|
*/
|
|
static JUCE_API const Colour findColourForName (const String& colourName,
|
|
const Colour& defaultColour);
|
|
|
|
private:
|
|
|
|
// this isn't a class you should ever instantiate - it's just here for the
|
|
// static values in it.
|
|
Colours();
|
|
};
|
|
|
|
#endif // __JUCE_COLOURS_JUCEHEADER__
|
|
/********* End of inlined file: juce_Colours.h *********/
|
|
|
|
/********* Start of inlined file: juce_SolidColourBrush.h *********/
|
|
#ifndef __JUCE_SOLIDCOLOURBRUSH_JUCEHEADER__
|
|
#define __JUCE_SOLIDCOLOURBRUSH_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Brush.h *********/
|
|
#ifndef __JUCE_BRUSH_JUCEHEADER__
|
|
#define __JUCE_BRUSH_JUCEHEADER__
|
|
|
|
class Path;
|
|
class AffineTransform;
|
|
class LowLevelGraphicsContext;
|
|
class Image;
|
|
class Graphics;
|
|
|
|
/**
|
|
A brush is used to fill areas with colours, patterns, or images.
|
|
|
|
The Graphics class has an idea of a current brush which it uses to render
|
|
shapes, rectangles, lines, text, etc.
|
|
|
|
This is the base class - there are subclasses for useful types of fill pattern,
|
|
and applications can define their own brushes too.
|
|
|
|
@see Graphics::setBrush, SolidColourBrush, GradientBrush, ImageBrush
|
|
*/
|
|
class JUCE_API Brush
|
|
{
|
|
protected:
|
|
|
|
/** Creates a Brush.
|
|
|
|
(Nothing much happens in the base class).
|
|
*/
|
|
Brush() throw();
|
|
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~Brush() throw();
|
|
|
|
/** Creates a copy of whatever class of Brush this is. */
|
|
virtual Brush* createCopy() const throw() = 0;
|
|
|
|
/** Does whatever is relevent to transform the geometry of this brush. */
|
|
virtual void applyTransform (const AffineTransform& transform) throw() = 0;
|
|
|
|
/** Does whatever is relevent to change the opacity of this brush. */
|
|
virtual void multiplyOpacity (const float multiple) throw() = 0;
|
|
|
|
/** Must return true if this brush won't draw any pixels. */
|
|
virtual bool isInvisible() const throw() = 0;
|
|
|
|
virtual void paintPath (LowLevelGraphicsContext& context,
|
|
const Path& path, const AffineTransform& transform) throw() = 0;
|
|
|
|
virtual void paintRectangle (LowLevelGraphicsContext& context,
|
|
int x, int y, int w, int h) throw() = 0;
|
|
|
|
virtual void paintAlphaChannel (LowLevelGraphicsContext& context,
|
|
const Image& alphaChannelImage, int imageX, int imageY,
|
|
int x, int y, int w, int h) throw() = 0;
|
|
|
|
virtual void paintVerticalLine (LowLevelGraphicsContext& context,
|
|
int x, float y1, float y2) throw();
|
|
|
|
virtual void paintHorizontalLine (LowLevelGraphicsContext& context,
|
|
int y, float x1, float x2) throw();
|
|
|
|
virtual void paintLine (LowLevelGraphicsContext& context,
|
|
float x1, float y1, float x2, float y2) throw();
|
|
|
|
private:
|
|
|
|
Brush (const Brush&);
|
|
const Brush& operator= (const Brush&);
|
|
};
|
|
|
|
#endif // __JUCE_BRUSH_JUCEHEADER__
|
|
/********* End of inlined file: juce_Brush.h *********/
|
|
|
|
/**
|
|
A Brush that fills its area with a solid (or semi-transparent) colour.
|
|
|
|
An application won't normally need to use this class directly, as drawing
|
|
with solid colours is taken care of automatically by the Graphics class
|
|
(it actually uses one of these brushes internally when you set the colour
|
|
with the Graphics::setColour() method).
|
|
|
|
@see Brush, Graphics::setBrush, GradientBrush, ImageBrush
|
|
*/
|
|
class JUCE_API SolidColourBrush : public Brush
|
|
{
|
|
public:
|
|
|
|
/** Creates a SolidColourBrush to draw with the given colour.
|
|
|
|
The colour can be changed later with the setColour() method.
|
|
*/
|
|
SolidColourBrush (const Colour& colour) throw();
|
|
|
|
/** Creates a SolidColourBrush set to black.
|
|
|
|
The colour can be changed later with the setColour() method.
|
|
*/
|
|
SolidColourBrush() throw();
|
|
|
|
/** Destructor. */
|
|
~SolidColourBrush() throw();
|
|
|
|
/** Returns the colour currently being used. */
|
|
const Colour& getColour() const throw() { return colour; }
|
|
|
|
/** Sets the colour to use for drawing. */
|
|
void setColour (const Colour& newColour) throw() { colour = newColour; }
|
|
|
|
Brush* createCopy() const throw();
|
|
|
|
void applyTransform (const AffineTransform& transform) throw();
|
|
|
|
bool isInvisible() const throw();
|
|
|
|
void multiplyOpacity (const float multiple) throw();
|
|
|
|
void paintPath (LowLevelGraphicsContext& context,
|
|
const Path& path, const AffineTransform& transform) throw();
|
|
|
|
void paintRectangle (LowLevelGraphicsContext& context,
|
|
int x, int y, int w, int h) throw();
|
|
|
|
void paintAlphaChannel (LowLevelGraphicsContext& context,
|
|
const Image& alphaChannelImage, int imageX, int imageY,
|
|
int x, int y, int w, int h) throw();
|
|
|
|
void paintVerticalLine (LowLevelGraphicsContext& context,
|
|
int x, float y1, float y2) throw();
|
|
|
|
void paintHorizontalLine (LowLevelGraphicsContext& context,
|
|
int y, float x1, float x2) throw();
|
|
|
|
void paintLine (LowLevelGraphicsContext& context,
|
|
float x1, float y1, float x2, float y2) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Colour colour;
|
|
|
|
SolidColourBrush (const SolidColourBrush&);
|
|
const SolidColourBrush& operator= (const SolidColourBrush&);
|
|
};
|
|
|
|
#endif // __JUCE_SOLIDCOLOURBRUSH_JUCEHEADER__
|
|
/********* End of inlined file: juce_SolidColourBrush.h *********/
|
|
|
|
/********* Start of inlined file: juce_RectanglePlacement.h *********/
|
|
#ifndef __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__
|
|
#define __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__
|
|
|
|
/**
|
|
Defines the method used to postion some kind of rectangular object within
|
|
a rectangular viewport.
|
|
|
|
Although similar to Justification, this is more specific, and has some extra
|
|
options.
|
|
*/
|
|
class JUCE_API RectanglePlacement
|
|
{
|
|
public:
|
|
|
|
/** Creates a RectanglePlacement object using a combination of flags. */
|
|
inline RectanglePlacement (const int flags_) throw() : flags (flags_) {}
|
|
|
|
/** Creates a copy of another Justification object. */
|
|
RectanglePlacement (const RectanglePlacement& other) throw();
|
|
|
|
/** Copies another Justification object. */
|
|
const RectanglePlacement& operator= (const RectanglePlacement& other) throw();
|
|
|
|
/** Flag values that can be combined and used in the constructor. */
|
|
enum
|
|
{
|
|
|
|
/** Indicates that the source rectangle's left edge should be aligned with the left edge of the target rectangle. */
|
|
xLeft = 1,
|
|
|
|
/** Indicates that the source rectangle's right edge should be aligned with the right edge of the target rectangle. */
|
|
xRight = 2,
|
|
|
|
/** Indicates that the source should be placed in the centre between the left and right
|
|
sides of the available space. */
|
|
xMid = 4,
|
|
|
|
/** Indicates that the source's top edge should be aligned with the top edge of the
|
|
destination rectangle. */
|
|
yTop = 8,
|
|
|
|
/** Indicates that the source's bottom edge should be aligned with the bottom edge of the
|
|
destination rectangle. */
|
|
yBottom = 16,
|
|
|
|
/** Indicates that the source should be placed in the centre between the top and bottom
|
|
sides of the available space. */
|
|
yMid = 32,
|
|
|
|
/** If this flag is set, then the source rectangle will be resized to completely fill
|
|
the destination rectangle, and all other flags are ignored.
|
|
*/
|
|
stretchToFit = 64,
|
|
|
|
/** If this flag is set, then the source rectangle will be resized so that it is the
|
|
minimum size to completely fill the destination rectangle, without changing its
|
|
aspect ratio. This means that some of the source rectangle may fall outside
|
|
the destination.
|
|
|
|
If this flag is not set, the source will be given the maximum size at which none
|
|
of it falls outside the destination rectangle.
|
|
*/
|
|
fillDestination = 128,
|
|
|
|
/** Indicates that the source rectangle can be reduced in size if required, but should
|
|
never be made larger than its original size.
|
|
*/
|
|
onlyReduceInSize = 256,
|
|
|
|
/** Indicates that the source rectangle can be enlarged if required, but should
|
|
never be made smaller than its original size.
|
|
*/
|
|
onlyIncreaseInSize = 512,
|
|
|
|
/** Indicates that the source rectangle's size should be left unchanged.
|
|
*/
|
|
doNotResize = (onlyIncreaseInSize | onlyReduceInSize),
|
|
|
|
/** A shorthand value that is equivalent to (xMid | yMid). */
|
|
centred = 4 + 32
|
|
};
|
|
|
|
/** Returns the raw flags that are set for this object. */
|
|
inline int getFlags() const throw() { return flags; }
|
|
|
|
/** Tests a set of flags for this object.
|
|
|
|
@returns true if any of the flags passed in are set on this object.
|
|
*/
|
|
inline bool testFlags (const int flagsToTest) const throw() { return (flags & flagsToTest) != 0; }
|
|
|
|
/** Adjusts the position and size of a rectangle to fit it into a space.
|
|
|
|
The source rectangle co-ordinates will be adjusted so that they fit into
|
|
the destination rectangle based on this object's flags.
|
|
*/
|
|
void applyTo (double& sourceX,
|
|
double& sourceY,
|
|
double& sourceW,
|
|
double& sourceH,
|
|
const double destinationX,
|
|
const double destinationY,
|
|
const double destinationW,
|
|
const double destinationH) const throw();
|
|
|
|
/** Returns the transform that should be applied to these source co-ordinates to fit them
|
|
into the destination rectangle using the current flags.
|
|
*/
|
|
const AffineTransform getTransformToFit (float sourceX,
|
|
float sourceY,
|
|
float sourceW,
|
|
float sourceH,
|
|
const float destinationX,
|
|
const float destinationY,
|
|
const float destinationW,
|
|
const float destinationH) const throw();
|
|
|
|
private:
|
|
|
|
int flags;
|
|
};
|
|
|
|
#endif // __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_RectanglePlacement.h *********/
|
|
|
|
class LowLevelGraphicsContext;
|
|
class Image;
|
|
class RectangleList;
|
|
|
|
/**
|
|
A graphics context, used for drawing a component or image.
|
|
|
|
When a Component needs painting, a Graphics context is passed to its
|
|
Component::paint() method, and this you then call methods within this
|
|
object to actually draw the component's content.
|
|
|
|
A Graphics can also be created from an image, to allow drawing directly onto
|
|
that image.
|
|
|
|
@see Component::paint
|
|
*/
|
|
class JUCE_API Graphics
|
|
{
|
|
public:
|
|
|
|
/** Creates a Graphics object to draw directly onto the given image.
|
|
|
|
The graphics object that is created will be set up to draw onto the image,
|
|
with the context's clipping area being the entire size of the image, and its
|
|
origin being the image's origin. To draw into a subsection of an image, use the
|
|
reduceClipRegion() and setOrigin() methods.
|
|
|
|
Obviously you shouldn't delete the image before this context is deleted.
|
|
*/
|
|
Graphics (Image& imageToDrawOnto) throw();
|
|
|
|
/** Destructor. */
|
|
~Graphics() throw();
|
|
|
|
/** Changes the current drawing colour.
|
|
|
|
This sets the colour that will now be used for drawing operations - it also
|
|
sets the opacity to that of the colour passed-in.
|
|
|
|
If a brush is being used when this method is called, the brush will be deselected,
|
|
and any subsequent drawing will be done with a solid colour brush instead.
|
|
|
|
@see setOpacity, setBrush, getColour
|
|
*/
|
|
void setColour (const Colour& newColour) throw();
|
|
|
|
/** Returns the colour that's currently being used.
|
|
|
|
This will return the last colour set by setColour(), even if the colour's not
|
|
currently being used for drawing because a brush has been selected instead.
|
|
|
|
@see setColour
|
|
*/
|
|
const Colour& getCurrentColour() const throw();
|
|
|
|
/** Changes the opacity to use with the current colour.
|
|
|
|
If a solid colour is being used for drawing, this changes its opacity (and this
|
|
will be reflected by calls to the getColour() method).
|
|
|
|
A value of 0.0 is completely transparent, 1.0 is completely opaque.
|
|
*/
|
|
void setOpacity (const float newOpacity) throw();
|
|
|
|
/** Changes the current brush to use for drawing.
|
|
|
|
If a null pointer is passed in, the context will revert to using a solid
|
|
colour for drawing (using the last colour set by setColour()).
|
|
|
|
If a brush is passed in, a copy of it will be used for subsequent drawing
|
|
operations until setColour() or setBrush() is called.
|
|
|
|
@see SolidColourBrush, GradientBrush, ImageBrush, Brush
|
|
*/
|
|
void setBrush (const Brush* const newBrush) throw();
|
|
|
|
/** Changes the font to use for subsequent text-drawing functions.
|
|
|
|
Note there's also a setFont (float, int) method to quickly change the size and
|
|
style of the current font.
|
|
|
|
@see drawSingleLineText, drawMultiLineText, drawTextAsPath, drawText, drawFittedText
|
|
*/
|
|
void setFont (const Font& newFont) throw();
|
|
|
|
/** Changes the size and style of the currently-selected font.
|
|
|
|
This is a convenient shortcut that changes the context's current font to a
|
|
different size or style. The typeface won't be changed.
|
|
|
|
@see Font
|
|
*/
|
|
void setFont (const float newFontHeight,
|
|
const int fontStyleFlags = Font::plain) throw();
|
|
|
|
/** Returns the font that's currently being used for text operations.
|
|
|
|
@see setFont
|
|
*/
|
|
const Font& getCurrentFont() const throw();
|
|
|
|
/** Draws a one-line text string.
|
|
|
|
This will use the current colour (or brush) to fill the text. The font is the last
|
|
one specified by setFont().
|
|
|
|
@param text the string to draw
|
|
@param startX the position to draw the left-hand edge of the text
|
|
@param baselineY the position of the text's baseline
|
|
@see drawMultiLineText, drawText, drawFittedText, GlyphArrangement::addLineOfText
|
|
*/
|
|
void drawSingleLineText (const String& text,
|
|
const int startX,
|
|
const int baselineY) const throw();
|
|
|
|
/** Draws text across multiple lines.
|
|
|
|
This will break the text onto a new line where there's a new-line or
|
|
carriage-return character, or at a word-boundary when the text becomes wider
|
|
than the size specified by the maximumLineWidth parameter.
|
|
|
|
@see setFont, drawSingleLineText, drawFittedText, GlyphArrangement::addJustifiedText
|
|
*/
|
|
void drawMultiLineText (const String& text,
|
|
const int startX,
|
|
const int baselineY,
|
|
const int maximumLineWidth) const throw();
|
|
|
|
/** Renders a string of text as a vector path.
|
|
|
|
This allows a string to be transformed with an arbitrary AffineTransform and
|
|
rendered using the current colour/brush. It's much slower than the normal text methods
|
|
but more accurate.
|
|
|
|
@see setFont
|
|
*/
|
|
void drawTextAsPath (const String& text,
|
|
const AffineTransform& transform) const throw();
|
|
|
|
/** Draws a line of text within a specified rectangle.
|
|
|
|
The text will be positioned within the rectangle based on the justification
|
|
flags passed-in. If the string is too long to fit inside the rectangle, it will
|
|
either be truncated or will have ellipsis added to its end (if the useEllipsesIfTooBig
|
|
flag is true).
|
|
|
|
@see drawSingleLineText, drawFittedText, drawMultiLineText, GlyphArrangement::addJustifiedText
|
|
*/
|
|
void drawText (const String& text,
|
|
const int x,
|
|
const int y,
|
|
const int width,
|
|
const int height,
|
|
const Justification& justificationType,
|
|
const bool useEllipsesIfTooBig) const throw();
|
|
|
|
/** Tries to draw a text string inside a given space.
|
|
|
|
This does its best to make the given text readable within the specified rectangle,
|
|
so it useful for labelling things.
|
|
|
|
If the text is too big, it'll be squashed horizontally or broken over multiple lines
|
|
if the maximumLinesToUse value allows this. If the text just won't fit into the space,
|
|
it'll cram as much as possible in there, and put some ellipsis at the end to show that
|
|
it's been truncated.
|
|
|
|
A Justification parameter lets you specify how the text is laid out within the rectangle,
|
|
both horizontally and vertically.
|
|
|
|
The minimumHorizontalScale parameter specifies how much the text can be squashed horizontally
|
|
to try to squeeze it into the space. If you don't want any horizontal scaling to occur, you
|
|
can set this value to 1.0f.
|
|
|
|
@see GlyphArrangement::addFittedText
|
|
*/
|
|
void drawFittedText (const String& text,
|
|
const int x,
|
|
const int y,
|
|
const int width,
|
|
const int height,
|
|
const Justification& justificationFlags,
|
|
const int maximumNumberOfLines,
|
|
const float minimumHorizontalScale = 0.7f) const throw();
|
|
|
|
/** Fills the context's entire clip region with the current colour or brush.
|
|
|
|
(See also the fillAll (const Colour&) method which is a quick way of filling
|
|
it with a given colour).
|
|
*/
|
|
void fillAll() const throw();
|
|
|
|
/** Fills the context's entire clip region with a given colour.
|
|
|
|
This leaves the context's current colour and brush unchanged, it just
|
|
uses the specified colour temporarily.
|
|
*/
|
|
void fillAll (const Colour& colourToUse) const throw();
|
|
|
|
/** Fills a rectangle with the current colour or brush.
|
|
|
|
@see drawRect, fillRoundedRectangle
|
|
*/
|
|
void fillRect (int x,
|
|
int y,
|
|
int width,
|
|
int height) const throw();
|
|
|
|
/** Fills a rectangle with the current colour or brush. */
|
|
void fillRect (const Rectangle& rectangle) const throw();
|
|
|
|
/** Fills a rectangle with the current colour or brush.
|
|
|
|
This uses sub-pixel positioning so is slower than the fillRect method which
|
|
takes integer co-ordinates.
|
|
*/
|
|
void fillRect (const float x,
|
|
const float y,
|
|
const float width,
|
|
const float height) const throw();
|
|
|
|
/** Uses the current colour or brush to fill a rectangle with rounded corners.
|
|
|
|
@see drawRoundedRectangle, Path::addRoundedRectangle
|
|
*/
|
|
void fillRoundedRectangle (const float x,
|
|
const float y,
|
|
const float width,
|
|
const float height,
|
|
const float cornerSize) const throw();
|
|
|
|
/** Uses the current colour or brush to fill a rectangle with rounded corners.
|
|
|
|
@see drawRoundedRectangle, Path::addRoundedRectangle
|
|
*/
|
|
void fillRoundedRectangle (const Rectangle& rectangle,
|
|
const float cornerSize) const throw();
|
|
|
|
/** Fills a rectangle with a checkerboard pattern, alternating between two colours.
|
|
*/
|
|
void fillCheckerBoard (int x, int y,
|
|
int width, int height,
|
|
const int checkWidth,
|
|
const int checkHeight,
|
|
const Colour& colour1,
|
|
const Colour& colour2) const throw();
|
|
|
|
/** Draws four lines to form a rectangular outline, using the current colour or brush.
|
|
|
|
The lines are drawn inside the given rectangle, and greater line thicknesses
|
|
extend inwards.
|
|
|
|
@see fillRect
|
|
*/
|
|
void drawRect (const int x,
|
|
const int y,
|
|
const int width,
|
|
const int height,
|
|
const int lineThickness = 1) const throw();
|
|
|
|
/** Draws four lines to form a rectangular outline, using the current colour or brush.
|
|
|
|
The lines are drawn inside the given rectangle, and greater line thicknesses
|
|
extend inwards.
|
|
|
|
@see fillRect
|
|
*/
|
|
void drawRect (const float x,
|
|
const float y,
|
|
const float width,
|
|
const float height,
|
|
const float lineThickness = 1.0f) const throw();
|
|
|
|
/** Draws four lines to form a rectangular outline, using the current colour or brush.
|
|
|
|
The lines are drawn inside the given rectangle, and greater line thicknesses
|
|
extend inwards.
|
|
|
|
@see fillRect
|
|
*/
|
|
void drawRect (const Rectangle& rectangle,
|
|
const int lineThickness = 1) const throw();
|
|
|
|
/** Uses the current colour or brush to draw the outline of a rectangle with rounded corners.
|
|
|
|
@see fillRoundedRectangle, Path::addRoundedRectangle
|
|
*/
|
|
void drawRoundedRectangle (const float x,
|
|
const float y,
|
|
const float width,
|
|
const float height,
|
|
const float cornerSize,
|
|
const float lineThickness) const throw();
|
|
|
|
/** Uses the current colour or brush to draw the outline of a rectangle with rounded corners.
|
|
|
|
@see fillRoundedRectangle, Path::addRoundedRectangle
|
|
*/
|
|
void drawRoundedRectangle (const Rectangle& rectangle,
|
|
const float cornerSize,
|
|
const float lineThickness) const throw();
|
|
|
|
/** Draws a 3D raised (or indented) bevel using two colours.
|
|
|
|
The bevel is drawn inside the given rectangle, and greater bevel thicknesses
|
|
extend inwards.
|
|
|
|
The top-left colour is used for the top- and left-hand edges of the
|
|
bevel; the bottom-right colour is used for the bottom- and right-hand
|
|
edges.
|
|
|
|
If useGradient is true, then the bevel fades out to make it look more curved
|
|
and less angular. If sharpEdgeOnOutside is true, the outside of the bevel is
|
|
sharp, and it fades towards the centre; if sharpEdgeOnOutside is false, then
|
|
the centre edges are sharp and it fades towards the outside.
|
|
*/
|
|
void drawBevel (const int x,
|
|
const int y,
|
|
const int width,
|
|
const int height,
|
|
const int bevelThickness,
|
|
const Colour& topLeftColour = Colours::white,
|
|
const Colour& bottomRightColour = Colours::black,
|
|
const bool useGradient = true,
|
|
const bool sharpEdgeOnOutside = true) const throw();
|
|
|
|
/** Draws a pixel using the current colour or brush.
|
|
*/
|
|
void setPixel (int x, int y) const throw();
|
|
|
|
/** Fills an ellipse with the current colour or brush.
|
|
|
|
The ellipse is drawn to fit inside the given rectangle.
|
|
|
|
@see drawEllipse, Path::addEllipse
|
|
*/
|
|
void fillEllipse (const float x,
|
|
const float y,
|
|
const float width,
|
|
const float height) const throw();
|
|
|
|
/** Draws an elliptical stroke using the current colour or brush.
|
|
|
|
@see fillEllipse, Path::addEllipse
|
|
*/
|
|
void drawEllipse (const float x,
|
|
const float y,
|
|
const float width,
|
|
const float height,
|
|
const float lineThickness) const throw();
|
|
|
|
/** Draws a line between two points.
|
|
|
|
The line is 1 pixel wide and drawn with the current colour or brush.
|
|
*/
|
|
void drawLine (float startX,
|
|
float startY,
|
|
float endX,
|
|
float endY) const throw();
|
|
|
|
/** Draws a line between two points with a given thickness.
|
|
|
|
@see Path::addLineSegment
|
|
*/
|
|
void drawLine (const float startX,
|
|
const float startY,
|
|
const float endX,
|
|
const float endY,
|
|
const float lineThickness) const throw();
|
|
|
|
/** Draws a line between two points.
|
|
|
|
The line is 1 pixel wide and drawn with the current colour or brush.
|
|
*/
|
|
void drawLine (const Line& line) const throw();
|
|
|
|
/** Draws a line between two points with a given thickness.
|
|
|
|
@see Path::addLineSegment
|
|
*/
|
|
void drawLine (const Line& line,
|
|
const float lineThickness) const throw();
|
|
|
|
/** Draws a dashed line using a custom set of dash-lengths.
|
|
|
|
@param startX the line's start x co-ordinate
|
|
@param startY the line's start y co-ordinate
|
|
@param endX the line's end x co-ordinate
|
|
@param endY the line's end y co-ordinate
|
|
@param dashLengths a series of lengths to specify the on/off lengths - e.g.
|
|
{ 4, 5, 6, 7 } will draw a line of 4 pixels, skip 5 pixels,
|
|
draw 6 pixels, skip 7 pixels, and then repeat.
|
|
@param numDashLengths the number of elements in the array (this must be an even number).
|
|
@param lineThickness the thickness of the line to draw
|
|
@see PathStrokeType::createDashedStroke
|
|
*/
|
|
void drawDashedLine (const float startX,
|
|
const float startY,
|
|
const float endX,
|
|
const float endY,
|
|
const float* const dashLengths,
|
|
const int numDashLengths,
|
|
const float lineThickness = 1.0f) const throw();
|
|
|
|
/** Draws a vertical line of pixels at a given x position.
|
|
|
|
The x position is an integer, but the top and bottom of the line can be sub-pixel
|
|
positions, and these will be anti-aliased if necessary.
|
|
*/
|
|
void drawVerticalLine (const int x, float top, float bottom) const throw();
|
|
|
|
/** Draws a horizontal line of pixels at a given y position.
|
|
|
|
The y position is an integer, but the left and right ends of the line can be sub-pixel
|
|
positions, and these will be anti-aliased if necessary.
|
|
*/
|
|
void drawHorizontalLine (const int y, float left, float right) const throw();
|
|
|
|
/** Fills a path using the currently selected colour or brush.
|
|
*/
|
|
void fillPath (const Path& path,
|
|
const AffineTransform& transform = AffineTransform::identity) const throw();
|
|
|
|
/** Draws a path's outline using the currently selected colour or brush.
|
|
*/
|
|
void strokePath (const Path& path,
|
|
const PathStrokeType& strokeType,
|
|
const AffineTransform& transform = AffineTransform::identity) const throw();
|
|
|
|
/** Draws a line with an arrowhead.
|
|
|
|
@param startX the line's start x co-ordinate
|
|
@param startY the line's start y co-ordinate
|
|
@param endX the line's end x co-ordinate (the tip of the arrowhead)
|
|
@param endY the line's end y co-ordinate (the tip of the arrowhead)
|
|
@param lineThickness the thickness of the line
|
|
@param arrowheadWidth the width of the arrow head (perpendicular to the line)
|
|
@param arrowheadLength the length of the arrow head (along the length of the line)
|
|
*/
|
|
void drawArrow (const float startX,
|
|
const float startY,
|
|
const float endX,
|
|
const float endY,
|
|
const float lineThickness,
|
|
const float arrowheadWidth,
|
|
const float arrowheadLength) const throw();
|
|
|
|
/** Types of rendering quality that can be specified when drawing images.
|
|
|
|
@see blendImage, Graphics::setImageResamplingQuality
|
|
*/
|
|
enum ResamplingQuality
|
|
{
|
|
lowResamplingQuality = 0, /**< Just uses a nearest-neighbour algorithm for resampling. */
|
|
mediumResamplingQuality = 1, /**< Uses bilinear interpolation for upsampling and area-averaging for downsampling. */
|
|
highResamplingQuality = 2 /**< Uses bicubic interpolation for upsampling and area-averaging for downsampling. */
|
|
};
|
|
|
|
/** Changes the quality that will be used when resampling images.
|
|
|
|
By default a Graphics object will be set to mediumRenderingQuality.
|
|
|
|
@see Graphics::drawImage, Graphics::drawImageTransformed, Graphics::drawImageWithin
|
|
*/
|
|
void setImageResamplingQuality (const ResamplingQuality newQuality) throw();
|
|
|
|
/** Draws an image.
|
|
|
|
This will draw the whole of an image, positioning its top-left corner at the
|
|
given co-ordinates, and keeping its size the same. This is the simplest image
|
|
drawing method - the others give more control over the scaling and clipping
|
|
of the images.
|
|
|
|
Images are composited using the context's current opacity, so if you
|
|
don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f)
|
|
(or setColour() with an opaque colour) before drawing images.
|
|
*/
|
|
void drawImageAt (const Image* const imageToDraw,
|
|
const int topLeftX,
|
|
const int topLeftY,
|
|
const bool fillAlphaChannelWithCurrentBrush = false) const throw();
|
|
|
|
/** Draws part of an image, rescaling it to fit in a given target region.
|
|
|
|
The specified area of the source image is rescaled and drawn to fill the
|
|
specifed destination rectangle.
|
|
|
|
Images are composited using the context's current opacity, so if you
|
|
don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f)
|
|
(or setColour() with an opaque colour) before drawing images.
|
|
|
|
@param imageToDraw the image to overlay
|
|
@param destX the left of the destination rectangle
|
|
@param destY the top of the destination rectangle
|
|
@param destWidth the width of the destination rectangle
|
|
@param destHeight the height of the destination rectangle
|
|
@param sourceX the left of the rectangle to copy from the source image
|
|
@param sourceY the top of the rectangle to copy from the source image
|
|
@param sourceWidth the width of the rectangle to copy from the source image
|
|
@param sourceHeight the height of the rectangle to copy from the source image
|
|
@param fillAlphaChannelWithCurrentBrush if true, then instead of drawing the source image's pixels,
|
|
the source image's alpha channel is used as a mask with
|
|
which to fill the destination using the current colour
|
|
or brush. (If the source is has no alpha channel, then
|
|
it will just fill the target with a solid rectangle)
|
|
@see setImageResamplingQuality, drawImageAt, drawImageWithin, fillAlphaMap
|
|
*/
|
|
void drawImage (const Image* const imageToDraw,
|
|
int destX,
|
|
int destY,
|
|
int destWidth,
|
|
int destHeight,
|
|
int sourceX,
|
|
int sourceY,
|
|
int sourceWidth,
|
|
int sourceHeight,
|
|
const bool fillAlphaChannelWithCurrentBrush = false) const throw();
|
|
|
|
/** Draws part of an image, having applied an affine transform to it.
|
|
|
|
This lets you throw the image around in some wacky ways, rotate it, shear,
|
|
scale it, etc.
|
|
|
|
A clipping subregion is specified within the source image and no pixels
|
|
outside this region will be used.
|
|
|
|
Images are composited using the context's current opacity, so if you
|
|
don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f)
|
|
(or setColour() with an opaque colour) before drawing images.
|
|
|
|
If fillAlphaChannelWithCurrentBrush is set to true, then the image's RGB channels
|
|
are ignored and it is filled with the current brush, masked by its alpha channel.
|
|
|
|
@see setImageResamplingQuality, drawImage
|
|
*/
|
|
void drawImageTransformed (const Image* const imageToDraw,
|
|
int sourceClipX,
|
|
int sourceClipY,
|
|
int sourceClipWidth,
|
|
int sourceClipHeight,
|
|
const AffineTransform& transform,
|
|
const bool fillAlphaChannelWithCurrentBrush = false) const throw();
|
|
|
|
/** Draws an image to fit within a designated rectangle.
|
|
|
|
If the image is too big or too small for the space, it will be rescaled
|
|
to fit as nicely as it can do without affecting its aspect ratio. It will
|
|
then be placed within the target rectangle according to the justification flags
|
|
specified.
|
|
|
|
@param imageToDraw the source image to draw
|
|
@param destX top-left of the target rectangle to fit it into
|
|
@param destY top-left of the target rectangle to fit it into
|
|
@param destWidth size of the target rectangle to fit the image into
|
|
@param destHeight size of the target rectangle to fit the image into
|
|
@param placementWithinTarget this specifies how the image should be positioned
|
|
within the target rectangle - see the RectanglePlacement
|
|
class for more details about this.
|
|
@param fillAlphaChannelWithCurrentBrush if true, then instead of drawing the image, just its
|
|
alpha channel will be used as a mask with which to
|
|
draw with the current brush or colour. This is
|
|
similar to fillAlphaMap(), and see also drawImage()
|
|
@see setImageResamplingQuality, drawImage, drawImageTransformed, drawImageAt, RectanglePlacement
|
|
*/
|
|
void drawImageWithin (const Image* const imageToDraw,
|
|
const int destX,
|
|
const int destY,
|
|
const int destWidth,
|
|
const int destHeight,
|
|
const RectanglePlacement& placementWithinTarget,
|
|
const bool fillAlphaChannelWithCurrentBrush = false) const throw();
|
|
|
|
/** Returns the position of the bounding box for the current clipping region.
|
|
|
|
@see getClipRegion, clipRegionIntersects
|
|
*/
|
|
const Rectangle getClipBounds() const throw();
|
|
|
|
/** Checks whether a rectangle overlaps the context's clipping region.
|
|
|
|
If this returns false, no part of the given area can be drawn onto, so this
|
|
method can be used to optimise a component's paint() method, by letting it
|
|
avoid drawing complex objects that aren't within the region being repainted.
|
|
*/
|
|
bool clipRegionIntersects (const int x, const int y, const int width, const int height) const throw();
|
|
|
|
/** Intersects the current clipping region with another region.
|
|
|
|
@returns true if the resulting clipping region is non-zero in size
|
|
@see setOrigin, clipRegionIntersects, getClipLeft, getClipRight, getClipWidth, getClipHeight
|
|
*/
|
|
bool reduceClipRegion (const int x, const int y,
|
|
const int width, const int height) throw();
|
|
|
|
/** Intersects the current clipping region with a rectangle list region.
|
|
|
|
@returns true if the resulting clipping region is non-zero in size
|
|
@see setOrigin, clipRegionIntersects, getClipLeft, getClipRight, getClipWidth, getClipHeight
|
|
*/
|
|
bool reduceClipRegion (const RectangleList& clipRegion) throw();
|
|
|
|
/** Excludes a rectangle to stop it being drawn into. */
|
|
void excludeClipRegion (const int x, const int y,
|
|
const int width, const int height) throw();
|
|
|
|
/** Returns true if no drawing can be done because the clip region is zero. */
|
|
bool isClipEmpty() const throw();
|
|
|
|
/** Saves the current graphics state on an internal stack.
|
|
|
|
To restore the state, use restoreState().
|
|
*/
|
|
void saveState() throw();
|
|
|
|
/** Restores a graphics state that was previously saved with saveState().
|
|
*/
|
|
void restoreState() throw();
|
|
|
|
/** Moves the position of the context's origin.
|
|
|
|
This changes the position that the context considers to be (0, 0) to
|
|
the specified position.
|
|
|
|
So if you call setOrigin (100, 100), then the position that was previously
|
|
referred to as (100, 100) will subsequently be considered to be (0, 0).
|
|
|
|
@see reduceClipRegion
|
|
*/
|
|
void setOrigin (const int newOriginX,
|
|
const int newOriginY) throw();
|
|
|
|
/** Resets the current colour, brush, and font to default settings. */
|
|
void resetToDefaultState() throw();
|
|
|
|
/** Returns true if this context is drawing to a vector-based device, such as a printer. */
|
|
bool isVectorDevice() const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
/** Create a graphics that uses a given low-level renderer.
|
|
|
|
For internal use only.
|
|
|
|
NB. The context will NOT be deleted by this object when it is deleted.
|
|
*/
|
|
Graphics (LowLevelGraphicsContext* const internalContext) throw();
|
|
|
|
/** @internal */
|
|
LowLevelGraphicsContext* getInternalContext() const throw() { return context; }
|
|
|
|
private:
|
|
|
|
LowLevelGraphicsContext* const context;
|
|
const bool ownsContext;
|
|
|
|
struct GraphicsState
|
|
{
|
|
GraphicsState() throw();
|
|
GraphicsState (const GraphicsState&) throw();
|
|
~GraphicsState() throw();
|
|
|
|
Colour colour;
|
|
Brush* brush;
|
|
Font font;
|
|
ResamplingQuality quality;
|
|
};
|
|
|
|
GraphicsState* state;
|
|
OwnedArray <GraphicsState> stateStack;
|
|
bool saveStatePending;
|
|
|
|
void saveStateIfPending() throw();
|
|
|
|
const Graphics& operator= (const Graphics& other);
|
|
Graphics (const Graphics&);
|
|
};
|
|
|
|
#endif // __JUCE_GRAPHICS_JUCEHEADER__
|
|
/********* End of inlined file: juce_Graphics.h *********/
|
|
|
|
/**
|
|
A graphical effect filter that can be applied to components.
|
|
|
|
An ImageEffectFilter can be applied to the image that a component
|
|
paints before it hits the screen.
|
|
|
|
This is used for adding effects like shadows, blurs, etc.
|
|
|
|
@see Component::setComponentEffect
|
|
*/
|
|
class JUCE_API ImageEffectFilter
|
|
{
|
|
public:
|
|
|
|
/** Overridden to render the effect.
|
|
|
|
The implementation of this method must use the image that is passed in
|
|
as its source, and should render its output to the graphics context passed in.
|
|
|
|
@param sourceImage the image that the source component has just rendered with
|
|
its paint() method. The image may or may not have an alpha
|
|
channel, depending on whether the component is opaque.
|
|
@param destContext the graphics context to use to draw the resultant image.
|
|
*/
|
|
virtual void applyEffect (Image& sourceImage,
|
|
Graphics& destContext) = 0;
|
|
|
|
/** Destructor. */
|
|
virtual ~ImageEffectFilter() {}
|
|
|
|
};
|
|
|
|
#endif // __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__
|
|
/********* End of inlined file: juce_ImageEffectFilter.h *********/
|
|
|
|
/********* Start of inlined file: juce_RectangleList.h *********/
|
|
#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__
|
|
#define __JUCE_RECTANGLELIST_JUCEHEADER__
|
|
|
|
/**
|
|
Maintains a set of rectangles as a complex region.
|
|
|
|
This class allows a set of rectangles to be treated as a solid shape, and can
|
|
add and remove rectangular sections of it, and simplify overlapping or
|
|
adjacent rectangles.
|
|
|
|
@see Rectangle
|
|
*/
|
|
class JUCE_API RectangleList
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty RectangleList */
|
|
RectangleList() throw();
|
|
|
|
/** Creates a copy of another list */
|
|
RectangleList (const RectangleList& other) throw();
|
|
|
|
/** Creates a list containing just one rectangle. */
|
|
RectangleList (const Rectangle& rect) throw();
|
|
|
|
/** Copies this list from another one. */
|
|
const RectangleList& operator= (const RectangleList& other) throw();
|
|
|
|
/** Destructor. */
|
|
~RectangleList() throw();
|
|
|
|
/** Returns true if the region is empty. */
|
|
bool isEmpty() const throw();
|
|
|
|
/** Returns the number of rectangles in the list. */
|
|
int getNumRectangles() const throw() { return rects.size(); }
|
|
|
|
/** Returns one of the rectangles at a particular index.
|
|
|
|
@returns the rectangle at the index, or an empty rectangle if the
|
|
index is out-of-range.
|
|
*/
|
|
const Rectangle getRectangle (const int index) const throw();
|
|
|
|
/** Removes all rectangles to leave an empty region. */
|
|
void clear() throw();
|
|
|
|
/** Merges a new rectangle into the list.
|
|
|
|
The rectangle being added will first be clipped to remove any parts of it
|
|
that overlap existing rectangles in the list.
|
|
*/
|
|
void add (const int x, const int y,
|
|
const int w, const int h) throw();
|
|
|
|
/** Merges a new rectangle into the list.
|
|
|
|
The rectangle being added will first be clipped to remove any parts of it
|
|
that overlap existing rectangles in the list, and adjacent rectangles will be
|
|
merged into it.
|
|
*/
|
|
void add (const Rectangle& rect) throw();
|
|
|
|
/** Dumbly adds a rectangle to the list without checking for overlaps.
|
|
|
|
This simply adds the rectangle to the end, it doesn't merge it or remove
|
|
any overlapping bits.
|
|
*/
|
|
void addWithoutMerging (const Rectangle& rect) throw();
|
|
|
|
/** Merges another rectangle list into this one.
|
|
|
|
Any overlaps between the two lists will be clipped, so that the result is
|
|
the union of both lists.
|
|
*/
|
|
void add (const RectangleList& other) throw();
|
|
|
|
/** Removes a rectangular region from the list.
|
|
|
|
Any rectangles in the list which overlap this will be clipped and subdivided
|
|
if necessary.
|
|
*/
|
|
void subtract (const Rectangle& rect) throw();
|
|
|
|
/** Removes all areas in another RectangleList from this one.
|
|
|
|
Any rectangles in the list which overlap this will be clipped and subdivided
|
|
if necessary.
|
|
*/
|
|
void subtract (const RectangleList& otherList) throw();
|
|
|
|
/** Removes any areas of the region that lie outside a given rectangle.
|
|
|
|
Any rectangles in the list which overlap this will be clipped and subdivided
|
|
if necessary.
|
|
|
|
Returns true if the resulting region is not empty, false if it is empty.
|
|
|
|
@see getIntersectionWith
|
|
*/
|
|
bool clipTo (const Rectangle& rect) throw();
|
|
|
|
/** Removes any areas of the region that lie outside a given rectangle list.
|
|
|
|
Any rectangles in this object which overlap the specified list will be clipped
|
|
and subdivided if necessary.
|
|
|
|
Returns true if the resulting region is not empty, false if it is empty.
|
|
|
|
@see getIntersectionWith
|
|
*/
|
|
bool clipTo (const RectangleList& other) throw();
|
|
|
|
/** Creates a region which is the result of clipping this one to a given rectangle.
|
|
|
|
Unlike the other clipTo method, this one doesn't affect this object - it puts the
|
|
resulting region into the list whose reference is passed-in.
|
|
|
|
Returns true if the resulting region is not empty, false if it is empty.
|
|
|
|
@see clipTo
|
|
*/
|
|
bool getIntersectionWith (const Rectangle& rect, RectangleList& destRegion) const throw();
|
|
|
|
/** Swaps the contents of this and another list.
|
|
|
|
This swaps their internal pointers, so is hugely faster than using copy-by-value
|
|
to swap them.
|
|
*/
|
|
void swapWith (RectangleList& otherList) throw();
|
|
|
|
/** Checks whether the region contains a given point.
|
|
|
|
@returns true if the point lies within one of the rectangles in the list
|
|
*/
|
|
bool containsPoint (const int x, const int y) const throw();
|
|
|
|
/** Checks whether the region contains the whole of a given rectangle.
|
|
|
|
@returns true all parts of the rectangle passed in lie within the region
|
|
defined by this object
|
|
@see intersectsRectangle, containsPoint
|
|
*/
|
|
bool containsRectangle (const Rectangle& rectangleToCheck) const throw();
|
|
|
|
/** Checks whether the region contains any part of a given rectangle.
|
|
|
|
@returns true if any part of the rectangle passed in lies within the region
|
|
defined by this object
|
|
@see containsRectangle
|
|
*/
|
|
bool intersectsRectangle (const Rectangle& rectangleToCheck) const throw();
|
|
|
|
/** Checks whether this region intersects any part of another one.
|
|
|
|
@see intersectsRectangle
|
|
*/
|
|
bool intersects (const RectangleList& other) const throw();
|
|
|
|
/** Returns the smallest rectangle that can enclose the whole of this region. */
|
|
const Rectangle getBounds() const throw();
|
|
|
|
/** Optimises the list into a minimum number of constituent rectangles.
|
|
|
|
This will try to combine any adjacent rectangles into larger ones where
|
|
possible, to simplify lists that might have been fragmented by repeated
|
|
add/subtract calls.
|
|
*/
|
|
void consolidate() throw();
|
|
|
|
/** Adds an x and y value to all the co-ordinates. */
|
|
void offsetAll (const int dx, const int dy) throw();
|
|
|
|
/** Creates a Path object to represent this region. */
|
|
const Path toPath() const throw();
|
|
|
|
/** An iterator for accessing all the rectangles in a RectangleList. */
|
|
class Iterator
|
|
{
|
|
public:
|
|
|
|
Iterator (const RectangleList& list) throw();
|
|
~Iterator() throw();
|
|
|
|
/** Advances to the next rectangle, and returns true if it's not finished.
|
|
|
|
Call this before using getRectangle() to find the rectangle that was returned.
|
|
*/
|
|
bool next() throw();
|
|
|
|
/** Returns the current rectangle. */
|
|
const Rectangle* getRectangle() const throw() { return current; }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
const Rectangle* current;
|
|
const RectangleList& owner;
|
|
int index;
|
|
|
|
Iterator (const Iterator&);
|
|
const Iterator& operator= (const Iterator&);
|
|
};
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class Iterator;
|
|
Array <Rectangle> rects;
|
|
};
|
|
|
|
#endif // __JUCE_RECTANGLELIST_JUCEHEADER__
|
|
/********* End of inlined file: juce_RectangleList.h *********/
|
|
|
|
/********* Start of inlined file: juce_BorderSize.h *********/
|
|
#ifndef __JUCE_BORDERSIZE_JUCEHEADER__
|
|
#define __JUCE_BORDERSIZE_JUCEHEADER__
|
|
|
|
/**
|
|
Specifies a set of gaps to be left around the sides of a rectangle.
|
|
|
|
This is basically the size of the spaces at the top, bottom, left and right of
|
|
a rectangle. It's used by various component classes to specify borders.
|
|
|
|
@see Rectangle
|
|
*/
|
|
class JUCE_API BorderSize
|
|
{
|
|
public:
|
|
|
|
/** Creates a null border.
|
|
|
|
All sizes are left as 0.
|
|
*/
|
|
BorderSize() throw();
|
|
|
|
/** Creates a copy of another border. */
|
|
BorderSize (const BorderSize& other) throw();
|
|
|
|
/** Creates a border with the given gaps. */
|
|
BorderSize (const int topGap,
|
|
const int leftGap,
|
|
const int bottomGap,
|
|
const int rightGap) throw();
|
|
|
|
/** Creates a border with the given gap on all sides. */
|
|
BorderSize (const int allGaps) throw();
|
|
|
|
/** Destructor. */
|
|
~BorderSize() throw();
|
|
|
|
/** Returns the gap that should be left at the top of the region. */
|
|
int getTop() const throw() { return top; }
|
|
|
|
/** Returns the gap that should be left at the top of the region. */
|
|
int getLeft() const throw() { return left; }
|
|
|
|
/** Returns the gap that should be left at the top of the region. */
|
|
int getBottom() const throw() { return bottom; }
|
|
|
|
/** Returns the gap that should be left at the top of the region. */
|
|
int getRight() const throw() { return right; }
|
|
|
|
/** Returns the sum of the top and bottom gaps. */
|
|
int getTopAndBottom() const throw() { return top + bottom; }
|
|
|
|
/** Returns the sum of the left and right gaps. */
|
|
int getLeftAndRight() const throw() { return left + right; }
|
|
|
|
/** Changes the top gap. */
|
|
void setTop (const int newTopGap) throw();
|
|
|
|
/** Changes the left gap. */
|
|
void setLeft (const int newLeftGap) throw();
|
|
|
|
/** Changes the bottom gap. */
|
|
void setBottom (const int newBottomGap) throw();
|
|
|
|
/** Changes the right gap. */
|
|
void setRight (const int newRightGap) throw();
|
|
|
|
/** Returns a rectangle with these borders removed from it. */
|
|
const Rectangle subtractedFrom (const Rectangle& original) const throw();
|
|
|
|
/** Removes this border from a given rectangle. */
|
|
void subtractFrom (Rectangle& rectangle) const throw();
|
|
|
|
/** Returns a rectangle with these borders added around it. */
|
|
const Rectangle addedTo (const Rectangle& original) const throw();
|
|
|
|
/** Adds this border around a given rectangle. */
|
|
void addTo (Rectangle& original) const throw();
|
|
|
|
bool operator== (const BorderSize& other) const throw();
|
|
bool operator!= (const BorderSize& other) const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int top, left, bottom, right;
|
|
};
|
|
|
|
#endif // __JUCE_BORDERSIZE_JUCEHEADER__
|
|
/********* End of inlined file: juce_BorderSize.h *********/
|
|
|
|
/********* Start of inlined file: juce_ComponentPeer.h *********/
|
|
#ifndef __JUCE_COMPONENTPEER_JUCEHEADER__
|
|
#define __JUCE_COMPONENTPEER_JUCEHEADER__
|
|
|
|
class Component;
|
|
class Graphics;
|
|
|
|
/********* Start of inlined file: juce_MessageListener.h *********/
|
|
#ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__
|
|
#define __JUCE_MESSAGELISTENER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Message.h *********/
|
|
#ifndef __JUCE_MESSAGE_JUCEHEADER__
|
|
#define __JUCE_MESSAGE_JUCEHEADER__
|
|
|
|
class MessageListener;
|
|
class MessageManager;
|
|
|
|
/** The base class for objects that can be delivered to a MessageListener.
|
|
|
|
The simplest Message object contains a few integer and pointer parameters
|
|
that the user can set, and this is enough for a lot of purposes. For passing more
|
|
complex data, subclasses of Message can also be used.
|
|
|
|
@see MessageListener, MessageManager, ActionListener, ChangeListener
|
|
*/
|
|
class JUCE_API Message
|
|
{
|
|
public:
|
|
|
|
/** Creates an uninitialised message.
|
|
|
|
The class's variables will also be left uninitialised.
|
|
*/
|
|
Message() throw();
|
|
|
|
/** Creates a message object, filling in the member variables.
|
|
|
|
The corresponding public member variables will be set from the parameters
|
|
passed in.
|
|
*/
|
|
Message (const int intParameter1,
|
|
const int intParameter2,
|
|
const int intParameter3,
|
|
void* const pointerParameter) throw();
|
|
|
|
/** Destructor. */
|
|
virtual ~Message() throw();
|
|
|
|
// These values can be used for carrying simple data that the application needs to
|
|
// pass around. For more complex messages, just create a subclass.
|
|
|
|
int intParameter1; /**< user-defined integer value. */
|
|
int intParameter2; /**< user-defined integer value. */
|
|
int intParameter3; /**< user-defined integer value. */
|
|
void* pointerParameter; /**< user-defined pointer value. */
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class MessageListener;
|
|
friend class MessageManager;
|
|
MessageListener* messageRecipient;
|
|
|
|
Message (const Message&);
|
|
const Message& operator= (const Message&);
|
|
};
|
|
|
|
#endif // __JUCE_MESSAGE_JUCEHEADER__
|
|
/********* End of inlined file: juce_Message.h *********/
|
|
|
|
/**
|
|
MessageListener subclasses can post and receive Message objects.
|
|
|
|
@see Message, MessageManager, ActionListener, ChangeListener
|
|
*/
|
|
class JUCE_API MessageListener
|
|
{
|
|
protected:
|
|
|
|
/** Creates a MessageListener. */
|
|
MessageListener() throw();
|
|
|
|
public:
|
|
|
|
/** Destructor.
|
|
|
|
When a MessageListener is deleted, it removes itself from a global list
|
|
of registered listeners, so that the isValidMessageListener() method
|
|
will no longer return true.
|
|
*/
|
|
virtual ~MessageListener();
|
|
|
|
/** This is the callback method that receives incoming messages.
|
|
|
|
This is called by the MessageManager from its dispatch loop.
|
|
|
|
@see postMessage
|
|
*/
|
|
virtual void handleMessage (const Message& message) = 0;
|
|
|
|
/** Sends a message to the message queue, for asynchronous delivery to this listener
|
|
later on.
|
|
|
|
This method can be called safely by any thread.
|
|
|
|
@param message the message object to send - this will be deleted
|
|
automatically by the message queue, so don't keep any
|
|
references to it after calling this method.
|
|
@see handleMessage
|
|
*/
|
|
void postMessage (Message* const message) const throw();
|
|
|
|
/** Checks whether this MessageListener has been deleted.
|
|
|
|
Although not foolproof, this method is safe to call on dangling or null
|
|
pointers. A list of active MessageListeners is kept internally, so this
|
|
checks whether the object is on this list or not.
|
|
|
|
Note that it's possible to get a false-positive here, if an object is
|
|
deleted and another is subsequently created that happens to be at the
|
|
exact same memory location, but I can't think of a good way of avoiding
|
|
this.
|
|
*/
|
|
bool isValidMessageListener() const throw();
|
|
};
|
|
|
|
#endif // __JUCE_MESSAGELISTENER_JUCEHEADER__
|
|
/********* End of inlined file: juce_MessageListener.h *********/
|
|
|
|
class ComponentBoundsConstrainer;
|
|
class ComponentDeletionWatcher;
|
|
|
|
/**
|
|
The base class for window objects that wrap a component as a real operating
|
|
system object.
|
|
|
|
This is an abstract base class - the platform specific code contains default
|
|
implementations of it that create and manage windows.
|
|
|
|
@see Component::createNewPeer
|
|
*/
|
|
class JUCE_API ComponentPeer : public MessageListener
|
|
{
|
|
public:
|
|
|
|
/** A combination of these flags is passed to the ComponentPeer constructor. */
|
|
enum StyleFlags
|
|
{
|
|
windowAppearsOnTaskbar = (1 << 0), /**< Indicates that the window should have a corresponding
|
|
entry on the taskbar (ignored on MacOSX) */
|
|
windowIsTemporary = (1 << 1), /**< Indicates that the window is a temporary popup, like a menu,
|
|
tooltip, etc. */
|
|
windowIgnoresMouseClicks = (1 << 2), /**< Indicates that the window should let mouse clicks pass
|
|
through it (may not be possible on some platforms). */
|
|
windowHasTitleBar = (1 << 3), /**< Indicates that the window should have a normal OS-specific
|
|
title bar and frame\. if not specified, the window will be
|
|
borderless. */
|
|
windowIsResizable = (1 << 4), /**< Indicates that the window should have a resizable border. */
|
|
windowHasMinimiseButton = (1 << 5), /**< Indicates that if the window has a title bar, it should have a
|
|
minimise button on it. */
|
|
windowHasMaximiseButton = (1 << 6), /**< Indicates that if the window has a title bar, it should have a
|
|
maximise button on it. */
|
|
windowHasCloseButton = (1 << 7), /**< Indicates that if the window has a title bar, it should have a
|
|
close button on it. */
|
|
windowHasDropShadow = (1 << 8), /**< Indicates that the window should have a drop-shadow (this may
|
|
not be possible on all platforms). */
|
|
windowRepaintedExplictly = (1 << 9), /**< Not intended for public use - this tells a window not to
|
|
do its own repainting, but only to repaint when the
|
|
performAnyPendingRepaintsNow() method is called. */
|
|
windowIgnoresKeyPresses = (1 << 10), /**< Tells the window not to catch any keypresses. This can
|
|
be used for things like plugin windows, to stop them interfering
|
|
with the host's shortcut keys */
|
|
windowIsSemiTransparent = (1 << 31) /**< Not intended for public use - makes a window transparent. */
|
|
|
|
};
|
|
|
|
/** Creates a peer.
|
|
|
|
The component is the one that we intend to represent, and the style flags are
|
|
a combination of the values in the StyleFlags enum
|
|
*/
|
|
ComponentPeer (Component* const component,
|
|
const int styleFlags) throw();
|
|
|
|
/** Destructor. */
|
|
virtual ~ComponentPeer();
|
|
|
|
/** Returns the component being represented by this peer. */
|
|
Component* getComponent() const throw() { return component; }
|
|
|
|
/** Returns the set of style flags that were set when the window was created.
|
|
|
|
@see Component::addToDesktop
|
|
*/
|
|
int getStyleFlags() const throw() { return styleFlags; }
|
|
|
|
/** Returns the raw handle to whatever kind of window is being used.
|
|
|
|
On windows, this is probably a HWND, on the mac, it's likely to be a WindowRef,
|
|
but rememeber there's no guarantees what you'll get back.
|
|
*/
|
|
virtual void* getNativeHandle() const = 0;
|
|
|
|
/** Shows or hides the window. */
|
|
virtual void setVisible (bool shouldBeVisible) = 0;
|
|
|
|
/** Changes the title of the window. */
|
|
virtual void setTitle (const String& title) = 0;
|
|
|
|
/** Moves the window without changing its size.
|
|
|
|
If the native window is contained in another window, then the co-ordinates are
|
|
relative to the parent window's origin, not the screen origin.
|
|
|
|
This should result in a callback to handleMovedOrResized().
|
|
*/
|
|
virtual void setPosition (int x, int y) = 0;
|
|
|
|
/** Resizes the window without changing its position.
|
|
|
|
This should result in a callback to handleMovedOrResized().
|
|
*/
|
|
virtual void setSize (int w, int h) = 0;
|
|
|
|
/** Moves and resizes the window.
|
|
|
|
If the native window is contained in another window, then the co-ordinates are
|
|
relative to the parent window's origin, not the screen origin.
|
|
|
|
This should result in a callback to handleMovedOrResized().
|
|
*/
|
|
virtual void setBounds (int x, int y, int w, int h, const bool isNowFullScreen) = 0;
|
|
|
|
/** Returns the current position and size of the window.
|
|
|
|
If the native window is contained in another window, then the co-ordinates are
|
|
relative to the parent window's origin, not the screen origin.
|
|
*/
|
|
virtual void getBounds (int& x, int& y, int& w, int& h) const = 0;
|
|
|
|
/** Returns the x-position of this window, relative to the screen's origin. */
|
|
virtual int getScreenX() const = 0;
|
|
|
|
/** Returns the y-position of this window, relative to the screen's origin. */
|
|
virtual int getScreenY() const = 0;
|
|
|
|
/** Converts a position relative to the top-left of this component to screen co-ordinates. */
|
|
virtual void relativePositionToGlobal (int& x, int& y) = 0;
|
|
|
|
/** Converts a screen co-ordinate to a position relative to the top-left of this component. */
|
|
virtual void globalPositionToRelative (int& x, int& y) = 0;
|
|
|
|
/** Minimises the window. */
|
|
virtual void setMinimised (bool shouldBeMinimised) = 0;
|
|
|
|
/** True if the window is currently minimised. */
|
|
virtual bool isMinimised() const = 0;
|
|
|
|
/** Enable/disable fullscreen mode for the window. */
|
|
virtual void setFullScreen (bool shouldBeFullScreen) = 0;
|
|
|
|
/** True if the window is currently full-screen. */
|
|
virtual bool isFullScreen() const = 0;
|
|
|
|
/** Sets the size to restore to if fullscreen mode is turned off. */
|
|
void setNonFullScreenBounds (const Rectangle& newBounds) throw();
|
|
|
|
/** Returns the size to restore to if fullscreen mode is turned off. */
|
|
const Rectangle& getNonFullScreenBounds() const throw();
|
|
|
|
/** Attempts to change the icon associated with this window.
|
|
*/
|
|
virtual void setIcon (const Image& newIcon) = 0;
|
|
|
|
/** Sets a constrainer to use if the peer can resize itself.
|
|
|
|
The constrainer won't be deleted by this object, so the caller must manage its lifetime.
|
|
*/
|
|
void setConstrainer (ComponentBoundsConstrainer* const newConstrainer) throw();
|
|
|
|
/** Returns the current constrainer, if one has been set. */
|
|
ComponentBoundsConstrainer* getConstrainer() const throw() { return constrainer; }
|
|
|
|
/** Checks if a point is in the window.
|
|
|
|
Coordinates are relative to the top-left of this window. If trueIfInAChildWindow
|
|
is false, then this returns false if the point is actually inside a child of this
|
|
window.
|
|
*/
|
|
virtual bool contains (int x, int y, bool trueIfInAChildWindow) const = 0;
|
|
|
|
/** Returns the size of the window frame that's around this window.
|
|
|
|
Whether or not the window has a normal window frame depends on the flags
|
|
that were set when the window was created by Component::addToDesktop()
|
|
*/
|
|
virtual const BorderSize getFrameSize() const = 0;
|
|
|
|
/** This is called when the window's bounds change.
|
|
|
|
A peer implementation must call this when the window is moved and resized, so that
|
|
this method can pass the message on to the component.
|
|
*/
|
|
void handleMovedOrResized();
|
|
|
|
/** This is called if the screen resolution changes.
|
|
|
|
A peer implementation must call this if the monitor arrangement changes or the available
|
|
screen size changes.
|
|
*/
|
|
void handleScreenSizeChange();
|
|
|
|
/** This is called to repaint the component into the given context. */
|
|
void handlePaint (LowLevelGraphicsContext& contextToPaintTo);
|
|
|
|
/** Sets this window to either be always-on-top or normal.
|
|
|
|
Some kinds of window might not be able to do this, so should return false.
|
|
*/
|
|
virtual bool setAlwaysOnTop (bool alwaysOnTop) = 0;
|
|
|
|
/** Brings the window to the top, optionally also giving it focus. */
|
|
virtual void toFront (bool makeActive) = 0;
|
|
|
|
/** Moves the window to be just behind another one. */
|
|
virtual void toBehind (ComponentPeer* other) = 0;
|
|
|
|
/** Called when the window is brought to the front, either by the OS or by a call
|
|
to toFront().
|
|
*/
|
|
void handleBroughtToFront();
|
|
|
|
/** True if the window has the keyboard focus. */
|
|
virtual bool isFocused() const = 0;
|
|
|
|
/** Tries to give the window keyboard focus. */
|
|
virtual void grabFocus() = 0;
|
|
|
|
/** Tells the window that text input may be required at the given position.
|
|
|
|
This may cause things like a virtual on-screen keyboard to appear, depending
|
|
on the OS.
|
|
*/
|
|
virtual void textInputRequired (int x, int y) = 0;
|
|
|
|
/** Called when the window gains keyboard focus. */
|
|
void handleFocusGain();
|
|
/** Called when the window loses keyboard focus. */
|
|
void handleFocusLoss();
|
|
|
|
Component* getLastFocusedSubcomponent() const throw();
|
|
|
|
/** Called when a key is pressed.
|
|
|
|
For keycode info, see the KeyPress class.
|
|
Returns true if the keystroke was used.
|
|
*/
|
|
bool handleKeyPress (const int keyCode,
|
|
const juce_wchar textCharacter);
|
|
|
|
/** Called whenever a key is pressed or released.
|
|
Returns true if the keystroke was used.
|
|
*/
|
|
bool handleKeyUpOrDown (const bool isKeyDown);
|
|
|
|
/** Called whenever a modifier key is pressed or released. */
|
|
void handleModifierKeysChange();
|
|
|
|
/** Invalidates a region of the window to be repainted asynchronously. */
|
|
virtual void repaint (int x, int y, int w, int h) = 0;
|
|
|
|
/** This can be called (from the message thread) to cause the immediate redrawing
|
|
of any areas of this window that need repainting.
|
|
|
|
You shouldn't ever really need to use this, it's mainly for special purposes
|
|
like supporting audio plugins where the host's event loop is out of our control.
|
|
*/
|
|
virtual void performAnyPendingRepaintsNow() = 0;
|
|
|
|
void handleMouseEnter (int x, int y, const int64 time);
|
|
void handleMouseMove (int x, int y, const int64 time);
|
|
void handleMouseDown (int x, int y, const int64 time);
|
|
void handleMouseDrag (int x, int y, const int64 time);
|
|
void handleMouseUp (const int oldModifiers, int x, int y, const int64 time);
|
|
void handleMouseExit (int x, int y, const int64 time);
|
|
void handleMouseWheel (const int amountX, const int amountY, const int64 time);
|
|
|
|
/** Causes a mouse-move callback to be made asynchronously. */
|
|
void sendFakeMouseMove() throw();
|
|
|
|
void handleUserClosingWindow();
|
|
|
|
void handleFileDragMove (const StringArray& files, int x, int y);
|
|
void handleFileDragExit (const StringArray& files);
|
|
void handleFileDragDrop (const StringArray& files, int x, int y);
|
|
|
|
/** Resets the masking region.
|
|
|
|
The subclass should call this every time it's about to call the handlePaint
|
|
method.
|
|
|
|
@see addMaskedRegion
|
|
*/
|
|
void clearMaskedRegion() throw();
|
|
|
|
/** Adds a rectangle to the set of areas not to paint over.
|
|
|
|
A component can call this on its peer during its paint() method, to signal
|
|
that the painting code should ignore a given region. The reason
|
|
for this is to stop embedded windows (such as OpenGL) getting painted over.
|
|
|
|
The masked region is cleared each time before a paint happens, so a component
|
|
will have to make sure it calls this every time it's painted.
|
|
*/
|
|
void addMaskedRegion (int x, int y, int w, int h) throw();
|
|
|
|
/** Returns the number of currently-active peers.
|
|
|
|
@see getPeer
|
|
*/
|
|
static int getNumPeers() throw();
|
|
|
|
/** Returns one of the currently-active peers.
|
|
|
|
@see getNumPeers
|
|
*/
|
|
static ComponentPeer* getPeer (const int index) throw();
|
|
|
|
/** Checks if this peer object is valid.
|
|
|
|
@see getNumPeers
|
|
*/
|
|
static bool isValidPeer (const ComponentPeer* const peer) throw();
|
|
|
|
static void bringModalComponentToFront();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
Component* const component;
|
|
const int styleFlags;
|
|
RectangleList maskedRegion;
|
|
Rectangle lastNonFullscreenBounds;
|
|
uint32 lastPaintTime;
|
|
ComponentBoundsConstrainer* constrainer;
|
|
|
|
static void updateCurrentModifiers() throw();
|
|
|
|
/** @internal */
|
|
void handleMessage (const Message& message);
|
|
|
|
private:
|
|
|
|
Component* lastFocusedComponent;
|
|
ComponentDeletionWatcher* dragAndDropTargetComponent;
|
|
Component* lastDragAndDropCompUnderMouse;
|
|
bool fakeMouseMessageSent : 1, isWindowMinimised : 1;
|
|
|
|
friend class Component;
|
|
static ComponentPeer* getPeerFor (const Component* const component) throw();
|
|
|
|
void setLastDragDropTarget (Component* comp);
|
|
|
|
ComponentPeer (const ComponentPeer&);
|
|
const ComponentPeer& operator= (const ComponentPeer&);
|
|
};
|
|
|
|
#endif // __JUCE_COMPONENTPEER_JUCEHEADER__
|
|
/********* End of inlined file: juce_ComponentPeer.h *********/
|
|
|
|
class LookAndFeel;
|
|
|
|
/**
|
|
The base class for all JUCE user-interface objects.
|
|
|
|
*/
|
|
class JUCE_API Component : public MouseListener,
|
|
protected MessageListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a component.
|
|
|
|
To get it to actually appear, you'll also need to:
|
|
- Either add it to a parent component or use the addToDesktop() method to
|
|
make it a desktop window
|
|
- Set its size and position to something sensible
|
|
- Use setVisible() to make it visible
|
|
|
|
And for it to serve any useful purpose, you'll need to write a
|
|
subclass of Component or use one of the other types of component from
|
|
the library.
|
|
*/
|
|
Component() throw();
|
|
|
|
/** Destructor.
|
|
|
|
Note that when a component is deleted, any child components it might
|
|
contain are NOT deleted unless you explicitly call deleteAllChildren() first.
|
|
*/
|
|
virtual ~Component();
|
|
|
|
/** Creates a component, setting its name at the same time.
|
|
|
|
@see getName, setName
|
|
*/
|
|
Component (const String& componentName) throw();
|
|
|
|
/** Returns the name of this component.
|
|
|
|
@see setName
|
|
*/
|
|
const String& getName() const throw() { return componentName_; }
|
|
|
|
/** Sets the name of this component.
|
|
|
|
When the name changes, all registered ComponentListeners will receive a
|
|
ComponentListener::componentNameChanged() callback.
|
|
|
|
@see getName
|
|
*/
|
|
virtual void setName (const String& newName);
|
|
|
|
/** Checks whether this Component object has been deleted.
|
|
|
|
This will check whether this object is still a valid component, or whether
|
|
it's been deleted.
|
|
|
|
It's safe to call this on null or dangling pointers, but note that there is a
|
|
small risk if another new (but different) component has been created at the
|
|
same memory address which this one occupied, this methods can return a
|
|
false positive.
|
|
*/
|
|
bool isValidComponent() const throw();
|
|
|
|
/** Makes the component visible or invisible.
|
|
|
|
This method will show or hide the component.
|
|
Note that components default to being non-visible when first created.
|
|
Also note that visible components won't be seen unless all their parent components
|
|
are also visible.
|
|
|
|
This method will call visibilityChanged() and also componentVisibilityChanged()
|
|
for any component listeners that are interested in this component.
|
|
|
|
@param shouldBeVisible whether to show or hide the component
|
|
@see isVisible, isShowing, visibilityChanged, ComponentListener::componentVisibilityChanged
|
|
*/
|
|
virtual void setVisible (bool shouldBeVisible);
|
|
|
|
/** Tests whether the component is visible or not.
|
|
|
|
this doesn't necessarily tell you whether this comp is actually on the screen
|
|
because this depends on whether all the parent components are also visible - use
|
|
isShowing() to find this out.
|
|
|
|
@see isShowing, setVisible
|
|
*/
|
|
bool isVisible() const throw() { return flags.visibleFlag; }
|
|
|
|
/** Called when this component's visiblility changes.
|
|
|
|
@see setVisible, isVisible
|
|
*/
|
|
virtual void visibilityChanged();
|
|
|
|
/** Tests whether this component and all its parents are visible.
|
|
|
|
@returns true only if this component and all its parents are visible.
|
|
@see isVisible
|
|
*/
|
|
bool isShowing() const throw();
|
|
|
|
/** Makes a component invisible using a groovy fade-out and animated zoom effect.
|
|
|
|
To do this, this function will cunningly:
|
|
- take a snapshot of the component as it currently looks
|
|
- call setVisible(false) on the component
|
|
- replace it with a special component that will continue drawing the
|
|
snapshot, animating it and gradually making it more transparent
|
|
- when it's gone, the special component will also be deleted
|
|
|
|
As soon as this method returns, the component can be safely removed and deleted
|
|
leaving the proxy to do the fade-out, so it's even ok to call this in a
|
|
component's destructor.
|
|
|
|
Passing non-zero x and y values will cause the ghostly component image to
|
|
also whizz off by this distance while fading out. If the scale factor is
|
|
not 1.0, it will also zoom from the component's current size to this new size.
|
|
|
|
One thing to be careful about is that the parent component must be able to cope
|
|
with this unknown component type being added to it.
|
|
*/
|
|
void fadeOutComponent (const int lengthOfFadeOutInMilliseconds,
|
|
const int deltaXToMove = 0,
|
|
const int deltaYToMove = 0,
|
|
const float scaleFactorAtEnd = 1.0f);
|
|
|
|
/** Makes this component appear as a window on the desktop.
|
|
|
|
Note that before calling this, you should make sure that the component's opacity is
|
|
set correctly using setOpaque(). If the component is non-opaque, the windowing
|
|
system will try to create a special transparent window for it, which will generally take
|
|
a lot more CPU to operate (and might not even be possible on some platforms).
|
|
|
|
If the component is inside a parent component at the time this method is called, it
|
|
will be first be removed from that parent. Likewise if a component on the desktop
|
|
is subsequently added to another component, it'll be removed from the desktop.
|
|
|
|
@param windowStyleFlags a combination of the flags specified in the
|
|
ComponentPeer::StyleFlags enum, which define the
|
|
window's characteristics.
|
|
@param nativeWindowToAttachTo this allows an OS object to be passed-in as the window
|
|
in which the juce component should place itself. On Windows,
|
|
this would be a HWND, a HIViewRef on the Mac. Not necessarily
|
|
supported on all platforms, and best left as 0 unless you know
|
|
what you're doing
|
|
@see removeFromDesktop, isOnDesktop, userTriedToCloseWindow,
|
|
getPeer, ComponentPeer::setMinimised, ComponentPeer::StyleFlags,
|
|
ComponentPeer::getStyleFlags, ComponentPeer::setFullScreen
|
|
*/
|
|
virtual void addToDesktop (int windowStyleFlags,
|
|
void* nativeWindowToAttachTo = 0);
|
|
|
|
/** If the component is currently showing on the desktop, this will hide it.
|
|
|
|
You can also use setVisible() to hide a desktop window temporarily, but
|
|
removeFromDesktop() will free any system resources that are being used up.
|
|
|
|
@see addToDesktop, isOnDesktop
|
|
*/
|
|
void removeFromDesktop();
|
|
|
|
/** Returns true if this component is currently showing on the desktop.
|
|
|
|
@see addToDesktop, removeFromDesktop
|
|
*/
|
|
bool isOnDesktop() const throw();
|
|
|
|
/** Returns the heavyweight window that contains this component.
|
|
|
|
If this component is itself on the desktop, this will return the window
|
|
object that it is using. Otherwise, it will return the window of
|
|
its top-level parent component.
|
|
|
|
This may return 0 if there isn't a desktop component.
|
|
|
|
@see addToDesktop, isOnDesktop
|
|
*/
|
|
ComponentPeer* getPeer() const throw();
|
|
|
|
/** For components on the desktop, this is called if the system wants to close the window.
|
|
|
|
This is a signal that either the user or the system wants the window to close. The
|
|
default implementation of this method will trigger an assertion to warn you that your
|
|
component should do something about it, but you can override this to ignore the event
|
|
if you want.
|
|
*/
|
|
virtual void userTriedToCloseWindow();
|
|
|
|
/** Called for a desktop component which has just been minimised or un-minimised.
|
|
|
|
This will only be called for components on the desktop.
|
|
|
|
@see getPeer, ComponentPeer::setMinimised, ComponentPeer::isMinimised
|
|
*/
|
|
virtual void minimisationStateChanged (bool isNowMinimised);
|
|
|
|
/** Brings the component to the front of its siblings.
|
|
|
|
If some of the component's siblings have had their 'always-on-top' flag set,
|
|
then they will still be kept in front of this one (unless of course this
|
|
one is also 'always-on-top').
|
|
|
|
@param shouldAlsoGainFocus if true, this will also try to assign keyboard focus
|
|
to the component (see grabKeyboardFocus() for more details)
|
|
@see toBack, toBehind, setAlwaysOnTop
|
|
*/
|
|
void toFront (const bool shouldAlsoGainFocus);
|
|
|
|
/** Changes this component's z-order to be at the back of all its siblings.
|
|
|
|
If the component is set to be 'always-on-top', it will only be moved to the
|
|
back of the other other 'always-on-top' components.
|
|
|
|
@see toFront, toBehind, setAlwaysOnTop
|
|
*/
|
|
void toBack();
|
|
|
|
/** Changes this component's z-order so that it's just behind another component.
|
|
|
|
@see toFront, toBack
|
|
*/
|
|
void toBehind (Component* const other);
|
|
|
|
/** Sets whether the component should always be kept at the front of its siblings.
|
|
|
|
@see isAlwaysOnTop
|
|
*/
|
|
void setAlwaysOnTop (const bool shouldStayOnTop);
|
|
|
|
/** Returns true if this component is set to always stay in front of its siblings.
|
|
|
|
@see setAlwaysOnTop
|
|
*/
|
|
bool isAlwaysOnTop() const throw();
|
|
|
|
/** Returns the x co-ordinate of the component's left edge.
|
|
|
|
This is a distance in pixels from the left edge of the component's parent.
|
|
|
|
@see getScreenX
|
|
*/
|
|
inline int getX() const throw() { return bounds_.getX(); }
|
|
|
|
/** Returns the y co-ordinate of the top of this component.
|
|
|
|
This is a distance in pixels from the top edge of the component's parent.
|
|
|
|
@see getScreenY
|
|
*/
|
|
inline int getY() const throw() { return bounds_.getY(); }
|
|
|
|
/** Returns the component's width in pixels. */
|
|
inline int getWidth() const throw() { return bounds_.getWidth(); }
|
|
|
|
/** Returns the component's height in pixels. */
|
|
inline int getHeight() const throw() { return bounds_.getHeight(); }
|
|
|
|
/** Returns the x co-ordinate of the component's right-hand edge.
|
|
|
|
This is a distance in pixels from the left edge of the component's parent.
|
|
*/
|
|
int getRight() const throw() { return bounds_.getRight(); }
|
|
|
|
/** Returns the y co-ordinate of the bottom edge of this component.
|
|
|
|
This is a distance in pixels from the top edge of the component's parent.
|
|
*/
|
|
int getBottom() const throw() { return bounds_.getBottom(); }
|
|
|
|
/** Returns this component's bounding box.
|
|
|
|
The rectangle returned is relative to the top-left of the component's parent.
|
|
*/
|
|
const Rectangle& getBounds() const throw() { return bounds_; }
|
|
|
|
/** Returns the region of this component that's not obscured by other, opaque components.
|
|
|
|
The RectangleList that is returned represents the area of this component
|
|
which isn't covered by opaque child components.
|
|
|
|
If includeSiblings is true, it will also take into account any siblings
|
|
that may be overlapping the component.
|
|
*/
|
|
void getVisibleArea (RectangleList& result,
|
|
const bool includeSiblings) const;
|
|
|
|
/** Returns this component's x co-ordinate relative the the screen's top-left origin.
|
|
|
|
@see getX, relativePositionToGlobal
|
|
*/
|
|
int getScreenX() const throw();
|
|
|
|
/** Returns this component's y co-ordinate relative the the screen's top-left origin.
|
|
|
|
@see getY, relativePositionToGlobal
|
|
*/
|
|
int getScreenY() const throw();
|
|
|
|
/** Converts a position relative to this component's top-left into a screen co-ordinate.
|
|
|
|
@see globalPositionToRelative, relativePositionToOtherComponent
|
|
*/
|
|
void relativePositionToGlobal (int& x, int& y) const throw();
|
|
|
|
/** Converts a screen co-ordinate into a position relative to this component's top-left.
|
|
|
|
@see relativePositionToGlobal, relativePositionToOtherComponent
|
|
*/
|
|
void globalPositionToRelative (int& x, int& y) const throw();
|
|
|
|
/** Converts a position relative to this component's top-left into a position
|
|
relative to another component's top-left.
|
|
|
|
@see relativePositionToGlobal, globalPositionToRelative
|
|
*/
|
|
void relativePositionToOtherComponent (const Component* const targetComponent,
|
|
int& x, int& y) const throw();
|
|
|
|
/** Moves the component to a new position.
|
|
|
|
Changes the component's top-left position (without changing its size).
|
|
The position is relative to the top-left of the component's parent.
|
|
|
|
If the component actually moves, this method will make a synchronous call to moved().
|
|
|
|
@see setBounds, ComponentListener::componentMovedOrResized
|
|
*/
|
|
void setTopLeftPosition (const int x, const int y);
|
|
|
|
/** Moves the component to a new position.
|
|
|
|
Changes the position of the component's top-right corner (keeping it the same size).
|
|
The position is relative to the top-left of the component's parent.
|
|
|
|
If the component actually moves, this method will make a synchronous call to moved().
|
|
*/
|
|
void setTopRightPosition (const int x, const int y);
|
|
|
|
/** Changes the size of the component.
|
|
|
|
A synchronous call to resized() will be occur if the size actually changes.
|
|
*/
|
|
void setSize (const int newWidth, const int newHeight);
|
|
|
|
/** Changes the component's position and size.
|
|
|
|
The co-ordinates are relative to the top-left of the component's parent, or relative
|
|
to the origin of the screen is the component is on the desktop.
|
|
|
|
If this method changes the component's top-left position, it will make a synchronous
|
|
call to moved(). If it changes the size, it will also make a call to resized().
|
|
|
|
@see setTopLeftPosition, setSize, ComponentListener::componentMovedOrResized
|
|
*/
|
|
void setBounds (int x, int y, int width, int height);
|
|
|
|
/** Changes the component's position and size.
|
|
|
|
@see setBounds
|
|
*/
|
|
void setBounds (const Rectangle& newBounds);
|
|
|
|
/** Changes the component's position and size in terms of fractions of its parent's size.
|
|
|
|
The values are factors of the parent's size, so for example
|
|
setBoundsRelative (0.2f, 0.2f, 0.5f, 0.5f) would give it half the
|
|
width and height of the parent, with its top-left position 20% of
|
|
the way across and down the parent.
|
|
*/
|
|
void setBoundsRelative (const float proportionalX, const float proportionalY,
|
|
const float proportionalWidth, const float proportionalHeight);
|
|
|
|
/** Changes the component's position and size based on the amount of space to leave around it.
|
|
|
|
This will position the component within its parent, leaving the specified number of
|
|
pixels around each edge.
|
|
*/
|
|
void setBoundsInset (const BorderSize& borders);
|
|
|
|
/** Positions the component within a given rectangle, keeping its proportions
|
|
unchanged.
|
|
|
|
If onlyReduceInSize is false, the component will be resized to fill as much of the
|
|
rectangle as possible without changing its aspect ratio (the component's
|
|
current size is used to determine its aspect ratio, so a zero-size component
|
|
won't work here). If onlyReduceInSize is true, it will only be resized if it's
|
|
too big to fit inside the rectangle.
|
|
|
|
It will then be positioned within the rectangle according to the justification flags
|
|
specified.
|
|
*/
|
|
void setBoundsToFit (int x, int y, int width, int height,
|
|
const Justification& justification,
|
|
const bool onlyReduceInSize);
|
|
|
|
/** Changes the position of the component's centre.
|
|
|
|
Leaves the component's size unchanged, but sets the position of its centre
|
|
relative to its parent's top-left.
|
|
*/
|
|
void setCentrePosition (const int x, const int y);
|
|
|
|
/** Changes the position of the component's centre.
|
|
|
|
Leaves the position unchanged, but positions its centre relative to its
|
|
parent's size. E.g. setCentreRelative (0.5f, 0.5f) would place it centrally in
|
|
its parent.
|
|
*/
|
|
void setCentreRelative (const float x, const float y);
|
|
|
|
/** Changes the component's size and centres it within its parent.
|
|
|
|
After changing the size, the component will be moved so that it's
|
|
centred within its parent.
|
|
*/
|
|
void centreWithSize (const int width, const int height);
|
|
|
|
/** Returns a proportion of the component's width.
|
|
|
|
This is a handy equivalent of (getWidth() * proportion).
|
|
*/
|
|
int proportionOfWidth (const float proportion) const throw();
|
|
|
|
/** Returns a proportion of the component's height.
|
|
|
|
This is a handy equivalent of (getHeight() * proportion).
|
|
*/
|
|
int proportionOfHeight (const float proportion) const throw();
|
|
|
|
/** Returns the width of the component's parent.
|
|
|
|
If the component has no parent (i.e. if it's on the desktop), this will return
|
|
the width of the screen.
|
|
*/
|
|
int getParentWidth() const throw();
|
|
|
|
/** Returns the height of the component's parent.
|
|
|
|
If the component has no parent (i.e. if it's on the desktop), this will return
|
|
the height of the screen.
|
|
*/
|
|
int getParentHeight() const throw();
|
|
|
|
/** Returns the screen co-ordinates of the monitor that contains this component.
|
|
|
|
If there's only one monitor, this will return its size - if there are multiple
|
|
monitors, it will return the area of the monitor that contains the component's
|
|
centre.
|
|
*/
|
|
const Rectangle getParentMonitorArea() const throw();
|
|
|
|
/** Returns the number of child components that this component contains.
|
|
|
|
@see getChildComponent, getIndexOfChildComponent
|
|
*/
|
|
int getNumChildComponents() const throw();
|
|
|
|
/** Returns one of this component's child components, by it index.
|
|
|
|
The component with index 0 is at the back of the z-order, the one at the
|
|
front will have index (getNumChildComponents() - 1).
|
|
|
|
If the index is out-of-range, this will return a null pointer.
|
|
|
|
@see getNumChildComponents, getIndexOfChildComponent
|
|
*/
|
|
Component* getChildComponent (const int index) const throw();
|
|
|
|
/** Returns the index of this component in the list of child components.
|
|
|
|
A value of 0 means it is first in the list (i.e. behind all other components). Higher
|
|
values are further towards the front.
|
|
|
|
Returns -1 if the component passed-in is not a child of this component.
|
|
|
|
@see getNumChildComponents, getChildComponent, addChildComponent, toFront, toBack, toBehind
|
|
*/
|
|
int getIndexOfChildComponent (const Component* const child) const throw();
|
|
|
|
/** Adds a child component to this one.
|
|
|
|
@param child the new component to add. If the component passed-in is already
|
|
the child of another component, it'll first be removed from that.
|
|
|
|
@param zOrder The index in the child-list at which this component should be inserted.
|
|
A value of -1 will insert it in front of the others, 0 is the back.
|
|
@see removeChildComponent, addAndMakeVisible, getChild,
|
|
ComponentListener::componentChildrenChanged
|
|
*/
|
|
void addChildComponent (Component* const child,
|
|
int zOrder = -1);
|
|
|
|
/** Adds a child component to this one, and also makes the child visible if it isn't.
|
|
|
|
Quite a useful function, this is just the same as calling addChildComponent()
|
|
followed by setVisible (true) on the child.
|
|
*/
|
|
void addAndMakeVisible (Component* const child,
|
|
int zOrder = -1);
|
|
|
|
/** Removes one of this component's child-components.
|
|
|
|
If the child passed-in isn't actually a child of this component (either because
|
|
it's invalid or is the child of a different parent), then nothing is done.
|
|
|
|
Note that removing a child will not delete it!
|
|
|
|
@see addChildComponent, ComponentListener::componentChildrenChanged
|
|
*/
|
|
void removeChildComponent (Component* const childToRemove);
|
|
|
|
/** Removes one of this component's child-components by index.
|
|
|
|
This will return a pointer to the component that was removed, or null if
|
|
the index was out-of-range.
|
|
|
|
Note that removing a child will not delete it!
|
|
|
|
@see addChildComponent, ComponentListener::componentChildrenChanged
|
|
*/
|
|
Component* removeChildComponent (const int childIndexToRemove);
|
|
|
|
/** Removes all this component's children.
|
|
|
|
Note that this won't delete them! To do that, use deleteAllChildren() instead.
|
|
*/
|
|
void removeAllChildren();
|
|
|
|
/** Removes all this component's children, and deletes them.
|
|
|
|
@see removeAllChildren
|
|
*/
|
|
void deleteAllChildren();
|
|
|
|
/** Returns the component which this component is inside.
|
|
|
|
If this is the highest-level component or hasn't yet been added to
|
|
a parent, this will return null.
|
|
*/
|
|
Component* getParentComponent() const throw() { return parentComponent_; }
|
|
|
|
/** Searches the parent components for a component of a specified class.
|
|
|
|
For example findParentComponentOfClass \<MyComp\>() would return the first parent
|
|
component that can be dynamically cast to a MyComp, or will return 0 if none
|
|
of the parents are suitable.
|
|
|
|
N.B. The dummy parameter is needed to work around a VC6 compiler bug.
|
|
*/
|
|
template <class TargetClass>
|
|
TargetClass* findParentComponentOfClass (TargetClass* const dummyParameter = 0) const
|
|
{
|
|
(void) dummyParameter;
|
|
Component* p = parentComponent_;
|
|
while (p != 0)
|
|
{
|
|
TargetClass* target = dynamic_cast <TargetClass*> (p);
|
|
if (target != 0)
|
|
return target;
|
|
|
|
p = p->parentComponent_;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/** Returns the highest-level component which contains this one or its parents.
|
|
|
|
This will search upwards in the parent-hierarchy from this component, until it
|
|
finds the highest one that doesn't have a parent (i.e. is on the desktop or
|
|
not yet added to a parent), and will return that.
|
|
*/
|
|
Component* getTopLevelComponent() const throw();
|
|
|
|
/** Checks whether a component is anywhere inside this component or its children.
|
|
|
|
This will recursively check through this components children to see if the
|
|
given component is anywhere inside.
|
|
*/
|
|
bool isParentOf (const Component* possibleChild) const throw();
|
|
|
|
/** Called to indicate that the component's parents have changed.
|
|
|
|
When a component is added or removed from its parent, this method will
|
|
be called on all of its children (recursively - so all children of its
|
|
children will also be called as well).
|
|
|
|
Subclasses can override this if they need to react to this in some way.
|
|
|
|
@see getParentComponent, isShowing, ComponentListener::componentParentHierarchyChanged
|
|
*/
|
|
virtual void parentHierarchyChanged();
|
|
|
|
/** Subclasses can use this callback to be told when children are added or removed.
|
|
|
|
@see parentHierarchyChanged
|
|
*/
|
|
virtual void childrenChanged();
|
|
|
|
/** Tests whether a given point inside the component.
|
|
|
|
Overriding this method allows you to create components which only intercept
|
|
mouse-clicks within a user-defined area.
|
|
|
|
This is called to find out whether a particular x, y co-ordinate is
|
|
considered to be inside the component or not, and is used by methods such
|
|
as contains() and getComponentAt() to work out which component
|
|
the mouse is clicked on.
|
|
|
|
Components with custom shapes will probably want to override it to perform
|
|
some more complex hit-testing.
|
|
|
|
The default implementation of this method returns either true or false,
|
|
depending on the value that was set by calling setInterceptsMouseClicks() (true
|
|
is the default return value).
|
|
|
|
Note that the hit-test region is not related to the opacity with which
|
|
areas of a component are painted.
|
|
|
|
Applications should never call hitTest() directly - instead use the
|
|
contains() method, because this will also test for occlusion by the
|
|
component's parent.
|
|
|
|
Note that for components on the desktop, this method will be ignored, because it's
|
|
not always possible to implement this behaviour on all platforms.
|
|
|
|
@param x the x co-ordinate to test, relative to the left hand edge of this
|
|
component. This value is guaranteed to be greater than or equal to
|
|
zero, and less than the component's width
|
|
@param y the y co-ordinate to test, relative to the top edge of this
|
|
component. This value is guaranteed to be greater than or equal to
|
|
zero, and less than the component's height
|
|
@returns true if the click is considered to be inside the component
|
|
@see setInterceptsMouseClicks, contains
|
|
*/
|
|
virtual bool hitTest (int x, int y);
|
|
|
|
/** Changes the default return value for the hitTest() method.
|
|
|
|
Setting this to false is an easy way to make a component pass its mouse-clicks
|
|
through to the components behind it.
|
|
|
|
When a component is created, the default setting for this is true.
|
|
|
|
@param allowClicksOnThisComponent if true, hitTest() will always return true; if false, it will
|
|
return false (or true for child components if allowClicksOnChildComponents
|
|
is true)
|
|
@param allowClicksOnChildComponents if this is true and allowClicksOnThisComponent is false, then child
|
|
components can be clicked on as normal but clicks on this component pass
|
|
straight through; if this is false and allowClicksOnThisComponent
|
|
is false, then neither this component nor any child components can
|
|
be clicked on
|
|
@see hitTest, getInterceptsMouseClicks
|
|
*/
|
|
void setInterceptsMouseClicks (const bool allowClicksOnThisComponent,
|
|
const bool allowClicksOnChildComponents) throw();
|
|
|
|
/** Retrieves the current state of the mouse-click interception flags.
|
|
|
|
On return, the two parameters are set to the state used in the last call to
|
|
setInterceptsMouseClicks().
|
|
|
|
@see setInterceptsMouseClicks
|
|
*/
|
|
void getInterceptsMouseClicks (bool& allowsClicksOnThisComponent,
|
|
bool& allowsClicksOnChildComponents) const throw();
|
|
|
|
/** Returns true if a given point lies within this component or one of its children.
|
|
|
|
Never override this method! Use hitTest to create custom hit regions.
|
|
|
|
@param x the x co-ordinate to test, relative to this component's left hand edge.
|
|
@param y the y co-ordinate to test, relative to this component's top edge.
|
|
@returns true if the point is within the component's hit-test area, but only if
|
|
that part of the component isn't clipped by its parent component. Note
|
|
that this won't take into account any overlapping sibling components
|
|
which might be in the way - for that, see reallyContains()
|
|
@see hitTest, reallyContains, getComponentAt
|
|
*/
|
|
virtual bool contains (int x, int y);
|
|
|
|
/** Returns true if a given point lies in this component, taking any overlapping
|
|
siblings into account.
|
|
|
|
@param x the x co-ordinate to test, relative to this component's left hand edge.
|
|
@param y the y co-ordinate to test, relative to this component's top edge.
|
|
@param returnTrueIfWithinAChild if the point actually lies within a child of this
|
|
component, this determines the value that will
|
|
be returned.
|
|
|
|
@see contains, getComponentAt
|
|
*/
|
|
bool reallyContains (int x, int y,
|
|
const bool returnTrueIfWithinAChild);
|
|
|
|
/** Returns the component at a certain point within this one.
|
|
|
|
@param x the x co-ordinate to test, relative to this component's left hand edge.
|
|
@param y the y co-ordinate to test, relative to this component's top edge.
|
|
@returns the component that is at this position - which may be 0, this component,
|
|
or one of its children. Note that overlapping siblings that might actually
|
|
be in the way are not taken into account by this method - to account for these,
|
|
instead call getComponentAt on the top-level parent of this component.
|
|
@see hitTest, contains, reallyContains
|
|
*/
|
|
Component* getComponentAt (const int x, const int y);
|
|
|
|
/** Marks the whole component as needing to be redrawn.
|
|
|
|
Calling this will not do any repainting immediately, but will mark the component
|
|
as 'dirty'. At some point in the near future the operating system will send a paint
|
|
message, which will redraw all the dirty regions of all components.
|
|
There's no guarantee about how soon after calling repaint() the redraw will actually
|
|
happen, and other queued events may be delivered before a redraw is done.
|
|
|
|
If the setBufferedToImage() method has been used to cause this component
|
|
to use a buffer, the repaint() call will invalidate the component's buffer.
|
|
|
|
To redraw just a subsection of the component rather than the whole thing,
|
|
use the repaint (int, int, int, int) method.
|
|
|
|
@see paint
|
|
*/
|
|
void repaint() throw();
|
|
|
|
/** Marks a subsection of this component as needing to be redrawn.
|
|
|
|
Calling this will not do any repainting immediately, but will mark the given region
|
|
of the component as 'dirty'. At some point in the near future the operating system
|
|
will send a paint message, which will redraw all the dirty regions of all components.
|
|
There's no guarantee about how soon after calling repaint() the redraw will actually
|
|
happen, and other queued events may be delivered before a redraw is done.
|
|
|
|
The region that is passed in will be clipped to keep it within the bounds of this
|
|
component.
|
|
|
|
@see repaint()
|
|
*/
|
|
void repaint (const int x, const int y,
|
|
const int width, const int height) throw();
|
|
|
|
/** Makes the component use an internal buffer to optimise its redrawing.
|
|
|
|
Setting this flag to true will cause the component to allocate an
|
|
internal buffer into which it paints itself, so that when asked to
|
|
redraw itself, it can use this buffer rather than actually calling the
|
|
paint() method.
|
|
|
|
The buffer is kept until the repaint() method is called directly on
|
|
this component (or until it is resized), when the image is invalidated
|
|
and then redrawn the next time the component is painted.
|
|
|
|
Note that only the drawing that happens within the component's paint()
|
|
method is drawn into the buffer, it's child components are not buffered, and
|
|
nor is the paintOverChildren() method.
|
|
|
|
@see repaint, paint, createComponentSnapshot
|
|
*/
|
|
void setBufferedToImage (const bool shouldBeBuffered) throw();
|
|
|
|
/** Generates a snapshot of part of this component.
|
|
|
|
This will return a new Image, the size of the rectangle specified,
|
|
containing a snapshot of the specified area of the component and all
|
|
its children.
|
|
|
|
The image may or may not have an alpha-channel, depending on whether the
|
|
image is opaque or not.
|
|
|
|
If the clipImageToComponentBounds parameter is true and the area is greater than
|
|
the size of the component, it'll be clipped. If clipImageToComponentBounds is false
|
|
then parts of the component beyond its bounds can be drawn.
|
|
|
|
The caller is responsible for deleting the image that is returned.
|
|
|
|
@see paintEntireComponent
|
|
*/
|
|
Image* createComponentSnapshot (const Rectangle& areaToGrab,
|
|
const bool clipImageToComponentBounds = true);
|
|
|
|
/** Draws this component and all its subcomponents onto the specified graphics
|
|
context.
|
|
|
|
You should very rarely have to use this method, it's simply there in case you need
|
|
to draw a component with a custom graphics context for some reason, e.g. for
|
|
creating a snapshot of the component.
|
|
|
|
It calls paint(), paintOverChildren() and recursively calls paintEntireComponent()
|
|
on its children in order to render the entire tree.
|
|
|
|
The graphics context may be left in an undefined state after this method returns,
|
|
so you may need to reset it if you're going to use it again.
|
|
*/
|
|
void paintEntireComponent (Graphics& context);
|
|
|
|
/** Adds an effect filter to alter the component's appearance.
|
|
|
|
When a component has an effect filter set, then this is applied to the
|
|
results of its paint() method. There are a few preset effects, such as
|
|
a drop-shadow or glow, but they can be user-defined as well.
|
|
|
|
The effect that is passed in will not be deleted by the component - the
|
|
caller must take care of deleting it.
|
|
|
|
To remove an effect from a component, pass a null pointer in as the parameter.
|
|
|
|
@see ImageEffectFilter, DropShadowEffect, GlowEffect
|
|
*/
|
|
void setComponentEffect (ImageEffectFilter* const newEffect);
|
|
|
|
/** Returns the current component effect.
|
|
|
|
@see setComponentEffect
|
|
*/
|
|
ImageEffectFilter* getComponentEffect() const throw() { return effect_; }
|
|
|
|
/** Finds the appropriate look-and-feel to use for this component.
|
|
|
|
If the component hasn't had a look-and-feel explicitly set, this will
|
|
return the parent's look-and-feel, or just the default one if there's no
|
|
parent.
|
|
|
|
@see setLookAndFeel, lookAndFeelChanged
|
|
*/
|
|
LookAndFeel& getLookAndFeel() const throw();
|
|
|
|
/** Sets the look and feel to use for this component.
|
|
|
|
This will also change the look and feel for any child components that haven't
|
|
had their look set explicitly.
|
|
|
|
The object passed in will not be deleted by the component, so it's the caller's
|
|
responsibility to manage it. It may be used at any time until this component
|
|
has been deleted.
|
|
|
|
Calling this method will also invoke the sendLookAndFeelChange() method.
|
|
|
|
@see getLookAndFeel, lookAndFeelChanged
|
|
*/
|
|
void setLookAndFeel (LookAndFeel* const newLookAndFeel);
|
|
|
|
/** Called to let the component react to a change in the look-and-feel setting.
|
|
|
|
When the look-and-feel is changed for a component, this will be called in
|
|
all its child components, recursively.
|
|
|
|
It can also be triggered manually by the sendLookAndFeelChange() method, in case
|
|
an application uses a LookAndFeel class that might have changed internally.
|
|
|
|
@see sendLookAndFeelChange, getLookAndFeel
|
|
*/
|
|
virtual void lookAndFeelChanged();
|
|
|
|
/** Calls the lookAndFeelChanged() method in this component and all its children.
|
|
|
|
This will recurse through the children and their children, calling lookAndFeelChanged()
|
|
on them all.
|
|
|
|
@see lookAndFeelChanged
|
|
*/
|
|
void sendLookAndFeelChange();
|
|
|
|
/** Indicates whether any parts of the component might be transparent.
|
|
|
|
Components that always paint all of their contents with solid colour and
|
|
thus completely cover any components behind them should use this method
|
|
to tell the repaint system that they are opaque.
|
|
|
|
This information is used to optimise drawing, because it means that
|
|
objects underneath opaque windows don't need to be painted.
|
|
|
|
By default, components are considered transparent, unless this is used to
|
|
make it otherwise.
|
|
|
|
@see isOpaque, getVisibleArea
|
|
*/
|
|
void setOpaque (const bool shouldBeOpaque) throw();
|
|
|
|
/** Returns true if no parts of this component are transparent.
|
|
|
|
@returns the value that was set by setOpaque, (the default being false)
|
|
@see setOpaque
|
|
*/
|
|
bool isOpaque() const throw();
|
|
|
|
/** Indicates whether the component should be brought to the front when clicked.
|
|
|
|
Setting this flag to true will cause the component to be brought to the front
|
|
when the mouse is clicked somewhere inside it or its child components.
|
|
|
|
Note that a top-level desktop window might still be brought to the front by the
|
|
operating system when it's clicked, depending on how the OS works.
|
|
|
|
By default this is set to false.
|
|
|
|
@see setMouseClickGrabsKeyboardFocus
|
|
*/
|
|
void setBroughtToFrontOnMouseClick (const bool shouldBeBroughtToFront) throw();
|
|
|
|
/** Indicates whether the component should be brought to the front when clicked-on.
|
|
|
|
@see setBroughtToFrontOnMouseClick
|
|
*/
|
|
bool isBroughtToFrontOnMouseClick() const throw();
|
|
|
|
// Keyboard focus methods
|
|
|
|
/** Sets a flag to indicate whether this component needs keyboard focus or not.
|
|
|
|
By default components aren't actually interested in gaining the
|
|
focus, but this method can be used to turn this on.
|
|
|
|
See the grabKeyboardFocus() method for details about the way a component
|
|
is chosen to receive the focus.
|
|
|
|
@see grabKeyboardFocus, getWantsKeyboardFocus
|
|
*/
|
|
void setWantsKeyboardFocus (const bool wantsFocus) throw();
|
|
|
|
/** Returns true if the component is interested in getting keyboard focus.
|
|
|
|
This returns the flag set by setWantsKeyboardFocus(). The default
|
|
setting is false.
|
|
|
|
@see setWantsKeyboardFocus
|
|
*/
|
|
bool getWantsKeyboardFocus() const throw();
|
|
|
|
/** Chooses whether a click on this component automatically grabs the focus.
|
|
|
|
By default this is set to true, but you might want a component which can
|
|
be focused, but where you don't want the user to be able to affect it directly
|
|
by clicking.
|
|
*/
|
|
void setMouseClickGrabsKeyboardFocus (const bool shouldGrabFocus);
|
|
|
|
/** Returns the last value set with setMouseClickGrabsKeyboardFocus().
|
|
|
|
See setMouseClickGrabsKeyboardFocus() for more info.
|
|
*/
|
|
bool getMouseClickGrabsKeyboardFocus() const throw();
|
|
|
|
/** Tries to give keyboard focus to this component.
|
|
|
|
When the user clicks on a component or its grabKeyboardFocus()
|
|
method is called, the following procedure is used to work out which
|
|
component should get it:
|
|
|
|
- if the component that was clicked on actually wants focus (as indicated
|
|
by calling getWantsKeyboardFocus), it gets it.
|
|
- if the component itself doesn't want focus, it will try to pass it
|
|
on to whichever of its children is the default component, as determined by
|
|
KeyboardFocusTraverser::getDefaultComponent()
|
|
- if none of its children want focus at all, it will pass it up to its
|
|
parent instead, unless it's a top-level component without a parent,
|
|
in which case it just takes the focus itself.
|
|
|
|
@see setWantsKeyboardFocus, getWantsKeyboardFocus, hasKeyboardFocus,
|
|
getCurrentlyFocusedComponent, focusGained, focusLost,
|
|
keyPressed, keyStateChanged
|
|
*/
|
|
void grabKeyboardFocus();
|
|
|
|
/** Returns true if this component currently has the keyboard focus.
|
|
|
|
@param trueIfChildIsFocused if this is true, then the method returns true if
|
|
either this component or any of its children (recursively)
|
|
have the focus. If false, the method only returns true if
|
|
this component has the focus.
|
|
|
|
@see grabKeyboardFocus, setWantsKeyboardFocus, getCurrentlyFocusedComponent,
|
|
focusGained, focusLost
|
|
*/
|
|
bool hasKeyboardFocus (const bool trueIfChildIsFocused) const throw();
|
|
|
|
/** Returns the component that currently has the keyboard focus.
|
|
|
|
@returns the focused component, or null if nothing is focused.
|
|
*/
|
|
static Component* JUCE_CALLTYPE getCurrentlyFocusedComponent() throw();
|
|
|
|
/** Tries to move the keyboard focus to one of this component's siblings.
|
|
|
|
This will try to move focus to either the next or previous component. (This
|
|
is the method that is used when shifting focus by pressing the tab key).
|
|
|
|
Components for which getWantsKeyboardFocus() returns false are not looked at.
|
|
|
|
@param moveToNext if true, the focus will move forwards; if false, it will
|
|
move backwards
|
|
@see grabKeyboardFocus, setFocusContainer, setWantsKeyboardFocus
|
|
*/
|
|
void moveKeyboardFocusToSibling (const bool moveToNext);
|
|
|
|
/** Creates a KeyboardFocusTraverser object to use to determine the logic by
|
|
which focus should be passed from this component.
|
|
|
|
The default implementation of this method will return a default
|
|
KeyboardFocusTraverser if this component is a focus container (as determined
|
|
by the setFocusContainer() method). If the component isn't a focus
|
|
container, then it will recursively ask its parents for a KeyboardFocusTraverser.
|
|
|
|
If you overrride this to return a custom KeyboardFocusTraverser, then
|
|
this component and all its sub-components will use the new object to
|
|
make their focusing decisions.
|
|
|
|
The method should return a new object, which the caller is required to
|
|
delete when no longer needed.
|
|
*/
|
|
virtual KeyboardFocusTraverser* createFocusTraverser();
|
|
|
|
/** Returns the focus order of this component, if one has been specified.
|
|
|
|
By default components don't have a focus order - in that case, this
|
|
will return 0. Lower numbers indicate that the component will be
|
|
earlier in the focus traversal order.
|
|
|
|
To change the order, call setExplicitFocusOrder().
|
|
|
|
The focus order may be used by the KeyboardFocusTraverser class as part of
|
|
its algorithm for deciding the order in which components should be traversed.
|
|
See the KeyboardFocusTraverser class for more details on this.
|
|
|
|
@see moveKeyboardFocusToSibling, createFocusTraverser, KeyboardFocusTraverser
|
|
*/
|
|
int getExplicitFocusOrder() const throw();
|
|
|
|
/** Sets the index used in determining the order in which focusable components
|
|
should be traversed.
|
|
|
|
A value of 0 or less is taken to mean that no explicit order is wanted, and
|
|
that traversal should use other factors, like the component's position.
|
|
|
|
@see getExplicitFocusOrder, moveKeyboardFocusToSibling
|
|
*/
|
|
void setExplicitFocusOrder (const int newFocusOrderIndex) throw();
|
|
|
|
/** Indicates whether this component is a parent for components that can have
|
|
their focus traversed.
|
|
|
|
This flag is used by the default implementation of the createFocusTraverser()
|
|
method, which uses the flag to find the first parent component (of the currently
|
|
focused one) which wants to be a focus container.
|
|
|
|
So using this method to set the flag to 'true' causes this component to
|
|
act as the top level within which focus is passed around.
|
|
|
|
@see isFocusContainer, createFocusTraverser, moveKeyboardFocusToSibling
|
|
*/
|
|
void setFocusContainer (const bool isFocusContainer) throw();
|
|
|
|
/** Returns true if this component has been marked as a focus container.
|
|
|
|
See setFocusContainer() for more details.
|
|
|
|
@see setFocusContainer, moveKeyboardFocusToSibling, createFocusTraverser
|
|
*/
|
|
bool isFocusContainer() const throw();
|
|
|
|
/** Returns true if the component (and all its parents) are enabled.
|
|
|
|
Components are enabled by default, and can be disabled with setEnabled(). Exactly
|
|
what difference this makes to the component depends on the type. E.g. buttons
|
|
and sliders will choose to draw themselves differently, etc.
|
|
|
|
Note that if one of this component's parents is disabled, this will always
|
|
return false, even if this component itself is enabled.
|
|
|
|
@see setEnabled, enablementChanged
|
|
*/
|
|
bool isEnabled() const throw();
|
|
|
|
/** Enables or disables this component.
|
|
|
|
Disabling a component will also cause all of its child components to become
|
|
disabled.
|
|
|
|
Similarly, enabling a component which is inside a disabled parent
|
|
component won't make any difference until the parent is re-enabled.
|
|
|
|
@see isEnabled, enablementChanged
|
|
*/
|
|
void setEnabled (const bool shouldBeEnabled);
|
|
|
|
/** Callback to indicate that this component has been enabled or disabled.
|
|
|
|
This can be triggered by one of the component's parent components
|
|
being enabled or disabled, as well as changes to the component itself.
|
|
|
|
The default implementation of this method does nothing; your class may
|
|
wish to repaint itself or something when this happens.
|
|
|
|
@see setEnabled, isEnabled
|
|
*/
|
|
virtual void enablementChanged();
|
|
|
|
/** Changes the mouse cursor shape to use when the mouse is over this component.
|
|
|
|
Note that the cursor set by this method can be overridden by the getMouseCursor
|
|
method.
|
|
|
|
@see MouseCursor
|
|
*/
|
|
void setMouseCursor (const MouseCursor& cursorType) throw();
|
|
|
|
/** Returns the mouse cursor shape to use when the mouse is over this component.
|
|
|
|
The default implementation will return the cursor that was set by setCursor()
|
|
but can be overridden for more specialised purposes, e.g. returning different
|
|
cursors depending on the mouse position.
|
|
|
|
@see MouseCursor
|
|
*/
|
|
virtual const MouseCursor getMouseCursor();
|
|
|
|
/** Forces the current mouse cursor to be updated.
|
|
|
|
If you're overriding the getMouseCursor() method to control which cursor is
|
|
displayed, then this will only be checked each time the user moves the mouse. So
|
|
if you want to force the system to check that the cursor being displayed is
|
|
up-to-date (even if the mouse is just sitting there), call this method.
|
|
|
|
This isn't needed if you're only using setMouseCursor().
|
|
*/
|
|
void updateMouseCursor() const throw();
|
|
|
|
/** Components can override this method to draw their content.
|
|
|
|
The paint() method gets called when a region of a component needs redrawing,
|
|
either because the component's repaint() method has been called, or because
|
|
something has happened on the screen that means a section of a window needs
|
|
to be redrawn.
|
|
|
|
Any child components will draw themselves over whatever this method draws. If
|
|
you need to paint over the top of your child components, you can also implement
|
|
the paintOverChildren() method to do this.
|
|
|
|
If you want to cause a component to redraw itself, this is done asynchronously -
|
|
calling the repaint() method marks a region of the component as "dirty", and the
|
|
paint() method will automatically be called sometime later, by the message thread,
|
|
to paint any bits that need refreshing. In Juce (and almost all modern UI frameworks),
|
|
you never redraw something synchronously.
|
|
|
|
You should never need to call this method directly - to take a snapshot of the
|
|
component you could use createComponentSnapshot() or paintEntireComponent().
|
|
|
|
@param g the graphics context that must be used to do the drawing operations.
|
|
@see repaint, paintOverChildren, Graphics
|
|
*/
|
|
virtual void paint (Graphics& g);
|
|
|
|
/** Components can override this method to draw over the top of their children.
|
|
|
|
For most drawing operations, it's better to use the normal paint() method,
|
|
but if you need to overlay something on top of the children, this can be
|
|
used.
|
|
|
|
@see paint, Graphics
|
|
*/
|
|
virtual void paintOverChildren (Graphics& g);
|
|
|
|
/** Called when the mouse moves inside this component.
|
|
|
|
If the mouse button isn't pressed and the mouse moves over a component,
|
|
this will be called to let the component react to this.
|
|
|
|
A component will always get a mouseEnter callback before a mouseMove.
|
|
|
|
@param e details about the position and status of the mouse event
|
|
@see mouseEnter, mouseExit, mouseDrag, contains
|
|
*/
|
|
virtual void mouseMove (const MouseEvent& e);
|
|
|
|
/** Called when the mouse first enters this component.
|
|
|
|
If the mouse button isn't pressed and the mouse moves into a component,
|
|
this will be called to let the component react to this.
|
|
|
|
When the mouse button is pressed and held down while being moved in
|
|
or out of a component, no mouseEnter or mouseExit callbacks are made - only
|
|
mouseDrag messages are sent to the component that the mouse was originally
|
|
clicked on, until the button is released.
|
|
|
|
If you're writing a component that needs to repaint itself when the mouse
|
|
enters and exits, it might be quicker to use the setRepaintsOnMouseActivity()
|
|
method.
|
|
|
|
@param e details about the position and status of the mouse event
|
|
@see mouseExit, mouseDrag, mouseMove, contains
|
|
*/
|
|
virtual void mouseEnter (const MouseEvent& e);
|
|
|
|
/** Called when the mouse moves out of this component.
|
|
|
|
This will be called when the mouse moves off the edge of this
|
|
component.
|
|
|
|
If the mouse button was pressed, and it was then dragged off the
|
|
edge of the component and released, then this callback will happen
|
|
when the button is released, after the mouseUp callback.
|
|
|
|
If you're writing a component that needs to repaint itself when the mouse
|
|
enters and exits, it might be quicker to use the setRepaintsOnMouseActivity()
|
|
method.
|
|
|
|
@param e details about the position and status of the mouse event
|
|
@see mouseEnter, mouseDrag, mouseMove, contains
|
|
*/
|
|
virtual void mouseExit (const MouseEvent& e);
|
|
|
|
/** Called when a mouse button is pressed while it's over this component.
|
|
|
|
The MouseEvent object passed in contains lots of methods for finding out
|
|
which button was pressed, as well as which modifier keys (e.g. shift, ctrl)
|
|
were held down at the time.
|
|
|
|
Once a button is held down, the mouseDrag method will be called when the
|
|
mouse moves, until the button is released.
|
|
|
|
@param e details about the position and status of the mouse event
|
|
@see mouseUp, mouseDrag, mouseDoubleClick, contains
|
|
*/
|
|
virtual void mouseDown (const MouseEvent& e);
|
|
|
|
/** Called when the mouse is moved while a button is held down.
|
|
|
|
When a mouse button is pressed inside a component, that component
|
|
receives mouseDrag callbacks each time the mouse moves, even if the
|
|
mouse strays outside the component's bounds.
|
|
|
|
If you want to be able to drag things off the edge of a component
|
|
and have the component scroll when you get to the edges, the
|
|
beginDragAutoRepeat() method might be useful.
|
|
|
|
@param e details about the position and status of the mouse event
|
|
@see mouseDown, mouseUp, mouseMove, contains, beginDragAutoRepeat
|
|
*/
|
|
virtual void mouseDrag (const MouseEvent& e);
|
|
|
|
/** Called when a mouse button is released.
|
|
|
|
A mouseUp callback is sent to the component in which a button was pressed
|
|
even if the mouse is actually over a different component when the
|
|
button is released.
|
|
|
|
The MouseEvent object passed in contains lots of methods for finding out
|
|
which buttons were down just before they were released.
|
|
|
|
@param e details about the position and status of the mouse event
|
|
@see mouseDown, mouseDrag, mouseDoubleClick, contains
|
|
*/
|
|
virtual void mouseUp (const MouseEvent& e);
|
|
|
|
/** Called when a mouse button has been double-clicked in this component.
|
|
|
|
The MouseEvent object passed in contains lots of methods for finding out
|
|
which button was pressed, as well as which modifier keys (e.g. shift, ctrl)
|
|
were held down at the time.
|
|
|
|
For altering the time limit used to detect double-clicks,
|
|
see MouseEvent::setDoubleClickTimeout.
|
|
|
|
@param e details about the position and status of the mouse event
|
|
@see mouseDown, mouseUp, MouseEvent::setDoubleClickTimeout,
|
|
MouseEvent::getDoubleClickTimeout
|
|
*/
|
|
virtual void mouseDoubleClick (const MouseEvent& e);
|
|
|
|
/** Called when the mouse-wheel is moved.
|
|
|
|
This callback is sent to the component that the mouse is over when the
|
|
wheel is moved.
|
|
|
|
If not overridden, the component will forward this message to its parent, so
|
|
that parent components can collect mouse-wheel messages that happen to
|
|
child components which aren't interested in them.
|
|
|
|
@param e details about the position and status of the mouse event
|
|
@param wheelIncrementX the speed and direction of the horizontal scroll-wheel - a positive
|
|
value means the wheel has been pushed to the right, negative means it
|
|
was pushed to the left
|
|
@param wheelIncrementY the speed and direction of the vertical scroll-wheel - a positive
|
|
value means the wheel has been pushed upwards, negative means it
|
|
was pushed downwards
|
|
*/
|
|
virtual void mouseWheelMove (const MouseEvent& e,
|
|
float wheelIncrementX,
|
|
float wheelIncrementY);
|
|
|
|
/** Ensures that a non-stop stream of mouse-drag events will be sent during the
|
|
next mouse-drag operation.
|
|
|
|
This allows you to make sure that mouseDrag() events sent continuously, even
|
|
when the mouse isn't moving. This can be useful for things like auto-scrolling
|
|
components when the mouse is near an edge.
|
|
|
|
Call this method during a mouseDown() or mouseDrag() callback, specifying the
|
|
minimum interval between consecutive mouse drag callbacks. The callbacks
|
|
will continue until the mouse is released, and then the interval will be reset,
|
|
so you need to make sure it's called every time you begin a drag event. If it
|
|
is called when the mouse isn't actually being pressed, it will apply to the next
|
|
mouse-drag operation that happens.
|
|
|
|
Passing an interval of 0 or less will cancel the auto-repeat.
|
|
|
|
@see mouseDrag
|
|
*/
|
|
static void beginDragAutoRepeat (const int millisecondIntervalBetweenCallbacks);
|
|
|
|
/** Causes automatic repaints when the mouse enters or exits this component.
|
|
|
|
If turned on, then when the mouse enters/exits, or when the button is pressed/released
|
|
on the component, it will trigger a repaint.
|
|
|
|
This is handy for things like buttons that need to draw themselves differently when
|
|
the mouse moves over them, and it avoids having to override all the different mouse
|
|
callbacks and call repaint().
|
|
|
|
@see mouseEnter, mouseExit, mouseDown, mouseUp
|
|
*/
|
|
void setRepaintsOnMouseActivity (const bool shouldRepaint) throw();
|
|
|
|
/** Registers a listener to be told when mouse events occur in this component.
|
|
|
|
If you need to get informed about mouse events in a component but can't or
|
|
don't want to override its methods, you can attach any number of listeners
|
|
to the component, and these will get told about the events in addition to
|
|
the component's own callbacks being called.
|
|
|
|
Note that a MouseListener can also be attached to more than one component.
|
|
|
|
@param newListener the listener to register
|
|
@param wantsEventsForAllNestedChildComponents if true, the listener will receive callbacks
|
|
for events that happen to any child component
|
|
within this component, including deeply-nested
|
|
child components. If false, it will only be
|
|
told about events that this component handles.
|
|
@see MouseListener, removeMouseListener
|
|
*/
|
|
void addMouseListener (MouseListener* const newListener,
|
|
const bool wantsEventsForAllNestedChildComponents) throw();
|
|
|
|
/** Deregisters a mouse listener.
|
|
|
|
@see addMouseListener, MouseListener
|
|
*/
|
|
void removeMouseListener (MouseListener* const listenerToRemove) throw();
|
|
|
|
/** Adds a listener that wants to hear about keypresses that this component receives.
|
|
|
|
The listeners that are registered with a component are called by its keyPressed() or
|
|
keyStateChanged() methods (assuming these haven't been overridden to do something else).
|
|
|
|
If you add an object as a key listener, be careful to remove it when the object
|
|
is deleted, or the component will be left with a dangling pointer.
|
|
|
|
@see keyPressed, keyStateChanged, removeKeyListener
|
|
*/
|
|
void addKeyListener (KeyListener* const newListener) throw();
|
|
|
|
/** Removes a previously-registered key listener.
|
|
|
|
@see addKeyListener
|
|
*/
|
|
void removeKeyListener (KeyListener* const listenerToRemove) throw();
|
|
|
|
/** Called when a key is pressed.
|
|
|
|
When a key is pressed, the component that has the keyboard focus will have this
|
|
method called. Remember that a component will only be given the focus if its
|
|
setWantsKeyboardFocus() method has been used to enable this.
|
|
|
|
If your implementation returns true, the event will be consumed and not passed
|
|
on to any other listeners. If it returns false, the key will be passed to any
|
|
KeyListeners that have been registered with this component. As soon as one of these
|
|
returns true, the process will stop, but if they all return false, the event will
|
|
be passed upwards to this component's parent, and so on.
|
|
|
|
The default implementation of this method does nothing and returns false.
|
|
|
|
@see keyStateChanged, getCurrentlyFocusedComponent, addKeyListener
|
|
*/
|
|
virtual bool keyPressed (const KeyPress& key);
|
|
|
|
/** Called when a key is pressed or released.
|
|
|
|
Whenever a key on the keyboard is pressed or released (including modifier keys
|
|
like shift and ctrl), this method will be called on the component that currently
|
|
has the keyboard focus. Remember that a component will only be given the focus if
|
|
its setWantsKeyboardFocus() method has been used to enable this.
|
|
|
|
If your implementation returns true, the event will be consumed and not passed
|
|
on to any other listeners. If it returns false, then any KeyListeners that have
|
|
been registered with this component will have their keyStateChanged methods called.
|
|
As soon as one of these returns true, the process will stop, but if they all return
|
|
false, the event will be passed upwards to this component's parent, and so on.
|
|
|
|
The default implementation of this method does nothing and returns false.
|
|
|
|
To find out which keys are up or down at any time, see the KeyPress::isKeyCurrentlyDown()
|
|
method.
|
|
|
|
@param isKeyDown true if a key has been pressed; false if it has been released
|
|
|
|
@see keyPressed, KeyPress, getCurrentlyFocusedComponent, addKeyListener
|
|
*/
|
|
virtual bool keyStateChanged (const bool isKeyDown);
|
|
|
|
/** Called when a modifier key is pressed or released.
|
|
|
|
Whenever the shift, control, alt or command keys are pressed or released,
|
|
this method will be called on the component that currently has the keyboard focus.
|
|
Remember that a component will only be given the focus if its setWantsKeyboardFocus()
|
|
method has been used to enable this.
|
|
|
|
The default implementation of this method actually calls its parent's modifierKeysChanged
|
|
method, so that focused components which aren't interested in this will give their
|
|
parents a chance to act on the event instead.
|
|
|
|
@see keyStateChanged, ModifierKeys
|
|
*/
|
|
virtual void modifierKeysChanged (const ModifierKeys& modifiers);
|
|
|
|
/** Enumeration used by the focusChanged() and focusLost() methods. */
|
|
enum FocusChangeType
|
|
{
|
|
focusChangedByMouseClick, /**< Means that the user clicked the mouse to change focus. */
|
|
focusChangedByTabKey, /**< Means that the user pressed the tab key to move the focus. */
|
|
focusChangedDirectly /**< Means that the focus was changed by a call to grabKeyboardFocus(). */
|
|
};
|
|
|
|
/** Called to indicate that this component has just acquired the keyboard focus.
|
|
|
|
@see focusLost, setWantsKeyboardFocus, getCurrentlyFocusedComponent, hasKeyboardFocus
|
|
*/
|
|
virtual void focusGained (FocusChangeType cause);
|
|
|
|
/** Called to indicate that this component has just lost the keyboard focus.
|
|
|
|
@see focusGained, setWantsKeyboardFocus, getCurrentlyFocusedComponent, hasKeyboardFocus
|
|
*/
|
|
virtual void focusLost (FocusChangeType cause);
|
|
|
|
/** Called to indicate that one of this component's children has been focused or unfocused.
|
|
|
|
Essentially this means that the return value of a call to hasKeyboardFocus (true) has
|
|
changed. It happens when focus moves from one of this component's children (at any depth)
|
|
to a component that isn't contained in this one, (or vice-versa).
|
|
|
|
@see focusGained, setWantsKeyboardFocus, getCurrentlyFocusedComponent, hasKeyboardFocus
|
|
*/
|
|
virtual void focusOfChildComponentChanged (FocusChangeType cause);
|
|
|
|
/** Returns true if the mouse is currently over this component.
|
|
|
|
If the mouse isn't over the component, this will return false, even if the
|
|
mouse is currently being dragged - so you can use this in your mouseDrag
|
|
method to find out whether it's really over the component or not.
|
|
|
|
Note that when the mouse button is being held down, then the only component
|
|
for which this method will return true is the one that was originally
|
|
clicked on.
|
|
|
|
@see isMouseButtonDown. isMouseOverOrDragging, mouseDrag
|
|
*/
|
|
bool isMouseOver() const throw();
|
|
|
|
/** Returns true if the mouse button is currently held down in this component.
|
|
|
|
Note that this is a test to see whether the mouse is being pressed in this
|
|
component, so it'll return false if called on component A when the mouse
|
|
is actually being dragged in component B.
|
|
|
|
@see isMouseButtonDownAnywhere, isMouseOver, isMouseOverOrDragging
|
|
*/
|
|
bool isMouseButtonDown() const throw();
|
|
|
|
/** True if the mouse is over this component, or if it's being dragged in this component.
|
|
|
|
This is a handy equivalent to (isMouseOver() || isMouseButtonDown()).
|
|
|
|
@see isMouseOver, isMouseButtonDown, isMouseButtonDownAnywhere
|
|
*/
|
|
bool isMouseOverOrDragging() const throw();
|
|
|
|
/** Returns true if a mouse button is currently down.
|
|
|
|
Unlike isMouseButtonDown, this will test the current state of the
|
|
buttons without regard to which component (if any) it has been
|
|
pressed in.
|
|
|
|
@see isMouseButtonDown, ModifierKeys
|
|
*/
|
|
static bool JUCE_CALLTYPE isMouseButtonDownAnywhere() throw();
|
|
|
|
/** Returns the mouse's current position, relative to this component.
|
|
|
|
The co-ordinates are relative to the component's top-left corner.
|
|
*/
|
|
void getMouseXYRelative (int& x, int& y) const throw();
|
|
|
|
/** Returns the component that's currently underneath the mouse.
|
|
|
|
@returns the component or 0 if there isn't one.
|
|
@see contains, getComponentAt
|
|
*/
|
|
static Component* JUCE_CALLTYPE getComponentUnderMouse() throw();
|
|
|
|
/** Allows the mouse to move beyond the edges of the screen.
|
|
|
|
Calling this method when the mouse button is currently pressed inside this component
|
|
will remove the cursor from the screen and allow the mouse to (seem to) move beyond
|
|
the edges of the screen.
|
|
|
|
This means that the co-ordinates returned to mouseDrag() will be unbounded, and this
|
|
can be used for things like custom slider controls or dragging objects around, where
|
|
movement would be otherwise be limited by the mouse hitting the edges of the screen.
|
|
|
|
The unbounded mode is automatically turned off when the mouse button is released, or
|
|
it can be turned off explicitly by calling this method again.
|
|
|
|
@param shouldUnboundedMovementBeEnabled whether to turn this mode on or off
|
|
@param keepCursorVisibleUntilOffscreen if set to false, the cursor will immediately be
|
|
hidden; if true, it will only be hidden when it
|
|
is moved beyond the edge of the screen
|
|
*/
|
|
void enableUnboundedMouseMovement (bool shouldUnboundedMovementBeEnabled,
|
|
bool keepCursorVisibleUntilOffscreen = false) throw();
|
|
|
|
/** Called when this component's size has been changed.
|
|
|
|
A component can implement this method to do things such as laying out its
|
|
child components when its width or height changes.
|
|
|
|
The method is called synchronously as a result of the setBounds or setSize
|
|
methods, so repeatedly changing a components size will repeatedly call its
|
|
resized method (unlike things like repainting, where multiple calls to repaint
|
|
are coalesced together).
|
|
|
|
If the component is a top-level window on the desktop, its size could also
|
|
be changed by operating-system factors beyond the application's control.
|
|
|
|
@see moved, setSize
|
|
*/
|
|
virtual void resized();
|
|
|
|
/** Called when this component's position has been changed.
|
|
|
|
This is called when the position relative to its parent changes, not when
|
|
its absolute position on the screen changes (so it won't be called for
|
|
all child components when a parent component is moved).
|
|
|
|
The method is called synchronously as a result of the setBounds, setTopLeftPosition
|
|
or any of the other repositioning methods, and like resized(), it will be
|
|
called each time those methods are called.
|
|
|
|
If the component is a top-level window on the desktop, its position could also
|
|
be changed by operating-system factors beyond the application's control.
|
|
|
|
@see resized, setBounds
|
|
*/
|
|
virtual void moved();
|
|
|
|
/** Called when one of this component's children is moved or resized.
|
|
|
|
If the parent wants to know about changes to its immediate children (not
|
|
to children of its children), this is the method to override.
|
|
|
|
@see moved, resized, parentSizeChanged
|
|
*/
|
|
virtual void childBoundsChanged (Component* child);
|
|
|
|
/** Called when this component's immediate parent has been resized.
|
|
|
|
If the component is a top-level window, this indicates that the screen size
|
|
has changed.
|
|
|
|
@see childBoundsChanged, moved, resized
|
|
*/
|
|
virtual void parentSizeChanged();
|
|
|
|
/** Called when this component has been moved to the front of its siblings.
|
|
|
|
The component may have been brought to the front by the toFront() method, or
|
|
by the operating system if it's a top-level window.
|
|
|
|
@see toFront
|
|
*/
|
|
virtual void broughtToFront();
|
|
|
|
/** Adds a listener to be told about changes to the component hierarchy or position.
|
|
|
|
Component listeners get called when this component's size, position or children
|
|
change - see the ComponentListener class for more details.
|
|
|
|
@param newListener the listener to register - if this is already registered, it
|
|
will be ignored.
|
|
@see ComponentListener, removeComponentListener
|
|
*/
|
|
void addComponentListener (ComponentListener* const newListener) throw();
|
|
|
|
/** Removes a component listener.
|
|
|
|
@see addComponentListener
|
|
*/
|
|
void removeComponentListener (ComponentListener* const listenerToRemove) throw();
|
|
|
|
/** Dispatches a numbered message to this component.
|
|
|
|
This is a quick and cheap way of allowing simple asynchronous messages to
|
|
be sent to components. It's also safe, because if the component that you
|
|
send the message to is a null or dangling pointer, this won't cause an error.
|
|
|
|
The command ID is later delivered to the component's handleCommandMessage() method by
|
|
the application's message queue.
|
|
|
|
@see handleCommandMessage
|
|
*/
|
|
void postCommandMessage (const int commandId) throw();
|
|
|
|
/** Called to handle a command that was sent by postCommandMessage().
|
|
|
|
This is called by the message thread when a command message arrives, and
|
|
the component can override this method to process it in any way it needs to.
|
|
|
|
@see postCommandMessage
|
|
*/
|
|
virtual void handleCommandMessage (int commandId);
|
|
|
|
/** Runs a component modally, waiting until the loop terminates.
|
|
|
|
This method first makes the component visible, brings it to the front and
|
|
gives it the keyboard focus.
|
|
|
|
It then runs a loop, dispatching messages from the system message queue, but
|
|
blocking all mouse or keyboard messages from reaching any components other
|
|
than this one and its children.
|
|
|
|
This loop continues until the component's exitModalState() method is called (or
|
|
the component is deleted), and then this method returns, returning the value
|
|
passed into exitModalState().
|
|
|
|
@see enterModalState, exitModalState, isCurrentlyModal, getCurrentlyModalComponent,
|
|
isCurrentlyBlockedByAnotherModalComponent, MessageManager::dispatchNextMessage
|
|
*/
|
|
int runModalLoop();
|
|
|
|
/** Puts the component into a modal state.
|
|
|
|
This makes the component modal, so that messages are blocked from reaching
|
|
any components other than this one and its children, but unlike runModalLoop(),
|
|
this method returns immediately.
|
|
|
|
If takeKeyboardFocus is true, the component will use grabKeyboardFocus() to
|
|
get the focus, which is usually what you'll want it to do. If not, it will leave
|
|
the focus unchanged.
|
|
|
|
@see exitModalState, runModalLoop
|
|
*/
|
|
void enterModalState (const bool takeKeyboardFocus = true);
|
|
|
|
/** Ends a component's modal state.
|
|
|
|
If this component is currently modal, this will turn of its modalness, and return
|
|
a value to the runModalLoop() method that might have be running its modal loop.
|
|
|
|
@see runModalLoop, enterModalState, isCurrentlyModal
|
|
*/
|
|
void exitModalState (const int returnValue);
|
|
|
|
/** Returns true if this component is the modal one.
|
|
|
|
It's possible to have nested modal components, e.g. a pop-up dialog box
|
|
that launches another pop-up, but this will only return true for
|
|
the one at the top of the stack.
|
|
|
|
@see getCurrentlyModalComponent
|
|
*/
|
|
bool isCurrentlyModal() const throw();
|
|
|
|
/** Returns the number of components that are currently in a modal state.
|
|
@see getCurrentlyModalComponent
|
|
*/
|
|
static int JUCE_CALLTYPE getNumCurrentlyModalComponents() throw();
|
|
|
|
/** Returns one of the components that are currently modal.
|
|
|
|
The index specifies which of the possible modal components to return. The order
|
|
of the components in this list is the reverse of the order in which they became
|
|
modal - so the component at index 0 is always the active component, and the others
|
|
are progressively earlier ones that are themselves now blocked by later ones.
|
|
|
|
@returns the modal component, or null if no components are modal (or if the
|
|
index is out of range)
|
|
@see getNumCurrentlyModalComponents, runModalLoop, isCurrentlyModal
|
|
*/
|
|
static Component* JUCE_CALLTYPE getCurrentlyModalComponent (int index = 0) throw();
|
|
|
|
/** Checks whether there's a modal component somewhere that's stopping this one
|
|
from receiving messages.
|
|
|
|
If there is a modal component, its canModalEventBeSentToComponent() method
|
|
will be called to see if it will still allow this component to receive events.
|
|
|
|
@see runModalLoop, getCurrentlyModalComponent
|
|
*/
|
|
bool isCurrentlyBlockedByAnotherModalComponent() const throw();
|
|
|
|
/** When a component is modal, this callback allows it to choose which other
|
|
components can still receive events.
|
|
|
|
When a modal component is active and the user clicks on a non-modal component,
|
|
this method is called on the modal component, and if it returns true, the
|
|
event is allowed to reach its target. If it returns false, the event is blocked
|
|
and the inputAttemptWhenModal() callback is made.
|
|
|
|
It called by the isCurrentlyBlockedByAnotherModalComponent() method. The default
|
|
implementation just returns false in all cases.
|
|
*/
|
|
virtual bool canModalEventBeSentToComponent (const Component* targetComponent);
|
|
|
|
/** Called when the user tries to click on a component that is blocked by another
|
|
modal component.
|
|
|
|
When a component is modal and the user clicks on one of the other components,
|
|
the modal component will receive this callback.
|
|
|
|
The default implementation of this method will play a beep, and bring the currently
|
|
modal component to the front, but it can be overridden to do other tasks.
|
|
|
|
@see isCurrentlyBlockedByAnotherModalComponent, canModalEventBeSentToComponent
|
|
*/
|
|
virtual void inputAttemptWhenModal();
|
|
|
|
/** Returns one of the component's properties as a string.
|
|
|
|
@param keyName the name of the property to retrieve
|
|
@param useParentComponentIfNotFound if this is true and the key isn't present in this component's
|
|
properties, then it will check whether the parent component has
|
|
the key.
|
|
@param defaultReturnValue a value to return if the named property doesn't actually exist
|
|
*/
|
|
const String getComponentProperty (const String& keyName,
|
|
const bool useParentComponentIfNotFound,
|
|
const String& defaultReturnValue = String::empty) const throw();
|
|
|
|
/** Returns one of the properties as an integer.
|
|
|
|
@param keyName the name of the property to retrieve
|
|
@param useParentComponentIfNotFound if this is true and the key isn't present in this component's
|
|
properties, then it will check whether the parent component has
|
|
the key.
|
|
@param defaultReturnValue a value to return if the named property doesn't actually exist
|
|
*/
|
|
int getComponentPropertyInt (const String& keyName,
|
|
const bool useParentComponentIfNotFound,
|
|
const int defaultReturnValue = 0) const throw();
|
|
|
|
/** Returns one of the properties as an double.
|
|
|
|
@param keyName the name of the property to retrieve
|
|
@param useParentComponentIfNotFound if this is true and the key isn't present in this component's
|
|
properties, then it will check whether the parent component has
|
|
the key.
|
|
@param defaultReturnValue a value to return if the named property doesn't actually exist
|
|
*/
|
|
double getComponentPropertyDouble (const String& keyName,
|
|
const bool useParentComponentIfNotFound,
|
|
const double defaultReturnValue = 0.0) const throw();
|
|
|
|
/** Returns one of the properties as an boolean.
|
|
|
|
The result will be true if the string found for this key name can be parsed as a non-zero
|
|
integer.
|
|
|
|
@param keyName the name of the property to retrieve
|
|
@param useParentComponentIfNotFound if this is true and the key isn't present in this component's
|
|
properties, then it will check whether the parent component has
|
|
the key.
|
|
@param defaultReturnValue a value to return if the named property doesn't actually exist
|
|
*/
|
|
bool getComponentPropertyBool (const String& keyName,
|
|
const bool useParentComponentIfNotFound,
|
|
const bool defaultReturnValue = false) const throw();
|
|
|
|
/** Returns one of the properties as an colour.
|
|
|
|
@param keyName the name of the property to retrieve
|
|
@param useParentComponentIfNotFound if this is true and the key isn't present in this component's
|
|
properties, then it will check whether the parent component has
|
|
the key.
|
|
@param defaultReturnValue a colour to return if the named property doesn't actually exist
|
|
*/
|
|
const Colour getComponentPropertyColour (const String& keyName,
|
|
const bool useParentComponentIfNotFound,
|
|
const Colour& defaultReturnValue = Colours::black) const throw();
|
|
|
|
/** Sets a named property as a string.
|
|
|
|
@param keyName the name of the property to set. (This mustn't be an empty string)
|
|
@param value the new value to set it to
|
|
@see removeComponentProperty
|
|
*/
|
|
void setComponentProperty (const String& keyName, const String& value) throw();
|
|
|
|
/** Sets a named property to an integer.
|
|
|
|
@param keyName the name of the property to set. (This mustn't be an empty string)
|
|
@param value the new value to set it to
|
|
@see removeComponentProperty
|
|
*/
|
|
void setComponentProperty (const String& keyName, const int value) throw();
|
|
|
|
/** Sets a named property to a double.
|
|
|
|
@param keyName the name of the property to set. (This mustn't be an empty string)
|
|
@param value the new value to set it to
|
|
@see removeComponentProperty
|
|
*/
|
|
void setComponentProperty (const String& keyName, const double value) throw();
|
|
|
|
/** Sets a named property to a boolean.
|
|
|
|
@param keyName the name of the property to set. (This mustn't be an empty string)
|
|
@param value the new value to set it to
|
|
@see removeComponentProperty
|
|
*/
|
|
void setComponentProperty (const String& keyName, const bool value) throw();
|
|
|
|
/** Sets a named property to a colour.
|
|
|
|
@param keyName the name of the property to set. (This mustn't be an empty string)
|
|
@param newColour the new colour to set it to
|
|
@see removeComponentProperty
|
|
*/
|
|
void setComponentProperty (const String& keyName, const Colour& newColour) throw();
|
|
|
|
/** Deletes a named component property.
|
|
|
|
@param keyName the name of the property to delete. (This mustn't be an empty string)
|
|
@see setComponentProperty, getComponentProperty
|
|
*/
|
|
void removeComponentProperty (const String& keyName) throw();
|
|
|
|
/** Returns the complete set of properties that have been set for this component.
|
|
|
|
If no properties have been set, this will return a null pointer.
|
|
|
|
@see getComponentProperty, setComponentProperty
|
|
*/
|
|
PropertySet* getComponentProperties() const throw() { return propertySet_; }
|
|
|
|
/** Looks for a colour that has been registered with the given colour ID number.
|
|
|
|
If a colour has been set for this ID number using setColour(), then it is
|
|
returned. If none has been set, the method will try calling the component's
|
|
LookAndFeel class's findColour() method. If none has been registered with the
|
|
look-and-feel either, it will just return black.
|
|
|
|
The colour IDs for various purposes are stored as enums in the components that
|
|
they are relevent to - for an example, see Slider::ColourIds,
|
|
Label::ColourIds, TextEditor::ColourIds, TreeView::ColourIds, etc.
|
|
|
|
@see setColour, isColourSpecified, colourChanged, LookAndFeel::findColour, LookAndFeel::setColour
|
|
*/
|
|
const Colour findColour (const int colourId, const bool inheritFromParent = false) const throw();
|
|
|
|
/** Registers a colour to be used for a particular purpose.
|
|
|
|
Changing a colour will cause a synchronous callback to the colourChanged()
|
|
method, which your component can override if it needs to do something when
|
|
colours are altered.
|
|
|
|
For more details about colour IDs, see the comments for findColour().
|
|
|
|
@see findColour, isColourSpecified, colourChanged, LookAndFeel::findColour, LookAndFeel::setColour
|
|
*/
|
|
void setColour (const int colourId, const Colour& colour);
|
|
|
|
/** If a colour has been set with setColour(), this will remove it.
|
|
|
|
This allows you to make a colour revert to its default state.
|
|
*/
|
|
void removeColour (const int colourId);
|
|
|
|
/** Returns true if the specified colour ID has been explicitly set for this
|
|
component using the setColour() method.
|
|
*/
|
|
bool isColourSpecified (const int colourId) const throw();
|
|
|
|
/** This looks for any colours that have been specified for this component,
|
|
and copies them to the specified target component.
|
|
*/
|
|
void copyAllExplicitColoursTo (Component& target) const throw();
|
|
|
|
/** This method is called when a colour is changed by the setColour() method.
|
|
|
|
@see setColour, findColour
|
|
*/
|
|
virtual void colourChanged();
|
|
|
|
/** Returns the underlying native window handle for this component.
|
|
|
|
This is platform-dependent and strictly for power-users only!
|
|
*/
|
|
void* getWindowHandle() const throw();
|
|
|
|
/** When created, each component is given a number to uniquely identify it.
|
|
|
|
The number is incremented each time a new component is created, so it's a more
|
|
unique way of identifying a component than using its memory location (which
|
|
may be reused after the component is deleted, of course).
|
|
*/
|
|
uint32 getComponentUID() const throw() { return componentUID; }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
friend class ComponentPeer;
|
|
friend class InternalDragRepeater;
|
|
|
|
static Component* currentlyFocusedComponent;
|
|
static Component* componentUnderMouse;
|
|
|
|
String componentName_;
|
|
Component* parentComponent_;
|
|
uint32 componentUID;
|
|
Rectangle bounds_;
|
|
unsigned short numDeepMouseListeners;
|
|
Array <Component*> childComponentList_;
|
|
LookAndFeel* lookAndFeel_;
|
|
MouseCursor cursor_;
|
|
ImageEffectFilter* effect_;
|
|
Image* bufferedImage_;
|
|
VoidArray* mouseListeners_;
|
|
VoidArray* keyListeners_;
|
|
VoidArray* componentListeners_;
|
|
PropertySet* propertySet_;
|
|
|
|
struct ComponentFlags
|
|
{
|
|
bool hasHeavyweightPeerFlag : 1;
|
|
bool visibleFlag : 1;
|
|
bool opaqueFlag : 1;
|
|
bool ignoresMouseClicksFlag : 1;
|
|
bool allowChildMouseClicksFlag : 1;
|
|
bool wantsFocusFlag : 1;
|
|
bool isFocusContainerFlag : 1;
|
|
bool dontFocusOnMouseClickFlag : 1;
|
|
bool alwaysOnTopFlag : 1;
|
|
bool bufferToImageFlag : 1;
|
|
bool bringToFrontOnClickFlag : 1;
|
|
bool repaintOnMouseActivityFlag : 1;
|
|
bool draggingFlag : 1;
|
|
bool mouseOverFlag : 1;
|
|
bool mouseInsideFlag : 1;
|
|
bool currentlyModalFlag : 1;
|
|
bool isDisabledFlag : 1;
|
|
bool childCompFocusedFlag : 1;
|
|
#ifdef JUCE_DEBUG
|
|
bool isInsidePaintCall : 1;
|
|
#endif
|
|
};
|
|
|
|
union
|
|
{
|
|
uint32 componentFlags_;
|
|
ComponentFlags flags;
|
|
};
|
|
|
|
void internalMouseEnter (int x, int y, const int64 time);
|
|
void internalMouseExit (int x, int y, const int64 time);
|
|
void internalMouseDown (int x, int y);
|
|
void internalMouseUp (const int oldModifiers, int x, int y, const int64 time);
|
|
void internalMouseDrag (int x, int y, const int64 time);
|
|
void internalMouseMove (int x, int y, const int64 time);
|
|
void internalMouseWheel (const int intAmountX, const int intAmountY, const int64 time);
|
|
void internalBroughtToFront();
|
|
void internalFocusGain (const FocusChangeType cause);
|
|
void internalFocusLoss (const FocusChangeType cause);
|
|
void internalChildFocusChange (FocusChangeType cause);
|
|
void internalModalInputAttempt();
|
|
void internalModifierKeysChanged();
|
|
void internalChildrenChanged();
|
|
void internalHierarchyChanged();
|
|
void internalUpdateMouseCursor (const bool forcedUpdate) throw();
|
|
void sendMovedResizedMessages (const bool wasMoved, const bool wasResized);
|
|
void repaintParent() throw();
|
|
void sendFakeMouseMove() const;
|
|
void takeKeyboardFocus (const FocusChangeType cause);
|
|
void grabFocusInternal (const FocusChangeType cause, const bool canTryParent = true);
|
|
static void giveAwayFocus();
|
|
void sendEnablementChangeMessage();
|
|
static void* runModalLoopCallback (void*);
|
|
static void bringModalComponentToFront();
|
|
void subtractObscuredRegions (RectangleList& result,
|
|
const int deltaX, const int deltaY,
|
|
const Rectangle& clipRect,
|
|
const Component* const compToAvoid) const throw();
|
|
void clipObscuredRegions (Graphics& g, const Rectangle& clipRect,
|
|
const int deltaX, const int deltaY) const throw();
|
|
|
|
// how much of the component is not off the edges of its parents
|
|
const Rectangle getUnclippedArea() const;
|
|
void sendVisibilityChangeMessage();
|
|
|
|
// This is included here just to cause a compile error if your code is still handling
|
|
// drag-and-drop with this method. If so, just update it to use the new FileDragAndDropTarget
|
|
// class, which is easy (just make your class inherit from FileDragAndDropTarget, and
|
|
// implement its methods instead of this Component method).
|
|
virtual void filesDropped (const StringArray&, int, int) {}
|
|
|
|
// components aren't allowed to have copy constructors, as this would mess up parent
|
|
// hierarchies. You might need to give your subclasses a private dummy constructor like
|
|
// this one to avoid compiler warnings.
|
|
Component (const Component&);
|
|
|
|
const Component& operator= (const Component&);
|
|
|
|
// (dummy method to cause a deliberate compile error - if you hit this, you need to update your
|
|
// subclass to use the new parameters to keyStateChanged)
|
|
virtual void keyStateChanged() {};
|
|
|
|
protected:
|
|
/** @internal */
|
|
virtual void internalRepaint (int x, int y, int w, int h);
|
|
|
|
virtual ComponentPeer* createNewPeer (int styleFlags, void* nativeWindowToAttachTo);
|
|
|
|
/** Overridden from the MessageListener parent class.
|
|
|
|
You can override this if you really need to, but be sure to pass your unwanted messages up
|
|
to this base class implementation, as the Component class needs to send itself messages
|
|
to work properly.
|
|
*/
|
|
void handleMessage (const Message&);
|
|
};
|
|
|
|
#endif // __JUCE_COMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_Component.h *********/
|
|
|
|
/********* Start of inlined file: juce_ApplicationCommandInfo.h *********/
|
|
#ifndef __JUCE_APPLICATIONCOMMANDINFO_JUCEHEADER__
|
|
#define __JUCE_APPLICATIONCOMMANDINFO_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ApplicationCommandID.h *********/
|
|
#ifndef __JUCE_APPLICATIONCOMMANDID_JUCEHEADER__
|
|
#define __JUCE_APPLICATIONCOMMANDID_JUCEHEADER__
|
|
|
|
/** A type used to hold the unique ID for an application command.
|
|
|
|
This is a numeric type, so it can be stored as an integer.
|
|
|
|
@see ApplicationCommandInfo, ApplicationCommandManager,
|
|
ApplicationCommandTarget, KeyPressMappingSet
|
|
*/
|
|
typedef int CommandID;
|
|
|
|
/** A set of general-purpose application command IDs.
|
|
|
|
Because these commands are likely to be used in most apps, they're defined
|
|
here to help different apps to use the same numeric values for them.
|
|
|
|
Of course you don't have to use these, but some of them are used internally by
|
|
Juce - e.g. the quit ID is recognised as a command by the JUCEApplication class.
|
|
|
|
@see ApplicationCommandInfo, ApplicationCommandManager,
|
|
ApplicationCommandTarget, KeyPressMappingSet
|
|
*/
|
|
namespace StandardApplicationCommandIDs
|
|
{
|
|
/** This command ID should be used to send a "Quit the App" command.
|
|
|
|
This command is recognised by the JUCEApplication class, so if it is invoked
|
|
and no other ApplicationCommandTarget handles the event first, the JUCEApplication
|
|
object will catch it and call JUCEApplication::systemRequestedQuit().
|
|
*/
|
|
static const CommandID quit = 0x1001;
|
|
|
|
/** The command ID that should be used to send a "Delete" command. */
|
|
static const CommandID del = 0x1002;
|
|
|
|
/** The command ID that should be used to send a "Cut" command. */
|
|
static const CommandID cut = 0x1003;
|
|
|
|
/** The command ID that should be used to send a "Copy to clipboard" command. */
|
|
static const CommandID copy = 0x1004;
|
|
|
|
/** The command ID that should be used to send a "Paste from clipboard" command. */
|
|
static const CommandID paste = 0x1005;
|
|
|
|
/** The command ID that should be used to send a "Select all" command. */
|
|
static const CommandID selectAll = 0x1006;
|
|
|
|
/** The command ID that should be used to send a "Deselect all" command. */
|
|
static const CommandID deselectAll = 0x1007;
|
|
}
|
|
|
|
#endif // __JUCE_APPLICATIONCOMMANDID_JUCEHEADER__
|
|
/********* End of inlined file: juce_ApplicationCommandID.h *********/
|
|
|
|
/**
|
|
Holds information describing an application command.
|
|
|
|
This object is used to pass information about a particular command, such as its
|
|
name, description and other usage flags.
|
|
|
|
When an ApplicationCommandTarget is asked to provide information about the commands
|
|
it can perform, this is the structure gets filled-in to describe each one.
|
|
|
|
@see ApplicationCommandTarget, ApplicationCommandTarget::getCommandInfo(),
|
|
ApplicationCommandManager
|
|
*/
|
|
struct JUCE_API ApplicationCommandInfo
|
|
{
|
|
|
|
ApplicationCommandInfo (const CommandID commandID) throw();
|
|
|
|
/** Sets a number of the structures values at once.
|
|
|
|
The meanings of each of the parameters is described below, in the appropriate
|
|
member variable's description.
|
|
*/
|
|
void setInfo (const String& shortName,
|
|
const String& description,
|
|
const String& categoryName,
|
|
const int flags) throw();
|
|
|
|
/** An easy way to set or remove the isDisabled bit in the structure's flags field.
|
|
|
|
If isActive is true, the flags member has the isDisabled bit cleared; if isActive
|
|
is false, the bit is set.
|
|
*/
|
|
void setActive (const bool isActive) throw();
|
|
|
|
/** An easy way to set or remove the isTicked bit in the structure's flags field.
|
|
*/
|
|
void setTicked (const bool isTicked) throw();
|
|
|
|
/** Handy method for adding a keypress to the defaultKeypresses array.
|
|
|
|
This is just so you can write things like:
|
|
@code
|
|
myinfo.addDefaultKeypress (T('s'), ModifierKeys::commandModifier);
|
|
@endcode
|
|
instead of
|
|
@code
|
|
myinfo.defaultKeypresses.add (KeyPress (T('s'), ModifierKeys::commandModifier));
|
|
@endcode
|
|
*/
|
|
void addDefaultKeypress (const int keyCode,
|
|
const ModifierKeys& modifiers) throw();
|
|
|
|
/** The command's unique ID number.
|
|
*/
|
|
CommandID commandID;
|
|
|
|
/** A short name to describe the command.
|
|
|
|
This should be suitable for use in menus, on buttons that trigger the command, etc.
|
|
|
|
You can use the setInfo() method to quickly set this and some of the command's
|
|
other properties.
|
|
*/
|
|
String shortName;
|
|
|
|
/** A longer description of the command.
|
|
|
|
This should be suitable for use in contexts such as a KeyMappingEditorComponent or
|
|
pop-up tooltip describing what the command does.
|
|
|
|
You can use the setInfo() method to quickly set this and some of the command's
|
|
other properties.
|
|
*/
|
|
String description;
|
|
|
|
/** A named category that the command fits into.
|
|
|
|
You can give your commands any category you like, and these will be displayed in
|
|
contexts such as the KeyMappingEditorComponent, where the category is used to group
|
|
commands together.
|
|
|
|
You can use the setInfo() method to quickly set this and some of the command's
|
|
other properties.
|
|
*/
|
|
String categoryName;
|
|
|
|
/** A list of zero or more keypresses that should be used as the default keys for
|
|
this command.
|
|
|
|
Methods such as KeyPressMappingSet::resetToDefaultMappings() will use the keypresses in
|
|
this list to initialise the default set of key-to-command mappings.
|
|
|
|
@see addDefaultKeypress
|
|
*/
|
|
Array <KeyPress> defaultKeypresses;
|
|
|
|
/** Flags describing the ways in which this command should be used.
|
|
|
|
A bitwise-OR of these values is stored in the ApplicationCommandInfo::flags
|
|
variable.
|
|
*/
|
|
enum CommandFlags
|
|
{
|
|
/** Indicates that the command can't currently be performed.
|
|
|
|
The ApplicationCommandTarget::getCommandInfo() method must set this flag if it's
|
|
not currently permissable to perform the command. If the flag is set, then
|
|
components that trigger the command, e.g. PopupMenu, may choose to grey-out the
|
|
command or show themselves as not being enabled.
|
|
|
|
@see ApplicationCommandInfo::setActive
|
|
*/
|
|
isDisabled = 1 << 0,
|
|
|
|
/** Indicates that the command should have a tick next to it on a menu.
|
|
|
|
If your command is shown on a menu and this is set, it'll show a tick next to
|
|
it. Other components such as buttons may also use this flag to indicate that it
|
|
is a value that can be toggled, and is currently in the 'on' state.
|
|
|
|
@see ApplicationCommandInfo::setTicked
|
|
*/
|
|
isTicked = 1 << 1,
|
|
|
|
/** If this flag is present, then when a KeyPressMappingSet invokes the command,
|
|
it will call the command twice, once on key-down and again on key-up.
|
|
|
|
@see ApplicationCommandTarget::InvocationInfo
|
|
*/
|
|
wantsKeyUpDownCallbacks = 1 << 2,
|
|
|
|
/** If this flag is present, then a KeyMappingEditorComponent will not display the
|
|
command in its list.
|
|
*/
|
|
hiddenFromKeyEditor = 1 << 3,
|
|
|
|
/** If this flag is present, then a KeyMappingEditorComponent will display the
|
|
command in its list, but won't allow the assigned keypress to be changed.
|
|
*/
|
|
readOnlyInKeyEditor = 1 << 4,
|
|
|
|
/** If this flag is present and the command is invoked from a keypress, then any
|
|
buttons or menus that are also connected to the command will not flash to
|
|
indicate that they've been triggered.
|
|
*/
|
|
dontTriggerVisualFeedback = 1 << 5
|
|
};
|
|
|
|
/** A bitwise-OR of the values specified in the CommandFlags enum.
|
|
|
|
You can use the setInfo() method to quickly set this and some of the command's
|
|
other properties.
|
|
*/
|
|
int flags;
|
|
};
|
|
|
|
#endif // __JUCE_APPLICATIONCOMMANDINFO_JUCEHEADER__
|
|
/********* End of inlined file: juce_ApplicationCommandInfo.h *********/
|
|
|
|
/**
|
|
A command target publishes a list of command IDs that it can perform.
|
|
|
|
An ApplicationCommandManager despatches commands to targets, which must be
|
|
able to provide information about what commands they can handle.
|
|
|
|
To create a target, you'll need to inherit from this class, implementing all of
|
|
its pure virtual methods.
|
|
|
|
For info about how a target is chosen to receive a command, see
|
|
ApplicationCommandManager::getFirstCommandTarget().
|
|
|
|
@see ApplicationCommandManager, ApplicationCommandInfo
|
|
*/
|
|
class JUCE_API ApplicationCommandTarget
|
|
{
|
|
public:
|
|
|
|
/** Creates a command target. */
|
|
ApplicationCommandTarget();
|
|
|
|
/** Destructor. */
|
|
virtual ~ApplicationCommandTarget();
|
|
|
|
/**
|
|
*/
|
|
struct JUCE_API InvocationInfo
|
|
{
|
|
|
|
InvocationInfo (const CommandID commandID) throw();
|
|
|
|
/** The UID of the command that should be performed. */
|
|
CommandID commandID;
|
|
|
|
/** The command's flags.
|
|
|
|
See ApplicationCommandInfo for a description of these flag values.
|
|
*/
|
|
int commandFlags;
|
|
|
|
/** The types of context in which the command might be called. */
|
|
enum InvocationMethod
|
|
{
|
|
direct = 0, /**< The command is being invoked directly by a piece of code. */
|
|
fromKeyPress, /**< The command is being invoked by a key-press. */
|
|
fromMenu, /**< The command is being invoked by a menu selection. */
|
|
fromButton /**< The command is being invoked by a button click. */
|
|
};
|
|
|
|
/** The type of event that triggered this command. */
|
|
InvocationMethod invocationMethod;
|
|
|
|
/** If triggered by a keypress or menu, this will be the component that had the
|
|
keyboard focus at the time.
|
|
|
|
If triggered by a button, it may be set to that component, or it may be null.
|
|
*/
|
|
Component* originatingComponent;
|
|
|
|
/** The keypress that was used to invoke it.
|
|
|
|
Note that this will be an invalid keypress if the command was invoked
|
|
by some other means than a keyboard shortcut.
|
|
*/
|
|
KeyPress keyPress;
|
|
|
|
/** True if the callback is being invoked when the key is pressed,
|
|
false if the key is being released.
|
|
|
|
@see KeyPressMappingSet::addCommand()
|
|
*/
|
|
bool isKeyDown;
|
|
|
|
/** If the key is being released, this indicates how long it had been held
|
|
down for.
|
|
|
|
(Only relevant if isKeyDown is false.)
|
|
*/
|
|
int millisecsSinceKeyPressed;
|
|
};
|
|
|
|
/** This must return the next target to try after this one.
|
|
|
|
When a command is being sent, and the first target can't handle
|
|
that command, this method is used to determine the next target that should
|
|
be tried.
|
|
|
|
It may return 0 if it doesn't know of another target.
|
|
|
|
If your target is a Component, you would usually use the findFirstTargetParentComponent()
|
|
method to return a parent component that might want to handle it.
|
|
|
|
@see invoke
|
|
*/
|
|
virtual ApplicationCommandTarget* getNextCommandTarget() = 0;
|
|
|
|
/** This must return a complete list of commands that this target can handle.
|
|
|
|
Your target should add all the command IDs that it handles to the array that is
|
|
passed-in.
|
|
*/
|
|
virtual void getAllCommands (Array <CommandID>& commands) = 0;
|
|
|
|
/** This must provide details about one of the commands that this target can perform.
|
|
|
|
This will be called with one of the command IDs that the target provided in its
|
|
getAllCommands() methods.
|
|
|
|
It should fill-in all appropriate fields of the ApplicationCommandInfo structure with
|
|
suitable information about the command. (The commandID field will already have been filled-in
|
|
by the caller).
|
|
|
|
The easiest way to set the info is using the ApplicationCommandInfo::setInfo() method to
|
|
set all the fields at once.
|
|
|
|
If the command is currently inactive for some reason, this method must use
|
|
ApplicationCommandInfo::setActive() to make that clear, (or it should set the isDisabled
|
|
bit of the ApplicationCommandInfo::flags field).
|
|
|
|
Any default key-presses for the command should be appended to the
|
|
ApplicationCommandInfo::defaultKeypresses field.
|
|
|
|
Note that if you change something that affects the status of the commands
|
|
that would be returned by this method (e.g. something that makes some commands
|
|
active or inactive), you should call ApplicationCommandManager::commandStatusChanged()
|
|
to cause the manager to refresh its status.
|
|
*/
|
|
virtual void getCommandInfo (const CommandID commandID,
|
|
ApplicationCommandInfo& result) = 0;
|
|
|
|
/** This must actually perform the specified command.
|
|
|
|
If this target is able to perform the command specified by the commandID field of the
|
|
InvocationInfo structure, then it should do so, and must return true.
|
|
|
|
If it can't handle this command, it should return false, which tells the caller to pass
|
|
the command on to the next target in line.
|
|
|
|
@see invoke, ApplicationCommandManager::invoke
|
|
*/
|
|
virtual bool perform (const InvocationInfo& info) = 0;
|
|
|
|
/** Makes this target invoke a command.
|
|
|
|
Your code can call this method to invoke a command on this target, but normally
|
|
you'd call it indirectly via ApplicationCommandManager::invoke() or
|
|
ApplicationCommandManager::invokeDirectly().
|
|
|
|
If this target can perform the given command, it will call its perform() method to
|
|
do so. If not, then getNextCommandTarget() will be used to determine the next target
|
|
to try, and the command will be passed along to it.
|
|
|
|
@param invocationInfo this must be correctly filled-in, describing the context for
|
|
the invocation.
|
|
@param asynchronously if false, the command will be performed before this method returns.
|
|
If true, a message will be posted so that the command will be performed
|
|
later on the message thread, and this method will return immediately.
|
|
@see perform, ApplicationCommandManager::invoke
|
|
*/
|
|
bool invoke (const InvocationInfo& invocationInfo,
|
|
const bool asynchronously);
|
|
|
|
/** Invokes a given command directly on this target.
|
|
|
|
This is just an easy way to call invoke() without having to fill out the InvocationInfo
|
|
structure.
|
|
*/
|
|
bool invokeDirectly (const CommandID commandID,
|
|
const bool asynchronously);
|
|
|
|
/** Searches this target and all subsequent ones for the first one that can handle
|
|
the specified command.
|
|
|
|
This will use getNextCommandTarget() to determine the chain of targets to try
|
|
after this one.
|
|
*/
|
|
ApplicationCommandTarget* getTargetForCommand (const CommandID commandID);
|
|
|
|
/** Checks whether this command can currently be performed by this target.
|
|
|
|
This will return true only if a call to getCommandInfo() doesn't set the
|
|
isDisabled flag to indicate that the command is inactive.
|
|
*/
|
|
bool isCommandActive (const CommandID commandID);
|
|
|
|
/** If this object is a Component, this method will seach upwards in its current
|
|
UI hierarchy for the next parent component that implements the
|
|
ApplicationCommandTarget class.
|
|
|
|
If your target is a Component, this is a very handy method to use in your
|
|
getNextCommandTarget() implementation.
|
|
*/
|
|
ApplicationCommandTarget* findFirstTargetParentComponent();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
// (for async invocation of commands)
|
|
class CommandTargetMessageInvoker : public MessageListener
|
|
{
|
|
public:
|
|
CommandTargetMessageInvoker (ApplicationCommandTarget* const owner);
|
|
~CommandTargetMessageInvoker();
|
|
|
|
void handleMessage (const Message& message);
|
|
|
|
private:
|
|
ApplicationCommandTarget* const owner;
|
|
|
|
CommandTargetMessageInvoker (const CommandTargetMessageInvoker&);
|
|
const CommandTargetMessageInvoker& operator= (const CommandTargetMessageInvoker&);
|
|
};
|
|
|
|
CommandTargetMessageInvoker* messageInvoker;
|
|
|
|
friend class CommandTargetMessageInvoker;
|
|
bool tryToInvoke (const InvocationInfo& info, const bool async);
|
|
};
|
|
|
|
#endif // __JUCE_APPLICATIONCOMMANDTARGET_JUCEHEADER__
|
|
/********* End of inlined file: juce_ApplicationCommandTarget.h *********/
|
|
|
|
/********* Start of inlined file: juce_ActionListener.h *********/
|
|
#ifndef __JUCE_ACTIONLISTENER_JUCEHEADER__
|
|
#define __JUCE_ACTIONLISTENER_JUCEHEADER__
|
|
|
|
/**
|
|
Receives callbacks to indicate that some kind of event has occurred.
|
|
|
|
Used by various classes, e.g. buttons when they are pressed, to tell listeners
|
|
about something that's happened.
|
|
|
|
@see ActionListenerList, ActionBroadcaster, ChangeListener
|
|
*/
|
|
class JUCE_API ActionListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~ActionListener() {}
|
|
|
|
/** Overridden by your subclass to receive the callback.
|
|
|
|
@param message the string that was specified when the event was triggered
|
|
by a call to ActionListenerList::sendActionMessage()
|
|
*/
|
|
virtual void actionListenerCallback (const String& message) = 0;
|
|
};
|
|
|
|
#endif // __JUCE_ACTIONLISTENER_JUCEHEADER__
|
|
/********* End of inlined file: juce_ActionListener.h *********/
|
|
|
|
/**
|
|
An instance of this class is used to specify initialisation and shutdown
|
|
code for the application.
|
|
|
|
An application that wants to run in the JUCE framework needs to declare a
|
|
subclass of JUCEApplication and implement its various pure virtual methods.
|
|
|
|
It then needs to use the START_JUCE_APPLICATION macro somewhere in a cpp file
|
|
to declare an instance of this class and generate a suitable platform-specific
|
|
main() function.
|
|
|
|
e.g. @code
|
|
class MyJUCEApp : public JUCEApplication
|
|
{
|
|
// NEVER put objects inside a JUCEApplication class - only use pointers to
|
|
// objects, which you must create in the initialise() method.
|
|
MyApplicationWindow* myMainWindow;
|
|
|
|
public:
|
|
MyJUCEApp()
|
|
: myMainWindow (0)
|
|
{
|
|
// never create any Juce objects in the constructor - do all your initialisation
|
|
// in the initialise() method.
|
|
}
|
|
|
|
~MyJUCEApp()
|
|
{
|
|
// all your shutdown code must have already been done in the shutdown() method -
|
|
// nothing should happen in this destructor.
|
|
}
|
|
|
|
void initialise (const String& commandLine)
|
|
{
|
|
myMainWindow = new MyApplicationWindow();
|
|
myMainWindow->setBounds (100, 100, 400, 500);
|
|
myMainWindow->setVisible (true);
|
|
}
|
|
|
|
void shutdown()
|
|
{
|
|
delete myMainWindow;
|
|
}
|
|
|
|
const String getApplicationName()
|
|
{
|
|
return T("Super JUCE-o-matic");
|
|
}
|
|
|
|
const String getApplicationVersion()
|
|
{
|
|
return T("1.0");
|
|
}
|
|
};
|
|
|
|
// this creates wrapper code to actually launch the app properly.
|
|
START_JUCE_APPLICATION (MyJUCEApp)
|
|
@endcode
|
|
|
|
Because this object will be created before Juce has properly initialised, you must
|
|
NEVER add any member variable objects that will be automatically constructed. Likewise
|
|
don't put ANY code in the constructor that could call Juce functions. Any objects that
|
|
you want to add to the class must be pointers, which you should instantiate during the
|
|
initialise() method, and delete in the shutdown() method.
|
|
|
|
@see MessageManager, DeletedAtShutdown
|
|
*/
|
|
class JUCE_API JUCEApplication : public ApplicationCommandTarget,
|
|
private ActionListener
|
|
{
|
|
protected:
|
|
|
|
/** Constructs a JUCE app object.
|
|
|
|
If subclasses implement a constructor or destructor, they shouldn't call any
|
|
JUCE code in there - put your startup/shutdown code in initialise() and
|
|
shutdown() instead.
|
|
*/
|
|
JUCEApplication();
|
|
|
|
public:
|
|
/** Destructor.
|
|
|
|
If subclasses implement a constructor or destructor, they shouldn't call any
|
|
JUCE code in there - put your startup/shutdown code in initialise() and
|
|
shutdown() instead.
|
|
*/
|
|
virtual ~JUCEApplication();
|
|
|
|
/** Returns the global instance of the application object being run. */
|
|
static JUCEApplication* getInstance() throw();
|
|
|
|
/** Called when the application starts.
|
|
|
|
This will be called once to let the application do whatever initialisation
|
|
it needs, create its windows, etc.
|
|
|
|
After the method returns, the normal event-dispatch loop will be run,
|
|
until the quit() method is called, at which point the shutdown()
|
|
method will be called to let the application clear up anything it needs
|
|
to delete.
|
|
|
|
If during the initialise() method, the application decides not to start-up
|
|
after all, it can just call the quit() method and the event loop won't be run.
|
|
|
|
@param commandLineParameters the line passed in does not include the
|
|
name of the executable, just the parameter list.
|
|
@see shutdown, quit
|
|
*/
|
|
virtual void initialise (const String& commandLineParameters) = 0;
|
|
|
|
/** Returns true if the application hasn't yet completed its initialise() method
|
|
and entered the main event loop.
|
|
|
|
This is handy for things like splash screens to know when the app's up-and-running
|
|
properly.
|
|
*/
|
|
bool isInitialising() const throw();
|
|
|
|
/* Called to allow the application to clear up before exiting.
|
|
|
|
After JUCEApplication::quit() has been called, the event-dispatch loop will
|
|
terminate, and this method will get called to allow the app to sort itself
|
|
out.
|
|
|
|
Be careful that nothing happens in this method that might rely on messages
|
|
being sent, or any kind of window activity, because the message loop is no
|
|
longer running at this point.
|
|
|
|
@see DeletedAtShutdown
|
|
*/
|
|
virtual void shutdown() = 0;
|
|
|
|
/** Returns the application's name.
|
|
|
|
An application must implement this to name itself.
|
|
*/
|
|
virtual const String getApplicationName() = 0;
|
|
|
|
/** Returns the application's version number.
|
|
|
|
An application can implement this to give itself a version.
|
|
(The default implementation of this just returns an empty string).
|
|
*/
|
|
virtual const String getApplicationVersion();
|
|
|
|
/** Checks whether multiple instances of the app are allowed.
|
|
|
|
If you application class returns true for this, more than one instance is
|
|
permitted to run (except on the Mac where this isn't possible).
|
|
|
|
If it's false, the second instance won't start, but it you will still get a
|
|
callback to anotherInstanceStarted() to tell you about this - which
|
|
gives you a chance to react to what the user was trying to do.
|
|
*/
|
|
virtual bool moreThanOneInstanceAllowed();
|
|
|
|
/** Indicates that the user has tried to start up another instance of the app.
|
|
|
|
This will get called even if moreThanOneInstanceAllowed() is false.
|
|
*/
|
|
virtual void anotherInstanceStarted (const String& commandLine);
|
|
|
|
/** Called when the operating system is trying to close the application.
|
|
|
|
The default implementation of this method is to call quit(), but it may
|
|
be overloaded to ignore the request or do some other special behaviour
|
|
instead. For example, you might want to offer the user the chance to save
|
|
their changes before quitting, and give them the chance to cancel.
|
|
|
|
If you want to send a quit signal to your app, this is the correct method
|
|
to call, because it means that requests that come from the system get handled
|
|
in the same way as those from your own application code. So e.g. you'd
|
|
call this method from a "quit" item on a menu bar.
|
|
*/
|
|
virtual void systemRequestedQuit();
|
|
|
|
/** If any unhandled exceptions make it through to the message dispatch loop, this
|
|
callback will be triggered, in case you want to log them or do some other
|
|
type of error-handling.
|
|
|
|
If the type of exception is derived from the std::exception class, the pointer
|
|
passed-in will be valid. If the exception is of unknown type, this pointer
|
|
will be null.
|
|
*/
|
|
virtual void unhandledException (const std::exception* e,
|
|
const String& sourceFilename,
|
|
const int lineNumber);
|
|
|
|
/** Signals that the main message loop should stop and the application should terminate.
|
|
|
|
This isn't synchronous, it just posts a quit message to the main queue, and
|
|
when this message arrives, the message loop will stop, the shutdown() method
|
|
will be called, and the app will exit.
|
|
|
|
Note that this will cause an unconditional quit to happen, so if you need an
|
|
extra level before this, e.g. to give the user the chance to save their work
|
|
and maybe cancel the quit, you'll need to handle this in the systemRequestedQuit()
|
|
method - see that method's help for more info.
|
|
|
|
@see MessageManager, DeletedAtShutdown
|
|
*/
|
|
static void quit();
|
|
|
|
/** Sets the value that should be returned as the application's exit code when the
|
|
app quits.
|
|
|
|
This is the value that's returned by the main() function. Normally you'd leave this
|
|
as 0 unless you want to indicate an error code.
|
|
|
|
@see getApplicationReturnValue
|
|
*/
|
|
void setApplicationReturnValue (const int newReturnValue) throw();
|
|
|
|
/** Returns the value that has been set as the application's exit code.
|
|
@see setApplicationReturnValue
|
|
*/
|
|
int getApplicationReturnValue() const throw() { return appReturnValue; }
|
|
|
|
/** Returns the application's command line params.
|
|
*/
|
|
const String getCommandLineParameters() const throw() { return commandLineParameters; }
|
|
|
|
// These are used by the START_JUCE_APPLICATION() macro and aren't for public use.
|
|
|
|
/** @internal */
|
|
static int main (String& commandLine, JUCEApplication* const newApp);
|
|
/** @internal */
|
|
static int main (int argc, char* argv[], JUCEApplication* const newApp);
|
|
|
|
/** @internal */
|
|
static void sendUnhandledException (const std::exception* const e,
|
|
const char* const sourceFile,
|
|
const int lineNumber);
|
|
|
|
/** @internal */
|
|
ApplicationCommandTarget* getNextCommandTarget();
|
|
/** @internal */
|
|
void getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result);
|
|
/** @internal */
|
|
void getAllCommands (Array <CommandID>& commands);
|
|
/** @internal */
|
|
bool perform (const InvocationInfo& info);
|
|
/** @internal */
|
|
void actionListenerCallback (const String& message);
|
|
|
|
private:
|
|
|
|
String commandLineParameters;
|
|
int appReturnValue;
|
|
bool stillInitialising;
|
|
|
|
static int shutdownAppAndClearUp();
|
|
};
|
|
|
|
#endif // __JUCE_APPLICATION_JUCEHEADER__
|
|
/********* End of inlined file: juce_Application.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_APPLICATIONCOMMANDID_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_APPLICATIONCOMMANDINFO_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_APPLICATIONCOMMANDMANAGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ApplicationCommandManager.h *********/
|
|
#ifndef __JUCE_APPLICATIONCOMMANDMANAGER_JUCEHEADER__
|
|
#define __JUCE_APPLICATIONCOMMANDMANAGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AsyncUpdater.h *********/
|
|
#ifndef __JUCE_ASYNCUPDATER_JUCEHEADER__
|
|
#define __JUCE_ASYNCUPDATER_JUCEHEADER__
|
|
|
|
/**
|
|
Has a callback method that is triggered asynchronously.
|
|
|
|
This object allows an asynchronous callback function to be triggered, for
|
|
tasks such as coalescing multiple updates into a single callback later on.
|
|
|
|
Basically, one or more calls to the triggerAsyncUpdate() will result in the
|
|
message thread calling handleAsyncUpdate() as soon as it can.
|
|
*/
|
|
class JUCE_API AsyncUpdater
|
|
{
|
|
public:
|
|
|
|
/** Creates an AsyncUpdater object. */
|
|
AsyncUpdater() throw();
|
|
|
|
/** Destructor.
|
|
|
|
If there are any pending callbacks when the object is deleted, these are lost.
|
|
*/
|
|
virtual ~AsyncUpdater();
|
|
|
|
/** Causes the callback to be triggered at a later time.
|
|
|
|
This method returns immediately, having made sure that a callback
|
|
to the handleAsyncUpdate() method will occur as soon as possible.
|
|
|
|
If an update callback is already pending but hasn't happened yet, calls
|
|
to this method will be ignored.
|
|
|
|
It's thread-safe to call this method from any number of threads without
|
|
needing to worry about locking.
|
|
*/
|
|
void triggerAsyncUpdate() throw();
|
|
|
|
/** This will stop any pending updates from happening.
|
|
|
|
If called after triggerAsyncUpdate() and before the handleAsyncUpdate()
|
|
callback happens, this will cancel the handleAsyncUpdate() callback.
|
|
*/
|
|
void cancelPendingUpdate() throw();
|
|
|
|
/** If an update has been triggered and is pending, this will invoke it
|
|
synchronously.
|
|
|
|
Use this as a kind of "flush" operation - if an update is pending, the
|
|
handleAsyncUpdate() method will be called immediately; if no update is
|
|
pending, then nothing will be done.
|
|
*/
|
|
void handleUpdateNowIfNeeded();
|
|
|
|
/** Called back to do whatever your class needs to do.
|
|
|
|
This method is called by the message thread at the next convenient time
|
|
after the triggerAsyncUpdate() method has been called.
|
|
*/
|
|
virtual void handleAsyncUpdate() = 0;
|
|
|
|
private:
|
|
|
|
class AsyncUpdaterInternal : public MessageListener
|
|
{
|
|
public:
|
|
AsyncUpdaterInternal() throw() {}
|
|
~AsyncUpdaterInternal() {}
|
|
|
|
void handleMessage (const Message&);
|
|
|
|
AsyncUpdater* owner;
|
|
|
|
private:
|
|
AsyncUpdaterInternal (const AsyncUpdaterInternal&);
|
|
const AsyncUpdaterInternal& operator= (const AsyncUpdaterInternal&);
|
|
};
|
|
|
|
AsyncUpdaterInternal internalAsyncHandler;
|
|
bool asyncMessagePending;
|
|
};
|
|
|
|
#endif // __JUCE_ASYNCUPDATER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AsyncUpdater.h *********/
|
|
|
|
/********* Start of inlined file: juce_Desktop.h *********/
|
|
#ifndef __JUCE_DESKTOP_JUCEHEADER__
|
|
#define __JUCE_DESKTOP_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DeletedAtShutdown.h *********/
|
|
#ifndef __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__
|
|
#define __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__
|
|
|
|
/**
|
|
Classes derived from this will be automatically deleted when the application exits.
|
|
|
|
After JUCEApplication::shutdown() has been called, any objects derived from
|
|
DeletedAtShutdown which are still in existence will be deleted in the reverse
|
|
order to that in which they were created.
|
|
|
|
So if you've got a singleton and don't want to have to explicitly delete it, just
|
|
inherit from this and it'll be taken care of.
|
|
*/
|
|
class JUCE_API DeletedAtShutdown
|
|
{
|
|
protected:
|
|
/** Creates a DeletedAtShutdown object. */
|
|
DeletedAtShutdown() throw();
|
|
|
|
/** Destructor.
|
|
|
|
It's ok to delete these objects explicitly - it's only the ones left
|
|
dangling at the end that will be deleted automatically.
|
|
*/
|
|
virtual ~DeletedAtShutdown();
|
|
|
|
public:
|
|
/** Deletes all extant objects.
|
|
|
|
This shouldn't be used by applications, as it's called automatically
|
|
in the shutdown code of the JUCEApplication class.
|
|
*/
|
|
static void deleteAll();
|
|
|
|
private:
|
|
DeletedAtShutdown (const DeletedAtShutdown&);
|
|
const DeletedAtShutdown& operator= (const DeletedAtShutdown&);
|
|
};
|
|
|
|
#endif // __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__
|
|
/********* End of inlined file: juce_DeletedAtShutdown.h *********/
|
|
|
|
/********* Start of inlined file: juce_Timer.h *********/
|
|
#ifndef __JUCE_TIMER_JUCEHEADER__
|
|
#define __JUCE_TIMER_JUCEHEADER__
|
|
|
|
class InternalTimerThread;
|
|
|
|
/**
|
|
Repeatedly calls a user-defined method at a specified time interval.
|
|
|
|
A Timer's timerCallback() method will be repeatedly called at a given
|
|
interval. Initially when a Timer object is created, they will do nothing
|
|
until the startTimer() method is called, then the message thread will
|
|
start calling it back until stopTimer() is called.
|
|
|
|
The time interval isn't guaranteed to be precise to any more than maybe
|
|
10-20ms, and the intervals may end up being much longer than requested if the
|
|
system is busy. Because it's the message thread that is doing the callbacks,
|
|
any messages that take a significant amount of time to process will block
|
|
all the timers for that period.
|
|
|
|
If you need to have a single callback that is shared by multiple timers with
|
|
different frequencies, then the MultiTimer class allows you to do that - its
|
|
structure is very similar to the Timer class, but contains multiple timers
|
|
internally, each one identified by an ID number.
|
|
|
|
@see MultiTimer
|
|
*/
|
|
class JUCE_API Timer
|
|
{
|
|
protected:
|
|
|
|
/** Creates a Timer.
|
|
|
|
When created, the timer is stopped, so use startTimer() to get it going.
|
|
*/
|
|
Timer() throw();
|
|
|
|
/** Creates a copy of another timer.
|
|
|
|
Note that this timer won't be started, even if the one you're copying
|
|
is running.
|
|
*/
|
|
Timer (const Timer& other) throw();
|
|
|
|
public:
|
|
|
|
/** Destructor. */
|
|
virtual ~Timer();
|
|
|
|
/** The user-defined callback routine that actually gets called periodically.
|
|
|
|
It's perfectly ok to call startTimer() or stopTimer() from within this
|
|
callback to change the subsequent intervals.
|
|
*/
|
|
virtual void timerCallback() = 0;
|
|
|
|
/** Starts the timer and sets the length of interval required.
|
|
|
|
If the timer is already started, this will reset it, so the
|
|
time between calling this method and the next timer callback
|
|
will not be less than the interval length passed in.
|
|
|
|
@param intervalInMilliseconds the interval to use (any values less than 1 will be
|
|
rounded up to 1)
|
|
*/
|
|
void startTimer (const int intervalInMilliseconds) throw();
|
|
|
|
/** Stops the timer.
|
|
|
|
No more callbacks will be made after this method returns.
|
|
|
|
If this is called from a different thread, any callbacks that may
|
|
be currently executing may be allowed to finish before the method
|
|
returns.
|
|
*/
|
|
void stopTimer() throw();
|
|
|
|
/** Checks if the timer has been started.
|
|
|
|
@returns true if the timer is running.
|
|
*/
|
|
bool isTimerRunning() const throw() { return periodMs > 0; }
|
|
|
|
/** Returns the timer's interval.
|
|
|
|
@returns the timer's interval in milliseconds if it's running, or 0 if it's not.
|
|
*/
|
|
int getTimerInterval() const throw() { return periodMs; }
|
|
|
|
private:
|
|
friend class InternalTimerThread;
|
|
int countdownMs, periodMs;
|
|
Timer* previous;
|
|
Timer* next;
|
|
|
|
const Timer& operator= (const Timer&);
|
|
};
|
|
|
|
#endif // __JUCE_TIMER_JUCEHEADER__
|
|
/********* End of inlined file: juce_Timer.h *********/
|
|
|
|
/**
|
|
Classes can implement this interface and register themselves with the Desktop class
|
|
to receive callbacks when the currently focused component changes.
|
|
|
|
@see Desktop::addFocusChangeListener, Desktop::removeFocusChangeListener
|
|
*/
|
|
class JUCE_API FocusChangeListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~FocusChangeListener() {}
|
|
|
|
/** Callback to indicate that the currently focused component has changed. */
|
|
virtual void globalFocusChanged (Component* focusedComponent) = 0;
|
|
};
|
|
|
|
/**
|
|
Describes and controls aspects of the computer's desktop.
|
|
|
|
*/
|
|
class JUCE_API Desktop : private DeletedAtShutdown,
|
|
private Timer,
|
|
private AsyncUpdater
|
|
{
|
|
public:
|
|
|
|
/** There's only one dektop object, and this method will return it.
|
|
*/
|
|
static Desktop& JUCE_CALLTYPE getInstance() throw();
|
|
|
|
/** Returns a list of the positions of all the monitors available.
|
|
|
|
The first rectangle in the list will be the main monitor area.
|
|
|
|
If clippedToWorkArea is true, it will exclude any areas like the taskbar on Windows,
|
|
or the menu bar on Mac. If clippedToWorkArea is false, the entire monitor area is returned.
|
|
*/
|
|
const RectangleList getAllMonitorDisplayAreas (const bool clippedToWorkArea = true) const throw();
|
|
|
|
/** Returns the position and size of the main monitor.
|
|
|
|
If clippedToWorkArea is true, it will exclude any areas like the taskbar on Windows,
|
|
or the menu bar on Mac. If clippedToWorkArea is false, the entire monitor area is returned.
|
|
*/
|
|
const Rectangle getMainMonitorArea (const bool clippedToWorkArea = true) const throw();
|
|
|
|
/** Returns the position and size of the monitor which contains this co-ordinate.
|
|
|
|
If none of the monitors contains the point, this will just return the
|
|
main monitor.
|
|
|
|
If clippedToWorkArea is true, it will exclude any areas like the taskbar on Windows,
|
|
or the menu bar on Mac. If clippedToWorkArea is false, the entire monitor area is returned.
|
|
*/
|
|
const Rectangle getMonitorAreaContaining (int x, int y, const bool clippedToWorkArea = true) const throw();
|
|
|
|
/** Returns the mouse position.
|
|
|
|
The co-ordinates are relative to the top-left of the main monitor.
|
|
*/
|
|
static void getMousePosition (int& x, int& y) throw();
|
|
|
|
/** Makes the mouse pointer jump to a given location.
|
|
|
|
The co-ordinates are relative to the top-left of the main monitor.
|
|
*/
|
|
static void setMousePosition (int x, int y) throw();
|
|
|
|
/** Returns the last position at which a mouse button was pressed.
|
|
*/
|
|
static void getLastMouseDownPosition (int& x, int& y) throw();
|
|
|
|
/** Returns the number of times the mouse button has been clicked since the
|
|
app started.
|
|
|
|
Each mouse-down event increments this number by 1.
|
|
*/
|
|
static int getMouseButtonClickCounter() throw();
|
|
|
|
/** This lets you prevent the screensaver from becoming active.
|
|
|
|
Handy if you're running some sort of presentation app where having a screensaver
|
|
appear would be annoying.
|
|
|
|
Pass false to disable the screensaver, and true to re-enable it. (Note that this
|
|
won't enable a screensaver unless the user has actually set one up).
|
|
|
|
The disablement will only happen while the Juce application is the foreground
|
|
process - if another task is running in front of it, then the screensaver will
|
|
be unaffected.
|
|
|
|
@see isScreenSaverEnabled
|
|
*/
|
|
static void setScreenSaverEnabled (const bool isEnabled) throw();
|
|
|
|
/** Returns true if the screensaver has not been turned off.
|
|
|
|
This will return the last value passed into setScreenSaverEnabled(). Note that
|
|
it won't tell you whether the user is actually using a screen saver, just
|
|
whether this app is deliberately preventing one from running.
|
|
|
|
@see setScreenSaverEnabled
|
|
*/
|
|
static bool isScreenSaverEnabled() throw();
|
|
|
|
/** Registers a MouseListener that will receive all mouse events that occur on
|
|
any component.
|
|
|
|
@see removeGlobalMouseListener
|
|
*/
|
|
void addGlobalMouseListener (MouseListener* const listener) throw();
|
|
|
|
/** Unregisters a MouseListener that was added with the addGlobalMouseListener()
|
|
method.
|
|
|
|
@see addGlobalMouseListener
|
|
*/
|
|
void removeGlobalMouseListener (MouseListener* const listener) throw();
|
|
|
|
/** Registers a MouseListener that will receive a callback whenever the focused
|
|
component changes.
|
|
*/
|
|
void addFocusChangeListener (FocusChangeListener* const listener) throw();
|
|
|
|
/** Unregisters a listener that was added with addFocusChangeListener(). */
|
|
void removeFocusChangeListener (FocusChangeListener* const listener) throw();
|
|
|
|
/** Takes a component and makes it full-screen, removing the taskbar, dock, etc.
|
|
|
|
The component must already be on the desktop for this method to work. It will
|
|
be resized to completely fill the screen and any extraneous taskbars, menu bars,
|
|
etc will be hidden.
|
|
|
|
To exit kiosk mode, just call setKioskModeComponent (0). When this is called,
|
|
the component that's currently being used will be resized back to the size
|
|
and position it was in before being put into this mode.
|
|
|
|
If allowMenusAndBars is true, things like the menu and dock (on mac) are still
|
|
allowed to pop up when the mouse moves onto them. If this is false, it'll try
|
|
to hide as much on-screen paraphenalia as possible.
|
|
*/
|
|
void setKioskModeComponent (Component* componentToUse,
|
|
const bool allowMenusAndBars = true);
|
|
|
|
/** Returns the component that is currently being used in kiosk-mode.
|
|
|
|
This is the component that was last set by setKioskModeComponent(). If none
|
|
has been set, this returns 0.
|
|
*/
|
|
Component* getKioskModeComponent() const { return kioskModeComponent; }
|
|
|
|
/** Returns the number of components that are currently active as top-level
|
|
desktop windows.
|
|
|
|
@see getComponent, Component::addToDesktop
|
|
*/
|
|
int getNumComponents() const throw();
|
|
|
|
/** Returns one of the top-level desktop window components.
|
|
|
|
The index is from 0 to getNumComponents() - 1. This could return 0 if the
|
|
index is out-of-range.
|
|
|
|
@see getNumComponents, Component::addToDesktop
|
|
*/
|
|
Component* getComponent (const int index) const throw();
|
|
|
|
/** Finds the component at a given screen location.
|
|
|
|
This will drill down into top-level windows to find the child component at
|
|
the given position.
|
|
|
|
Returns 0 if the co-ordinates are inside a non-Juce window.
|
|
*/
|
|
Component* findComponentAt (const int screenX,
|
|
const int screenY) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
/** Tells this object to refresh its idea of what the screen resolution is.
|
|
|
|
(Called internally by the native code).
|
|
*/
|
|
void refreshMonitorSizes() throw();
|
|
|
|
/** True if the OS supports semitransparent windows */
|
|
static bool canUseSemiTransparentWindows() throw();
|
|
|
|
private:
|
|
|
|
friend class Component;
|
|
friend class ComponentPeer;
|
|
SortedSet <void*> mouseListeners, focusListeners;
|
|
VoidArray desktopComponents;
|
|
|
|
friend class DeletedAtShutdown;
|
|
friend class TopLevelWindowManager;
|
|
Desktop() throw();
|
|
~Desktop() throw();
|
|
|
|
Array <Rectangle> monitorCoordsClipped, monitorCoordsUnclipped;
|
|
int lastMouseX, lastMouseY;
|
|
|
|
Component* kioskModeComponent;
|
|
Rectangle kioskComponentOriginalBounds;
|
|
|
|
void timerCallback();
|
|
void sendMouseMove();
|
|
void resetTimer() throw();
|
|
|
|
int getNumDisplayMonitors() const throw();
|
|
const Rectangle getDisplayMonitorCoordinates (const int index, const bool clippedToWorkArea) const throw();
|
|
|
|
void addDesktopComponent (Component* const c) throw();
|
|
void removeDesktopComponent (Component* const c) throw();
|
|
void componentBroughtToFront (Component* const c) throw();
|
|
|
|
void triggerFocusCallback() throw();
|
|
void handleAsyncUpdate();
|
|
|
|
Desktop (const Desktop&);
|
|
const Desktop& operator= (const Desktop&);
|
|
};
|
|
|
|
#endif // __JUCE_DESKTOP_JUCEHEADER__
|
|
/********* End of inlined file: juce_Desktop.h *********/
|
|
|
|
class KeyPressMappingSet;
|
|
class ApplicationCommandManagerListener;
|
|
|
|
/**
|
|
One of these objects holds a list of all the commands your app can perform,
|
|
and despatches these commands when needed.
|
|
|
|
Application commands are a good way to trigger actions in your app, e.g. "Quit",
|
|
"Copy", "Paste", etc. Menus, buttons and keypresses can all be given commands
|
|
to invoke automatically, which means you don't have to handle the result of a menu
|
|
or button click manually. Commands are despatched to ApplicationCommandTarget objects
|
|
which can choose which events they want to handle.
|
|
|
|
This architecture also allows for nested ApplicationCommandTargets, so that for example
|
|
you could have two different objects, one inside the other, both of which can respond to
|
|
a "delete" command. Depending on which one has focus, the command will be sent to the
|
|
appropriate place, regardless of whether it was triggered by a menu, keypress or some other
|
|
method.
|
|
|
|
To set up your app to use commands, you'll need to do the following:
|
|
|
|
- Create a global ApplicationCommandManager to hold the list of all possible
|
|
commands. (This will also manage a set of key-mappings for them).
|
|
|
|
- Make some of your UI components (or other objects) inherit from ApplicationCommandTarget.
|
|
This allows the object to provide a list of commands that it can perform, and
|
|
to handle them.
|
|
|
|
- Register each type of command using ApplicationCommandManager::registerAllCommandsForTarget(),
|
|
or ApplicationCommandManager::registerCommand().
|
|
|
|
- If you want key-presses to trigger your commands, use the ApplicationCommandManager::getKeyMappings()
|
|
method to access the key-mapper object, which you will need to register as a key-listener
|
|
in whatever top-level component you're using. See the KeyPressMappingSet class for more help
|
|
about setting this up.
|
|
|
|
- Use methods such as PopupMenu::addCommandItem() or Button::setCommandToTrigger() to
|
|
cause these commands to be invoked automatically.
|
|
|
|
- Commands can be invoked directly by your code using ApplicationCommandManager::invokeDirectly().
|
|
|
|
When a command is invoked, the ApplicationCommandManager will try to choose the best
|
|
ApplicationCommandTarget to receive the specified command. To do this it will use the
|
|
current keyboard focus to see which component might be interested, and will search the
|
|
component hierarchy for those that also implement the ApplicationCommandTarget interface.
|
|
If an ApplicationCommandTarget isn't interested in the command that is being invoked, then
|
|
the next one in line will be tried (see the ApplicationCommandTarget::getNextCommandTarget()
|
|
method), and so on until ApplicationCommandTarget::getNextCommandTarget() returns 0. At this
|
|
point if the command still hasn't been performed, it will be passed to the current
|
|
JUCEApplication object (which is itself an ApplicationCommandTarget).
|
|
|
|
To exert some custom control over which ApplicationCommandTarget is chosen to invoke a command,
|
|
you can override the ApplicationCommandManager::getFirstCommandTarget() method and choose
|
|
the object yourself.
|
|
|
|
@see ApplicationCommandTarget, ApplicationCommandInfo
|
|
*/
|
|
class JUCE_API ApplicationCommandManager : private AsyncUpdater,
|
|
private FocusChangeListener
|
|
{
|
|
public:
|
|
|
|
/** Creates an ApplicationCommandManager.
|
|
|
|
Once created, you'll need to register all your app's commands with it, using
|
|
ApplicationCommandManager::registerAllCommandsForTarget() or
|
|
ApplicationCommandManager::registerCommand().
|
|
*/
|
|
ApplicationCommandManager();
|
|
|
|
/** Destructor.
|
|
|
|
Make sure that you don't delete this if pointers to it are still being used by
|
|
objects such as PopupMenus or Buttons.
|
|
*/
|
|
virtual ~ApplicationCommandManager();
|
|
|
|
/** Clears the current list of all commands.
|
|
|
|
Note that this will also clear the contents of the KeyPressMappingSet.
|
|
*/
|
|
void clearCommands();
|
|
|
|
/** Adds a command to the list of registered commands.
|
|
|
|
@see registerAllCommandsForTarget
|
|
*/
|
|
void registerCommand (const ApplicationCommandInfo& newCommand);
|
|
|
|
/** Adds all the commands that this target publishes to the manager's list.
|
|
|
|
This will use ApplicationCommandTarget::getAllCommands() and ApplicationCommandTarget::getCommandInfo()
|
|
to get details about all the commands that this target can do, and will call
|
|
registerCommand() to add each one to the manger's list.
|
|
|
|
@see registerCommand
|
|
*/
|
|
void registerAllCommandsForTarget (ApplicationCommandTarget* target);
|
|
|
|
/** Removes the command with a specified ID.
|
|
|
|
Note that this will also remove any key mappings that are mapped to the command.
|
|
*/
|
|
void removeCommand (const CommandID commandID);
|
|
|
|
/** This should be called to tell the manager that one of its registered commands may have changed
|
|
its active status.
|
|
|
|
Because the command manager only finds out whether a command is active or inactive by querying
|
|
the current ApplicationCommandTarget, this is used to tell it that things may have changed. It
|
|
allows things like buttons to update their enablement, etc.
|
|
|
|
This method will cause an asynchronous call to ApplicationCommandManagerListener::applicationCommandListChanged()
|
|
for any registered listeners.
|
|
*/
|
|
void commandStatusChanged();
|
|
|
|
/** Returns the number of commands that have been registered.
|
|
|
|
@see registerCommand
|
|
*/
|
|
int getNumCommands() const throw() { return commands.size(); }
|
|
|
|
/** Returns the details about one of the registered commands.
|
|
|
|
The index is between 0 and (getNumCommands() - 1).
|
|
*/
|
|
const ApplicationCommandInfo* getCommandForIndex (const int index) const throw() { return commands [index]; }
|
|
|
|
/** Returns the details about a given command ID.
|
|
|
|
This will search the list of registered commands for one with the given command
|
|
ID number, and return its associated info. If no matching command is found, this
|
|
will return 0.
|
|
*/
|
|
const ApplicationCommandInfo* getCommandForID (const CommandID commandID) const throw();
|
|
|
|
/** Returns the name field for a command.
|
|
|
|
An empty string is returned if no command with this ID has been registered.
|
|
@see getDescriptionOfCommand
|
|
*/
|
|
const String getNameOfCommand (const CommandID commandID) const throw();
|
|
|
|
/** Returns the description field for a command.
|
|
|
|
An empty string is returned if no command with this ID has been registered. If the
|
|
command has no description, this will return its short name field instead.
|
|
|
|
@see getNameOfCommand
|
|
*/
|
|
const String getDescriptionOfCommand (const CommandID commandID) const throw();
|
|
|
|
/** Returns the list of categories.
|
|
|
|
This will go through all registered commands, and return a list of all the distict
|
|
categoryName values from their ApplicationCommandInfo structure.
|
|
|
|
@see getCommandsInCategory()
|
|
*/
|
|
const StringArray getCommandCategories() const throw();
|
|
|
|
/** Returns a list of all the command UIDs in a particular category.
|
|
|
|
@see getCommandCategories()
|
|
*/
|
|
const Array <CommandID> getCommandsInCategory (const String& categoryName) const throw();
|
|
|
|
/** Returns the manager's internal set of key mappings.
|
|
|
|
This object can be used to edit the keypresses. To actually link this object up
|
|
to invoke commands when a key is pressed, see the comments for the KeyPressMappingSet
|
|
class.
|
|
|
|
@see KeyPressMappingSet
|
|
*/
|
|
KeyPressMappingSet* getKeyMappings() const throw() { return keyMappings; }
|
|
|
|
/** Invokes the given command directly, sending it to the default target.
|
|
|
|
This is just an easy way to call invoke() without having to fill out the InvocationInfo
|
|
structure.
|
|
*/
|
|
bool invokeDirectly (const CommandID commandID,
|
|
const bool asynchronously);
|
|
|
|
/** Sends a command to the default target.
|
|
|
|
This will choose a target using getFirstCommandTarget(), and send the specified command
|
|
to it using the ApplicationCommandTarget::invoke() method. This means that if the
|
|
first target can't handle the command, it will be passed on to targets further down the
|
|
chain (see ApplicationCommandTarget::invoke() for more info).
|
|
|
|
@param invocationInfo this must be correctly filled-in, describing the context for
|
|
the invocation.
|
|
@param asynchronously if false, the command will be performed before this method returns.
|
|
If true, a message will be posted so that the command will be performed
|
|
later on the message thread, and this method will return immediately.
|
|
|
|
@see ApplicationCommandTarget::invoke
|
|
*/
|
|
bool invoke (const ApplicationCommandTarget::InvocationInfo& invocationInfo,
|
|
const bool asynchronously);
|
|
|
|
/** Chooses the ApplicationCommandTarget to which a command should be sent.
|
|
|
|
Whenever the manager needs to know which target a command should be sent to, it calls
|
|
this method to determine the first one to try.
|
|
|
|
By default, this method will return the target that was set by calling setFirstCommandTarget().
|
|
If no target is set, it will return the result of findDefaultComponentTarget().
|
|
|
|
If you need to make sure all commands go via your own custom target, then you can
|
|
either use setFirstCommandTarget() to specify a single target, or override this method
|
|
if you need more complex logic to choose one.
|
|
|
|
It may return 0 if no targets are available.
|
|
|
|
@see getTargetForCommand, invoke, invokeDirectly
|
|
*/
|
|
virtual ApplicationCommandTarget* getFirstCommandTarget (const CommandID commandID);
|
|
|
|
/** Sets a target to be returned by getFirstCommandTarget().
|
|
|
|
If this is set to 0, then getFirstCommandTarget() will by default return the
|
|
result of findDefaultComponentTarget().
|
|
|
|
If you use this to set a target, make sure you call setFirstCommandTarget (0) before
|
|
deleting the target object.
|
|
*/
|
|
void setFirstCommandTarget (ApplicationCommandTarget* const newTarget) throw();
|
|
|
|
/** Tries to find the best target to use to perform a given command.
|
|
|
|
This will call getFirstCommandTarget() to find the preferred target, and will
|
|
check whether that target can handle the given command. If it can't, then it'll use
|
|
ApplicationCommandTarget::getNextCommandTarget() to find the next one to try, and
|
|
so on until no more are available.
|
|
|
|
If no targets are found that can perform the command, this method will return 0.
|
|
|
|
If a target is found, then it will get the target to fill-in the upToDateInfo
|
|
structure with the latest info about that command, so that the caller can see
|
|
whether the command is disabled, ticked, etc.
|
|
*/
|
|
ApplicationCommandTarget* getTargetForCommand (const CommandID commandID,
|
|
ApplicationCommandInfo& upToDateInfo);
|
|
|
|
/** Registers a listener that will be called when various events occur. */
|
|
void addListener (ApplicationCommandManagerListener* const listener) throw();
|
|
|
|
/** Deregisters a previously-added listener. */
|
|
void removeListener (ApplicationCommandManagerListener* const listener) throw();
|
|
|
|
/** Looks for a suitable command target based on which Components have the keyboard focus.
|
|
|
|
This is used by the default implementation of ApplicationCommandTarget::getFirstCommandTarget(),
|
|
but is exposed here in case it's useful.
|
|
|
|
It tries to pick the best ApplicationCommandTarget by looking at focused components, top level
|
|
windows, etc., and using the findTargetForComponent() method.
|
|
*/
|
|
static ApplicationCommandTarget* findDefaultComponentTarget();
|
|
|
|
/** Examines this component and all its parents in turn, looking for the first one
|
|
which is a ApplicationCommandTarget.
|
|
|
|
Returns the first ApplicationCommandTarget that it finds, or 0 if none of them implement
|
|
that class.
|
|
*/
|
|
static ApplicationCommandTarget* findTargetForComponent (Component* component);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
OwnedArray <ApplicationCommandInfo> commands;
|
|
SortedSet <void*> listeners;
|
|
KeyPressMappingSet* keyMappings;
|
|
ApplicationCommandTarget* firstTarget;
|
|
|
|
void sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo& info) const;
|
|
void handleAsyncUpdate();
|
|
void globalFocusChanged (Component*);
|
|
|
|
// xxx this is just here to cause a compile error in old code that hasn't been changed to use the new
|
|
// version of this method.
|
|
virtual short getFirstCommandTarget() { return 0; }
|
|
};
|
|
|
|
/**
|
|
A listener that receives callbacks from an ApplicationCommandManager when
|
|
commands are invoked or the command list is changed.
|
|
|
|
@see ApplicationCommandManager::addListener, ApplicationCommandManager::removeListener
|
|
|
|
*/
|
|
class JUCE_API ApplicationCommandManagerListener
|
|
{
|
|
public:
|
|
|
|
/** Destructor. */
|
|
virtual ~ApplicationCommandManagerListener() {}
|
|
|
|
/** Called when an app command is about to be invoked. */
|
|
virtual void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info) = 0;
|
|
|
|
/** Called when commands are registered or deregistered from the
|
|
command manager, or when commands are made active or inactive.
|
|
|
|
Note that if you're using this to watch for changes to whether a command is disabled,
|
|
you'll need to make sure that ApplicationCommandManager::commandStatusChanged() is called
|
|
whenever the status of your command might have changed.
|
|
*/
|
|
virtual void applicationCommandListChanged() = 0;
|
|
};
|
|
|
|
#endif // __JUCE_APPLICATIONCOMMANDMANAGER_JUCEHEADER__
|
|
/********* End of inlined file: juce_ApplicationCommandManager.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_APPLICATIONCOMMANDTARGET_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_APPLICATIONPROPERTIES_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ApplicationProperties.h *********/
|
|
#ifndef __JUCE_APPLICATIONPROPERTIES_JUCEHEADER__
|
|
#define __JUCE_APPLICATIONPROPERTIES_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PropertiesFile.h *********/
|
|
#ifndef __JUCE_PROPERTIESFILE_JUCEHEADER__
|
|
#define __JUCE_PROPERTIESFILE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ChangeBroadcaster.h *********/
|
|
#ifndef __JUCE_CHANGEBROADCASTER_JUCEHEADER__
|
|
#define __JUCE_CHANGEBROADCASTER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ChangeListenerList.h *********/
|
|
#ifndef __JUCE_CHANGELISTENERLIST_JUCEHEADER__
|
|
#define __JUCE_CHANGELISTENERLIST_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ChangeListener.h *********/
|
|
#ifndef __JUCE_CHANGELISTENER_JUCEHEADER__
|
|
#define __JUCE_CHANGELISTENER_JUCEHEADER__
|
|
|
|
/**
|
|
Receives callbacks about changes to some kind of object.
|
|
|
|
Many objects use a ChangeListenerList to keep a set of listeners which they
|
|
will inform when something changes. A subclass of ChangeListener
|
|
is used to receive these callbacks.
|
|
|
|
Note that the major difference between an ActionListener and a ChangeListener
|
|
is that for a ChangeListener, multiple changes will be coalesced into fewer
|
|
callbacks, but ActionListeners perform one callback for every event posted.
|
|
|
|
@see ChangeListenerList, ChangeBroadcaster, ActionListener
|
|
*/
|
|
class JUCE_API ChangeListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~ChangeListener() {}
|
|
|
|
/** Overridden by your subclass to receive the callback.
|
|
|
|
@param objectThatHasChanged the value that was passed to the
|
|
ChangeListenerList::sendChangeMessage() method
|
|
*/
|
|
virtual void changeListenerCallback (void* objectThatHasChanged) = 0;
|
|
};
|
|
|
|
#endif // __JUCE_CHANGELISTENER_JUCEHEADER__
|
|
/********* End of inlined file: juce_ChangeListener.h *********/
|
|
|
|
/**
|
|
A set of ChangeListeners.
|
|
|
|
Listeners can be added and removed from the list, and change messages can be
|
|
broadcast to all the listeners.
|
|
|
|
@see ChangeListener, ChangeBroadcaster
|
|
*/
|
|
class JUCE_API ChangeListenerList : public MessageListener
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty list. */
|
|
ChangeListenerList() throw();
|
|
|
|
/** Destructor. */
|
|
~ChangeListenerList() throw();
|
|
|
|
/** Adds a listener to the list.
|
|
|
|
(Trying to add a listener that's already on the list will have no effect).
|
|
*/
|
|
void addChangeListener (ChangeListener* const listener) throw();
|
|
|
|
/** Removes a listener from the list.
|
|
|
|
If the listener isn't on the list, this won't have any effect.
|
|
*/
|
|
void removeChangeListener (ChangeListener* const listener) throw();
|
|
|
|
/** Removes all listeners from the list. */
|
|
void removeAllChangeListeners() throw();
|
|
|
|
/** Posts an asynchronous change message to all the listeners.
|
|
|
|
If a message has already been sent and hasn't yet been delivered, this
|
|
method won't send another - in this way it coalesces multiple frequent
|
|
changes into fewer actual callbacks to the ChangeListeners. Contrast this
|
|
with the ActionListener, which posts a new event for every call to its
|
|
sendActionMessage() method.
|
|
|
|
Only listeners which are on the list when the change event is delivered
|
|
will receive the event - and this may include listeners that weren't on
|
|
the list when the change message was sent.
|
|
|
|
@param objectThatHasChanged this pointer is passed to the
|
|
ChangeListener::changeListenerCallback() method,
|
|
and can be any value the application needs
|
|
@see sendSynchronousChangeMessage
|
|
*/
|
|
void sendChangeMessage (void* objectThatHasChanged) throw();
|
|
|
|
/** This will synchronously callback all the ChangeListeners.
|
|
|
|
Use this if you need to synchronously force a call to all the
|
|
listeners' ChangeListener::changeListenerCallback() methods.
|
|
*/
|
|
void sendSynchronousChangeMessage (void* objectThatHasChanged);
|
|
|
|
/** If a change message has been sent but not yet dispatched, this will
|
|
use sendSynchronousChangeMessage() to make the callback immediately.
|
|
*/
|
|
void dispatchPendingMessages();
|
|
|
|
/** @internal */
|
|
void handleMessage (const Message&);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
SortedSet <void*> listeners;
|
|
CriticalSection lock;
|
|
void* lastChangedObject;
|
|
bool messagePending;
|
|
|
|
ChangeListenerList (const ChangeListenerList&);
|
|
const ChangeListenerList& operator= (const ChangeListenerList&);
|
|
};
|
|
|
|
#endif // __JUCE_CHANGELISTENERLIST_JUCEHEADER__
|
|
/********* End of inlined file: juce_ChangeListenerList.h *********/
|
|
|
|
/** Manages a list of ChangeListeners, and can send them messages.
|
|
|
|
To quickly add methods to your class that can add/remove change
|
|
listeners and broadcast to them, you can derive from this.
|
|
|
|
@see ChangeListenerList, ChangeListener
|
|
*/
|
|
class JUCE_API ChangeBroadcaster
|
|
{
|
|
public:
|
|
|
|
/** Creates an ChangeBroadcaster. */
|
|
ChangeBroadcaster() throw();
|
|
|
|
/** Destructor. */
|
|
virtual ~ChangeBroadcaster();
|
|
|
|
/** Adds a listener to the list.
|
|
|
|
(Trying to add a listener that's already on the list will have no effect).
|
|
*/
|
|
void addChangeListener (ChangeListener* const listener) throw();
|
|
|
|
/** Removes a listener from the list.
|
|
|
|
If the listener isn't on the list, this won't have any effect.
|
|
*/
|
|
void removeChangeListener (ChangeListener* const listener) throw();
|
|
|
|
/** Removes all listeners from the list. */
|
|
void removeAllChangeListeners() throw();
|
|
|
|
/** Broadcasts a change message to all the registered listeners.
|
|
|
|
The message will be delivered asynchronously by the event thread, so this
|
|
method will not directly call any of the listeners. For a synchronous
|
|
message, use sendSynchronousChangeMessage().
|
|
|
|
@see ChangeListenerList::sendActionMessage
|
|
*/
|
|
void sendChangeMessage (void* objectThatHasChanged) throw();
|
|
|
|
/** Sends a synchronous change message to all the registered listeners.
|
|
|
|
@see ChangeListenerList::sendSynchronousChangeMessage
|
|
*/
|
|
void sendSynchronousChangeMessage (void* objectThatHasChanged);
|
|
|
|
/** If a change message has been sent but not yet dispatched, this will
|
|
use sendSynchronousChangeMessage() to make the callback immediately.
|
|
*/
|
|
void dispatchPendingMessages();
|
|
|
|
private:
|
|
|
|
ChangeListenerList changeListenerList;
|
|
|
|
ChangeBroadcaster (const ChangeBroadcaster&);
|
|
const ChangeBroadcaster& operator= (const ChangeBroadcaster&);
|
|
};
|
|
|
|
#endif // __JUCE_CHANGEBROADCASTER_JUCEHEADER__
|
|
/********* End of inlined file: juce_ChangeBroadcaster.h *********/
|
|
|
|
/** Wrapper on a file that stores a list of key/value data pairs.
|
|
|
|
Useful for storing application settings, etc. See the PropertySet class for
|
|
the interfaces that read and write values.
|
|
|
|
Not designed for very large amounts of data, as it keeps all the values in
|
|
memory and writes them out to disk lazily when they are changed.
|
|
|
|
Because this class derives from ChangeBroadcaster, ChangeListeners can be registered
|
|
with it, and these will be signalled when a value changes.
|
|
|
|
@see PropertySet
|
|
*/
|
|
class JUCE_API PropertiesFile : public PropertySet,
|
|
public ChangeBroadcaster,
|
|
private Timer
|
|
{
|
|
public:
|
|
|
|
enum FileFormatOptions
|
|
{
|
|
ignoreCaseOfKeyNames = 1,
|
|
storeAsBinary = 2,
|
|
storeAsCompressedBinary = 4,
|
|
storeAsXML = 8
|
|
};
|
|
|
|
/**
|
|
Creates a PropertiesFile object.
|
|
|
|
@param file the file to use
|
|
@param millisecondsBeforeSaving if this is zero or greater, then after a value
|
|
is changed, the object will wait for this amount
|
|
of time and then save the file. If zero, the file
|
|
will be written to disk immediately on being changed
|
|
(which might be slow, as it'll re-write synchronously
|
|
each time a value-change method is called). If it is
|
|
less than zero, the file won't be saved until
|
|
save() or saveIfNeeded() are explicitly called.
|
|
@param options a combination of the flags in the FileFormatOptions
|
|
enum, which specify the type of file to save, and other
|
|
options.
|
|
*/
|
|
PropertiesFile (const File& file,
|
|
const int millisecondsBeforeSaving,
|
|
const int options) throw();
|
|
|
|
/** Destructor.
|
|
|
|
When deleted, the file will first call saveIfNeeded() to flush any changes to disk.
|
|
*/
|
|
~PropertiesFile();
|
|
|
|
/** This will flush all the values to disk if they've changed since the last
|
|
time they were saved.
|
|
|
|
Returns false if it fails to write to the file for some reason (maybe because
|
|
it's read-only or the directory doesn't exist or something).
|
|
|
|
@see save
|
|
*/
|
|
bool saveIfNeeded();
|
|
|
|
/** This will force a write-to-disk of the current values, regardless of whether
|
|
anything has changed since the last save.
|
|
|
|
Returns false if it fails to write to the file for some reason (maybe because
|
|
it's read-only or the directory doesn't exist or something).
|
|
|
|
@see saveIfNeeded
|
|
*/
|
|
bool save();
|
|
|
|
/** Returns true if the properties have been altered since the last time they were
|
|
saved.
|
|
*/
|
|
bool needsToBeSaved() const throw();
|
|
|
|
/** Returns the file that's being used. */
|
|
const File getFile() const throw();
|
|
|
|
/** Handy utility to create a properties file in whatever the standard OS-specific
|
|
location is for these things.
|
|
|
|
This uses getDefaultAppSettingsFile() to decide what file to create, then
|
|
creates a PropertiesFile object with the specified properties. See
|
|
getDefaultAppSettingsFile() and the class's constructor for descriptions of
|
|
what the parameters do.
|
|
|
|
@see getDefaultAppSettingsFile
|
|
*/
|
|
static PropertiesFile* createDefaultAppPropertiesFile (const String& applicationName,
|
|
const String& fileNameSuffix,
|
|
const String& folderName,
|
|
const bool commonToAllUsers,
|
|
const int millisecondsBeforeSaving,
|
|
const int propertiesFileOptions);
|
|
|
|
/** Handy utility to choose a file in the standard OS-dependent location for application
|
|
settings files.
|
|
|
|
So on a Mac, this will return a file called:
|
|
~/Library/Preferences/[folderName]/[applicationName].[fileNameSuffix]
|
|
|
|
On Windows it'll return something like:
|
|
C:\\Documents and Settings\\username\\Application Data\\[folderName]\\[applicationName].[fileNameSuffix]
|
|
|
|
On Linux it'll return
|
|
~/.[folderName]/[applicationName].[fileNameSuffix]
|
|
|
|
If you pass an empty string as the folder name, it'll use the app name for this (or
|
|
omit the folder name on the Mac).
|
|
|
|
If commonToAllUsers is true, then this will return the same file for all users of the
|
|
computer, regardless of the current user. If it is false, the file will be specific to
|
|
only the current user. Use this to choose whether you're saving settings that are common
|
|
or user-specific.
|
|
*/
|
|
static const File getDefaultAppSettingsFile (const String& applicationName,
|
|
const String& fileNameSuffix,
|
|
const String& folderName,
|
|
const bool commonToAllUsers);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
virtual void propertyChanged();
|
|
|
|
private:
|
|
|
|
File file;
|
|
int timerInterval;
|
|
const int options;
|
|
bool needsWriting;
|
|
|
|
void timerCallback();
|
|
|
|
PropertiesFile (const PropertiesFile&);
|
|
const PropertiesFile& operator= (const PropertiesFile&);
|
|
};
|
|
|
|
#endif // __JUCE_PROPERTIESFILE_JUCEHEADER__
|
|
/********* End of inlined file: juce_PropertiesFile.h *********/
|
|
|
|
/**
|
|
Manages a collection of properties.
|
|
|
|
This is a slightly higher-level wrapper for PropertiesFile, which can be used
|
|
as a singleton.
|
|
|
|
It holds two different PropertiesFile objects internally, one for user-specific
|
|
settings (stored in your user directory), and one for settings that are common to
|
|
all users (stored in a folder accessible to all users).
|
|
|
|
The class manages the creation of these files on-demand, allowing access via the
|
|
getUserSettings() and getCommonSettings() methods. It also has a few handy
|
|
methods like testWriteAccess() to check that the files can be saved.
|
|
|
|
If you're using one of these as a singleton, then your app's start-up code should
|
|
first of all call setStorageParameters() to tell it the parameters to use to create
|
|
the properties files.
|
|
|
|
@see PropertiesFile
|
|
*/
|
|
class JUCE_API ApplicationProperties : public DeletedAtShutdown
|
|
{
|
|
public:
|
|
|
|
/**
|
|
Creates an ApplicationProperties object.
|
|
|
|
Before using it, you must call setStorageParameters() to give it the info
|
|
it needs to create the property files.
|
|
*/
|
|
ApplicationProperties() throw();
|
|
|
|
/** Destructor.
|
|
*/
|
|
~ApplicationProperties();
|
|
|
|
juce_DeclareSingleton (ApplicationProperties, false)
|
|
|
|
/** Gives the object the information it needs to create the appropriate properties files.
|
|
|
|
See the comments for PropertiesFile::createDefaultAppPropertiesFile() for more
|
|
info about how these parameters are used.
|
|
*/
|
|
void setStorageParameters (const String& applicationName,
|
|
const String& fileNameSuffix,
|
|
const String& folderName,
|
|
const int millisecondsBeforeSaving,
|
|
const int propertiesFileOptions) throw();
|
|
|
|
/** Tests whether the files can be successfully written to, and can show
|
|
an error message if not.
|
|
|
|
Returns true if none of the tests fail.
|
|
|
|
@param testUserSettings if true, the user settings file will be tested
|
|
@param testCommonSettings if true, the common settings file will be tested
|
|
@param showWarningDialogOnFailure if true, the method will show a helpful error
|
|
message box if either of the tests fail
|
|
*/
|
|
bool testWriteAccess (const bool testUserSettings,
|
|
const bool testCommonSettings,
|
|
const bool showWarningDialogOnFailure);
|
|
|
|
/** Returns the user settings file.
|
|
|
|
The first time this is called, it will create and load the properties file.
|
|
|
|
Note that when you search the user PropertiesFile for a value that it doesn't contain,
|
|
the common settings are used as a second-chance place to look. This is done via the
|
|
PropertySet::setFallbackPropertySet() method - by default the common settings are set
|
|
to the fallback for the user settings.
|
|
|
|
@see getCommonSettings
|
|
*/
|
|
PropertiesFile* getUserSettings() throw();
|
|
|
|
/** Returns the common settings file.
|
|
|
|
The first time this is called, it will create and load the properties file.
|
|
|
|
@param returnUserPropsIfReadOnly if this is true, and the common properties file is
|
|
read-only (e.g. because the user doesn't have permission to write
|
|
to shared files), then this will return the user settings instead,
|
|
(like getUserSettings() would do). This is handy if you'd like to
|
|
write a value to the common settings, but if that's no possible,
|
|
then you'd rather write to the user settings than none at all.
|
|
If returnUserPropsIfReadOnly is false, this method will always return
|
|
the common settings, even if any changes to them can't be saved.
|
|
@see getUserSettings
|
|
*/
|
|
PropertiesFile* getCommonSettings (const bool returnUserPropsIfReadOnly) throw();
|
|
|
|
/** Saves both files if they need to be saved.
|
|
|
|
@see PropertiesFile::saveIfNeeded
|
|
*/
|
|
bool saveIfNeeded();
|
|
|
|
/** Flushes and closes both files if they are open.
|
|
|
|
This flushes any pending changes to disk with PropertiesFile::saveIfNeeded()
|
|
and closes both files. They will then be re-opened the next time getUserSettings()
|
|
or getCommonSettings() is called.
|
|
*/
|
|
void closeFiles();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
PropertiesFile* userProps;
|
|
PropertiesFile* commonProps;
|
|
|
|
String appName, fileSuffix, folderName;
|
|
int msBeforeSaving, options;
|
|
int commonSettingsAreReadOnly;
|
|
|
|
ApplicationProperties (const ApplicationProperties&);
|
|
const ApplicationProperties& operator= (const ApplicationProperties&);
|
|
|
|
void openFiles() throw();
|
|
};
|
|
|
|
#endif // __JUCE_APPLICATIONPROPERTIES_JUCEHEADER__
|
|
/********* End of inlined file: juce_ApplicationProperties.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MIDIBUFFER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MidiBuffer.h *********/
|
|
#ifndef __JUCE_MIDIBUFFER_JUCEHEADER__
|
|
#define __JUCE_MIDIBUFFER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MidiMessage.h *********/
|
|
#ifndef __JUCE_MIDIMESSAGE_JUCEHEADER__
|
|
#define __JUCE_MIDIMESSAGE_JUCEHEADER__
|
|
|
|
/**
|
|
Encapsulates a MIDI message.
|
|
|
|
@see MidiMessageSequence, MidiOutput, MidiInput
|
|
*/
|
|
class JUCE_API MidiMessage
|
|
{
|
|
public:
|
|
|
|
/** Creates a 3-byte short midi message.
|
|
|
|
@param byte1 message byte 1
|
|
@param byte2 message byte 2
|
|
@param byte3 message byte 3
|
|
@param timeStamp the time to give the midi message - this value doesn't
|
|
use any particular units, so will be application-specific
|
|
*/
|
|
MidiMessage (const int byte1,
|
|
const int byte2,
|
|
const int byte3,
|
|
const double timeStamp = 0) throw();
|
|
|
|
/** Creates a 2-byte short midi message.
|
|
|
|
@param byte1 message byte 1
|
|
@param byte2 message byte 2
|
|
@param timeStamp the time to give the midi message - this value doesn't
|
|
use any particular units, so will be application-specific
|
|
*/
|
|
MidiMessage (const int byte1,
|
|
const int byte2,
|
|
const double timeStamp = 0) throw();
|
|
|
|
/** Creates a 1-byte short midi message.
|
|
|
|
@param byte1 message byte 1
|
|
@param timeStamp the time to give the midi message - this value doesn't
|
|
use any particular units, so will be application-specific
|
|
*/
|
|
MidiMessage (const int byte1,
|
|
const double timeStamp = 0) throw();
|
|
|
|
/** Creates a midi message from a block of data. */
|
|
MidiMessage (const uint8* const data,
|
|
const int dataSize,
|
|
const double timeStamp = 0) throw();
|
|
|
|
/** Reads the next midi message from some data.
|
|
|
|
This will read as many bytes from a data stream as it needs to make a
|
|
complete message, and will return the number of bytes it used. This lets
|
|
you read a sequence of midi messages from a file or stream.
|
|
|
|
@param data the data to read from
|
|
@param size the maximum number of bytes it's allowed to read
|
|
@param numBytesUsed returns the number of bytes that were actually needed
|
|
@param lastStatusByte in a sequence of midi messages, the initial byte
|
|
can be dropped from a message if it's the same as the
|
|
first byte of the previous message, so this lets you
|
|
supply the byte to use if the first byte of the message
|
|
has in fact been dropped.
|
|
@param timeStamp the time to give the midi message - this value doesn't
|
|
use any particular units, so will be application-specific
|
|
*/
|
|
MidiMessage (const uint8* data,
|
|
int size,
|
|
int& numBytesUsed,
|
|
uint8 lastStatusByte,
|
|
double timeStamp = 0) throw();
|
|
|
|
/** Creates a copy of another midi message. */
|
|
MidiMessage (const MidiMessage& other) throw();
|
|
|
|
/** Creates a copy of another midi message, with a different timestamp. */
|
|
MidiMessage (const MidiMessage& other,
|
|
const double newTimeStamp) throw();
|
|
|
|
/** Destructor. */
|
|
~MidiMessage() throw();
|
|
|
|
/** Copies this message from another one. */
|
|
const MidiMessage& operator= (const MidiMessage& other) throw();
|
|
|
|
/** Returns a pointer to the raw midi data.
|
|
|
|
@see getRawDataSize
|
|
*/
|
|
uint8* getRawData() const throw() { return data; }
|
|
|
|
/** Returns the number of bytes of data in the message.
|
|
|
|
@see getRawData
|
|
*/
|
|
int getRawDataSize() const throw() { return size; }
|
|
|
|
/** Returns the timestamp associated with this message.
|
|
|
|
The exact meaning of this time and its units will vary, as messages are used in
|
|
a variety of different contexts.
|
|
|
|
If you're getting the message from a midi file, this could be a time in seconds, or
|
|
a number of ticks - see MidiFile::convertTimestampTicksToSeconds().
|
|
|
|
If the message is being used in a MidiBuffer, it might indicate the number of
|
|
audio samples from the start of the buffer.
|
|
|
|
If the message was created by a MidiInput, see MidiInputCallback::handleIncomingMidiMessage()
|
|
for details of the way that it initialises this value.
|
|
|
|
@see setTimeStamp, addToTimeStamp
|
|
*/
|
|
double getTimeStamp() const throw() { return timeStamp; }
|
|
|
|
/** Changes the message's associated timestamp.
|
|
|
|
The units for the timestamp will be application-specific - see the notes for getTimeStamp().
|
|
|
|
@see addToTimeStamp, getTimeStamp
|
|
*/
|
|
void setTimeStamp (const double newTimestamp) throw() { timeStamp = newTimestamp; }
|
|
|
|
/** Adds a value to the message's timestamp.
|
|
|
|
The units for the timestamp will be application-specific.
|
|
*/
|
|
void addToTimeStamp (const double delta) throw() { timeStamp += delta; }
|
|
|
|
/** Returns the midi channel associated with the message.
|
|
|
|
@returns a value 1 to 16 if the message has a channel, or 0 if it hasn't (e.g.
|
|
if it's a sysex)
|
|
@see isForChannel, setChannel
|
|
*/
|
|
int getChannel() const throw();
|
|
|
|
/** Returns true if the message applies to the given midi channel.
|
|
|
|
@param channelNumber the channel number to look for, in the range 1 to 16
|
|
@see getChannel, setChannel
|
|
*/
|
|
bool isForChannel (const int channelNumber) const throw();
|
|
|
|
/** Changes the message's midi channel.
|
|
|
|
This won't do anything for non-channel messages like sysexes.
|
|
|
|
@param newChannelNumber the channel number to change it to, in the range 1 to 16
|
|
*/
|
|
void setChannel (const int newChannelNumber) throw();
|
|
|
|
/** Returns true if this is a system-exclusive message.
|
|
*/
|
|
bool isSysEx() const throw();
|
|
|
|
/** Returns a pointer to the sysex data inside the message.
|
|
|
|
If this event isn't a sysex event, it'll return 0.
|
|
|
|
@see getSysExDataSize
|
|
*/
|
|
const uint8* getSysExData() const throw();
|
|
|
|
/** Returns the size of the sysex data.
|
|
|
|
This value excludes the 0xf0 header byte and the 0xf7 at the end.
|
|
|
|
@see getSysExData
|
|
*/
|
|
int getSysExDataSize() const throw();
|
|
|
|
/** Returns true if this message is a 'key-down' event.
|
|
|
|
This will return false for a note-on event with a velocity of 0.
|
|
|
|
@see isNoteOff, getNoteNumber, getVelocity, noteOn
|
|
*/
|
|
bool isNoteOn() const throw();
|
|
|
|
/** Creates a key-down message (using a floating-point velocity).
|
|
|
|
@param channel the midi channel, in the range 1 to 16
|
|
@param noteNumber the key number, 0 to 127
|
|
@param velocity in the range 0 to 1.0
|
|
@see isNoteOn
|
|
*/
|
|
static const MidiMessage noteOn (const int channel,
|
|
const int noteNumber,
|
|
const float velocity) throw();
|
|
|
|
/** Creates a key-down message (using an integer velocity).
|
|
|
|
@param channel the midi channel, in the range 1 to 16
|
|
@param noteNumber the key number, 0 to 127
|
|
@param velocity in the range 0 to 127
|
|
@see isNoteOn
|
|
*/
|
|
static const MidiMessage noteOn (const int channel,
|
|
const int noteNumber,
|
|
const uint8 velocity) throw();
|
|
|
|
/** Returns true if this message is a 'key-up' event.
|
|
|
|
This will also return true for a note-on event with a velocity of 0.
|
|
|
|
@see isNoteOn, getNoteNumber, getVelocity, noteOff
|
|
*/
|
|
bool isNoteOff() const throw();
|
|
|
|
/** Creates a key-up message.
|
|
|
|
@param channel the midi channel, in the range 1 to 16
|
|
@param noteNumber the key number, 0 to 127
|
|
@see isNoteOff
|
|
*/
|
|
static const MidiMessage noteOff (const int channel,
|
|
const int noteNumber) throw();
|
|
|
|
/** Returns true if this message is a 'key-down' or 'key-up' event.
|
|
|
|
@see isNoteOn, isNoteOff
|
|
*/
|
|
bool isNoteOnOrOff() const throw();
|
|
|
|
/** Returns the midi note number for note-on and note-off messages.
|
|
|
|
If the message isn't a note-on or off, the value returned will be
|
|
meaningless.
|
|
|
|
@see isNoteOff, getMidiNoteName, getMidiNoteInHertz, setNoteNumber
|
|
*/
|
|
int getNoteNumber() const throw();
|
|
|
|
/** Changes the midi note number of a note-on or note-off message.
|
|
|
|
If the message isn't a note on or off, this will do nothing.
|
|
*/
|
|
void setNoteNumber (const int newNoteNumber) throw();
|
|
|
|
/** Returns the velocity of a note-on or note-off message.
|
|
|
|
The value returned will be in the range 0 to 127.
|
|
|
|
If the message isn't a note-on or off event, it will return 0.
|
|
|
|
@see getFloatVelocity
|
|
*/
|
|
uint8 getVelocity() const throw();
|
|
|
|
/** Returns the velocity of a note-on or note-off message.
|
|
|
|
The value returned will be in the range 0 to 1.0
|
|
|
|
If the message isn't a note-on or off event, it will return 0.
|
|
|
|
@see getVelocity, setVelocity
|
|
*/
|
|
float getFloatVelocity() const throw();
|
|
|
|
/** Changes the velocity of a note-on or note-off message.
|
|
|
|
If the message isn't a note on or off, this will do nothing.
|
|
|
|
@param newVelocity the new velocity, in the range 0 to 1.0
|
|
@see getFloatVelocity, multiplyVelocity
|
|
*/
|
|
void setVelocity (const float newVelocity) throw();
|
|
|
|
/** Multiplies the velocity of a note-on or note-off message by a given amount.
|
|
|
|
If the message isn't a note on or off, this will do nothing.
|
|
|
|
@param scaleFactor the value by which to multiply the velocity
|
|
@see setVelocity
|
|
*/
|
|
void multiplyVelocity (const float scaleFactor) throw();
|
|
|
|
/** Returns true if the message is a program (patch) change message.
|
|
|
|
@see getProgramChangeNumber, getGMInstrumentName
|
|
*/
|
|
bool isProgramChange() const throw();
|
|
|
|
/** Returns the new program number of a program change message.
|
|
|
|
If the message isn't a program change, the value returned will be
|
|
nonsense.
|
|
|
|
@see isProgramChange, getGMInstrumentName
|
|
*/
|
|
int getProgramChangeNumber() const throw();
|
|
|
|
/** Creates a program-change message.
|
|
|
|
@param channel the midi channel, in the range 1 to 16
|
|
@param programNumber the midi program number, 0 to 127
|
|
@see isProgramChange, getGMInstrumentName
|
|
*/
|
|
static const MidiMessage programChange (const int channel,
|
|
const int programNumber) throw();
|
|
|
|
/** Returns true if the message is a pitch-wheel move.
|
|
|
|
@see getPitchWheelValue, pitchWheel
|
|
*/
|
|
bool isPitchWheel() const throw();
|
|
|
|
/** Returns the pitch wheel position from a pitch-wheel move message.
|
|
|
|
The value returned is a 14-bit number from 0 to 0x3fff, indicating the wheel position.
|
|
If called for messages which aren't pitch wheel events, the number returned will be
|
|
nonsense.
|
|
|
|
@see isPitchWheel
|
|
*/
|
|
int getPitchWheelValue() const throw();
|
|
|
|
/** Creates a pitch-wheel move message.
|
|
|
|
@param channel the midi channel, in the range 1 to 16
|
|
@param position the wheel position, in the range 0 to 16383
|
|
@see isPitchWheel
|
|
*/
|
|
static const MidiMessage pitchWheel (const int channel,
|
|
const int position) throw();
|
|
|
|
/** Returns true if the message is an aftertouch event.
|
|
|
|
For aftertouch events, use the getNoteNumber() method to find out the key
|
|
that it applies to, and getAftertouchValue() to find out the amount. Use
|
|
getChannel() to find out the channel.
|
|
|
|
@see getAftertouchValue, getNoteNumber
|
|
*/
|
|
bool isAftertouch() const throw();
|
|
|
|
/** Returns the amount of aftertouch from an aftertouch messages.
|
|
|
|
The value returned is in the range 0 to 127, and will be nonsense for messages
|
|
other than aftertouch messages.
|
|
|
|
@see isAftertouch
|
|
*/
|
|
int getAfterTouchValue() const throw();
|
|
|
|
/** Creates an aftertouch message.
|
|
|
|
@param channel the midi channel, in the range 1 to 16
|
|
@param noteNumber the key number, 0 to 127
|
|
@param aftertouchAmount the amount of aftertouch, 0 to 127
|
|
@see isAftertouch
|
|
*/
|
|
static const MidiMessage aftertouchChange (const int channel,
|
|
const int noteNumber,
|
|
const int aftertouchAmount) throw();
|
|
|
|
/** Returns true if the message is a channel-pressure change event.
|
|
|
|
This is like aftertouch, but common to the whole channel rather than a specific
|
|
note. Use getChannelPressureValue() to find out the pressure, and getChannel()
|
|
to find out the channel.
|
|
|
|
@see channelPressureChange
|
|
*/
|
|
bool isChannelPressure() const throw();
|
|
|
|
/** Returns the pressure from a channel pressure change message.
|
|
|
|
@returns the pressure, in the range 0 to 127
|
|
@see isChannelPressure, channelPressureChange
|
|
*/
|
|
int getChannelPressureValue() const throw();
|
|
|
|
/** Creates a channel-pressure change event.
|
|
|
|
@param channel the midi channel: 1 to 16
|
|
@param pressure the pressure, 0 to 127
|
|
@see isChannelPressure
|
|
*/
|
|
static const MidiMessage channelPressureChange (const int channel,
|
|
const int pressure) throw();
|
|
|
|
/** Returns true if this is a midi controller message.
|
|
|
|
@see getControllerNumber, getControllerValue, controllerEvent
|
|
*/
|
|
bool isController() const throw();
|
|
|
|
/** Returns the controller number of a controller message.
|
|
|
|
The name of the controller can be looked up using the getControllerName() method.
|
|
|
|
Note that the value returned is invalid for messages that aren't controller changes.
|
|
|
|
@see isController, getControllerName, getControllerValue
|
|
*/
|
|
int getControllerNumber() const throw();
|
|
|
|
/** Returns the controller value from a controller message.
|
|
|
|
A value 0 to 127 is returned to indicate the new controller position.
|
|
|
|
Note that the value returned is invalid for messages that aren't controller changes.
|
|
|
|
@see isController, getControllerNumber
|
|
*/
|
|
int getControllerValue() const throw();
|
|
|
|
/** Creates a controller message.
|
|
|
|
@param channel the midi channel, in the range 1 to 16
|
|
@param controllerType the type of controller
|
|
@param value the controller value
|
|
@see isController
|
|
*/
|
|
static const MidiMessage controllerEvent (const int channel,
|
|
const int controllerType,
|
|
const int value) throw();
|
|
|
|
/** Checks whether this message is an all-notes-off message.
|
|
|
|
@see allNotesOff
|
|
*/
|
|
bool isAllNotesOff() const throw();
|
|
|
|
/** Checks whether this message is an all-sound-off message.
|
|
|
|
@see allSoundOff
|
|
*/
|
|
bool isAllSoundOff() const throw();
|
|
|
|
/** Creates an all-notes-off message.
|
|
|
|
@param channel the midi channel, in the range 1 to 16
|
|
@see isAllNotesOff
|
|
*/
|
|
static const MidiMessage allNotesOff (const int channel) throw();
|
|
|
|
/** Creates an all-sound-off message.
|
|
|
|
@param channel the midi channel, in the range 1 to 16
|
|
@see isAllSoundOff
|
|
*/
|
|
static const MidiMessage allSoundOff (const int channel) throw();
|
|
|
|
/** Creates an all-controllers-off message.
|
|
|
|
@param channel the midi channel, in the range 1 to 16
|
|
*/
|
|
static const MidiMessage allControllersOff (const int channel) throw();
|
|
|
|
/** Returns true if this event is a meta-event.
|
|
|
|
Meta-events are things like tempo changes, track names, etc.
|
|
|
|
@see getMetaEventType, isTrackMetaEvent, isEndOfTrackMetaEvent,
|
|
isTextMetaEvent, isTrackNameEvent, isTempoMetaEvent, isTimeSignatureMetaEvent,
|
|
isKeySignatureMetaEvent, isMidiChannelMetaEvent
|
|
*/
|
|
bool isMetaEvent() const throw();
|
|
|
|
/** Returns a meta-event's type number.
|
|
|
|
If the message isn't a meta-event, this will return -1.
|
|
|
|
@see isMetaEvent, isTrackMetaEvent, isEndOfTrackMetaEvent,
|
|
isTextMetaEvent, isTrackNameEvent, isTempoMetaEvent, isTimeSignatureMetaEvent,
|
|
isKeySignatureMetaEvent, isMidiChannelMetaEvent
|
|
*/
|
|
int getMetaEventType() const throw();
|
|
|
|
/** Returns a pointer to the data in a meta-event.
|
|
|
|
@see isMetaEvent, getMetaEventLength
|
|
*/
|
|
const uint8* getMetaEventData() const throw();
|
|
|
|
/** Returns the length of the data for a meta-event.
|
|
|
|
@see isMetaEvent, getMetaEventData
|
|
*/
|
|
int getMetaEventLength() const throw();
|
|
|
|
/** Returns true if this is a 'track' meta-event. */
|
|
bool isTrackMetaEvent() const throw();
|
|
|
|
/** Returns true if this is an 'end-of-track' meta-event. */
|
|
bool isEndOfTrackMetaEvent() const throw();
|
|
|
|
/** Creates an end-of-track meta-event.
|
|
|
|
@see isEndOfTrackMetaEvent
|
|
*/
|
|
static const MidiMessage endOfTrack() throw();
|
|
|
|
/** Returns true if this is an 'track name' meta-event.
|
|
|
|
You can use the getTextFromTextMetaEvent() method to get the track's name.
|
|
*/
|
|
bool isTrackNameEvent() const throw();
|
|
|
|
/** Returns true if this is a 'text' meta-event.
|
|
|
|
@see getTextFromTextMetaEvent
|
|
*/
|
|
bool isTextMetaEvent() const throw();
|
|
|
|
/** Returns the text from a text meta-event.
|
|
|
|
@see isTextMetaEvent
|
|
*/
|
|
const String getTextFromTextMetaEvent() const throw();
|
|
|
|
/** Returns true if this is a 'tempo' meta-event.
|
|
|
|
@see getTempoMetaEventTickLength, getTempoSecondsPerQuarterNote
|
|
*/
|
|
bool isTempoMetaEvent() const throw();
|
|
|
|
/** Returns the tick length from a tempo meta-event.
|
|
|
|
@param timeFormat the 16-bit time format value from the midi file's header.
|
|
@returns the tick length (in seconds).
|
|
@see isTempoMetaEvent
|
|
*/
|
|
double getTempoMetaEventTickLength (const short timeFormat) const throw();
|
|
|
|
/** Calculates the seconds-per-quarter-note from a tempo meta-event.
|
|
|
|
@see isTempoMetaEvent, getTempoMetaEventTickLength
|
|
*/
|
|
double getTempoSecondsPerQuarterNote() const throw();
|
|
|
|
/** Creates a tempo meta-event.
|
|
|
|
@see isTempoMetaEvent
|
|
*/
|
|
static const MidiMessage tempoMetaEvent (const int microsecondsPerQuarterNote) throw();
|
|
|
|
/** Returns true if this is a 'time-signature' meta-event.
|
|
|
|
@see getTimeSignatureInfo
|
|
*/
|
|
bool isTimeSignatureMetaEvent() const throw();
|
|
|
|
/** Returns the time-signature values from a time-signature meta-event.
|
|
|
|
@see isTimeSignatureMetaEvent
|
|
*/
|
|
void getTimeSignatureInfo (int& numerator,
|
|
int& denominator) const throw();
|
|
|
|
/** Creates a time-signature meta-event.
|
|
|
|
@see isTimeSignatureMetaEvent
|
|
*/
|
|
static const MidiMessage timeSignatureMetaEvent (const int numerator,
|
|
const int denominator) throw();
|
|
|
|
/** Returns true if this is a 'key-signature' meta-event.
|
|
|
|
@see getKeySignatureNumberOfSharpsOrFlats
|
|
*/
|
|
bool isKeySignatureMetaEvent() const throw();
|
|
|
|
/** Returns the key from a key-signature meta-event.
|
|
|
|
@see isKeySignatureMetaEvent
|
|
*/
|
|
int getKeySignatureNumberOfSharpsOrFlats() const throw();
|
|
|
|
/** Returns true if this is a 'channel' meta-event.
|
|
|
|
A channel meta-event specifies the midi channel that should be used
|
|
for subsequent meta-events.
|
|
|
|
@see getMidiChannelMetaEventChannel
|
|
*/
|
|
bool isMidiChannelMetaEvent() const throw();
|
|
|
|
/** Returns the channel number from a channel meta-event.
|
|
|
|
@returns the channel, in the range 1 to 16.
|
|
@see isMidiChannelMetaEvent
|
|
*/
|
|
int getMidiChannelMetaEventChannel() const throw();
|
|
|
|
/** Creates a midi channel meta-event.
|
|
|
|
@param channel the midi channel, in the range 1 to 16
|
|
@see isMidiChannelMetaEvent
|
|
*/
|
|
static const MidiMessage midiChannelMetaEvent (const int channel) throw();
|
|
|
|
/** Returns true if this is an active-sense message. */
|
|
bool isActiveSense() const throw();
|
|
|
|
/** Returns true if this is a midi start event.
|
|
|
|
@see midiStart
|
|
*/
|
|
bool isMidiStart() const throw();
|
|
|
|
/** Creates a midi start event. */
|
|
static const MidiMessage midiStart() throw();
|
|
|
|
/** Returns true if this is a midi continue event.
|
|
|
|
@see midiContinue
|
|
*/
|
|
bool isMidiContinue() const throw();
|
|
|
|
/** Creates a midi continue event. */
|
|
static const MidiMessage midiContinue() throw();
|
|
|
|
/** Returns true if this is a midi stop event.
|
|
|
|
@see midiStop
|
|
*/
|
|
bool isMidiStop() const throw();
|
|
|
|
/** Creates a midi stop event. */
|
|
static const MidiMessage midiStop() throw();
|
|
|
|
/** Returns true if this is a midi clock event.
|
|
|
|
@see midiClock, songPositionPointer
|
|
*/
|
|
bool isMidiClock() const throw();
|
|
|
|
/** Creates a midi clock event. */
|
|
static const MidiMessage midiClock() throw();
|
|
|
|
/** Returns true if this is a song-position-pointer message.
|
|
|
|
@see getSongPositionPointerMidiBeat, songPositionPointer
|
|
*/
|
|
bool isSongPositionPointer() const throw();
|
|
|
|
/** Returns the midi beat-number of a song-position-pointer message.
|
|
|
|
@see isSongPositionPointer, songPositionPointer
|
|
*/
|
|
int getSongPositionPointerMidiBeat() const throw();
|
|
|
|
/** Creates a song-position-pointer message.
|
|
|
|
The position is a number of midi beats from the start of the song, where 1 midi
|
|
beat is 6 midi clocks, and there are 24 midi clocks in a quarter-note. So there
|
|
are 4 midi beats in a quarter-note.
|
|
|
|
@see isSongPositionPointer, getSongPositionPointerMidiBeat
|
|
*/
|
|
static const MidiMessage songPositionPointer (const int positionInMidiBeats) throw();
|
|
|
|
/** Returns true if this is a quarter-frame midi timecode message.
|
|
|
|
@see quarterFrame, getQuarterFrameSequenceNumber, getQuarterFrameValue
|
|
*/
|
|
bool isQuarterFrame() const throw();
|
|
|
|
/** Returns the sequence number of a quarter-frame midi timecode message.
|
|
|
|
This will be a value between 0 and 7.
|
|
|
|
@see isQuarterFrame, getQuarterFrameValue, quarterFrame
|
|
*/
|
|
int getQuarterFrameSequenceNumber() const throw();
|
|
|
|
/** Returns the value from a quarter-frame message.
|
|
|
|
This will be the lower nybble of the message's data-byte, a value
|
|
between 0 and 15
|
|
*/
|
|
int getQuarterFrameValue() const throw();
|
|
|
|
/** Creates a quarter-frame MTC message.
|
|
|
|
@param sequenceNumber a value 0 to 7 for the upper nybble of the message's data byte
|
|
@param value a value 0 to 15 for the lower nybble of the message's data byte
|
|
*/
|
|
static const MidiMessage quarterFrame (const int sequenceNumber,
|
|
const int value) throw();
|
|
|
|
/** SMPTE timecode types.
|
|
|
|
Used by the getFullFrameParameters() and fullFrame() methods.
|
|
*/
|
|
enum SmpteTimecodeType
|
|
{
|
|
fps24 = 0,
|
|
fps25 = 1,
|
|
fps30drop = 2,
|
|
fps30 = 3
|
|
};
|
|
|
|
/** Returns true if this is a full-frame midi timecode message.
|
|
*/
|
|
bool isFullFrame() const throw();
|
|
|
|
/** Extracts the timecode information from a full-frame midi timecode message.
|
|
|
|
You should only call this on messages where you've used isFullFrame() to
|
|
check that they're the right kind.
|
|
*/
|
|
void getFullFrameParameters (int& hours,
|
|
int& minutes,
|
|
int& seconds,
|
|
int& frames,
|
|
SmpteTimecodeType& timecodeType) const throw();
|
|
|
|
/** Creates a full-frame MTC message.
|
|
*/
|
|
static const MidiMessage fullFrame (const int hours,
|
|
const int minutes,
|
|
const int seconds,
|
|
const int frames,
|
|
SmpteTimecodeType timecodeType);
|
|
|
|
/** Types of MMC command.
|
|
|
|
@see isMidiMachineControlMessage, getMidiMachineControlCommand, midiMachineControlCommand
|
|
*/
|
|
enum MidiMachineControlCommand
|
|
{
|
|
mmc_stop = 1,
|
|
mmc_play = 2,
|
|
mmc_deferredplay = 3,
|
|
mmc_fastforward = 4,
|
|
mmc_rewind = 5,
|
|
mmc_recordStart = 6,
|
|
mmc_recordStop = 7,
|
|
mmc_pause = 9
|
|
};
|
|
|
|
/** Checks whether this is an MMC message.
|
|
|
|
If it is, you can use the getMidiMachineControlCommand() to find out its type.
|
|
*/
|
|
bool isMidiMachineControlMessage() const throw();
|
|
|
|
/** For an MMC message, this returns its type.
|
|
|
|
Make sure it's actually an MMC message with isMidiMachineControlMessage() before
|
|
calling this method.
|
|
*/
|
|
MidiMachineControlCommand getMidiMachineControlCommand() const throw();
|
|
|
|
/** Creates an MMC message.
|
|
*/
|
|
static const MidiMessage midiMachineControlCommand (MidiMachineControlCommand command);
|
|
|
|
/** Checks whether this is an MMC "goto" message.
|
|
|
|
If it is, the parameters passed-in are set to the time that the message contains.
|
|
|
|
@see midiMachineControlGoto
|
|
*/
|
|
bool isMidiMachineControlGoto (int& hours,
|
|
int& minutes,
|
|
int& seconds,
|
|
int& frames) const throw();
|
|
|
|
/** Creates an MMC "goto" message.
|
|
|
|
This messages tells the device to go to a specific frame.
|
|
|
|
@see isMidiMachineControlGoto
|
|
*/
|
|
static const MidiMessage midiMachineControlGoto (int hours,
|
|
int minutes,
|
|
int seconds,
|
|
int frames);
|
|
|
|
/** Creates a master-volume change message.
|
|
|
|
@param volume the volume, 0 to 1.0
|
|
*/
|
|
static const MidiMessage masterVolume (const float volume) throw();
|
|
|
|
/** Creates a system-exclusive message.
|
|
|
|
The data passed in is wrapped with header and tail bytes of 0xf0 and 0xf7.
|
|
*/
|
|
static const MidiMessage createSysExMessage (const uint8* sysexData,
|
|
const int dataSize) throw();
|
|
|
|
/** Reads a midi variable-length integer.
|
|
|
|
@param data the data to read the number from
|
|
@param numBytesUsed on return, this will be set to the number of bytes that were read
|
|
*/
|
|
static int readVariableLengthVal (const uint8* data,
|
|
int& numBytesUsed) throw();
|
|
|
|
/** Based on the first byte of a short midi message, this uses a lookup table
|
|
to return the message length (either 1, 2, or 3 bytes).
|
|
|
|
The value passed in must be 0x80 or higher.
|
|
*/
|
|
static int getMessageLengthFromFirstByte (const uint8 firstByte) throw();
|
|
|
|
/** Returns the name of a midi note number.
|
|
|
|
E.g "C", "D#", etc.
|
|
|
|
@param noteNumber the midi note number, 0 to 127
|
|
@param useSharps if true, sharpened notes are used, e.g. "C#", otherwise
|
|
they'll be flattened, e.g. "Db"
|
|
@param includeOctaveNumber if true, the octave number will be appended to the string,
|
|
e.g. "C#4"
|
|
@param octaveNumForMiddleC if an octave number is being appended, this indicates the
|
|
number that will be used for middle C's octave
|
|
|
|
@see getMidiNoteInHertz
|
|
*/
|
|
static const String getMidiNoteName (int noteNumber,
|
|
bool useSharps,
|
|
bool includeOctaveNumber,
|
|
int octaveNumForMiddleC) throw();
|
|
|
|
/** Returns the frequency of a midi note number.
|
|
|
|
@see getMidiNoteName
|
|
*/
|
|
static const double getMidiNoteInHertz (int noteNumber) throw();
|
|
|
|
/** Returns the standard name of a GM instrument.
|
|
|
|
@param midiInstrumentNumber the program number 0 to 127
|
|
@see getProgramChangeNumber
|
|
*/
|
|
static const String getGMInstrumentName (int midiInstrumentNumber) throw();
|
|
|
|
/** Returns the name of a bank of GM instruments.
|
|
|
|
@param midiBankNumber the bank, 0 to 15
|
|
*/
|
|
static const String getGMInstrumentBankName (int midiBankNumber) throw();
|
|
|
|
/** Returns the standard name of a channel 10 percussion sound.
|
|
|
|
@param midiNoteNumber the key number, 35 to 81
|
|
*/
|
|
static const String getRhythmInstrumentName (int midiNoteNumber) throw();
|
|
|
|
/** Returns the name of a controller type number.
|
|
|
|
@see getControllerNumber
|
|
*/
|
|
static const String getControllerName (int controllerNumber) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
double timeStamp;
|
|
uint8* data;
|
|
int message, size;
|
|
};
|
|
|
|
#endif // __JUCE_MIDIMESSAGE_JUCEHEADER__
|
|
/********* End of inlined file: juce_MidiMessage.h *********/
|
|
|
|
/**
|
|
Holds a sequence of time-stamped midi events.
|
|
|
|
Analogous to the AudioSampleBuffer, this holds a set of midi events with
|
|
integer time-stamps. The buffer is kept sorted in order of the time-stamps.
|
|
|
|
@see MidiMessage
|
|
*/
|
|
class JUCE_API MidiBuffer : private ArrayAllocationBase <uint8>
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty MidiBuffer. */
|
|
MidiBuffer() throw();
|
|
|
|
/** Creates a MidiBuffer containing a single midi message. */
|
|
MidiBuffer (const MidiMessage& message) throw();
|
|
|
|
/** Creates a copy of another MidiBuffer. */
|
|
MidiBuffer (const MidiBuffer& other) throw();
|
|
|
|
/** Makes a copy of another MidiBuffer. */
|
|
const MidiBuffer& operator= (const MidiBuffer& other) throw();
|
|
|
|
/** Destructor */
|
|
~MidiBuffer() throw();
|
|
|
|
/** Removes all events from the buffer. */
|
|
void clear() throw();
|
|
|
|
/** Removes all events between two times from the buffer.
|
|
|
|
All events for which (start <= event position < start + numSamples) will
|
|
be removed.
|
|
*/
|
|
void clear (const int start,
|
|
const int numSamples) throw();
|
|
|
|
/** Returns true if the buffer is empty.
|
|
|
|
To actually retrieve the events, use a MidiBuffer::Iterator object
|
|
*/
|
|
bool isEmpty() const throw();
|
|
|
|
/** Counts the number of events in the buffer.
|
|
|
|
This is actually quite a slow operation, as it has to iterate through all
|
|
the events, so you might prefer to call isEmpty() if that's all you need
|
|
to know.
|
|
*/
|
|
int getNumEvents() const throw();
|
|
|
|
/** Adds an event to the buffer.
|
|
|
|
The sample number will be used to determine the position of the event in
|
|
the buffer, which is always kept sorted. The MidiMessage's timestamp is
|
|
ignored.
|
|
|
|
If an event is added whose sample position is the same as one or more events
|
|
already in the buffer, the new event will be placed after the existing ones.
|
|
|
|
To retrieve events, use a MidiBuffer::Iterator object
|
|
*/
|
|
void addEvent (const MidiMessage& midiMessage,
|
|
const int sampleNumber) throw();
|
|
|
|
/** Adds an event to the buffer from raw midi data.
|
|
|
|
The sample number will be used to determine the position of the event in
|
|
the buffer, which is always kept sorted.
|
|
|
|
If an event is added whose sample position is the same as one or more events
|
|
already in the buffer, the new event will be placed after the existing ones.
|
|
|
|
The event data will be inspected to calculate the number of bytes in length that
|
|
the midi event really takes up, so maxBytesOfMidiData may be longer than the data
|
|
that actually gets stored. E.g. if you pass in a note-on and a length of 4 bytes,
|
|
it'll actually only store 3 bytes. If the midi data is invalid, it might not
|
|
add an event at all.
|
|
|
|
To retrieve events, use a MidiBuffer::Iterator object
|
|
*/
|
|
void addEvent (const uint8* const rawMidiData,
|
|
const int maxBytesOfMidiData,
|
|
const int sampleNumber) throw();
|
|
|
|
/** Adds some events from another buffer to this one.
|
|
|
|
@param otherBuffer the buffer containing the events you want to add
|
|
@param startSample the lowest sample number in the source buffer for which
|
|
events should be added. Any source events whose timestamp is
|
|
less than this will be ignored
|
|
@param numSamples the valid range of samples from the source buffer for which
|
|
events should be added - i.e. events in the source buffer whose
|
|
timestamp is greater than or equal to (startSample + numSamples)
|
|
will be ignored. If this value is less than 0, all events after
|
|
startSample will be taken.
|
|
@param sampleDeltaToAdd a value which will be added to the source timestamps of the events
|
|
that are added to this buffer
|
|
*/
|
|
void addEvents (const MidiBuffer& otherBuffer,
|
|
const int startSample,
|
|
const int numSamples,
|
|
const int sampleDeltaToAdd) throw();
|
|
|
|
/** Returns the sample number of the first event in the buffer.
|
|
|
|
If the buffer's empty, this will just return 0.
|
|
*/
|
|
int getFirstEventTime() const throw();
|
|
|
|
/** Returns the sample number of the last event in the buffer.
|
|
|
|
If the buffer's empty, this will just return 0.
|
|
*/
|
|
int getLastEventTime() const throw();
|
|
|
|
/** Exchanges the contents of this buffer with another one.
|
|
|
|
This is a quick operation, because no memory allocating or copying is done, it
|
|
just swaps the internal state of the two buffers.
|
|
*/
|
|
void swap (MidiBuffer& other);
|
|
|
|
/**
|
|
Used to iterate through the events in a MidiBuffer.
|
|
|
|
Note that altering the buffer while an iterator is using it isn't a
|
|
safe operation.
|
|
|
|
@see MidiBuffer
|
|
*/
|
|
class Iterator
|
|
{
|
|
public:
|
|
|
|
/** Creates an Iterator for this MidiBuffer. */
|
|
Iterator (const MidiBuffer& buffer) throw();
|
|
|
|
/** Destructor. */
|
|
~Iterator() throw();
|
|
|
|
/** Repositions the iterator so that the next event retrieved will be the first
|
|
one whose sample position is at greater than or equal to the given position.
|
|
*/
|
|
void setNextSamplePosition (const int samplePosition) throw();
|
|
|
|
/** Retrieves a copy of the next event from the buffer.
|
|
|
|
@param result on return, this will be the message (the MidiMessage's timestamp
|
|
is not set)
|
|
@param samplePosition on return, this will be the position of the event
|
|
@returns true if an event was found, or false if the iterator has reached
|
|
the end of the buffer
|
|
*/
|
|
bool getNextEvent (MidiMessage& result,
|
|
int& samplePosition) throw();
|
|
|
|
/** Retrieves the next event from the buffer.
|
|
|
|
@param midiData on return, this pointer will be set to a block of data containing
|
|
the midi message. Note that to make it fast, this is a pointer
|
|
directly into the MidiBuffer's internal data, so is only valid
|
|
temporarily until the MidiBuffer is altered.
|
|
@param numBytesOfMidiData on return, this is the number of bytes of data used by the
|
|
midi message
|
|
@param samplePosition on return, this will be the position of the event
|
|
@returns true if an event was found, or false if the iterator has reached
|
|
the end of the buffer
|
|
*/
|
|
bool getNextEvent (const uint8* &midiData,
|
|
int& numBytesOfMidiData,
|
|
int& samplePosition) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
const MidiBuffer& buffer;
|
|
const uint8* data;
|
|
|
|
Iterator (const Iterator&);
|
|
const Iterator& operator= (const Iterator&);
|
|
};
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class MidiBuffer::Iterator;
|
|
int bytesUsed;
|
|
|
|
uint8* findEventAfter (uint8* d, const int samplePosition) const throw();
|
|
};
|
|
|
|
#endif // __JUCE_MIDIBUFFER_JUCEHEADER__
|
|
/********* End of inlined file: juce_MidiBuffer.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MIDIFILE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MidiFile.h *********/
|
|
#ifndef __JUCE_MIDIFILE_JUCEHEADER__
|
|
#define __JUCE_MIDIFILE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MidiMessageSequence.h *********/
|
|
#ifndef __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__
|
|
#define __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__
|
|
|
|
/**
|
|
A sequence of timestamped midi messages.
|
|
|
|
This allows the sequence to be manipulated, and also to be read from and
|
|
written to a standard midi file.
|
|
|
|
@see MidiMessage, MidiFile
|
|
*/
|
|
class JUCE_API MidiMessageSequence
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty midi sequence object. */
|
|
MidiMessageSequence();
|
|
|
|
/** Creates a copy of another sequence. */
|
|
MidiMessageSequence (const MidiMessageSequence& other);
|
|
|
|
/** Replaces this sequence with another one. */
|
|
const MidiMessageSequence& operator= (const MidiMessageSequence& other);
|
|
|
|
/** Destructor. */
|
|
~MidiMessageSequence();
|
|
|
|
/** Structure used to hold midi events in the sequence.
|
|
|
|
These structures act as 'handles' on the events as they are moved about in
|
|
the list, and make it quick to find the matching note-offs for note-on events.
|
|
|
|
@see MidiMessageSequence::getEventPointer
|
|
*/
|
|
class MidiEventHolder
|
|
{
|
|
public:
|
|
|
|
/** Destructor. */
|
|
~MidiEventHolder();
|
|
|
|
/** The message itself, whose timestamp is used to specify the event's time.
|
|
*/
|
|
MidiMessage message;
|
|
|
|
/** The matching note-off event (if this is a note-on event).
|
|
|
|
If this isn't a note-on, this pointer will be null.
|
|
|
|
Use the MidiMessageSequence::updateMatchedPairs() method to keep these
|
|
note-offs up-to-date after events have been moved around in the sequence
|
|
or deleted.
|
|
*/
|
|
MidiEventHolder* noteOffObject;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class MidiMessageSequence;
|
|
MidiEventHolder (const MidiMessage& message);
|
|
};
|
|
|
|
/** Clears the sequence. */
|
|
void clear();
|
|
|
|
/** Returns the number of events in the sequence. */
|
|
int getNumEvents() const;
|
|
|
|
/** Returns a pointer to one of the events. */
|
|
MidiEventHolder* getEventPointer (const int index) const;
|
|
|
|
/** Returns the time of the note-up that matches the note-on at this index.
|
|
|
|
If the event at this index isn't a note-on, it'll just return 0.
|
|
|
|
@see MidiMessageSequence::MidiEventHolder::noteOffObject
|
|
*/
|
|
double getTimeOfMatchingKeyUp (const int index) const;
|
|
|
|
/** Returns the index of the note-up that matches the note-on at this index.
|
|
|
|
If the event at this index isn't a note-on, it'll just return -1.
|
|
|
|
@see MidiMessageSequence::MidiEventHolder::noteOffObject
|
|
*/
|
|
int getIndexOfMatchingKeyUp (const int index) const;
|
|
|
|
/** Returns the index of an event. */
|
|
int getIndexOf (MidiEventHolder* const event) const;
|
|
|
|
/** Returns the index of the first event on or after the given timestamp.
|
|
|
|
If the time is beyond the end of the sequence, this will return the
|
|
number of events.
|
|
*/
|
|
int getNextIndexAtTime (const double timeStamp) const;
|
|
|
|
/** Returns the timestamp of the first event in the sequence.
|
|
|
|
@see getEndTime
|
|
*/
|
|
double getStartTime() const;
|
|
|
|
/** Returns the timestamp of the last event in the sequence.
|
|
|
|
@see getStartTime
|
|
*/
|
|
double getEndTime() const;
|
|
|
|
/** Returns the timestamp of the event at a given index.
|
|
|
|
If the index is out-of-range, this will return 0.0
|
|
*/
|
|
double getEventTime (const int index) const;
|
|
|
|
/** Inserts a midi message into the sequence.
|
|
|
|
The index at which the new message gets inserted will depend on its timestamp,
|
|
because the sequence is kept sorted.
|
|
|
|
Remember to call updateMatchedPairs() after adding note-on events.
|
|
|
|
@param newMessage the new message to add (an internal copy will be made)
|
|
@param timeAdjustment an optional value to add to the timestamp of the message
|
|
that will be inserted
|
|
@see updateMatchedPairs
|
|
*/
|
|
void addEvent (const MidiMessage& newMessage,
|
|
double timeAdjustment = 0);
|
|
|
|
/** Deletes one of the events in the sequence.
|
|
|
|
Remember to call updateMatchedPairs() after removing events.
|
|
|
|
@param index the index of the event to delete
|
|
@param deleteMatchingNoteUp whether to also remove the matching note-off
|
|
if the event you're removing is a note-on
|
|
*/
|
|
void deleteEvent (const int index,
|
|
const bool deleteMatchingNoteUp);
|
|
|
|
/** Merges another sequence into this one.
|
|
|
|
Remember to call updateMatchedPairs() after using this method.
|
|
|
|
@param other the sequence to add from
|
|
@param timeAdjustmentDelta an amount to add to the timestamps of the midi events
|
|
as they are read from the other sequence
|
|
@param firstAllowableDestTime events will not be added if their time is earlier
|
|
than this time. (This is after their time has been adjusted
|
|
by the timeAdjustmentDelta)
|
|
@param endOfAllowableDestTimes events will not be added if their time is equal to
|
|
or greater than this time. (This is after their time has
|
|
been adjusted by the timeAdjustmentDelta)
|
|
*/
|
|
void addSequence (const MidiMessageSequence& other,
|
|
double timeAdjustmentDelta,
|
|
double firstAllowableDestTime,
|
|
double endOfAllowableDestTimes);
|
|
|
|
/** Makes sure all the note-on and note-off pairs are up-to-date.
|
|
|
|
Call this after moving messages about or deleting/adding messages, and it
|
|
will scan the list and make sure all the note-offs in the MidiEventHolder
|
|
structures are pointing at the correct ones.
|
|
*/
|
|
void updateMatchedPairs();
|
|
|
|
/** Copies all the messages for a particular midi channel to another sequence.
|
|
|
|
@param channelNumberToExtract the midi channel to look for, in the range 1 to 16
|
|
@param destSequence the sequence that the chosen events should be copied to
|
|
@param alsoIncludeMetaEvents if true, any meta-events (which don't apply to a specific
|
|
channel) will also be copied across.
|
|
@see extractSysExMessages
|
|
*/
|
|
void extractMidiChannelMessages (const int channelNumberToExtract,
|
|
MidiMessageSequence& destSequence,
|
|
const bool alsoIncludeMetaEvents) const;
|
|
|
|
/** Copies all midi sys-ex messages to another sequence.
|
|
|
|
@param destSequence this is the sequence to which any sys-exes in this sequence
|
|
will be added
|
|
@see extractMidiChannelMessages
|
|
*/
|
|
void extractSysExMessages (MidiMessageSequence& destSequence) const;
|
|
|
|
/** Removes any messages in this sequence that have a specific midi channel.
|
|
|
|
@param channelNumberToRemove the midi channel to look for, in the range 1 to 16
|
|
*/
|
|
void deleteMidiChannelMessages (const int channelNumberToRemove);
|
|
|
|
/** Removes any sys-ex messages from this sequence.
|
|
*/
|
|
void deleteSysExMessages();
|
|
|
|
/** Adds an offset to the timestamps of all events in the sequence.
|
|
|
|
@param deltaTime the amount to add to each timestamp.
|
|
*/
|
|
void addTimeToMessages (const double deltaTime);
|
|
|
|
/** Scans through the sequence to determine the state of any midi controllers at
|
|
a given time.
|
|
|
|
This will create a sequence of midi controller changes that can be
|
|
used to set all midi controllers to the state they would be in at the
|
|
specified time within this sequence.
|
|
|
|
As well as controllers, it will also recreate the midi program number
|
|
and pitch bend position.
|
|
|
|
@param channelNumber the midi channel to look for, in the range 1 to 16. Controllers
|
|
for other channels will be ignored.
|
|
@param time the time at which you want to find out the state - there are
|
|
no explicit units for this time measurement, it's the same units
|
|
as used for the timestamps of the messages
|
|
@param resultMessages an array to which midi controller-change messages will be added. This
|
|
will be the minimum number of controller changes to recreate the
|
|
state at the required time.
|
|
*/
|
|
void createControllerUpdatesForTime (const int channelNumber,
|
|
const double time,
|
|
OwnedArray<MidiMessage>& resultMessages);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
/** @internal */
|
|
static int compareElements (const MidiMessageSequence::MidiEventHolder* const first,
|
|
const MidiMessageSequence::MidiEventHolder* const second) throw();
|
|
|
|
private:
|
|
|
|
friend class MidiComparator;
|
|
friend class MidiFile;
|
|
OwnedArray <MidiEventHolder> list;
|
|
|
|
void sort();
|
|
};
|
|
|
|
#endif // __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_MidiMessageSequence.h *********/
|
|
|
|
/**
|
|
Reads/writes standard midi format files.
|
|
|
|
To read a midi file, create a MidiFile object and call its readFrom() method. You
|
|
can then get the individual midi tracks from it using the getTrack() method.
|
|
|
|
To write a file, create a MidiFile object, add some MidiMessageSequence objects
|
|
to it using the addTrack() method, and then call its writeTo() method to stream
|
|
it out.
|
|
|
|
@see MidiMessageSequence
|
|
*/
|
|
class JUCE_API MidiFile
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty MidiFile object.
|
|
*/
|
|
MidiFile() throw();
|
|
|
|
/** Destructor. */
|
|
~MidiFile() throw();
|
|
|
|
/** Returns the number of tracks in the file.
|
|
|
|
@see getTrack, addTrack
|
|
*/
|
|
int getNumTracks() const throw();
|
|
|
|
/** Returns a pointer to one of the tracks in the file.
|
|
|
|
@returns a pointer to the track, or 0 if the index is out-of-range
|
|
@see getNumTracks, addTrack
|
|
*/
|
|
const MidiMessageSequence* getTrack (const int index) const throw();
|
|
|
|
/** Adds a midi track to the file.
|
|
|
|
This will make its own internal copy of the sequence that is passed-in.
|
|
|
|
@see getNumTracks, getTrack
|
|
*/
|
|
void addTrack (const MidiMessageSequence& trackSequence) throw();
|
|
|
|
/** Removes all midi tracks from the file.
|
|
|
|
@see getNumTracks
|
|
*/
|
|
void clear() throw();
|
|
|
|
/** Returns the raw time format code that will be written to a stream.
|
|
|
|
After reading a midi file, this method will return the time-format that
|
|
was read from the file's header. It can be changed using the setTicksPerQuarterNote()
|
|
or setSmpteTimeFormat() methods.
|
|
|
|
If the value returned is positive, it indicates the number of midi ticks
|
|
per quarter-note - see setTicksPerQuarterNote().
|
|
|
|
It it's negative, the upper byte indicates the frames-per-second (but negative), and
|
|
the lower byte is the number of ticks per frame - see setSmpteTimeFormat().
|
|
*/
|
|
short getTimeFormat() const throw();
|
|
|
|
/** Sets the time format to use when this file is written to a stream.
|
|
|
|
If this is called, the file will be written as bars/beats using the
|
|
specified resolution, rather than SMPTE absolute times, as would be
|
|
used if setSmpteTimeFormat() had been called instead.
|
|
|
|
@param ticksPerQuarterNote e.g. 96, 960
|
|
@see setSmpteTimeFormat
|
|
*/
|
|
void setTicksPerQuarterNote (const int ticksPerQuarterNote) throw();
|
|
|
|
/** Sets the time format to use when this file is written to a stream.
|
|
|
|
If this is called, the file will be written using absolute times, rather
|
|
than bars/beats as would be the case if setTicksPerBeat() had been called
|
|
instead.
|
|
|
|
@param framesPerSecond must be 24, 25, 29 or 30
|
|
@param subframeResolution the sub-second resolution, e.g. 4 (midi time code),
|
|
8, 10, 80 (SMPTE bit resolution), or 100. For millisecond
|
|
timing, setSmpteTimeFormat (25, 40)
|
|
@see setTicksPerBeat
|
|
*/
|
|
void setSmpteTimeFormat (const int framesPerSecond,
|
|
const int subframeResolution) throw();
|
|
|
|
/** Makes a list of all the tempo-change meta-events from all tracks in the midi file.
|
|
|
|
Useful for finding the positions of all the tempo changes in a file.
|
|
|
|
@param tempoChangeEvents a list to which all the events will be added
|
|
*/
|
|
void findAllTempoEvents (MidiMessageSequence& tempoChangeEvents) const;
|
|
|
|
/** Makes a list of all the time-signature meta-events from all tracks in the midi file.
|
|
|
|
Useful for finding the positions of all the tempo changes in a file.
|
|
|
|
@param timeSigEvents a list to which all the events will be added
|
|
*/
|
|
void findAllTimeSigEvents (MidiMessageSequence& timeSigEvents) const;
|
|
|
|
/** Returns the latest timestamp in any of the tracks.
|
|
|
|
(Useful for finding the length of the file).
|
|
*/
|
|
double getLastTimestamp() const;
|
|
|
|
/** Reads a midi file format stream.
|
|
|
|
After calling this, you can get the tracks that were read from the file by using the
|
|
getNumTracks() and getTrack() methods.
|
|
|
|
The timestamps of the midi events in the tracks will represent their positions in
|
|
terms of midi ticks. To convert them to seconds, use the convertTimestampTicksToSeconds()
|
|
method.
|
|
|
|
@returns true if the stream was read successfully
|
|
*/
|
|
bool readFrom (InputStream& sourceStream);
|
|
|
|
/** Writes the midi tracks as a standard midi file.
|
|
|
|
@returns true if the operation succeeded.
|
|
*/
|
|
bool writeTo (OutputStream& destStream);
|
|
|
|
/** Converts the timestamp of all the midi events from midi ticks to seconds.
|
|
|
|
This will use the midi time format and tempo/time signature info in the
|
|
tracks to convert all the timestamps to absolute values in seconds.
|
|
*/
|
|
void convertTimestampTicksToSeconds();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
/** @internal */
|
|
static int compareElements (const MidiMessageSequence::MidiEventHolder* const first,
|
|
const MidiMessageSequence::MidiEventHolder* const second) throw();
|
|
|
|
private:
|
|
MidiMessageSequence* tracks [128];
|
|
short numTracks, timeFormat;
|
|
|
|
MidiFile (const MidiFile&);
|
|
const MidiFile& operator= (const MidiFile&);
|
|
|
|
void readNextTrack (const char* data, int size);
|
|
void writeTrack (OutputStream& mainOut, const int trackNum);
|
|
};
|
|
|
|
#endif // __JUCE_MIDIFILE_JUCEHEADER__
|
|
/********* End of inlined file: juce_MidiFile.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MidiKeyboardState.h *********/
|
|
#ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__
|
|
#define __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__
|
|
|
|
class MidiKeyboardState;
|
|
|
|
/**
|
|
Receives events from a MidiKeyboardState object.
|
|
|
|
@see MidiKeyboardState
|
|
*/
|
|
class JUCE_API MidiKeyboardStateListener
|
|
{
|
|
public:
|
|
|
|
MidiKeyboardStateListener() throw() {}
|
|
virtual ~MidiKeyboardStateListener() {}
|
|
|
|
/** Called when one of the MidiKeyboardState's keys is pressed.
|
|
|
|
This will be called synchronously when the state is either processing a
|
|
buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
|
|
when a note is being played with its MidiKeyboardState::noteOn() method.
|
|
|
|
Note that this callback could happen from an audio callback thread, so be
|
|
careful not to block, and avoid any UI activity in the callback.
|
|
*/
|
|
virtual void handleNoteOn (MidiKeyboardState* source,
|
|
int midiChannel, int midiNoteNumber, float velocity) = 0;
|
|
|
|
/** Called when one of the MidiKeyboardState's keys is released.
|
|
|
|
This will be called synchronously when the state is either processing a
|
|
buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
|
|
when a note is being played with its MidiKeyboardState::noteOff() method.
|
|
|
|
Note that this callback could happen from an audio callback thread, so be
|
|
careful not to block, and avoid any UI activity in the callback.
|
|
*/
|
|
virtual void handleNoteOff (MidiKeyboardState* source,
|
|
int midiChannel, int midiNoteNumber) = 0;
|
|
};
|
|
|
|
/**
|
|
Represents a piano keyboard, keeping track of which keys are currently pressed.
|
|
|
|
This object can parse a stream of midi events, using them to update its idea
|
|
of which keys are pressed for each individiual midi channel.
|
|
|
|
When keys go up or down, it can broadcast these events to listener objects.
|
|
|
|
It also allows key up/down events to be triggered with its noteOn() and noteOff()
|
|
methods, and midi messages for these events will be merged into the
|
|
midi stream that gets processed by processNextMidiBuffer().
|
|
*/
|
|
class JUCE_API MidiKeyboardState
|
|
{
|
|
public:
|
|
|
|
MidiKeyboardState();
|
|
~MidiKeyboardState();
|
|
|
|
/** Resets the state of the object.
|
|
|
|
All internal data for all the channels is reset, but no events are sent as a
|
|
result.
|
|
|
|
If you want to release any keys that are currently down, and to send out note-up
|
|
midi messages for this, use the allNotesOff() method instead.
|
|
*/
|
|
void reset();
|
|
|
|
/** Returns true if the given midi key is currently held down for the given midi channel.
|
|
|
|
The channel number must be between 1 and 16. If you want to see if any notes are
|
|
on for a range of channels, use the isNoteOnForChannels() method.
|
|
*/
|
|
bool isNoteOn (const int midiChannel, const int midiNoteNumber) const throw();
|
|
|
|
/** Returns true if the given midi key is currently held down on any of a set of midi channels.
|
|
|
|
The channel mask has a bit set for each midi channel you want to test for - bit
|
|
0 = midi channel 1, bit 1 = midi channel 2, etc.
|
|
|
|
If a note is on for at least one of the specified channels, this returns true.
|
|
*/
|
|
bool isNoteOnForChannels (const int midiChannelMask, const int midiNoteNumber) const throw();
|
|
|
|
/** Turns a specified note on.
|
|
|
|
This will cause a suitable midi note-on event to be injected into the midi buffer during the
|
|
next call to processNextMidiBuffer().
|
|
|
|
It will also trigger a synchronous callback to the listeners to tell them that the key has
|
|
gone down.
|
|
*/
|
|
void noteOn (const int midiChannel, const int midiNoteNumber, const float velocity);
|
|
|
|
/** Turns a specified note off.
|
|
|
|
This will cause a suitable midi note-off event to be injected into the midi buffer during the
|
|
next call to processNextMidiBuffer().
|
|
|
|
It will also trigger a synchronous callback to the listeners to tell them that the key has
|
|
gone up.
|
|
|
|
But if the note isn't acutally down for the given channel, this method will in fact do nothing.
|
|
*/
|
|
void noteOff (const int midiChannel, const int midiNoteNumber);
|
|
|
|
/** This will turn off any currently-down notes for the given midi channel.
|
|
|
|
If you pass 0 for the midi channel, it will in fact turn off all notes on all channels.
|
|
|
|
Calling this method will make calls to noteOff(), so can trigger synchronous callbacks
|
|
and events being added to the midi stream.
|
|
*/
|
|
void allNotesOff (const int midiChannel);
|
|
|
|
/** Looks at a key-up/down event and uses it to update the state of this object.
|
|
|
|
To process a buffer full of midi messages, use the processNextMidiBuffer() method
|
|
instead.
|
|
*/
|
|
void processNextMidiEvent (const MidiMessage& message);
|
|
|
|
/** Scans a midi stream for up/down events and adds its own events to it.
|
|
|
|
This will look for any up/down events and use them to update the internal state,
|
|
synchronously making suitable callbacks to the listeners.
|
|
|
|
If injectIndirectEvents is true, then midi events to produce the recent noteOn()
|
|
and noteOff() calls will be added into the buffer.
|
|
|
|
Only the section of the buffer whose timestamps are between startSample and
|
|
(startSample + numSamples) will be affected, and any events added will be placed
|
|
between these times.
|
|
|
|
If you're going to use this method, you'll need to keep calling it regularly for
|
|
it to work satisfactorily.
|
|
|
|
To process a single midi event at a time, use the processNextMidiEvent() method
|
|
instead.
|
|
*/
|
|
void processNextMidiBuffer (MidiBuffer& buffer,
|
|
const int startSample,
|
|
const int numSamples,
|
|
const bool injectIndirectEvents);
|
|
|
|
/** Registers a listener for callbacks when keys go up or down.
|
|
|
|
@see removeListener
|
|
*/
|
|
void addListener (MidiKeyboardStateListener* const listener) throw();
|
|
|
|
/** Deregisters a listener.
|
|
|
|
@see addListener
|
|
*/
|
|
void removeListener (MidiKeyboardStateListener* const listener) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
CriticalSection lock;
|
|
uint16 noteStates [128];
|
|
MidiBuffer eventsToAdd;
|
|
VoidArray listeners;
|
|
|
|
void noteOnInternal (const int midiChannel, const int midiNoteNumber, const float velocity);
|
|
void noteOffInternal (const int midiChannel, const int midiNoteNumber);
|
|
|
|
MidiKeyboardState (const MidiKeyboardState&);
|
|
const MidiKeyboardState& operator= (const MidiKeyboardState&);
|
|
};
|
|
|
|
#endif // __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__
|
|
/********* End of inlined file: juce_MidiKeyboardState.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MIDIMESSAGE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MidiMessageCollector.h *********/
|
|
#ifndef __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__
|
|
#define __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MidiInput.h *********/
|
|
#ifndef __JUCE_MIDIINPUT_JUCEHEADER__
|
|
#define __JUCE_MIDIINPUT_JUCEHEADER__
|
|
|
|
class MidiInput;
|
|
|
|
/**
|
|
Receives midi messages from a midi input device.
|
|
|
|
This class is overridden to handle incoming midi messages. See the MidiInput
|
|
class for more details.
|
|
|
|
@see MidiInput
|
|
*/
|
|
class JUCE_API MidiInputCallback
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~MidiInputCallback() {}
|
|
|
|
/** Receives an incoming message.
|
|
|
|
A MidiInput object will call this method when a midi event arrives. It'll be
|
|
called on a high-priority system thread, so avoid doing anything time-consuming
|
|
in here, and avoid making any UI calls. You might find the MidiBuffer class helpful
|
|
for queueing incoming messages for use later.
|
|
|
|
@param source the MidiInput object that generated the message
|
|
@param message the incoming message. The message's timestamp is set to a value
|
|
equivalent to (Time::getMillisecondCounter() / 1000.0) to specify the
|
|
time when the message arrived.
|
|
*/
|
|
virtual void handleIncomingMidiMessage (MidiInput* source,
|
|
const MidiMessage& message) = 0;
|
|
|
|
/** Notification sent each time a packet of a multi-packet sysex message arrives.
|
|
|
|
If a long sysex message is broken up into multiple packets, this callback is made
|
|
for each packet that arrives until the message is finished, at which point
|
|
the normal handleIncomingMidiMessage() callback will be made with the entire
|
|
message.
|
|
|
|
The message passed in will contain the start of a sysex, but won't be finished
|
|
with the terminating 0xf7 byte.
|
|
*/
|
|
virtual void handlePartialSysexMessage (MidiInput* source,
|
|
const uint8* messageData,
|
|
const int numBytesSoFar,
|
|
const double timestamp)
|
|
{
|
|
// (this bit is just to avoid compiler warnings about unused variables)
|
|
(void) source; (void) messageData; (void) numBytesSoFar; (void) timestamp;
|
|
}
|
|
};
|
|
|
|
/**
|
|
Represents a midi input device.
|
|
|
|
To create one of these, use the static getDevices() method to find out what inputs are
|
|
available, and then use the openDevice() method to try to open one.
|
|
|
|
@see MidiOutput
|
|
*/
|
|
class JUCE_API MidiInput
|
|
{
|
|
public:
|
|
|
|
/** Returns a list of the available midi input devices.
|
|
|
|
You can open one of the devices by passing its index into the
|
|
openDevice() method.
|
|
|
|
@see getDefaultDeviceIndex, openDevice
|
|
*/
|
|
static const StringArray getDevices();
|
|
|
|
/** Returns the index of the default midi input device to use.
|
|
|
|
This refers to the index in the list returned by getDevices().
|
|
*/
|
|
static int getDefaultDeviceIndex();
|
|
|
|
/** Tries to open one of the midi input devices.
|
|
|
|
This will return a MidiInput object if it manages to open it. You can then
|
|
call start() and stop() on this device, and delete it when no longer needed.
|
|
|
|
If the device can't be opened, this will return a null pointer.
|
|
|
|
@param deviceIndex the index of a device from the list returned by getDevices()
|
|
@param callback the object that will receive the midi messages from this device.
|
|
|
|
@see MidiInputCallback, getDevices
|
|
*/
|
|
static MidiInput* openDevice (int deviceIndex,
|
|
MidiInputCallback* callback);
|
|
|
|
#if JUCE_LINUX || DOXYGEN
|
|
/** LINUX ONLY - This will try to create a new midi input device.
|
|
|
|
This will attempt to create a new midi input device with the specified name,
|
|
for other apps to connect to.
|
|
|
|
Returns 0 if a device can't be created.
|
|
|
|
@param deviceName the name to use for the new device
|
|
@param callback the object that will receive the midi messages from this device.
|
|
*/
|
|
static MidiInput* createNewDevice (const String& deviceName,
|
|
MidiInputCallback* callback);
|
|
#endif
|
|
|
|
/** Destructor. */
|
|
virtual ~MidiInput();
|
|
|
|
/** Returns the name of this device.
|
|
*/
|
|
virtual const String getName() const throw() { return name; }
|
|
|
|
/** Allows you to set a custom name for the device, in case you don't like the name
|
|
it was given when created.
|
|
*/
|
|
virtual void setName (const String& newName) throw() { name = newName; }
|
|
|
|
/** Starts the device running.
|
|
|
|
After calling this, the device will start sending midi messages to the
|
|
MidiInputCallback object that was specified when the openDevice() method
|
|
was called.
|
|
|
|
@see stop
|
|
*/
|
|
virtual void start();
|
|
|
|
/** Stops the device running.
|
|
|
|
@see start
|
|
*/
|
|
virtual void stop();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
String name;
|
|
void* internal;
|
|
|
|
MidiInput (const String& name);
|
|
MidiInput (const MidiInput&);
|
|
};
|
|
|
|
#endif // __JUCE_MIDIINPUT_JUCEHEADER__
|
|
/********* End of inlined file: juce_MidiInput.h *********/
|
|
|
|
/**
|
|
Collects incoming realtime MIDI messages and turns them into blocks suitable for
|
|
processing by a block-based audio callback.
|
|
|
|
The class can also be used as either a MidiKeyboardStateListener or a MidiInputCallback
|
|
so it can easily use a midi input or keyboard component as its source.
|
|
|
|
@see MidiMessage, MidiInput
|
|
*/
|
|
class JUCE_API MidiMessageCollector : public MidiKeyboardStateListener,
|
|
public MidiInputCallback
|
|
{
|
|
public:
|
|
|
|
/** Creates a MidiMessageCollector. */
|
|
MidiMessageCollector();
|
|
|
|
/** Destructor. */
|
|
~MidiMessageCollector();
|
|
|
|
/** Clears any messages from the queue.
|
|
|
|
You need to call this method before starting to use the collector, so that
|
|
it knows the correct sample rate to use.
|
|
*/
|
|
void reset (const double sampleRate);
|
|
|
|
/** Takes an incoming real-time message and adds it to the queue.
|
|
|
|
The message's timestamp is taken, and it will be ready for retrieval as part
|
|
of the block returned by the next call to removeNextBlockOfMessages().
|
|
|
|
This method is fully thread-safe when overlapping calls are made with
|
|
removeNextBlockOfMessages().
|
|
*/
|
|
void addMessageToQueue (const MidiMessage& message);
|
|
|
|
/** Removes all the pending messages from the queue as a buffer.
|
|
|
|
This will also correct the messages' timestamps to make sure they're in
|
|
the range 0 to numSamples - 1.
|
|
|
|
This call should be made regularly by something like an audio processing
|
|
callback, because the time that it happens is used in calculating the
|
|
midi event positions.
|
|
|
|
This method is fully thread-safe when overlapping calls are made with
|
|
addMessageToQueue().
|
|
*/
|
|
void removeNextBlockOfMessages (MidiBuffer& destBuffer,
|
|
const int numSamples);
|
|
|
|
/** @internal */
|
|
void handleNoteOn (MidiKeyboardState* source, int midiChannel, int midiNoteNumber, float velocity);
|
|
/** @internal */
|
|
void handleNoteOff (MidiKeyboardState* source, int midiChannel, int midiNoteNumber);
|
|
/** @internal */
|
|
void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
double lastCallbackTime;
|
|
CriticalSection midiCallbackLock;
|
|
MidiBuffer incomingMessages;
|
|
double sampleRate;
|
|
|
|
MidiMessageCollector (const MidiMessageCollector&);
|
|
const MidiMessageCollector& operator= (const MidiMessageCollector&);
|
|
};
|
|
|
|
#endif // __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__
|
|
/********* End of inlined file: juce_MidiMessageCollector.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioDataConverters.h *********/
|
|
#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__
|
|
#define __JUCE_AUDIODATACONVERTERS_JUCEHEADER__
|
|
|
|
/**
|
|
A set of routines to convert buffers of 32-bit floating point data to and from
|
|
various integer formats.
|
|
|
|
*/
|
|
class JUCE_API AudioDataConverters
|
|
{
|
|
public:
|
|
|
|
static void convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 2);
|
|
static void convertFloatToInt16BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 2);
|
|
|
|
static void convertFloatToInt24LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 3);
|
|
static void convertFloatToInt24BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 3);
|
|
|
|
static void convertFloatToInt32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4);
|
|
static void convertFloatToInt32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4);
|
|
|
|
static void convertFloatToFloat32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4);
|
|
static void convertFloatToFloat32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4);
|
|
|
|
static void convertInt16LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 2);
|
|
static void convertInt16BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 2);
|
|
|
|
static void convertInt24LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 3);
|
|
static void convertInt24BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 3);
|
|
|
|
static void convertInt32LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4);
|
|
static void convertInt32BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4);
|
|
|
|
static void convertFloat32LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4);
|
|
static void convertFloat32BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4);
|
|
|
|
enum DataFormat
|
|
{
|
|
int16LE,
|
|
int16BE,
|
|
int24LE,
|
|
int24BE,
|
|
int32LE,
|
|
int32BE,
|
|
float32LE,
|
|
float32BE,
|
|
};
|
|
|
|
static void convertFloatToFormat (const DataFormat destFormat,
|
|
const float* source, void* dest, int numSamples);
|
|
|
|
static void convertFormatToFloat (const DataFormat sourceFormat,
|
|
const void* source, float* dest, int numSamples);
|
|
|
|
static void interleaveSamples (const float** source, float* dest,
|
|
const int numSamples, const int numChannels);
|
|
|
|
static void deinterleaveSamples (const float* source, float** dest,
|
|
const int numSamples, const int numChannels);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIODATACONVERTERS_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioDataConverters.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioSampleBuffer.h *********/
|
|
#ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__
|
|
#define __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__
|
|
|
|
class AudioFormatReader;
|
|
class AudioFormatWriter;
|
|
|
|
/**
|
|
A multi-channel buffer of 32-bit floating point audio samples.
|
|
|
|
*/
|
|
class JUCE_API AudioSampleBuffer
|
|
{
|
|
public:
|
|
|
|
/** Creates a buffer with a specified number of channels and samples.
|
|
|
|
The contents of the buffer will initially be undefined, so use clear() to
|
|
set all the samples to zero.
|
|
|
|
The buffer will allocate its memory internally, and this will be released
|
|
when the buffer is deleted.
|
|
*/
|
|
AudioSampleBuffer (const int numChannels,
|
|
const int numSamples) throw();
|
|
|
|
/** Creates a buffer using a pre-allocated block of memory.
|
|
|
|
Note that if the buffer is resized or its number of channels is changed, it
|
|
will re-allocate memory internally and copy the existing data to this new area,
|
|
so it will then stop directly addressing this memory.
|
|
|
|
@param dataToReferTo a pre-allocated array containing pointers to the data
|
|
for each channel that should be used by this buffer. The
|
|
buffer will only refer to this memory, it won't try to delete
|
|
it when the buffer is deleted or resized.
|
|
@param numChannels the number of channels to use - this must correspond to the
|
|
number of elements in the array passed in
|
|
@param numSamples the number of samples to use - this must correspond to the
|
|
size of the arrays passed in
|
|
*/
|
|
AudioSampleBuffer (float** dataToReferTo,
|
|
const int numChannels,
|
|
const int numSamples) throw();
|
|
|
|
/** Copies another buffer.
|
|
|
|
This buffer will make its own copy of the other's data, unless the buffer was created
|
|
using an external data buffer, in which case boths buffers will just point to the same
|
|
shared block of data.
|
|
*/
|
|
AudioSampleBuffer (const AudioSampleBuffer& other) throw();
|
|
|
|
/** Copies another buffer onto this one.
|
|
|
|
This buffer's size will be changed to that of the other buffer.
|
|
*/
|
|
const AudioSampleBuffer& operator= (const AudioSampleBuffer& other) throw();
|
|
|
|
/** Destructor.
|
|
|
|
This will free any memory allocated by the buffer.
|
|
*/
|
|
virtual ~AudioSampleBuffer() throw();
|
|
|
|
/** Returns the number of channels of audio data that this buffer contains.
|
|
|
|
@see getSampleData
|
|
*/
|
|
int getNumChannels() const throw() { return numChannels; }
|
|
|
|
/** Returns the number of samples allocated in each of the buffer's channels.
|
|
|
|
@see getSampleData
|
|
*/
|
|
int getNumSamples() const throw() { return size; }
|
|
|
|
/** Returns a pointer one of the buffer's channels.
|
|
|
|
For speed, this doesn't check whether the channel number is out of range,
|
|
so be careful when using it!
|
|
*/
|
|
float* getSampleData (const int channelNumber) const throw()
|
|
{
|
|
jassert (((unsigned int) channelNumber) < (unsigned int) numChannels);
|
|
return channels [channelNumber];
|
|
}
|
|
|
|
/** Returns a pointer to a sample in one of the buffer's channels.
|
|
|
|
For speed, this doesn't check whether the channel and sample number
|
|
are out-of-range, so be careful when using it!
|
|
*/
|
|
float* getSampleData (const int channelNumber,
|
|
const int sampleOffset) const throw()
|
|
{
|
|
jassert (((unsigned int) channelNumber) < (unsigned int) numChannels);
|
|
jassert (((unsigned int) sampleOffset) < (unsigned int) size);
|
|
return channels [channelNumber] + sampleOffset;
|
|
}
|
|
|
|
/** Returns an array of pointers to the channels in the buffer.
|
|
|
|
Don't modify any of the pointers that are returned, and bear in mind that
|
|
these will become invalid if the buffer is resized.
|
|
*/
|
|
float** getArrayOfChannels() const throw() { return channels; }
|
|
|
|
/** Chages the buffer's size or number of channels.
|
|
|
|
This can expand or contract the buffer's length, and add or remove channels.
|
|
|
|
If keepExistingContent is true, it will try to preserve as much of the
|
|
old data as it can in the new buffer.
|
|
|
|
If clearExtraSpace is true, then any extra channels or space that is
|
|
allocated will be also be cleared. If false, then this space is left
|
|
uninitialised.
|
|
|
|
If avoidReallocating is true, then changing the buffer's size won't reduce the
|
|
amount of memory that is currently allocated (but it will still increase it if
|
|
the new size is bigger than the amount it currently has). If this is false, then
|
|
a new allocation will be done so that the buffer uses takes up the minimum amount
|
|
of memory that it needs.
|
|
*/
|
|
void setSize (const int newNumChannels,
|
|
const int newNumSamples,
|
|
const bool keepExistingContent = false,
|
|
const bool clearExtraSpace = false,
|
|
const bool avoidReallocating = false) throw();
|
|
|
|
/** Makes this buffer point to a pre-allocated set of channel data arrays.
|
|
|
|
There's also a constructor that lets you specify arrays like this, but this
|
|
lets you change the channels dynamically.
|
|
|
|
Note that if the buffer is resized or its number of channels is changed, it
|
|
will re-allocate memory internally and copy the existing data to this new area,
|
|
so it will then stop directly addressing this memory.
|
|
|
|
@param dataToReferTo a pre-allocated array containing pointers to the data
|
|
for each channel that should be used by this buffer. The
|
|
buffer will only refer to this memory, it won't try to delete
|
|
it when the buffer is deleted or resized.
|
|
@param numChannels the number of channels to use - this must correspond to the
|
|
number of elements in the array passed in
|
|
@param numSamples the number of samples to use - this must correspond to the
|
|
size of the arrays passed in
|
|
*/
|
|
void setDataToReferTo (float** dataToReferTo,
|
|
const int numChannels,
|
|
const int numSamples) throw();
|
|
|
|
/** Clears all the samples in all channels. */
|
|
void clear() throw();
|
|
|
|
/** Clears a specified region of all the channels.
|
|
|
|
For speed, this doesn't check whether the channel and sample number
|
|
are in-range, so be careful!
|
|
*/
|
|
void clear (const int startSample,
|
|
const int numSamples) throw();
|
|
|
|
/** Clears a specified region of just one channel.
|
|
|
|
For speed, this doesn't check whether the channel and sample number
|
|
are in-range, so be careful!
|
|
*/
|
|
void clear (const int channel,
|
|
const int startSample,
|
|
const int numSamples) throw();
|
|
|
|
/** Applies a gain multiple to a region of one channel.
|
|
|
|
For speed, this doesn't check whether the channel and sample number
|
|
are in-range, so be careful!
|
|
*/
|
|
void applyGain (const int channel,
|
|
const int startSample,
|
|
int numSamples,
|
|
const float gain) throw();
|
|
|
|
/** Applies a gain multiple to a region of all the channels.
|
|
|
|
For speed, this doesn't check whether the sample numbers
|
|
are in-range, so be careful!
|
|
*/
|
|
void applyGain (const int startSample,
|
|
const int numSamples,
|
|
const float gain) throw();
|
|
|
|
/** Applies a range of gains to a region of a channel.
|
|
|
|
The gain that is applied to each sample will vary from
|
|
startGain on the first sample to endGain on the last Sample,
|
|
so it can be used to do basic fades.
|
|
|
|
For speed, this doesn't check whether the sample numbers
|
|
are in-range, so be careful!
|
|
*/
|
|
void applyGainRamp (const int channel,
|
|
const int startSample,
|
|
int numSamples,
|
|
float startGain,
|
|
float endGain) throw();
|
|
|
|
/** Adds samples from another buffer to this one.
|
|
|
|
@param destChannel the channel within this buffer to add the samples to
|
|
@param destStartSample the start sample within this buffer's channel
|
|
@param source the source buffer to add from
|
|
@param sourceChannel the channel within the source buffer to read from
|
|
@param sourceStartSample the offset within the source buffer's channel to start reading samples from
|
|
@param numSamples the number of samples to process
|
|
@param gainToApplyToSource an optional gain to apply to the source samples before they are
|
|
added to this buffer's samples
|
|
|
|
@see copyFrom
|
|
*/
|
|
void addFrom (const int destChannel,
|
|
const int destStartSample,
|
|
const AudioSampleBuffer& source,
|
|
const int sourceChannel,
|
|
const int sourceStartSample,
|
|
int numSamples,
|
|
const float gainToApplyToSource = 1.0f) throw();
|
|
|
|
/** Adds samples from an array of floats to one of the channels.
|
|
|
|
@param destChannel the channel within this buffer to add the samples to
|
|
@param destStartSample the start sample within this buffer's channel
|
|
@param source the source data to use
|
|
@param numSamples the number of samples to process
|
|
@param gainToApplyToSource an optional gain to apply to the source samples before they are
|
|
added to this buffer's samples
|
|
|
|
@see copyFrom
|
|
*/
|
|
void addFrom (const int destChannel,
|
|
const int destStartSample,
|
|
const float* source,
|
|
int numSamples,
|
|
const float gainToApplyToSource = 1.0f) throw();
|
|
|
|
/** Adds samples from an array of floats, applying a gain ramp to them.
|
|
|
|
@param destChannel the channel within this buffer to add the samples to
|
|
@param destStartSample the start sample within this buffer's channel
|
|
@param source the source data to use
|
|
@param numSamples the number of samples to process
|
|
@param startGain the gain to apply to the first sample (this is multiplied with
|
|
the source samples before they are added to this buffer)
|
|
@param endGain the gain to apply to the final sample. The gain is linearly
|
|
interpolated between the first and last samples.
|
|
*/
|
|
void addFromWithRamp (const int destChannel,
|
|
const int destStartSample,
|
|
const float* source,
|
|
int numSamples,
|
|
float startGain,
|
|
float endGain) throw();
|
|
|
|
/** Copies samples from another buffer to this one.
|
|
|
|
@param destChannel the channel within this buffer to copy the samples to
|
|
@param destStartSample the start sample within this buffer's channel
|
|
@param source the source buffer to read from
|
|
@param sourceChannel the channel within the source buffer to read from
|
|
@param sourceStartSample the offset within the source buffer's channel to start reading samples from
|
|
@param numSamples the number of samples to process
|
|
|
|
@see addFrom
|
|
*/
|
|
void copyFrom (const int destChannel,
|
|
const int destStartSample,
|
|
const AudioSampleBuffer& source,
|
|
const int sourceChannel,
|
|
const int sourceStartSample,
|
|
int numSamples) throw();
|
|
|
|
/** Copies samples from an array of floats into one of the channels.
|
|
|
|
@param destChannel the channel within this buffer to copy the samples to
|
|
@param destStartSample the start sample within this buffer's channel
|
|
@param source the source buffer to read from
|
|
@param numSamples the number of samples to process
|
|
|
|
@see addFrom
|
|
*/
|
|
void copyFrom (const int destChannel,
|
|
const int destStartSample,
|
|
const float* source,
|
|
int numSamples) throw();
|
|
|
|
/** Copies samples from an array of floats into one of the channels, applying a gain to it.
|
|
|
|
@param destChannel the channel within this buffer to copy the samples to
|
|
@param destStartSample the start sample within this buffer's channel
|
|
@param source the source buffer to read from
|
|
@param numSamples the number of samples to process
|
|
@param gain the gain to apply
|
|
|
|
@see addFrom
|
|
*/
|
|
void copyFrom (const int destChannel,
|
|
const int destStartSample,
|
|
const float* source,
|
|
int numSamples,
|
|
const float gain) throw();
|
|
|
|
/** Copies samples from an array of floats into one of the channels, applying a gain ramp.
|
|
|
|
@param destChannel the channel within this buffer to copy the samples to
|
|
@param destStartSample the start sample within this buffer's channel
|
|
@param source the source buffer to read from
|
|
@param numSamples the number of samples to process
|
|
@param startGain the gain to apply to the first sample (this is multiplied with
|
|
the source samples before they are copied to this buffer)
|
|
@param endGain the gain to apply to the final sample. The gain is linearly
|
|
interpolated between the first and last samples.
|
|
|
|
@see addFrom
|
|
*/
|
|
void copyFromWithRamp (const int destChannel,
|
|
const int destStartSample,
|
|
const float* source,
|
|
int numSamples,
|
|
float startGain,
|
|
float endGain) throw();
|
|
|
|
/** Finds the highest and lowest sample values in a given range.
|
|
|
|
@param channel the channel to read from
|
|
@param startSample the start sample within the channel
|
|
@param numSamples the number of samples to check
|
|
@param minVal on return, the lowest value that was found
|
|
@param maxVal on return, the highest value that was found
|
|
*/
|
|
void findMinMax (const int channel,
|
|
const int startSample,
|
|
int numSamples,
|
|
float& minVal,
|
|
float& maxVal) const throw();
|
|
|
|
/** Finds the highest absolute sample value within a region of a channel.
|
|
*/
|
|
float getMagnitude (const int channel,
|
|
const int startSample,
|
|
const int numSamples) const throw();
|
|
|
|
/** Finds the highest absolute sample value within a region on all channels.
|
|
*/
|
|
float getMagnitude (const int startSample,
|
|
const int numSamples) const throw();
|
|
|
|
/** Returns the root mean squared level for a region of a channel.
|
|
*/
|
|
float getRMSLevel (const int channel,
|
|
const int startSample,
|
|
const int numSamples) const throw();
|
|
|
|
/** Fills a section of the buffer using an AudioReader as its source.
|
|
|
|
This will convert the reader's fixed- or floating-point data to
|
|
the buffer's floating-point format, and will try to intelligently
|
|
cope with mismatches between the number of channels in the reader
|
|
and the buffer.
|
|
|
|
@see writeToAudioWriter
|
|
*/
|
|
void readFromAudioReader (AudioFormatReader* reader,
|
|
const int startSample,
|
|
const int numSamples,
|
|
const int readerStartSample,
|
|
const bool useReaderLeftChan,
|
|
const bool useReaderRightChan) throw();
|
|
|
|
/** Writes a section of this buffer to an audio writer.
|
|
|
|
This saves you having to mess about with channels or floating/fixed
|
|
point conversion.
|
|
|
|
@see readFromAudioReader
|
|
*/
|
|
void writeToAudioWriter (AudioFormatWriter* writer,
|
|
const int startSample,
|
|
const int numSamples) const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int numChannels, size, allocatedBytes;
|
|
float** channels;
|
|
float* allocatedData;
|
|
float* preallocatedChannelSpace [32];
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioSampleBuffer.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_IIRFILTER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_IIRFilter.h *********/
|
|
#ifndef __JUCE_IIRFILTER_JUCEHEADER__
|
|
#define __JUCE_IIRFILTER_JUCEHEADER__
|
|
|
|
/**
|
|
An IIR filter that can perform low, high, or band-pass filtering on an
|
|
audio signal.
|
|
|
|
@see IIRFilterAudioSource
|
|
*/
|
|
class JUCE_API IIRFilter
|
|
{
|
|
public:
|
|
|
|
/** Creates a filter.
|
|
|
|
Initially the filter is inactive, so will have no effect on samples that
|
|
you process with it. Use the appropriate method to turn it into the type
|
|
of filter needed.
|
|
*/
|
|
IIRFilter() throw();
|
|
|
|
/** Creates a copy of another filter. */
|
|
IIRFilter (const IIRFilter& other) throw();
|
|
|
|
/** Destructor. */
|
|
~IIRFilter() throw();
|
|
|
|
/** Resets the filter's processing pipeline, ready to start a new stream of data.
|
|
|
|
Note that this clears the processing state, but the type of filter and
|
|
its coefficients aren't changed. To put a filter into an inactive state, use
|
|
the makeInactive() method.
|
|
*/
|
|
void reset() throw();
|
|
|
|
/** Performs the filter operation on the given set of samples.
|
|
*/
|
|
void processSamples (float* const samples,
|
|
const int numSamples) throw();
|
|
|
|
/** Processes a single sample, without any locking or checking.
|
|
|
|
Use this if you need fast processing of a single value, but be aware that
|
|
this isn't thread-safe in the way that processSamples() is.
|
|
*/
|
|
float processSingleSampleRaw (const float sample) throw();
|
|
|
|
/** Sets the filter up to act as a low-pass filter.
|
|
*/
|
|
void makeLowPass (const double sampleRate,
|
|
const double frequency) throw();
|
|
|
|
/** Sets the filter up to act as a high-pass filter.
|
|
*/
|
|
void makeHighPass (const double sampleRate,
|
|
const double frequency) throw();
|
|
|
|
/** Sets the filter up to act as a low-pass shelf filter with variable Q and gain.
|
|
|
|
The gain is a scale factor that the low frequencies are multiplied by, so values
|
|
greater than 1.0 will boost the low frequencies, values less than 1.0 will
|
|
attenuate them.
|
|
*/
|
|
void makeLowShelf (const double sampleRate,
|
|
const double cutOffFrequency,
|
|
const double Q,
|
|
const float gainFactor) throw();
|
|
|
|
/** Sets the filter up to act as a high-pass shelf filter with variable Q and gain.
|
|
|
|
The gain is a scale factor that the high frequencies are multiplied by, so values
|
|
greater than 1.0 will boost the high frequencies, values less than 1.0 will
|
|
attenuate them.
|
|
*/
|
|
void makeHighShelf (const double sampleRate,
|
|
const double cutOffFrequency,
|
|
const double Q,
|
|
const float gainFactor) throw();
|
|
|
|
/** Sets the filter up to act as a band pass filter centred around a
|
|
frequency, with a variable Q and gain.
|
|
|
|
The gain is a scale factor that the centre frequencies are multiplied by, so
|
|
values greater than 1.0 will boost the centre frequencies, values less than
|
|
1.0 will attenuate them.
|
|
*/
|
|
void makeBandPass (const double sampleRate,
|
|
const double centreFrequency,
|
|
const double Q,
|
|
const float gainFactor) throw();
|
|
|
|
/** Clears the filter's coefficients so that it becomes inactive.
|
|
*/
|
|
void makeInactive() throw();
|
|
|
|
/** Makes this filter duplicate the set-up of another one.
|
|
*/
|
|
void copyCoefficientsFrom (const IIRFilter& other) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
CriticalSection processLock;
|
|
|
|
void setCoefficients (double c1, double c2, double c3,
|
|
double c4, double c5, double c6) throw();
|
|
|
|
bool active;
|
|
float coefficients[6];
|
|
float x1, x2, y1, y2;
|
|
|
|
// (use the copyCoefficientsFrom() method instead of this operator)
|
|
const IIRFilter& operator= (const IIRFilter&);
|
|
};
|
|
|
|
#endif // __JUCE_IIRFILTER_JUCEHEADER__
|
|
/********* End of inlined file: juce_IIRFilter.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOPLAYHEAD_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioPlayHead.h *********/
|
|
#ifndef __JUCE_AUDIOPLAYHEAD_JUCEHEADER__
|
|
#define __JUCE_AUDIOPLAYHEAD_JUCEHEADER__
|
|
|
|
/**
|
|
A subclass of AudioPlayHead can supply information about the position and
|
|
status of a moving play head during audio playback.
|
|
|
|
One of these can be supplied to an AudioProcessor object so that it can find
|
|
out about the position of the audio that it is rendering.
|
|
|
|
@see AudioProcessor::setPlayHead, AudioProcessor::getPlayHead
|
|
*/
|
|
class JUCE_API AudioPlayHead
|
|
{
|
|
protected:
|
|
|
|
AudioPlayHead() {}
|
|
|
|
public:
|
|
virtual ~AudioPlayHead() {}
|
|
|
|
/** Frame rate types. */
|
|
enum FrameRateType
|
|
{
|
|
fps24 = 0,
|
|
fps25 = 1,
|
|
fps2997 = 2,
|
|
fps30 = 3,
|
|
fps2997drop = 4,
|
|
fps30drop = 5,
|
|
fpsUnknown = 99
|
|
};
|
|
|
|
/** This structure is filled-in by the AudioPlayHead::getCurrentPosition() method.
|
|
*/
|
|
struct CurrentPositionInfo
|
|
{
|
|
/** The tempo in BPM */
|
|
double bpm;
|
|
|
|
/** Time signature numerator, e.g. the 3 of a 3/4 time sig */
|
|
int timeSigNumerator;
|
|
/** Time signature denominator, e.g. the 4 of a 3/4 time sig */
|
|
int timeSigDenominator;
|
|
|
|
/** The current play position, in seconds from the start of the edit. */
|
|
double timeInSeconds;
|
|
|
|
/** For timecode, the position of the start of the edit, in seconds from 00:00:00:00. */
|
|
double editOriginTime;
|
|
|
|
/** The current play position in pulses-per-quarter-note.
|
|
|
|
This is the number of quarter notes since the edit start.
|
|
*/
|
|
double ppqPosition;
|
|
|
|
/** The position of the start of the last bar, in pulses-per-quarter-note.
|
|
|
|
This is the number of quarter notes from the start of the edit to the
|
|
start of the current bar.
|
|
|
|
Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If
|
|
it's not available, the value will be 0.
|
|
*/
|
|
double ppqPositionOfLastBarStart;
|
|
|
|
/** The video frame rate, if applicable. */
|
|
FrameRateType frameRate;
|
|
|
|
/** True if the transport is currently playing. */
|
|
bool isPlaying;
|
|
|
|
/** True if the transport is currently recording.
|
|
|
|
(When isRecording is true, then isPlaying will also be true).
|
|
*/
|
|
bool isRecording;
|
|
};
|
|
|
|
/** Fills-in the given structure with details about the transport's
|
|
position at the start of the current processing block.
|
|
*/
|
|
virtual bool getCurrentPosition (CurrentPositionInfo& result) = 0;
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOPLAYHEAD_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioPlayHead.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOPROCESSOR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioProcessor.h *********/
|
|
#ifndef __JUCE_AUDIOPROCESSOR_JUCEHEADER__
|
|
#define __JUCE_AUDIOPROCESSOR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioProcessorEditor.h *********/
|
|
#ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__
|
|
#define __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__
|
|
|
|
class AudioProcessor;
|
|
|
|
/**
|
|
Base class for the component that acts as the GUI for an AudioProcessor.
|
|
|
|
Derive your editor component from this class, and create an instance of it
|
|
by overriding the AudioProcessor::createEditor() method.
|
|
|
|
@see AudioProcessor, GenericAudioProcessorEditor
|
|
*/
|
|
class JUCE_API AudioProcessorEditor : public Component
|
|
{
|
|
protected:
|
|
|
|
/** Creates an editor for the specified processor.
|
|
*/
|
|
AudioProcessorEditor (AudioProcessor* const owner);
|
|
|
|
public:
|
|
/** Destructor. */
|
|
~AudioProcessorEditor();
|
|
|
|
/** Returns a pointer to the processor that this editor represents. */
|
|
AudioProcessor* getAudioProcessor() const throw() { return owner; }
|
|
|
|
private:
|
|
|
|
AudioProcessor* const owner;
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioProcessorEditor.h *********/
|
|
|
|
/********* Start of inlined file: juce_AudioProcessorListener.h *********/
|
|
#ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__
|
|
#define __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__
|
|
|
|
class AudioProcessor;
|
|
|
|
/**
|
|
Base class for listeners that want to know about changes to an AudioProcessor.
|
|
|
|
Use AudioProcessor::addListener() to register your listener with an AudioProcessor.
|
|
|
|
@see AudioProcessor
|
|
*/
|
|
class JUCE_API AudioProcessorListener
|
|
{
|
|
public:
|
|
|
|
/** Destructor. */
|
|
virtual ~AudioProcessorListener() {}
|
|
|
|
/** Receives a callback when a parameter is changed.
|
|
|
|
IMPORTANT NOTE: this will be called synchronously when a parameter changes, and
|
|
many audio processors will change their parameter during their audio callback.
|
|
This means that not only has your handler code got to be completely thread-safe,
|
|
but it's also got to be VERY fast, and avoid blocking. If you need to handle
|
|
this event on your message thread, use this callback to trigger an AsyncUpdater
|
|
or ChangeBroadcaster which you can respond to on the message thread.
|
|
*/
|
|
virtual void audioProcessorParameterChanged (AudioProcessor* processor,
|
|
int parameterIndex,
|
|
float newValue) = 0;
|
|
|
|
/** Called to indicate that something else in the plugin has changed, like its
|
|
program, number of parameters, etc.
|
|
|
|
IMPORTANT NOTE: this will be called synchronously, and many audio processors will
|
|
call it during their audio callback. This means that not only has your handler code
|
|
got to be completely thread-safe, but it's also got to be VERY fast, and avoid
|
|
blocking. If you need to handle this event on your message thread, use this callback
|
|
to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the
|
|
message thread.
|
|
*/
|
|
virtual void audioProcessorChanged (AudioProcessor* processor) = 0;
|
|
|
|
/** Indicates that a parameter change gesture has started.
|
|
|
|
E.g. if the user is dragging a slider, this would be called when they first
|
|
press the mouse button, and audioProcessorParameterChangeGestureEnd would be
|
|
called when they release it.
|
|
|
|
IMPORTANT NOTE: this will be called synchronously, and many audio processors will
|
|
call it during their audio callback. This means that not only has your handler code
|
|
got to be completely thread-safe, but it's also got to be VERY fast, and avoid
|
|
blocking. If you need to handle this event on your message thread, use this callback
|
|
to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the
|
|
message thread.
|
|
|
|
@see audioProcessorParameterChangeGestureEnd
|
|
*/
|
|
virtual void audioProcessorParameterChangeGestureBegin (AudioProcessor* processor,
|
|
int parameterIndex);
|
|
|
|
/** Indicates that a parameter change gesture has finished.
|
|
|
|
E.g. if the user is dragging a slider, this would be called when they release
|
|
the mouse button.
|
|
|
|
IMPORTANT NOTE: this will be called synchronously, and many audio processors will
|
|
call it during their audio callback. This means that not only has your handler code
|
|
got to be completely thread-safe, but it's also got to be VERY fast, and avoid
|
|
blocking. If you need to handle this event on your message thread, use this callback
|
|
to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the
|
|
message thread.
|
|
|
|
@see audioPluginParameterChangeGestureStart
|
|
*/
|
|
virtual void audioProcessorParameterChangeGestureEnd (AudioProcessor* processor,
|
|
int parameterIndex);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioProcessorListener.h *********/
|
|
|
|
/**
|
|
Base class for audio processing filters or plugins.
|
|
|
|
This is intended to act as a base class of audio filter that is general enough to
|
|
be wrapped as a VST, AU, RTAS, etc, or used internally.
|
|
|
|
It is also used by the plugin hosting code as the wrapper around an instance
|
|
of a loaded plugin.
|
|
|
|
Derive your filter class from this base class, and if you're building a plugin,
|
|
you should implement a global function called createPluginFilter() which creates
|
|
and returns a new instance of your subclass.
|
|
*/
|
|
class JUCE_API AudioProcessor
|
|
{
|
|
protected:
|
|
|
|
/** Constructor.
|
|
|
|
You can also do your initialisation tasks in the initialiseFilterInfo()
|
|
call, which will be made after this object has been created.
|
|
*/
|
|
AudioProcessor();
|
|
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~AudioProcessor();
|
|
|
|
/** Returns the name of this processor.
|
|
*/
|
|
virtual const String getName() const = 0;
|
|
|
|
/** Called before playback starts, to let the filter prepare itself.
|
|
|
|
The sample rate is the target sample rate, and will remain constant until
|
|
playback stops.
|
|
|
|
The estimatedSamplesPerBlock value is a HINT about the typical number of
|
|
samples that will be processed for each callback, but isn't any kind
|
|
of guarantee. The actual block sizes that the host uses may be different
|
|
each time the callback happens, and may be more or less than this value.
|
|
*/
|
|
virtual void prepareToPlay (double sampleRate,
|
|
int estimatedSamplesPerBlock) = 0;
|
|
|
|
/** Called after playback has stopped, to let the filter free up any resources it
|
|
no longer needs.
|
|
*/
|
|
virtual void releaseResources() = 0;
|
|
|
|
/** Renders the next block.
|
|
|
|
When this method is called, the buffer contains a number of channels which is
|
|
at least as great as the maximum number of input and output channels that
|
|
this filter is using. It will be filled with the filter's input data and
|
|
should be replaced with the filter's output.
|
|
|
|
So for example if your filter has 2 input channels and 4 output channels, then
|
|
the buffer will contain 4 channels, the first two being filled with the
|
|
input data. Your filter should read these, do its processing, and replace
|
|
the contents of all 4 channels with its output.
|
|
|
|
Or if your filter has 5 inputs and 2 outputs, the buffer will have 5 channels,
|
|
all filled with data, and your filter should overwrite the first 2 of these
|
|
with its output. But be VERY careful not to write anything to the last 3
|
|
channels, as these might be mapped to memory that the host assumes is read-only!
|
|
|
|
Note that if you have more outputs than inputs, then only those channels that
|
|
correspond to an input channel are guaranteed to contain sensible data - e.g.
|
|
in the case of 2 inputs and 4 outputs, the first two channels contain the input,
|
|
but the last two channels may contain garbage, so you should be careful not to
|
|
let this pass through without being overwritten or cleared.
|
|
|
|
Also note that the buffer may have more channels than are strictly necessary,
|
|
but your should only read/write from the ones that your filter is supposed to
|
|
be using.
|
|
|
|
The number of samples in these buffers is NOT guaranteed to be the same for every
|
|
callback, and may be more or less than the estimated value given to prepareToPlay().
|
|
Your code must be able to cope with variable-sized blocks, or you're going to get
|
|
clicks and crashes!
|
|
|
|
If the filter is receiving a midi input, then the midiMessages array will be filled
|
|
with the midi messages for this block. Each message's timestamp will indicate the
|
|
message's time, as a number of samples from the start of the block.
|
|
|
|
Any messages left in the midi buffer when this method has finished are assumed to
|
|
be the filter's midi output. This means that your filter should be careful to
|
|
clear any incoming messages from the array if it doesn't want them to be passed-on.
|
|
|
|
Be very careful about what you do in this callback - it's going to be called by
|
|
the audio thread, so any kind of interaction with the UI is absolutely
|
|
out of the question. If you change a parameter in here and need to tell your UI to
|
|
update itself, the best way is probably to inherit from a ChangeBroadcaster, let
|
|
the UI components register as listeners, and then call sendChangeMessage() inside the
|
|
processBlock() method to send out an asynchronous message. You could also use
|
|
the AsyncUpdater class in a similar way.
|
|
*/
|
|
virtual void processBlock (AudioSampleBuffer& buffer,
|
|
MidiBuffer& midiMessages) = 0;
|
|
|
|
/** Returns the current AudioPlayHead object that should be used to find
|
|
out the state and position of the playhead.
|
|
|
|
You can call this from your processBlock() method, and use the AudioPlayHead
|
|
object to get the details about the time of the start of the block currently
|
|
being processed.
|
|
|
|
If the host hasn't supplied a playhead object, this will return 0.
|
|
*/
|
|
AudioPlayHead* getPlayHead() const throw() { return playHead; }
|
|
|
|
/** Returns the current sample rate.
|
|
|
|
This can be called from your processBlock() method - it's not guaranteed
|
|
to be valid at any other time, and may return 0 if it's unknown.
|
|
*/
|
|
double getSampleRate() const throw() { return sampleRate; }
|
|
|
|
/** Returns the current typical block size that is being used.
|
|
|
|
This can be called from your processBlock() method - it's not guaranteed
|
|
to be valid at any other time.
|
|
|
|
Remember it's not the ONLY block size that may be used when calling
|
|
processBlock, it's just the normal one. The actual block sizes used may be
|
|
larger or smaller than this, and will vary between successive calls.
|
|
*/
|
|
int getBlockSize() const throw() { return blockSize; }
|
|
|
|
/** Returns the number of input channels that the host will be sending the filter.
|
|
|
|
If writing a plugin, your JucePluginCharacteristics.h file should specify the
|
|
number of channels that your filter would prefer to have, and this method lets
|
|
you know how many the host is actually using.
|
|
|
|
Note that this method is only valid during or after the prepareToPlay()
|
|
method call. Until that point, the number of channels will be unknown.
|
|
*/
|
|
int getNumInputChannels() const throw() { return numInputChannels; }
|
|
|
|
/** Returns the number of output channels that the host will be sending the filter.
|
|
|
|
If writing a plugin, your JucePluginCharacteristics.h file should specify the
|
|
number of channels that your filter would prefer to have, and this method lets
|
|
you know how many the host is actually using.
|
|
|
|
Note that this method is only valid during or after the prepareToPlay()
|
|
method call. Until that point, the number of channels will be unknown.
|
|
*/
|
|
int getNumOutputChannels() const throw() { return numOutputChannels; }
|
|
|
|
/** Returns the name of one of the input channels, as returned by the host.
|
|
|
|
The host might not supply very useful names for channels, and this might be
|
|
something like "1", "2", "left", "right", etc.
|
|
*/
|
|
virtual const String getInputChannelName (const int channelIndex) const = 0;
|
|
|
|
/** Returns the name of one of the output channels, as returned by the host.
|
|
|
|
The host might not supply very useful names for channels, and this might be
|
|
something like "1", "2", "left", "right", etc.
|
|
*/
|
|
virtual const String getOutputChannelName (const int channelIndex) const = 0;
|
|
|
|
/** Returns true if the specified channel is part of a stereo pair with its neighbour. */
|
|
virtual bool isInputChannelStereoPair (int index) const = 0;
|
|
|
|
/** Returns true if the specified channel is part of a stereo pair with its neighbour. */
|
|
virtual bool isOutputChannelStereoPair (int index) const = 0;
|
|
|
|
/** This returns the number of samples delay that the filter imposes on the audio
|
|
passing through it.
|
|
|
|
The host will call this to find the latency - the filter itself should set this value
|
|
by calling setLatencySamples() as soon as it can during its initialisation.
|
|
*/
|
|
int getLatencySamples() const throw() { return latencySamples; }
|
|
|
|
/** The filter should call this to set the number of samples delay that it introduces.
|
|
|
|
The filter should call this as soon as it can during initialisation, and can call it
|
|
later if the value changes.
|
|
*/
|
|
void setLatencySamples (const int newLatency);
|
|
|
|
/** Returns true if the processor wants midi messages. */
|
|
virtual bool acceptsMidi() const = 0;
|
|
|
|
/** Returns true if the processor produces midi messages. */
|
|
virtual bool producesMidi() const = 0;
|
|
|
|
/** This returns a critical section that will automatically be locked while the host
|
|
is calling the processBlock() method.
|
|
|
|
Use it from your UI or other threads to lock access to variables that are used
|
|
by the process callback, but obviously be careful not to keep it locked for
|
|
too long, because that could cause stuttering playback. If you need to do something
|
|
that'll take a long time and need the processing to stop while it happens, use the
|
|
suspendProcessing() method instead.
|
|
|
|
@see suspendProcessing
|
|
*/
|
|
const CriticalSection& getCallbackLock() const throw() { return callbackLock; }
|
|
|
|
/** Enables and disables the processing callback.
|
|
|
|
If you need to do something time-consuming on a thread and would like to make sure
|
|
the audio processing callback doesn't happen until you've finished, use this
|
|
to disable the callback and re-enable it again afterwards.
|
|
|
|
E.g.
|
|
@code
|
|
void loadNewPatch()
|
|
{
|
|
suspendProcessing (true);
|
|
|
|
..do something that takes ages..
|
|
|
|
suspendProcessing (false);
|
|
}
|
|
@endcode
|
|
|
|
If the host tries to make an audio callback while processing is suspended, the
|
|
filter will return an empty buffer, but won't block the audio thread like it would
|
|
do if you use the getCallbackLock() critical section to synchronise access.
|
|
|
|
If you're going to use this, your processBlock() method must call isSuspended() and
|
|
check whether it's suspended or not. If it is, then it should skip doing any real
|
|
processing, either emitting silence or passing the input through unchanged.
|
|
|
|
@see getCallbackLock
|
|
*/
|
|
void suspendProcessing (const bool shouldBeSuspended);
|
|
|
|
/** Returns true if processing is currently suspended.
|
|
@see suspendProcessing
|
|
*/
|
|
bool isSuspended() const throw() { return suspended; }
|
|
|
|
/** A plugin can override this to be told when it should reset any playing voices.
|
|
|
|
The default implementation does nothing, but a host may call this to tell the
|
|
plugin that it should stop any tails or sounds that have been left running.
|
|
*/
|
|
virtual void reset();
|
|
|
|
/** Returns true if the processor is being run in an offline mode for rendering.
|
|
|
|
If the processor is being run live on realtime signals, this returns false.
|
|
If the mode is unknown, this will assume it's realtime and return false.
|
|
|
|
This value may be unreliable until the prepareToPlay() method has been called,
|
|
and could change each time prepareToPlay() is called.
|
|
|
|
@see setNonRealtime()
|
|
*/
|
|
bool isNonRealtime() const throw() { return nonRealtime; }
|
|
|
|
/** Called by the host to tell this processor whether it's being used in a non-realime
|
|
capacity for offline rendering or bouncing.
|
|
|
|
Whatever value is passed-in will be
|
|
*/
|
|
void setNonRealtime (const bool isNonRealtime) throw();
|
|
|
|
/** Creates the filter's UI.
|
|
|
|
This can return 0 if you want a UI-less filter, in which case the host may create
|
|
a generic UI that lets the user twiddle the parameters directly.
|
|
|
|
If you do want to pass back a component, the component should be created and set to
|
|
the correct size before returning it.
|
|
|
|
Remember not to do anything silly like allowing your filter to keep a pointer to
|
|
the component that gets created - it could be deleted later without any warning, which
|
|
would make your pointer into a dangler. Use the getActiveEditor() method instead.
|
|
|
|
The correct way to handle the connection between an editor component and its
|
|
filter is to use something like a ChangeBroadcaster so that the editor can
|
|
register itself as a listener, and be told when a change occurs. This lets them
|
|
safely unregister themselves when they are deleted.
|
|
|
|
Here are a few things to bear in mind when writing an editor:
|
|
|
|
- Initially there won't be an editor, until the user opens one, or they might
|
|
not open one at all. Your filter mustn't rely on it being there.
|
|
- An editor object may be deleted and a replacement one created again at any time.
|
|
- It's safe to assume that an editor will be deleted before its filter.
|
|
*/
|
|
virtual AudioProcessorEditor* createEditor() = 0;
|
|
|
|
/** Returns the active editor, if there is one.
|
|
|
|
Bear in mind this can return 0, even if an editor has previously been
|
|
opened.
|
|
*/
|
|
AudioProcessorEditor* getActiveEditor() const throw() { return activeEditor; }
|
|
|
|
/** Returns the active editor, or if there isn't one, it will create one.
|
|
|
|
This may call createEditor() internally to create the component.
|
|
*/
|
|
AudioProcessorEditor* createEditorIfNeeded();
|
|
|
|
/** This must return the correct value immediately after the object has been
|
|
created, and mustn't change the number of parameters later.
|
|
*/
|
|
virtual int getNumParameters() = 0;
|
|
|
|
/** Returns the name of a particular parameter. */
|
|
virtual const String getParameterName (int parameterIndex) = 0;
|
|
|
|
/** Called by the host to find out the value of one of the filter's parameters.
|
|
|
|
The host will expect the value returned to be between 0 and 1.0.
|
|
|
|
This could be called quite frequently, so try to make your code efficient.
|
|
It's also likely to be called by non-UI threads, so the code in here should
|
|
be thread-aware.
|
|
*/
|
|
virtual float getParameter (int parameterIndex) = 0;
|
|
|
|
/** Returns the value of a parameter as a text string. */
|
|
virtual const String getParameterText (int parameterIndex) = 0;
|
|
|
|
/** The host will call this method to change the value of one of the filter's parameters.
|
|
|
|
The host may call this at any time, including during the audio processing
|
|
callback, so the filter has to process this very fast and avoid blocking.
|
|
|
|
If you want to set the value of a parameter internally, e.g. from your
|
|
editor component, then don't call this directly - instead, use the
|
|
setParameterNotifyingHost() method, which will also send a message to
|
|
the host telling it about the change. If the message isn't sent, the host
|
|
won't be able to automate your parameters properly.
|
|
|
|
The value passed will be between 0 and 1.0.
|
|
*/
|
|
virtual void setParameter (int parameterIndex,
|
|
float newValue) = 0;
|
|
|
|
/** Your filter can call this when it needs to change one of its parameters.
|
|
|
|
This could happen when the editor or some other internal operation changes
|
|
a parameter. This method will call the setParameter() method to change the
|
|
value, and will then send a message to the host telling it about the change.
|
|
|
|
Note that to make sure the host correctly handles automation, you should call
|
|
the beginParameterChangeGesture() and endParameterChangeGesture() methods to
|
|
tell the host when the user has started and stopped changing the parameter.
|
|
*/
|
|
void setParameterNotifyingHost (int parameterIndex,
|
|
float newValue);
|
|
|
|
/** Returns true if the host can automate this parameter.
|
|
|
|
By default, this returns true for all parameters.
|
|
*/
|
|
virtual bool isParameterAutomatable (int parameterIndex) const;
|
|
|
|
/** Should return true if this parameter is a "meta" parameter.
|
|
|
|
A meta-parameter is a parameter that changes other params. It is used
|
|
by some hosts (e.g. AudioUnit hosts).
|
|
|
|
By default this returns false.
|
|
*/
|
|
virtual bool isMetaParameter (int parameterIndex) const;
|
|
|
|
/** Sends a signal to the host to tell it that the user is about to start changing this
|
|
parameter.
|
|
|
|
This allows the host to know when a parameter is actively being held by the user, and
|
|
it may use this information to help it record automation.
|
|
|
|
If you call this, it must be matched by a later call to endParameterChangeGesture().
|
|
*/
|
|
void beginParameterChangeGesture (int parameterIndex);
|
|
|
|
/** Tells the host that the user has finished changing this parameter.
|
|
|
|
This allows the host to know when a parameter is actively being held by the user, and
|
|
it may use this information to help it record automation.
|
|
|
|
A call to this method must follow a call to beginParameterChangeGesture().
|
|
*/
|
|
void endParameterChangeGesture (int parameterIndex);
|
|
|
|
/** The filter can call this when something (apart from a parameter value) has changed.
|
|
|
|
It sends a hint to the host that something like the program, number of parameters,
|
|
etc, has changed, and that it should update itself.
|
|
*/
|
|
void updateHostDisplay();
|
|
|
|
/** Returns the number of preset programs the filter supports.
|
|
|
|
The value returned must be valid as soon as this object is created, and
|
|
must not change over its lifetime.
|
|
|
|
This value shouldn't be less than 1.
|
|
*/
|
|
virtual int getNumPrograms() = 0;
|
|
|
|
/** Returns the number of the currently active program.
|
|
*/
|
|
virtual int getCurrentProgram() = 0;
|
|
|
|
/** Called by the host to change the current program.
|
|
*/
|
|
virtual void setCurrentProgram (int index) = 0;
|
|
|
|
/** Must return the name of a given program. */
|
|
virtual const String getProgramName (int index) = 0;
|
|
|
|
/** Called by the host to rename a program.
|
|
*/
|
|
virtual void changeProgramName (int index, const String& newName) = 0;
|
|
|
|
/** The host will call this method when it wants to save the filter's internal state.
|
|
|
|
This must copy any info about the filter's state into the block of memory provided,
|
|
so that the host can store this and later restore it using setStateInformation().
|
|
|
|
Note that there's also a getCurrentProgramStateInformation() method, which only
|
|
stores the current program, not the state of the entire filter.
|
|
|
|
See also the helper function copyXmlToBinary() for storing settings as XML.
|
|
|
|
@see getCurrentProgramStateInformation
|
|
*/
|
|
virtual void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData) = 0;
|
|
|
|
/** The host will call this method if it wants to save the state of just the filter's
|
|
current program.
|
|
|
|
Unlike getStateInformation, this should only return the current program's state.
|
|
|
|
Not all hosts support this, and if you don't implement it, the base class
|
|
method just calls getStateInformation() instead. If you do implement it, be
|
|
sure to also implement getCurrentProgramStateInformation.
|
|
|
|
@see getStateInformation, setCurrentProgramStateInformation
|
|
*/
|
|
virtual void getCurrentProgramStateInformation (JUCE_NAMESPACE::MemoryBlock& destData);
|
|
|
|
/** This must restore the filter's state from a block of data previously created
|
|
using getStateInformation().
|
|
|
|
Note that there's also a setCurrentProgramStateInformation() method, which tries
|
|
to restore just the current program, not the state of the entire filter.
|
|
|
|
See also the helper function getXmlFromBinary() for loading settings as XML.
|
|
|
|
@see setCurrentProgramStateInformation
|
|
*/
|
|
virtual void setStateInformation (const void* data, int sizeInBytes) = 0;
|
|
|
|
/** The host will call this method if it wants to restore the state of just the filter's
|
|
current program.
|
|
|
|
Not all hosts support this, and if you don't implement it, the base class
|
|
method just calls setStateInformation() instead. If you do implement it, be
|
|
sure to also implement getCurrentProgramStateInformation.
|
|
|
|
@see setStateInformation, getCurrentProgramStateInformation
|
|
*/
|
|
virtual void setCurrentProgramStateInformation (const void* data, int sizeInBytes);
|
|
|
|
/** Adds a listener that will be called when an aspect of this processor changes. */
|
|
void addListener (AudioProcessorListener* const newListener) throw();
|
|
|
|
/** Removes a previously added listener. */
|
|
void removeListener (AudioProcessorListener* const listenerToRemove) throw();
|
|
|
|
/** Not for public use - this is called before deleting an editor component. */
|
|
void editorBeingDeleted (AudioProcessorEditor* const editor) throw();
|
|
|
|
/** Not for public use - this is called to initialise the processor. */
|
|
void setPlayHead (AudioPlayHead* const newPlayHead) throw();
|
|
|
|
/** Not for public use - this is called to initialise the processor before playing. */
|
|
void setPlayConfigDetails (const int numIns, const int numOuts,
|
|
const double sampleRate,
|
|
const int blockSize) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
/** Helper function that just converts an xml element into a binary blob.
|
|
|
|
Use this in your filter's getStateInformation() method if you want to
|
|
store its state as xml.
|
|
|
|
Then use getXmlFromBinary() to reverse this operation and retrieve the XML
|
|
from a binary blob.
|
|
*/
|
|
static void copyXmlToBinary (const XmlElement& xml,
|
|
JUCE_NAMESPACE::MemoryBlock& destData);
|
|
|
|
/** Retrieves an XML element that was stored as binary with the copyXmlToBinary() method.
|
|
|
|
This might return 0 if the data's unsuitable or corrupted. Otherwise it will return
|
|
an XmlElement object that the caller must delete when no longer needed.
|
|
*/
|
|
static XmlElement* getXmlFromBinary (const void* data,
|
|
const int sizeInBytes);
|
|
|
|
/** @internal */
|
|
AudioPlayHead* playHead;
|
|
|
|
/** @internal */
|
|
void sendParamChangeMessageToListeners (const int parameterIndex, const float newValue);
|
|
|
|
private:
|
|
VoidArray listeners;
|
|
AudioProcessorEditor* activeEditor;
|
|
double sampleRate;
|
|
int blockSize, numInputChannels, numOutputChannels, latencySamples;
|
|
bool suspended, nonRealtime;
|
|
CriticalSection callbackLock, listenerLock;
|
|
|
|
#ifdef JUCE_DEBUG
|
|
BitArray changingParams;
|
|
#endif
|
|
|
|
AudioProcessor (const AudioProcessor&);
|
|
const AudioProcessor& operator= (const AudioProcessor&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOPROCESSOR_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioProcessor.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioProcessorGraph.h *********/
|
|
#ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__
|
|
#define __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioPluginFormatManager.h *********/
|
|
#ifndef __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__
|
|
#define __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioPluginFormat.h *********/
|
|
#ifndef __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__
|
|
#define __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioPluginInstance.h *********/
|
|
#ifndef __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__
|
|
#define __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PluginDescription.h *********/
|
|
#ifndef __JUCE_PLUGINDESCRIPTION_JUCEHEADER__
|
|
#define __JUCE_PLUGINDESCRIPTION_JUCEHEADER__
|
|
|
|
/**
|
|
A small class to represent some facts about a particular type of plugin.
|
|
|
|
This class is for storing and managing the details about a plugin without
|
|
actually having to load an instance of it.
|
|
|
|
A KnownPluginList contains a list of PluginDescription objects.
|
|
|
|
@see KnownPluginList
|
|
*/
|
|
class JUCE_API PluginDescription
|
|
{
|
|
public:
|
|
|
|
PluginDescription() throw();
|
|
PluginDescription (const PluginDescription& other) throw();
|
|
const PluginDescription& operator= (const PluginDescription& other) throw();
|
|
~PluginDescription() throw();
|
|
|
|
/** The name of the plugin. */
|
|
String name;
|
|
|
|
/** The plugin format, e.g. "VST", "AudioUnit", etc.
|
|
*/
|
|
String pluginFormatName;
|
|
|
|
/** A category, such as "Dynamics", "Reverbs", etc.
|
|
*/
|
|
String category;
|
|
|
|
/** The manufacturer. */
|
|
String manufacturerName;
|
|
|
|
/** The version. This string doesn't have any particular format. */
|
|
String version;
|
|
|
|
/** Either the file containing the plugin module, or some other unique way
|
|
of identifying it.
|
|
|
|
E.g. for an AU, this would be an ID string that the component manager
|
|
could use to retrieve the plugin. For a VST, it's the file path.
|
|
*/
|
|
String fileOrIdentifier;
|
|
|
|
/** The last time the plugin file was changed.
|
|
This is handy when scanning for new or changed plugins.
|
|
*/
|
|
Time lastFileModTime;
|
|
|
|
/** A unique ID for the plugin.
|
|
|
|
Note that this might not be unique between formats, e.g. a VST and some
|
|
other format might actually have the same id.
|
|
|
|
@see createIdentifierString
|
|
*/
|
|
int uid;
|
|
|
|
/** True if the plugin identifies itself as a synthesiser. */
|
|
bool isInstrument;
|
|
|
|
/** The number of inputs. */
|
|
int numInputChannels;
|
|
|
|
/** The number of outputs. */
|
|
int numOutputChannels;
|
|
|
|
/** Returns true if the two descriptions refer the the same plugin.
|
|
|
|
This isn't quite as simple as them just having the same file (because of
|
|
shell plugins).
|
|
*/
|
|
bool isDuplicateOf (const PluginDescription& other) const;
|
|
|
|
/** Returns a string that can be saved and used to uniquely identify the
|
|
plugin again.
|
|
|
|
This contains less info than the XML encoding, and is independent of the
|
|
plugin's file location, so can be used to store a plugin ID for use
|
|
across different machines.
|
|
*/
|
|
const String createIdentifierString() const throw();
|
|
|
|
/** Creates an XML object containing these details.
|
|
|
|
@see loadFromXml
|
|
*/
|
|
XmlElement* createXml() const;
|
|
|
|
/** Reloads the info in this structure from an XML record that was previously
|
|
saved with createXML().
|
|
|
|
Returns true if the XML was a valid plugin description.
|
|
*/
|
|
bool loadFromXml (const XmlElement& xml);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
};
|
|
|
|
#endif // __JUCE_PLUGINDESCRIPTION_JUCEHEADER__
|
|
/********* End of inlined file: juce_PluginDescription.h *********/
|
|
|
|
/**
|
|
Base class for an active instance of a plugin.
|
|
|
|
This derives from the AudioProcessor class, and adds some extra functionality
|
|
that helps when wrapping dynamically loaded plugins.
|
|
|
|
@see AudioProcessor, AudioPluginFormat
|
|
*/
|
|
class JUCE_API AudioPluginInstance : public AudioProcessor
|
|
{
|
|
public:
|
|
|
|
/** Destructor.
|
|
|
|
Make sure that you delete any UI components that belong to this plugin before
|
|
deleting the plugin.
|
|
*/
|
|
virtual ~AudioPluginInstance();
|
|
|
|
/** Fills-in the appropriate parts of this plugin description object.
|
|
*/
|
|
virtual void fillInPluginDescription (PluginDescription& description) const = 0;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
AudioPluginInstance();
|
|
|
|
AudioPluginInstance (const AudioPluginInstance&);
|
|
const AudioPluginInstance& operator= (const AudioPluginInstance&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioPluginInstance.h *********/
|
|
|
|
class PluginDescription;
|
|
|
|
/**
|
|
The base class for a type of plugin format, such as VST, AudioUnit, LADSPA, etc.
|
|
|
|
Use the static getNumFormats() and getFormat() calls to find the types
|
|
of format that are available.
|
|
*/
|
|
class JUCE_API AudioPluginFormat
|
|
{
|
|
public:
|
|
|
|
/** Destructor. */
|
|
virtual ~AudioPluginFormat();
|
|
|
|
/** Returns the format name.
|
|
|
|
E.g. "VST", "AudioUnit", etc.
|
|
*/
|
|
virtual const String getName() const = 0;
|
|
|
|
/** This tries to create descriptions for all the plugin types available in
|
|
a binary module file.
|
|
|
|
The file will be some kind of DLL or bundle.
|
|
|
|
Normally there will only be one type returned, but some plugins
|
|
(e.g. VST shells) can use a single DLL to create a set of different plugin
|
|
subtypes, so in that case, each subtype is returned as a separate object.
|
|
*/
|
|
virtual void findAllTypesForFile (OwnedArray <PluginDescription>& results,
|
|
const String& fileOrIdentifier) = 0;
|
|
|
|
/** Tries to recreate a type from a previously generated PluginDescription.
|
|
|
|
@see PluginDescription::createInstance
|
|
*/
|
|
virtual AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc) = 0;
|
|
|
|
/** Should do a quick check to see if this file or directory might be a plugin of
|
|
this format.
|
|
|
|
This is for searching for potential files, so it shouldn't actually try to
|
|
load the plugin or do anything time-consuming.
|
|
*/
|
|
virtual bool fileMightContainThisPluginType (const String& fileOrIdentifier) = 0;
|
|
|
|
/** Returns a readable version of the name of the plugin that this identifier refers to.
|
|
*/
|
|
virtual const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) = 0;
|
|
|
|
/** Checks whether this plugin could possibly be loaded.
|
|
|
|
It doesn't actually need to load it, just to check whether the file or component
|
|
still exists.
|
|
*/
|
|
virtual bool doesPluginStillExist (const PluginDescription& desc) = 0;
|
|
|
|
/** Searches a suggested set of directories for any plugins in this format.
|
|
|
|
The path might be ignored, e.g. by AUs, which are found by the OS rather
|
|
than manually.
|
|
*/
|
|
virtual const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch,
|
|
const bool recursive) = 0;
|
|
|
|
/** Returns the typical places to look for this kind of plugin.
|
|
|
|
Note that if this returns no paths, it means that the format can't be scanned-for
|
|
(i.e. it's an internal format that doesn't live in files)
|
|
*/
|
|
virtual const FileSearchPath getDefaultLocationsToSearch() = 0;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
AudioPluginFormat() throw();
|
|
|
|
AudioPluginFormat (const AudioPluginFormat&);
|
|
const AudioPluginFormat& operator= (const AudioPluginFormat&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioPluginFormat.h *********/
|
|
|
|
/**
|
|
This maintains a list of known AudioPluginFormats.
|
|
|
|
@see AudioPluginFormat
|
|
*/
|
|
class JUCE_API AudioPluginFormatManager : public DeletedAtShutdown
|
|
{
|
|
public:
|
|
|
|
AudioPluginFormatManager() throw();
|
|
|
|
/** Destructor. */
|
|
~AudioPluginFormatManager() throw();
|
|
|
|
juce_DeclareSingleton_SingleThreaded (AudioPluginFormatManager, false);
|
|
|
|
/** Adds any formats that it knows about, e.g. VST.
|
|
*/
|
|
void addDefaultFormats();
|
|
|
|
/** Returns the number of types of format that are available.
|
|
|
|
Use getFormat() to get one of them.
|
|
*/
|
|
int getNumFormats() throw();
|
|
|
|
/** Returns one of the available formats.
|
|
|
|
@see getNumFormats
|
|
*/
|
|
AudioPluginFormat* getFormat (const int index) throw();
|
|
|
|
/** Adds a format to the list.
|
|
|
|
The object passed in will be owned and deleted by the manager.
|
|
*/
|
|
void addFormat (AudioPluginFormat* const format) throw();
|
|
|
|
/** Tries to load the type for this description, by trying all the formats
|
|
that this manager knows about.
|
|
|
|
The caller is responsible for deleting the object that is returned.
|
|
|
|
If it can't load the plugin, it returns 0 and leaves a message in the
|
|
errorMessage string.
|
|
*/
|
|
AudioPluginInstance* createPluginInstance (const PluginDescription& description,
|
|
String& errorMessage) const;
|
|
|
|
/** Checks that the file or component for this plugin actually still exists.
|
|
|
|
(This won't try to load the plugin)
|
|
*/
|
|
bool doesPluginStillExist (const PluginDescription& description) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
OwnedArray <AudioPluginFormat> formats;
|
|
|
|
AudioPluginFormatManager (const AudioPluginFormatManager&);
|
|
const AudioPluginFormatManager& operator= (const AudioPluginFormatManager&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioPluginFormatManager.h *********/
|
|
|
|
/********* Start of inlined file: juce_KnownPluginList.h *********/
|
|
#ifndef __JUCE_KNOWNPLUGINLIST_JUCEHEADER__
|
|
#define __JUCE_KNOWNPLUGINLIST_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PopupMenu.h *********/
|
|
#ifndef __JUCE_POPUPMENU_JUCEHEADER__
|
|
#define __JUCE_POPUPMENU_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PopupMenuCustomComponent.h *********/
|
|
#ifndef __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__
|
|
|
|
/** A user-defined copmonent that can appear inside one of the rows of a popup menu.
|
|
|
|
@see PopupMenu::addCustomItem
|
|
*/
|
|
class JUCE_API PopupMenuCustomComponent : public Component
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
~PopupMenuCustomComponent();
|
|
|
|
/** Chooses the size that this component would like to have.
|
|
|
|
Note that the size which this method returns isn't necessarily the one that
|
|
the menu will give it, as it will be stretched to fit the other items in
|
|
the menu.
|
|
*/
|
|
virtual void getIdealSize (int& idealWidth,
|
|
int& idealHeight) = 0;
|
|
|
|
/** Dismisses the menu indicating that this item has been chosen.
|
|
|
|
This will cause the menu to exit from its modal state, returning
|
|
this item's id as the result.
|
|
*/
|
|
void triggerMenuItem();
|
|
|
|
/** Returns true if this item should be highlighted because the mouse is
|
|
over it.
|
|
|
|
You can call this method in your paint() method to find out whether
|
|
to draw a highlight.
|
|
*/
|
|
bool isItemHighlighted() const throw() { return isHighlighted; }
|
|
|
|
protected:
|
|
/** Constructor.
|
|
|
|
If isTriggeredAutomatically is true, then the menu will automatically detect
|
|
a click on this component and use that to trigger it. If it's false, then it's
|
|
up to your class to manually trigger the item if it wants to.
|
|
*/
|
|
PopupMenuCustomComponent (const bool isTriggeredAutomatically = true);
|
|
|
|
private:
|
|
friend class MenuItemInfo;
|
|
friend class MenuItemComponent;
|
|
friend class PopupMenuWindow;
|
|
int refCount_;
|
|
bool isHighlighted, isTriggeredAutomatically;
|
|
|
|
PopupMenuCustomComponent (const PopupMenuCustomComponent&);
|
|
const PopupMenuCustomComponent& operator= (const PopupMenuCustomComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_PopupMenuCustomComponent.h *********/
|
|
|
|
/** Creates and displays a popup-menu.
|
|
|
|
To show a popup-menu, you create one of these, add some items to it, then
|
|
call its show() method, which returns the id of the item the user selects.
|
|
|
|
E.g. @code
|
|
void MyWidget::mouseDown (const MouseEvent& e)
|
|
{
|
|
PopupMenu m;
|
|
m.addItem (1, "item 1");
|
|
m.addItem (2, "item 2");
|
|
|
|
const int result = m.show();
|
|
|
|
if (result == 0)
|
|
{
|
|
// user dismissed the menu without picking anything
|
|
}
|
|
else if (result == 1)
|
|
{
|
|
// user picked item 1
|
|
}
|
|
else if (result == 2)
|
|
{
|
|
// user picked item 2
|
|
}
|
|
}
|
|
@endcode
|
|
|
|
Submenus are easy too: @code
|
|
|
|
void MyWidget::mouseDown (const MouseEvent& e)
|
|
{
|
|
PopupMenu subMenu;
|
|
subMenu.addItem (1, "item 1");
|
|
subMenu.addItem (2, "item 2");
|
|
|
|
PopupMenu mainMenu;
|
|
mainMenu.addItem (3, "item 3");
|
|
mainMenu.addSubMenu ("other choices", subMenu);
|
|
|
|
const int result = m.show();
|
|
|
|
...etc
|
|
}
|
|
@endcode
|
|
*/
|
|
class JUCE_API PopupMenu
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty popup menu. */
|
|
PopupMenu() throw();
|
|
|
|
/** Creates a copy of another menu. */
|
|
PopupMenu (const PopupMenu& other) throw();
|
|
|
|
/** Destructor. */
|
|
~PopupMenu() throw();
|
|
|
|
/** Copies this menu from another one. */
|
|
const PopupMenu& operator= (const PopupMenu& other) throw();
|
|
|
|
/** Resets the menu, removing all its items. */
|
|
void clear() throw();
|
|
|
|
/** Appends a new text item for this menu to show.
|
|
|
|
@param itemResultId the number that will be returned from the show() method
|
|
if the user picks this item. The value should never be
|
|
zero, because that's used to indicate that the user didn't
|
|
select anything.
|
|
@param itemText the text to show.
|
|
@param isActive if false, the item will be shown 'greyed-out' and can't be
|
|
picked
|
|
@param isTicked if true, the item will be shown with a tick next to it
|
|
@param iconToUse if this is non-zero, it should be an image that will be
|
|
displayed to the left of the item. This method will take its
|
|
own copy of the image passed-in, so there's no need to keep
|
|
it hanging around.
|
|
|
|
@see addSeparator, addColouredItem, addCustomItem, addSubMenu
|
|
*/
|
|
void addItem (const int itemResultId,
|
|
const String& itemText,
|
|
const bool isActive = true,
|
|
const bool isTicked = false,
|
|
const Image* const iconToUse = 0) throw();
|
|
|
|
/** Adds an item that represents one of the commands in a command manager object.
|
|
|
|
@param commandManager the manager to use to trigger the command and get information
|
|
about it
|
|
@param commandID the ID of the command
|
|
@param displayName if this is non-empty, then this string will be used instead of
|
|
the command's registered name
|
|
*/
|
|
void addCommandItem (ApplicationCommandManager* commandManager,
|
|
const int commandID,
|
|
const String& displayName = String::empty) throw();
|
|
|
|
/** Appends a text item with a special colour.
|
|
|
|
This is the same as addItem(), but specifies a colour to use for the
|
|
text, which will override the default colours that are used by the
|
|
current look-and-feel. See addItem() for a description of the parameters.
|
|
*/
|
|
void addColouredItem (const int itemResultId,
|
|
const String& itemText,
|
|
const Colour& itemTextColour,
|
|
const bool isActive = true,
|
|
const bool isTicked = false,
|
|
const Image* const iconToUse = 0) throw();
|
|
|
|
/** Appends a custom menu item.
|
|
|
|
This will add a user-defined component to use as a menu item. The component
|
|
passed in will be deleted by this menu when it's no longer needed.
|
|
|
|
@see PopupMenuCustomComponent
|
|
*/
|
|
void addCustomItem (const int itemResultId,
|
|
PopupMenuCustomComponent* const customComponent) throw();
|
|
|
|
/** Appends a custom menu item that can't be used to trigger a result.
|
|
|
|
This will add a user-defined component to use as a menu item. Unlike the
|
|
addCustomItem() method that takes a PopupMenuCustomComponent, this version
|
|
can't trigger a result from it, so doesn't take a menu ID. It also doesn't
|
|
delete the component when it's finished, so it's the caller's responsibility
|
|
to manage the component that is passed-in.
|
|
|
|
if triggerMenuItemAutomaticallyWhenClicked is true, the menu itself will handle
|
|
detection of a mouse-click on your component, and use that to trigger the
|
|
menu ID specified in itemResultId. If this is false, the menu item can't
|
|
be triggered, so itemResultId is not used.
|
|
|
|
@see PopupMenuCustomComponent
|
|
*/
|
|
void addCustomItem (const int itemResultId,
|
|
Component* customComponent,
|
|
int idealWidth, int idealHeight,
|
|
const bool triggerMenuItemAutomaticallyWhenClicked) throw();
|
|
|
|
/** Appends a sub-menu.
|
|
|
|
If the menu that's passed in is empty, it will appear as an inactive item.
|
|
*/
|
|
void addSubMenu (const String& subMenuName,
|
|
const PopupMenu& subMenu,
|
|
const bool isActive = true,
|
|
Image* const iconToUse = 0,
|
|
const bool isTicked = false) throw();
|
|
|
|
/** Appends a separator to the menu, to help break it up into sections.
|
|
|
|
The menu class is smart enough not to display separators at the top or bottom
|
|
of the menu, and it will replace mutliple adjacent separators with a single
|
|
one, so your code can be quite free and easy about adding these, and it'll
|
|
always look ok.
|
|
*/
|
|
void addSeparator() throw();
|
|
|
|
/** Adds a non-clickable text item to the menu.
|
|
|
|
This is a bold-font items which can be used as a header to separate the items
|
|
into named groups.
|
|
*/
|
|
void addSectionHeader (const String& title) throw();
|
|
|
|
/** Returns the number of items that the menu currently contains.
|
|
|
|
(This doesn't count separators).
|
|
*/
|
|
int getNumItems() const throw();
|
|
|
|
/** Returns true if the menu contains a command item that triggers the given command. */
|
|
bool containsCommandItem (const int commandID) const throw();
|
|
|
|
/** Returns true if the menu contains any items that can be used. */
|
|
bool containsAnyActiveItems() const throw();
|
|
|
|
/** Displays the menu and waits for the user to pick something.
|
|
|
|
This will display the menu modally, and return the ID of the item that the
|
|
user picks. If they click somewhere off the menu to get rid of it without
|
|
choosing anything, this will return 0.
|
|
|
|
The current location of the mouse will be used as the position to show the
|
|
menu - to explicitly set the menu's position, use showAt() instead. Depending
|
|
on where this point is on the screen, the menu will appear above, below or
|
|
to the side of the point.
|
|
|
|
@param itemIdThatMustBeVisible if you set this to the ID of one of the menu items,
|
|
then when the menu first appears, it will make sure
|
|
that this item is visible. So if the menu has too many
|
|
items to fit on the screen, it will be scrolled to a
|
|
position where this item is visible.
|
|
@param minimumWidth a minimum width for the menu, in pixels. It may be wider
|
|
than this if some items are too long to fit.
|
|
@param maximumNumColumns if there are too many items to fit on-screen in a single
|
|
vertical column, the menu may be laid out as a series of
|
|
columns - this is the maximum number allowed. To use the
|
|
default value for this (probably about 7), you can pass
|
|
in zero.
|
|
@param standardItemHeight if this is non-zero, it will be used as the standard
|
|
height for menu items (apart from custom items)
|
|
@see showAt
|
|
*/
|
|
int show (const int itemIdThatMustBeVisible = 0,
|
|
const int minimumWidth = 0,
|
|
const int maximumNumColumns = 0,
|
|
const int standardItemHeight = 0);
|
|
|
|
/** Displays the menu at a specific location.
|
|
|
|
This is the same as show(), but uses a specific location (in global screen
|
|
co-ordinates) rather than the current mouse position.
|
|
|
|
Note that the co-ordinates don't specify the top-left of the menu - they
|
|
indicate a point of interest, and the menu will position itself nearby to
|
|
this point, trying to keep it fully on-screen.
|
|
|
|
@see show()
|
|
*/
|
|
int showAt (const int screenX,
|
|
const int screenY,
|
|
const int itemIdThatMustBeVisible = 0,
|
|
const int minimumWidth = 0,
|
|
const int maximumNumColumns = 0,
|
|
const int standardItemHeight = 0);
|
|
|
|
/** Displays the menu as if it's attached to a component such as a button.
|
|
|
|
This is similar to showAt(), but will position it next to the given component, e.g.
|
|
so that the menu's edge is aligned with that of the component. This is intended for
|
|
things like buttons that trigger a pop-up menu.
|
|
*/
|
|
int showAt (Component* componentToAttachTo,
|
|
const int itemIdThatMustBeVisible = 0,
|
|
const int minimumWidth = 0,
|
|
const int maximumNumColumns = 0,
|
|
const int standardItemHeight = 0);
|
|
|
|
/** Closes any menus that are currently open.
|
|
|
|
This might be useful if you have a situation where your window is being closed
|
|
by some means other than a user action, and you'd like to make sure that menus
|
|
aren't left hanging around.
|
|
*/
|
|
static void JUCE_CALLTYPE dismissAllActiveMenus() throw();
|
|
|
|
/** Specifies a look-and-feel for the menu and any sub-menus that it has.
|
|
|
|
This can be called before show() if you need a customised menu. Be careful
|
|
not to delete the LookAndFeel object before the menu has been deleted.
|
|
*/
|
|
void setLookAndFeel (LookAndFeel* const newLookAndFeel) throw();
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the menu.
|
|
|
|
These constants can be used either via the LookAndFeel::setColour()
|
|
method for the look and feel that is set for this menu with setLookAndFeel()
|
|
|
|
@see setLookAndFeel, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1000700, /**< The colour to fill the menu's background with. */
|
|
textColourId = 0x1000600, /**< The colour for normal menu item text, (unless the
|
|
colour is specified when the item is added). */
|
|
headerTextColourId = 0x1000601, /**< The colour for section header item text (see the
|
|
addSectionHeader() method). */
|
|
highlightedBackgroundColourId = 0x1000900, /**< The colour to fill the background of the currently
|
|
highlighted menu item. */
|
|
highlightedTextColourId = 0x1000800, /**< The colour to use for the text of the currently
|
|
highlighted item. */
|
|
};
|
|
|
|
/**
|
|
Allows you to iterate through the items in a pop-up menu, and examine
|
|
their properties.
|
|
|
|
To use this, just create one and repeatedly call its next() method. When this
|
|
returns true, all the member variables of the iterator are filled-out with
|
|
information describing the menu item. When it returns false, the end of the
|
|
list has been reached.
|
|
*/
|
|
class JUCE_API MenuItemIterator
|
|
{
|
|
public:
|
|
|
|
/** Creates an iterator that will scan through the items in the specified
|
|
menu.
|
|
|
|
Be careful not to add any items to a menu while it is being iterated,
|
|
or things could get out of step.
|
|
*/
|
|
MenuItemIterator (const PopupMenu& menu) throw();
|
|
|
|
/** Destructor. */
|
|
~MenuItemIterator() throw();
|
|
|
|
/** Returns true if there is another item, and sets up all this object's
|
|
member variables to reflect that item's properties.
|
|
*/
|
|
bool next() throw();
|
|
|
|
String itemName;
|
|
const PopupMenu* subMenu;
|
|
int itemId;
|
|
bool isSeparator;
|
|
bool isTicked;
|
|
bool isEnabled;
|
|
bool isCustomComponent;
|
|
bool isSectionHeader;
|
|
const Colour* customColour;
|
|
const Image* customImage;
|
|
ApplicationCommandManager* commandManager;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
const PopupMenu& menu;
|
|
int index;
|
|
|
|
MenuItemIterator (const MenuItemIterator&);
|
|
const MenuItemIterator& operator= (const MenuItemIterator&);
|
|
};
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class PopupMenuWindow;
|
|
friend class MenuItemIterator;
|
|
VoidArray items;
|
|
LookAndFeel* lookAndFeel;
|
|
bool separatorPending;
|
|
|
|
void addSeparatorIfPending();
|
|
|
|
int showMenu (const int x, const int y, const int w, const int h,
|
|
const int itemIdThatMustBeVisible,
|
|
const int minimumWidth,
|
|
const int maximumNumColumns,
|
|
const int standardItemHeight,
|
|
const bool alignToRectangle,
|
|
Component* const componentAttachedTo) throw();
|
|
|
|
friend class MenuBarComponent;
|
|
Component* createMenuComponent (const int x, const int y, const int w, const int h,
|
|
const int itemIdThatMustBeVisible,
|
|
const int minimumWidth,
|
|
const int maximumNumColumns,
|
|
const int standardItemHeight,
|
|
const bool alignToRectangle,
|
|
Component* menuBarComponent,
|
|
ApplicationCommandManager** managerOfChosenCommand,
|
|
Component* const componentAttachedTo) throw();
|
|
};
|
|
|
|
#endif // __JUCE_POPUPMENU_JUCEHEADER__
|
|
/********* End of inlined file: juce_PopupMenu.h *********/
|
|
|
|
/**
|
|
Manages a list of plugin types.
|
|
|
|
This can be easily edited, saved and loaded, and used to create instances of
|
|
the plugin types in it.
|
|
|
|
@see PluginListComponent
|
|
*/
|
|
class JUCE_API KnownPluginList : public ChangeBroadcaster
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty list.
|
|
*/
|
|
KnownPluginList();
|
|
|
|
/** Destructor. */
|
|
~KnownPluginList();
|
|
|
|
/** Clears the list. */
|
|
void clear();
|
|
|
|
/** Returns the number of types currently in the list.
|
|
@see getType
|
|
*/
|
|
int getNumTypes() const throw() { return types.size(); }
|
|
|
|
/** Returns one of the types.
|
|
@see getNumTypes
|
|
*/
|
|
PluginDescription* getType (const int index) const throw() { return types [index]; }
|
|
|
|
/** Looks for a type in the list which comes from this file.
|
|
*/
|
|
PluginDescription* getTypeForFile (const String& fileOrIdentifier) const throw();
|
|
|
|
/** Looks for a type in the list which matches a plugin type ID.
|
|
|
|
The identifierString parameter must have been created by
|
|
PluginDescription::createIdentifierString().
|
|
*/
|
|
PluginDescription* getTypeForIdentifierString (const String& identifierString) const throw();
|
|
|
|
/** Adds a type manually from its description. */
|
|
bool addType (const PluginDescription& type);
|
|
|
|
/** Removes a type. */
|
|
void removeType (const int index) throw();
|
|
|
|
/** Looks for all types that can be loaded from a given file, and adds them
|
|
to the list.
|
|
|
|
If dontRescanIfAlreadyInList is true, then the file will only be loaded and
|
|
re-tested if it's not already in the list, or if the file's modification
|
|
time has changed since the list was created. If dontRescanIfAlreadyInList is
|
|
false, the file will always be reloaded and tested.
|
|
|
|
Returns true if any new types were added, and all the types found in this
|
|
file (even if it was already known and hasn't been re-scanned) get returned
|
|
in the array.
|
|
*/
|
|
bool scanAndAddFile (const String& possiblePluginFileOrIdentifier,
|
|
const bool dontRescanIfAlreadyInList,
|
|
OwnedArray <PluginDescription>& typesFound,
|
|
AudioPluginFormat& formatToUse);
|
|
|
|
/** Returns true if the specified file is already known about and if it
|
|
hasn't been modified since our entry was created.
|
|
*/
|
|
bool isListingUpToDate (const String& possiblePluginFileOrIdentifier) const throw();
|
|
|
|
/** Scans and adds a bunch of files that might have been dragged-and-dropped.
|
|
|
|
If any types are found in the files, their descriptions are returned in the array.
|
|
*/
|
|
void scanAndAddDragAndDroppedFiles (const StringArray& filenames,
|
|
OwnedArray <PluginDescription>& typesFound);
|
|
|
|
/** Sort methods used to change the order of the plugins in the list.
|
|
*/
|
|
enum SortMethod
|
|
{
|
|
defaultOrder = 0,
|
|
sortAlphabetically,
|
|
sortByCategory,
|
|
sortByManufacturer,
|
|
sortByFileSystemLocation
|
|
};
|
|
|
|
/** Adds all the plugin types to a popup menu so that the user can select one.
|
|
|
|
Depending on the sort method, it may add sub-menus for categories,
|
|
manufacturers, etc.
|
|
|
|
Use getIndexChosenByMenu() to find out the type that was chosen.
|
|
*/
|
|
void addToMenu (PopupMenu& menu,
|
|
const SortMethod sortMethod) const;
|
|
|
|
/** Converts a menu item index that has been chosen into its index in this list.
|
|
|
|
Returns -1 if it's not an ID that was used.
|
|
|
|
@see addToMenu
|
|
*/
|
|
int getIndexChosenByMenu (const int menuResultCode) const;
|
|
|
|
/** Sorts the list. */
|
|
void sort (const SortMethod method);
|
|
|
|
/** Creates some XML that can be used to store the state of this list.
|
|
*/
|
|
XmlElement* createXml() const;
|
|
|
|
/** Recreates the state of this list from its stored XML format.
|
|
*/
|
|
void recreateFromXml (const XmlElement& xml);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
OwnedArray <PluginDescription> types;
|
|
|
|
KnownPluginList (const KnownPluginList&);
|
|
const KnownPluginList& operator= (const KnownPluginList&);
|
|
};
|
|
|
|
#endif // __JUCE_KNOWNPLUGINLIST_JUCEHEADER__
|
|
/********* End of inlined file: juce_KnownPluginList.h *********/
|
|
|
|
/**
|
|
A type of AudioProcessor which plays back a graph of other AudioProcessors.
|
|
|
|
Use one of these objects if you want to wire-up a set of AudioProcessors
|
|
and play back the result.
|
|
|
|
Processors can be added to the graph as "nodes" using addNode(), and once
|
|
added, you can connect any of their input or output channels to other
|
|
nodes using addConnection().
|
|
|
|
To play back a graph through an audio device, you might want to use an
|
|
AudioProcessorPlayer object.
|
|
*/
|
|
class JUCE_API AudioProcessorGraph : public AudioProcessor,
|
|
public AsyncUpdater
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty graph.
|
|
*/
|
|
AudioProcessorGraph();
|
|
|
|
/** Destructor.
|
|
|
|
Any processor objects that have been added to the graph will also be deleted.
|
|
*/
|
|
~AudioProcessorGraph();
|
|
|
|
/** Represents one of the nodes, or processors, in an AudioProcessorGraph.
|
|
|
|
To create a node, call AudioProcessorGraph::addNode().
|
|
*/
|
|
class JUCE_API Node : public ReferenceCountedObject
|
|
{
|
|
public:
|
|
/** Destructor.
|
|
*/
|
|
~Node();
|
|
|
|
/** The ID number assigned to this node.
|
|
|
|
This is assigned by the graph that owns it, and can't be changed.
|
|
*/
|
|
const uint32 id;
|
|
|
|
/** The actual processor object that this node represents.
|
|
*/
|
|
AudioProcessor* const processor;
|
|
|
|
/** A set of user-definable properties that are associated with this node.
|
|
|
|
This can be used to attach values to the node for whatever purpose seems
|
|
useful. For example, you might store an x and y position if your application
|
|
is displaying the nodes on-screen.
|
|
*/
|
|
PropertySet properties;
|
|
|
|
/** A convenient typedef for referring to a pointer to a node object.
|
|
*/
|
|
typedef ReferenceCountedObjectPtr <Node> Ptr;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class AudioProcessorGraph;
|
|
|
|
bool isPrepared;
|
|
|
|
Node (const uint32 id, AudioProcessor* const processor) throw();
|
|
|
|
void prepare (const double sampleRate, const int blockSize, AudioProcessorGraph* const graph);
|
|
void unprepare();
|
|
|
|
Node (const Node&);
|
|
const Node& operator= (const Node&);
|
|
};
|
|
|
|
/** Represents a connection between two channels of two nodes in an AudioProcessorGraph.
|
|
|
|
To create a connection, use AudioProcessorGraph::addConnection().
|
|
*/
|
|
struct JUCE_API Connection
|
|
{
|
|
public:
|
|
|
|
/** The ID number of the node which is the input source for this connection.
|
|
@see AudioProcessorGraph::getNodeForId
|
|
*/
|
|
uint32 sourceNodeId;
|
|
|
|
/** The index of the output channel of the source node from which this
|
|
connection takes its data.
|
|
|
|
If this value is the special number AudioProcessorGraph::midiChannelIndex, then
|
|
it is referring to the source node's midi output. Otherwise, it is the zero-based
|
|
index of an audio output channel in the source node.
|
|
*/
|
|
int sourceChannelIndex;
|
|
|
|
/** The ID number of the node which is the destination for this connection.
|
|
@see AudioProcessorGraph::getNodeForId
|
|
*/
|
|
uint32 destNodeId;
|
|
|
|
/** The index of the input channel of the destination node to which this
|
|
connection delivers its data.
|
|
|
|
If this value is the special number AudioProcessorGraph::midiChannelIndex, then
|
|
it is referring to the destination node's midi input. Otherwise, it is the zero-based
|
|
index of an audio input channel in the destination node.
|
|
*/
|
|
int destChannelIndex;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
};
|
|
|
|
/** Deletes all nodes and connections from this graph.
|
|
|
|
Any processor objects in the graph will be deleted.
|
|
*/
|
|
void clear();
|
|
|
|
/** Returns the number of nodes in the graph. */
|
|
int getNumNodes() const throw() { return nodes.size(); }
|
|
|
|
/** Returns a pointer to one of the nodes in the graph.
|
|
|
|
This will return 0 if the index is out of range.
|
|
@see getNodeForId
|
|
*/
|
|
Node* getNode (const int index) const throw() { return nodes [index]; }
|
|
|
|
/** Searches the graph for a node with the given ID number and returns it.
|
|
|
|
If no such node was found, this returns 0.
|
|
@see getNode
|
|
*/
|
|
Node* getNodeForId (const uint32 nodeId) const throw();
|
|
|
|
/** Adds a node to the graph.
|
|
|
|
This creates a new node in the graph, for the specified processor. Once you have
|
|
added a processor to the graph, the graph owns it and will delete it later when
|
|
it is no longer needed.
|
|
|
|
The optional nodeId parameter lets you specify an ID to use for the node, but
|
|
if the value is already in use, this new node will overwrite the old one.
|
|
|
|
If this succeeds, it returns a pointer to the newly-created node.
|
|
*/
|
|
Node* addNode (AudioProcessor* const newProcessor,
|
|
uint32 nodeId = 0);
|
|
|
|
/** Deletes a node within the graph which has the specified ID.
|
|
|
|
This will also delete any connections that are attached to this node.
|
|
*/
|
|
bool removeNode (const uint32 nodeId);
|
|
|
|
/** Returns the number of connections in the graph. */
|
|
int getNumConnections() const throw() { return connections.size(); }
|
|
|
|
/** Returns a pointer to one of the connections in the graph. */
|
|
const Connection* getConnection (const int index) const throw() { return connections [index]; }
|
|
|
|
/** Searches for a connection between some specified channels.
|
|
|
|
If no such connection is found, this returns 0.
|
|
*/
|
|
const Connection* getConnectionBetween (const uint32 sourceNodeId,
|
|
const int sourceChannelIndex,
|
|
const uint32 destNodeId,
|
|
const int destChannelIndex) const throw();
|
|
|
|
/** Returns true if there is a connection between any of the channels of
|
|
two specified nodes.
|
|
*/
|
|
bool isConnected (const uint32 possibleSourceNodeId,
|
|
const uint32 possibleDestNodeId) const throw();
|
|
|
|
/** Returns true if it would be legal to connect the specified points.
|
|
*/
|
|
bool canConnect (const uint32 sourceNodeId, const int sourceChannelIndex,
|
|
const uint32 destNodeId, const int destChannelIndex) const throw();
|
|
|
|
/** Attempts to connect two specified channels of two nodes.
|
|
|
|
If this isn't allowed (e.g. because you're trying to connect a midi channel
|
|
to an audio one or other such nonsense), then it'll return false.
|
|
*/
|
|
bool addConnection (const uint32 sourceNodeId, const int sourceChannelIndex,
|
|
const uint32 destNodeId, const int destChannelIndex);
|
|
|
|
/** Deletes the connection with the specified index.
|
|
|
|
Returns true if a connection was actually deleted.
|
|
*/
|
|
void removeConnection (const int index);
|
|
|
|
/** Deletes any connection between two specified points.
|
|
|
|
Returns true if a connection was actually deleted.
|
|
*/
|
|
bool removeConnection (const uint32 sourceNodeId, const int sourceChannelIndex,
|
|
const uint32 destNodeId, const int destChannelIndex);
|
|
|
|
/** Removes all connections from the specified node.
|
|
*/
|
|
bool disconnectNode (const uint32 nodeId);
|
|
|
|
/** Performs a sanity checks of all the connections.
|
|
|
|
This might be useful if some of the processors are doing things like changing
|
|
their channel counts, which could render some connections obsolete.
|
|
*/
|
|
bool removeIllegalConnections();
|
|
|
|
/** A special number that represents the midi channel of a node.
|
|
|
|
This is used as a channel index value if you want to refer to the midi input
|
|
or output instead of an audio channel.
|
|
*/
|
|
static const int midiChannelIndex;
|
|
|
|
/** A special type of AudioProcessor that can live inside an AudioProcessorGraph
|
|
in order to use the audio that comes into and out of the graph itself.
|
|
|
|
If you create an AudioGraphIOProcessor in "input" mode, it will act as a
|
|
node in the graph which delivers the audio that is coming into the parent
|
|
graph. This allows you to stream the data to other nodes and process the
|
|
incoming audio.
|
|
|
|
Likewise, one of these in "output" mode can be sent data which it will add to
|
|
the sum of data being sent to the graph's output.
|
|
|
|
@see AudioProcessorGraph
|
|
*/
|
|
class JUCE_API AudioGraphIOProcessor : public AudioPluginInstance
|
|
{
|
|
public:
|
|
/** Specifies the mode in which this processor will operate.
|
|
*/
|
|
enum IODeviceType
|
|
{
|
|
audioInputNode, /**< In this mode, the processor has output channels
|
|
representing all the audio input channels that are
|
|
coming into its parent audio graph. */
|
|
audioOutputNode, /**< In this mode, the processor has input channels
|
|
representing all the audio output channels that are
|
|
going out of its parent audio graph. */
|
|
midiInputNode, /**< In this mode, the processor has a midi output which
|
|
delivers the same midi data that is arriving at its
|
|
parent graph. */
|
|
midiOutputNode /**< In this mode, the processor has a midi input and
|
|
any data sent to it will be passed out of the parent
|
|
graph. */
|
|
};
|
|
|
|
/** Returns the mode of this processor. */
|
|
IODeviceType getType() const throw() { return type; }
|
|
|
|
/** Returns the parent graph to which this processor belongs, or 0 if it
|
|
hasn't yet been added to one. */
|
|
AudioProcessorGraph* getParentGraph() const throw() { return graph; }
|
|
|
|
/** True if this is an audio or midi input. */
|
|
bool isInput() const throw();
|
|
/** True if this is an audio or midi output. */
|
|
bool isOutput() const throw();
|
|
|
|
AudioGraphIOProcessor (const IODeviceType type);
|
|
~AudioGraphIOProcessor();
|
|
|
|
const String getName() const;
|
|
void fillInPluginDescription (PluginDescription& d) const;
|
|
|
|
void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock);
|
|
void releaseResources();
|
|
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
|
|
|
|
const String getInputChannelName (const int channelIndex) const;
|
|
const String getOutputChannelName (const int channelIndex) const;
|
|
bool isInputChannelStereoPair (int index) const;
|
|
bool isOutputChannelStereoPair (int index) const;
|
|
bool acceptsMidi() const;
|
|
bool producesMidi() const;
|
|
|
|
AudioProcessorEditor* createEditor();
|
|
|
|
int getNumParameters();
|
|
const String getParameterName (int);
|
|
float getParameter (int);
|
|
const String getParameterText (int);
|
|
void setParameter (int, float);
|
|
|
|
int getNumPrograms();
|
|
int getCurrentProgram();
|
|
void setCurrentProgram (int);
|
|
const String getProgramName (int);
|
|
void changeProgramName (int, const String&);
|
|
|
|
void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData);
|
|
void setStateInformation (const void* data, int sizeInBytes);
|
|
|
|
/** @internal */
|
|
void setParentGraph (AudioProcessorGraph* const graph) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
const IODeviceType type;
|
|
AudioProcessorGraph* graph;
|
|
|
|
AudioGraphIOProcessor (const AudioGraphIOProcessor&);
|
|
const AudioGraphIOProcessor& operator= (const AudioGraphIOProcessor&);
|
|
};
|
|
|
|
// AudioProcessor methods:
|
|
|
|
const String getName() const;
|
|
|
|
void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock);
|
|
void releaseResources();
|
|
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
|
|
|
|
const String getInputChannelName (const int channelIndex) const;
|
|
const String getOutputChannelName (const int channelIndex) const;
|
|
bool isInputChannelStereoPair (int index) const;
|
|
bool isOutputChannelStereoPair (int index) const;
|
|
|
|
bool acceptsMidi() const;
|
|
bool producesMidi() const;
|
|
|
|
AudioProcessorEditor* createEditor() { return 0; }
|
|
|
|
int getNumParameters() { return 0; }
|
|
const String getParameterName (int) { return String::empty; }
|
|
float getParameter (int) { return 0; }
|
|
const String getParameterText (int) { return String::empty; }
|
|
void setParameter (int, float) { }
|
|
|
|
int getNumPrograms() { return 0; }
|
|
int getCurrentProgram() { return 0; }
|
|
void setCurrentProgram (int) { }
|
|
const String getProgramName (int) { return String::empty; }
|
|
void changeProgramName (int, const String&) { }
|
|
|
|
void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData);
|
|
void setStateInformation (const void* data, int sizeInBytes);
|
|
|
|
/** @internal */
|
|
void handleAsyncUpdate();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
ReferenceCountedArray <Node> nodes;
|
|
OwnedArray <Connection> connections;
|
|
int lastNodeId;
|
|
AudioSampleBuffer renderingBuffers;
|
|
OwnedArray <MidiBuffer> midiBuffers;
|
|
|
|
CriticalSection renderLock;
|
|
VoidArray renderingOps;
|
|
|
|
friend class AudioGraphIOProcessor;
|
|
AudioSampleBuffer* currentAudioInputBuffer;
|
|
AudioSampleBuffer currentAudioOutputBuffer;
|
|
MidiBuffer* currentMidiInputBuffer;
|
|
MidiBuffer currentMidiOutputBuffer;
|
|
|
|
void clearRenderingSequence();
|
|
void buildRenderingSequence();
|
|
|
|
bool isAnInputTo (const uint32 possibleInputId,
|
|
const uint32 possibleDestinationId,
|
|
const int recursionCheck) const throw();
|
|
|
|
AudioProcessorGraph (const AudioProcessorGraph&);
|
|
const AudioProcessorGraph& operator= (const AudioProcessorGraph&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioProcessorGraph.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioProcessorPlayer.h *********/
|
|
#ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__
|
|
#define __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioIODevice.h *********/
|
|
#ifndef __JUCE_AUDIOIODEVICE_JUCEHEADER__
|
|
#define __JUCE_AUDIOIODEVICE_JUCEHEADER__
|
|
|
|
class AudioIODevice;
|
|
|
|
/**
|
|
One of these is passed to an AudioIODevice object to stream the audio data
|
|
in and out.
|
|
|
|
The AudioIODevice will repeatedly call this class's audioDeviceIOCallback()
|
|
method on its own high-priority audio thread, when it needs to send or receive
|
|
the next block of data.
|
|
|
|
@see AudioIODevice, AudioDeviceManager
|
|
*/
|
|
class JUCE_API AudioIODeviceCallback
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~AudioIODeviceCallback() {}
|
|
|
|
/** Processes a block of incoming and outgoing audio data.
|
|
|
|
The subclass's implementation should use the incoming audio for whatever
|
|
purposes it needs to, and must fill all the output channels with the next
|
|
block of output data before returning.
|
|
|
|
The channel data is arranged with the same array indices as the channel name
|
|
array returned by AudioIODevice::getOutputChannelNames(), but those channels
|
|
that aren't specified in AudioIODevice::open() will have a null pointer for their
|
|
associated channel, so remember to check for this.
|
|
|
|
@param inputChannelData a set of arrays containing the audio data for each
|
|
incoming channel - this data is valid until the function
|
|
returns. There will be one channel of data for each input
|
|
channel that was enabled when the audio device was opened
|
|
(see AudioIODevice::open())
|
|
@param numInputChannels the number of pointers to channel data in the
|
|
inputChannelData array.
|
|
@param outputChannelData a set of arrays which need to be filled with the data
|
|
that should be sent to each outgoing channel of the device.
|
|
There will be one channel of data for each output channel
|
|
that was enabled when the audio device was opened (see
|
|
AudioIODevice::open())
|
|
The initial contents of the array is undefined, so the
|
|
callback function must fill all the channels with zeros if
|
|
its output is silence. Failing to do this could cause quite
|
|
an unpleasant noise!
|
|
@param numOutputChannels the number of pointers to channel data in the
|
|
outputChannelData array.
|
|
@param numSamples the number of samples in each channel of the input and
|
|
output arrays. The number of samples will depend on the
|
|
audio device's buffer size and will usually remain constant,
|
|
although this isn't guaranteed, so make sure your code can
|
|
cope with reasonable changes in the buffer size from one
|
|
callback to the next.
|
|
*/
|
|
virtual void audioDeviceIOCallback (const float** inputChannelData,
|
|
int numInputChannels,
|
|
float** outputChannelData,
|
|
int numOutputChannels,
|
|
int numSamples) = 0;
|
|
|
|
/** Called to indicate that the device is about to start calling back.
|
|
|
|
This will be called just before the audio callbacks begin, either when this
|
|
callback has just been added to an audio device, or after the device has been
|
|
restarted because of a sample-rate or block-size change.
|
|
|
|
You can use this opportunity to find out the sample rate and block size
|
|
that the device is going to use by calling the AudioIODevice::getCurrentSampleRate()
|
|
and AudioIODevice::getCurrentBufferSizeSamples() on the supplied pointer.
|
|
|
|
@param device the audio IO device that will be used to drive the callback.
|
|
Note that if you're going to store this this pointer, it is
|
|
only valid until the next time that audioDeviceStopped is called.
|
|
*/
|
|
virtual void audioDeviceAboutToStart (AudioIODevice* device) = 0;
|
|
|
|
/** Called to indicate that the device has stopped.
|
|
*/
|
|
virtual void audioDeviceStopped() = 0;
|
|
};
|
|
|
|
/**
|
|
Base class for an audio device with synchronised input and output channels.
|
|
|
|
Subclasses of this are used to implement different protocols such as DirectSound,
|
|
ASIO, CoreAudio, etc.
|
|
|
|
To create one of these, you'll need to use the AudioIODeviceType class - see the
|
|
documentation for that class for more info.
|
|
|
|
For an easier way of managing audio devices and their settings, have a look at the
|
|
AudioDeviceManager class.
|
|
|
|
@see AudioIODeviceType, AudioDeviceManager
|
|
*/
|
|
class JUCE_API AudioIODevice
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~AudioIODevice();
|
|
|
|
/** Returns the device's name, (as set in the constructor). */
|
|
const String& getName() const throw() { return name; }
|
|
|
|
/** Returns the type of the device.
|
|
|
|
E.g. "CoreAudio", "ASIO", etc. - this comes from the AudioIODeviceType that created it.
|
|
*/
|
|
const String& getTypeName() const throw() { return typeName; }
|
|
|
|
/** Returns the names of all the available output channels on this device.
|
|
To find out which of these are currently in use, call getActiveOutputChannels().
|
|
*/
|
|
virtual const StringArray getOutputChannelNames() = 0;
|
|
|
|
/** Returns the names of all the available input channels on this device.
|
|
To find out which of these are currently in use, call getActiveInputChannels().
|
|
*/
|
|
virtual const StringArray getInputChannelNames() = 0;
|
|
|
|
/** Returns the number of sample-rates this device supports.
|
|
|
|
To find out which rates are available on this device, use this method to
|
|
find out how many there are, and getSampleRate() to get the rates.
|
|
|
|
@see getSampleRate
|
|
*/
|
|
virtual int getNumSampleRates() = 0;
|
|
|
|
/** Returns one of the sample-rates this device supports.
|
|
|
|
To find out which rates are available on this device, use getNumSampleRates() to
|
|
find out how many there are, and getSampleRate() to get the individual rates.
|
|
|
|
The sample rate is set by the open() method.
|
|
|
|
(Note that for DirectSound some rates might not work, depending on combinations
|
|
of i/o channels that are being opened).
|
|
|
|
@see getNumSampleRates
|
|
*/
|
|
virtual double getSampleRate (int index) = 0;
|
|
|
|
/** Returns the number of sizes of buffer that are available.
|
|
|
|
@see getBufferSizeSamples, getDefaultBufferSize
|
|
*/
|
|
virtual int getNumBufferSizesAvailable() = 0;
|
|
|
|
/** Returns one of the possible buffer-sizes.
|
|
|
|
@param index the index of the buffer-size to use, from 0 to getNumBufferSizesAvailable() - 1
|
|
@returns a number of samples
|
|
@see getNumBufferSizesAvailable, getDefaultBufferSize
|
|
*/
|
|
virtual int getBufferSizeSamples (int index) = 0;
|
|
|
|
/** Returns the default buffer-size to use.
|
|
|
|
@returns a number of samples
|
|
@see getNumBufferSizesAvailable, getBufferSizeSamples
|
|
*/
|
|
virtual int getDefaultBufferSize() = 0;
|
|
|
|
/** Tries to open the device ready to play.
|
|
|
|
@param inputChannels a BitArray in which a set bit indicates that the corresponding
|
|
input channel should be enabled
|
|
@param outputChannels a BitArray in which a set bit indicates that the corresponding
|
|
output channel should be enabled
|
|
@param sampleRate the sample rate to try to use - to find out which rates are
|
|
available, see getNumSampleRates() and getSampleRate()
|
|
@param bufferSizeSamples the size of i/o buffer to use - to find out the available buffer
|
|
sizes, see getNumBufferSizesAvailable() and getBufferSizeSamples()
|
|
@returns an error description if there's a problem, or an empty string if it succeeds in
|
|
opening the device
|
|
@see close
|
|
*/
|
|
virtual const String open (const BitArray& inputChannels,
|
|
const BitArray& outputChannels,
|
|
double sampleRate,
|
|
int bufferSizeSamples) = 0;
|
|
|
|
/** Closes and releases the device if it's open. */
|
|
virtual void close() = 0;
|
|
|
|
/** Returns true if the device is still open.
|
|
|
|
A device might spontaneously close itself if something goes wrong, so this checks if
|
|
it's still open.
|
|
*/
|
|
virtual bool isOpen() = 0;
|
|
|
|
/** Starts the device actually playing.
|
|
|
|
This must be called after the device has been opened.
|
|
|
|
@param callback the callback to use for streaming the data.
|
|
@see AudioIODeviceCallback, open
|
|
*/
|
|
virtual void start (AudioIODeviceCallback* callback) = 0;
|
|
|
|
/** Stops the device playing.
|
|
|
|
Once a device has been started, this will stop it. Any pending calls to the
|
|
callback class will be flushed before this method returns.
|
|
*/
|
|
virtual void stop() = 0;
|
|
|
|
/** Returns true if the device is still calling back.
|
|
|
|
The device might mysteriously stop, so this checks whether it's
|
|
still playing.
|
|
*/
|
|
virtual bool isPlaying() = 0;
|
|
|
|
/** Returns the last error that happened if anything went wrong. */
|
|
virtual const String getLastError() = 0;
|
|
|
|
/** Returns the buffer size that the device is currently using.
|
|
|
|
If the device isn't actually open, this value doesn't really mean much.
|
|
*/
|
|
virtual int getCurrentBufferSizeSamples() = 0;
|
|
|
|
/** Returns the sample rate that the device is currently using.
|
|
|
|
If the device isn't actually open, this value doesn't really mean much.
|
|
*/
|
|
virtual double getCurrentSampleRate() = 0;
|
|
|
|
/** Returns the device's current physical bit-depth.
|
|
|
|
If the device isn't actually open, this value doesn't really mean much.
|
|
*/
|
|
virtual int getCurrentBitDepth() = 0;
|
|
|
|
/** Returns a mask showing which of the available output channels are currently
|
|
enabled.
|
|
@see getOutputChannelNames
|
|
*/
|
|
virtual const BitArray getActiveOutputChannels() const = 0;
|
|
|
|
/** Returns a mask showing which of the available input channels are currently
|
|
enabled.
|
|
@see getInputChannelNames
|
|
*/
|
|
virtual const BitArray getActiveInputChannels() const = 0;
|
|
|
|
/** Returns the device's output latency.
|
|
|
|
This is the delay in samples between a callback getting a block of data, and
|
|
that data actually getting played.
|
|
*/
|
|
virtual int getOutputLatencyInSamples() = 0;
|
|
|
|
/** Returns the device's input latency.
|
|
|
|
This is the delay in samples between some audio actually arriving at the soundcard,
|
|
and the callback getting passed this block of data.
|
|
*/
|
|
virtual int getInputLatencyInSamples() = 0;
|
|
|
|
/** True if this device can show a pop-up control panel for editing its settings.
|
|
|
|
This is generally just true of ASIO devices. If true, you can call showControlPanel()
|
|
to display it.
|
|
*/
|
|
virtual bool hasControlPanel() const;
|
|
|
|
/** Shows a device-specific control panel if there is one.
|
|
|
|
This should only be called for devices which return true from hasControlPanel().
|
|
*/
|
|
virtual bool showControlPanel();
|
|
|
|
protected:
|
|
/** Creates a device, setting its name and type member variables. */
|
|
AudioIODevice (const String& deviceName,
|
|
const String& typeName);
|
|
|
|
/** @internal */
|
|
String name, typeName;
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOIODEVICE_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioIODevice.h *********/
|
|
|
|
/**
|
|
An AudioIODeviceCallback object which streams audio through an AudioProcessor.
|
|
|
|
To use one of these, just make it the callback used by your AudioIODevice, and
|
|
give it a processor to use by calling setProcessor().
|
|
|
|
It's also a MidiInputCallback, so you can connect it to both an audio and midi
|
|
input to send both streams through the processor.
|
|
|
|
@see AudioProcessor, AudioProcessorGraph
|
|
*/
|
|
class JUCE_API AudioProcessorPlayer : public AudioIODeviceCallback,
|
|
public MidiInputCallback
|
|
{
|
|
public:
|
|
|
|
/**
|
|
*/
|
|
AudioProcessorPlayer();
|
|
|
|
/** Destructor. */
|
|
virtual ~AudioProcessorPlayer();
|
|
|
|
/** Sets the processor that should be played.
|
|
|
|
The processor that is passed in will not be deleted or owned by this object.
|
|
To stop anything playing, pass in 0 to this method.
|
|
*/
|
|
void setProcessor (AudioProcessor* const processorToPlay);
|
|
|
|
/** Returns the current audio processor that is being played.
|
|
*/
|
|
AudioProcessor* getCurrentProcessor() const throw() { return processor; }
|
|
|
|
/** Returns a midi message collector that you can pass midi messages to if you
|
|
want them to be injected into the midi stream that is being sent to the
|
|
processor.
|
|
*/
|
|
MidiMessageCollector& getMidiMessageCollector() throw() { return messageCollector; }
|
|
|
|
/** @internal */
|
|
void audioDeviceIOCallback (const float** inputChannelData,
|
|
int totalNumInputChannels,
|
|
float** outputChannelData,
|
|
int totalNumOutputChannels,
|
|
int numSamples);
|
|
/** @internal */
|
|
void audioDeviceAboutToStart (AudioIODevice* device);
|
|
/** @internal */
|
|
void audioDeviceStopped();
|
|
/** @internal */
|
|
void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
AudioProcessor* processor;
|
|
CriticalSection lock;
|
|
double sampleRate;
|
|
int blockSize;
|
|
bool isPrepared;
|
|
|
|
int numInputChans, numOutputChans;
|
|
float* channels [128];
|
|
AudioSampleBuffer tempBuffer;
|
|
|
|
MidiBuffer incomingMidi;
|
|
MidiMessageCollector messageCollector;
|
|
|
|
AudioProcessorPlayer (const AudioProcessorPlayer&);
|
|
const AudioProcessorPlayer& operator= (const AudioProcessorPlayer&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioProcessorPlayer.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_GenericAudioProcessorEditor.h *********/
|
|
#ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__
|
|
#define __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PropertyPanel.h *********/
|
|
#ifndef __JUCE_PROPERTYPANEL_JUCEHEADER__
|
|
#define __JUCE_PROPERTYPANEL_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PropertyComponent.h *********/
|
|
#ifndef __JUCE_PROPERTYCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_PROPERTYCOMPONENT_JUCEHEADER__
|
|
|
|
class EditableProperty;
|
|
|
|
/**
|
|
A base class for a component that goes in a PropertyPanel and displays one of
|
|
an item's properties.
|
|
|
|
Subclasses of this are used to display a property in various forms, e.g. a
|
|
ChoicePropertyComponent shows its value as a combo box; a SliderPropertyComponent
|
|
shows its value as a slider; a TextPropertyComponent as a text box, etc.
|
|
|
|
A subclass must implement the refresh() method which will be called to tell the
|
|
component to update itself, and is also responsible for calling this it when the
|
|
item that it refers to is changed.
|
|
|
|
@see PropertyPanel, TextPropertyComponent, SliderPropertyComponent,
|
|
ChoicePropertyComponent, ButtonPropertyComponent, BooleanPropertyComponent
|
|
*/
|
|
class JUCE_API PropertyComponent : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates a PropertyComponent.
|
|
|
|
@param propertyName the name is stored as this component's name, and is
|
|
used as the name displayed next to this component in
|
|
a property panel
|
|
@param preferredHeight the height that the component should be given - some
|
|
items may need to be larger than a normal row height.
|
|
This value can also be set if a subclass changes the
|
|
preferredHeight member variable.
|
|
*/
|
|
PropertyComponent (const String& propertyName,
|
|
const int preferredHeight = 25);
|
|
|
|
/** Destructor. */
|
|
~PropertyComponent();
|
|
|
|
/** Returns this item's preferred height.
|
|
|
|
This value is specified either in the constructor or by a subclass changing the
|
|
preferredHeight member variable.
|
|
*/
|
|
int getPreferredHeight() const throw() { return preferredHeight; }
|
|
|
|
/** Updates the property component if the item it refers to has changed.
|
|
|
|
A subclass must implement this method, and other objects may call it to
|
|
force it to refresh itself.
|
|
|
|
The subclass should be economical in the amount of work is done, so for
|
|
example it should check whether it really needs to do a repaint rather than
|
|
just doing one every time this method is called, as it may be called when
|
|
the value being displayed hasn't actually changed.
|
|
*/
|
|
virtual void refresh() = 0;
|
|
|
|
/** The default paint method fills the background and draws a label for the
|
|
item's name.
|
|
|
|
@see LookAndFeel::drawPropertyComponentBackground(), LookAndFeel::drawPropertyComponentLabel()
|
|
*/
|
|
void paint (Graphics& g);
|
|
|
|
/** The default resize method positions any child component to the right of this
|
|
one, based on the look and feel's default label size.
|
|
*/
|
|
void resized();
|
|
|
|
/** By default, this just repaints the component. */
|
|
void enablementChanged();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** Used by the PropertyPanel to determine how high this component needs to be.
|
|
|
|
A subclass can update this value in its constructor but shouldn't alter it later
|
|
as changes won't necessarily be picked up.
|
|
*/
|
|
int preferredHeight;
|
|
};
|
|
|
|
#endif // __JUCE_PROPERTYCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_PropertyComponent.h *********/
|
|
|
|
/********* Start of inlined file: juce_Viewport.h *********/
|
|
#ifndef __JUCE_VIEWPORT_JUCEHEADER__
|
|
#define __JUCE_VIEWPORT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ScrollBar.h *********/
|
|
#ifndef __JUCE_SCROLLBAR_JUCEHEADER__
|
|
#define __JUCE_SCROLLBAR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Button.h *********/
|
|
#ifndef __JUCE_BUTTON_JUCEHEADER__
|
|
#define __JUCE_BUTTON_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_TooltipWindow.h *********/
|
|
#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__
|
|
#define __JUCE_TOOLTIPWINDOW_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_TooltipClient.h *********/
|
|
#ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__
|
|
#define __JUCE_TOOLTIPCLIENT_JUCEHEADER__
|
|
|
|
/**
|
|
Components that want to use pop-up tooltips should implement this interface.
|
|
|
|
A TooltipWindow will wait for the mouse to hover over a component that
|
|
implements the TooltipClient interface, and when it finds one, it will display
|
|
the tooltip returned by its getTooltip() method.
|
|
|
|
@see TooltipWindow, SettableTooltipClient
|
|
*/
|
|
class JUCE_API TooltipClient
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~TooltipClient() {}
|
|
|
|
/** Returns the string that this object wants to show as its tooltip. */
|
|
virtual const String getTooltip() = 0;
|
|
};
|
|
|
|
/**
|
|
An implementation of TooltipClient that stores the tooltip string and a method
|
|
for changing it.
|
|
|
|
This makes it easy to add a tooltip to a custom component, by simply adding this
|
|
as a base class and calling setTooltip().
|
|
|
|
Many of the Juce widgets already use this as a base class to implement their
|
|
tooltips.
|
|
|
|
@see TooltipClient, TooltipWindow
|
|
*/
|
|
class JUCE_API SettableTooltipClient : public TooltipClient
|
|
{
|
|
public:
|
|
|
|
/** Destructor. */
|
|
virtual ~SettableTooltipClient() {}
|
|
|
|
virtual void setTooltip (const String& newTooltip) { tooltipString = newTooltip; }
|
|
|
|
virtual const String getTooltip() { return tooltipString; }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
String tooltipString;
|
|
};
|
|
|
|
#endif // __JUCE_TOOLTIPCLIENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_TooltipClient.h *********/
|
|
|
|
/**
|
|
A window that displays a pop-up tooltip when the mouse hovers over another component.
|
|
|
|
To enable tooltips in your app, just create a single instance of a TooltipWindow
|
|
object.
|
|
|
|
The TooltipWindow object will then stay invisible, waiting until the mouse
|
|
hovers for the specified length of time - it will then see if it's currently
|
|
over a component which implements the TooltipClient interface, and if so,
|
|
it will make itself visible to show the tooltip in the appropriate place.
|
|
|
|
@see TooltipClient, SettableTooltipClient
|
|
*/
|
|
class JUCE_API TooltipWindow : public Component,
|
|
private Timer
|
|
{
|
|
public:
|
|
|
|
/** Creates a tooltip window.
|
|
|
|
Make sure your app only creates one instance of this class, otherwise you'll
|
|
get multiple overlaid tooltips appearing. The window will initially be invisible
|
|
and will make itself visible when it needs to display a tip.
|
|
|
|
To change the style of tooltips, see the LookAndFeel class for its tooltip
|
|
methods.
|
|
|
|
@param parentComponent if set to 0, the TooltipWindow will appear on the desktop,
|
|
otherwise the tooltip will be added to the given parent
|
|
component.
|
|
@param millisecondsBeforeTipAppears the time for which the mouse has to stay still
|
|
before a tooltip will be shown
|
|
|
|
@see TooltipClient, LookAndFeel::drawTooltip, LookAndFeel::getTooltipSize
|
|
*/
|
|
TooltipWindow (Component* parentComponent = 0,
|
|
const int millisecondsBeforeTipAppears = 700);
|
|
|
|
/** Destructor. */
|
|
~TooltipWindow();
|
|
|
|
/** Changes the time before the tip appears.
|
|
This lets you change the value that was set in the constructor.
|
|
*/
|
|
void setMillisecondsBeforeTipAppears (const int newTimeMs = 700) throw();
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the tooltip.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1001b00, /**< The colour to fill the background with. */
|
|
textColourId = 0x1001c00, /**< The colour to use for the text. */
|
|
outlineColourId = 0x1001c10 /**< The colour to use to draw an outline around the tooltip. */
|
|
};
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
int millisecondsBeforeTipAppears;
|
|
int mouseX, mouseY, mouseClicks;
|
|
unsigned int lastCompChangeTime, lastHideTime;
|
|
Component* lastComponentUnderMouse;
|
|
bool changedCompsSinceShown;
|
|
String tipShowing, lastTipUnderMouse;
|
|
|
|
void paint (Graphics& g);
|
|
void mouseEnter (const MouseEvent& e);
|
|
void timerCallback();
|
|
|
|
static const String getTipFor (Component* const c);
|
|
void showFor (Component* const c, const String& tip);
|
|
void hide();
|
|
|
|
TooltipWindow (const TooltipWindow&);
|
|
const TooltipWindow& operator= (const TooltipWindow&);
|
|
};
|
|
|
|
#endif // __JUCE_TOOLTIPWINDOW_JUCEHEADER__
|
|
/********* End of inlined file: juce_TooltipWindow.h *********/
|
|
|
|
class Button;
|
|
|
|
/**
|
|
Used to receive callbacks when a button is clicked.
|
|
|
|
@see Button::addButtonListener, Button::removeButtonListener
|
|
*/
|
|
class JUCE_API ButtonListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~ButtonListener() {}
|
|
|
|
/** Called when the button is clicked. */
|
|
virtual void buttonClicked (Button* button) = 0;
|
|
|
|
/** Called when the button's state changes. */
|
|
virtual void buttonStateChanged (Button*) {}
|
|
};
|
|
|
|
/**
|
|
A base class for buttons.
|
|
|
|
This contains all the logic for button behaviours such as enabling/disabling,
|
|
responding to shortcut keystrokes, auto-repeating when held down, toggle-buttons
|
|
and radio groups, etc.
|
|
|
|
@see TextButton, DrawableButton, ToggleButton
|
|
*/
|
|
class JUCE_API Button : public Component,
|
|
public SettableTooltipClient,
|
|
public ApplicationCommandManagerListener,
|
|
private KeyListener
|
|
{
|
|
protected:
|
|
|
|
/** Creates a button.
|
|
|
|
@param buttonName the text to put in the button (the component's name is also
|
|
initially set to this string, but these can be changed later
|
|
using the setName() and setButtonText() methods)
|
|
*/
|
|
Button (const String& buttonName);
|
|
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~Button();
|
|
|
|
/** Changes the button's text.
|
|
|
|
@see getButtonText
|
|
*/
|
|
void setButtonText (const String& newText) throw();
|
|
|
|
/** Returns the text displayed in the button.
|
|
|
|
@see setButtonText
|
|
*/
|
|
const String getButtonText() const throw() { return text; }
|
|
|
|
/** Returns true if the button is currently being held down by the mouse.
|
|
|
|
@see isOver
|
|
*/
|
|
bool isDown() const throw();
|
|
|
|
/** Returns true if the mouse is currently over the button.
|
|
|
|
This will be also be true if the mouse is being held down.
|
|
|
|
@see isDown
|
|
*/
|
|
bool isOver() const throw();
|
|
|
|
/** A button has an on/off state associated with it, and this changes that.
|
|
|
|
By default buttons are 'off' and for simple buttons that you click to perform
|
|
an action you won't change this. Toggle buttons, however will want to
|
|
change their state when turned on or off.
|
|
|
|
@param shouldBeOn whether to set the button's toggle state to be on or
|
|
off. If it's a member of a button group, this will
|
|
always try to turn it on, and to turn off any other
|
|
buttons in the group
|
|
@param sendChangeNotification if true, a callback will be made to clicked(); if false
|
|
the button will be repainted but no notification will
|
|
be sent
|
|
@see getToggleState, setRadioGroupId
|
|
*/
|
|
void setToggleState (const bool shouldBeOn,
|
|
const bool sendChangeNotification);
|
|
|
|
/** Returns true if the button in 'on'.
|
|
|
|
By default buttons are 'off' and for simple buttons that you click to perform
|
|
an action you won't change this. Toggle buttons, however will want to
|
|
change their state when turned on or off.
|
|
|
|
@see setToggleState
|
|
*/
|
|
bool getToggleState() const throw() { return isOn; }
|
|
|
|
/** This tells the button to automatically flip the toggle state when
|
|
the button is clicked.
|
|
|
|
If set to true, then before the clicked() callback occurs, the toggle-state
|
|
of the button is flipped.
|
|
*/
|
|
void setClickingTogglesState (const bool shouldToggle) throw();
|
|
|
|
/** Returns true if this button is set to be an automatic toggle-button.
|
|
|
|
This returns the last value that was passed to setClickingTogglesState().
|
|
*/
|
|
bool getClickingTogglesState() const throw();
|
|
|
|
/** Enables the button to act as a member of a mutually-exclusive group
|
|
of 'radio buttons'.
|
|
|
|
If the group ID is set to a non-zero number, then this button will
|
|
act as part of a group of buttons with the same ID, only one of
|
|
which can be 'on' at the same time. Note that when it's part of
|
|
a group, clicking a toggle-button that's 'on' won't turn it off.
|
|
|
|
To find other buttons with the same ID, this button will search through
|
|
its sibling components for ToggleButtons, so all the buttons for a
|
|
particular group must be placed inside the same parent component.
|
|
|
|
Set the group ID back to zero if you want it to act as a normal toggle
|
|
button again.
|
|
|
|
@see getRadioGroupId
|
|
*/
|
|
void setRadioGroupId (const int newGroupId);
|
|
|
|
/** Returns the ID of the group to which this button belongs.
|
|
|
|
(See setRadioGroupId() for an explanation of this).
|
|
*/
|
|
int getRadioGroupId() const throw() { return radioGroupId; }
|
|
|
|
/** Registers a listener to receive events when this button's state changes.
|
|
|
|
If the listener is already registered, this will not register it again.
|
|
|
|
@see removeButtonListener
|
|
*/
|
|
void addButtonListener (ButtonListener* const newListener) throw();
|
|
|
|
/** Removes a previously-registered button listener
|
|
|
|
@see addButtonListener
|
|
*/
|
|
void removeButtonListener (ButtonListener* const listener) throw();
|
|
|
|
/** Causes the button to act as if it's been clicked.
|
|
|
|
This will asynchronously make the button draw itself going down and up, and
|
|
will then call back the clicked() method as if mouse was clicked on it.
|
|
|
|
@see clicked
|
|
*/
|
|
virtual void triggerClick();
|
|
|
|
/** Sets a command ID for this button to automatically invoke when it's clicked.
|
|
|
|
When the button is pressed, it will use the given manager to trigger the
|
|
command ID.
|
|
|
|
Obviously be careful that the ApplicationCommandManager doesn't get deleted
|
|
before this button is. To disable the command triggering, call this method and
|
|
pass 0 for the parameters.
|
|
|
|
If generateTooltip is true, then the button's tooltip will be automatically
|
|
generated based on the name of this command and its current shortcut key.
|
|
|
|
@see addShortcut, getCommandID
|
|
*/
|
|
void setCommandToTrigger (ApplicationCommandManager* commandManagerToUse,
|
|
const int commandID,
|
|
const bool generateTooltip);
|
|
|
|
/** Returns the command ID that was set by setCommandToTrigger().
|
|
*/
|
|
int getCommandID() const throw() { return commandID; }
|
|
|
|
/** Assigns a shortcut key to trigger the button.
|
|
|
|
The button registers itself with its top-level parent component for keypresses.
|
|
|
|
Note that a different way of linking buttons to keypresses is by using the
|
|
setKeyPressToTrigger() method to invoke a command - the difference being that
|
|
setting a shortcut allows the button to be temporarily linked to a keypress
|
|
only while it's on-screen.
|
|
|
|
@see clearShortcuts
|
|
*/
|
|
void addShortcut (const KeyPress& key);
|
|
|
|
/** Removes all key shortcuts that had been set for this button.
|
|
|
|
@see addShortcut
|
|
*/
|
|
void clearShortcuts();
|
|
|
|
/** Returns true if the given keypress is a shortcut for this button.
|
|
|
|
@see addShortcut
|
|
*/
|
|
bool isRegisteredForShortcut (const KeyPress& key) const throw();
|
|
|
|
/** Sets an auto-repeat speed for the button when it is held down.
|
|
|
|
(Auto-repeat is disabled by default).
|
|
|
|
@param initialDelayInMillisecs how long to wait after the mouse is pressed before
|
|
triggering the next click. If this is zero, auto-repeat
|
|
is disabled
|
|
@param repeatDelayInMillisecs the frequently subsequent repeated clicks should be
|
|
triggered
|
|
@param minimumDelayInMillisecs if this is greater than 0, the auto-repeat speed will
|
|
get faster, the longer the button is held down, up to the
|
|
minimum interval specified here
|
|
*/
|
|
void setRepeatSpeed (const int initialDelayInMillisecs,
|
|
const int repeatDelayInMillisecs,
|
|
const int minimumDelayInMillisecs = -1) throw();
|
|
|
|
/** Sets whether the button click should happen when the mouse is pressed or released.
|
|
|
|
By default the button is only considered to have been clicked when the mouse is
|
|
released, but setting this to true will make it call the clicked() method as soon
|
|
as the button is pressed.
|
|
|
|
This is useful if the button is being used to show a pop-up menu, as it allows
|
|
the click to be used as a drag onto the menu.
|
|
*/
|
|
void setTriggeredOnMouseDown (const bool isTriggeredOnMouseDown) throw();
|
|
|
|
/** Returns the number of milliseconds since the last time the button
|
|
went into the 'down' state.
|
|
*/
|
|
uint32 getMillisecondsSinceButtonDown() const throw();
|
|
|
|
/** (overridden from Component to do special stuff). */
|
|
void setVisible (bool shouldBeVisible);
|
|
|
|
/** Sets the tooltip for this button.
|
|
|
|
@see TooltipClient, TooltipWindow
|
|
*/
|
|
void setTooltip (const String& newTooltip);
|
|
|
|
// (implementation of the TooltipClient method)
|
|
const String getTooltip();
|
|
|
|
/** A combination of these flags are used by setConnectedEdges().
|
|
*/
|
|
enum ConnectedEdgeFlags
|
|
{
|
|
ConnectedOnLeft = 1,
|
|
ConnectedOnRight = 2,
|
|
ConnectedOnTop = 4,
|
|
ConnectedOnBottom = 8
|
|
};
|
|
|
|
/** Hints about which edges of the button might be connected to adjoining buttons.
|
|
|
|
The value passed in is a bitwise combination of any of the values in the
|
|
ConnectedEdgeFlags enum.
|
|
|
|
E.g. if you are placing two buttons adjacent to each other, you could use this to
|
|
indicate which edges are touching, and the LookAndFeel might choose to drawn them
|
|
without rounded corners on the edges that connect. It's only a hint, so the
|
|
LookAndFeel can choose to ignore it if it's not relevent for this type of
|
|
button.
|
|
*/
|
|
void setConnectedEdges (const int connectedEdgeFlags) throw();
|
|
|
|
/** Returns the set of flags passed into setConnectedEdges(). */
|
|
int getConnectedEdgeFlags() const throw() { return connectedEdgeFlags; }
|
|
|
|
/** Indicates whether the button adjoins another one on its left edge.
|
|
@see setConnectedEdges
|
|
*/
|
|
bool isConnectedOnLeft() const throw() { return (connectedEdgeFlags & ConnectedOnLeft) != 0; }
|
|
|
|
/** Indicates whether the button adjoins another one on its right edge.
|
|
@see setConnectedEdges
|
|
*/
|
|
bool isConnectedOnRight() const throw() { return (connectedEdgeFlags & ConnectedOnRight) != 0; }
|
|
|
|
/** Indicates whether the button adjoins another one on its top edge.
|
|
@see setConnectedEdges
|
|
*/
|
|
bool isConnectedOnTop() const throw() { return (connectedEdgeFlags & ConnectedOnTop) != 0; }
|
|
|
|
/** Indicates whether the button adjoins another one on its bottom edge.
|
|
@see setConnectedEdges
|
|
*/
|
|
bool isConnectedOnBottom() const throw() { return (connectedEdgeFlags & ConnectedOnBottom) != 0; }
|
|
|
|
/** Used by setState(). */
|
|
enum ButtonState
|
|
{
|
|
buttonNormal,
|
|
buttonOver,
|
|
buttonDown
|
|
};
|
|
|
|
/** Can be used to force the button into a particular state.
|
|
|
|
This only changes the button's appearance, it won't trigger a click, or stop any mouse-clicks
|
|
from happening.
|
|
|
|
The state that you set here will only last until it is automatically changed when the mouse
|
|
enters or exits the button, or the mouse-button is pressed or released.
|
|
*/
|
|
void setState (const ButtonState newState);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
/** This method is called when the button has been clicked.
|
|
|
|
Subclasses can override this to perform whatever they actions they need
|
|
to do.
|
|
|
|
Alternatively, a ButtonListener can be added to the button, and these listeners
|
|
will be called when the click occurs.
|
|
|
|
@see triggerClick
|
|
*/
|
|
virtual void clicked();
|
|
|
|
/** This method is called when the button has been clicked.
|
|
|
|
By default it just calls clicked(), but you might want to override it to handle
|
|
things like clicking when a modifier key is pressed, etc.
|
|
|
|
@see ModifierKeys
|
|
*/
|
|
virtual void clicked (const ModifierKeys& modifiers);
|
|
|
|
/** Subclasses should override this to actually paint the button's contents.
|
|
|
|
It's better to use this than the paint method, because it gives you information
|
|
about the over/down state of the button.
|
|
|
|
@param g the graphics context to use
|
|
@param isMouseOverButton true if the button is either in the 'over' or
|
|
'down' state
|
|
@param isButtonDown true if the button should be drawn in the 'down' position
|
|
*/
|
|
virtual void paintButton (Graphics& g,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown) = 0;
|
|
|
|
/** Called when the button's up/down/over state changes.
|
|
|
|
Subclasses can override this if they need to do something special when the button
|
|
goes up or down.
|
|
|
|
@see isDown, isOver
|
|
*/
|
|
virtual void buttonStateChanged();
|
|
|
|
/** @internal */
|
|
virtual void internalClickCallback (const ModifierKeys& modifiers);
|
|
/** @internal */
|
|
void handleCommandMessage (int commandId);
|
|
/** @internal */
|
|
void mouseEnter (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseExit (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseUp (const MouseEvent& e);
|
|
/** @internal */
|
|
bool keyPressed (const KeyPress& key);
|
|
/** @internal */
|
|
bool keyPressed (const KeyPress& key, Component* originatingComponent);
|
|
/** @internal */
|
|
bool keyStateChanged (const bool isKeyDown, Component* originatingComponent);
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void parentHierarchyChanged();
|
|
/** @internal */
|
|
void focusGained (FocusChangeType cause);
|
|
/** @internal */
|
|
void focusLost (FocusChangeType cause);
|
|
/** @internal */
|
|
void enablementChanged();
|
|
/** @internal */
|
|
void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo&);
|
|
/** @internal */
|
|
void applicationCommandListChanged();
|
|
|
|
private:
|
|
|
|
Array <KeyPress> shortcuts;
|
|
Component* keySource;
|
|
String text;
|
|
SortedSet <void*> buttonListeners;
|
|
|
|
friend class InternalButtonRepeatTimer;
|
|
Timer* repeatTimer;
|
|
uint32 buttonPressTime, lastTimeCallbackTime;
|
|
ApplicationCommandManager* commandManagerToUse;
|
|
int autoRepeatDelay, autoRepeatSpeed, autoRepeatMinimumDelay;
|
|
int radioGroupId, commandID, connectedEdgeFlags;
|
|
ButtonState buttonState;
|
|
|
|
bool isOn : 1;
|
|
bool clickTogglesState : 1;
|
|
bool needsToRelease : 1;
|
|
bool needsRepainting : 1;
|
|
bool isKeyDown : 1;
|
|
bool triggerOnMouseDown : 1;
|
|
bool generateTooltip : 1;
|
|
|
|
void repeatTimerCallback() throw();
|
|
Timer& getRepeatTimer() throw();
|
|
|
|
ButtonState updateState (const MouseEvent* const e) throw();
|
|
bool isShortcutPressed() const throw();
|
|
void turnOffOtherButtonsInGroup (const bool sendChangeNotification);
|
|
|
|
void flashButtonState() throw();
|
|
void sendClickMessage (const ModifierKeys& modifiers);
|
|
void sendStateMessage();
|
|
|
|
Button (const Button&);
|
|
const Button& operator= (const Button&);
|
|
};
|
|
|
|
#endif // __JUCE_BUTTON_JUCEHEADER__
|
|
/********* End of inlined file: juce_Button.h *********/
|
|
|
|
class ScrollBar;
|
|
|
|
/**
|
|
A class for receiving events from a ScrollBar.
|
|
|
|
You can register a ScrollBarListener with a ScrollBar using the ScrollBar::addListener()
|
|
method, and it will be called when the bar's position changes.
|
|
|
|
@see ScrollBar::addListener, ScrollBar::removeListener
|
|
*/
|
|
class JUCE_API ScrollBarListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~ScrollBarListener() {}
|
|
|
|
/** Called when a ScrollBar is moved.
|
|
|
|
@param scrollBarThatHasMoved the bar that has moved
|
|
@param newRangeStart the new range start of this bar
|
|
*/
|
|
virtual void scrollBarMoved (ScrollBar* scrollBarThatHasMoved,
|
|
const double newRangeStart) = 0;
|
|
};
|
|
|
|
/**
|
|
A scrollbar component.
|
|
|
|
To use a scrollbar, set up its total range using the setRangeLimits() method - this
|
|
sets the range of values it can represent. Then you can use setCurrentRange() to
|
|
change the position and size of the scrollbar's 'thumb'.
|
|
|
|
Registering a ScrollBarListener with the scrollbar will allow you to find out when
|
|
the user moves it, and you can use the getCurrentRangeStart() to find out where
|
|
they moved it to.
|
|
|
|
The scrollbar will adjust its own visibility according to whether its thumb size
|
|
allows it to actually be scrolled.
|
|
|
|
For most purposes, it's probably easier to use a ViewportContainer or ListBox
|
|
instead of handling a scrollbar directly.
|
|
|
|
@see ScrollBarListener
|
|
*/
|
|
class JUCE_API ScrollBar : public Component,
|
|
public AsyncUpdater,
|
|
private Timer
|
|
{
|
|
public:
|
|
|
|
/** Creates a Scrollbar.
|
|
|
|
@param isVertical whether it should be a vertical or horizontal bar
|
|
@param buttonsAreVisible whether to show the up/down or left/right buttons
|
|
*/
|
|
ScrollBar (const bool isVertical,
|
|
const bool buttonsAreVisible = true);
|
|
|
|
/** Destructor. */
|
|
~ScrollBar();
|
|
|
|
/** Returns true if the scrollbar is vertical, false if it's horizontal. */
|
|
bool isVertical() const throw() { return vertical; }
|
|
|
|
/** Changes the scrollbar's direction.
|
|
|
|
You'll also need to resize the bar appropriately - this just changes its internal
|
|
layout.
|
|
|
|
@param shouldBeVertical true makes it vertical; false makes it horizontal.
|
|
*/
|
|
void setOrientation (const bool shouldBeVertical) throw();
|
|
|
|
/** Shows or hides the scrollbar's buttons. */
|
|
void setButtonVisibility (const bool buttonsAreVisible);
|
|
|
|
/** Tells the scrollbar whether to make itself invisible when not needed.
|
|
|
|
The default behaviour is for a scrollbar to become invisible when the thumb
|
|
fills the whole of its range (i.e. when it can't be moved). Setting this
|
|
value to false forces the bar to always be visible.
|
|
*/
|
|
void setAutoHide (const bool shouldHideWhenFullRange);
|
|
|
|
/** Sets the minimum and maximum values that the bar will move between.
|
|
|
|
The bar's thumb will always be constrained so that the top of the thumb
|
|
will be >= minimum, and the bottom of the thumb <= maximum.
|
|
|
|
@see setCurrentRange
|
|
*/
|
|
void setRangeLimits (const double minimum,
|
|
const double maximum) throw();
|
|
|
|
/** Returns the lower value that the thumb can be set to.
|
|
|
|
This is the value set by setRangeLimits().
|
|
*/
|
|
double getMinimumRangeLimit() const throw() { return minimum; }
|
|
|
|
/** Returns the upper value that the thumb can be set to.
|
|
|
|
This is the value set by setRangeLimits().
|
|
*/
|
|
double getMaximumRangeLimit() const throw() { return maximum; }
|
|
|
|
/** Changes the position of the scrollbar's 'thumb'.
|
|
|
|
This sets both the position and size of the thumb - to just set the position without
|
|
changing the size, you can use setCurrentRangeStart().
|
|
|
|
If this method call actually changes the scrollbar's position, it will trigger an
|
|
asynchronous call to ScrollBarListener::scrollBarMoved() for all the listeners that
|
|
are registered.
|
|
|
|
@param newStart the top (or left) of the thumb, in the range
|
|
getMinimumRangeLimit() <= newStart <= getMaximumRangeLimit(). If the
|
|
value is beyond these limits, it will be clipped.
|
|
@param newSize the size of the thumb, such that
|
|
getMinimumRangeLimit() <= newStart + newSize <= getMaximumRangeLimit(). If the
|
|
size is beyond these limits, it will be clipped.
|
|
@see setCurrentRangeStart, getCurrentRangeStart, getCurrentRangeSize
|
|
*/
|
|
void setCurrentRange (double newStart,
|
|
double newSize) throw();
|
|
|
|
/** Moves the bar's thumb position.
|
|
|
|
This will move the thumb position without changing the thumb size. Note
|
|
that the maximum thumb start position is (getMaximumRangeLimit() - getCurrentRangeSize()).
|
|
|
|
If this method call actually changes the scrollbar's position, it will trigger an
|
|
asynchronous call to ScrollBarListener::scrollBarMoved() for all the listeners that
|
|
are registered.
|
|
|
|
@see setCurrentRange
|
|
*/
|
|
void setCurrentRangeStart (double newStart) throw();
|
|
|
|
/** Returns the position of the top of the thumb.
|
|
|
|
@see setCurrentRangeStart
|
|
*/
|
|
double getCurrentRangeStart() const throw() { return rangeStart; }
|
|
|
|
/** Returns the current size of the thumb.
|
|
|
|
@see setCurrentRange
|
|
*/
|
|
double getCurrentRangeSize() const throw() { return rangeSize; }
|
|
|
|
/** Sets the amount by which the up and down buttons will move the bar.
|
|
|
|
The value here is in terms of the total range, and is added or subtracted
|
|
from the thumb position when the user clicks an up/down (or left/right) button.
|
|
*/
|
|
void setSingleStepSize (const double newSingleStepSize) throw();
|
|
|
|
/** Moves the scrollbar by a number of single-steps.
|
|
|
|
This will move the bar by a multiple of its single-step interval (as
|
|
specified using the setSingleStepSize() method).
|
|
|
|
A positive value here will move the bar down or to the right, a negative
|
|
value moves it up or to the left.
|
|
*/
|
|
void moveScrollbarInSteps (const int howManySteps) throw();
|
|
|
|
/** Moves the scroll bar up or down in pages.
|
|
|
|
This will move the bar by a multiple of its current thumb size, effectively
|
|
doing a page-up or down.
|
|
|
|
A positive value here will move the bar down or to the right, a negative
|
|
value moves it up or to the left.
|
|
*/
|
|
void moveScrollbarInPages (const int howManyPages) throw();
|
|
|
|
/** Scrolls to the top (or left).
|
|
|
|
This is the same as calling setCurrentRangeStart (getMinimumRangeLimit());
|
|
*/
|
|
void scrollToTop() throw();
|
|
|
|
/** Scrolls to the bottom (or right).
|
|
|
|
This is the same as calling setCurrentRangeStart (getMaximumRangeLimit() - getCurrentRangeSize());
|
|
*/
|
|
void scrollToBottom() throw();
|
|
|
|
/** Changes the delay before the up and down buttons autorepeat when they are held
|
|
down.
|
|
|
|
For an explanation of what the parameters are for, see Button::setRepeatSpeed().
|
|
|
|
@see Button::setRepeatSpeed
|
|
*/
|
|
void setButtonRepeatSpeed (const int initialDelayInMillisecs,
|
|
const int repeatDelayInMillisecs,
|
|
const int minimumDelayInMillisecs = -1) throw();
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the component.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1000300, /**< The background colour of the scrollbar. */
|
|
thumbColourId = 0x1000400, /**< A base colour to use for the thumb. The look and feel will probably use variations on this colour. */
|
|
trackColourId = 0x1000401 /**< A base colour to use for the slot area of the bar. The look and feel will probably use variations on this colour. */
|
|
};
|
|
|
|
/** Registers a listener that will be called when the scrollbar is moved. */
|
|
void addListener (ScrollBarListener* const listener) throw();
|
|
|
|
/** Deregisters a previously-registered listener. */
|
|
void removeListener (ScrollBarListener* const listener) throw();
|
|
|
|
/** @internal */
|
|
bool keyPressed (const KeyPress& key);
|
|
/** @internal */
|
|
void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
|
|
/** @internal */
|
|
void lookAndFeelChanged();
|
|
/** @internal */
|
|
void handleAsyncUpdate();
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseUp (const MouseEvent& e);
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
double minimum, maximum;
|
|
double rangeStart, rangeSize;
|
|
double singleStepSize, dragStartRange;
|
|
int thumbAreaStart, thumbAreaSize, thumbStart, thumbSize;
|
|
int dragStartMousePos, lastMousePos;
|
|
int initialDelayInMillisecs, repeatDelayInMillisecs, minimumDelayInMillisecs;
|
|
bool vertical, isDraggingThumb, alwaysVisible;
|
|
Button* upButton;
|
|
Button* downButton;
|
|
SortedSet <void*> listeners;
|
|
|
|
void updateThumbPosition() throw();
|
|
void timerCallback();
|
|
|
|
ScrollBar (const ScrollBar&);
|
|
const ScrollBar& operator= (const ScrollBar&);
|
|
};
|
|
|
|
#endif // __JUCE_SCROLLBAR_JUCEHEADER__
|
|
/********* End of inlined file: juce_ScrollBar.h *********/
|
|
|
|
/**
|
|
A Viewport is used to contain a larger child component, and allows the child
|
|
to be automatically scrolled around.
|
|
|
|
To use a Viewport, just create one and set the component that goes inside it
|
|
using the setViewedComponent() method. When the child component changes size,
|
|
the Viewport will adjust its scrollbars accordingly.
|
|
|
|
A subclass of the viewport can be created which will receive calls to its
|
|
visibleAreaChanged() method when the subcomponent changes position or size.
|
|
|
|
*/
|
|
class JUCE_API Viewport : public Component,
|
|
private ComponentListener,
|
|
private ScrollBarListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a Viewport.
|
|
|
|
The viewport is initially empty - use the setViewedComponent() method to
|
|
add a child component for it to manage.
|
|
*/
|
|
Viewport (const String& componentName = String::empty);
|
|
|
|
/** Destructor. */
|
|
~Viewport();
|
|
|
|
/** Sets the component that this viewport will contain and scroll around.
|
|
|
|
This will add the given component to this Viewport and position it at
|
|
(0, 0).
|
|
|
|
(Don't add or remove any child components directly using the normal
|
|
Component::addChildComponent() methods).
|
|
|
|
@param newViewedComponent the component to add to this viewport (this pointer
|
|
may be null). The component passed in will be deleted
|
|
by the Viewport when it's no longer needed
|
|
@see getViewedComponent
|
|
*/
|
|
void setViewedComponent (Component* const newViewedComponent);
|
|
|
|
/** Returns the component that's currently being used inside the Viewport.
|
|
|
|
@see setViewedComponent
|
|
*/
|
|
Component* getViewedComponent() const throw() { return contentComp; }
|
|
|
|
/** Changes the position of the viewed component.
|
|
|
|
The inner component will be moved so that the pixel at the top left of
|
|
the viewport will be the pixel at position (xPixelsOffset, yPixelsOffset)
|
|
within the inner component.
|
|
|
|
This will update the scrollbars and might cause a call to visibleAreaChanged().
|
|
|
|
@see getViewPositionX, getViewPositionY, setViewPositionProportionately
|
|
*/
|
|
void setViewPosition (const int xPixelsOffset,
|
|
const int yPixelsOffset);
|
|
|
|
/** Changes the view position as a proportion of the distance it can move.
|
|
|
|
The values here are from 0.0 to 1.0 - where (0, 0) would put the
|
|
visible area in the top-left, and (1, 1) would put it as far down and
|
|
to the right as it's possible to go whilst keeping the child component
|
|
on-screen.
|
|
*/
|
|
void setViewPositionProportionately (const double proportionX,
|
|
const double proportionY);
|
|
|
|
/** Returns the position within the child component of the top-left of its visible area.
|
|
@see getViewWidth, setViewPosition
|
|
*/
|
|
int getViewPositionX() const throw() { return lastVX; }
|
|
|
|
/** Returns the position within the child component of the top-left of its visible area.
|
|
@see getViewHeight, setViewPosition
|
|
*/
|
|
int getViewPositionY() const throw() { return lastVY; }
|
|
|
|
/** Returns the width of the visible area of the child component.
|
|
|
|
This may be less than the width of this Viewport if there's a vertical scrollbar
|
|
or if the child component is itself smaller.
|
|
*/
|
|
int getViewWidth() const throw() { return lastVW; }
|
|
|
|
/** Returns the height of the visible area of the child component.
|
|
|
|
This may be less than the height of this Viewport if there's a horizontal scrollbar
|
|
or if the child component is itself smaller.
|
|
*/
|
|
int getViewHeight() const throw() { return lastVH; }
|
|
|
|
/** Returns the width available within this component for the contents.
|
|
|
|
This will be the width of the viewport component minus the width of a
|
|
vertical scrollbar (if visible).
|
|
*/
|
|
int getMaximumVisibleWidth() const throw();
|
|
|
|
/** Returns the height available within this component for the contents.
|
|
|
|
This will be the height of the viewport component minus the space taken up
|
|
by a horizontal scrollbar (if visible).
|
|
*/
|
|
int getMaximumVisibleHeight() const throw();
|
|
|
|
/** Callback method that is called when the visible area changes.
|
|
|
|
This will be called when the visible area is moved either be scrolling or
|
|
by calls to setViewPosition(), etc.
|
|
*/
|
|
virtual void visibleAreaChanged (int visibleX, int visibleY,
|
|
int visibleW, int visibleH);
|
|
|
|
/** Turns scrollbars on or off.
|
|
|
|
If set to false, the scrollbars won't ever appear. When true (the default)
|
|
they will appear only when needed.
|
|
*/
|
|
void setScrollBarsShown (const bool showVerticalScrollbarIfNeeded,
|
|
const bool showHorizontalScrollbarIfNeeded);
|
|
|
|
/** True if the vertical scrollbar is enabled.
|
|
@see setScrollBarsShown
|
|
*/
|
|
bool isVerticalScrollBarShown() const throw() { return showVScrollbar; }
|
|
|
|
/** True if the horizontal scrollbar is enabled.
|
|
@see setScrollBarsShown
|
|
*/
|
|
bool isHorizontalScrollBarShown() const throw() { return showHScrollbar; }
|
|
|
|
/** Changes the width of the scrollbars.
|
|
|
|
If this isn't specified, the default width from the LookAndFeel class will be used.
|
|
|
|
@see LookAndFeel::getDefaultScrollbarWidth
|
|
*/
|
|
void setScrollBarThickness (const int thickness);
|
|
|
|
/** Returns the thickness of the scrollbars.
|
|
|
|
@see setScrollBarThickness
|
|
*/
|
|
int getScrollBarThickness() const throw();
|
|
|
|
/** Changes the distance that a single-step click on a scrollbar button
|
|
will move the viewport.
|
|
*/
|
|
void setSingleStepSizes (const int stepX, const int stepY);
|
|
|
|
/** Shows or hides the buttons on any scrollbars that are used.
|
|
|
|
@see ScrollBar::setButtonVisibility
|
|
*/
|
|
void setScrollBarButtonVisibility (const bool buttonsVisible);
|
|
|
|
/** Returns a pointer to the scrollbar component being used.
|
|
|
|
Handy if you need to customise the bar somehow.
|
|
*/
|
|
ScrollBar* getVerticalScrollBar() const throw() { return verticalScrollBar; }
|
|
|
|
/** Returns a pointer to the scrollbar component being used.
|
|
|
|
Handy if you need to customise the bar somehow.
|
|
*/
|
|
ScrollBar* getHorizontalScrollBar() const throw() { return horizontalScrollBar; }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void scrollBarMoved (ScrollBar* scrollBarThatHasMoved, const double newRangeStart);
|
|
/** @internal */
|
|
void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
|
|
/** @internal */
|
|
bool keyPressed (const KeyPress& key);
|
|
/** @internal */
|
|
void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized);
|
|
/** @internal */
|
|
bool useMouseWheelMoveIfNeeded (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
|
|
|
|
private:
|
|
Component* contentComp;
|
|
int lastVX, lastVY, lastVW, lastVH;
|
|
int scrollBarThickness;
|
|
int singleStepX, singleStepY;
|
|
bool showHScrollbar, showVScrollbar;
|
|
Component* contentHolder;
|
|
ScrollBar* verticalScrollBar;
|
|
ScrollBar* horizontalScrollBar;
|
|
|
|
void updateVisibleRegion();
|
|
Viewport (const Viewport&);
|
|
const Viewport& operator= (const Viewport&);
|
|
};
|
|
|
|
#endif // __JUCE_VIEWPORT_JUCEHEADER__
|
|
/********* End of inlined file: juce_Viewport.h *********/
|
|
|
|
/**
|
|
A panel that holds a list of PropertyComponent objects.
|
|
|
|
This panel displays a list of PropertyComponents, and allows them to be organised
|
|
into collapsible sections.
|
|
|
|
To use, simply create one of these and add your properties to it with addProperties()
|
|
or addSection().
|
|
|
|
@see PropertyComponent
|
|
*/
|
|
class JUCE_API PropertyPanel : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty property panel. */
|
|
PropertyPanel();
|
|
|
|
/** Destructor. */
|
|
~PropertyPanel();
|
|
|
|
/** Deletes all property components from the panel.
|
|
*/
|
|
void clear();
|
|
|
|
/** Adds a set of properties to the panel.
|
|
|
|
The components in the list will be owned by this object and will be automatically
|
|
deleted later on when no longer needed.
|
|
|
|
These properties are added without them being inside a named section. If you
|
|
want them to be kept together in a collapsible section, use addSection() instead.
|
|
*/
|
|
void addProperties (const Array <PropertyComponent*>& newPropertyComponents);
|
|
|
|
/** Adds a set of properties to the panel.
|
|
|
|
These properties are added at the bottom of the list, under a section heading with
|
|
a plus/minus button that allows it to be opened and closed.
|
|
|
|
The components in the list will be owned by this object and will be automatically
|
|
deleted later on when no longer needed.
|
|
|
|
To add properies without them being in a section, use addProperties().
|
|
*/
|
|
void addSection (const String& sectionTitle,
|
|
const Array <PropertyComponent*>& newPropertyComponents,
|
|
const bool shouldSectionInitiallyBeOpen = true);
|
|
|
|
/** Calls the refresh() method of all PropertyComponents in the panel */
|
|
void refreshAll() const;
|
|
|
|
/** Returns a list of all the names of sections in the panel.
|
|
|
|
These are the sections that have been added with addSection().
|
|
*/
|
|
const StringArray getSectionNames() const;
|
|
|
|
/** Returns true if the section at this index is currently open.
|
|
|
|
The index is from 0 up to the number of items returned by getSectionNames().
|
|
*/
|
|
bool isSectionOpen (const int sectionIndex) const;
|
|
|
|
/** Opens or closes one of the sections.
|
|
|
|
The index is from 0 up to the number of items returned by getSectionNames().
|
|
*/
|
|
void setSectionOpen (const int sectionIndex, const bool shouldBeOpen);
|
|
|
|
/** Enables or disables one of the sections.
|
|
|
|
The index is from 0 up to the number of items returned by getSectionNames().
|
|
*/
|
|
void setSectionEnabled (const int sectionIndex, const bool shouldBeEnabled);
|
|
|
|
/** Saves the current state of open/closed sections so it can be restored later.
|
|
|
|
The caller is responsible for deleting the object that is returned.
|
|
|
|
To restore this state, use restoreOpennessState().
|
|
|
|
@see restoreOpennessState
|
|
*/
|
|
XmlElement* getOpennessState() const;
|
|
|
|
/** Restores a previously saved arrangement of open/closed sections.
|
|
|
|
This will try to restore a snapshot of the panel's state that was created by
|
|
the getOpennessState() method. If any of the sections named in the original
|
|
XML aren't present, they will be ignored.
|
|
|
|
@see getOpennessState
|
|
*/
|
|
void restoreOpennessState (const XmlElement& newState);
|
|
|
|
/** Sets a message to be displayed when there are no properties in the panel.
|
|
|
|
The default message is "nothing selected".
|
|
*/
|
|
void setMessageWhenEmpty (const String& newMessage);
|
|
|
|
/** Returns the message that is displayed when there are no properties.
|
|
@see setMessageWhenEmpty
|
|
*/
|
|
const String& getMessageWhenEmpty() const throw();
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Viewport* viewport;
|
|
Component* propertyHolderComponent;
|
|
String messageWhenEmpty;
|
|
|
|
void updatePropHolderLayout() const;
|
|
void updatePropHolderLayout (const int width) const;
|
|
};
|
|
|
|
#endif // __JUCE_PROPERTYPANEL_JUCEHEADER__
|
|
/********* End of inlined file: juce_PropertyPanel.h *********/
|
|
|
|
/**
|
|
A type of UI component that displays the parameters of an AudioProcessor as
|
|
a simple list of sliders.
|
|
|
|
This can be used for showing an editor for a processor that doesn't supply
|
|
its own custom editor.
|
|
|
|
@see AudioProcessor
|
|
*/
|
|
class JUCE_API GenericAudioProcessorEditor : public AudioProcessorEditor
|
|
{
|
|
public:
|
|
|
|
GenericAudioProcessorEditor (AudioProcessor* const owner);
|
|
~GenericAudioProcessorEditor();
|
|
|
|
void paint (Graphics& g);
|
|
void resized();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
PropertyPanel* panel;
|
|
};
|
|
|
|
#endif // __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__
|
|
/********* End of inlined file: juce_GenericAudioProcessorEditor.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioFormatReaderSource.h *********/
|
|
#ifndef __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__
|
|
#define __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PositionableAudioSource.h *********/
|
|
#ifndef __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__
|
|
#define __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioSource.h *********/
|
|
#ifndef __JUCE_AUDIOSOURCE_JUCEHEADER__
|
|
#define __JUCE_AUDIOSOURCE_JUCEHEADER__
|
|
|
|
/**
|
|
Used by AudioSource::getNextAudioBlock().
|
|
*/
|
|
struct JUCE_API AudioSourceChannelInfo
|
|
{
|
|
/** The destination buffer to fill with audio data.
|
|
|
|
When the AudioSource::getNextAudioBlock() method is called, the active section
|
|
of this buffer should be filled with whatever output the source produces.
|
|
|
|
Only the samples specified by the startSample and numSamples members of this structure
|
|
should be affected by the call.
|
|
|
|
The contents of the buffer when it is passed to the the AudioSource::getNextAudioBlock()
|
|
method can be treated as the input if the source is performing some kind of filter operation,
|
|
but should be cleared if this is not the case - the clearActiveBufferRegion() is
|
|
a handy way of doing this.
|
|
|
|
The number of channels in the buffer could be anything, so the AudioSource
|
|
must cope with this in whatever way is appropriate for its function.
|
|
*/
|
|
AudioSampleBuffer* buffer;
|
|
|
|
/** The first sample in the buffer from which the callback is expected
|
|
to write data. */
|
|
int startSample;
|
|
|
|
/** The number of samples in the buffer which the callback is expected to
|
|
fill with data. */
|
|
int numSamples;
|
|
|
|
/** Convenient method to clear the buffer if the source is not producing any data. */
|
|
void clearActiveBufferRegion() const
|
|
{
|
|
if (buffer != 0)
|
|
buffer->clear (startSample, numSamples);
|
|
}
|
|
};
|
|
|
|
/**
|
|
Base class for objects that can produce a continuous stream of audio.
|
|
|
|
@see AudioFormatReaderSource, ResamplingAudioSource
|
|
*/
|
|
class JUCE_API AudioSource
|
|
{
|
|
protected:
|
|
|
|
/** Creates an AudioSource. */
|
|
AudioSource() throw() {}
|
|
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~AudioSource() {}
|
|
|
|
/** Tells the source to prepare for playing.
|
|
|
|
The source can use this opportunity to initialise anything it needs to.
|
|
|
|
Note that this method could be called more than once in succession without
|
|
a matching call to releaseResources(), so make sure your code is robust and
|
|
can handle that kind of situation.
|
|
|
|
@param samplesPerBlockExpected the number of samples that the source
|
|
will be expected to supply each time its
|
|
getNextAudioBlock() method is called. This
|
|
number may vary slightly, because it will be dependent
|
|
on audio hardware callbacks, and these aren't
|
|
guaranteed to always use a constant block size, so
|
|
the source should be able to cope with small variations.
|
|
@param sampleRate the sample rate that the output will be used at - this
|
|
is needed by sources such as tone generators.
|
|
@see releaseResources, getNextAudioBlock
|
|
*/
|
|
virtual void prepareToPlay (int samplesPerBlockExpected,
|
|
double sampleRate) = 0;
|
|
|
|
/** Allows the source to release anything it no longer needs after playback has stopped.
|
|
|
|
This will be called when the source is no longer going to have its getNextAudioBlock()
|
|
method called, so it should release any spare memory, etc. that it might have
|
|
allocated during the prepareToPlay() call.
|
|
|
|
Note that there's no guarantee that prepareToPlay() will actually have been called before
|
|
releaseResources(), and it may be called more than once in succession, so make sure your
|
|
code is robust and doesn't make any assumptions about when it will be called.
|
|
|
|
@see prepareToPlay, getNextAudioBlock
|
|
*/
|
|
virtual void releaseResources() = 0;
|
|
|
|
/** Called repeatedly to fetch subsequent blocks of audio data.
|
|
|
|
After calling the prepareToPlay() method, this callback will be made each
|
|
time the audio playback hardware (or whatever other destination the audio
|
|
data is going to) needs another block of data.
|
|
|
|
It will generally be called on a high-priority system thread, or possibly even
|
|
an interrupt, so be careful not to do too much work here, as that will cause
|
|
audio glitches!
|
|
|
|
@see AudioSourceChannelInfo, prepareToPlay, releaseResources
|
|
*/
|
|
virtual void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) = 0;
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOSOURCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioSource.h *********/
|
|
|
|
/**
|
|
A type of AudioSource which can be repositioned.
|
|
|
|
The basic AudioSource just streams continuously with no idea of a current
|
|
time or length, so the PositionableAudioSource is used for a finite stream
|
|
that has a current read position.
|
|
|
|
@see AudioSource, AudioTransportSource
|
|
*/
|
|
class JUCE_API PositionableAudioSource : public AudioSource
|
|
{
|
|
protected:
|
|
|
|
/** Creates the PositionableAudioSource. */
|
|
PositionableAudioSource() throw() {}
|
|
|
|
public:
|
|
/** Destructor */
|
|
~PositionableAudioSource() {}
|
|
|
|
/** Tells the stream to move to a new position.
|
|
|
|
Calling this indicates that the next call to AudioSource::getNextAudioBlock()
|
|
should return samples from this position.
|
|
|
|
Note that this may be called on a different thread to getNextAudioBlock(),
|
|
so the subclass should make sure it's synchronised.
|
|
*/
|
|
virtual void setNextReadPosition (int newPosition) = 0;
|
|
|
|
/** Returns the position from which the next block will be returned.
|
|
|
|
@see setNextReadPosition
|
|
*/
|
|
virtual int getNextReadPosition() const = 0;
|
|
|
|
/** Returns the total length of the stream (in samples). */
|
|
virtual int getTotalLength() const = 0;
|
|
|
|
/** Returns true if this source is actually playing in a loop. */
|
|
virtual bool isLooping() const = 0;
|
|
};
|
|
|
|
#endif // __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_PositionableAudioSource.h *********/
|
|
|
|
/********* Start of inlined file: juce_AudioFormatReader.h *********/
|
|
#ifndef __JUCE_AUDIOFORMATREADER_JUCEHEADER__
|
|
#define __JUCE_AUDIOFORMATREADER_JUCEHEADER__
|
|
|
|
class AudioFormat;
|
|
|
|
/**
|
|
Reads samples from an audio file stream.
|
|
|
|
A subclass that reads a specific type of audio format will be created by
|
|
an AudioFormat object.
|
|
|
|
@see AudioFormat, AudioFormatWriter
|
|
*/
|
|
class JUCE_API AudioFormatReader
|
|
{
|
|
protected:
|
|
|
|
/** Creates an AudioFormatReader object.
|
|
|
|
@param sourceStream the stream to read from - this will be deleted
|
|
by this object when it is no longer needed. (Some
|
|
specialised readers might not use this parameter and
|
|
can leave it as 0).
|
|
@param formatName the description that will be returned by the getFormatName()
|
|
method
|
|
*/
|
|
AudioFormatReader (InputStream* const sourceStream,
|
|
const String& formatName);
|
|
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~AudioFormatReader();
|
|
|
|
/** Returns a description of what type of format this is.
|
|
|
|
E.g. "AIFF"
|
|
*/
|
|
const String getFormatName() const throw() { return formatName; }
|
|
|
|
/** Reads samples from the stream.
|
|
|
|
@param destSamples an array of buffers into which the sample data for each
|
|
channel will be written.
|
|
If the format is fixed-point, each channel will be written
|
|
as an array of 32-bit signed integers using the full
|
|
range -0x80000000 to 0x7fffffff, regardless of the source's
|
|
bit-depth. If it is a floating-point format, you should cast
|
|
the resulting array to a (float**) to get the values (in the
|
|
range -1.0 to 1.0 or beyond)
|
|
If the format is stereo, then destSamples[0] is the left channel
|
|
data, and destSamples[1] is the right channel.
|
|
The numDestChannels parameter indicates how many pointers this array
|
|
contains, but some of these pointers can be null if you don't want to
|
|
read data for some of the channels
|
|
@param numDestChannels the number of array elements in the destChannels array
|
|
@param startSampleInSource the position in the audio file or stream at which the samples
|
|
should be read, as a number of samples from the start of the
|
|
stream. It's ok for this to be beyond the start or end of the
|
|
available data - any samples that are out-of-range will be returned
|
|
as zeros.
|
|
@param numSamplesToRead the number of samples to read. If this is greater than the number
|
|
of samples that the file or stream contains. the result will be padded
|
|
with zeros
|
|
@param fillLeftoverChannelsWithCopies if true, this indicates that if there's no source data available
|
|
for some of the channels that you pass in, then they should be filled with
|
|
copies of valid source channels.
|
|
E.g. if you're reading a mono file and you pass 2 channels to this method, then
|
|
if fillLeftoverChannelsWithCopies is true, both destination channels will be filled
|
|
with the same data from the file's single channel. If fillLeftoverChannelsWithCopies
|
|
was false, then only the first channel would be filled with the file's contents, and
|
|
the second would be cleared. If there are many channels, e.g. you try to read 4 channels
|
|
from a stereo file, then the last 3 would all end up with copies of the same data.
|
|
@returns true if the operation succeeded, false if there was an error. Note
|
|
that reading sections of data beyond the extent of the stream isn't an
|
|
error - the reader should just return zeros for these regions
|
|
@see readMaxLevels
|
|
*/
|
|
bool read (int** destSamples,
|
|
int numDestChannels,
|
|
int64 startSampleInSource,
|
|
int numSamplesToRead,
|
|
const bool fillLeftoverChannelsWithCopies);
|
|
|
|
/** Finds the highest and lowest sample levels from a section of the audio stream.
|
|
|
|
This will read a block of samples from the stream, and measure the
|
|
highest and lowest sample levels from the channels in that section, returning
|
|
these as normalised floating-point levels.
|
|
|
|
@param startSample the offset into the audio stream to start reading from. It's
|
|
ok for this to be beyond the start or end of the stream.
|
|
@param numSamples how many samples to read
|
|
@param lowestLeft on return, this is the lowest absolute sample from the left channel
|
|
@param highestLeft on return, this is the highest absolute sample from the left channel
|
|
@param lowestRight on return, this is the lowest absolute sample from the right
|
|
channel (if there is one)
|
|
@param highestRight on return, this is the highest absolute sample from the right
|
|
channel (if there is one)
|
|
@see read
|
|
*/
|
|
virtual void readMaxLevels (int64 startSample,
|
|
int64 numSamples,
|
|
float& lowestLeft,
|
|
float& highestLeft,
|
|
float& lowestRight,
|
|
float& highestRight);
|
|
|
|
/** Scans the source looking for a sample whose magnitude is in a specified range.
|
|
|
|
This will read from the source, either forwards or backwards between two sample
|
|
positions, until it finds a sample whose magnitude lies between two specified levels.
|
|
|
|
If it finds a suitable sample, it returns its position; if not, it will return -1.
|
|
|
|
There's also a minimumConsecutiveSamples setting to help avoid spikes or zero-crossing
|
|
points when you're searching for a continuous range of samples
|
|
|
|
@param startSample the first sample to look at
|
|
@param numSamplesToSearch the number of samples to scan. If this value is negative,
|
|
the search will go backwards
|
|
@param magnitudeRangeMinimum the lowest magnitude (inclusive) that is considered a hit, from 0 to 1.0
|
|
@param magnitudeRangeMaximum the highest magnitude (inclusive) that is considered a hit, from 0 to 1.0
|
|
@param minimumConsecutiveSamples if this is > 0, the method will only look for a sequence
|
|
of this many consecutive samples, all of which lie
|
|
within the target range. When it finds such a sequence,
|
|
it returns the position of the first in-range sample
|
|
it found (i.e. the earliest one if scanning forwards, the
|
|
latest one if scanning backwards)
|
|
*/
|
|
int64 searchForLevel (int64 startSample,
|
|
int64 numSamplesToSearch,
|
|
const double magnitudeRangeMinimum,
|
|
const double magnitudeRangeMaximum,
|
|
const int minimumConsecutiveSamples);
|
|
|
|
/** The sample-rate of the stream. */
|
|
double sampleRate;
|
|
|
|
/** The number of bits per sample, e.g. 16, 24, 32. */
|
|
unsigned int bitsPerSample;
|
|
|
|
/** The total number of samples in the audio stream. */
|
|
int64 lengthInSamples;
|
|
|
|
/** The total number of channels in the audio stream. */
|
|
unsigned int numChannels;
|
|
|
|
/** Indicates whether the data is floating-point or fixed. */
|
|
bool usesFloatingPointData;
|
|
|
|
/** A set of metadata values that the reader has pulled out of the stream.
|
|
|
|
Exactly what these values are depends on the format, so you can
|
|
check out the format implementation code to see what kind of stuff
|
|
they understand.
|
|
*/
|
|
StringPairArray metadataValues;
|
|
|
|
/** The input stream, for use by subclasses. */
|
|
InputStream* input;
|
|
|
|
/** Subclasses must implement this method to perform the low-level read operation.
|
|
|
|
Callers should use read() instead of calling this directly.
|
|
|
|
@param destSamples the array of destination buffers to fill. Some of these
|
|
pointers may be null
|
|
@param numDestChannels the number of items in the destSamples array. This
|
|
value is guaranteed not to be greater than the number of
|
|
channels that this reader object contains
|
|
@param startOffsetInDestBuffer the number of samples from the start of the
|
|
dest data at which to begin writing
|
|
@param startSampleInFile the number of samples into the source data at which
|
|
to begin reading. This value is guaranteed to be >= 0.
|
|
@param numSamples the number of samples to read
|
|
*/
|
|
virtual bool readSamples (int** destSamples,
|
|
int numDestChannels,
|
|
int startOffsetInDestBuffer,
|
|
int64 startSampleInFile,
|
|
int numSamples) = 0;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
String formatName;
|
|
|
|
AudioFormatReader (const AudioFormatReader&);
|
|
const AudioFormatReader& operator= (const AudioFormatReader&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOFORMATREADER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioFormatReader.h *********/
|
|
|
|
/**
|
|
A type of AudioSource that will read from an AudioFormatReader.
|
|
|
|
@see PositionableAudioSource, AudioTransportSource, BufferingAudioSource
|
|
*/
|
|
class JUCE_API AudioFormatReaderSource : public PositionableAudioSource
|
|
{
|
|
public:
|
|
|
|
/** Creates an AudioFormatReaderSource for a given reader.
|
|
|
|
@param sourceReader the reader to use as the data source
|
|
@param deleteReaderWhenThisIsDeleted if true, the reader passed-in will be deleted
|
|
when this object is deleted; if false it will be
|
|
left up to the caller to manage its lifetime
|
|
*/
|
|
AudioFormatReaderSource (AudioFormatReader* const sourceReader,
|
|
const bool deleteReaderWhenThisIsDeleted);
|
|
|
|
/** Destructor. */
|
|
~AudioFormatReaderSource();
|
|
|
|
/** Toggles loop-mode.
|
|
|
|
If set to true, it will continuously loop the input source. If false,
|
|
it will just emit silence after the source has finished.
|
|
|
|
@see isLooping
|
|
*/
|
|
void setLooping (const bool shouldLoop) throw();
|
|
|
|
/** Returns whether loop-mode is turned on or not. */
|
|
bool isLooping() const { return looping; }
|
|
|
|
/** Returns the reader that's being used. */
|
|
AudioFormatReader* getAudioFormatReader() const throw() { return reader; }
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void prepareToPlay (int samplesPerBlockExpected, double sampleRate);
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void releaseResources();
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);
|
|
|
|
/** Implements the PositionableAudioSource method. */
|
|
void setNextReadPosition (int newPosition);
|
|
|
|
/** Implements the PositionableAudioSource method. */
|
|
int getNextReadPosition() const;
|
|
|
|
/** Implements the PositionableAudioSource method. */
|
|
int getTotalLength() const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
AudioFormatReader* reader;
|
|
bool deleteReader;
|
|
|
|
int volatile nextPlayPos;
|
|
bool volatile looping;
|
|
|
|
void readBufferSection (int start, int length, AudioSampleBuffer& buffer, int startSample);
|
|
|
|
AudioFormatReaderSource (const AudioFormatReaderSource&);
|
|
const AudioFormatReaderSource& operator= (const AudioFormatReaderSource&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioFormatReaderSource.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOSOURCE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioSourcePlayer.h *********/
|
|
#ifndef __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__
|
|
#define __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__
|
|
|
|
/**
|
|
Wrapper class to continuously stream audio from an audio source to an
|
|
AudioIODevice.
|
|
|
|
This object acts as an AudioIODeviceCallback, so can be attached to an
|
|
output device, and will stream audio from an AudioSource.
|
|
*/
|
|
class JUCE_API AudioSourcePlayer : public AudioIODeviceCallback
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty AudioSourcePlayer. */
|
|
AudioSourcePlayer();
|
|
|
|
/** Destructor.
|
|
|
|
Make sure this object isn't still being used by an AudioIODevice before
|
|
deleting it!
|
|
*/
|
|
virtual ~AudioSourcePlayer();
|
|
|
|
/** Changes the current audio source to play from.
|
|
|
|
If the source passed in is already being used, this method will do nothing.
|
|
If the source is not null, its prepareToPlay() method will be called
|
|
before it starts being used for playback.
|
|
|
|
If there's another source currently playing, its releaseResources() method
|
|
will be called after it has been swapped for the new one.
|
|
|
|
@param newSource the new source to use - this will NOT be deleted
|
|
by this object when no longer needed, so it's the
|
|
caller's responsibility to manage it.
|
|
*/
|
|
void setSource (AudioSource* newSource);
|
|
|
|
/** Returns the source that's playing.
|
|
|
|
May return 0 if there's no source.
|
|
*/
|
|
AudioSource* getCurrentSource() const throw() { return source; }
|
|
|
|
/** Sets a gain to apply to the audio data. */
|
|
void setGain (const float newGain) throw();
|
|
|
|
/** Implementation of the AudioIODeviceCallback method. */
|
|
void audioDeviceIOCallback (const float** inputChannelData,
|
|
int totalNumInputChannels,
|
|
float** outputChannelData,
|
|
int totalNumOutputChannels,
|
|
int numSamples);
|
|
|
|
/** Implementation of the AudioIODeviceCallback method. */
|
|
void audioDeviceAboutToStart (AudioIODevice* device);
|
|
|
|
/** Implementation of the AudioIODeviceCallback method. */
|
|
void audioDeviceStopped();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
CriticalSection readLock;
|
|
AudioSource* source;
|
|
double sampleRate;
|
|
int bufferSize;
|
|
float* channels [128];
|
|
float* outputChans [128];
|
|
const float* inputChans [128];
|
|
AudioSampleBuffer tempBuffer;
|
|
float lastGain, gain;
|
|
|
|
AudioSourcePlayer (const AudioSourcePlayer&);
|
|
const AudioSourcePlayer& operator= (const AudioSourcePlayer&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioSourcePlayer.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioTransportSource.h *********/
|
|
#ifndef __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__
|
|
#define __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_BufferingAudioSource.h *********/
|
|
#ifndef __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__
|
|
#define __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__
|
|
|
|
/**
|
|
An AudioSource which takes another source as input, and buffers it using a thread.
|
|
|
|
Create this as a wrapper around another thread, and it will read-ahead with
|
|
a background thread to smooth out playback. You can either create one of these
|
|
directly, or use it indirectly using an AudioTransportSource.
|
|
|
|
@see PositionableAudioSource, AudioTransportSource
|
|
*/
|
|
class JUCE_API BufferingAudioSource : public PositionableAudioSource
|
|
{
|
|
public:
|
|
|
|
/** Creates a BufferingAudioSource.
|
|
|
|
@param source the input source to read from
|
|
@param deleteSourceWhenDeleted if true, then the input source object will
|
|
be deleted when this object is deleted
|
|
@param numberOfSamplesToBuffer the size of buffer to use for reading ahead
|
|
*/
|
|
BufferingAudioSource (PositionableAudioSource* source,
|
|
const bool deleteSourceWhenDeleted,
|
|
int numberOfSamplesToBuffer);
|
|
|
|
/** Destructor.
|
|
|
|
The input source may be deleted depending on whether the deleteSourceWhenDeleted
|
|
flag was set in the constructor.
|
|
*/
|
|
~BufferingAudioSource();
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void prepareToPlay (int samplesPerBlockExpected, double sampleRate);
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void releaseResources();
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);
|
|
|
|
/** Implements the PositionableAudioSource method. */
|
|
void setNextReadPosition (int newPosition);
|
|
|
|
/** Implements the PositionableAudioSource method. */
|
|
int getNextReadPosition() const;
|
|
|
|
/** Implements the PositionableAudioSource method. */
|
|
int getTotalLength() const { return source->getTotalLength(); }
|
|
|
|
/** Implements the PositionableAudioSource method. */
|
|
bool isLooping() const { return source->isLooping(); }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
PositionableAudioSource* source;
|
|
bool deleteSourceWhenDeleted;
|
|
int numberOfSamplesToBuffer;
|
|
AudioSampleBuffer buffer;
|
|
CriticalSection bufferStartPosLock;
|
|
int volatile bufferValidStart, bufferValidEnd, nextPlayPos;
|
|
bool wasSourceLooping;
|
|
double volatile sampleRate;
|
|
|
|
friend class SharedBufferingAudioSourceThread;
|
|
bool readNextBufferChunk();
|
|
void readBufferSection (int start, int length, int bufferOffset);
|
|
|
|
BufferingAudioSource (const BufferingAudioSource&);
|
|
const BufferingAudioSource& operator= (const BufferingAudioSource&);
|
|
};
|
|
|
|
#endif // __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_BufferingAudioSource.h *********/
|
|
|
|
/********* Start of inlined file: juce_ResamplingAudioSource.h *********/
|
|
#ifndef __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__
|
|
#define __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__
|
|
|
|
/**
|
|
A type of AudioSource that takes an input source and changes its sample rate.
|
|
|
|
@see AudioSource
|
|
*/
|
|
class JUCE_API ResamplingAudioSource : public AudioSource
|
|
{
|
|
public:
|
|
|
|
/** Creates a ResamplingAudioSource for a given input source.
|
|
|
|
@param inputSource the input source to read from
|
|
@param deleteInputWhenDeleted if true, the input source will be deleted when
|
|
this object is deleted
|
|
*/
|
|
ResamplingAudioSource (AudioSource* const inputSource,
|
|
const bool deleteInputWhenDeleted);
|
|
|
|
/** Destructor. */
|
|
~ResamplingAudioSource();
|
|
|
|
/** Changes the resampling ratio.
|
|
|
|
(This value can be changed at any time, even while the source is running).
|
|
|
|
@param samplesInPerOutputSample if set to 1.0, the input is passed through; higher
|
|
values will speed it up; lower values will slow it
|
|
down. The ratio must be greater than 0
|
|
*/
|
|
void setResamplingRatio (const double samplesInPerOutputSample);
|
|
|
|
/** Returns the current resampling ratio.
|
|
|
|
This is the value that was set by setResamplingRatio().
|
|
*/
|
|
double getResamplingRatio() const throw() { return ratio; }
|
|
|
|
void prepareToPlay (int samplesPerBlockExpected, double sampleRate);
|
|
void releaseResources();
|
|
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
AudioSource* const input;
|
|
const bool deleteInputWhenDeleted;
|
|
double ratio, lastRatio;
|
|
AudioSampleBuffer buffer;
|
|
int bufferPos, sampsInBuffer;
|
|
double subSampleOffset;
|
|
double coefficients[6];
|
|
CriticalSection ratioLock;
|
|
|
|
void setFilterCoefficients (double c1, double c2, double c3, double c4, double c5, double c6);
|
|
void createLowPass (const double proportionalRate);
|
|
|
|
struct FilterState
|
|
{
|
|
double x1, x2, y1, y2;
|
|
};
|
|
|
|
FilterState filterStates[2];
|
|
void resetFilters();
|
|
|
|
void applyFilter (float* samples, int num, FilterState& fs);
|
|
|
|
ResamplingAudioSource (const ResamplingAudioSource&);
|
|
const ResamplingAudioSource& operator= (const ResamplingAudioSource&);
|
|
};
|
|
|
|
#endif // __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_ResamplingAudioSource.h *********/
|
|
|
|
/**
|
|
An AudioSource that takes a PositionableAudioSource and allows it to be
|
|
played, stopped, started, etc.
|
|
|
|
This can also be told use a buffer and background thread to read ahead, and
|
|
if can correct for different sample-rates.
|
|
|
|
You may want to use one of these along with an AudioSourcePlayer and AudioIODevice
|
|
to control playback of an audio file.
|
|
|
|
@see AudioSource, AudioSourcePlayer
|
|
*/
|
|
class JUCE_API AudioTransportSource : public PositionableAudioSource,
|
|
public ChangeBroadcaster
|
|
{
|
|
public:
|
|
|
|
/** Creates an AudioTransportSource.
|
|
|
|
After creating one of these, use the setSource() method to select an input source.
|
|
*/
|
|
AudioTransportSource();
|
|
|
|
/** Destructor. */
|
|
~AudioTransportSource();
|
|
|
|
/** Sets the reader that is being used as the input source.
|
|
|
|
This will stop playback, reset the position to 0 and change to the new reader.
|
|
|
|
The source passed in will not be deleted by this object, so must be managed by
|
|
the caller.
|
|
|
|
@param newSource the new input source to use. This may be zero
|
|
@param readAheadBufferSize a size of buffer to use for reading ahead. If this
|
|
is zero, no reading ahead will be done; if it's
|
|
greater than zero, a BufferingAudioSource will be used
|
|
to do the reading-ahead
|
|
@param sourceSampleRateToCorrectFor if this is non-zero, it specifies the sample
|
|
rate of the source, and playback will be sample-rate
|
|
adjusted to maintain playback at the correct pitch. If
|
|
this is 0, no sample-rate adjustment will be performed
|
|
*/
|
|
void setSource (PositionableAudioSource* const newSource,
|
|
int readAheadBufferSize = 0,
|
|
double sourceSampleRateToCorrectFor = 0.0);
|
|
|
|
/** Changes the current playback position in the source stream.
|
|
|
|
The next time the getNextAudioBlock() method is called, this
|
|
is the time from which it'll read data.
|
|
|
|
@see getPosition
|
|
*/
|
|
void setPosition (double newPosition);
|
|
|
|
/** Returns the position that the next data block will be read from
|
|
|
|
This is a time in seconds.
|
|
*/
|
|
double getCurrentPosition() const;
|
|
|
|
/** Returns true if the player has stopped because its input stream ran out of data.
|
|
*/
|
|
bool hasStreamFinished() const throw() { return inputStreamEOF; }
|
|
|
|
/** Starts playing (if a source has been selected).
|
|
|
|
If it starts playing, this will send a message to any ChangeListeners
|
|
that are registered with this object.
|
|
*/
|
|
void start();
|
|
|
|
/** Stops playing.
|
|
|
|
If it's actually playing, this will send a message to any ChangeListeners
|
|
that are registered with this object.
|
|
*/
|
|
void stop();
|
|
|
|
/** Returns true if it's currently playing. */
|
|
bool isPlaying() const throw() { return playing; }
|
|
|
|
/** Changes the gain to apply to the output.
|
|
|
|
@param newGain a factor by which to multiply the outgoing samples,
|
|
so 1.0 = 0dB, 0.5 = -6dB, 2.0 = 6dB, etc.
|
|
*/
|
|
void setGain (const float newGain) throw();
|
|
|
|
/** Returns the current gain setting.
|
|
|
|
@see setGain
|
|
*/
|
|
float getGain() const throw() { return gain; }
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void prepareToPlay (int samplesPerBlockExpected, double sampleRate);
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void releaseResources();
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);
|
|
|
|
/** Implements the PositionableAudioSource method. */
|
|
void setNextReadPosition (int newPosition);
|
|
|
|
/** Implements the PositionableAudioSource method. */
|
|
int getNextReadPosition() const;
|
|
|
|
/** Implements the PositionableAudioSource method. */
|
|
int getTotalLength() const;
|
|
|
|
/** Implements the PositionableAudioSource method. */
|
|
bool isLooping() const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
PositionableAudioSource* source;
|
|
ResamplingAudioSource* resamplerSource;
|
|
BufferingAudioSource* bufferingSource;
|
|
PositionableAudioSource* positionableSource;
|
|
AudioSource* masterSource;
|
|
|
|
CriticalSection callbackLock;
|
|
float volatile gain, lastGain;
|
|
bool volatile playing, stopped;
|
|
double sampleRate, sourceSampleRate;
|
|
int blockSize, readAheadBufferSize;
|
|
bool isPrepared, inputStreamEOF;
|
|
|
|
AudioTransportSource (const AudioTransportSource&);
|
|
const AudioTransportSource& operator= (const AudioTransportSource&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioTransportSource.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ChannelRemappingAudioSource.h *********/
|
|
#ifndef __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__
|
|
#define __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__
|
|
|
|
/**
|
|
An AudioSource that takes the audio from another source, and re-maps its
|
|
input and output channels to a different arrangement.
|
|
|
|
You can use this to increase or decrease the number of channels that an
|
|
audio source uses, or to re-order those channels.
|
|
|
|
Call the reset() method before using it to set up a default mapping, and then
|
|
the setInputChannelMapping() and setOutputChannelMapping() methods to
|
|
create an appropriate mapping, otherwise no channels will be connected and
|
|
it'll produce silence.
|
|
|
|
@see AudioSource
|
|
*/
|
|
class ChannelRemappingAudioSource : public AudioSource
|
|
{
|
|
public:
|
|
|
|
/** Creates a remapping source that will pass on audio from the given input.
|
|
|
|
@param source the input source to use. Make sure that this doesn't
|
|
get deleted before the ChannelRemappingAudioSource object
|
|
@param deleteSourceWhenDeleted if true, the input source will be deleted
|
|
when this object is deleted, if false, the caller is
|
|
responsible for its deletion
|
|
*/
|
|
ChannelRemappingAudioSource (AudioSource* const source,
|
|
const bool deleteSourceWhenDeleted);
|
|
|
|
/** Destructor. */
|
|
~ChannelRemappingAudioSource();
|
|
|
|
/** Specifies a number of channels that this audio source must produce from its
|
|
getNextAudioBlock() callback.
|
|
*/
|
|
void setNumberOfChannelsToProduce (const int requiredNumberOfChannels) throw();
|
|
|
|
/** Clears any mapped channels.
|
|
|
|
After this, no channels are mapped, so this object will produce silence. Create
|
|
some mappings with setInputChannelMapping() and setOutputChannelMapping().
|
|
*/
|
|
void clearAllMappings() throw();
|
|
|
|
/** Creates an input channel mapping.
|
|
|
|
When the getNextAudioBlock() method is called, the data in channel sourceChannelIndex of the incoming
|
|
data will be sent to destChannelIndex of our input source.
|
|
|
|
@param destChannelIndex the index of an input channel in our input audio source (i.e. the
|
|
source specified when this object was created).
|
|
@param sourceChannelIndex the index of the input channel in the incoming audio data buffer
|
|
during our getNextAudioBlock() callback
|
|
*/
|
|
void setInputChannelMapping (const int destChannelIndex,
|
|
const int sourceChannelIndex) throw();
|
|
|
|
/** Creates an output channel mapping.
|
|
|
|
When the getNextAudioBlock() method is called, the data returned in channel sourceChannelIndex by
|
|
our input audio source will be copied to channel destChannelIndex of the final buffer.
|
|
|
|
@param sourceChannelIndex the index of an output channel coming from our input audio source
|
|
(i.e. the source specified when this object was created).
|
|
@param destChannelIndex the index of the output channel in the incoming audio data buffer
|
|
during our getNextAudioBlock() callback
|
|
*/
|
|
void setOutputChannelMapping (const int sourceChannelIndex,
|
|
const int destChannelIndex) throw();
|
|
|
|
/** Returns the channel from our input that will be sent to channel inputChannelIndex of
|
|
our input audio source.
|
|
*/
|
|
int getRemappedInputChannel (const int inputChannelIndex) const throw();
|
|
|
|
/** Returns the output channel to which channel outputChannelIndex of our input audio
|
|
source will be sent to.
|
|
*/
|
|
int getRemappedOutputChannel (const int outputChannelIndex) const throw();
|
|
|
|
/** Returns an XML object to encapsulate the state of the mappings.
|
|
|
|
@see restoreFromXml
|
|
*/
|
|
XmlElement* createXml() const throw();
|
|
|
|
/** Restores the mappings from an XML object created by createXML().
|
|
|
|
@see createXml
|
|
*/
|
|
void restoreFromXml (const XmlElement& e) throw();
|
|
|
|
void prepareToPlay (int samplesPerBlockExpected, double sampleRate);
|
|
void releaseResources();
|
|
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int requiredNumberOfChannels;
|
|
Array <int> remappedInputs, remappedOutputs;
|
|
|
|
AudioSource* const source;
|
|
const bool deleteSourceWhenDeleted;
|
|
|
|
AudioSampleBuffer buffer;
|
|
AudioSourceChannelInfo remappedInfo;
|
|
|
|
CriticalSection lock;
|
|
|
|
ChannelRemappingAudioSource (const ChannelRemappingAudioSource&);
|
|
const ChannelRemappingAudioSource& operator= (const ChannelRemappingAudioSource&);
|
|
};
|
|
|
|
#endif // __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_ChannelRemappingAudioSource.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_IIRFilterAudioSource.h *********/
|
|
#ifndef __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__
|
|
#define __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__
|
|
|
|
/**
|
|
An AudioSource that performs an IIR filter on another source.
|
|
*/
|
|
class JUCE_API IIRFilterAudioSource : public AudioSource
|
|
{
|
|
public:
|
|
|
|
/** Creates a IIRFilterAudioSource for a given input source.
|
|
|
|
@param inputSource the input source to read from
|
|
@param deleteInputWhenDeleted if true, the input source will be deleted when
|
|
this object is deleted
|
|
*/
|
|
IIRFilterAudioSource (AudioSource* const inputSource,
|
|
const bool deleteInputWhenDeleted);
|
|
|
|
/** Destructor. */
|
|
~IIRFilterAudioSource();
|
|
|
|
/** Changes the filter to use the same parameters as the one being passed in.
|
|
*/
|
|
void setFilterParameters (const IIRFilter& newSettings);
|
|
|
|
void prepareToPlay (int samplesPerBlockExpected, double sampleRate);
|
|
void releaseResources();
|
|
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
AudioSource* const input;
|
|
const bool deleteInputWhenDeleted;
|
|
OwnedArray <IIRFilter> iirFilters;
|
|
|
|
IIRFilterAudioSource (const IIRFilterAudioSource&);
|
|
const IIRFilterAudioSource& operator= (const IIRFilterAudioSource&);
|
|
};
|
|
|
|
#endif // __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_IIRFilterAudioSource.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MixerAudioSource.h *********/
|
|
#ifndef __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__
|
|
#define __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__
|
|
|
|
/**
|
|
An AudioSource that mixes together the output of a set of other AudioSources.
|
|
|
|
Input sources can be added and removed while the mixer is running as long as their
|
|
prepareToPlay() and releaseResources() methods are called before and after adding
|
|
them to the mixer.
|
|
*/
|
|
class JUCE_API MixerAudioSource : public AudioSource
|
|
{
|
|
public:
|
|
|
|
/** Creates a MixerAudioSource.
|
|
*/
|
|
MixerAudioSource();
|
|
|
|
/** Destructor. */
|
|
~MixerAudioSource();
|
|
|
|
/** Adds an input source to the mixer.
|
|
|
|
If the mixer is running you'll need to make sure that the input source
|
|
is ready to play by calling its prepareToPlay() method before adding it.
|
|
If the mixer is stopped, then its input sources will be automatically
|
|
prepared when the mixer's prepareToPlay() method is called.
|
|
|
|
@param newInput the source to add to the mixer
|
|
@param deleteWhenRemoved if true, then this source will be deleted when
|
|
the mixer is deleted or when removeAllInputs() is
|
|
called (unless the source is previously removed
|
|
with the removeInputSource method)
|
|
*/
|
|
void addInputSource (AudioSource* newInput,
|
|
const bool deleteWhenRemoved);
|
|
|
|
/** Removes an input source.
|
|
|
|
If the mixer is running, this will remove the source but not call its
|
|
releaseResources() method, so the caller might want to do this manually.
|
|
|
|
@param input the source to remove
|
|
@param deleteSource whether to delete this source after it's been removed
|
|
*/
|
|
void removeInputSource (AudioSource* input,
|
|
const bool deleteSource);
|
|
|
|
/** Removes all the input sources.
|
|
|
|
If the mixer is running, this will remove the sources but not call their
|
|
releaseResources() method, so the caller might want to do this manually.
|
|
|
|
Any sources which were added with the deleteWhenRemoved flag set will be
|
|
deleted by this method.
|
|
*/
|
|
void removeAllInputs();
|
|
|
|
/** Implementation of the AudioSource method.
|
|
|
|
This will call prepareToPlay() on all its input sources.
|
|
*/
|
|
void prepareToPlay (int samplesPerBlockExpected, double sampleRate);
|
|
|
|
/** Implementation of the AudioSource method.
|
|
|
|
This will call releaseResources() on all its input sources.
|
|
*/
|
|
void releaseResources();
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
VoidArray inputs;
|
|
BitArray inputsToDelete;
|
|
CriticalSection lock;
|
|
AudioSampleBuffer tempBuffer;
|
|
double currentSampleRate;
|
|
int bufferSizeExpected;
|
|
|
|
MixerAudioSource (const MixerAudioSource&);
|
|
const MixerAudioSource& operator= (const MixerAudioSource&);
|
|
};
|
|
|
|
#endif // __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_MixerAudioSource.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ToneGeneratorAudioSource.h *********/
|
|
#ifndef __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__
|
|
#define __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__
|
|
|
|
/**
|
|
A simple AudioSource that generates a sine wave.
|
|
|
|
*/
|
|
class JUCE_API ToneGeneratorAudioSource : public AudioSource
|
|
{
|
|
public:
|
|
|
|
/** Creates a ToneGeneratorAudioSource. */
|
|
ToneGeneratorAudioSource();
|
|
|
|
/** Destructor. */
|
|
~ToneGeneratorAudioSource();
|
|
|
|
/** Sets the signal's amplitude. */
|
|
void setAmplitude (const float newAmplitude);
|
|
|
|
/** Sets the signal's frequency. */
|
|
void setFrequency (const double newFrequencyHz);
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void prepareToPlay (int samplesPerBlockExpected, double sampleRate);
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void releaseResources();
|
|
|
|
/** Implementation of the AudioSource method. */
|
|
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
double frequency, sampleRate;
|
|
double currentPhase, phasePerSample;
|
|
float amplitude;
|
|
|
|
ToneGeneratorAudioSource (const ToneGeneratorAudioSource&);
|
|
const ToneGeneratorAudioSource& operator= (const ToneGeneratorAudioSource&);
|
|
};
|
|
|
|
#endif // __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__
|
|
/********* End of inlined file: juce_ToneGeneratorAudioSource.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioDeviceManager.h *********/
|
|
#ifndef __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__
|
|
#define __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioIODeviceType.h *********/
|
|
#ifndef __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__
|
|
#define __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__
|
|
|
|
class AudioDeviceManager;
|
|
class Component;
|
|
|
|
/**
|
|
Represents a type of audio driver, such as DirectSound, ASIO, CoreAudio, etc.
|
|
|
|
To get a list of available audio driver types, use the createDeviceTypes()
|
|
method. Each of the objects returned can then be used to list the available
|
|
devices of that type. E.g.
|
|
@code
|
|
OwnedArray <AudioIODeviceType> types;
|
|
AudioIODeviceType::createDeviceTypes (types);
|
|
|
|
for (int i = 0; i < types.size(); ++i)
|
|
{
|
|
String typeName (types[i]->getTypeName()); // This will be things like "DirectSound", "CoreAudio", etc.
|
|
|
|
types[i]->scanForDevices(); // This must be called before getting the list of devices
|
|
|
|
StringArray deviceNames (types[i]->getDeviceNames()); // This will now return a list of available devices of this type
|
|
|
|
for (int j = 0; j < deviceNames.size(); ++j)
|
|
{
|
|
AudioIODevice* device = types[i]->createDevice (deviceNames [j]);
|
|
|
|
...
|
|
}
|
|
}
|
|
@endcode
|
|
|
|
For an easier way of managing audio devices and their settings, have a look at the
|
|
AudioDeviceManager class.
|
|
|
|
@see AudioIODevice, AudioDeviceManager
|
|
*/
|
|
class JUCE_API AudioIODeviceType
|
|
{
|
|
public:
|
|
|
|
/** Returns the name of this type of driver that this object manages.
|
|
|
|
This will be something like "DirectSound", "ASIO", "CoreAudio", "ALSA", etc.
|
|
*/
|
|
const String& getTypeName() const throw() { return typeName; }
|
|
|
|
/** Refreshes the object's cached list of known devices.
|
|
|
|
This must be called at least once before calling getDeviceNames() or any of
|
|
the other device creation methods.
|
|
*/
|
|
virtual void scanForDevices() = 0;
|
|
|
|
/** Returns the list of available devices of this type.
|
|
|
|
The scanForDevices() method must have been called to create this list.
|
|
|
|
@param wantInputNames only really used by DirectSound where devices are split up
|
|
into inputs and outputs, this indicates whether to use
|
|
the input or output name to refer to a pair of devices.
|
|
*/
|
|
virtual const StringArray getDeviceNames (const bool wantInputNames = false) const = 0;
|
|
|
|
/** Returns the name of the default device.
|
|
|
|
This will be one of the names from the getDeviceNames() list.
|
|
|
|
@param forInput if true, this means that a default input device should be
|
|
returned; if false, it should return the default output
|
|
*/
|
|
virtual int getDefaultDeviceIndex (const bool forInput) const = 0;
|
|
|
|
/** Returns the index of a given device in the list of device names.
|
|
If asInput is true, it shows the index in the inputs list, otherwise it
|
|
looks for it in the outputs list.
|
|
*/
|
|
virtual int getIndexOfDevice (AudioIODevice* device, const bool asInput) const = 0;
|
|
|
|
/** Returns true if two different devices can be used for the input and output.
|
|
*/
|
|
virtual bool hasSeparateInputsAndOutputs() const = 0;
|
|
|
|
/** Creates one of the devices of this type.
|
|
|
|
The deviceName must be one of the strings returned by getDeviceNames(), and
|
|
scanForDevices() must have been called before this method is used.
|
|
*/
|
|
virtual AudioIODevice* createDevice (const String& outputDeviceName,
|
|
const String& inputDeviceName) = 0;
|
|
|
|
struct DeviceSetupDetails
|
|
{
|
|
AudioDeviceManager* manager;
|
|
int minNumInputChannels, maxNumInputChannels;
|
|
int minNumOutputChannels, maxNumOutputChannels;
|
|
bool useStereoPairs;
|
|
};
|
|
|
|
/** Destructor. */
|
|
virtual ~AudioIODeviceType();
|
|
|
|
protected:
|
|
AudioIODeviceType (const tchar* const typeName);
|
|
|
|
private:
|
|
String typeName;
|
|
|
|
AudioIODeviceType (const AudioIODeviceType&);
|
|
const AudioIODeviceType& operator= (const AudioIODeviceType&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioIODeviceType.h *********/
|
|
|
|
/********* Start of inlined file: juce_MidiOutput.h *********/
|
|
#ifndef __JUCE_MIDIOUTPUT_JUCEHEADER__
|
|
#define __JUCE_MIDIOUTPUT_JUCEHEADER__
|
|
|
|
/**
|
|
Represents a midi output device.
|
|
|
|
To create one of these, use the static getDevices() method to find out what
|
|
outputs are available, then use the openDevice() method to try to open one.
|
|
|
|
@see MidiInput
|
|
*/
|
|
class JUCE_API MidiOutput : private Thread
|
|
{
|
|
public:
|
|
|
|
/** Returns a list of the available midi output devices.
|
|
|
|
You can open one of the devices by passing its index into the
|
|
openDevice() method.
|
|
|
|
@see getDefaultDeviceIndex, openDevice
|
|
*/
|
|
static const StringArray getDevices();
|
|
|
|
/** Returns the index of the default midi output device to use.
|
|
|
|
This refers to the index in the list returned by getDevices().
|
|
*/
|
|
static int getDefaultDeviceIndex();
|
|
|
|
/** Tries to open one of the midi output devices.
|
|
|
|
This will return a MidiOutput object if it manages to open it. You can then
|
|
send messages to this device, and delete it when no longer needed.
|
|
|
|
If the device can't be opened, this will return a null pointer.
|
|
|
|
@param deviceIndex the index of a device from the list returned by getDevices()
|
|
@see getDevices
|
|
*/
|
|
static MidiOutput* openDevice (int deviceIndex);
|
|
|
|
#if JUCE_LINUX || DOXYGEN
|
|
/** LINUX ONLY - This will try to create a new midi output device.
|
|
|
|
This will attempt to create a new midi output device that other apps can connect
|
|
to and use as their midi input.
|
|
|
|
Returns 0 if a device can't be created.
|
|
|
|
@param deviceName the name to use for the new device
|
|
*/
|
|
static MidiOutput* createNewDevice (const String& deviceName);
|
|
#endif
|
|
|
|
/** Destructor. */
|
|
virtual ~MidiOutput();
|
|
|
|
/** Makes this device output a midi message.
|
|
|
|
@see MidiMessage
|
|
*/
|
|
virtual void sendMessageNow (const MidiMessage& message);
|
|
|
|
/** Sends a midi reset to the device. */
|
|
virtual void reset();
|
|
|
|
/** Returns the current volume setting for this device. */
|
|
virtual bool getVolume (float& leftVol,
|
|
float& rightVol);
|
|
|
|
/** Changes the overall volume for this device. */
|
|
virtual void setVolume (float leftVol,
|
|
float rightVol);
|
|
|
|
/** This lets you supply a block of messages that will be sent out at some point
|
|
in the future.
|
|
|
|
The MidiOutput class has an internal thread that can send out timestamped
|
|
messages - this appends a set of messages to its internal buffer, ready for
|
|
sending.
|
|
|
|
This will only work if you've already started the thread with startBackgroundThread().
|
|
|
|
A time is supplied, at which the block of messages should be sent. This time uses
|
|
the same time base as Time::getMillisecondCounter(), and must be in the future.
|
|
|
|
The samplesPerSecondForBuffer parameter indicates the number of samples per second
|
|
used by the MidiBuffer. Each event in a MidiBuffer has a sample position, and the
|
|
samplesPerSecondForBuffer value is needed to convert this sample position to a
|
|
real time.
|
|
*/
|
|
virtual void sendBlockOfMessages (const MidiBuffer& buffer,
|
|
const double millisecondCounterToStartAt,
|
|
double samplesPerSecondForBuffer) throw();
|
|
|
|
/** Gets rid of any midi messages that had been added by sendBlockOfMessages().
|
|
*/
|
|
virtual void clearAllPendingMessages() throw();
|
|
|
|
/** Starts up a background thread so that the device can send blocks of data.
|
|
|
|
Call this to get the device ready, before using sendBlockOfMessages().
|
|
*/
|
|
virtual void startBackgroundThread() throw();
|
|
|
|
/** Stops the background thread, and clears any pending midi events.
|
|
|
|
@see startBackgroundThread
|
|
*/
|
|
virtual void stopBackgroundThread() throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
void* internal;
|
|
|
|
struct PendingMessage
|
|
{
|
|
PendingMessage (const uint8* const data, const int len, const double sampleNumber) throw();
|
|
|
|
MidiMessage message;
|
|
PendingMessage* next;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
};
|
|
|
|
CriticalSection lock;
|
|
PendingMessage* firstMessage;
|
|
|
|
MidiOutput() throw();
|
|
MidiOutput (const MidiOutput&);
|
|
|
|
void run();
|
|
};
|
|
|
|
#endif // __JUCE_MIDIOUTPUT_JUCEHEADER__
|
|
/********* End of inlined file: juce_MidiOutput.h *********/
|
|
|
|
/********* Start of inlined file: juce_ComboBox.h *********/
|
|
#ifndef __JUCE_COMBOBOX_JUCEHEADER__
|
|
#define __JUCE_COMBOBOX_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Label.h *********/
|
|
#ifndef __JUCE_LABEL_JUCEHEADER__
|
|
#define __JUCE_LABEL_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ComponentDeletionWatcher.h *********/
|
|
#ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__
|
|
#define __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__
|
|
|
|
/**
|
|
Object for monitoring a component, and later testing whether it's still valid.
|
|
|
|
Slightly obscure, this one, but it's used internally for making sure that
|
|
after some callbacks, a component hasn't been deleted. It's more reliable than
|
|
just using isValidComponent(), which can provide false-positives if a new
|
|
component is created at the same memory location as an old one.
|
|
*/
|
|
class JUCE_API ComponentDeletionWatcher
|
|
{
|
|
public:
|
|
|
|
/** Creates a watcher for a given component.
|
|
|
|
The component must be valid at the time it's passed in.
|
|
*/
|
|
ComponentDeletionWatcher (const Component* const componentToWatch) throw();
|
|
|
|
/** Destructor. */
|
|
~ComponentDeletionWatcher() throw();
|
|
|
|
/** Returns true if the component has been deleted since the time that this
|
|
object was created.
|
|
*/
|
|
bool hasBeenDeleted() const throw();
|
|
|
|
/** Returns the component that's being watched, or null if it has been deleted. */
|
|
const Component* getComponent() const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
const Component* const componentToWatch;
|
|
const uint32 componentUID;
|
|
|
|
ComponentDeletionWatcher (const ComponentDeletionWatcher&);
|
|
const ComponentDeletionWatcher& operator= (const ComponentDeletionWatcher&);
|
|
};
|
|
|
|
#endif // __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__
|
|
/********* End of inlined file: juce_ComponentDeletionWatcher.h *********/
|
|
|
|
/********* Start of inlined file: juce_TextEditor.h *********/
|
|
#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__
|
|
#define __JUCE_TEXTEDITOR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_UndoManager.h *********/
|
|
#ifndef __JUCE_UNDOMANAGER_JUCEHEADER__
|
|
#define __JUCE_UNDOMANAGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_UndoableAction.h *********/
|
|
#ifndef __JUCE_UNDOABLEACTION_JUCEHEADER__
|
|
#define __JUCE_UNDOABLEACTION_JUCEHEADER__
|
|
|
|
/**
|
|
Used by the UndoManager class to store an action which can be done
|
|
and undone.
|
|
|
|
@see UndoManager
|
|
*/
|
|
class JUCE_API UndoableAction
|
|
{
|
|
protected:
|
|
/** Creates an action. */
|
|
UndoableAction() throw() {}
|
|
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~UndoableAction() {}
|
|
|
|
/** Overridden by a subclass to perform the action.
|
|
|
|
This method is called by the UndoManager, and shouldn't be used directly by
|
|
applications.
|
|
|
|
Be careful not to make any calls in a perform() method that could call
|
|
recursively back into the UndoManager::perform() method
|
|
|
|
@returns true if the action could be performed.
|
|
@see UndoManager::perform
|
|
*/
|
|
virtual bool perform() = 0;
|
|
|
|
/** Overridden by a subclass to undo the action.
|
|
|
|
This method is called by the UndoManager, and shouldn't be used directly by
|
|
applications.
|
|
|
|
Be careful not to make any calls in an undo() method that could call
|
|
recursively back into the UndoManager::perform() method
|
|
|
|
@returns true if the action could be undone without any errors.
|
|
@see UndoManager::perform
|
|
*/
|
|
virtual bool undo() = 0;
|
|
|
|
/** Returns a value to indicate how much memory this object takes up.
|
|
|
|
Because the UndoManager keeps a list of UndoableActions, this is used
|
|
to work out how much space each one will take up, so that the UndoManager
|
|
can work out how many to keep.
|
|
|
|
The default value returned here is 10 - units are arbitrary and
|
|
don't have to be accurate.
|
|
|
|
@see UndoManager::getNumberOfUnitsTakenUpByStoredCommands,
|
|
UndoManager::setMaxNumberOfStoredUnits
|
|
*/
|
|
virtual int getSizeInUnits() { return 10; }
|
|
};
|
|
|
|
#endif // __JUCE_UNDOABLEACTION_JUCEHEADER__
|
|
/********* End of inlined file: juce_UndoableAction.h *********/
|
|
|
|
/**
|
|
Manages a list of undo/redo commands.
|
|
|
|
An UndoManager object keeps a list of past actions and can use these actions
|
|
to move backwards and forwards through an undo history.
|
|
|
|
To use it, create subclasses of UndoableAction which perform all the
|
|
actions you need, then when you need to actually perform an action, create one
|
|
and pass it to the UndoManager's perform() method.
|
|
|
|
The manager also uses the concept of 'transactions' to group the actions
|
|
together - all actions performed between calls to beginNewTransaction() are
|
|
grouped together and are all undone/redone as a group.
|
|
|
|
The UndoManager is a ChangeBroadcaster, so listeners can register to be told
|
|
when actions are performed or undone.
|
|
|
|
@see UndoableAction
|
|
*/
|
|
class JUCE_API UndoManager : public ChangeBroadcaster
|
|
{
|
|
public:
|
|
|
|
/** Creates an UndoManager.
|
|
|
|
@param maxNumberOfUnitsToKeep each UndoableAction object returns a value
|
|
to indicate how much storage it takes up
|
|
(UndoableAction::getSizeInUnits()), so this
|
|
lets you specify the maximum total number of
|
|
units that the undomanager is allowed to
|
|
keep in memory before letting the older actions
|
|
drop off the end of the list.
|
|
@param minimumTransactionsToKeep this specifies the minimum number of transactions
|
|
that will be kept, even if this involves exceeding
|
|
the amount of space specified in maxNumberOfUnitsToKeep
|
|
*/
|
|
UndoManager (const int maxNumberOfUnitsToKeep = 30000,
|
|
const int minimumTransactionsToKeep = 30);
|
|
|
|
/** Destructor. */
|
|
~UndoManager();
|
|
|
|
/** Deletes all stored actions in the list. */
|
|
void clearUndoHistory();
|
|
|
|
/** Returns the current amount of space to use for storing UndoableAction objects.
|
|
|
|
@see setMaxNumberOfStoredUnits
|
|
*/
|
|
int getNumberOfUnitsTakenUpByStoredCommands() const;
|
|
|
|
/** Sets the amount of space that can be used for storing UndoableAction objects.
|
|
|
|
@param maxNumberOfUnitsToKeep each UndoableAction object returns a value
|
|
to indicate how much storage it takes up
|
|
(UndoableAction::getSizeInUnits()), so this
|
|
lets you specify the maximum total number of
|
|
units that the undomanager is allowed to
|
|
keep in memory before letting the older actions
|
|
drop off the end of the list.
|
|
@param minimumTransactionsToKeep this specifies the minimum number of transactions
|
|
that will be kept, even if this involves exceeding
|
|
the amount of space specified in maxNumberOfUnitsToKeep
|
|
@see getNumberOfUnitsTakenUpByStoredCommands
|
|
*/
|
|
void setMaxNumberOfStoredUnits (const int maxNumberOfUnitsToKeep,
|
|
const int minimumTransactionsToKeep);
|
|
|
|
/** Performs an action and adds it to the undo history list.
|
|
|
|
@param action the action to perform - this will be deleted by the UndoManager
|
|
when no longer needed
|
|
@param actionName if this string is non-empty, the current transaction will be
|
|
given this name; if it's empty, the current transaction name will
|
|
be left unchanged. See setCurrentTransactionName()
|
|
@returns true if the command succeeds - see UndoableAction::perform
|
|
@see beginNewTransaction
|
|
*/
|
|
bool perform (UndoableAction* const action,
|
|
const String& actionName = String::empty);
|
|
|
|
/** Starts a new group of actions that together will be treated as a single transaction.
|
|
|
|
All actions that are passed to the perform() method between calls to this
|
|
method are grouped together and undone/redone together by a single call to
|
|
undo() or redo().
|
|
|
|
@param actionName a description of the transaction that is about to be
|
|
performed
|
|
*/
|
|
void beginNewTransaction (const String& actionName = String::empty);
|
|
|
|
/** Changes the name stored for the current transaction.
|
|
|
|
Each transaction is given a name when the beginNewTransaction() method is
|
|
called, but this can be used to change that name without starting a new
|
|
transaction.
|
|
*/
|
|
void setCurrentTransactionName (const String& newName);
|
|
|
|
/** Returns true if there's at least one action in the list to undo.
|
|
|
|
@see getUndoDescription, undo, canRedo
|
|
*/
|
|
bool canUndo() const;
|
|
|
|
/** Returns the description of the transaction that would be next to get undone.
|
|
|
|
The description returned is the one that was passed into beginNewTransaction
|
|
before the set of actions was performed.
|
|
|
|
@see undo
|
|
*/
|
|
const String getUndoDescription() const;
|
|
|
|
/** Tries to roll-back the last transaction.
|
|
|
|
@returns true if the transaction can be undone, and false if it fails, or
|
|
if there aren't any transactions to undo
|
|
*/
|
|
bool undo();
|
|
|
|
/** Tries to roll-back any actions that were added to the current transaction.
|
|
|
|
This will perform an undo() only if there are some actions in the undo list
|
|
that were added after the last call to beginNewTransaction().
|
|
|
|
This is useful because it lets you call beginNewTransaction(), then
|
|
perform an operation which may or may not actually perform some actions, and
|
|
then call this method to get rid of any actions that might have been done
|
|
without it rolling back the previous transaction if nothing was actually
|
|
done.
|
|
|
|
@returns true if any actions were undone.
|
|
*/
|
|
bool undoCurrentTransactionOnly();
|
|
|
|
/** Returns a list of the UndoableAction objects that have been performed during the
|
|
transaction that is currently open.
|
|
|
|
Effectively, this is the list of actions that would be undone if undoCurrentTransactionOnly()
|
|
were to be called now.
|
|
|
|
The first item in the list is the earliest action performed.
|
|
*/
|
|
void getActionsInCurrentTransaction (Array <const UndoableAction*>& actionsFound) const;
|
|
|
|
/** Returns true if there's at least one action in the list to redo.
|
|
|
|
@see getRedoDescription, redo, canUndo
|
|
*/
|
|
bool canRedo() const;
|
|
|
|
/** Returns the description of the transaction that would be next to get redone.
|
|
|
|
The description returned is the one that was passed into beginNewTransaction
|
|
before the set of actions was performed.
|
|
|
|
@see redo
|
|
*/
|
|
const String getRedoDescription() const;
|
|
|
|
/** Tries to redo the last transaction that was undone.
|
|
|
|
@returns true if the transaction can be redone, and false if it fails, or
|
|
if there aren't any transactions to redo
|
|
*/
|
|
bool redo();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
OwnedArray <OwnedArray <UndoableAction> > transactions;
|
|
StringArray transactionNames;
|
|
String currentTransactionName;
|
|
int totalUnitsStored, maxNumUnitsToKeep, minimumTransactionsToKeep, nextIndex;
|
|
bool newTransaction, reentrancyCheck;
|
|
|
|
// disallow copy constructor
|
|
UndoManager (const UndoManager&);
|
|
const UndoManager& operator= (const UndoManager&);
|
|
};
|
|
|
|
#endif // __JUCE_UNDOMANAGER_JUCEHEADER__
|
|
/********* End of inlined file: juce_UndoManager.h *********/
|
|
|
|
class TextEditor;
|
|
class TextHolderComponent;
|
|
|
|
/**
|
|
Receives callbacks from a TextEditor component when it changes.
|
|
|
|
@see TextEditor::addListener
|
|
*/
|
|
class JUCE_API TextEditorListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~TextEditorListener() {}
|
|
|
|
/** Called when the user changes the text in some way. */
|
|
virtual void textEditorTextChanged (TextEditor& editor) = 0;
|
|
|
|
/** Called when the user presses the return key. */
|
|
virtual void textEditorReturnKeyPressed (TextEditor& editor) = 0;
|
|
|
|
/** Called when the user presses the escape key. */
|
|
virtual void textEditorEscapeKeyPressed (TextEditor& editor) = 0;
|
|
|
|
/** Called when the text editor loses focus. */
|
|
virtual void textEditorFocusLost (TextEditor& editor) = 0;
|
|
};
|
|
|
|
/**
|
|
A component containing text that can be edited.
|
|
|
|
A TextEditor can either be in single- or multi-line mode, and supports mixed
|
|
fonts and colours.
|
|
|
|
@see TextEditorListener, Label
|
|
*/
|
|
class JUCE_API TextEditor : public Component,
|
|
public SettableTooltipClient
|
|
{
|
|
public:
|
|
|
|
/** Creates a new, empty text editor.
|
|
|
|
@param componentName the name to pass to the component for it to use as its name
|
|
@param passwordCharacter if this is not zero, this character will be used as a replacement
|
|
for all characters that are drawn on screen - e.g. to create
|
|
a password-style textbox containing circular blobs instead of text,
|
|
you could set this value to 0x25cf, which is the unicode character
|
|
for a black splodge (not all fonts include this, though), or 0x2022,
|
|
which is a bullet (probably the best choice for linux).
|
|
*/
|
|
TextEditor (const String& componentName = String::empty,
|
|
const tchar passwordCharacter = 0);
|
|
|
|
/** Destructor. */
|
|
virtual ~TextEditor();
|
|
|
|
/** Puts the editor into either multi- or single-line mode.
|
|
|
|
By default, the editor will be in single-line mode, so use this if you need a multi-line
|
|
editor.
|
|
|
|
See also the setReturnKeyStartsNewLine() method, which will also need to be turned
|
|
on if you want a multi-line editor with line-breaks.
|
|
|
|
@see isMultiLine, setReturnKeyStartsNewLine
|
|
*/
|
|
void setMultiLine (const bool shouldBeMultiLine,
|
|
const bool shouldWordWrap = true);
|
|
|
|
/** Returns true if the editor is in multi-line mode.
|
|
*/
|
|
bool isMultiLine() const throw();
|
|
|
|
/** Changes the behaviour of the return key.
|
|
|
|
If set to true, the return key will insert a new-line into the text; if false
|
|
it will trigger a call to the TextEditorListener::textEditorReturnKeyPressed()
|
|
method. By default this is set to false, and when true it will only insert
|
|
new-lines when in multi-line mode (see setMultiLine()).
|
|
*/
|
|
void setReturnKeyStartsNewLine (const bool shouldStartNewLine);
|
|
|
|
/** Returns the value set by setReturnKeyStartsNewLine().
|
|
|
|
See setReturnKeyStartsNewLine() for more info.
|
|
*/
|
|
bool getReturnKeyStartsNewLine() const throw() { return returnKeyStartsNewLine; }
|
|
|
|
/** Indicates whether the tab key should be accepted and used to input a tab character,
|
|
or whether it gets ignored.
|
|
|
|
By default the tab key is ignored, so that it can be used to switch keyboard focus
|
|
between components.
|
|
*/
|
|
void setTabKeyUsedAsCharacter (const bool shouldTabKeyBeUsed) throw();
|
|
|
|
/** Returns true if the tab key is being used for input.
|
|
@see setTabKeyUsedAsCharacter
|
|
*/
|
|
bool isTabKeyUsedAsCharacter() const throw() { return tabKeyUsed; }
|
|
|
|
/** Changes the editor to read-only mode.
|
|
|
|
By default, the text editor is not read-only. If you're making it read-only, you
|
|
might also want to call setCaretVisible (false) to get rid of the caret.
|
|
|
|
The text can still be highlighted and copied when in read-only mode.
|
|
|
|
@see isReadOnly, setCaretVisible
|
|
*/
|
|
void setReadOnly (const bool shouldBeReadOnly);
|
|
|
|
/** Returns true if the editor is in read-only mode.
|
|
*/
|
|
bool isReadOnly() const throw();
|
|
|
|
/** Makes the caret visible or invisible.
|
|
|
|
By default the caret is visible.
|
|
|
|
@see setCaretColour, setCaretPosition
|
|
*/
|
|
void setCaretVisible (const bool shouldBeVisible) throw();
|
|
|
|
/** Returns true if the caret is enabled.
|
|
@see setCaretVisible
|
|
*/
|
|
bool isCaretVisible() const throw() { return caretVisible; }
|
|
|
|
/** Enables/disables a vertical scrollbar.
|
|
|
|
(This only applies when in multi-line mode). When the text gets too long to fit
|
|
in the component, a scrollbar can appear to allow it to be scrolled. Even when
|
|
this is enabled, the scrollbar will be hidden unless it's needed.
|
|
|
|
By default the scrollbar is enabled.
|
|
*/
|
|
void setScrollbarsShown (bool shouldBeEnabled) throw();
|
|
|
|
/** Returns true if scrollbars are enabled.
|
|
@see setScrollbarsShown
|
|
*/
|
|
bool areScrollbarsShown() const throw() { return scrollbarVisible; }
|
|
|
|
/** Changes the password character used to disguise the text.
|
|
|
|
@param passwordCharacter if this is not zero, this character will be used as a replacement
|
|
for all characters that are drawn on screen - e.g. to create
|
|
a password-style textbox containing circular blobs instead of text,
|
|
you could set this value to 0x25cf, which is the unicode character
|
|
for a black splodge (not all fonts include this, though), or 0x2022,
|
|
which is a bullet (probably the best choice for linux).
|
|
*/
|
|
void setPasswordCharacter (const tchar passwordCharacter) throw();
|
|
|
|
/** Returns the current password character.
|
|
@see setPasswordCharacter
|
|
l */
|
|
tchar getPasswordCharacter() const throw() { return passwordCharacter; }
|
|
|
|
/** Allows a right-click menu to appear for the editor.
|
|
|
|
(This defaults to being enabled).
|
|
|
|
If enabled, right-clicking (or command-clicking on the Mac) will pop up a menu
|
|
of options such as cut/copy/paste, undo/redo, etc.
|
|
*/
|
|
void setPopupMenuEnabled (const bool menuEnabled) throw();
|
|
|
|
/** Returns true if the right-click menu is enabled.
|
|
@see setPopupMenuEnabled
|
|
*/
|
|
bool isPopupMenuEnabled() const throw() { return popupMenuEnabled; }
|
|
|
|
/** Returns true if a popup-menu is currently being displayed.
|
|
*/
|
|
bool isPopupMenuCurrentlyActive() const throw() { return menuActive; }
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the editor.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1000200, /**< The colour to use for the text component's background - this can be
|
|
transparent if necessary. */
|
|
|
|
textColourId = 0x1000201, /**< The colour that will be used when text is added to the editor. Note
|
|
that because the editor can contain multiple colours, calling this
|
|
method won't change the colour of existing text - to do that, call
|
|
applyFontToAllText() after calling this method.*/
|
|
|
|
highlightColourId = 0x1000202, /**< The colour with which to fill the background of highlighted sections of
|
|
the text - this can be transparent if you don't want to show any
|
|
highlighting.*/
|
|
|
|
highlightedTextColourId = 0x1000203, /**< The colour with which to draw the text in highlighted sections. */
|
|
|
|
caretColourId = 0x1000204, /**< The colour with which to draw the caret. */
|
|
|
|
outlineColourId = 0x1000205, /**< If this is non-transparent, it will be used to draw a box around
|
|
the edge of the component. */
|
|
|
|
focusedOutlineColourId = 0x1000206, /**< If this is non-transparent, it will be used to draw a box around
|
|
the edge of the component when it has focus. */
|
|
|
|
shadowColourId = 0x1000207, /**< If this is non-transparent, it'll be used to draw an inner shadow
|
|
around the edge of the editor. */
|
|
};
|
|
|
|
/** Sets the font to use for newly added text.
|
|
|
|
This will change the font that will be used next time any text is added or entered
|
|
into the editor. It won't change the font of any existing text - to do that, use
|
|
applyFontToAllText() instead.
|
|
|
|
@see applyFontToAllText
|
|
*/
|
|
void setFont (const Font& newFont) throw();
|
|
|
|
/** Applies a font to all the text in the editor.
|
|
|
|
This will also set the current font to use for any new text that's added.
|
|
|
|
@see setFont
|
|
*/
|
|
void applyFontToAllText (const Font& newFont);
|
|
|
|
/** Returns the font that's currently being used for new text.
|
|
|
|
@see setFont
|
|
*/
|
|
const Font getFont() const throw();
|
|
|
|
/** If set to true, focusing on the editor will highlight all its text.
|
|
|
|
(Set to false by default).
|
|
|
|
This is useful for boxes where you expect the user to re-enter all the
|
|
text when they focus on the component, rather than editing what's already there.
|
|
*/
|
|
void setSelectAllWhenFocused (const bool b) throw();
|
|
|
|
/** Sets limits on the characters that can be entered.
|
|
|
|
@param maxTextLength if this is > 0, it sets a maximum length limit; if 0, no
|
|
limit is set
|
|
@param allowedCharacters if this is non-empty, then only characters that occur in
|
|
this string are allowed to be entered into the editor.
|
|
*/
|
|
void setInputRestrictions (const int maxTextLength,
|
|
const String& allowedCharacters = String::empty) throw();
|
|
|
|
/** When the text editor is empty, it can be set to display a message.
|
|
|
|
This is handy for things like telling the user what to type in the box - the
|
|
string is only displayed, it's not taken to actually be the contents of
|
|
the editor.
|
|
*/
|
|
void setTextToShowWhenEmpty (const String& text, const Colour& colourToUse) throw();
|
|
|
|
/** Changes the size of the scrollbars that are used.
|
|
|
|
Handy if you need smaller scrollbars for a small text box.
|
|
*/
|
|
void setScrollBarThickness (const int newThicknessPixels);
|
|
|
|
/** Shows or hides the buttons on any scrollbars that are used.
|
|
|
|
@see ScrollBar::setButtonVisibility
|
|
*/
|
|
void setScrollBarButtonVisibility (const bool buttonsVisible);
|
|
|
|
/** Registers a listener to be told when things happen to the text.
|
|
|
|
@see removeListener
|
|
*/
|
|
void addListener (TextEditorListener* const newListener) throw();
|
|
|
|
/** Deregisters a listener.
|
|
|
|
@see addListener
|
|
*/
|
|
void removeListener (TextEditorListener* const listenerToRemove) throw();
|
|
|
|
/** Returns the entire contents of the editor. */
|
|
const String getText() const throw();
|
|
|
|
/** Returns a section of the contents of the editor. */
|
|
const String getTextSubstring (const int startCharacter, const int endCharacter) const throw();
|
|
|
|
/** Returns true if there are no characters in the editor.
|
|
|
|
This is more efficient than calling getText().isEmpty().
|
|
*/
|
|
bool isEmpty() const throw();
|
|
|
|
/** Sets the entire content of the editor.
|
|
|
|
This will clear the editor and insert the given text (using the current text colour
|
|
and font). You can set the current text colour using
|
|
@code setColour (TextEditor::textColourId, ...);
|
|
@endcode
|
|
|
|
@param newText the text to add
|
|
@param sendTextChangeMessage if true, this will cause a change message to
|
|
be sent to all the listeners.
|
|
@see insertText
|
|
*/
|
|
void setText (const String& newText,
|
|
const bool sendTextChangeMessage = true);
|
|
|
|
/** Inserts some text at the current cursor position.
|
|
|
|
If a section of the text is highlighted, it will be replaced by
|
|
this string, otherwise it will be inserted.
|
|
|
|
To delete a section of text, you can use setHighlightedRegion() to
|
|
highlight it, and call insertTextAtCursor (String::empty).
|
|
|
|
@see setCaretPosition, getCaretPosition, setHighlightedRegion
|
|
*/
|
|
void insertTextAtCursor (String textToInsert);
|
|
|
|
/** Deletes all the text from the editor. */
|
|
void clear();
|
|
|
|
/** Deletes the currently selected region, and puts it on the clipboard.
|
|
|
|
@see copy, paste, SystemClipboard
|
|
*/
|
|
void cut();
|
|
|
|
/** Copies any currently selected region to the clipboard.
|
|
|
|
@see cut, paste, SystemClipboard
|
|
*/
|
|
void copy();
|
|
|
|
/** Pastes the contents of the clipboard into the editor at the cursor position.
|
|
|
|
@see cut, copy, SystemClipboard
|
|
*/
|
|
void paste();
|
|
|
|
/** Moves the caret to be in front of a given character.
|
|
|
|
@see getCaretPosition
|
|
*/
|
|
void setCaretPosition (const int newIndex) throw();
|
|
|
|
/** Returns the current index of the caret.
|
|
|
|
@see setCaretPosition
|
|
*/
|
|
int getCaretPosition() const throw();
|
|
|
|
/** Attempts to scroll the text editor so that the caret ends up at
|
|
a specified position.
|
|
|
|
This won't affect the caret's position within the text, it tries to scroll
|
|
the entire editor vertically and horizontally so that the caret is sitting
|
|
at the given position (relative to the top-left of this component).
|
|
|
|
Depending on the amount of text available, it might not be possible to
|
|
scroll far enough for the caret to reach this exact position, but it
|
|
will go as far as it can in that direction.
|
|
*/
|
|
void scrollEditorToPositionCaret (const int desiredCaretX,
|
|
const int desiredCaretY) throw();
|
|
|
|
/** Get the graphical position of the caret.
|
|
|
|
The rectangle returned is relative to the component's top-left corner.
|
|
@see scrollEditorToPositionCaret
|
|
*/
|
|
const Rectangle getCaretRectangle() throw();
|
|
|
|
/** Selects a section of the text.
|
|
*/
|
|
void setHighlightedRegion (int startIndex,
|
|
int numberOfCharactersToHighlight) throw();
|
|
|
|
/** Returns the first character that is selected.
|
|
|
|
If nothing is selected, this will still return a character index, but getHighlightedRegionLength()
|
|
will return 0.
|
|
|
|
@see setHighlightedRegion, getHighlightedRegionLength
|
|
*/
|
|
int getHighlightedRegionStart() const throw() { return selectionStart; }
|
|
|
|
/** Returns the number of characters that are selected.
|
|
|
|
@see setHighlightedRegion, getHighlightedRegionStart
|
|
*/
|
|
int getHighlightedRegionLength() const throw() { return jmax (0, selectionEnd - selectionStart); }
|
|
|
|
/** Returns the section of text that is currently selected. */
|
|
const String getHighlightedText() const throw();
|
|
|
|
/** Finds the index of the character at a given position.
|
|
|
|
The co-ordinates are relative to the component's top-left.
|
|
*/
|
|
int getTextIndexAt (const int x, const int y) throw();
|
|
|
|
/** Counts the number of characters in the text.
|
|
|
|
This is quicker than getting the text as a string if you just need to know
|
|
the length.
|
|
*/
|
|
int getTotalNumChars() throw();
|
|
|
|
/** Returns the total width of the text, as it is currently laid-out.
|
|
|
|
This may be larger than the size of the TextEditor, and can change when
|
|
the TextEditor is resized or the text changes.
|
|
*/
|
|
int getTextWidth() const throw();
|
|
|
|
/** Returns the maximum height of the text, as it is currently laid-out.
|
|
|
|
This may be larger than the size of the TextEditor, and can change when
|
|
the TextEditor is resized or the text changes.
|
|
*/
|
|
int getTextHeight() const throw();
|
|
|
|
/** Changes the size of the gap at the top and left-edge of the editor.
|
|
|
|
By default there's a gap of 4 pixels.
|
|
*/
|
|
void setIndents (const int newLeftIndent, const int newTopIndent) throw();
|
|
|
|
/** Changes the size of border left around the edge of the component.
|
|
|
|
@see getBorder
|
|
*/
|
|
void setBorder (const BorderSize& border) throw();
|
|
|
|
/** Returns the size of border around the edge of the component.
|
|
|
|
@see setBorder
|
|
*/
|
|
const BorderSize getBorder() const throw();
|
|
|
|
/** Used to disable the auto-scrolling which keeps the cursor visible.
|
|
|
|
If true (the default), the editor will scroll when the cursor moves offscreen. If
|
|
set to false, it won't.
|
|
*/
|
|
void setScrollToShowCursor (const bool shouldScrollToShowCursor) throw();
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void paintOverChildren (Graphics& g);
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseUp (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDoubleClick (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
|
|
/** @internal */
|
|
bool keyPressed (const KeyPress& key);
|
|
/** @internal */
|
|
bool keyStateChanged (const bool isKeyDown);
|
|
/** @internal */
|
|
void focusGained (FocusChangeType cause);
|
|
/** @internal */
|
|
void focusLost (FocusChangeType cause);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void enablementChanged();
|
|
/** @internal */
|
|
void colourChanged();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
/** This adds the items to the popup menu.
|
|
|
|
By default it adds the cut/copy/paste items, but you can override this if
|
|
you need to replace these with your own items.
|
|
|
|
If you want to add your own items to the existing ones, you can override this,
|
|
call the base class's addPopupMenuItems() method, then append your own items.
|
|
|
|
When the menu has been shown, performPopupMenuAction() will be called to
|
|
perform the item that the user has chosen.
|
|
|
|
The default menu items will be added using item IDs in the range
|
|
0x7fff0000 - 0x7fff1000, so you should avoid those values for your own
|
|
menu IDs.
|
|
|
|
If this was triggered by a mouse-click, the mouseClickEvent parameter will be
|
|
a pointer to the info about it, or may be null if the menu is being triggered
|
|
by some other means.
|
|
|
|
@see performPopupMenuAction, setPopupMenuEnabled, isPopupMenuEnabled
|
|
*/
|
|
virtual void addPopupMenuItems (PopupMenu& menuToAddTo,
|
|
const MouseEvent* mouseClickEvent);
|
|
|
|
/** This is called to perform one of the items that was shown on the popup menu.
|
|
|
|
If you've overridden addPopupMenuItems(), you should also override this
|
|
to perform the actions that you've added.
|
|
|
|
If you've overridden addPopupMenuItems() but have still left the default items
|
|
on the menu, remember to call the superclass's performPopupMenuAction()
|
|
so that it can perform the default actions if that's what the user clicked on.
|
|
|
|
@see addPopupMenuItems, setPopupMenuEnabled, isPopupMenuEnabled
|
|
*/
|
|
virtual void performPopupMenuAction (const int menuItemID);
|
|
|
|
/** Scrolls the minimum distance needed to get the caret into view. */
|
|
void scrollToMakeSureCursorIsVisible() throw();
|
|
|
|
/** @internal */
|
|
void moveCaret (int newCaretPos) throw();
|
|
|
|
/** @internal */
|
|
void moveCursorTo (const int newPosition, const bool isSelecting) throw();
|
|
|
|
/** Used internally to dispatch a text-change message. */
|
|
void textChanged() throw();
|
|
|
|
/** Begins a new transaction in the UndoManager.
|
|
*/
|
|
void newTransaction() throw();
|
|
|
|
/** Used internally to trigger an undo or redo. */
|
|
void doUndoRedo (const bool isRedo);
|
|
|
|
/** Can be overridden to intercept return key presses directly */
|
|
virtual void returnPressed();
|
|
|
|
/** Can be overridden to intercept escape key presses directly */
|
|
virtual void escapePressed();
|
|
|
|
/** @internal */
|
|
void handleCommandMessage (int commandId);
|
|
|
|
private:
|
|
|
|
Viewport* viewport;
|
|
TextHolderComponent* textHolder;
|
|
BorderSize borderSize;
|
|
|
|
bool readOnly : 1;
|
|
bool multiline : 1;
|
|
bool wordWrap : 1;
|
|
bool returnKeyStartsNewLine : 1;
|
|
bool caretVisible : 1;
|
|
bool popupMenuEnabled : 1;
|
|
bool selectAllTextWhenFocused : 1;
|
|
bool scrollbarVisible : 1;
|
|
bool wasFocused : 1;
|
|
bool caretFlashState : 1;
|
|
bool keepCursorOnScreen : 1;
|
|
bool tabKeyUsed : 1;
|
|
bool menuActive : 1;
|
|
|
|
UndoManager undoManager;
|
|
float cursorX, cursorY, cursorHeight;
|
|
int maxTextLength;
|
|
int selectionStart, selectionEnd;
|
|
int leftIndent, topIndent;
|
|
unsigned int lastTransactionTime;
|
|
Font currentFont;
|
|
int totalNumChars, caretPosition;
|
|
VoidArray sections;
|
|
String textToShowWhenEmpty;
|
|
Colour colourForTextWhenEmpty;
|
|
tchar passwordCharacter;
|
|
|
|
enum
|
|
{
|
|
notDragging,
|
|
draggingSelectionStart,
|
|
draggingSelectionEnd
|
|
} dragType;
|
|
|
|
String allowedCharacters;
|
|
SortedSet <void*> listeners;
|
|
|
|
friend class TextEditorInsertAction;
|
|
friend class TextEditorRemoveAction;
|
|
|
|
void coalesceSimilarSections() throw();
|
|
void splitSection (const int sectionIndex, const int charToSplitAt) throw();
|
|
|
|
void clearInternal (UndoManager* const um) throw();
|
|
|
|
void insert (const String& text,
|
|
const int insertIndex,
|
|
const Font& font,
|
|
const Colour& colour,
|
|
UndoManager* const um,
|
|
const int caretPositionToMoveTo) throw();
|
|
|
|
void reinsert (const int insertIndex,
|
|
const VoidArray& sections) throw();
|
|
|
|
void remove (const int startIndex,
|
|
int endIndex,
|
|
UndoManager* const um,
|
|
const int caretPositionToMoveTo) throw();
|
|
|
|
void getCharPosition (const int index,
|
|
float& x, float& y,
|
|
float& lineHeight) const throw();
|
|
|
|
void updateCaretPosition() throw();
|
|
|
|
int indexAtPosition (const float x,
|
|
const float y) throw();
|
|
|
|
int findWordBreakAfter (const int position) const throw();
|
|
int findWordBreakBefore (const int position) const throw();
|
|
|
|
friend class TextHolderComponent;
|
|
friend class TextEditorViewport;
|
|
void drawContent (Graphics& g);
|
|
void updateTextHolderSize() throw();
|
|
float getWordWrapWidth() const throw();
|
|
void timerCallbackInt();
|
|
void repaintCaret();
|
|
void repaintText (int textStartIndex, int textEndIndex);
|
|
|
|
TextEditor (const TextEditor&);
|
|
const TextEditor& operator= (const TextEditor&);
|
|
};
|
|
|
|
#endif // __JUCE_TEXTEDITOR_JUCEHEADER__
|
|
/********* End of inlined file: juce_TextEditor.h *********/
|
|
|
|
class Label;
|
|
|
|
/**
|
|
A class for receiving events from a Label.
|
|
|
|
You can register a LabelListener with a Label using the Label::addListener()
|
|
method, and it will be called when the text of the label changes, either because
|
|
of a call to Label::setText() or by the user editing the text (if the label is
|
|
editable).
|
|
|
|
@see Label::addListener, Label::removeListener
|
|
*/
|
|
class JUCE_API LabelListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~LabelListener() {}
|
|
|
|
/** Called when a Label's text has changed.
|
|
*/
|
|
virtual void labelTextChanged (Label* labelThatHasChanged) = 0;
|
|
};
|
|
|
|
/**
|
|
A component that displays a text string, and can optionally become a text
|
|
editor when clicked.
|
|
*/
|
|
class JUCE_API Label : public Component,
|
|
public SettableTooltipClient,
|
|
protected TextEditorListener,
|
|
private ComponentListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a Label.
|
|
|
|
@param componentName the name to give the component
|
|
@param labelText the text to show in the label
|
|
*/
|
|
Label (const String& componentName,
|
|
const String& labelText);
|
|
|
|
/** Destructor. */
|
|
~Label();
|
|
|
|
/** Changes the label text.
|
|
|
|
If broadcastChangeMessage is true and the new text is different to the current
|
|
text, then the class will broadcast a change message to any LabelListeners that
|
|
are registered.
|
|
*/
|
|
void setText (const String& newText,
|
|
const bool broadcastChangeMessage);
|
|
|
|
/** Returns the label's current text.
|
|
|
|
@param returnActiveEditorContents if this is true and the label is currently
|
|
being edited, then this method will return the
|
|
text as it's being shown in the editor. If false,
|
|
then the value returned here won't be updated until
|
|
the user has finished typing and pressed the return
|
|
key.
|
|
*/
|
|
const String getText (const bool returnActiveEditorContents = false) const throw();
|
|
|
|
/** Changes the font to use to draw the text.
|
|
|
|
@see getFont
|
|
*/
|
|
void setFont (const Font& newFont) throw();
|
|
|
|
/** Returns the font currently being used.
|
|
|
|
@see setFont
|
|
*/
|
|
const Font& getFont() const throw();
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the label.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
Note that you can also use the constants from TextEditor::ColourIds to change the
|
|
colour of the text editor that is opened when a label is editable.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1000280, /**< The background colour to fill the label with. */
|
|
textColourId = 0x1000281, /**< The colour for the text. */
|
|
outlineColourId = 0x1000282 /**< An optional colour to use to draw a border around the label.
|
|
Leave this transparent to not have an outline. */
|
|
};
|
|
|
|
/** Sets the style of justification to be used for positioning the text.
|
|
|
|
(The default is Justification::centredLeft)
|
|
*/
|
|
void setJustificationType (const Justification& justification) throw();
|
|
|
|
/** Returns the type of justification, as set in setJustificationType(). */
|
|
const Justification getJustificationType() const throw() { return justification; }
|
|
|
|
/** Changes the gap that is left between the edge of the component and the text.
|
|
By default there's a small gap left at the sides of the component to allow for
|
|
the drawing of the border, but you can change this if necessary.
|
|
*/
|
|
void setBorderSize (int horizontalBorder, int verticalBorder);
|
|
|
|
/** Returns the size of the horizontal gap being left around the text.
|
|
*/
|
|
int getHorizontalBorderSize() const throw() { return horizontalBorderSize; }
|
|
|
|
/** Returns the size of the vertical gap being left around the text.
|
|
*/
|
|
int getVerticalBorderSize() const throw() { return verticalBorderSize; }
|
|
|
|
/** Makes this label "stick to" another component.
|
|
|
|
This will cause the label to follow another component around, staying
|
|
either to its left or above it.
|
|
|
|
@param owner the component to follow
|
|
@param onLeft if true, the label will stay on the left of its component; if
|
|
false, it will stay above it.
|
|
*/
|
|
void attachToComponent (Component* owner,
|
|
const bool onLeft);
|
|
|
|
/** If this label has been attached to another component using attachToComponent, this
|
|
returns the other component.
|
|
|
|
Returns 0 if the label is not attached.
|
|
*/
|
|
Component* getAttachedComponent() const throw() { return ownerComponent; }
|
|
|
|
/** If the label is attached to the left of another component, this returns true.
|
|
|
|
Returns false if the label is above the other component. This is only relevent if
|
|
attachToComponent() has been called.
|
|
*/
|
|
bool isAttachedOnLeft() const throw() { return leftOfOwnerComp; }
|
|
|
|
/** Specifies the minimum amount that the font can be squashed horizantally before it starts
|
|
using ellipsis.
|
|
|
|
@see Graphics::drawFittedText
|
|
*/
|
|
void setMinimumHorizontalScale (const float newScale);
|
|
|
|
float getMinimumHorizontalScale() const throw() { return minimumHorizontalScale; }
|
|
|
|
/** Registers a listener that will be called when the label's text changes. */
|
|
void addListener (LabelListener* const listener) throw();
|
|
|
|
/** Deregisters a previously-registered listener. */
|
|
void removeListener (LabelListener* const listener) throw();
|
|
|
|
/** Makes the label turn into a TextEditor when clicked.
|
|
|
|
By default this is turned off.
|
|
|
|
If turned on, then single- or double-clicking will turn the label into
|
|
an editor. If the user then changes the text, then the ChangeBroadcaster
|
|
base class will be used to send change messages to any listeners that
|
|
have registered.
|
|
|
|
If the user changes the text, the textWasEdited() method will be called
|
|
afterwards, and subclasses can override this if they need to do anything
|
|
special.
|
|
|
|
@param editOnSingleClick if true, just clicking once on the label will start editing the text
|
|
@param editOnDoubleClick if true, a double-click is needed to start editing
|
|
@param lossOfFocusDiscardsChanges if true, clicking somewhere else while the text is being
|
|
edited will discard any changes; if false, then this will
|
|
commit the changes.
|
|
@see showEditor, setEditorColours, TextEditor
|
|
*/
|
|
void setEditable (const bool editOnSingleClick,
|
|
const bool editOnDoubleClick = false,
|
|
const bool lossOfFocusDiscardsChanges = false) throw();
|
|
|
|
/** Returns true if this option was set using setEditable(). */
|
|
bool isEditableOnSingleClick() const throw() { return editSingleClick; }
|
|
|
|
/** Returns true if this option was set using setEditable(). */
|
|
bool isEditableOnDoubleClick() const throw() { return editDoubleClick; }
|
|
|
|
/** Returns true if this option has been set in a call to setEditable(). */
|
|
bool doesLossOfFocusDiscardChanges() const throw() { return lossOfFocusDiscardsChanges; }
|
|
|
|
/** Returns true if the user can edit this label's text. */
|
|
bool isEditable() const throw() { return editSingleClick || editDoubleClick; }
|
|
|
|
/** Makes the editor appear as if the label had been clicked by the user.
|
|
|
|
@see textWasEdited, setEditable
|
|
*/
|
|
void showEditor();
|
|
|
|
/** Hides the editor if it was being shown.
|
|
|
|
@param discardCurrentEditorContents if true, the label's text will be
|
|
reset to whatever it was before the editor
|
|
was shown; if false, the current contents of the
|
|
editor will be used to set the label's text
|
|
before it is hidden.
|
|
*/
|
|
void hideEditor (const bool discardCurrentEditorContents);
|
|
|
|
/** Returns true if the editor is currently focused and active. */
|
|
bool isBeingEdited() const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void mouseUp (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDoubleClick (const MouseEvent& e);
|
|
/** @internal */
|
|
void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized);
|
|
/** @internal */
|
|
void componentParentHierarchyChanged (Component& component);
|
|
/** @internal */
|
|
void componentVisibilityChanged (Component& component);
|
|
/** @internal */
|
|
void inputAttemptWhenModal();
|
|
/** @internal */
|
|
void focusGained (FocusChangeType);
|
|
/** @internal */
|
|
void enablementChanged();
|
|
/** @internal */
|
|
KeyboardFocusTraverser* createFocusTraverser();
|
|
/** @internal */
|
|
void textEditorTextChanged (TextEditor& editor);
|
|
/** @internal */
|
|
void textEditorReturnKeyPressed (TextEditor& editor);
|
|
/** @internal */
|
|
void textEditorEscapeKeyPressed (TextEditor& editor);
|
|
/** @internal */
|
|
void textEditorFocusLost (TextEditor& editor);
|
|
/** @internal */
|
|
void colourChanged();
|
|
|
|
/** Creates the TextEditor component that will be used when the user has clicked on the label.
|
|
|
|
Subclasses can override this if they need to customise this component in some way.
|
|
*/
|
|
virtual TextEditor* createEditorComponent();
|
|
|
|
/** Called after the user changes the text.
|
|
*/
|
|
virtual void textWasEdited();
|
|
|
|
/** Called when the text has been altered.
|
|
*/
|
|
virtual void textWasChanged();
|
|
|
|
/** Called when the text editor has just appeared, due to a user click or other
|
|
focus change.
|
|
*/
|
|
virtual void editorShown (TextEditor* editorComponent);
|
|
|
|
/** Called when the text editor is going to be deleted, after editing has finished.
|
|
*/
|
|
virtual void editorAboutToBeHidden (TextEditor* editorComponent);
|
|
|
|
private:
|
|
String text;
|
|
Font font;
|
|
Justification justification;
|
|
TextEditor* editor;
|
|
SortedSet <void*> listeners;
|
|
Component* ownerComponent;
|
|
ComponentDeletionWatcher* deletionWatcher;
|
|
int horizontalBorderSize, verticalBorderSize;
|
|
float minimumHorizontalScale;
|
|
bool editSingleClick : 1;
|
|
bool editDoubleClick : 1;
|
|
bool lossOfFocusDiscardsChanges : 1;
|
|
bool leftOfOwnerComp : 1;
|
|
|
|
bool updateFromTextEditorContents();
|
|
void callChangeListeners();
|
|
|
|
Label (const Label&);
|
|
const Label& operator= (const Label&);
|
|
};
|
|
|
|
#endif // __JUCE_LABEL_JUCEHEADER__
|
|
/********* End of inlined file: juce_Label.h *********/
|
|
|
|
class ComboBox;
|
|
|
|
/**
|
|
A class for receiving events from a ComboBox.
|
|
|
|
You can register a ComboBoxListener with a ComboBox using the ComboBox::addListener()
|
|
method, and it will be called when the selected item in the box changes.
|
|
|
|
@see ComboBox::addListener, ComboBox::removeListener
|
|
*/
|
|
class JUCE_API ComboBoxListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~ComboBoxListener() {}
|
|
|
|
/** Called when a ComboBox has its selected item changed.
|
|
*/
|
|
virtual void comboBoxChanged (ComboBox* comboBoxThatHasChanged) = 0;
|
|
};
|
|
|
|
/**
|
|
A component that lets the user choose from a drop-down list of choices.
|
|
|
|
The combo-box has a list of text strings, each with an associated id number,
|
|
that will be shown in the drop-down list when the user clicks on the component.
|
|
|
|
The currently selected choice is displayed in the combo-box, and this can
|
|
either be read-only text, or editable.
|
|
|
|
To find out when the user selects a different item or edits the text, you
|
|
can register a ComboBoxListener to receive callbacks.
|
|
|
|
@see ComboBoxListener
|
|
*/
|
|
class JUCE_API ComboBox : public Component,
|
|
public SettableTooltipClient,
|
|
private LabelListener,
|
|
private AsyncUpdater
|
|
{
|
|
public:
|
|
|
|
/** Creates a combo-box.
|
|
|
|
On construction, the text field will be empty, so you should call the
|
|
setSelectedId() or setText() method to choose the initial value before
|
|
displaying it.
|
|
|
|
@param componentName the name to set for the component (see Component::setName())
|
|
*/
|
|
ComboBox (const String& componentName);
|
|
|
|
/** Destructor. */
|
|
~ComboBox();
|
|
|
|
/** Sets whether the test in the combo-box is editable.
|
|
|
|
The default state for a new ComboBox is non-editable, and can only be changed
|
|
by choosing from the drop-down list.
|
|
*/
|
|
void setEditableText (const bool isEditable);
|
|
|
|
/** Returns true if the text is directly editable.
|
|
@see setEditableText
|
|
*/
|
|
bool isTextEditable() const throw();
|
|
|
|
/** Sets the style of justification to be used for positioning the text.
|
|
|
|
The default is Justification::centredLeft. The text is displayed using a
|
|
Label component inside the ComboBox.
|
|
*/
|
|
void setJustificationType (const Justification& justification) throw();
|
|
|
|
/** Returns the current justification for the text box.
|
|
@see setJustificationType
|
|
*/
|
|
const Justification getJustificationType() const throw();
|
|
|
|
/** Adds an item to be shown in the drop-down list.
|
|
|
|
@param newItemText the text of the item to show in the list
|
|
@param newItemId an associated ID number that can be set or retrieved - see
|
|
getSelectedId() and setSelectedId()
|
|
@see setItemEnabled, addSeparator, addSectionHeading, removeItem, getNumItems, getItemText, getItemId
|
|
*/
|
|
void addItem (const String& newItemText,
|
|
const int newItemId) throw();
|
|
|
|
/** Adds a separator line to the drop-down list.
|
|
|
|
This is like adding a separator to a popup menu. See PopupMenu::addSeparator().
|
|
*/
|
|
void addSeparator() throw();
|
|
|
|
/** Adds a heading to the drop-down list, so that you can group the items into
|
|
different sections.
|
|
|
|
The headings are indented slightly differently to set them apart from the
|
|
items on the list, and obviously can't be selected. You might want to add
|
|
separators between your sections too.
|
|
|
|
@see addItem, addSeparator
|
|
*/
|
|
void addSectionHeading (const String& headingName) throw();
|
|
|
|
/** This allows items in the drop-down list to be selectively disabled.
|
|
|
|
When you add an item, it's enabled by default, but you can call this
|
|
method to change its status.
|
|
|
|
If you disable an item which is already selected, this won't change the
|
|
current selection - it just stops the user choosing that item from the list.
|
|
*/
|
|
void setItemEnabled (const int itemId,
|
|
const bool isEnabled) throw();
|
|
|
|
/** Changes the text for an existing item.
|
|
*/
|
|
void changeItemText (const int itemId,
|
|
const String& newText) throw();
|
|
|
|
/** Removes all the items from the drop-down list.
|
|
|
|
If this call causes the content to be cleared, then a change-message
|
|
will be broadcast unless dontSendChangeMessage is true.
|
|
|
|
@see addItem, removeItem, getNumItems
|
|
*/
|
|
void clear (const bool dontSendChangeMessage = false);
|
|
|
|
/** Returns the number of items that have been added to the list.
|
|
|
|
Note that this doesn't include headers or separators.
|
|
*/
|
|
int getNumItems() const throw();
|
|
|
|
/** Returns the text for one of the items in the list.
|
|
|
|
Note that this doesn't include headers or separators.
|
|
|
|
@param index the item's index from 0 to (getNumItems() - 1)
|
|
*/
|
|
const String getItemText (const int index) const throw();
|
|
|
|
/** Returns the ID for one of the items in the list.
|
|
|
|
Note that this doesn't include headers or separators.
|
|
|
|
@param index the item's index from 0 to (getNumItems() - 1)
|
|
*/
|
|
int getItemId (const int index) const throw();
|
|
|
|
/** Returns the ID of the item that's currently shown in the box.
|
|
|
|
If no item is selected, or if the text is editable and the user
|
|
has entered something which isn't one of the items in the list, then
|
|
this will return 0.
|
|
|
|
@see setSelectedId, getSelectedItemIndex, getText
|
|
*/
|
|
int getSelectedId() const throw();
|
|
|
|
/** Sets one of the items to be the current selection.
|
|
|
|
This will set the ComboBox's text to that of the item that matches
|
|
this ID.
|
|
|
|
@param newItemId the new item to select
|
|
@param dontSendChangeMessage if set to true, this method won't trigger a
|
|
change notification
|
|
@see getSelectedId, setSelectedItemIndex, setText
|
|
*/
|
|
void setSelectedId (const int newItemId,
|
|
const bool dontSendChangeMessage = false) throw();
|
|
|
|
/** Returns the index of the item that's currently shown in the box.
|
|
|
|
If no item is selected, or if the text is editable and the user
|
|
has entered something which isn't one of the items in the list, then
|
|
this will return -1.
|
|
|
|
@see setSelectedItemIndex, getSelectedId, getText
|
|
*/
|
|
int getSelectedItemIndex() const throw();
|
|
|
|
/** Sets one of the items to be the current selection.
|
|
|
|
This will set the ComboBox's text to that of the item at the given
|
|
index in the list.
|
|
|
|
@param newItemIndex the new item to select
|
|
@param dontSendChangeMessage if set to true, this method won't trigger a
|
|
change notification
|
|
@see getSelectedItemIndex, setSelectedId, setText
|
|
*/
|
|
void setSelectedItemIndex (const int newItemIndex,
|
|
const bool dontSendChangeMessage = false) throw();
|
|
|
|
/** Returns the text that is currently shown in the combo-box's text field.
|
|
|
|
If the ComboBox has editable text, then this text may have been edited
|
|
by the user; otherwise it will be one of the items from the list, or
|
|
possibly an empty string if nothing was selected.
|
|
|
|
@see setText, getSelectedId, getSelectedItemIndex
|
|
*/
|
|
const String getText() const throw();
|
|
|
|
/** Sets the contents of the combo-box's text field.
|
|
|
|
The text passed-in will be set as the current text regardless of whether
|
|
it is one of the items in the list. If the current text isn't one of the
|
|
items, then getSelectedId() will return -1, otherwise it wil return
|
|
the approriate ID.
|
|
|
|
@param newText the text to select
|
|
@param dontSendChangeMessage if set to true, this method won't trigger a
|
|
change notification
|
|
@see getText
|
|
*/
|
|
void setText (const String& newText,
|
|
const bool dontSendChangeMessage = false) throw();
|
|
|
|
/** Programmatically opens the text editor to allow the user to edit the current item.
|
|
|
|
This is the same effect as when the box is clicked-on.
|
|
@see Label::showEditor();
|
|
*/
|
|
void showEditor();
|
|
|
|
/** Registers a listener that will be called when the box's content changes. */
|
|
void addListener (ComboBoxListener* const listener) throw();
|
|
|
|
/** Deregisters a previously-registered listener. */
|
|
void removeListener (ComboBoxListener* const listener) throw();
|
|
|
|
/** Sets a message to display when there is no item currently selected.
|
|
|
|
@see getTextWhenNothingSelected
|
|
*/
|
|
void setTextWhenNothingSelected (const String& newMessage) throw();
|
|
|
|
/** Returns the text that is shown when no item is selected.
|
|
|
|
@see setTextWhenNothingSelected
|
|
*/
|
|
const String getTextWhenNothingSelected() const throw();
|
|
|
|
/** Sets the message to show when there are no items in the list, and the user clicks
|
|
on the drop-down box.
|
|
|
|
By default it just says "no choices", but this lets you change it to something more
|
|
meaningful.
|
|
*/
|
|
void setTextWhenNoChoicesAvailable (const String& newMessage) throw();
|
|
|
|
/** Returns the text shown when no items have been added to the list.
|
|
@see setTextWhenNoChoicesAvailable
|
|
*/
|
|
const String getTextWhenNoChoicesAvailable() const throw();
|
|
|
|
/** Gives the ComboBox a tooltip. */
|
|
void setTooltip (const String& newTooltip);
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the combo box.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
To change the colours of the menu that pops up
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1000b00, /**< The background colour to fill the box with. */
|
|
textColourId = 0x1000a00, /**< The colour for the text in the box. */
|
|
outlineColourId = 0x1000c00, /**< The colour for an outline around the box. */
|
|
buttonColourId = 0x1000d00, /**< The base colour for the button (a LookAndFeel class will probably use variations on this). */
|
|
arrowColourId = 0x1000e00, /**< The colour for the arrow shape that pops up the menu */
|
|
};
|
|
|
|
/** @internal */
|
|
void labelTextChanged (Label*);
|
|
/** @internal */
|
|
void enablementChanged();
|
|
/** @internal */
|
|
void colourChanged();
|
|
/** @internal */
|
|
void focusGained (Component::FocusChangeType cause);
|
|
/** @internal */
|
|
void focusLost (Component::FocusChangeType cause);
|
|
/** @internal */
|
|
void handleAsyncUpdate();
|
|
/** @internal */
|
|
const String getTooltip() { return label->getTooltip(); }
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent&);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent&);
|
|
/** @internal */
|
|
void mouseUp (const MouseEvent&);
|
|
/** @internal */
|
|
void lookAndFeelChanged();
|
|
/** @internal */
|
|
void paint (Graphics&);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
bool keyStateChanged (const bool isKeyDown);
|
|
/** @internal */
|
|
bool keyPressed (const KeyPress&);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
struct ItemInfo
|
|
{
|
|
String name;
|
|
int itemId;
|
|
bool isEnabled : 1, isHeading : 1;
|
|
|
|
bool isSeparator() const throw();
|
|
bool isRealItem() const throw();
|
|
};
|
|
|
|
OwnedArray <ItemInfo> items;
|
|
int currentIndex;
|
|
bool isButtonDown;
|
|
bool separatorPending;
|
|
bool menuActive;
|
|
SortedSet <void*> listeners;
|
|
Label* label;
|
|
String textWhenNothingSelected, noChoicesMessage;
|
|
|
|
void showPopup();
|
|
|
|
ItemInfo* getItemForId (const int itemId) const throw();
|
|
ItemInfo* getItemForIndex (const int index) const throw();
|
|
|
|
ComboBox (const ComboBox&);
|
|
const ComboBox& operator= (const ComboBox&);
|
|
};
|
|
|
|
#endif // __JUCE_COMBOBOX_JUCEHEADER__
|
|
/********* End of inlined file: juce_ComboBox.h *********/
|
|
|
|
/**
|
|
Manages the state of some audio and midi i/o devices.
|
|
|
|
This class keeps tracks of a currently-selected audio device, through
|
|
with which it continuously streams data from an audio callback, as well as
|
|
one or more midi inputs.
|
|
|
|
The idea is that your application will create one global instance of this object,
|
|
and let it take care of creating and deleting specific types of audio devices
|
|
internally. So when the device is changed, your callbacks will just keep running
|
|
without having to worry about this.
|
|
|
|
The manager can save and reload all of its device settings as XML, which
|
|
makes it very easy for you to save and reload the audio setup of your
|
|
application.
|
|
|
|
And to make it easy to let the user change its settings, there's a component
|
|
to do just that - the AudioDeviceSelectorComponent class, which contains a set of
|
|
device selection/sample-rate/latency controls.
|
|
|
|
To use an AudioDeviceManager, create one, and use initialise() to set it up. Then
|
|
call addAudioCallback() to register your audio callback with it, and use that to process
|
|
your audio data.
|
|
|
|
The manager also acts as a handy hub for incoming midi messages, allowing a
|
|
listener to register for messages from either a specific midi device, or from whatever
|
|
the current default midi input device is. The listener then doesn't have to worry about
|
|
re-registering with different midi devices if they are changed or deleted.
|
|
|
|
And yet another neat trick is that amount of CPU time being used is measured and
|
|
available with the getCpuUsage() method.
|
|
|
|
The AudioDeviceManager is a ChangeBroadcaster, and will send a change message to
|
|
listeners whenever one of its settings is changed.
|
|
|
|
@see AudioDeviceSelectorComponent, AudioIODevice, AudioIODeviceType
|
|
*/
|
|
class JUCE_API AudioDeviceManager : public ChangeBroadcaster
|
|
{
|
|
public:
|
|
|
|
/** Creates a default AudioDeviceManager.
|
|
|
|
Initially no audio device will be selected. You should call the initialise() method
|
|
and register an audio callback with setAudioCallback() before it'll be able to
|
|
actually make any noise.
|
|
*/
|
|
AudioDeviceManager();
|
|
|
|
/** Destructor. */
|
|
~AudioDeviceManager();
|
|
|
|
/**
|
|
This structure holds a set of properties describing the current audio setup.
|
|
|
|
@see AudioDeviceManager::setAudioDeviceSetup()
|
|
*/
|
|
struct JUCE_API AudioDeviceSetup
|
|
{
|
|
AudioDeviceSetup();
|
|
bool operator== (const AudioDeviceSetup& other) const;
|
|
|
|
/** The name of the audio device used for output.
|
|
The name has to be one of the ones listed by the AudioDeviceManager's currently
|
|
selected device type.
|
|
This may be the same as the input device.
|
|
*/
|
|
String outputDeviceName;
|
|
|
|
/** The name of the audio device used for input.
|
|
This may be the same as the output device.
|
|
*/
|
|
String inputDeviceName;
|
|
|
|
/** The current sample rate.
|
|
This rate is used for both the input and output devices.
|
|
*/
|
|
double sampleRate;
|
|
|
|
/** The buffer size, in samples.
|
|
This buffer size is used for both the input and output devices.
|
|
*/
|
|
int bufferSize;
|
|
|
|
/** The set of active input channels.
|
|
The bits that are set in this array indicate the channels of the
|
|
input device that are active.
|
|
*/
|
|
BitArray inputChannels;
|
|
|
|
/** If this is true, it indicates that the inputChannels array
|
|
should be ignored, and instead, the device's default channels
|
|
should be used.
|
|
*/
|
|
bool useDefaultInputChannels;
|
|
|
|
/** The set of active output channels.
|
|
The bits that are set in this array indicate the channels of the
|
|
input device that are active.
|
|
*/
|
|
BitArray outputChannels;
|
|
|
|
/** If this is true, it indicates that the outputChannels array
|
|
should be ignored, and instead, the device's default channels
|
|
should be used.
|
|
*/
|
|
bool useDefaultOutputChannels;
|
|
};
|
|
|
|
/** Opens a set of audio devices ready for use.
|
|
|
|
This will attempt to open either a default audio device, or one that was
|
|
previously saved as XML.
|
|
|
|
@param numInputChannelsNeeded a minimum number of input channels needed
|
|
by your app.
|
|
@param numOutputChannelsNeeded a minimum number of output channels to open
|
|
@param savedState either a previously-saved state that was produced
|
|
by createStateXml(), or 0 if you want the manager
|
|
to choose the best device to open.
|
|
@param selectDefaultDeviceOnFailure if true, then if the device specified in the XML
|
|
fails to open, then a default device will be used
|
|
instead. If false, then on failure, no device is
|
|
opened.
|
|
@param preferredDefaultDeviceName if this is not empty, and there's a device with this
|
|
name, then that will be used as the default device
|
|
(assuming that there wasn't one specified in the XML).
|
|
The string can actually be a simple wildcard, containing "*"
|
|
and "?" characters
|
|
@param preferredSetupOptions if this is non-null, the structure will be used as the
|
|
set of preferred settings when opening the device. If you
|
|
use this parameter, the preferredDefaultDeviceName
|
|
field will be ignored
|
|
|
|
@returns an error message if anything went wrong, or an empty string if it worked ok.
|
|
*/
|
|
const String initialise (const int numInputChannelsNeeded,
|
|
const int numOutputChannelsNeeded,
|
|
const XmlElement* const savedState,
|
|
const bool selectDefaultDeviceOnFailure,
|
|
const String& preferredDefaultDeviceName = String::empty,
|
|
const AudioDeviceSetup* preferredSetupOptions = 0);
|
|
|
|
/** Returns some XML representing the current state of the manager.
|
|
|
|
This stores the current device, its samplerate, block size, etc, and
|
|
can be restored later with initialise().
|
|
*/
|
|
XmlElement* createStateXml() const;
|
|
|
|
/** Returns the current device properties that are in use.
|
|
|
|
@see setAudioDeviceSetup
|
|
*/
|
|
void getAudioDeviceSetup (AudioDeviceSetup& setup);
|
|
|
|
/** Changes the current device or its settings.
|
|
|
|
If you want to change a device property, like the current sample rate or
|
|
block size, you can call getAudioDeviceSetup() to retrieve the current
|
|
settings, then tweak the appropriate fields in the AudioDeviceSetup structure,
|
|
and pass it back into this method to apply the new settings.
|
|
|
|
@param newSetup the settings that you'd like to use
|
|
@param treatAsChosenDevice if this is true and if the device opens correctly, these new
|
|
settings will be taken as having been explicitly chosen by the
|
|
user, and the next time createStateXml() is called, these settings
|
|
will be returned. If it's false, then the device is treated as a
|
|
temporary or default device, and a call to createStateXml() will
|
|
return either the last settings that were made with treatAsChosenDevice
|
|
as true, or the last XML settings that were passed into initialise().
|
|
@returns an error message if anything went wrong, or an empty string if it worked ok.
|
|
|
|
@see getAudioDeviceSetup
|
|
*/
|
|
const String setAudioDeviceSetup (const AudioDeviceSetup& newSetup,
|
|
const bool treatAsChosenDevice);
|
|
|
|
/** Returns the currently-active audio device. */
|
|
AudioIODevice* getCurrentAudioDevice() const throw() { return currentAudioDevice; }
|
|
|
|
/** Returns the type of audio device currently in use.
|
|
@see setCurrentAudioDeviceType
|
|
*/
|
|
const String getCurrentAudioDeviceType() const throw() { return currentDeviceType; }
|
|
|
|
/** Returns the currently active audio device type object.
|
|
Don't keep a copy of this pointer - it's owned by the device manager and could
|
|
change at any time.
|
|
*/
|
|
AudioIODeviceType* getCurrentDeviceTypeObject() const;
|
|
|
|
/** Changes the class of audio device being used.
|
|
|
|
This switches between, e.g. ASIO and DirectSound. On the Mac you probably won't ever call
|
|
this because there's only one type: CoreAudio.
|
|
|
|
For a list of types, see getAvailableDeviceTypes().
|
|
*/
|
|
void setCurrentAudioDeviceType (const String& type,
|
|
const bool treatAsChosenDevice);
|
|
|
|
/** Closes the currently-open device.
|
|
|
|
You can call restartLastAudioDevice() later to reopen it in the same state
|
|
that it was just in.
|
|
*/
|
|
void closeAudioDevice();
|
|
|
|
/** Tries to reload the last audio device that was running.
|
|
|
|
Note that this only reloads the last device that was running before
|
|
closeAudioDevice() was called - it doesn't reload any kind of saved-state,
|
|
and can only be called after a device has been opened with SetAudioDevice().
|
|
|
|
If a device is already open, this call will do nothing.
|
|
*/
|
|
void restartLastAudioDevice();
|
|
|
|
/** Registers an audio callback to be used.
|
|
|
|
The manager will redirect callbacks from whatever audio device is currently
|
|
in use to all registered callback objects. If more than one callback is
|
|
active, they will all be given the same input data, and their outputs will
|
|
be summed.
|
|
|
|
If necessary, this method will invoke audioDeviceAboutToStart() on the callback
|
|
object before returning.
|
|
|
|
To remove a callback, use removeAudioCallback().
|
|
*/
|
|
void addAudioCallback (AudioIODeviceCallback* newCallback);
|
|
|
|
/** Deregisters a previously added callback.
|
|
|
|
If necessary, this method will invoke audioDeviceStopped() on the callback
|
|
object before returning.
|
|
|
|
@see addAudioCallback
|
|
*/
|
|
void removeAudioCallback (AudioIODeviceCallback* callback);
|
|
|
|
/** Returns the average proportion of available CPU being spent inside the audio callbacks.
|
|
|
|
Returns a value between 0 and 1.0
|
|
*/
|
|
double getCpuUsage() const;
|
|
|
|
/** Enables or disables a midi input device.
|
|
|
|
The list of devices can be obtained with the MidiInput::getDevices() method.
|
|
|
|
Any incoming messages from enabled input devices will be forwarded on to all the
|
|
listeners that have been registered with the addMidiInputCallback() method. They
|
|
can either register for messages from a particular device, or from just the
|
|
"default" midi input.
|
|
|
|
Routing the midi input via an AudioDeviceManager means that when a listener
|
|
registers for the default midi input, this default device can be changed by the
|
|
manager without the listeners having to know about it or re-register.
|
|
|
|
It also means that a listener can stay registered for a midi input that is disabled
|
|
or not present, so that when the input is re-enabled, the listener will start
|
|
receiving messages again.
|
|
|
|
@see addMidiInputCallback, isMidiInputEnabled
|
|
*/
|
|
void setMidiInputEnabled (const String& midiInputDeviceName,
|
|
const bool enabled);
|
|
|
|
/** Returns true if a given midi input device is being used.
|
|
|
|
@see setMidiInputEnabled
|
|
*/
|
|
bool isMidiInputEnabled (const String& midiInputDeviceName) const;
|
|
|
|
/** Registers a listener for callbacks when midi events arrive from a midi input.
|
|
|
|
The device name can be empty to indicate that it wants events from whatever the
|
|
current "default" device is. Or it can be the name of one of the midi input devices
|
|
(see MidiInput::getDevices() for the names).
|
|
|
|
Only devices which are enabled (see the setMidiInputEnabled() method) will have their
|
|
events forwarded on to listeners.
|
|
*/
|
|
void addMidiInputCallback (const String& midiInputDeviceName,
|
|
MidiInputCallback* callback);
|
|
|
|
/** Removes a listener that was previously registered with addMidiInputCallback().
|
|
*/
|
|
void removeMidiInputCallback (const String& midiInputDeviceName,
|
|
MidiInputCallback* callback);
|
|
|
|
/** Sets a midi output device to use as the default.
|
|
|
|
The list of devices can be obtained with the MidiOutput::getDevices() method.
|
|
|
|
The specified device will be opened automatically and can be retrieved with the
|
|
getDefaultMidiOutput() method.
|
|
|
|
Pass in an empty string to deselect all devices. For the default device, you
|
|
can use MidiOutput::getDevices() [MidiOutput::getDefaultDeviceIndex()].
|
|
|
|
@see getDefaultMidiOutput, getDefaultMidiOutputName
|
|
*/
|
|
void setDefaultMidiOutput (const String& deviceName);
|
|
|
|
/** Returns the name of the default midi output.
|
|
|
|
@see setDefaultMidiOutput, getDefaultMidiOutput
|
|
*/
|
|
const String getDefaultMidiOutputName() const throw() { return defaultMidiOutputName; }
|
|
|
|
/** Returns the current default midi output device.
|
|
|
|
If no device has been selected, or the device can't be opened, this will
|
|
return 0.
|
|
|
|
@see getDefaultMidiOutputName
|
|
*/
|
|
MidiOutput* getDefaultMidiOutput() const throw() { return defaultMidiOutput; }
|
|
|
|
/** Returns a list of the types of device supported.
|
|
*/
|
|
const OwnedArray <AudioIODeviceType>& getAvailableDeviceTypes();
|
|
|
|
/** Creates a list of available types.
|
|
|
|
This will add a set of new AudioIODeviceType objects to the specified list, to
|
|
represent each available types of device.
|
|
|
|
You can override this if your app needs to do something specific, like avoid
|
|
using DirectSound devices, etc.
|
|
*/
|
|
virtual void createAudioDeviceTypes (OwnedArray <AudioIODeviceType>& types);
|
|
|
|
/** Plays a beep through the current audio device.
|
|
|
|
This is here to allow the audio setup UI panels to easily include a "test"
|
|
button so that the user can check where the audio is coming from.
|
|
*/
|
|
void playTestSound();
|
|
|
|
/** Turns on level-measuring.
|
|
|
|
When enabled, the device manager will measure the peak input level
|
|
across all channels, and you can get this level by calling getCurrentInputLevel().
|
|
|
|
This is mainly intended for audio setup UI panels to use to create a mic
|
|
level display, so that the user can check that they've selected the right
|
|
device.
|
|
|
|
A simple filter is used to make the level decay smoothly, but this is
|
|
only intended for giving rough feedback, and not for any kind of accurate
|
|
measurement.
|
|
*/
|
|
void enableInputLevelMeasurement (const bool enableMeasurement);
|
|
|
|
/** Returns the current input level.
|
|
|
|
To use this, you must first enable it by calling enableInputLevelMeasurement().
|
|
|
|
See enableInputLevelMeasurement() for more info.
|
|
*/
|
|
double getCurrentInputLevel() const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
OwnedArray <AudioIODeviceType> availableDeviceTypes;
|
|
OwnedArray <AudioDeviceSetup> lastDeviceTypeConfigs;
|
|
|
|
AudioDeviceSetup currentSetup;
|
|
AudioIODevice* currentAudioDevice;
|
|
SortedSet <AudioIODeviceCallback*> callbacks;
|
|
int numInputChansNeeded, numOutputChansNeeded;
|
|
String currentDeviceType;
|
|
BitArray inputChannels, outputChannels;
|
|
XmlElement* lastExplicitSettings;
|
|
mutable bool listNeedsScanning;
|
|
bool useInputNames;
|
|
int inputLevelMeasurementEnabledCount;
|
|
double inputLevel;
|
|
AudioSampleBuffer* testSound;
|
|
int testSoundPosition;
|
|
AudioSampleBuffer tempBuffer;
|
|
|
|
StringArray midiInsFromXml;
|
|
OwnedArray <MidiInput> enabledMidiInputs;
|
|
Array <MidiInputCallback*> midiCallbacks;
|
|
Array <MidiInput*> midiCallbackDevices;
|
|
String defaultMidiOutputName;
|
|
MidiOutput* defaultMidiOutput;
|
|
CriticalSection audioCallbackLock, midiCallbackLock;
|
|
|
|
double cpuUsageMs, timeToCpuScale;
|
|
|
|
class CallbackHandler : public AudioIODeviceCallback,
|
|
public MidiInputCallback
|
|
{
|
|
public:
|
|
AudioDeviceManager* owner;
|
|
|
|
void audioDeviceIOCallback (const float** inputChannelData,
|
|
int totalNumInputChannels,
|
|
float** outputChannelData,
|
|
int totalNumOutputChannels,
|
|
int numSamples);
|
|
|
|
void audioDeviceAboutToStart (AudioIODevice*);
|
|
|
|
void audioDeviceStopped();
|
|
|
|
void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message);
|
|
};
|
|
|
|
CallbackHandler callbackHandler;
|
|
friend class CallbackHandler;
|
|
|
|
void audioDeviceIOCallbackInt (const float** inputChannelData,
|
|
int totalNumInputChannels,
|
|
float** outputChannelData,
|
|
int totalNumOutputChannels,
|
|
int numSamples);
|
|
void audioDeviceAboutToStartInt (AudioIODevice* const device);
|
|
void audioDeviceStoppedInt();
|
|
|
|
void handleIncomingMidiMessageInt (MidiInput* source, const MidiMessage& message);
|
|
|
|
const String restartDevice (int blockSizeToUse, double sampleRateToUse,
|
|
const BitArray& ins, const BitArray& outs);
|
|
void stopDevice();
|
|
|
|
void updateXml();
|
|
|
|
void createDeviceTypesIfNeeded();
|
|
void scanDevicesIfNeeded();
|
|
void deleteCurrentDevice();
|
|
double chooseBestSampleRate (double preferred) const;
|
|
void insertDefaultDeviceNames (AudioDeviceSetup& setup) const;
|
|
|
|
AudioIODeviceType* findType (const String& inputName, const String& outputName);
|
|
|
|
AudioDeviceManager (const AudioDeviceManager&);
|
|
const AudioDeviceManager& operator= (const AudioDeviceManager&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioDeviceManager.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOIODEVICE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MIDIINPUT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MIDIOUTPUT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_SAMPLER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Sampler.h *********/
|
|
#ifndef __JUCE_SAMPLER_JUCEHEADER__
|
|
#define __JUCE_SAMPLER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Synthesiser.h *********/
|
|
#ifndef __JUCE_SYNTHESISER_JUCEHEADER__
|
|
#define __JUCE_SYNTHESISER_JUCEHEADER__
|
|
|
|
/**
|
|
Describes one of the sounds that a Synthesiser can play.
|
|
|
|
A synthesiser can contain one or more sounds, and a sound can choose which
|
|
midi notes and channels can trigger it.
|
|
|
|
The SynthesiserSound is a passive class that just describes what the sound is -
|
|
the actual audio rendering for a sound is done by a SynthesiserVoice. This allows
|
|
more than one SynthesiserVoice to play the same sound at the same time.
|
|
|
|
@see Synthesiser, SynthesiserVoice
|
|
*/
|
|
class JUCE_API SynthesiserSound : public ReferenceCountedObject
|
|
{
|
|
protected:
|
|
|
|
SynthesiserSound();
|
|
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~SynthesiserSound();
|
|
|
|
/** Returns true if this sound should be played when a given midi note is pressed.
|
|
|
|
The Synthesiser will use this information when deciding which sounds to trigger
|
|
for a given note.
|
|
*/
|
|
virtual bool appliesToNote (const int midiNoteNumber) = 0;
|
|
|
|
/** Returns true if the sound should be triggered by midi events on a given channel.
|
|
|
|
The Synthesiser will use this information when deciding which sounds to trigger
|
|
for a given note.
|
|
*/
|
|
virtual bool appliesToChannel (const int midiChannel) = 0;
|
|
|
|
/**
|
|
*/
|
|
typedef ReferenceCountedObjectPtr <SynthesiserSound> Ptr;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
};
|
|
|
|
/**
|
|
Represents a voice that a Synthesiser can use to play a SynthesiserSound.
|
|
|
|
A voice plays a single sound at a time, and a synthesiser holds an array of
|
|
voices so that it can play polyphonically.
|
|
|
|
@see Synthesiser, SynthesiserSound
|
|
*/
|
|
class JUCE_API SynthesiserVoice
|
|
{
|
|
public:
|
|
|
|
/** Creates a voice. */
|
|
SynthesiserVoice();
|
|
|
|
/** Destructor. */
|
|
virtual ~SynthesiserVoice();
|
|
|
|
/** Returns the midi note that this voice is currently playing.
|
|
|
|
Returns a value less than 0 if no note is playing.
|
|
*/
|
|
int getCurrentlyPlayingNote() const throw() { return currentlyPlayingNote; }
|
|
|
|
/** Returns the sound that this voice is currently playing.
|
|
|
|
Returns 0 if it's not playing.
|
|
*/
|
|
const SynthesiserSound::Ptr getCurrentlyPlayingSound() const throw() { return currentlyPlayingSound; }
|
|
|
|
/** Must return true if this voice object is capable of playing the given sound.
|
|
|
|
If there are different classes of sound, and different classes of voice, a voice can
|
|
choose which ones it wants to take on.
|
|
|
|
A typical implementation of this method may just return true if there's only one type
|
|
of voice and sound, or it might check the type of the sound object passed-in and
|
|
see if it's one that it understands.
|
|
*/
|
|
virtual bool canPlaySound (SynthesiserSound* sound) = 0;
|
|
|
|
/** Called to start a new note.
|
|
|
|
This will be called during the rendering callback, so must be fast and thread-safe.
|
|
*/
|
|
virtual void startNote (const int midiNoteNumber,
|
|
const float velocity,
|
|
SynthesiserSound* sound,
|
|
const int currentPitchWheelPosition) = 0;
|
|
|
|
/** Called to stop a note.
|
|
|
|
This will be called during the rendering callback, so must be fast and thread-safe.
|
|
|
|
If allowTailOff is false or the voice doesn't want to tail-off, then it must stop all
|
|
sound immediately, and must call clearCurrentNote() to reset the state of this voice
|
|
and allow the synth to reassign it another sound.
|
|
|
|
If allowTailOff is true and the voice decides to do a tail-off, then it's allowed to
|
|
begin fading out its sound, and it can stop playing until it's finished. As soon as it
|
|
finishes playing (during the rendering callback), it must make sure that it calls
|
|
clearCurrentNote().
|
|
*/
|
|
virtual void stopNote (const bool allowTailOff) = 0;
|
|
|
|
/** Called to let the voice know that the pitch wheel has been moved.
|
|
|
|
This will be called during the rendering callback, so must be fast and thread-safe.
|
|
*/
|
|
virtual void pitchWheelMoved (const int newValue) = 0;
|
|
|
|
/** Called to let the voice know that a midi controller has been moved.
|
|
|
|
This will be called during the rendering callback, so must be fast and thread-safe.
|
|
*/
|
|
virtual void controllerMoved (const int controllerNumber,
|
|
const int newValue) = 0;
|
|
|
|
/** Renders the next block of data for this voice.
|
|
|
|
The output audio data must be added to the current contents of the buffer provided.
|
|
Only the region of the buffer between startSample and (startSample + numSamples)
|
|
should be altered by this method.
|
|
|
|
If the voice is currently silent, it should just return without doing anything.
|
|
|
|
If the sound that the voice is playing finishes during the course of this rendered
|
|
block, it must call clearCurrentNote(), to tell the synthesiser that it has finished.
|
|
|
|
The size of the blocks that are rendered can change each time it is called, and may
|
|
involve rendering as little as 1 sample at a time. In between rendering callbacks,
|
|
the voice's methods will be called to tell it about note and controller events.
|
|
*/
|
|
virtual void renderNextBlock (AudioSampleBuffer& outputBuffer,
|
|
int startSample,
|
|
int numSamples) = 0;
|
|
|
|
/** Returns true if the voice is currently playing a sound which is mapped to the given
|
|
midi channel.
|
|
|
|
If it's not currently playing, this will return false.
|
|
*/
|
|
bool isPlayingChannel (const int midiChannel) const;
|
|
|
|
/** Changes the voice's reference sample rate.
|
|
|
|
The rate is set so that subclasses know the output rate and can set their pitch
|
|
accordingly.
|
|
|
|
This method is called by the synth, and subclasses can access the current rate with
|
|
the currentSampleRate member.
|
|
*/
|
|
void setCurrentPlaybackSampleRate (const double newRate);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
/** Returns the current target sample rate at which rendering is being done.
|
|
|
|
This is available for subclasses so they can pitch things correctly.
|
|
*/
|
|
double getSampleRate() const throw() { return currentSampleRate; }
|
|
|
|
/** Resets the state of this voice after a sound has finished playing.
|
|
|
|
The subclass must call this when it finishes playing a note and becomes available
|
|
to play new ones.
|
|
|
|
It must either call it in the stopNote() method, or if the voice is tailing off,
|
|
then it should call it later during the renderNextBlock method, as soon as it
|
|
finishes its tail-off.
|
|
|
|
It can also be called at any time during the render callback if the sound happens
|
|
to have finished, e.g. if it's playing a sample and the sample finishes.
|
|
*/
|
|
void clearCurrentNote();
|
|
|
|
private:
|
|
|
|
friend class Synthesiser;
|
|
|
|
double currentSampleRate;
|
|
int currentlyPlayingNote;
|
|
uint32 noteOnTime;
|
|
SynthesiserSound::Ptr currentlyPlayingSound;
|
|
};
|
|
|
|
/**
|
|
Base class for a musical device that can play sounds.
|
|
|
|
To create a synthesiser, you'll need to create a subclass of SynthesiserSound
|
|
to describe each sound available to your synth, and a subclass of SynthesiserVoice
|
|
which can play back one of these sounds.
|
|
|
|
Then you can use the addVoice() and addSound() methods to give the synthesiser a
|
|
set of sounds, and a set of voices it can use to play them. If you only give it
|
|
one voice it will be monophonic - the more voices it has, the more polyphony it'll
|
|
have available.
|
|
|
|
Then repeatedly call the renderNextBlock() method to produce the audio. Any midi
|
|
events that go in will be scanned for note on/off messages, and these are used to
|
|
start and stop the voices playing the appropriate sounds.
|
|
|
|
While it's playing, you can also cause notes to be triggered by calling the noteOn(),
|
|
noteOff() and other controller methods.
|
|
|
|
Before rendering, be sure to call the setCurrentPlaybackSampleRate() to tell it
|
|
what the target playback rate is. This value is passed on to the voices so that
|
|
they can pitch their output correctly.
|
|
*/
|
|
class JUCE_API Synthesiser
|
|
{
|
|
public:
|
|
|
|
/** Creates a new synthesiser.
|
|
|
|
You'll need to add some sounds and voices before it'll make any sound..
|
|
*/
|
|
Synthesiser();
|
|
|
|
/** Destructor. */
|
|
virtual ~Synthesiser();
|
|
|
|
/** Deletes all voices. */
|
|
void clearVoices();
|
|
|
|
/** Returns the number of voices that have been added. */
|
|
int getNumVoices() const throw() { return voices.size(); }
|
|
|
|
/** Returns one of the voices that have been added. */
|
|
SynthesiserVoice* getVoice (const int index) const throw();
|
|
|
|
/** Adds a new voice to the synth.
|
|
|
|
All the voices should be the same class of object and are treated equally.
|
|
|
|
The object passed in will be managed by the synthesiser, which will delete
|
|
it later on when no longer needed. The caller should not retain a pointer to the
|
|
voice.
|
|
*/
|
|
void addVoice (SynthesiserVoice* const newVoice);
|
|
|
|
/** Deletes one of the voices. */
|
|
void removeVoice (const int index);
|
|
|
|
/** Deletes all sounds. */
|
|
void clearSounds();
|
|
|
|
/** Returns the number of sounds that have been added to the synth. */
|
|
int getNumSounds() const throw() { return sounds.size(); }
|
|
|
|
/** Returns one of the sounds. */
|
|
SynthesiserSound* getSound (const int index) const throw() { return sounds [index]; }
|
|
|
|
/** Adds a new sound to the synthesiser.
|
|
|
|
The object passed in is reference counted, so will be deleted when it is removed
|
|
from the synthesiser, and when no voices are still using it.
|
|
*/
|
|
void addSound (const SynthesiserSound::Ptr& newSound);
|
|
|
|
/** Removes and deletes one of the sounds. */
|
|
void removeSound (const int index);
|
|
|
|
/** If set to true, then the synth will try to take over an existing voice if
|
|
it runs out and needs to play another note.
|
|
|
|
The value of this boolean is passed into findFreeVoice(), so the result will
|
|
depend on the implementation of this method.
|
|
*/
|
|
void setNoteStealingEnabled (const bool shouldStealNotes);
|
|
|
|
/** Returns true if note-stealing is enabled.
|
|
@see setNoteStealingEnabled
|
|
*/
|
|
bool isNoteStealingEnabled() const throw() { return shouldStealNotes; }
|
|
|
|
/** Triggers a note-on event.
|
|
|
|
The default method here will find all the sounds that want to be triggered by
|
|
this note/channel. For each sound, it'll try to find a free voice, and use the
|
|
voice to start playing the sound.
|
|
|
|
Subclasses might want to override this if they need a more complex algorithm.
|
|
|
|
This method will be called automatically according to the midi data passed into
|
|
renderNextBlock(), but may be called explicitly too.
|
|
*/
|
|
virtual void noteOn (const int midiChannel,
|
|
const int midiNoteNumber,
|
|
const float velocity);
|
|
|
|
/** Triggers a note-off event.
|
|
|
|
This will turn off any voices that are playing a sound for the given note/channel.
|
|
|
|
If allowTailOff is true, the voices will be allowed to fade out the notes gracefully
|
|
(if they can do). If this is false, the notes will all be cut off immediately.
|
|
|
|
This method will be called automatically according to the midi data passed into
|
|
renderNextBlock(), but may be called explicitly too.
|
|
*/
|
|
virtual void noteOff (const int midiChannel,
|
|
const int midiNoteNumber,
|
|
const bool allowTailOff);
|
|
|
|
/** Turns off all notes.
|
|
|
|
This will turn off any voices that are playing a sound on the given midi channel.
|
|
|
|
If midiChannel is 0 or less, then all voices will be turned off, regardless of
|
|
which channel they're playing.
|
|
|
|
If allowTailOff is true, the voices will be allowed to fade out the notes gracefully
|
|
(if they can do). If this is false, the notes will all be cut off immediately.
|
|
|
|
This method will be called automatically according to the midi data passed into
|
|
renderNextBlock(), but may be called explicitly too.
|
|
*/
|
|
virtual void allNotesOff (const int midiChannel,
|
|
const bool allowTailOff);
|
|
|
|
/** Sends a pitch-wheel message.
|
|
|
|
This will send a pitch-wheel message to any voices that are playing sounds on
|
|
the given midi channel.
|
|
|
|
This method will be called automatically according to the midi data passed into
|
|
renderNextBlock(), but may be called explicitly too.
|
|
|
|
@param midiChannel the midi channel for the event
|
|
@param wheelValue the wheel position, from 0 to 0x3fff, as returned by MidiMessage::getPitchWheelValue()
|
|
*/
|
|
virtual void handlePitchWheel (const int midiChannel,
|
|
const int wheelValue);
|
|
|
|
/** Sends a midi controller message.
|
|
|
|
This will send a midi controller message to any voices that are playing sounds on
|
|
the given midi channel.
|
|
|
|
This method will be called automatically according to the midi data passed into
|
|
renderNextBlock(), but may be called explicitly too.
|
|
|
|
@param midiChannel the midi channel for the event
|
|
@param controllerNumber the midi controller type, as returned by MidiMessage::getControllerNumber()
|
|
@param controllerValue the midi controller value, between 0 and 127, as returned by MidiMessage::getControllerValue()
|
|
*/
|
|
virtual void handleController (const int midiChannel,
|
|
const int controllerNumber,
|
|
const int controllerValue);
|
|
|
|
/** Tells the synthesiser what the sample rate is for the audio it's being used to
|
|
render.
|
|
|
|
This value is propagated to the voices so that they can use it to render the correct
|
|
pitches.
|
|
*/
|
|
void setCurrentPlaybackSampleRate (const double sampleRate);
|
|
|
|
/** Creates the next block of audio output.
|
|
|
|
This will process the next numSamples of data from all the voices, and add that output
|
|
to the audio block supplied, starting from the offset specified. Note that the
|
|
data will be added to the current contents of the buffer, so you should clear it
|
|
before calling this method if necessary.
|
|
|
|
The midi events in the inputMidi buffer are parsed for note and controller events,
|
|
and these are used to trigger the voices. Note that the startSample offset applies
|
|
both to the audio output buffer and the midi input buffer, so any midi events
|
|
with timestamps outside the specified region will be ignored.
|
|
*/
|
|
void renderNextBlock (AudioSampleBuffer& outputAudio,
|
|
const MidiBuffer& inputMidi,
|
|
int startSample,
|
|
int numSamples);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
/** This is used to control access to the rendering callback and the note trigger methods. */
|
|
CriticalSection lock;
|
|
|
|
OwnedArray <SynthesiserVoice> voices;
|
|
ReferenceCountedArray <SynthesiserSound> sounds;
|
|
|
|
/** The last pitch-wheel values for each midi channel. */
|
|
int lastPitchWheelValues [16];
|
|
|
|
/** Searches through the voices to find one that's not currently playing, and which
|
|
can play the given sound.
|
|
|
|
Returns 0 if all voices are busy and stealing isn't enabled.
|
|
|
|
This can be overridden to implement custom voice-stealing algorithms.
|
|
*/
|
|
virtual SynthesiserVoice* findFreeVoice (SynthesiserSound* soundToPlay,
|
|
const bool stealIfNoneAvailable) const;
|
|
|
|
/** Starts a specified voice playing a particular sound.
|
|
|
|
You'll probably never need to call this, it's used internally by noteOn(), but
|
|
may be needed by subclasses for custom behaviours.
|
|
*/
|
|
void startVoice (SynthesiserVoice* const voice,
|
|
SynthesiserSound* const sound,
|
|
const int midiChannel,
|
|
const int midiNoteNumber,
|
|
const float velocity);
|
|
|
|
/** xxx Temporary method here to cause a compiler error - note the new parameters for this method. */
|
|
int findFreeVoice (const bool) const { return 0; }
|
|
|
|
private:
|
|
double sampleRate;
|
|
uint32 lastNoteOnCounter;
|
|
bool shouldStealNotes;
|
|
|
|
Synthesiser (const Synthesiser&);
|
|
const Synthesiser& operator= (const Synthesiser&);
|
|
};
|
|
|
|
#endif // __JUCE_SYNTHESISER_JUCEHEADER__
|
|
/********* End of inlined file: juce_Synthesiser.h *********/
|
|
|
|
/**
|
|
A subclass of SynthesiserSound that represents a sampled audio clip.
|
|
|
|
This is a pretty basic sampler, and just attempts to load the whole audio stream
|
|
into memory.
|
|
|
|
To use it, create a Synthesiser, add some SamplerVoice objects to it, then
|
|
give it some SampledSound objects to play.
|
|
|
|
@see SamplerVoice, Synthesiser, SynthesiserSound
|
|
*/
|
|
class JUCE_API SamplerSound : public SynthesiserSound
|
|
{
|
|
public:
|
|
|
|
/** Creates a sampled sound from an audio reader.
|
|
|
|
This will attempt to load the audio from the source into memory and store
|
|
it in this object.
|
|
|
|
@param name a name for the sample
|
|
@param source the audio to load. This object can be safely deleted by the
|
|
caller after this constructor returns
|
|
@param midiNotes the set of midi keys that this sound should be played on. This
|
|
is used by the SynthesiserSound::appliesToNote() method
|
|
@param midiNoteForNormalPitch the midi note at which the sample should be played
|
|
with its natural rate. All other notes will be pitched
|
|
up or down relative to this one
|
|
@param attackTimeSecs the attack (fade-in) time, in seconds
|
|
@param releaseTimeSecs the decay (fade-out) time, in seconds
|
|
@param maxSampleLengthSeconds a maximum length of audio to read from the audio
|
|
source, in seconds
|
|
*/
|
|
SamplerSound (const String& name,
|
|
AudioFormatReader& source,
|
|
const BitArray& midiNotes,
|
|
const int midiNoteForNormalPitch,
|
|
const double attackTimeSecs,
|
|
const double releaseTimeSecs,
|
|
const double maxSampleLengthSeconds);
|
|
|
|
/** Destructor. */
|
|
~SamplerSound();
|
|
|
|
/** Returns the sample's name */
|
|
const String& getName() const throw() { return name; }
|
|
|
|
/** Returns the audio sample data.
|
|
This could be 0 if there was a problem loading it.
|
|
*/
|
|
AudioSampleBuffer* getAudioData() const throw() { return data; }
|
|
|
|
bool appliesToNote (const int midiNoteNumber);
|
|
bool appliesToChannel (const int midiChannel);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class SamplerVoice;
|
|
|
|
String name;
|
|
AudioSampleBuffer* data;
|
|
double sourceSampleRate;
|
|
BitArray midiNotes;
|
|
int length, attackSamples, releaseSamples;
|
|
int midiRootNote;
|
|
};
|
|
|
|
/**
|
|
A subclass of SynthesiserVoice that can play a SamplerSound.
|
|
|
|
To use it, create a Synthesiser, add some SamplerVoice objects to it, then
|
|
give it some SampledSound objects to play.
|
|
|
|
@see SamplerSound, Synthesiser, SynthesiserVoice
|
|
*/
|
|
class JUCE_API SamplerVoice : public SynthesiserVoice
|
|
{
|
|
public:
|
|
|
|
/** Creates a SamplerVoice.
|
|
*/
|
|
SamplerVoice();
|
|
|
|
/** Destructor. */
|
|
~SamplerVoice();
|
|
|
|
bool canPlaySound (SynthesiserSound* sound);
|
|
|
|
void startNote (const int midiNoteNumber,
|
|
const float velocity,
|
|
SynthesiserSound* sound,
|
|
const int currentPitchWheelPosition);
|
|
|
|
void stopNote (const bool allowTailOff);
|
|
|
|
void pitchWheelMoved (const int newValue);
|
|
void controllerMoved (const int controllerNumber,
|
|
const int newValue);
|
|
|
|
void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
double pitchRatio;
|
|
double sourceSamplePosition;
|
|
float lgain, rgain, attackReleaseLevel, attackDelta, releaseDelta;
|
|
bool isInAttack, isInRelease;
|
|
};
|
|
|
|
#endif // __JUCE_SAMPLER_JUCEHEADER__
|
|
/********* End of inlined file: juce_Sampler.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_SYNTHESISER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioUnitPluginFormat.h *********/
|
|
#ifndef __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__
|
|
#define __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__
|
|
|
|
#if JUCE_PLUGINHOST_AU && JUCE_MAC
|
|
|
|
/**
|
|
Implements a plugin format manager for AudioUnits.
|
|
*/
|
|
class JUCE_API AudioUnitPluginFormat : public AudioPluginFormat
|
|
{
|
|
public:
|
|
|
|
AudioUnitPluginFormat();
|
|
~AudioUnitPluginFormat();
|
|
|
|
const String getName() const { return "AudioUnit"; }
|
|
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
|
|
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
|
|
bool fileMightContainThisPluginType (const String& fileOrIdentifier);
|
|
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier);
|
|
const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive);
|
|
bool doesPluginStillExist (const PluginDescription& desc);
|
|
const FileSearchPath getDefaultLocationsToSearch();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
AudioUnitPluginFormat (const AudioUnitPluginFormat&);
|
|
const AudioUnitPluginFormat& operator= (const AudioUnitPluginFormat&);
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif // __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioUnitPluginFormat.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DirectXPluginFormat.h *********/
|
|
#ifndef __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__
|
|
#define __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__
|
|
|
|
#if JUCE_PLUGINHOST_DX && JUCE_WIN32
|
|
|
|
// Sorry, this file is just a placeholder at the moment!...
|
|
|
|
/**
|
|
Implements a plugin format manager for DirectX plugins.
|
|
*/
|
|
class JUCE_API DirectXPluginFormat : public AudioPluginFormat
|
|
{
|
|
public:
|
|
|
|
DirectXPluginFormat();
|
|
~DirectXPluginFormat();
|
|
|
|
const String getName() const { return "DirectX"; }
|
|
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
|
|
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
|
|
bool fileMightContainThisPluginType (const String& fileOrIdentifier);
|
|
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) { return fileOrIdentifier; }
|
|
const FileSearchPath getDefaultLocationsToSearch();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
DirectXPluginFormat (const DirectXPluginFormat&);
|
|
const DirectXPluginFormat& operator= (const DirectXPluginFormat&);
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif // __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__
|
|
/********* End of inlined file: juce_DirectXPluginFormat.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_LADSPAPluginFormat.h *********/
|
|
#ifndef __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__
|
|
#define __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__
|
|
|
|
#if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX
|
|
|
|
// Sorry, this file is just a placeholder at the moment!...
|
|
|
|
/**
|
|
Implements a plugin format manager for DirectX plugins.
|
|
*/
|
|
class JUCE_API LADSPAPluginFormat : public AudioPluginFormat
|
|
{
|
|
public:
|
|
|
|
LADSPAPluginFormat();
|
|
~LADSPAPluginFormat();
|
|
|
|
const String getName() const { return "LADSPA"; }
|
|
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
|
|
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
|
|
bool fileMightContainThisPluginType (const String& fileOrIdentifier);
|
|
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) { return fileOrIdentifier; }
|
|
const FileSearchPath getDefaultLocationsToSearch();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
LADSPAPluginFormat (const LADSPAPluginFormat&);
|
|
const LADSPAPluginFormat& operator= (const LADSPAPluginFormat&);
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif // __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__
|
|
/********* End of inlined file: juce_LADSPAPluginFormat.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_VSTMidiEventList.h *********/
|
|
#ifdef __aeffect__
|
|
|
|
#ifndef __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
|
#define __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
|
|
|
/** Holds a set of VSTMidiEvent objects and makes it easy to add
|
|
events to the list.
|
|
|
|
This is used by both the VST hosting code and the plugin wrapper.
|
|
*/
|
|
class VSTMidiEventList
|
|
{
|
|
public:
|
|
|
|
VSTMidiEventList()
|
|
: events (0), numEventsUsed (0), numEventsAllocated (0)
|
|
{
|
|
}
|
|
|
|
~VSTMidiEventList()
|
|
{
|
|
freeEvents();
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
numEventsUsed = 0;
|
|
|
|
if (events != 0)
|
|
events->numEvents = 0;
|
|
}
|
|
|
|
void addEvent (const void* const midiData, const int numBytes, const int frameOffset)
|
|
{
|
|
ensureSize (numEventsUsed + 1);
|
|
|
|
VstMidiEvent* const e = (VstMidiEvent*) (events->events [numEventsUsed]);
|
|
events->numEvents = ++numEventsUsed;
|
|
|
|
if (numBytes <= 4)
|
|
{
|
|
if (e->type == kVstSysExType)
|
|
{
|
|
juce_free (((VstMidiSysexEvent*) e)->sysexDump);
|
|
e->type = kVstMidiType;
|
|
e->byteSize = sizeof (VstMidiEvent);
|
|
e->noteLength = 0;
|
|
e->noteOffset = 0;
|
|
e->detune = 0;
|
|
e->noteOffVelocity = 0;
|
|
}
|
|
|
|
e->deltaFrames = frameOffset;
|
|
memcpy (e->midiData, midiData, numBytes);
|
|
}
|
|
else
|
|
{
|
|
VstMidiSysexEvent* const se = (VstMidiSysexEvent*) e;
|
|
|
|
if (se->type == kVstSysExType)
|
|
se->sysexDump = (char*) juce_realloc (se->sysexDump, numBytes);
|
|
else
|
|
se->sysexDump = (char*) juce_malloc (numBytes);
|
|
|
|
memcpy (se->sysexDump, midiData, numBytes);
|
|
|
|
se->type = kVstSysExType;
|
|
se->byteSize = sizeof (VstMidiSysexEvent);
|
|
se->deltaFrames = frameOffset;
|
|
se->flags = 0;
|
|
se->dumpBytes = numBytes;
|
|
se->resvd1 = 0;
|
|
se->resvd2 = 0;
|
|
}
|
|
}
|
|
|
|
// Handy method to pull the events out of an event buffer supplied by the host
|
|
// or plugin.
|
|
static void addEventsToMidiBuffer (const VstEvents* events, MidiBuffer& dest)
|
|
{
|
|
for (int i = 0; i < events->numEvents; ++i)
|
|
{
|
|
const VstEvent* const e = events->events[i];
|
|
|
|
if (e != 0)
|
|
{
|
|
if (e->type == kVstMidiType)
|
|
{
|
|
dest.addEvent ((const JUCE_NAMESPACE::uint8*) ((const VstMidiEvent*) e)->midiData,
|
|
4, e->deltaFrames);
|
|
}
|
|
else if (e->type == kVstSysExType)
|
|
{
|
|
dest.addEvent ((const JUCE_NAMESPACE::uint8*) ((const VstMidiSysexEvent*) e)->sysexDump,
|
|
(int) ((const VstMidiSysexEvent*) e)->dumpBytes,
|
|
e->deltaFrames);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ensureSize (int numEventsNeeded)
|
|
{
|
|
if (numEventsNeeded > numEventsAllocated)
|
|
{
|
|
numEventsNeeded = (numEventsNeeded + 32) & ~31;
|
|
|
|
const int size = 20 + sizeof (VstEvent*) * numEventsNeeded;
|
|
|
|
if (events == 0)
|
|
events = (VstEvents*) juce_calloc (size);
|
|
else
|
|
events = (VstEvents*) juce_realloc (events, size);
|
|
|
|
for (int i = numEventsAllocated; i < numEventsNeeded; ++i)
|
|
{
|
|
VstMidiEvent* const e = (VstMidiEvent*) juce_calloc (jmax ((int) sizeof (VstMidiEvent),
|
|
(int) sizeof (VstMidiSysexEvent)));
|
|
e->type = kVstMidiType;
|
|
e->byteSize = sizeof (VstMidiEvent);
|
|
|
|
events->events[i] = (VstEvent*) e;
|
|
}
|
|
|
|
numEventsAllocated = numEventsNeeded;
|
|
}
|
|
}
|
|
|
|
void freeEvents()
|
|
{
|
|
if (events != 0)
|
|
{
|
|
for (int i = numEventsAllocated; --i >= 0;)
|
|
{
|
|
VstMidiEvent* const e = (VstMidiEvent*) (events->events[i]);
|
|
|
|
if (e->type == kVstSysExType)
|
|
juce_free (((VstMidiSysexEvent*) e)->sysexDump);
|
|
|
|
juce_free (e);
|
|
}
|
|
|
|
juce_free (events);
|
|
events = 0;
|
|
numEventsUsed = 0;
|
|
numEventsAllocated = 0;
|
|
}
|
|
}
|
|
|
|
VstEvents* events;
|
|
|
|
private:
|
|
int numEventsUsed, numEventsAllocated;
|
|
};
|
|
|
|
#endif // __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
|
#endif // __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
|
|
/********* End of inlined file: juce_VSTMidiEventList.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_VSTPLUGINFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_VSTPluginFormat.h *********/
|
|
#ifndef __JUCE_VSTPLUGINFORMAT_JUCEHEADER__
|
|
#define __JUCE_VSTPLUGINFORMAT_JUCEHEADER__
|
|
|
|
#if JUCE_PLUGINHOST_VST
|
|
|
|
/**
|
|
Implements a plugin format manager for VSTs.
|
|
*/
|
|
class JUCE_API VSTPluginFormat : public AudioPluginFormat
|
|
{
|
|
public:
|
|
|
|
VSTPluginFormat();
|
|
~VSTPluginFormat();
|
|
|
|
const String getName() const { return "VST"; }
|
|
void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
|
|
AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
|
|
bool fileMightContainThisPluginType (const String& fileOrIdentifier);
|
|
const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier);
|
|
const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive);
|
|
bool doesPluginStillExist (const PluginDescription& desc);
|
|
const FileSearchPath getDefaultLocationsToSearch();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
VSTPluginFormat (const VSTPluginFormat&);
|
|
const VSTPluginFormat& operator= (const VSTPluginFormat&);
|
|
|
|
void recursiveFileSearch (StringArray& results, const File& dir, const bool recursive);
|
|
};
|
|
|
|
#endif
|
|
#endif // __JUCE_VSTPLUGINFORMAT_JUCEHEADER__
|
|
/********* End of inlined file: juce_VSTPluginFormat.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_KNOWNPLUGINLIST_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_PLUGINDESCRIPTION_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_PLUGINDIRECTORYSCANNER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PluginDirectoryScanner.h *********/
|
|
#ifndef __JUCE_PLUGINDIRECTORYSCANNER_JUCEHEADER__
|
|
#define __JUCE_PLUGINDIRECTORYSCANNER_JUCEHEADER__
|
|
|
|
/**
|
|
Scans a directory for plugins, and adds them to a KnownPluginList.
|
|
|
|
To use one of these, create it and call scanNextFile() repeatedly, until
|
|
it returns false.
|
|
*/
|
|
class JUCE_API PluginDirectoryScanner
|
|
{
|
|
public:
|
|
|
|
/**
|
|
Creates a scanner.
|
|
|
|
@param listToAddResultsTo this will get the new types added to it.
|
|
@param formatToLookFor this is the type of format that you want to look for
|
|
@param directoriesToSearch the path to search
|
|
@param searchRecursively true to search recursively
|
|
@param deadMansPedalFile if this isn't File::nonexistent, then it will
|
|
be used as a file to store the names of any plugins
|
|
that crash during initialisation. If there are
|
|
any plugins listed in it, then these will always
|
|
be scanned after all other possible files have
|
|
been tried - in this way, even if there's a few
|
|
dodgy plugins in your path, then a couple of rescans
|
|
will still manage to find all the proper plugins.
|
|
It's probably best to choose a file in the user's
|
|
application data directory (alongside your app's
|
|
settings file) for this. The file format it uses
|
|
is just a list of filenames of the modules that
|
|
failed.
|
|
*/
|
|
PluginDirectoryScanner (KnownPluginList& listToAddResultsTo,
|
|
AudioPluginFormat& formatToLookFor,
|
|
FileSearchPath directoriesToSearch,
|
|
const bool searchRecursively,
|
|
const File& deadMansPedalFile);
|
|
|
|
/** Destructor. */
|
|
~PluginDirectoryScanner();
|
|
|
|
/** Tries the next likely-looking file.
|
|
|
|
If dontRescanIfAlreadyInList is true, then the file will only be loaded and
|
|
re-tested if it's not already in the list, or if the file's modification
|
|
time has changed since the list was created. If dontRescanIfAlreadyInList is
|
|
false, the file will always be reloaded and tested.
|
|
|
|
Returns false when there are no more files to try.
|
|
*/
|
|
bool scanNextFile (const bool dontRescanIfAlreadyInList);
|
|
|
|
/** Returns the description of the plugin that will be scanned during the next
|
|
call to scanNextFile().
|
|
|
|
This is handy if you want to show the user which file is currently getting
|
|
scanned.
|
|
*/
|
|
const String getNextPluginFileThatWillBeScanned() const throw();
|
|
|
|
/** Returns the estimated progress, between 0 and 1.
|
|
*/
|
|
float getProgress() const { return progress; }
|
|
|
|
/** This returns a list of all the filenames of things that looked like being
|
|
a plugin file, but which failed to open for some reason.
|
|
*/
|
|
const StringArray& getFailedFiles() const throw() { return failedFiles; }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
KnownPluginList& list;
|
|
AudioPluginFormat& format;
|
|
StringArray filesOrIdentifiersToScan;
|
|
File deadMansPedalFile;
|
|
StringArray failedFiles;
|
|
int nextIndex;
|
|
float progress;
|
|
|
|
const StringArray getDeadMansPedalFile() throw();
|
|
void setDeadMansPedalFile (const StringArray& newContents) throw();
|
|
|
|
PluginDirectoryScanner (const PluginDirectoryScanner&);
|
|
const PluginDirectoryScanner& operator= (const PluginDirectoryScanner&);
|
|
};
|
|
|
|
#endif // __JUCE_PLUGINDIRECTORYSCANNER_JUCEHEADER__
|
|
/********* End of inlined file: juce_PluginDirectoryScanner.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PluginListComponent.h *********/
|
|
#ifndef __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ListBox.h *********/
|
|
#ifndef __JUCE_LISTBOX_JUCEHEADER__
|
|
#define __JUCE_LISTBOX_JUCEHEADER__
|
|
|
|
class ListViewport;
|
|
|
|
/**
|
|
A subclass of this is used to drive a ListBox.
|
|
|
|
@see ListBox
|
|
*/
|
|
class JUCE_API ListBoxModel
|
|
{
|
|
public:
|
|
|
|
/** Destructor. */
|
|
virtual ~ListBoxModel() {}
|
|
|
|
/** This has to return the number of items in the list.
|
|
|
|
@see ListBox::getNumRows()
|
|
*/
|
|
virtual int getNumRows() = 0;
|
|
|
|
/** This method must be implemented to draw a row of the list.
|
|
*/
|
|
virtual void paintListBoxItem (int rowNumber,
|
|
Graphics& g,
|
|
int width, int height,
|
|
bool rowIsSelected) = 0;
|
|
|
|
/** This is used to create or update a custom component to go in a row of the list.
|
|
|
|
Any row may contain a custom component, or can just be drawn with the paintListBoxItem() method
|
|
and handle mouse clicks with listBoxItemClicked().
|
|
|
|
This method will be called whenever a custom component might need to be updated - e.g.
|
|
when the table is changed, or TableListBox::updateContent() is called.
|
|
|
|
If you don't need a custom component for the specified row, then return 0.
|
|
|
|
If you do want a custom component, and the existingComponentToUpdate is null, then
|
|
this method must create a suitable new component and return it.
|
|
|
|
If the existingComponentToUpdate is non-null, it will be a pointer to a component previously created
|
|
by this method. In this case, the method must either update it to make sure it's correctly representing
|
|
the given row (which may be different from the one that the component was created for), or it can
|
|
delete this component and return a new one.
|
|
|
|
The component that your method returns will be deleted by the ListBox when it is no longer needed.
|
|
*/
|
|
virtual Component* refreshComponentForRow (int rowNumber, bool isRowSelected,
|
|
Component* existingComponentToUpdate);
|
|
|
|
/** This can be overridden to react to the user clicking on a row.
|
|
|
|
@see listBoxItemDoubleClicked
|
|
*/
|
|
virtual void listBoxItemClicked (int row, const MouseEvent& e);
|
|
|
|
/** This can be overridden to react to the user double-clicking on a row.
|
|
|
|
@see listBoxItemClicked
|
|
*/
|
|
virtual void listBoxItemDoubleClicked (int row, const MouseEvent& e);
|
|
|
|
/** This can be overridden to react to the user double-clicking on a part of the list where
|
|
there are no rows.
|
|
|
|
@see listBoxItemClicked
|
|
*/
|
|
virtual void backgroundClicked();
|
|
|
|
/** Override this to be informed when rows are selected or deselected.
|
|
|
|
This will be called whenever a row is selected or deselected. If a range of
|
|
rows is selected all at once, this will just be called once for that event.
|
|
|
|
@param lastRowSelected the last row that the user selected. If no
|
|
rows are currently selected, this may be -1.
|
|
*/
|
|
virtual void selectedRowsChanged (int lastRowSelected);
|
|
|
|
/** Override this to be informed when the delete key is pressed.
|
|
|
|
If no rows are selected when they press the key, this won't be called.
|
|
|
|
@param lastRowSelected the last row that had been selected when they pressed the
|
|
key - if there are multiple selections, this might not be
|
|
very useful
|
|
*/
|
|
virtual void deleteKeyPressed (int lastRowSelected);
|
|
|
|
/** Override this to be informed when the return key is pressed.
|
|
|
|
If no rows are selected when they press the key, this won't be called.
|
|
|
|
@param lastRowSelected the last row that had been selected when they pressed the
|
|
key - if there are multiple selections, this might not be
|
|
very useful
|
|
*/
|
|
virtual void returnKeyPressed (int lastRowSelected);
|
|
|
|
/** Override this to be informed when the list is scrolled.
|
|
|
|
This might be caused by the user moving the scrollbar, or by programmatic changes
|
|
to the list position.
|
|
*/
|
|
virtual void listWasScrolled();
|
|
|
|
/** To allow rows from your list to be dragged-and-dropped, implement this method.
|
|
|
|
If this returns a non-empty name then when the user drags a row, the listbox will
|
|
try to find a DragAndDropContainer in its parent hierarchy, and will use it to trigger
|
|
a drag-and-drop operation, using this string as the source description, with the listbox
|
|
itself as the source component.
|
|
|
|
@see DragAndDropContainer::startDragging
|
|
*/
|
|
virtual const String getDragSourceDescription (const SparseSet<int>& currentlySelectedRows);
|
|
};
|
|
|
|
/**
|
|
A list of items that can be scrolled vertically.
|
|
|
|
To create a list, you'll need to create a subclass of ListBoxModel. This can
|
|
either paint each row of the list and respond to events via callbacks, or for
|
|
more specialised tasks, it can supply a custom component to fill each row.
|
|
|
|
@see ComboBox, TableListBox
|
|
*/
|
|
class JUCE_API ListBox : public Component,
|
|
public SettableTooltipClient
|
|
{
|
|
public:
|
|
|
|
/** Creates a ListBox.
|
|
|
|
The model pointer passed-in can be null, in which case you can set it later
|
|
with setModel().
|
|
*/
|
|
ListBox (const String& componentName,
|
|
ListBoxModel* const model);
|
|
|
|
/** Destructor. */
|
|
~ListBox();
|
|
|
|
/** Changes the current data model to display. */
|
|
void setModel (ListBoxModel* const newModel);
|
|
|
|
/** Returns the current list model. */
|
|
ListBoxModel* getModel() const throw() { return model; }
|
|
|
|
/** Causes the list to refresh its content.
|
|
|
|
Call this when the number of rows in the list changes, or if you want it
|
|
to call refreshComponentForRow() on all the row components.
|
|
|
|
Be careful not to call it from a different thread, though, as it's not
|
|
thread-safe.
|
|
*/
|
|
void updateContent();
|
|
|
|
/** Turns on multiple-selection of rows.
|
|
|
|
By default this is disabled.
|
|
|
|
When your row component gets clicked you'll need to call the
|
|
selectRowsBasedOnModifierKeys() method to tell the list that it's been
|
|
clicked and to get it to do the appropriate selection based on whether
|
|
the ctrl/shift keys are held down.
|
|
*/
|
|
void setMultipleSelectionEnabled (bool shouldBeEnabled);
|
|
|
|
/** Makes the list react to mouse moves by selecting the row that the mouse if over.
|
|
|
|
This function is here primarily for the ComboBox class to use, but might be
|
|
useful for some other purpose too.
|
|
*/
|
|
void setMouseMoveSelectsRows (bool shouldSelect);
|
|
|
|
/** Selects a row.
|
|
|
|
If the row is already selected, this won't do anything.
|
|
|
|
@param rowNumber the row to select
|
|
@param dontScrollToShowThisRow if true, the list's position won't change; if false and
|
|
the selected row is off-screen, it'll scroll to make
|
|
sure that row is on-screen
|
|
@param deselectOthersFirst if true and there are multiple selections, these will
|
|
first be deselected before this item is selected
|
|
@see isRowSelected, selectRowsBasedOnModifierKeys, flipRowSelection, deselectRow,
|
|
deselectAllRows, selectRangeOfRows
|
|
*/
|
|
void selectRow (const int rowNumber,
|
|
bool dontScrollToShowThisRow = false,
|
|
bool deselectOthersFirst = true);
|
|
|
|
/** Selects a set of rows.
|
|
|
|
This will add these rows to the current selection, so you might need to
|
|
clear the current selection first with deselectAllRows()
|
|
|
|
@param firstRow the first row to select (inclusive)
|
|
@param lastRow the last row to select (inclusive)
|
|
*/
|
|
void selectRangeOfRows (int firstRow,
|
|
int lastRow);
|
|
|
|
/** Deselects a row.
|
|
|
|
If it's not currently selected, this will do nothing.
|
|
|
|
@see selectRow, deselectAllRows
|
|
*/
|
|
void deselectRow (const int rowNumber);
|
|
|
|
/** Deselects any currently selected rows.
|
|
|
|
@see deselectRow
|
|
*/
|
|
void deselectAllRows();
|
|
|
|
/** Selects or deselects a row.
|
|
|
|
If the row's currently selected, this deselects it, and vice-versa.
|
|
*/
|
|
void flipRowSelection (const int rowNumber);
|
|
|
|
/** Returns a sparse set indicating the rows that are currently selected.
|
|
|
|
@see setSelectedRows
|
|
*/
|
|
const SparseSet<int> getSelectedRows() const;
|
|
|
|
/** Sets the rows that should be selected, based on an explicit set of ranges.
|
|
|
|
If sendNotificationEventToModel is true, the ListBoxModel::selectedRowsChanged()
|
|
method will be called. If it's false, no notification will be sent to the model.
|
|
|
|
@see getSelectedRows
|
|
*/
|
|
void setSelectedRows (const SparseSet<int>& setOfRowsToBeSelected,
|
|
const bool sendNotificationEventToModel = true);
|
|
|
|
/** Checks whether a row is selected.
|
|
*/
|
|
bool isRowSelected (const int rowNumber) const;
|
|
|
|
/** Returns the number of rows that are currently selected.
|
|
|
|
@see getSelectedRow, isRowSelected, getLastRowSelected
|
|
*/
|
|
int getNumSelectedRows() const;
|
|
|
|
/** Returns the row number of a selected row.
|
|
|
|
This will return the row number of the Nth selected row. The row numbers returned will
|
|
be sorted in order from low to high.
|
|
|
|
@param index the index of the selected row to return, (from 0 to getNumSelectedRows() - 1)
|
|
@returns the row number, or -1 if the index was out of range or if there aren't any rows
|
|
selected
|
|
@see getNumSelectedRows, isRowSelected, getLastRowSelected
|
|
*/
|
|
int getSelectedRow (const int index = 0) const;
|
|
|
|
/** Returns the last row that the user selected.
|
|
|
|
This isn't the same as the highest row number that is currently selected - if the user
|
|
had multiply-selected rows 10, 5 and then 6 in that order, this would return 6.
|
|
|
|
If nothing is selected, it will return -1.
|
|
*/
|
|
int getLastRowSelected() const;
|
|
|
|
/** Multiply-selects rows based on the modifier keys.
|
|
|
|
If no modifier keys are down, this will select the given row and
|
|
deselect any others.
|
|
|
|
If the ctrl (or command on the Mac) key is down, it'll flip the
|
|
state of the selected row.
|
|
|
|
If the shift key is down, it'll select up to the given row from the
|
|
last row selected.
|
|
|
|
@see selectRow
|
|
*/
|
|
void selectRowsBasedOnModifierKeys (const int rowThatWasClickedOn,
|
|
const ModifierKeys& modifiers);
|
|
|
|
/** Scrolls the list to a particular position.
|
|
|
|
The proportion is between 0 and 1.0, so 0 scrolls to the top of the list,
|
|
1.0 scrolls to the bottom.
|
|
|
|
If the total number of rows all fit onto the screen at once, then this
|
|
method won't do anything.
|
|
|
|
@see getVerticalPosition
|
|
*/
|
|
void setVerticalPosition (const double newProportion);
|
|
|
|
/** Returns the current vertical position as a proportion of the total.
|
|
|
|
This can be used in conjunction with setVerticalPosition() to save and restore
|
|
the list's position. It returns a value in the range 0 to 1.
|
|
|
|
@see setVerticalPosition
|
|
*/
|
|
double getVerticalPosition() const;
|
|
|
|
/** Scrolls if necessary to make sure that a particular row is visible.
|
|
*/
|
|
void scrollToEnsureRowIsOnscreen (const int row);
|
|
|
|
/** Returns a pointer to the scrollbar.
|
|
|
|
(Unlikely to be useful for most people).
|
|
*/
|
|
ScrollBar* getVerticalScrollBar() const throw();
|
|
|
|
/** Returns a pointer to the scrollbar.
|
|
|
|
(Unlikely to be useful for most people).
|
|
*/
|
|
ScrollBar* getHorizontalScrollBar() const throw();
|
|
|
|
/** Finds the row index that contains a given x,y position.
|
|
|
|
The position is relative to the ListBox's top-left.
|
|
|
|
If no row exists at this position, the method will return -1.
|
|
|
|
@see getComponentForRowNumber
|
|
*/
|
|
int getRowContainingPosition (const int x, const int y) const throw();
|
|
|
|
/** Finds a row index that would be the most suitable place to insert a new
|
|
item for a given position.
|
|
|
|
This is useful when the user is e.g. dragging and dropping onto the listbox,
|
|
because it lets you easily choose the best position to insert the item that
|
|
they drop, based on where they drop it.
|
|
|
|
If the position is out of range, this will return -1. If the position is
|
|
beyond the end of the list, it will return getNumRows() to indicate the end
|
|
of the list.
|
|
|
|
@see getComponentForRowNumber
|
|
*/
|
|
int getInsertionIndexForPosition (const int x, const int y) const throw();
|
|
|
|
/** Returns the position of one of the rows, relative to the top-left of
|
|
the listbox.
|
|
|
|
This may be off-screen, and the range of the row number that is passed-in is
|
|
not checked to see if it's a valid row.
|
|
*/
|
|
const Rectangle getRowPosition (const int rowNumber,
|
|
const bool relativeToComponentTopLeft) const throw();
|
|
|
|
/** Finds the row component for a given row in the list.
|
|
|
|
The component returned will have been created using createRowComponent().
|
|
|
|
If the component for this row is off-screen or if the row is out-of-range,
|
|
this will return 0.
|
|
|
|
@see getRowContainingPosition
|
|
*/
|
|
Component* getComponentForRowNumber (const int rowNumber) const throw();
|
|
|
|
/** Returns the row number that the given component represents.
|
|
|
|
If the component isn't one of the list's rows, this will return -1.
|
|
*/
|
|
int getRowNumberOfComponent (Component* const rowComponent) const throw();
|
|
|
|
/** Returns the width of a row (which may be less than the width of this component
|
|
if there's a scrollbar).
|
|
*/
|
|
int getVisibleRowWidth() const throw();
|
|
|
|
/** Sets the height of each row in the list.
|
|
|
|
The default height is 22 pixels.
|
|
|
|
@see getRowHeight
|
|
*/
|
|
void setRowHeight (const int newHeight);
|
|
|
|
/** Returns the height of a row in the list.
|
|
|
|
@see setRowHeight
|
|
*/
|
|
int getRowHeight() const throw() { return rowHeight; }
|
|
|
|
/** Returns the number of rows actually visible.
|
|
|
|
This is the number of whole rows which will fit on-screen, so the value might
|
|
be more than the actual number of rows in the list.
|
|
*/
|
|
int getNumRowsOnScreen() const throw();
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the label.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1002800, /**< The background colour to fill the list with.
|
|
Make this transparent if you don't want the background to be filled. */
|
|
outlineColourId = 0x1002810, /**< An optional colour to use to draw a border around the list.
|
|
Make this transparent to not have an outline. */
|
|
textColourId = 0x1002820 /**< The preferred colour to use for drawing text in the listbox. */
|
|
};
|
|
|
|
/** Sets the thickness of a border that will be drawn around the box.
|
|
|
|
To set the colour of the outline, use @code setColour (ListBox::outlineColourId, colourXYZ); @endcode
|
|
@see outlineColourId
|
|
*/
|
|
void setOutlineThickness (const int outlineThickness);
|
|
|
|
/** Returns the thickness of outline that will be drawn around the listbox.
|
|
|
|
@see setOutlineColour
|
|
*/
|
|
int getOutlineThickness() const throw() { return outlineThickness; }
|
|
|
|
/** Sets a component that the list should use as a header.
|
|
|
|
This will position the given component at the top of the list, maintaining the
|
|
height of the component passed-in, but rescaling it horizontally to match the
|
|
width of the items in the listbox.
|
|
|
|
The component will be deleted when setHeaderComponent() is called with a
|
|
different component, or when the listbox is deleted.
|
|
*/
|
|
void setHeaderComponent (Component* const newHeaderComponent);
|
|
|
|
/** Changes the width of the rows in the list.
|
|
|
|
This can be used to make the list's row components wider than the list itself - the
|
|
width of the rows will be either the width of the list or this value, whichever is
|
|
greater, and if the rows become wider than the list, a horizontal scrollbar will
|
|
appear.
|
|
|
|
The default value for this is 0, which means that the rows will always
|
|
be the same width as the list.
|
|
*/
|
|
void setMinimumContentWidth (const int newMinimumWidth);
|
|
|
|
/** Returns the space currently available for the row items, taking into account
|
|
borders, scrollbars, etc.
|
|
*/
|
|
int getVisibleContentWidth() const throw();
|
|
|
|
/** Repaints one of the rows.
|
|
|
|
This is a lightweight alternative to calling updateContent, and just causes a
|
|
repaint of the row's area.
|
|
*/
|
|
void repaintRow (const int rowNumber) throw();
|
|
|
|
/** This fairly obscure method creates an image that just shows the currently
|
|
selected row components.
|
|
|
|
It's a handy method for doing drag-and-drop, as it can be passed to the
|
|
DragAndDropContainer for use as the drag image.
|
|
|
|
Note that it will make the row components temporarily invisible, so if you're
|
|
using custom components this could affect them if they're sensitive to that
|
|
sort of thing.
|
|
|
|
@see Component::createComponentSnapshot
|
|
*/
|
|
Image* createSnapshotOfSelectedRows();
|
|
|
|
/** Returns the viewport that this ListBox uses.
|
|
|
|
You may need to use this to change parameters such as whether scrollbars
|
|
are shown, etc.
|
|
*/
|
|
Viewport* getViewport() const throw();
|
|
|
|
/** @internal */
|
|
bool keyPressed (const KeyPress& key);
|
|
/** @internal */
|
|
bool keyStateChanged (const bool isKeyDown);
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void paintOverChildren (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void visibilityChanged();
|
|
/** @internal */
|
|
void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
|
|
/** @internal */
|
|
void mouseMove (const MouseEvent&);
|
|
/** @internal */
|
|
void mouseExit (const MouseEvent&);
|
|
/** @internal */
|
|
void mouseUp (const MouseEvent&);
|
|
/** @internal */
|
|
void colourChanged();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
friend class ListViewport;
|
|
friend class TableListBox;
|
|
ListBoxModel* model;
|
|
ListViewport* viewport;
|
|
Component* headerComponent;
|
|
int totalItems, rowHeight, minimumRowWidth;
|
|
int outlineThickness;
|
|
int lastMouseX, lastMouseY, lastRowSelected;
|
|
bool mouseMoveSelects, multipleSelection, hasDoneInitialUpdate;
|
|
SparseSet <int> selected;
|
|
|
|
void selectRowInternal (const int rowNumber,
|
|
bool dontScrollToShowThisRow,
|
|
bool deselectOthersFirst,
|
|
bool isMouseClick);
|
|
|
|
ListBox (const ListBox&);
|
|
const ListBox& operator= (const ListBox&);
|
|
};
|
|
|
|
#endif // __JUCE_LISTBOX_JUCEHEADER__
|
|
/********* End of inlined file: juce_ListBox.h *********/
|
|
|
|
/********* Start of inlined file: juce_TextButton.h *********/
|
|
#ifndef __JUCE_TEXTBUTTON_JUCEHEADER__
|
|
#define __JUCE_TEXTBUTTON_JUCEHEADER__
|
|
|
|
/**
|
|
A button that uses the standard lozenge-shaped background with a line of
|
|
text on it.
|
|
|
|
@see Button, DrawableButton
|
|
*/
|
|
class JUCE_API TextButton : public Button
|
|
{
|
|
public:
|
|
|
|
/** Creates a TextButton.
|
|
|
|
@param buttonName the text to put in the button (the component's name is also
|
|
initially set to this string, but these can be changed later
|
|
using the setName() and setButtonText() methods)
|
|
@param toolTip an optional string to use as a toolip
|
|
|
|
@see Button
|
|
*/
|
|
TextButton (const String& buttonName,
|
|
const String& toolTip = String::empty);
|
|
|
|
/** Destructor. */
|
|
~TextButton();
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the button.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
buttonColourId = 0x1000100, /**< The colour used to fill the button shape (when the button is toggled
|
|
'off'). The look-and-feel class might re-interpret this to add
|
|
effects, etc. */
|
|
buttonOnColourId = 0x1000101, /**< The colour used to fill the button shape (when the button is toggled
|
|
'on'). The look-and-feel class might re-interpret this to add
|
|
effects, etc. */
|
|
textColourId = 0x1000102 /**< The colour to use for the button's text. */
|
|
};
|
|
|
|
/** Resizes the button to fit neatly around its current text.
|
|
|
|
If newHeight is >= 0, the button's height will be changed to this
|
|
value. If it's less than zero, its height will be unaffected.
|
|
*/
|
|
void changeWidthToFitText (const int newHeight = -1);
|
|
|
|
/** This can be overridden to use different fonts than the default one.
|
|
|
|
Note that you'll need to set the font's size appropriately, too.
|
|
*/
|
|
virtual const Font getFont();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown);
|
|
/** @internal */
|
|
void colourChanged();
|
|
|
|
private:
|
|
TextButton (const TextButton&);
|
|
const TextButton& operator= (const TextButton&);
|
|
};
|
|
|
|
#endif // __JUCE_TEXTBUTTON_JUCEHEADER__
|
|
/********* End of inlined file: juce_TextButton.h *********/
|
|
|
|
/**
|
|
A component displaying a list of plugins, with options to scan for them,
|
|
add, remove and sort them.
|
|
*/
|
|
class JUCE_API PluginListComponent : public Component,
|
|
public ListBoxModel,
|
|
public ChangeListener,
|
|
public ButtonListener,
|
|
public Timer
|
|
{
|
|
public:
|
|
|
|
/**
|
|
Creates the list component.
|
|
|
|
For info about the deadMansPedalFile, see the PluginDirectoryScanner constructor.
|
|
|
|
The properties file, if supplied, is used to store the user's last search paths.
|
|
*/
|
|
PluginListComponent (KnownPluginList& listToRepresent,
|
|
const File& deadMansPedalFile,
|
|
PropertiesFile* const propertiesToUse);
|
|
|
|
/** Destructor. */
|
|
~PluginListComponent();
|
|
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
bool isInterestedInFileDrag (const StringArray& files);
|
|
/** @internal */
|
|
void filesDropped (const StringArray& files, int, int);
|
|
/** @internal */
|
|
int getNumRows();
|
|
/** @internal */
|
|
void paintListBoxItem (int row, Graphics& g, int width, int height, bool rowIsSelected);
|
|
/** @internal */
|
|
void deleteKeyPressed (int lastRowSelected);
|
|
/** @internal */
|
|
void buttonClicked (Button* b);
|
|
/** @internal */
|
|
void changeListenerCallback (void*);
|
|
/** @internal */
|
|
void timerCallback();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
KnownPluginList& list;
|
|
File deadMansPedalFile;
|
|
ListBox* listBox;
|
|
TextButton* optionsButton;
|
|
PropertiesFile* propertiesToUse;
|
|
int typeToScan;
|
|
|
|
void scanFor (AudioPluginFormat* format);
|
|
|
|
PluginListComponent (const PluginListComponent&);
|
|
const PluginListComponent& operator= (const PluginListComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_PluginListComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AiffAudioFormat.h *********/
|
|
#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__
|
|
#define __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioFormat.h *********/
|
|
#ifndef __JUCE_AUDIOFORMAT_JUCEHEADER__
|
|
#define __JUCE_AUDIOFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioFormatWriter.h *********/
|
|
#ifndef __JUCE_AUDIOFORMATWRITER_JUCEHEADER__
|
|
#define __JUCE_AUDIOFORMATWRITER_JUCEHEADER__
|
|
|
|
/**
|
|
Writes samples to an audio file stream.
|
|
|
|
A subclass that writes a specific type of audio format will be created by
|
|
an AudioFormat object.
|
|
|
|
After creating one of these with the AudioFormat::createWriterFor() method
|
|
you can call its write() method to store the samples, and then delete it.
|
|
|
|
@see AudioFormat, AudioFormatReader
|
|
*/
|
|
class JUCE_API AudioFormatWriter
|
|
{
|
|
protected:
|
|
|
|
/** Creates an AudioFormatWriter object.
|
|
|
|
@param destStream the stream to write to - this will be deleted
|
|
by this object when it is no longer needed
|
|
@param formatName the description that will be returned by the getFormatName()
|
|
method
|
|
@param sampleRate the sample rate to use - the base class just stores
|
|
this value, it doesn't do anything with it
|
|
@param numberOfChannels the number of channels to write - the base class just stores
|
|
this value, it doesn't do anything with it
|
|
@param bitsPerSample the bit depth of the stream - the base class just stores
|
|
this value, it doesn't do anything with it
|
|
*/
|
|
AudioFormatWriter (OutputStream* const destStream,
|
|
const String& formatName,
|
|
const double sampleRate,
|
|
const unsigned int numberOfChannels,
|
|
const unsigned int bitsPerSample);
|
|
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~AudioFormatWriter();
|
|
|
|
/** Returns a description of what type of format this is.
|
|
|
|
E.g. "AIFF file"
|
|
*/
|
|
const String getFormatName() const throw() { return formatName; }
|
|
|
|
/** Writes a set of samples to the audio stream.
|
|
|
|
Note that if you're trying to write the contents of an AudioSampleBuffer, you
|
|
can use AudioSampleBuffer::writeToAudioWriter().
|
|
|
|
@param samplesToWrite an array of arrays containing the sample data for
|
|
each channel to write. This is a zero-terminated
|
|
array of arrays, and can contain a different number
|
|
of channels than the actual stream uses, and the
|
|
writer should do its best to cope with this.
|
|
If the format is fixed-point, each channel will be formatted
|
|
as an array of signed integers using the full 32-bit
|
|
range -0x80000000 to 0x7fffffff, regardless of the source's
|
|
bit-depth. If it is a floating-point format, you should treat
|
|
the arrays as arrays of floats, and just cast it to an (int**)
|
|
to pass it into the method.
|
|
@param numSamples the number of samples to write
|
|
*/
|
|
virtual bool write (const int** samplesToWrite,
|
|
int numSamples) = 0;
|
|
|
|
/** Reads a section of samples from an AudioFormatReader, and writes these to
|
|
the output.
|
|
|
|
This will take care of any floating-point conversion that's required to convert
|
|
between the two formats. It won't deal with sample-rate conversion, though.
|
|
|
|
If numSamplesToRead < 0, it will write the entire length of the reader.
|
|
|
|
@returns false if it can't read or write properly during the operation
|
|
*/
|
|
bool writeFromAudioReader (AudioFormatReader& reader,
|
|
int64 startSample,
|
|
int64 numSamplesToRead);
|
|
|
|
/** Reads some samples from an AudioSource, and writes these to the output.
|
|
|
|
The source must already have been initialised with the AudioSource::prepareToPlay() method
|
|
|
|
@param source the source to read from
|
|
@param numSamplesToRead total number of samples to read and write
|
|
@param samplesPerBlock the maximum number of samples to fetch from the source
|
|
@returns false if it can't read or write properly during the operation
|
|
*/
|
|
bool writeFromAudioSource (AudioSource& source,
|
|
int numSamplesToRead,
|
|
const int samplesPerBlock = 2048);
|
|
|
|
/** Returns the sample rate being used. */
|
|
double getSampleRate() const throw() { return sampleRate; }
|
|
|
|
/** Returns the number of channels being written. */
|
|
int getNumChannels() const throw() { return numChannels; }
|
|
|
|
/** Returns the bit-depth of the data being written. */
|
|
int getBitsPerSample() const throw() { return bitsPerSample; }
|
|
|
|
/** Returns true if it's a floating-point format, false if it's fixed-point. */
|
|
bool isFloatingPoint() const throw() { return usesFloatingPointData; }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** The sample rate of the stream. */
|
|
double sampleRate;
|
|
|
|
/** The number of channels being written to the stream. */
|
|
unsigned int numChannels;
|
|
|
|
/** The bit depth of the file. */
|
|
unsigned int bitsPerSample;
|
|
|
|
/** True if it's a floating-point format, false if it's fixed-point. */
|
|
bool usesFloatingPointData;
|
|
|
|
/** The output stream for Use by subclasses. */
|
|
OutputStream* output;
|
|
|
|
private:
|
|
String formatName;
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOFORMATWRITER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioFormatWriter.h *********/
|
|
|
|
/**
|
|
Subclasses of AudioFormat are used to read and write different audio
|
|
file formats.
|
|
|
|
@see AudioFormatReader, AudioFormatWriter, WavAudioFormat, AiffAudioFormat
|
|
*/
|
|
class JUCE_API AudioFormat
|
|
{
|
|
public:
|
|
|
|
/** Destructor. */
|
|
virtual ~AudioFormat();
|
|
|
|
/** Returns the name of this format.
|
|
|
|
e.g. "WAV file" or "AIFF file"
|
|
*/
|
|
const String& getFormatName() const;
|
|
|
|
/** Returns all the file extensions that might apply to a file of this format.
|
|
|
|
The first item will be the one that's preferred when creating a new file.
|
|
|
|
So for a wav file this might just return ".wav"; for an AIFF file it might
|
|
return two items, ".aif" and ".aiff"
|
|
*/
|
|
const StringArray& getFileExtensions() const;
|
|
|
|
/** Returns true if this the given file can be read by this format.
|
|
|
|
Subclasses shouldn't do too much work here, just check the extension or
|
|
file type. The base class implementation just checks the file's extension
|
|
against one of the ones that was registered in the constructor.
|
|
*/
|
|
virtual bool canHandleFile (const File& fileToTest);
|
|
|
|
/** Returns a set of sample rates that the format can read and write. */
|
|
virtual const Array <int> getPossibleSampleRates() = 0;
|
|
|
|
/** Returns a set of bit depths that the format can read and write. */
|
|
virtual const Array <int> getPossibleBitDepths() = 0;
|
|
|
|
/** Returns true if the format can do 2-channel audio. */
|
|
virtual bool canDoStereo() = 0;
|
|
|
|
/** Returns true if the format can do 1-channel audio. */
|
|
virtual bool canDoMono() = 0;
|
|
|
|
/** Returns true if the format uses compressed data. */
|
|
virtual bool isCompressed();
|
|
|
|
/** Returns a list of different qualities that can be used when writing.
|
|
|
|
Non-compressed formats will just return an empty array, but for something
|
|
like Ogg-Vorbis or MP3, it might return a list of bit-rates, etc.
|
|
|
|
When calling createWriterFor(), an index from this array is passed in to
|
|
tell the format which option is required.
|
|
*/
|
|
virtual const StringArray getQualityOptions();
|
|
|
|
/** Tries to create an object that can read from a stream containing audio
|
|
data in this format.
|
|
|
|
The reader object that is returned can be used to read from the stream, and
|
|
should then be deleted by the caller.
|
|
|
|
@param sourceStream the stream to read from - the AudioFormatReader object
|
|
that is returned will delete this stream when it no longer
|
|
needs it.
|
|
@param deleteStreamIfOpeningFails if no reader can be created, this determines whether this method
|
|
should delete the stream object that was passed-in. (If a valid
|
|
reader is returned, it will always be in charge of deleting the
|
|
stream, so this parameter is ignored)
|
|
@see AudioFormatReader
|
|
*/
|
|
virtual AudioFormatReader* createReaderFor (InputStream* sourceStream,
|
|
const bool deleteStreamIfOpeningFails) = 0;
|
|
|
|
/** Tries to create an object that can write to a stream with this audio format.
|
|
|
|
The writer object that is returned can be used to write to the stream, and
|
|
should then be deleted by the caller.
|
|
|
|
If the stream can't be created for some reason (e.g. the parameters passed in
|
|
here aren't suitable), this will return 0.
|
|
|
|
@param streamToWriteTo the stream that the data will go to - this will be
|
|
deleted by the AudioFormatWriter object when it's no longer
|
|
needed. If no AudioFormatWriter can be created by this method,
|
|
the stream will NOT be deleted, so that the caller can re-use it
|
|
to try to open a different format, etc
|
|
@param sampleRateToUse the sample rate for the file, which must be one of the ones
|
|
returned by getPossibleSampleRates()
|
|
@param numberOfChannels the number of channels - this must be either 1 or 2, and
|
|
the choice will depend on the results of canDoMono() and
|
|
canDoStereo()
|
|
@param bitsPerSample the bits per sample to use - this must be one of the values
|
|
returned by getPossibleBitDepths()
|
|
@param metadataValues a set of metadata values that the writer should try to write
|
|
to the stream. Exactly what these are depends on the format,
|
|
and the subclass doesn't actually have to do anything with
|
|
them if it doesn't want to. Have a look at the specific format
|
|
implementation classes to see possible values that can be
|
|
used
|
|
@param qualityOptionIndex the index of one of compression qualities returned by the
|
|
getQualityOptions() method. If there aren't any quality options
|
|
for this format, just pass 0 in this parameter, as it'll be
|
|
ignored
|
|
@see AudioFormatWriter
|
|
*/
|
|
virtual AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
|
|
double sampleRateToUse,
|
|
unsigned int numberOfChannels,
|
|
int bitsPerSample,
|
|
const StringPairArray& metadataValues,
|
|
int qualityOptionIndex) = 0;
|
|
|
|
protected:
|
|
/** Creates an AudioFormat object.
|
|
|
|
@param formatName this sets the value that will be returned by getFormatName()
|
|
@param fileExtensions a zero-terminated list of file extensions - this is what will
|
|
be returned by getFileExtension()
|
|
*/
|
|
AudioFormat (const String& formatName,
|
|
const tchar** const fileExtensions);
|
|
|
|
private:
|
|
|
|
String formatName;
|
|
StringArray fileExtensions;
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOFORMAT_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioFormat.h *********/
|
|
|
|
/**
|
|
Reads and Writes AIFF format audio files.
|
|
|
|
@see AudioFormat
|
|
*/
|
|
class JUCE_API AiffAudioFormat : public AudioFormat
|
|
{
|
|
public:
|
|
|
|
/** Creates an format object. */
|
|
AiffAudioFormat();
|
|
|
|
/** Destructor. */
|
|
~AiffAudioFormat();
|
|
|
|
const Array <int> getPossibleSampleRates();
|
|
const Array <int> getPossibleBitDepths();
|
|
bool canDoStereo();
|
|
bool canDoMono();
|
|
#if JUCE_MAC
|
|
bool canHandleFile (const File& fileToTest);
|
|
#endif
|
|
|
|
AudioFormatReader* createReaderFor (InputStream* sourceStream,
|
|
const bool deleteStreamIfOpeningFails);
|
|
|
|
AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
|
|
double sampleRateToUse,
|
|
unsigned int numberOfChannels,
|
|
int bitsPerSample,
|
|
const StringPairArray& metadataValues,
|
|
int qualityOptionIndex);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
};
|
|
|
|
#endif // __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__
|
|
/********* End of inlined file: juce_AiffAudioFormat.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOCDBURNER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioCDBurner.h *********/
|
|
#ifndef __JUCE_AUDIOCDBURNER_JUCEHEADER__
|
|
#define __JUCE_AUDIOCDBURNER_JUCEHEADER__
|
|
|
|
/**
|
|
*/
|
|
class AudioCDBurner
|
|
{
|
|
public:
|
|
|
|
/** Returns a list of available optical drives.
|
|
|
|
Use openDevice() to open one of the items from this list.
|
|
*/
|
|
static const StringArray findAvailableDevices();
|
|
|
|
/** Tries to open one of the optical drives.
|
|
|
|
The deviceIndex is an index into the array returned by findAvailableDevices().
|
|
*/
|
|
static AudioCDBurner* openDevice (const int deviceIndex);
|
|
|
|
/** Destructor. */
|
|
~AudioCDBurner();
|
|
|
|
/** Returns true if there's a writable disk in the drive.
|
|
*/
|
|
bool isDiskPresent() const;
|
|
|
|
/** Returns the number of free blocks on the disk.
|
|
|
|
There are 75 blocks per second, at 44100Hz.
|
|
*/
|
|
int getNumAvailableAudioBlocks() const;
|
|
|
|
/** Adds a track to be written.
|
|
|
|
The source passed-in here will be kept by this object, and it will
|
|
be used and deleted at some point in the future, either during the
|
|
burn() method or when this AudioCDBurner object is deleted. Your caller
|
|
method shouldn't keep a reference to it or use it again after passing
|
|
it in here.
|
|
*/
|
|
bool addAudioTrack (AudioSource* source, int numSamples);
|
|
|
|
/**
|
|
|
|
Return true to cancel the current burn operation
|
|
*/
|
|
class BurnProgressListener
|
|
{
|
|
public:
|
|
BurnProgressListener() throw() {}
|
|
virtual ~BurnProgressListener() {}
|
|
|
|
/** Called at intervals to report on the progress of the AudioCDBurner.
|
|
|
|
To cancel the burn, return true from this.
|
|
*/
|
|
virtual bool audioCDBurnProgress (float proportionComplete) = 0;
|
|
};
|
|
|
|
const String burn (BurnProgressListener* listener,
|
|
const bool ejectDiscAfterwards,
|
|
const bool peformFakeBurnForTesting);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
AudioCDBurner (const int deviceIndex);
|
|
|
|
void* internal;
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOCDBURNER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioCDBurner.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOCDREADER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioCDReader.h *********/
|
|
#ifndef __JUCE_AUDIOCDREADER_JUCEHEADER__
|
|
#define __JUCE_AUDIOCDREADER_JUCEHEADER__
|
|
|
|
#if JUCE_MAC
|
|
|
|
#endif
|
|
|
|
/**
|
|
A type of AudioFormatReader that reads from an audio CD.
|
|
|
|
One of these can be used to read a CD as if it's one big audio stream. Use the
|
|
getPositionOfTrackStart() method to find where the individual tracks are
|
|
within the stream.
|
|
|
|
@see AudioFormatReader
|
|
*/
|
|
class JUCE_API AudioCDReader : public AudioFormatReader
|
|
{
|
|
public:
|
|
|
|
/** Returns a list of names of Audio CDs currently available for reading.
|
|
|
|
If there's a CD drive but no CD in it, this might return an empty list, or
|
|
possibly a device that can be opened but which has no tracks, depending
|
|
on the platform.
|
|
|
|
@see createReaderForCD
|
|
*/
|
|
static const StringArray getAvailableCDNames();
|
|
|
|
/** Tries to create an AudioFormatReader that can read from an Audio CD.
|
|
|
|
@param index the index of one of the available CDs - use getAvailableCDNames()
|
|
to find out how many there are.
|
|
@returns a new AudioCDReader object, or 0 if it couldn't be created. The
|
|
caller will be responsible for deleting the object returned.
|
|
*/
|
|
static AudioCDReader* createReaderForCD (const int index);
|
|
|
|
/** Destructor. */
|
|
~AudioCDReader();
|
|
|
|
/** Implementation of the AudioFormatReader method. */
|
|
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
|
|
int64 startSampleInFile, int numSamples);
|
|
|
|
/** Checks whether the CD has been removed from the drive.
|
|
*/
|
|
bool isCDStillPresent() const;
|
|
|
|
/** Returns the total number of tracks (audio + data).
|
|
*/
|
|
int getNumTracks() const;
|
|
|
|
/** Finds the sample offset of the start of a track.
|
|
|
|
@param trackNum the track number, where 0 is the first track.
|
|
*/
|
|
int getPositionOfTrackStart (int trackNum) const;
|
|
|
|
/** Returns true if a given track is an audio track.
|
|
|
|
@param trackNum the track number, where 0 is the first track.
|
|
*/
|
|
bool isTrackAudio (int trackNum) const;
|
|
|
|
/** Refreshes the object's table of contents.
|
|
|
|
If the disc has been ejected and a different one put in since this
|
|
object was created, this will cause it to update its idea of how many tracks
|
|
there are, etc.
|
|
*/
|
|
void refreshTrackLengths();
|
|
|
|
/** Enables scanning for indexes within tracks.
|
|
|
|
@see getLastIndex
|
|
*/
|
|
void enableIndexScanning (bool enabled);
|
|
|
|
/** Returns the index number found during the last read() call.
|
|
|
|
Index scanning is turned off by default - turn it on with enableIndexScanning().
|
|
|
|
Then when the read() method is called, if it comes across an index within that
|
|
block, the index number is stored and returned by this method.
|
|
|
|
Some devices might not support indexes, of course.
|
|
|
|
(If you don't know what CD indexes are, it's unlikely you'll ever need them).
|
|
|
|
@see enableIndexScanning
|
|
*/
|
|
int getLastIndex() const;
|
|
|
|
/** Scans a track to find the position of any indexes within it.
|
|
|
|
@param trackNumber the track to look in, where 0 is the first track on the disc
|
|
@returns an array of sample positions of any index points found (not including
|
|
the index that marks the start of the track)
|
|
*/
|
|
const Array <int> findIndexesInTrack (const int trackNumber);
|
|
|
|
/** Returns the CDDB id number for the CD.
|
|
|
|
It's not a great way of identifying a disc, but it's traditional.
|
|
*/
|
|
int getCDDBId();
|
|
|
|
/** Tries to eject the disk.
|
|
|
|
Of course this might not be possible, if some other process is using it.
|
|
*/
|
|
void ejectDisk();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
#if JUCE_MAC
|
|
File volumeDir;
|
|
OwnedArray<File> tracks;
|
|
Array <int> trackStartSamples;
|
|
int currentReaderTrack;
|
|
AudioFormatReader* reader;
|
|
AudioCDReader (const File& volume);
|
|
public:
|
|
static int compareElements (const File* const, const File* const) throw();
|
|
private:
|
|
|
|
#elif JUCE_WIN32
|
|
int numTracks;
|
|
int trackStarts[100];
|
|
bool audioTracks [100];
|
|
void* handle;
|
|
bool indexingEnabled;
|
|
int lastIndex, firstFrameInBuffer, samplesInBuffer;
|
|
MemoryBlock buffer;
|
|
AudioCDReader (void* handle);
|
|
int getIndexAt (int samplePos);
|
|
|
|
#elif JUCE_LINUX
|
|
AudioCDReader();
|
|
#endif
|
|
|
|
AudioCDReader (const AudioCDReader&);
|
|
const AudioCDReader& operator= (const AudioCDReader&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOCDREADER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioCDReader.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOFORMAT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioFormatManager.h *********/
|
|
#ifndef __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__
|
|
#define __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__
|
|
|
|
/**
|
|
A class for keeping a list of available audio formats, and for deciding which
|
|
one to use to open a given file.
|
|
|
|
You can either use this class as a singleton object, or create instances of it
|
|
yourself. Once created, use its registerFormat() method to tell it which
|
|
formats it should use.
|
|
|
|
@see AudioFormat
|
|
*/
|
|
class JUCE_API AudioFormatManager
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty format manager.
|
|
|
|
Before it'll be any use, you'll need to call registerFormat() with all the
|
|
formats you want it to be able to recognise.
|
|
*/
|
|
AudioFormatManager();
|
|
|
|
/** Destructor. */
|
|
~AudioFormatManager();
|
|
|
|
juce_DeclareSingleton (AudioFormatManager, false);
|
|
|
|
/** Adds a format to the manager's list of available file types.
|
|
|
|
The object passed-in will be deleted by this object, so don't keep a pointer
|
|
to it!
|
|
|
|
If makeThisTheDefaultFormat is true, then the getDefaultFormat() method will
|
|
return this one when called.
|
|
*/
|
|
void registerFormat (AudioFormat* newFormat,
|
|
const bool makeThisTheDefaultFormat);
|
|
|
|
/** Handy method to make it easy to register the formats that come with Juce.
|
|
|
|
Currently, this will add WAV and AIFF to the list.
|
|
*/
|
|
void registerBasicFormats();
|
|
|
|
/** Clears the list of known formats. */
|
|
void clearFormats();
|
|
|
|
/** Returns the number of currently registered file formats. */
|
|
int getNumKnownFormats() const;
|
|
|
|
/** Returns one of the registered file formats. */
|
|
AudioFormat* getKnownFormat (const int index) const;
|
|
|
|
/** Looks for which of the known formats is listed as being for a given file
|
|
extension.
|
|
|
|
The extension may have a dot before it, so e.g. ".wav" or "wav" are both ok.
|
|
*/
|
|
AudioFormat* findFormatForFileExtension (const String& fileExtension) const;
|
|
|
|
/** Returns the format which has been set as the default one.
|
|
|
|
You can set a format as being the default when it is registered. It's useful
|
|
when you want to write to a file, because the best format may change between
|
|
platforms, e.g. AIFF is preferred on the Mac, WAV on Windows.
|
|
|
|
If none has been set as the default, this method will just return the first
|
|
one in the list.
|
|
*/
|
|
AudioFormat* getDefaultFormat() const;
|
|
|
|
/** Returns a set of wildcards for file-matching that contains the extensions for
|
|
all known formats.
|
|
|
|
E.g. if might return "*.wav;*.aiff" if it just knows about wavs and aiffs.
|
|
*/
|
|
const String getWildcardForAllFormats() const;
|
|
|
|
/** Searches through the known formats to try to create a suitable reader for
|
|
this file.
|
|
|
|
If none of the registered formats can open the file, it'll return 0. If it
|
|
returns a reader, it's the caller's responsibility to delete the reader.
|
|
*/
|
|
AudioFormatReader* createReaderFor (const File& audioFile);
|
|
|
|
/** Searches through the known formats to try to create a suitable reader for
|
|
this stream.
|
|
|
|
The stream object that is passed-in will be deleted by this method or by the
|
|
reader that is returned, so the caller should not keep any references to it.
|
|
|
|
The stream that is passed-in must be capable of being repositioned so
|
|
that all the formats can have a go at opening it.
|
|
|
|
If none of the registered formats can open the stream, it'll return 0. If it
|
|
returns a reader, it's the caller's responsibility to delete the reader.
|
|
*/
|
|
AudioFormatReader* createReaderFor (InputStream* audioFileStream);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
VoidArray knownFormats;
|
|
int defaultFormatIndex;
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioFormatManager.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOFORMATREADER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOFORMATWRITER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioThumbnailCache.h *********/
|
|
#ifndef __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__
|
|
#define __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioThumbnail.h *********/
|
|
#ifndef __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__
|
|
#define __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__
|
|
|
|
class AudioThumbnailCache;
|
|
|
|
/**
|
|
Makes it easy to quickly draw scaled views of the waveform shape of an
|
|
audio file.
|
|
|
|
To use this class, just create an AudioThumbNail class for the file you want
|
|
to draw, call setSource to tell it which file or resource to use, then call
|
|
drawChannel() to draw it.
|
|
|
|
The class will asynchronously scan the wavefile to create its scaled-down view,
|
|
so you should make your UI repaint itself as this data comes in. To do this, the
|
|
AudioThumbnail is a ChangeBroadcaster, and will broadcast a message when its
|
|
listeners should repaint themselves.
|
|
|
|
The thumbnail stores an internal low-res version of the wave data, and this can
|
|
be loaded and saved to avoid having to scan the file again.
|
|
|
|
@see AudioThumbnailCache
|
|
*/
|
|
class JUCE_API AudioThumbnail : public ChangeBroadcaster,
|
|
public TimeSliceClient,
|
|
private Timer
|
|
{
|
|
public:
|
|
|
|
/** Creates an audio thumbnail.
|
|
|
|
@param sourceSamplesPerThumbnailSample when creating a stored, low-res version
|
|
of the audio data, this is the scale at which it should be done. (This
|
|
number is the number of original samples that will be averaged for each
|
|
low-res sample)
|
|
@param formatManagerToUse the audio format manager that is used to open the file
|
|
@param cacheToUse an instance of an AudioThumbnailCache - this provides a background
|
|
thread and storage that is used to by the thumbnail, and the cache
|
|
object can be shared between multiple thumbnails
|
|
*/
|
|
AudioThumbnail (const int sourceSamplesPerThumbnailSample,
|
|
AudioFormatManager& formatManagerToUse,
|
|
AudioThumbnailCache& cacheToUse);
|
|
|
|
/** Destructor. */
|
|
~AudioThumbnail();
|
|
|
|
/** Specifies the file or stream that contains the audio file.
|
|
|
|
For a file, just call
|
|
@code
|
|
setSource (new FileInputSource (file))
|
|
@endcode
|
|
|
|
You can pass a zero in here to clear the thumbnail.
|
|
|
|
The source that is passed in will be deleted by this object when it is no
|
|
longer needed
|
|
*/
|
|
void setSource (InputSource* const newSource);
|
|
|
|
/** Reloads the low res thumbnail data from an input stream.
|
|
|
|
The thumb will automatically attempt to reload itself from its
|
|
AudioThumbnailCache.
|
|
*/
|
|
void loadFrom (InputStream& input);
|
|
|
|
/** Saves the low res thumbnail data to an output stream.
|
|
|
|
The thumb will automatically attempt to save itself to its
|
|
AudioThumbnailCache after it finishes scanning the wave file.
|
|
*/
|
|
void saveTo (OutputStream& output) const;
|
|
|
|
/** Returns the number of channels in the file.
|
|
*/
|
|
int getNumChannels() const throw();
|
|
|
|
/** Returns the length of the audio file, in seconds.
|
|
*/
|
|
double getTotalLength() const throw();
|
|
|
|
/** Renders the waveform shape for a channel.
|
|
|
|
The waveform will be drawn within the specified rectangle, where startTime
|
|
and endTime specify the times within the audio file that should be positioned
|
|
at the left and right edges of the rectangle.
|
|
|
|
The waveform will be scaled vertically so that a full-volume sample will fill
|
|
the rectangle vertically, but you can also specify an extra vertical scale factor
|
|
with the verticalZoomFactor parameter.
|
|
*/
|
|
void drawChannel (Graphics& g,
|
|
int x, int y, int w, int h,
|
|
double startTimeSeconds,
|
|
double endTimeSeconds,
|
|
int channelNum,
|
|
const float verticalZoomFactor);
|
|
|
|
/** Returns true if the low res preview is fully generated.
|
|
*/
|
|
bool isFullyLoaded() const throw();
|
|
|
|
/** @internal */
|
|
bool useTimeSlice();
|
|
/** @internal */
|
|
void timerCallback();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
AudioFormatManager& formatManagerToUse;
|
|
AudioThumbnailCache& cache;
|
|
InputSource* source;
|
|
|
|
CriticalSection readerLock;
|
|
AudioFormatReader* reader;
|
|
|
|
MemoryBlock data, cachedLevels;
|
|
int orginalSamplesPerThumbnailSample;
|
|
|
|
int numChannelsCached, numSamplesCached;
|
|
double cachedStart, cachedTimePerPixel;
|
|
bool cacheNeedsRefilling;
|
|
|
|
void clear();
|
|
|
|
AudioFormatReader* createReader() const;
|
|
|
|
void generateSection (AudioFormatReader& reader,
|
|
int64 startSample,
|
|
int numSamples);
|
|
|
|
char* getChannelData (int channel) const;
|
|
|
|
void refillCache (const int numSamples,
|
|
double startTime,
|
|
const double timePerPixel);
|
|
|
|
friend class AudioThumbnailCache;
|
|
|
|
// true if it needs more callbacks from the readNextBlockFromAudioFile() method
|
|
bool initialiseFromAudioFile (AudioFormatReader& reader);
|
|
|
|
// returns true if more needs to be read
|
|
bool readNextBlockFromAudioFile (AudioFormatReader& reader);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioThumbnail.h *********/
|
|
|
|
struct ThumbnailCacheEntry;
|
|
|
|
/**
|
|
An instance of this class is used to manage multiple AudioThumbnail objects.
|
|
|
|
The cache runs a single background thread that is shared by all the thumbnails
|
|
that need it, and it maintains a set of low-res previews in memory, to avoid
|
|
having to re-scan audio files too often.
|
|
|
|
@see AudioThumbnail
|
|
*/
|
|
class JUCE_API AudioThumbnailCache : public TimeSliceThread
|
|
{
|
|
public:
|
|
|
|
/** Creates a cache object.
|
|
|
|
The maxNumThumbsToStore parameter lets you specify how many previews should
|
|
be kept in memory at once.
|
|
*/
|
|
AudioThumbnailCache (const int maxNumThumbsToStore);
|
|
|
|
/** Destructor. */
|
|
~AudioThumbnailCache();
|
|
|
|
/** Clears out any stored thumbnails.
|
|
*/
|
|
void clear();
|
|
|
|
/** Reloads the specified thumb if this cache contains the appropriate stored
|
|
data.
|
|
|
|
This is called automatically by the AudioThumbnail class, so you shouldn't
|
|
normally need to call it directly.
|
|
*/
|
|
bool loadThumb (AudioThumbnail& thumb, const int64 hashCode);
|
|
|
|
/** Stores the cachable data from the specified thumb in this cache.
|
|
|
|
This is called automatically by the AudioThumbnail class, so you shouldn't
|
|
normally need to call it directly.
|
|
*/
|
|
void storeThumb (const AudioThumbnail& thumb, const int64 hashCode);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
OwnedArray <ThumbnailCacheEntry> thumbs;
|
|
int maxNumThumbsToStore;
|
|
|
|
friend class AudioThumbnail;
|
|
void addThumbnail (AudioThumbnail* const thumb);
|
|
void removeThumbnail (AudioThumbnail* const thumb);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioThumbnailCache.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FlacAudioFormat.h *********/
|
|
#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__
|
|
#define __JUCE_FLACAUDIOFORMAT_JUCEHEADER__
|
|
|
|
#if JUCE_USE_FLAC || defined (DOXYGEN)
|
|
|
|
/**
|
|
Reads and writes the lossless-compression FLAC audio format.
|
|
|
|
To compile this, you'll need to set the JUCE_USE_FLAC flag in juce_Config.h,
|
|
and make sure your include search path and library search path are set up to find
|
|
the FLAC header files and static libraries.
|
|
|
|
@see AudioFormat
|
|
*/
|
|
class JUCE_API FlacAudioFormat : public AudioFormat
|
|
{
|
|
public:
|
|
|
|
FlacAudioFormat();
|
|
~FlacAudioFormat();
|
|
|
|
const Array <int> getPossibleSampleRates();
|
|
const Array <int> getPossibleBitDepths();
|
|
bool canDoStereo();
|
|
bool canDoMono();
|
|
bool isCompressed();
|
|
|
|
AudioFormatReader* createReaderFor (InputStream* sourceStream,
|
|
const bool deleteStreamIfOpeningFails);
|
|
|
|
AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
|
|
double sampleRateToUse,
|
|
unsigned int numberOfChannels,
|
|
int bitsPerSample,
|
|
const StringPairArray& metadataValues,
|
|
int qualityOptionIndex);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
};
|
|
|
|
#endif
|
|
#endif // __JUCE_FLACAUDIOFORMAT_JUCEHEADER__
|
|
/********* End of inlined file: juce_FlacAudioFormat.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioSubsectionReader.h *********/
|
|
#ifndef __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__
|
|
#define __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__
|
|
|
|
/**
|
|
This class is used to wrap an AudioFormatReader and only read from a
|
|
subsection of the file.
|
|
|
|
So if you have a reader which can read a 1000 sample file, you could wrap it
|
|
in one of these to only access, e.g. samples 100 to 200, and any samples
|
|
outside that will come back as 0. Accessing sample 0 from this reader will
|
|
actually read the first sample from the other's subsection, which might
|
|
be at a non-zero position.
|
|
|
|
@see AudioFormatReader
|
|
*/
|
|
class JUCE_API AudioSubsectionReader : public AudioFormatReader
|
|
{
|
|
public:
|
|
|
|
/** Creates a AudioSubsectionReader for a given data source.
|
|
|
|
@param sourceReader the source reader from which we'll be taking data
|
|
@param subsectionStartSample the sample within the source reader which will be
|
|
mapped onto sample 0 for this reader.
|
|
@param subsectionLength the number of samples from the source that will
|
|
make up the subsection. If this reader is asked for
|
|
any samples beyond this region, it will return zero.
|
|
@param deleteSourceWhenDeleted if true, the sourceReader object will be deleted when
|
|
this object is deleted.
|
|
*/
|
|
AudioSubsectionReader (AudioFormatReader* const sourceReader,
|
|
const int64 subsectionStartSample,
|
|
const int64 subsectionLength,
|
|
const bool deleteSourceWhenDeleted);
|
|
|
|
/** Destructor. */
|
|
~AudioSubsectionReader();
|
|
|
|
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
|
|
int64 startSampleInFile, int numSamples);
|
|
|
|
void readMaxLevels (int64 startSample,
|
|
int64 numSamples,
|
|
float& lowestLeft,
|
|
float& highestLeft,
|
|
float& lowestRight,
|
|
float& highestRight);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
AudioFormatReader* const source;
|
|
int64 startSample, length;
|
|
const bool deleteSourceWhenDeleted;
|
|
|
|
AudioSubsectionReader (const AudioSubsectionReader&);
|
|
const AudioSubsectionReader& operator= (const AudioSubsectionReader&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioSubsectionReader.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_WavAudioFormat.h *********/
|
|
#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__
|
|
#define __JUCE_WAVAUDIOFORMAT_JUCEHEADER__
|
|
|
|
/**
|
|
Reads and Writes WAV format audio files.
|
|
|
|
@see AudioFormat
|
|
*/
|
|
class JUCE_API WavAudioFormat : public AudioFormat
|
|
{
|
|
public:
|
|
|
|
/** Creates a format object. */
|
|
WavAudioFormat();
|
|
|
|
/** Destructor. */
|
|
~WavAudioFormat();
|
|
|
|
/** Metadata property name used by wav readers and writers for adding
|
|
a BWAV chunk to the file.
|
|
|
|
@see AudioFormatReader::metadataValues, createWriterFor
|
|
*/
|
|
static const tchar* const bwavDescription;
|
|
|
|
/** Metadata property name used by wav readers and writers for adding
|
|
a BWAV chunk to the file.
|
|
|
|
@see AudioFormatReader::metadataValues, createWriterFor
|
|
*/
|
|
static const tchar* const bwavOriginator;
|
|
|
|
/** Metadata property name used by wav readers and writers for adding
|
|
a BWAV chunk to the file.
|
|
|
|
@see AudioFormatReader::metadataValues, createWriterFor
|
|
*/
|
|
static const tchar* const bwavOriginatorRef;
|
|
|
|
/** Metadata property name used by wav readers and writers for adding
|
|
a BWAV chunk to the file.
|
|
|
|
Date format is: yyyy-mm-dd
|
|
|
|
@see AudioFormatReader::metadataValues, createWriterFor
|
|
*/
|
|
static const tchar* const bwavOriginationDate;
|
|
|
|
/** Metadata property name used by wav readers and writers for adding
|
|
a BWAV chunk to the file.
|
|
|
|
Time format is: hh-mm-ss
|
|
|
|
@see AudioFormatReader::metadataValues, createWriterFor
|
|
*/
|
|
static const tchar* const bwavOriginationTime;
|
|
|
|
/** Metadata property name used by wav readers and writers for adding
|
|
a BWAV chunk to the file.
|
|
|
|
This is the number of samples from the start of an edit that the
|
|
file is supposed to begin at. Seems like an obvious mistake to
|
|
only allow a file to occur in an edit once, but that's the way
|
|
it is..
|
|
|
|
@see AudioFormatReader::metadataValues, createWriterFor
|
|
*/
|
|
static const tchar* const bwavTimeReference;
|
|
|
|
/** Metadata property name used by wav readers and writers for adding
|
|
a BWAV chunk to the file.
|
|
|
|
This is a
|
|
|
|
@see AudioFormatReader::metadataValues, createWriterFor
|
|
*/
|
|
static const tchar* const bwavCodingHistory;
|
|
|
|
/** Utility function to fill out the appropriate metadata for a BWAV file.
|
|
|
|
This just makes it easier than using the property names directly, and it
|
|
fills out the time and date in the right format.
|
|
*/
|
|
static const StringPairArray createBWAVMetadata (const String& description,
|
|
const String& originator,
|
|
const String& originatorRef,
|
|
const Time& dateAndTime,
|
|
const int64 timeReferenceSamples,
|
|
const String& codingHistory);
|
|
|
|
const Array <int> getPossibleSampleRates();
|
|
const Array <int> getPossibleBitDepths();
|
|
bool canDoStereo();
|
|
bool canDoMono();
|
|
|
|
AudioFormatReader* createReaderFor (InputStream* sourceStream,
|
|
const bool deleteStreamIfOpeningFails);
|
|
|
|
AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
|
|
double sampleRateToUse,
|
|
unsigned int numberOfChannels,
|
|
int bitsPerSample,
|
|
const StringPairArray& metadataValues,
|
|
int qualityOptionIndex);
|
|
|
|
/** Utility function to replace the metadata in a wav file with a new set of values.
|
|
|
|
If possible, this cheats by overwriting just the metadata region of the file, rather
|
|
than by copying the whole file again.
|
|
*/
|
|
bool replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
};
|
|
|
|
#endif // __JUCE_WAVAUDIOFORMAT_JUCEHEADER__
|
|
/********* End of inlined file: juce_WavAudioFormat.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_OggVorbisAudioFormat.h *********/
|
|
#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__
|
|
#define __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__
|
|
|
|
#if JUCE_USE_OGGVORBIS || defined (DOXYGEN)
|
|
|
|
/**
|
|
Reads and writes the Ogg-Vorbis audio format.
|
|
|
|
To compile this, you'll need to set the JUCE_USE_OGGVORBIS flag in juce_Config.h,
|
|
and make sure your include search path and library search path are set up to find
|
|
the Vorbis and Ogg header files and static libraries.
|
|
|
|
@see AudioFormat,
|
|
*/
|
|
class JUCE_API OggVorbisAudioFormat : public AudioFormat
|
|
{
|
|
public:
|
|
|
|
OggVorbisAudioFormat();
|
|
~OggVorbisAudioFormat();
|
|
|
|
const Array <int> getPossibleSampleRates();
|
|
const Array <int> getPossibleBitDepths();
|
|
bool canDoStereo();
|
|
bool canDoMono();
|
|
bool isCompressed();
|
|
const StringArray getQualityOptions();
|
|
|
|
/** Tries to estimate the quality level of an ogg file based on its size.
|
|
|
|
If it can't read the file for some reason, this will just return 1 (medium quality),
|
|
otherwise it will return the approximate quality setting that would have been used
|
|
to create the file.
|
|
|
|
@see getQualityOptions
|
|
*/
|
|
int estimateOggFileQuality (const File& source);
|
|
|
|
AudioFormatReader* createReaderFor (InputStream* sourceStream,
|
|
const bool deleteStreamIfOpeningFails);
|
|
|
|
AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
|
|
double sampleRateToUse,
|
|
unsigned int numberOfChannels,
|
|
int bitsPerSample,
|
|
const StringPairArray& metadataValues,
|
|
int qualityOptionIndex);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
};
|
|
|
|
#endif
|
|
#endif // __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__
|
|
/********* End of inlined file: juce_OggVorbisAudioFormat.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_QuickTimeAudioFormat.h *********/
|
|
#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__
|
|
#define __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__
|
|
|
|
#if JUCE_QUICKTIME
|
|
|
|
/**
|
|
Uses QuickTime to read the audio track a movie or media file.
|
|
|
|
As well as QuickTime movies, this should also manage to open other audio
|
|
files that quicktime can understand, like mp3, m4a, etc.
|
|
|
|
@see AudioFormat
|
|
*/
|
|
class JUCE_API QuickTimeAudioFormat : public AudioFormat
|
|
{
|
|
public:
|
|
|
|
/** Creates a format object. */
|
|
QuickTimeAudioFormat();
|
|
|
|
/** Destructor. */
|
|
~QuickTimeAudioFormat();
|
|
|
|
const Array <int> getPossibleSampleRates();
|
|
const Array <int> getPossibleBitDepths();
|
|
bool canDoStereo();
|
|
bool canDoMono();
|
|
|
|
AudioFormatReader* createReaderFor (InputStream* sourceStream,
|
|
const bool deleteStreamIfOpeningFails);
|
|
|
|
AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
|
|
double sampleRateToUse,
|
|
unsigned int numberOfChannels,
|
|
int bitsPerSample,
|
|
const StringPairArray& metadataValues,
|
|
int qualityOptionIndex);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
};
|
|
|
|
#endif
|
|
#endif // __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__
|
|
/********* End of inlined file: juce_QuickTimeAudioFormat.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ActionBroadcaster.h *********/
|
|
#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__
|
|
#define __JUCE_ACTIONBROADCASTER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ActionListenerList.h *********/
|
|
#ifndef __JUCE_ACTIONLISTENERLIST_JUCEHEADER__
|
|
#define __JUCE_ACTIONLISTENERLIST_JUCEHEADER__
|
|
|
|
/**
|
|
A set of ActionListeners.
|
|
|
|
Listeners can be added and removed from the list, and messages can be
|
|
broadcast to all the listeners.
|
|
|
|
@see ActionListener, ActionBroadcaster
|
|
*/
|
|
class JUCE_API ActionListenerList : public MessageListener
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty list. */
|
|
ActionListenerList() throw();
|
|
|
|
/** Destructor. */
|
|
~ActionListenerList() throw();
|
|
|
|
/** Adds a listener to the list.
|
|
|
|
(Trying to add a listener that's already on the list will have no effect).
|
|
*/
|
|
void addActionListener (ActionListener* const listener) throw();
|
|
|
|
/** Removes a listener from the list.
|
|
|
|
If the listener isn't on the list, this won't have any effect.
|
|
*/
|
|
void removeActionListener (ActionListener* const listener) throw();
|
|
|
|
/** Removes all listeners from the list. */
|
|
void removeAllActionListeners() throw();
|
|
|
|
/** Broadcasts a message to all the registered listeners.
|
|
|
|
This sends the message asynchronously.
|
|
|
|
If a listener is on the list when this method is called but is removed from
|
|
the list before the message arrives, it won't receive the message. Similarly
|
|
listeners that are added to the list after the message is sent but before it
|
|
arrives won't get the message either.
|
|
*/
|
|
void sendActionMessage (const String& message) const;
|
|
|
|
/** @internal */
|
|
void handleMessage (const Message&);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
SortedSet <void*> actionListeners_;
|
|
CriticalSection actionListenerLock_;
|
|
|
|
ActionListenerList (const ActionListenerList&);
|
|
const ActionListenerList& operator= (const ActionListenerList&);
|
|
};
|
|
|
|
#endif // __JUCE_ACTIONLISTENERLIST_JUCEHEADER__
|
|
/********* End of inlined file: juce_ActionListenerList.h *********/
|
|
|
|
/** Manages a list of ActionListeners, and can send them messages.
|
|
|
|
To quickly add methods to your class that can add/remove action
|
|
listeners and broadcast to them, you can derive from this.
|
|
|
|
@see ActionListenerList, ActionListener
|
|
*/
|
|
class JUCE_API ActionBroadcaster
|
|
{
|
|
public:
|
|
|
|
/** Creates an ActionBroadcaster. */
|
|
ActionBroadcaster() throw();
|
|
|
|
/** Destructor. */
|
|
virtual ~ActionBroadcaster();
|
|
|
|
/** Adds a listener to the list.
|
|
|
|
(Trying to add a listener that's already on the list will have no effect).
|
|
*/
|
|
void addActionListener (ActionListener* const listener);
|
|
|
|
/** Removes a listener from the list.
|
|
|
|
If the listener isn't on the list, this won't have any effect.
|
|
*/
|
|
void removeActionListener (ActionListener* const listener);
|
|
|
|
/** Removes all listeners from the list. */
|
|
void removeAllActionListeners();
|
|
|
|
/** Broadcasts a message to all the registered listeners.
|
|
|
|
@see ActionListenerList::sendActionMessage
|
|
*/
|
|
void sendActionMessage (const String& message) const;
|
|
|
|
private:
|
|
|
|
ActionListenerList actionListenerList;
|
|
|
|
ActionBroadcaster (const ActionBroadcaster&);
|
|
const ActionBroadcaster& operator= (const ActionBroadcaster&);
|
|
};
|
|
|
|
#endif // __JUCE_ACTIONBROADCASTER_JUCEHEADER__
|
|
/********* End of inlined file: juce_ActionBroadcaster.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_ACTIONLISTENER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_ACTIONLISTENERLIST_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_ASYNCUPDATER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_CALLBACKMESSAGE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_CallbackMessage.h *********/
|
|
#ifndef __JUCE_CALLBACKMESSAGE_JUCEHEADER__
|
|
#define __JUCE_CALLBACKMESSAGE_JUCEHEADER__
|
|
|
|
/**
|
|
A message that calls a custom function when it gets delivered.
|
|
|
|
You can use this class to fire off actions that you want to be performed later
|
|
on the message thread.
|
|
|
|
Unlike other Message objects, these don't get sent to a MessageListener, you
|
|
just call the post() method to send them, and when they arrive, your
|
|
messageCallback() method will automatically be invoked.
|
|
|
|
@see MessageListener, MessageManager, ActionListener, ChangeListener
|
|
*/
|
|
class JUCE_API CallbackMessage : public Message
|
|
{
|
|
public:
|
|
|
|
CallbackMessage() throw();
|
|
|
|
/** Destructor. */
|
|
~CallbackMessage() throw();
|
|
|
|
/** Called when the message is delivered.
|
|
|
|
You should implement this method and make it do whatever action you want
|
|
to perform.
|
|
|
|
Note that like all other messages, this object will be deleted immediately
|
|
after this method has been invoked.
|
|
*/
|
|
virtual void messageCallback() = 0;
|
|
|
|
/** Instead of sending this message to a MessageListener, just call this method
|
|
to post it to the event queue.
|
|
|
|
After you've called this, this object will belong to the MessageManager,
|
|
which will delete it later. So make sure you don't delete the object yourself,
|
|
call post() more than once, or call post() on a stack-based obect!
|
|
*/
|
|
void post();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
CallbackMessage (const CallbackMessage&);
|
|
const CallbackMessage& operator= (const CallbackMessage&);
|
|
};
|
|
|
|
#endif // __JUCE_CALLBACKMESSAGE_JUCEHEADER__
|
|
/********* End of inlined file: juce_CallbackMessage.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_CHANGEBROADCASTER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_CHANGELISTENER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_CHANGELISTENERLIST_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_InterprocessConnection.h *********/
|
|
#ifndef __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__
|
|
#define __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__
|
|
|
|
class InterprocessConnectionServer;
|
|
|
|
/**
|
|
Manages a simple two-way messaging connection to another process, using either
|
|
a socket or a named pipe as the transport medium.
|
|
|
|
To connect to a waiting socket or an open pipe, use the connectToSocket() or
|
|
connectToPipe() methods. If this succeeds, messages can be sent to the other end,
|
|
and incoming messages will result in a callback via the messageReceived()
|
|
method.
|
|
|
|
To open a pipe and wait for another client to connect to it, use the createPipe()
|
|
method.
|
|
|
|
To act as a socket server and create connections for one or more client, see the
|
|
InterprocessConnectionServer class.
|
|
|
|
@see InterprocessConnectionServer, Socket, NamedPipe
|
|
*/
|
|
class JUCE_API InterprocessConnection : public Thread,
|
|
private MessageListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a connection.
|
|
|
|
Connections are created manually, connecting them with the connectToSocket()
|
|
or connectToPipe() methods, or they are created automatically by a InterprocessConnectionServer
|
|
when a client wants to connect.
|
|
|
|
@param callbacksOnMessageThread if true, callbacks to the connectionMade(),
|
|
connectionLost() and messageReceived() methods will
|
|
always be made using the message thread; if false,
|
|
these will be called immediately on the connection's
|
|
own thread.
|
|
@param magicMessageHeaderNumber a magic number to use in the header to check the
|
|
validity of the data blocks being sent and received. This
|
|
can be any number, but the sender and receiver must obviously
|
|
use matching values or they won't recognise each other.
|
|
*/
|
|
InterprocessConnection (const bool callbacksOnMessageThread = true,
|
|
const uint32 magicMessageHeaderNumber = 0xf2b49e2c);
|
|
|
|
/** Destructor. */
|
|
~InterprocessConnection();
|
|
|
|
/** Tries to connect this object to a socket.
|
|
|
|
For this to work, the machine on the other end needs to have a InterprocessConnectionServer
|
|
object waiting to receive client connections on this port number.
|
|
|
|
@param hostName the host computer, either a network address or name
|
|
@param portNumber the socket port number to try to connect to
|
|
@param timeOutMillisecs how long to keep trying before giving up
|
|
@returns true if the connection is established successfully
|
|
@see Socket
|
|
*/
|
|
bool connectToSocket (const String& hostName,
|
|
const int portNumber,
|
|
const int timeOutMillisecs);
|
|
|
|
/** Tries to connect the object to an existing named pipe.
|
|
|
|
For this to work, another process on the same computer must already have opened
|
|
an InterprocessConnection object and used createPipe() to create a pipe for this
|
|
to connect to.
|
|
|
|
You can optionally specify a timeout length to be passed to the NamedPipe::read() method.
|
|
|
|
@returns true if it connects successfully.
|
|
@see createPipe, NamedPipe
|
|
*/
|
|
bool connectToPipe (const String& pipeName,
|
|
const int pipeReceiveMessageTimeoutMs = -1);
|
|
|
|
/** Tries to create a new pipe for other processes to connect to.
|
|
|
|
This creates a pipe with the given name, so that other processes can use
|
|
connectToPipe() to connect to the other end.
|
|
|
|
You can optionally specify a timeout length to be passed to the NamedPipe::read() method.
|
|
|
|
If another process is already using this pipe, this will fail and return false.
|
|
*/
|
|
bool createPipe (const String& pipeName,
|
|
const int pipeReceiveMessageTimeoutMs = -1);
|
|
|
|
/** Disconnects and closes any currently-open sockets or pipes. */
|
|
void disconnect();
|
|
|
|
/** True if a socket or pipe is currently active. */
|
|
bool isConnected() const;
|
|
|
|
/** Returns the socket that this connection is using (or null if it uses a pipe). */
|
|
StreamingSocket* getSocket() const throw() { return socket; }
|
|
|
|
/** Returns the pipe that this connection is using (or null if it uses a socket). */
|
|
NamedPipe* getPipe() const throw() { return pipe; }
|
|
|
|
/** Returns the name of the machine at the other end of this connection.
|
|
|
|
This will return an empty string if the other machine isn't known for
|
|
some reason.
|
|
*/
|
|
const String getConnectedHostName() const;
|
|
|
|
/** Tries to send a message to the other end of this connection.
|
|
|
|
This will fail if it's not connected, or if there's some kind of write error. If
|
|
it succeeds, the connection object at the other end will receive the message by
|
|
a callback to its messageReceived() method.
|
|
|
|
@see messageReceived
|
|
*/
|
|
bool sendMessage (const MemoryBlock& message);
|
|
|
|
/** Called when the connection is first connected.
|
|
|
|
If the connection was created with the callbacksOnMessageThread flag set, then
|
|
this will be called on the message thread; otherwise it will be called on a server
|
|
thread.
|
|
*/
|
|
virtual void connectionMade() = 0;
|
|
|
|
/** Called when the connection is broken.
|
|
|
|
If the connection was created with the callbacksOnMessageThread flag set, then
|
|
this will be called on the message thread; otherwise it will be called on a server
|
|
thread.
|
|
*/
|
|
virtual void connectionLost() = 0;
|
|
|
|
/** Called when a message arrives.
|
|
|
|
When the object at the other end of this connection sends us a message with sendMessage(),
|
|
this callback is used to deliver it to us.
|
|
|
|
If the connection was created with the callbacksOnMessageThread flag set, then
|
|
this will be called on the message thread; otherwise it will be called on a server
|
|
thread.
|
|
|
|
@see sendMessage
|
|
*/
|
|
virtual void messageReceived (const MemoryBlock& message) = 0;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
CriticalSection pipeAndSocketLock;
|
|
StreamingSocket* socket;
|
|
NamedPipe* pipe;
|
|
bool callbackConnectionState;
|
|
const bool useMessageThread;
|
|
const uint32 magicMessageHeader;
|
|
int pipeReceiveMessageTimeout;
|
|
|
|
friend class InterprocessConnectionServer;
|
|
|
|
void initialiseWithSocket (StreamingSocket* const socket_);
|
|
void initialiseWithPipe (NamedPipe* const pipe_);
|
|
|
|
void handleMessage (const Message& message);
|
|
|
|
void connectionMadeInt();
|
|
void connectionLostInt();
|
|
void deliverDataInt (const MemoryBlock& data);
|
|
|
|
bool readNextMessageInt();
|
|
void run();
|
|
|
|
InterprocessConnection (const InterprocessConnection&);
|
|
const InterprocessConnection& operator= (const InterprocessConnection&);
|
|
};
|
|
|
|
#endif // __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__
|
|
/********* End of inlined file: juce_InterprocessConnection.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_InterprocessConnectionServer.h *********/
|
|
#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__
|
|
#define __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__
|
|
|
|
/**
|
|
An object that waits for client sockets to connect to a port on this host, and
|
|
creates InterprocessConnection objects for each one.
|
|
|
|
To use this, create a class derived from it which implements the createConnectionObject()
|
|
method, so that it creates suitable connection objects for each client that tries
|
|
to connect.
|
|
|
|
@see InterprocessConnection
|
|
*/
|
|
class JUCE_API InterprocessConnectionServer : private Thread
|
|
{
|
|
public:
|
|
|
|
/** Creates an uninitialised server object.
|
|
*/
|
|
InterprocessConnectionServer();
|
|
|
|
/** Destructor. */
|
|
~InterprocessConnectionServer();
|
|
|
|
/** Starts an internal thread which listens on the given port number.
|
|
|
|
While this is running, in another process tries to connect with the
|
|
InterprocessConnection::connectToSocket() method, this object will call
|
|
createConnectionObject() to create a connection to that client.
|
|
|
|
Use stop() to stop the thread running.
|
|
|
|
@see createConnectionObject, stop
|
|
*/
|
|
bool beginWaitingForSocket (const int portNumber);
|
|
|
|
/** Terminates the listener thread, if it's active.
|
|
|
|
@see beginWaitingForSocket
|
|
*/
|
|
void stop();
|
|
|
|
protected:
|
|
/** Creates a suitable connection object for a client process that wants to
|
|
connect to this one.
|
|
|
|
This will be called by the listener thread when a client process tries
|
|
to connect, and must return a new InterprocessConnection object that will
|
|
then run as this end of the connection.
|
|
|
|
@see InterprocessConnection
|
|
*/
|
|
virtual InterprocessConnection* createConnectionObject() = 0;
|
|
|
|
public:
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
StreamingSocket* volatile socket;
|
|
|
|
void run();
|
|
|
|
InterprocessConnectionServer (const InterprocessConnectionServer&);
|
|
const InterprocessConnectionServer& operator= (const InterprocessConnectionServer&);
|
|
};
|
|
|
|
#endif // __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__
|
|
/********* End of inlined file: juce_InterprocessConnectionServer.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MESSAGE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MESSAGEMANAGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MessageManager.h *********/
|
|
#ifndef __JUCE_MESSAGEMANAGER_JUCEHEADER__
|
|
#define __JUCE_MESSAGEMANAGER_JUCEHEADER__
|
|
|
|
class Component;
|
|
class MessageManagerLock;
|
|
|
|
/** See MessageManager::callFunctionOnMessageThread() for use of this function type
|
|
*/
|
|
typedef void* (MessageCallbackFunction) (void* userData);
|
|
|
|
/** Delivers Message objects to MessageListeners, and handles the event-dispatch loop.
|
|
|
|
@see Message, MessageListener, MessageManagerLock, JUCEApplication
|
|
*/
|
|
class JUCE_API MessageManager
|
|
{
|
|
public:
|
|
|
|
/** Returns the global instance of the MessageManager. */
|
|
static MessageManager* getInstance() throw();
|
|
|
|
/** Runs the event dispatch loop until a stop message is posted.
|
|
|
|
This method is only intended to be run by the application's startup routine,
|
|
as it blocks, and will only return after the stopDispatchLoop() method has been used.
|
|
|
|
@see stopDispatchLoop
|
|
*/
|
|
void runDispatchLoop();
|
|
|
|
/** Sends a signal that the dispatch loop should terminate.
|
|
|
|
After this is called, the runDispatchLoop() or runDispatchLoopUntil() methods
|
|
will be interrupted and will return.
|
|
|
|
@see runDispatchLoop
|
|
*/
|
|
void stopDispatchLoop();
|
|
|
|
/** Returns true if the stopDispatchLoop() method has been called.
|
|
*/
|
|
bool hasStopMessageBeenSent() const throw() { return quitMessagePosted; }
|
|
|
|
/** Synchronously dispatches messages until a given time has elapsed.
|
|
|
|
Returns false if a quit message has been posted by a call to stopDispatchLoop(),
|
|
otherwise returns true.
|
|
*/
|
|
bool runDispatchLoopUntil (int millisecondsToRunFor);
|
|
|
|
/** Calls a function using the message-thread.
|
|
|
|
This can be used by any thread to cause this function to be called-back
|
|
by the message thread. If it's the message-thread that's calling this method,
|
|
then the function will just be called; if another thread is calling, a message
|
|
will be posted to the queue, and this method will block until that message
|
|
is delivered, the function is called, and the result is returned.
|
|
|
|
Be careful not to cause any deadlocks with this! It's easy to do - e.g. if the caller
|
|
thread has a critical section locked, which an unrelated message callback then tries to lock
|
|
before the message thread gets round to processing this callback.
|
|
|
|
@param callback the function to call - its signature must be @code
|
|
void* myCallbackFunction (void*) @endcode
|
|
@param userData a user-defined pointer that will be passed to the function that gets called
|
|
@returns the value that the callback function returns.
|
|
@see MessageManagerLock
|
|
*/
|
|
void* callFunctionOnMessageThread (MessageCallbackFunction* callback,
|
|
void* userData);
|
|
|
|
/** Returns true if the caller-thread is the message thread. */
|
|
bool isThisTheMessageThread() const throw();
|
|
|
|
/** Called to tell the manager which thread is the one that's running the dispatch loop.
|
|
|
|
(Best to ignore this method unless you really know what you're doing..)
|
|
@see getCurrentMessageThread
|
|
*/
|
|
void setCurrentMessageThread (const Thread::ThreadID threadId) throw();
|
|
|
|
/** Returns the ID of the current message thread, as set by setCurrentMessageThread().
|
|
|
|
(Best to ignore this method unless you really know what you're doing..)
|
|
@see setCurrentMessageThread
|
|
*/
|
|
Thread::ThreadID getCurrentMessageThread() const throw() { return messageThreadId; }
|
|
|
|
/** Returns true if the caller thread has currenltly got the message manager locked.
|
|
|
|
see the MessageManagerLock class for more info about this.
|
|
|
|
This will be true if the caller is the message thread, because that automatically
|
|
gains a lock while a message is being dispatched.
|
|
*/
|
|
bool currentThreadHasLockedMessageManager() const throw();
|
|
|
|
/** Sends a message to all other JUCE applications that are running.
|
|
|
|
@param messageText the string that will be passed to the actionListenerCallback()
|
|
method of the broadcast listeners in the other app.
|
|
@see registerBroadcastListener, ActionListener
|
|
*/
|
|
static void broadcastMessage (const String& messageText) throw();
|
|
|
|
/** Registers a listener to get told about broadcast messages.
|
|
|
|
The actionListenerCallback() callback's string parameter
|
|
is the message passed into broadcastMessage().
|
|
|
|
@see broadcastMessage
|
|
*/
|
|
void registerBroadcastListener (ActionListener* listener) throw();
|
|
|
|
/** Deregisters a broadcast listener. */
|
|
void deregisterBroadcastListener (ActionListener* listener) throw();
|
|
|
|
/** @internal */
|
|
void deliverMessage (void*);
|
|
/** @internal */
|
|
void deliverBroadcastMessage (const String&);
|
|
/** @internal */
|
|
~MessageManager() throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
MessageManager() throw();
|
|
|
|
friend class MessageListener;
|
|
friend class ChangeBroadcaster;
|
|
friend class ActionBroadcaster;
|
|
friend class CallbackMessage;
|
|
static MessageManager* instance;
|
|
|
|
SortedSet<const MessageListener*> messageListeners;
|
|
ActionListenerList* broadcastListeners;
|
|
|
|
friend class JUCEApplication;
|
|
bool quitMessagePosted, quitMessageReceived;
|
|
Thread::ThreadID messageThreadId;
|
|
|
|
VoidArray modalComponents;
|
|
static void* exitModalLoopCallback (void*);
|
|
|
|
void postMessageToQueue (Message* const message);
|
|
void postCallbackMessage (Message* const message);
|
|
|
|
static void doPlatformSpecificInitialisation();
|
|
static void doPlatformSpecificShutdown();
|
|
|
|
friend class MessageManagerLock;
|
|
Thread::ThreadID volatile threadWithLock;
|
|
CriticalSection lockingLock;
|
|
|
|
MessageManager (const MessageManager&);
|
|
const MessageManager& operator= (const MessageManager&);
|
|
};
|
|
|
|
/** Used to make sure that the calling thread has exclusive access to the message loop.
|
|
|
|
Because it's not thread-safe to call any of the Component or other UI classes
|
|
from threads other than the message thread, one of these objects can be used to
|
|
lock the message loop and allow this to be done. The message thread will be
|
|
suspended for the lifetime of the MessageManagerLock object, so create one on
|
|
the stack like this: @code
|
|
void MyThread::run()
|
|
{
|
|
someData = 1234;
|
|
|
|
const MessageManagerLock mmLock;
|
|
// the event loop will now be locked so it's safe to make a few calls..
|
|
|
|
myComponent->setBounds (newBounds);
|
|
myComponent->repaint();
|
|
|
|
// ..the event loop will now be unlocked as the MessageManagerLock goes out of scope
|
|
}
|
|
@endcode
|
|
|
|
Obviously be careful not to create one of these and leave it lying around, or
|
|
your app will grind to a halt!
|
|
|
|
Another caveat is that using this in conjunction with other CriticalSections
|
|
can create lots of interesting ways of producing a deadlock! In particular, if
|
|
your message thread calls stopThread() for a thread that uses these locks,
|
|
you'll get an (occasional) deadlock..
|
|
|
|
@see MessageManager, MessageManager::currentThreadHasLockedMessageManager
|
|
*/
|
|
class JUCE_API MessageManagerLock
|
|
{
|
|
public:
|
|
|
|
/** Tries to acquire a lock on the message manager.
|
|
|
|
The constructor attempts to gain a lock on the message loop, and the lock will be
|
|
kept for the lifetime of this object.
|
|
|
|
Optionally, you can pass a thread object here, and while waiting to obtain the lock,
|
|
this method will keep checking whether the thread has been given the
|
|
Thread::signalThreadShouldExit() signal. If this happens, then it will return
|
|
without gaining the lock. If you pass a thread, you must check whether the lock was
|
|
successful by calling lockWasGained(). If this is false, your thread is being told to
|
|
die, so you should take evasive action.
|
|
|
|
If you pass zero for the thread object, it will wait indefinitely for the lock - be
|
|
careful when doing this, because it's very easy to deadlock if your message thread
|
|
attempts to call stopThread() on a thread just as that thread attempts to get the
|
|
message lock.
|
|
|
|
If the calling thread already has the lock, nothing will be done, so it's safe and
|
|
quick to use these locks recursively.
|
|
|
|
E.g.
|
|
@code
|
|
void run()
|
|
{
|
|
...
|
|
|
|
while (! threadShouldExit())
|
|
{
|
|
MessageManagerLock mml (Thread::getCurrentThread());
|
|
|
|
if (! mml.lockWasGained())
|
|
return; // another thread is trying to kill us!
|
|
|
|
..do some locked stuff here..
|
|
}
|
|
|
|
..and now the MM is now unlocked..
|
|
}
|
|
@endcode
|
|
|
|
*/
|
|
MessageManagerLock (Thread* const threadToCheckForExitSignal = 0) throw();
|
|
|
|
/** This has the same behaviour as the other constructor, but takes a ThreadPoolJob
|
|
instead of a thread.
|
|
|
|
See the MessageManagerLock (Thread*) constructor for details on how this works.
|
|
*/
|
|
MessageManagerLock (ThreadPoolJob* const jobToCheckForExitSignal) throw();
|
|
|
|
/** Releases the current thread's lock on the message manager.
|
|
|
|
Make sure this object is created and deleted by the same thread,
|
|
otherwise there are no guarantees what will happen!
|
|
*/
|
|
~MessageManagerLock() throw();
|
|
|
|
/** Returns true if the lock was successfully acquired.
|
|
|
|
(See the constructor that takes a Thread for more info).
|
|
*/
|
|
bool lockWasGained() const throw() { return locked; }
|
|
|
|
private:
|
|
bool locked, needsUnlocking;
|
|
void* sharedEvents;
|
|
|
|
void init (Thread* const thread, ThreadPoolJob* const job) throw();
|
|
};
|
|
|
|
#endif // __JUCE_MESSAGEMANAGER_JUCEHEADER__
|
|
/********* End of inlined file: juce_MessageManager.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MULTITIMER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MultiTimer.h *********/
|
|
#ifndef __JUCE_MULTITIMER_JUCEHEADER__
|
|
#define __JUCE_MULTITIMER_JUCEHEADER__
|
|
|
|
/**
|
|
A type of timer class that can run multiple timers with different frequencies,
|
|
all of which share a single callback.
|
|
|
|
This class is very similar to the Timer class, but allows you run multiple
|
|
separate timers, where each one has a unique ID number. The methods in this
|
|
class are exactly equivalent to those in Timer, but with the addition of
|
|
this ID number.
|
|
|
|
To use it, you need to create a subclass of MultiTimer, implementing the
|
|
timerCallback() method. Then you can start timers with startTimer(), and
|
|
each time the callback is triggered, it passes in the ID of the timer that
|
|
caused it.
|
|
|
|
@see Timer
|
|
*/
|
|
class JUCE_API MultiTimer
|
|
{
|
|
protected:
|
|
|
|
/** Creates a MultiTimer.
|
|
|
|
When created, no timers are running, so use startTimer() to start things off.
|
|
*/
|
|
MultiTimer() throw();
|
|
|
|
/** Creates a copy of another timer.
|
|
|
|
Note that this timer will not contain any running timers, even if the one you're
|
|
copying from was running.
|
|
*/
|
|
MultiTimer (const MultiTimer& other) throw();
|
|
|
|
public:
|
|
|
|
/** Destructor. */
|
|
virtual ~MultiTimer();
|
|
|
|
/** The user-defined callback routine that actually gets called by each of the
|
|
timers that are running.
|
|
|
|
It's perfectly ok to call startTimer() or stopTimer() from within this
|
|
callback to change the subsequent intervals.
|
|
*/
|
|
virtual void timerCallback (const int timerId) = 0;
|
|
|
|
/** Starts a timer and sets the length of interval required.
|
|
|
|
If the timer is already started, this will reset it, so the
|
|
time between calling this method and the next timer callback
|
|
will not be less than the interval length passed in.
|
|
|
|
@param timerId a unique Id number that identifies the timer to
|
|
start. This is the id that will be passed back
|
|
to the timerCallback() method when this timer is
|
|
triggered
|
|
@param intervalInMilliseconds the interval to use (any values less than 1 will be
|
|
rounded up to 1)
|
|
*/
|
|
void startTimer (const int timerId, const int intervalInMilliseconds) throw();
|
|
|
|
/** Stops a timer.
|
|
|
|
If a timer has been started with the given ID number, it will be cancelled.
|
|
No more callbacks will be made for the specified timer after this method returns.
|
|
|
|
If this is called from a different thread, any callbacks that may
|
|
be currently executing may be allowed to finish before the method
|
|
returns.
|
|
*/
|
|
void stopTimer (const int timerId) throw();
|
|
|
|
/** Checks whether a timer has been started for a specified ID.
|
|
|
|
@returns true if a timer with the given ID is running.
|
|
*/
|
|
bool isTimerRunning (const int timerId) const throw();
|
|
|
|
/** Returns the interval for a specified timer ID.
|
|
|
|
@returns the timer's interval in milliseconds if it's running, or 0 if it's no timer
|
|
is running for the ID number specified.
|
|
*/
|
|
int getTimerInterval (const int timerId) const throw();
|
|
|
|
private:
|
|
CriticalSection timerListLock;
|
|
VoidArray timers;
|
|
|
|
const MultiTimer& operator= (const MultiTimer&);
|
|
};
|
|
|
|
#endif // __JUCE_MULTITIMER_JUCEHEADER__
|
|
/********* End of inlined file: juce_MultiTimer.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TIMER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_BRUSH_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_GRADIENTBRUSH_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_GradientBrush.h *********/
|
|
#ifndef __JUCE_GRADIENTBRUSH_JUCEHEADER__
|
|
#define __JUCE_GRADIENTBRUSH_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ColourGradient.h *********/
|
|
#ifndef __JUCE_COLOURGRADIENT_JUCEHEADER__
|
|
#define __JUCE_COLOURGRADIENT_JUCEHEADER__
|
|
|
|
/**
|
|
Structure used to define a colour gradient for painting areas.
|
|
|
|
@see GradientBrush
|
|
*/
|
|
class JUCE_API ColourGradient
|
|
{
|
|
public:
|
|
|
|
/** Creates a gradient object.
|
|
|
|
(x1, y1) is the location to draw with colour1. Likewise (x2, y2) is where
|
|
colour2 should be. In between them there's a gradient.
|
|
|
|
If isRadial is true, the colours form a circular gradient with (x1, y1) at
|
|
its centre.
|
|
|
|
The alpha transparencies of the colours are used, so note that
|
|
if you blend from transparent to a solid colour, the RGB of the transparent
|
|
colour will become visible in parts of the gradient. e.g. blending
|
|
from Colour::transparentBlack to Colours::white will produce a
|
|
muddy grey colour midway, but Colour::transparentWhite to Colours::white
|
|
will be white all the way across.
|
|
|
|
@see ColourGradient
|
|
*/
|
|
ColourGradient (const Colour& colour1,
|
|
const float x1,
|
|
const float y1,
|
|
const Colour& colour2,
|
|
const float x2,
|
|
const float y2,
|
|
const bool isRadial) throw();
|
|
|
|
/** Creates an uninitialised gradient.
|
|
|
|
If you use this constructor instead of the other one, be sure to set all the
|
|
object's public member variables before using it!
|
|
*/
|
|
ColourGradient() throw();
|
|
|
|
/** Destructor */
|
|
~ColourGradient() throw();
|
|
|
|
/** Removes any colours that have been added.
|
|
|
|
This will also remove any start and end colours, so the gradient won't work. You'll
|
|
need to add more colours with addColour().
|
|
*/
|
|
void clearColours() throw();
|
|
|
|
/** Adds a colour at a point along the length of the gradient.
|
|
|
|
This allows the gradient to go through a spectrum of colours, instead of just a
|
|
start and end colour.
|
|
|
|
@param proportionAlongGradient a value between 0 and 1.0, which is the proportion
|
|
of the distance along the line between the two points
|
|
at which the colour should occur.
|
|
@param colour the colour that should be used at this point
|
|
*/
|
|
void addColour (const double proportionAlongGradient,
|
|
const Colour& colour) throw();
|
|
|
|
/** Multiplies the alpha value of all the colours by the given scale factor */
|
|
void multiplyOpacity (const float multiplier) throw();
|
|
|
|
/** Returns the number of colour-stops that have been added. */
|
|
int getNumColours() const throw();
|
|
|
|
/** Returns the position along the length of the gradient of the colour with this index.
|
|
|
|
The index is from 0 to getNumColours() - 1. The return value will be between 0.0 and 1.0
|
|
*/
|
|
double getColourPosition (const int index) const throw();
|
|
|
|
/** Returns the colour that was added with a given index.
|
|
|
|
The index is from 0 to getNumColours() - 1. The return value will be between 0.0 and 1.0
|
|
*/
|
|
const Colour getColour (const int index) const throw();
|
|
|
|
/** Creates a set of interpolated premultiplied ARGB values.
|
|
|
|
The caller must delete the array that is returned using juce_free().
|
|
*/
|
|
PixelARGB* createLookupTable (int& numEntries) const throw();
|
|
|
|
/** Returns true if all colours are opaque. */
|
|
bool isOpaque() const throw();
|
|
|
|
/** Returns true if all colours are completely transparent. */
|
|
bool isInvisible() const throw();
|
|
|
|
float x1;
|
|
float y1;
|
|
|
|
float x2;
|
|
float y2;
|
|
|
|
/** If true, the gradient should be filled circularly, centred around
|
|
(x1, y1), with (x2, y2) defining a point on the circumference.
|
|
|
|
If false, the gradient is linear between the two points.
|
|
*/
|
|
bool isRadial;
|
|
|
|
/** A transform to apply to the resultant gradient shape */
|
|
AffineTransform transform;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Array <uint32> colours;
|
|
};
|
|
|
|
#endif // __JUCE_COLOURGRADIENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_ColourGradient.h *********/
|
|
|
|
/**
|
|
A Brush that fills areas with a colour gradient.
|
|
|
|
The gradient can either be linear or circular.
|
|
|
|
@see Brush, Graphics::setBrush, SolidColourBrush, ImageBrush
|
|
*/
|
|
class JUCE_API GradientBrush : public Brush
|
|
{
|
|
public:
|
|
|
|
/** Creates a gradient brush, ready for use in Graphics::setBrush().
|
|
|
|
(x1, y1) is the location relative to the origin of the Graphics context,
|
|
at which the colour should be colour1. Likewise for (x2, y2) and colour2.
|
|
|
|
If isRadial is true, the colours form a circular gradient with (x1, y1) at
|
|
its centre.
|
|
|
|
The alpha transparencies of the colours are used, so the brush
|
|
need not be completely opaque. Note that this means that if you
|
|
blend from transparent to a solid colour, the RGB of the transparent
|
|
colour will become visible in parts of the gradient. e.g. blending
|
|
from Colour::transparentBlack to Colours::white will produce a
|
|
grey colour, but Colour::transparentWhite to Colours::white will be
|
|
white all the way across.
|
|
|
|
@see ColourGradient
|
|
*/
|
|
GradientBrush (const Colour& colour1,
|
|
const float x1,
|
|
const float y1,
|
|
const Colour& colour2,
|
|
const float x2,
|
|
const float y2,
|
|
const bool isRadial) throw();
|
|
|
|
/** Creates a gradient brush from a ColourGradient object.
|
|
*/
|
|
GradientBrush (const ColourGradient& gradient) throw();
|
|
|
|
/** Destructor. */
|
|
~GradientBrush() throw();
|
|
|
|
/** Returns the current gradient information */
|
|
const ColourGradient& getGradient() const throw() { return gradient; }
|
|
|
|
Brush* createCopy() const throw();
|
|
|
|
void applyTransform (const AffineTransform& transform) throw();
|
|
|
|
void multiplyOpacity (const float multiple) throw();
|
|
|
|
bool isInvisible() const throw();
|
|
|
|
void paintPath (LowLevelGraphicsContext& context,
|
|
const Path& path, const AffineTransform& transform) throw();
|
|
|
|
void paintRectangle (LowLevelGraphicsContext& context,
|
|
int x, int y, int w, int h) throw();
|
|
|
|
void paintAlphaChannel (LowLevelGraphicsContext& context,
|
|
const Image& alphaChannelImage, int imageX, int imageY,
|
|
int x, int y, int w, int h) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
ColourGradient gradient;
|
|
|
|
private:
|
|
GradientBrush (const GradientBrush&);
|
|
const GradientBrush& operator= (const GradientBrush&);
|
|
};
|
|
|
|
#endif // __JUCE_GRADIENTBRUSH_JUCEHEADER__
|
|
/********* End of inlined file: juce_GradientBrush.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_IMAGEBRUSH_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ImageBrush.h *********/
|
|
#ifndef __JUCE_IMAGEBRUSH_JUCEHEADER__
|
|
#define __JUCE_IMAGEBRUSH_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Image.h *********/
|
|
#ifndef __JUCE_IMAGE_JUCEHEADER__
|
|
#define __JUCE_IMAGE_JUCEHEADER__
|
|
|
|
/**
|
|
Holds a fixed-size bitmap.
|
|
|
|
The image is stored in either 24-bit RGB or 32-bit premultiplied-ARGB format.
|
|
|
|
To draw into an image, create a Graphics object for it.
|
|
e.g. @code
|
|
|
|
// create a transparent 500x500 image..
|
|
Image myImage (Image::RGB, 500, 500, true);
|
|
|
|
Graphics g (myImage);
|
|
g.setColour (Colours::red);
|
|
g.fillEllipse (20, 20, 300, 200); // draws a red ellipse in our image.
|
|
@endcode
|
|
|
|
Other useful ways to create an image are with the ImageCache class, or the
|
|
ImageFileFormat, which provides a way to load common image files.
|
|
|
|
@see Graphics, ImageFileFormat, ImageCache, ImageConvolutionKernel
|
|
*/
|
|
class JUCE_API Image
|
|
{
|
|
public:
|
|
|
|
enum PixelFormat
|
|
{
|
|
RGB, /**<< each pixel is a 3-byte packed RGB colour value. For byte order, see the PixelRGB class. */
|
|
ARGB, /**<< each pixel is a 4-byte ARGB premultiplied colour value. For byte order, see the PixelARGB class. */
|
|
SingleChannel /**<< each pixel is a 1-byte alpha channel value. */
|
|
};
|
|
|
|
/** Creates an in-memory image with a specified size and format.
|
|
|
|
@param format the number of colour channels in the image
|
|
@param imageWidth the desired width of the image, in pixels - this value must be
|
|
greater than zero (otherwise a width of 1 will be used)
|
|
@param imageHeight the desired width of the image, in pixels - this value must be
|
|
greater than zero (otherwise a height of 1 will be used)
|
|
@param clearImage if true, the image will initially be cleared to black or transparent
|
|
black. If false, the image may contain random data, and the
|
|
user will have to deal with this
|
|
*/
|
|
Image (const PixelFormat format,
|
|
const int imageWidth,
|
|
const int imageHeight,
|
|
const bool clearImage);
|
|
|
|
/** Creates a copy of another image.
|
|
|
|
@see createCopy
|
|
*/
|
|
Image (const Image& other);
|
|
|
|
/** Destructor. */
|
|
virtual ~Image();
|
|
|
|
/** Returns the image's width (in pixels). */
|
|
int getWidth() const throw() { return imageWidth; }
|
|
|
|
/** Returns the image's height (in pixels). */
|
|
int getHeight() const throw() { return imageHeight; }
|
|
|
|
/** Returns the image's pixel format. */
|
|
PixelFormat getFormat() const throw() { return format; }
|
|
|
|
/** True if the image's format is ARGB. */
|
|
bool isARGB() const throw() { return format == ARGB; }
|
|
|
|
/** True if the image's format is RGB. */
|
|
bool isRGB() const throw() { return format == RGB; }
|
|
|
|
/** True if the image contains an alpha-channel. */
|
|
bool hasAlphaChannel() const throw() { return format != RGB; }
|
|
|
|
/** Clears a section of the image with a given colour.
|
|
|
|
This won't do any alpha-blending - it just sets all pixels in the image to
|
|
the given colour (which may be non-opaque if the image has an alpha channel).
|
|
*/
|
|
virtual void clear (int x, int y, int w, int h,
|
|
const Colour& colourToClearTo = Colour (0x00000000));
|
|
|
|
/** Returns a new image that's a copy of this one.
|
|
|
|
A new size for the copied image can be specified, or values less than
|
|
zero can be passed-in to use the image's existing dimensions.
|
|
|
|
It's up to the caller to delete the image when no longer needed.
|
|
*/
|
|
virtual Image* createCopy (int newWidth = -1,
|
|
int newHeight = -1,
|
|
const Graphics::ResamplingQuality quality = Graphics::mediumResamplingQuality) const;
|
|
|
|
/** Returns the colour of one of the pixels in the image.
|
|
|
|
If the co-ordinates given are beyond the image's boundaries, this will
|
|
return Colours::transparentBlack.
|
|
|
|
(0, 0) is the image's top-left corner.
|
|
|
|
@see getAlphaAt, setPixelAt, blendPixelAt
|
|
*/
|
|
virtual const Colour getPixelAt (const int x, const int y) const;
|
|
|
|
/** Sets the colour of one of the image's pixels.
|
|
|
|
If the co-ordinates are beyond the image's boundaries, then nothing will
|
|
happen.
|
|
|
|
Note that unlike blendPixelAt(), this won't do any alpha-blending, it'll
|
|
just replace the existing pixel with the given one. The colour's opacity
|
|
will be ignored if this image doesn't have an alpha-channel.
|
|
|
|
(0, 0) is the image's top-left corner.
|
|
|
|
@see blendPixelAt
|
|
*/
|
|
virtual void setPixelAt (const int x, const int y, const Colour& colour);
|
|
|
|
/** Changes the opacity of a pixel.
|
|
|
|
This only has an effect if the image has an alpha channel and if the
|
|
given co-ordinates are inside the image's boundary.
|
|
|
|
The multiplier must be in the range 0 to 1.0, and the current alpha
|
|
at the given co-ordinates will be multiplied by this value.
|
|
|
|
@see getAlphaAt, setPixelAt
|
|
*/
|
|
virtual void multiplyAlphaAt (const int x, const int y, const float multiplier);
|
|
|
|
/** Changes the overall opacity of the image.
|
|
|
|
This will multiply the alpha value of each pixel in the image by the given
|
|
amount (limiting the resulting alpha values between 0 and 255). This allows
|
|
you to make an image more or less transparent.
|
|
|
|
If the image doesn't have an alpha channel, this won't have any effect.
|
|
*/
|
|
virtual void multiplyAllAlphas (const float amountToMultiplyBy);
|
|
|
|
/** Changes all the colours to be shades of grey, based on their current luminosity.
|
|
*/
|
|
virtual void desaturate();
|
|
|
|
/** Locks some of the pixels in the image so they can be read and written to.
|
|
|
|
This returns a pointer to some memory containing the pixels in the given
|
|
rectangle. It also returns values for the line and pixel stride used within
|
|
the data. The format of the pixel data is the same as that of this image.
|
|
|
|
When you've finished reading and changing the data, you must call
|
|
releasePixelDataReadWrite() to give the pixels back to the image.
|
|
|
|
For images that are stored in memory, this method may just return a direct
|
|
pointer to the image's data, but other types of image may be stored elsewhere,
|
|
e.g. in video memory, and if so, this lockPixelDataReadWrite() and
|
|
releasePixelDataReadWrite() may need to create a temporary copy in main memory.
|
|
|
|
If you only need read-access to the pixel data, use lockPixelDataReadOnly()
|
|
instead.
|
|
|
|
@see releasePixelDataReadWrite, lockPixelDataReadOnly
|
|
*/
|
|
virtual uint8* lockPixelDataReadWrite (int x, int y, int w, int h, int& lineStride, int& pixelStride);
|
|
|
|
/** Releases a block of memory that was locked with lockPixelDataReadWrite().
|
|
*/
|
|
virtual void releasePixelDataReadWrite (void* sourceData);
|
|
|
|
/** Locks some of the pixels in the image so they can be read.
|
|
|
|
This returns a pointer to some memory containing the pixels in the given
|
|
rectangle. It also returns values for the line and pixel stride used within
|
|
the data. The format of the pixel data is the same as that of this image.
|
|
|
|
When you've finished reading the data, you must call releasePixelDataReadOnly()
|
|
to let the image free the memory if necessary.
|
|
|
|
For images that are stored in memory, this method may just return a direct
|
|
pointer to the image's data, but other types of image may be stored elsewhere,
|
|
e.g. in video memory, and if so, this lockPixelDataReadWrite() and
|
|
releasePixelDataReadWrite() may need to create a temporary copy in main memory.
|
|
|
|
If you only need to read and write the pixel data, use lockPixelDataReadWrite()
|
|
instead.
|
|
|
|
@see releasePixelDataReadOnly, lockPixelDataReadWrite
|
|
*/
|
|
virtual const uint8* lockPixelDataReadOnly (int x, int y, int w, int h, int& lineStride, int& pixelStride) const;
|
|
|
|
/** Releases a block of memory that was locked with lockPixelDataReadOnly().
|
|
*/
|
|
virtual void releasePixelDataReadOnly (const void* sourceData) const;
|
|
|
|
/** Copies some pixel values to a rectangle of the image.
|
|
|
|
The format of the pixel data must match that of the image itself, and the
|
|
rectangle supplied must be within the image's bounds.
|
|
*/
|
|
virtual void setPixelData (int destX, int destY, int destW, int destH,
|
|
const uint8* sourcePixelData, int sourceLineStride);
|
|
|
|
/** Copies a section of the image to somewhere else within itself.
|
|
*/
|
|
virtual void moveImageSection (int destX, int destY,
|
|
int sourceX, int sourceY,
|
|
int width, int height);
|
|
|
|
/** Creates a RectangleList containing rectangles for all non-transparent pixels
|
|
of the image.
|
|
|
|
@param result the list that will have the area added to it
|
|
@param alphaThreshold for a semi-transparent image, any pixels whose alpha is
|
|
above this level will be considered opaque
|
|
*/
|
|
void createSolidAreaMask (RectangleList& result,
|
|
const float alphaThreshold = 0.5f) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
/** Creates a context suitable for drawing onto this image.
|
|
|
|
Don't call this method directly! It's used internally by the Graphics class.
|
|
*/
|
|
virtual LowLevelGraphicsContext* createLowLevelContext();
|
|
|
|
protected:
|
|
const PixelFormat format;
|
|
const int imageWidth, imageHeight;
|
|
|
|
/** Used internally so that subclasses can call a constructor that doesn't allocate memory */
|
|
Image (const PixelFormat format,
|
|
const int imageWidth,
|
|
const int imageHeight);
|
|
|
|
int pixelStride, lineStride;
|
|
uint8* imageData;
|
|
|
|
private:
|
|
|
|
const Image& operator= (const Image&);
|
|
};
|
|
|
|
#endif // __JUCE_IMAGE_JUCEHEADER__
|
|
/********* End of inlined file: juce_Image.h *********/
|
|
|
|
/**
|
|
A Brush that fills areas with tiled repetitions of an image.
|
|
|
|
@see Brush, Graphics::setBrush, SolidColourBrush, GradientBrush
|
|
*/
|
|
class JUCE_API ImageBrush : public Brush
|
|
{
|
|
public:
|
|
|
|
/* Creates an image brush, ready for use in Graphics::setBrush().
|
|
|
|
(x, y) is an anchor point for the top-left of the image
|
|
A reference to the image passed in will be kept, so don't delete
|
|
it within the lifetime of this object
|
|
*/
|
|
ImageBrush (Image* const image,
|
|
const int anchorX,
|
|
const int anchorY,
|
|
const float opacity) throw();
|
|
|
|
/** Destructor. */
|
|
~ImageBrush() throw();
|
|
|
|
/** Returns the image currently being used. */
|
|
Image* getImage() const throw() { return image; }
|
|
|
|
/** Returns the current anchor X position. */
|
|
int getAnchorX() const throw() { return anchorX; }
|
|
|
|
/** Returns the current anchor Y position. */
|
|
int getAnchorY() const throw() { return anchorY; }
|
|
|
|
/** Returns the current opacity. */
|
|
float getOpacity() const throw() { return opacity; }
|
|
|
|
Brush* createCopy() const throw();
|
|
|
|
void applyTransform (const AffineTransform& transform) throw();
|
|
|
|
void multiplyOpacity (const float multiple) throw();
|
|
|
|
bool isInvisible() const throw();
|
|
|
|
void paintPath (LowLevelGraphicsContext& context,
|
|
const Path& path, const AffineTransform& transform) throw();
|
|
|
|
void paintRectangle (LowLevelGraphicsContext& context,
|
|
int x, int y, int w, int h) throw();
|
|
|
|
void paintAlphaChannel (LowLevelGraphicsContext& context,
|
|
const Image& alphaChannelImage, int imageX, int imageY,
|
|
int x, int y, int w, int h) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
Image* image;
|
|
int anchorX, anchorY;
|
|
float opacity;
|
|
|
|
private:
|
|
ImageBrush (const ImageBrush&);
|
|
const ImageBrush& operator= (const ImageBrush&);
|
|
|
|
void getStartXY (int& x, int& y) const throw();
|
|
};
|
|
|
|
#endif // __JUCE_IMAGEBRUSH_JUCEHEADER__
|
|
/********* End of inlined file: juce_ImageBrush.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_SOLIDCOLOURBRUSH_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_COLOUR_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_COLOURGRADIENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_COLOURS_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_PIXELFORMATS_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_FONT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_GLYPHARRANGEMENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_GlyphArrangement.h *********/
|
|
#ifndef __JUCE_GLYPHARRANGEMENT_JUCEHEADER__
|
|
#define __JUCE_GLYPHARRANGEMENT_JUCEHEADER__
|
|
|
|
/**
|
|
An glyph from a particular font, with a particular size, style,
|
|
typeface and position.
|
|
|
|
@see GlyphArrangement, Font
|
|
*/
|
|
class JUCE_API PositionedGlyph
|
|
{
|
|
public:
|
|
|
|
/** Returns the character the glyph represents. */
|
|
juce_wchar getCharacter() const throw() { return glyphInfo->getCharacter(); }
|
|
/** Checks whether the glyph is actually empty. */
|
|
bool isWhitespace() const throw() { return CharacterFunctions::isWhitespace (glyphInfo->getCharacter()); }
|
|
|
|
/** Returns the position of the glyph's left-hand edge. */
|
|
float getLeft() const throw() { return x; }
|
|
/** Returns the position of the glyph's right-hand edge. */
|
|
float getRight() const throw() { return x + w; }
|
|
/** Returns the y position of the glyph's baseline. */
|
|
float getBaselineY() const throw() { return y; }
|
|
/** Returns the y position of the top of the glyph. */
|
|
float getTop() const throw() { return y - fontAscent; }
|
|
/** Returns the y position of the bottom of the glyph. */
|
|
float getBottom() const throw() { return y + fontHeight - fontAscent; }
|
|
|
|
/** Shifts the glyph's position by a relative amount. */
|
|
void moveBy (const float deltaX,
|
|
const float deltaY) throw();
|
|
|
|
/** Draws the glyph into a graphics context. */
|
|
void draw (const Graphics& g) const throw();
|
|
|
|
/** Draws the glyph into a graphics context, with an extra transform applied to it. */
|
|
void draw (const Graphics& g, const AffineTransform& transform) const throw();
|
|
|
|
/** Returns the path for this glyph.
|
|
|
|
@param path the glyph's outline will be appended to this path
|
|
*/
|
|
void createPath (Path& path) const throw();
|
|
|
|
/** Checks to see if a point lies within this glyph. */
|
|
bool hitTest (float x, float y) const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
friend class GlyphArrangement;
|
|
float x, y, w;
|
|
float fontHeight, fontAscent, fontHorizontalScale;
|
|
bool isUnderlined;
|
|
const TypefaceGlyphInfo* glyphInfo;
|
|
|
|
PositionedGlyph() throw();
|
|
};
|
|
|
|
/**
|
|
A set of glyphs, each with a position.
|
|
|
|
You can create a GlyphArrangement, text to it and then draw it onto a
|
|
graphics context. It's used internally by the text methods in the
|
|
Graphics class, but can be used directly if more control is needed.
|
|
|
|
@see Font, PositionedGlyph
|
|
*/
|
|
class JUCE_API GlyphArrangement
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty arrangement. */
|
|
GlyphArrangement() throw();
|
|
|
|
/** Takes a copy of another arrangement. */
|
|
GlyphArrangement (const GlyphArrangement& other) throw();
|
|
|
|
/** Copies another arrangement onto this one.
|
|
|
|
To add another arrangement without clearing this one, use addGlyphArrangement().
|
|
*/
|
|
const GlyphArrangement& operator= (const GlyphArrangement& other) throw();
|
|
|
|
/** Destructor. */
|
|
~GlyphArrangement() throw();
|
|
|
|
/** Returns the total number of glyphs in the arrangement. */
|
|
int getNumGlyphs() const throw() { return numGlyphs; }
|
|
|
|
/** Returns one of the glyphs from the arrangement.
|
|
|
|
@param index the glyph's index, from 0 to (getNumGlyphs() - 1). Be
|
|
careful not to pass an out-of-range index here, as it
|
|
doesn't do any bounds-checking.
|
|
*/
|
|
PositionedGlyph& getGlyph (const int index) const throw();
|
|
|
|
/** Clears all text from the arrangement and resets it.
|
|
*/
|
|
void clear() throw();
|
|
|
|
/** Appends a line of text to the arrangement.
|
|
|
|
This will add the text as a single line, where x is the left-hand edge of the
|
|
first character, and y is the position for the text's baseline.
|
|
|
|
If the text contains new-lines or carriage-returns, this will ignore them - use
|
|
addJustifiedText() to add multi-line arrangements.
|
|
*/
|
|
void addLineOfText (const Font& font,
|
|
const String& text,
|
|
const float x,
|
|
const float y) throw();
|
|
|
|
/** Adds a line of text, truncating it if it's wider than a specified size.
|
|
|
|
This is the same as addLineOfText(), but if the line's width exceeds the value
|
|
specified in maxWidthPixels, it will be truncated using either ellipsis (i.e. dots: "..."),
|
|
if useEllipsis is true, or if this is false, it will just drop any subsequent characters.
|
|
*/
|
|
void addCurtailedLineOfText (const Font& font,
|
|
const String& text,
|
|
float x,
|
|
const float y,
|
|
const float maxWidthPixels,
|
|
const bool useEllipsis) throw();
|
|
|
|
/** Adds some multi-line text, breaking lines at word-boundaries if they are too wide.
|
|
|
|
This will add text to the arrangement, breaking it into new lines either where there
|
|
is a new-line or carriage-return character in the text, or where a line's width
|
|
exceeds the value set in maxLineWidth.
|
|
|
|
Each line that is added will be laid out using the flags set in horizontalLayout, so
|
|
the lines can be left- or right-justified, or centred horizontally in the space
|
|
between x and (x + maxLineWidth).
|
|
|
|
The y co-ordinate is the position of the baseline of the first line of text - subsequent
|
|
lines will be placed below it, separated by a distance of font.getHeight().
|
|
*/
|
|
void addJustifiedText (const Font& font,
|
|
const String& text,
|
|
float x, float y,
|
|
const float maxLineWidth,
|
|
const Justification& horizontalLayout) throw();
|
|
|
|
/** Tries to fit some text withing a given space.
|
|
|
|
This does its best to make the given text readable within the specified rectangle,
|
|
so it useful for labelling things.
|
|
|
|
If the text is too big, it'll be squashed horizontally or broken over multiple lines
|
|
if the maximumLinesToUse value allows this. If the text just won't fit into the space,
|
|
it'll cram as much as possible in there, and put some ellipsis at the end to show that
|
|
it's been truncated.
|
|
|
|
A Justification parameter lets you specify how the text is laid out within the rectangle,
|
|
both horizontally and vertically.
|
|
|
|
@see Graphics::drawFittedText
|
|
*/
|
|
void addFittedText (const Font& font,
|
|
const String& text,
|
|
float x, float y,
|
|
float width, float height,
|
|
const Justification& layout,
|
|
int maximumLinesToUse,
|
|
const float minimumHorizontalScale = 0.7f) throw();
|
|
|
|
/** Appends another glyph arrangement to this one. */
|
|
void addGlyphArrangement (const GlyphArrangement& other) throw();
|
|
|
|
/** Draws this glyph arrangement to a graphics context.
|
|
|
|
This uses cached bitmaps so is much faster than the draw (Graphics&, const AffineTransform&)
|
|
method, which renders the glyphs as filled vectors.
|
|
*/
|
|
void draw (const Graphics& g) const throw();
|
|
|
|
/** Draws this glyph arrangement to a graphics context.
|
|
|
|
This renders the paths as filled vectors, so is far slower than the draw (Graphics&)
|
|
method for non-transformed arrangements.
|
|
*/
|
|
void draw (const Graphics& g, const AffineTransform& transform) const throw();
|
|
|
|
/** Converts the set of glyphs into a path.
|
|
|
|
@param path the glyphs' outlines will be appended to this path
|
|
*/
|
|
void createPath (Path& path) const throw();
|
|
|
|
/** Looks for a glyph that contains the given co-ordinate.
|
|
|
|
@returns the index of the glyph, or -1 if none were found.
|
|
*/
|
|
int findGlyphIndexAt (float x, float y) const throw();
|
|
|
|
/** Finds the smallest rectangle that will enclose a subset of the glyphs.
|
|
|
|
@param startIndex the first glyph to test
|
|
@param numGlyphs the number of glyphs to include; if this is < 0, all glyphs after
|
|
startIndex will be included
|
|
@param left on return, the leftmost co-ordinate of the rectangle
|
|
@param top on return, the top co-ordinate of the rectangle
|
|
@param right on return, the rightmost co-ordinate of the rectangle
|
|
@param bottom on return, the bottom co-ordinate of the rectangle
|
|
@param includeWhitespace if true, the extent of any whitespace characters will also
|
|
be taken into account
|
|
*/
|
|
void getBoundingBox (int startIndex,
|
|
int numGlyphs,
|
|
float& left,
|
|
float& top,
|
|
float& right,
|
|
float& bottom,
|
|
const bool includeWhitespace) const throw();
|
|
|
|
/** Shifts a set of glyphs by a given amount.
|
|
|
|
@param startIndex the first glyph to transform
|
|
@param numGlyphs the number of glyphs to move; if this is < 0, all glyphs after
|
|
startIndex will be used
|
|
@param deltaX the amount to add to their x-positions
|
|
@param deltaY the amount to add to their y-positions
|
|
*/
|
|
void moveRangeOfGlyphs (int startIndex, int numGlyphs,
|
|
const float deltaX,
|
|
const float deltaY) throw();
|
|
|
|
/** Removes a set of glyphs from the arrangement.
|
|
|
|
@param startIndex the first glyph to remove
|
|
@param numGlyphs the number of glyphs to remove; if this is < 0, all glyphs after
|
|
startIndex will be deleted
|
|
*/
|
|
void removeRangeOfGlyphs (int startIndex, int numGlyphs) throw();
|
|
|
|
/** Expands or compresses a set of glyphs horizontally.
|
|
|
|
@param startIndex the first glyph to transform
|
|
@param numGlyphs the number of glyphs to stretch; if this is < 0, all glyphs after
|
|
startIndex will be used
|
|
@param horizontalScaleFactor how much to scale their horizontal width by
|
|
*/
|
|
void stretchRangeOfGlyphs (int startIndex, int numGlyphs,
|
|
const float horizontalScaleFactor) throw();
|
|
|
|
/** Justifies a set of glyphs within a given space.
|
|
|
|
This moves the glyphs as a block so that the whole thing is located within the
|
|
given rectangle with the specified layout.
|
|
|
|
If the Justification::horizontallyJustified flag is specified, each line will
|
|
be stretched out to fill the specified width.
|
|
*/
|
|
void justifyGlyphs (const int startIndex, const int numGlyphs,
|
|
const float x,
|
|
const float y,
|
|
const float width,
|
|
const float height,
|
|
const Justification& justification) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int numGlyphs, numAllocated;
|
|
PositionedGlyph* glyphs;
|
|
|
|
void ensureNumGlyphsAllocated (int minGlyphs) throw();
|
|
void removeLast() throw();
|
|
void appendEllipsis (const Font& font, const float maxXPixels) throw();
|
|
|
|
void incGlyphRefCount (const int index) const throw();
|
|
void decGlyphRefCount (const int index) const throw();
|
|
|
|
void spreadOutLine (const int start, const int numGlyphs, const float targetWidth) throw();
|
|
};
|
|
|
|
#endif // __JUCE_GLYPHARRANGEMENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_GlyphArrangement.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TEXTLAYOUT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_TextLayout.h *********/
|
|
#ifndef __JUCE_TEXTLAYOUT_JUCEHEADER__
|
|
#define __JUCE_TEXTLAYOUT_JUCEHEADER__
|
|
|
|
class Graphics;
|
|
|
|
/**
|
|
A laid-out arrangement of text.
|
|
|
|
You can add text in different fonts to a TextLayout object, then call its
|
|
layout() method to word-wrap it into lines. The layout can then be drawn
|
|
using a graphics context.
|
|
|
|
It's handy if you've got a message to display, because you can format it,
|
|
measure the extent of the layout, and then create a suitably-sized window
|
|
to show it in.
|
|
|
|
@see Font, Graphics::drawFittedText, GlyphArrangement
|
|
*/
|
|
class JUCE_API TextLayout
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty text layout.
|
|
|
|
Text can then be appended using the appendText() method.
|
|
*/
|
|
TextLayout() throw();
|
|
|
|
/** Creates a copy of another layout object. */
|
|
TextLayout (const TextLayout& other) throw();
|
|
|
|
/** Creates a text layout from an initial string and font. */
|
|
TextLayout (const String& text, const Font& font) throw();
|
|
|
|
/** Destructor. */
|
|
~TextLayout() throw();
|
|
|
|
/** Copies another layout onto this one. */
|
|
const TextLayout& operator= (const TextLayout& layoutToCopy) throw();
|
|
|
|
/** Clears the layout, removing all its text. */
|
|
void clear() throw();
|
|
|
|
/** Adds a string to the end of the arrangement.
|
|
|
|
The string will be broken onto new lines wherever it contains
|
|
carriage-returns or linefeeds. After adding it, you can call layout()
|
|
to wrap long lines into a paragraph and justify it.
|
|
*/
|
|
void appendText (const String& textToAppend,
|
|
const Font& fontToUse) throw();
|
|
|
|
/** Replaces all the text with a new string.
|
|
|
|
This is equivalent to calling clear() followed by appendText().
|
|
*/
|
|
void setText (const String& newText,
|
|
const Font& fontToUse) throw();
|
|
|
|
/** Breaks the text up to form a paragraph with the given width.
|
|
|
|
@param maximumWidth any text wider than this will be split
|
|
across multiple lines
|
|
@param justification how the lines are to be laid-out horizontally
|
|
@param attemptToBalanceLineLengths if true, it will try to split the lines at a
|
|
width that keeps all the lines of text at a
|
|
similar length - this is good when you're displaying
|
|
a short message and don't want it to get split
|
|
onto two lines with only a couple of words on
|
|
the second line, which looks untidy.
|
|
*/
|
|
void layout (int maximumWidth,
|
|
const Justification& justification,
|
|
const bool attemptToBalanceLineLengths) throw();
|
|
|
|
/** Returns the overall width of the entire text layout. */
|
|
int getWidth() const throw();
|
|
|
|
/** Returns the overall height of the entire text layout. */
|
|
int getHeight() const throw();
|
|
|
|
/** Returns the total number of lines of text. */
|
|
int getNumLines() const throw() { return totalLines; }
|
|
|
|
/** Returns the width of a particular line of text.
|
|
|
|
@param lineNumber the line, from 0 to (getNumLines() - 1)
|
|
*/
|
|
int getLineWidth (const int lineNumber) const throw();
|
|
|
|
/** Renders the text at a specified position using a graphics context.
|
|
*/
|
|
void draw (Graphics& g,
|
|
const int topLeftX,
|
|
const int topLeftY) const throw();
|
|
|
|
/** Renders the text within a specified rectangle using a graphics context.
|
|
|
|
The justification flags dictate how the block of text should be positioned
|
|
within the rectangle.
|
|
*/
|
|
void drawWithin (Graphics& g,
|
|
int x, int y, int w, int h,
|
|
const Justification& layoutFlags) const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
VoidArray tokens;
|
|
int totalLines;
|
|
};
|
|
|
|
#endif // __JUCE_TEXTLAYOUT_JUCEHEADER__
|
|
/********* End of inlined file: juce_TextLayout.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TYPEFACE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_EDGETABLE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_EdgeTable.h *********/
|
|
#ifndef __JUCE_EDGETABLE_JUCEHEADER__
|
|
#define __JUCE_EDGETABLE_JUCEHEADER__
|
|
|
|
class Path;
|
|
|
|
static const int juce_edgeTableDefaultEdgesPerLine = 10;
|
|
|
|
/**
|
|
A table of horizontal scan-line segments - used for rasterising Paths.
|
|
|
|
@see Path, Graphics
|
|
*/
|
|
class JUCE_API EdgeTable
|
|
{
|
|
public:
|
|
|
|
/** Indicates the quality at which the edge table should be generated.
|
|
|
|
Higher values will have better quality anti-aliasing, but will take
|
|
longer to generate the edge table and to render it.
|
|
*/
|
|
enum OversamplingLevel
|
|
{
|
|
Oversampling_none = 0, /**< No vertical anti-aliasing at all. */
|
|
Oversampling_4times = 2, /**< Anti-aliased with 4 levels of grey - good enough for normal use. */
|
|
Oversampling_16times = 4, /**< Anti-aliased with 16 levels of grey - very good quality. */
|
|
Oversampling_32times = 5, /**< Anti-aliased with 32 levels of grey - very good quality but slower. */
|
|
Oversampling_256times = 8 /**< Anti-aliased with 256 levels of grey - best quality, but too slow for
|
|
normal user-interface use. */
|
|
};
|
|
|
|
/** Creates an empty edge table ready to have paths added.
|
|
|
|
A table is created with a fixed vertical size, and only sections of paths
|
|
which lie within their range will be added to the table.
|
|
|
|
@param topY the lowest y co-ordinate that the table can contain
|
|
@param height the number of horizontal lines it can contain
|
|
@param verticalOversampling the amount of oversampling used for anti-aliasing
|
|
@param expectedEdgesPerLine used to optimise the table's internal data usage - it's not
|
|
worth changing this except for very special purposes
|
|
*/
|
|
EdgeTable (const int topY,
|
|
const int height,
|
|
const OversamplingLevel verticalOversampling = Oversampling_4times,
|
|
const int expectedEdgesPerLine = juce_edgeTableDefaultEdgesPerLine) throw();
|
|
|
|
/** Creates a copy of another edge table. */
|
|
EdgeTable (const EdgeTable& other) throw();
|
|
|
|
/** Copies from another edge table. */
|
|
const EdgeTable& operator= (const EdgeTable& other) throw();
|
|
|
|
/** Destructor. */
|
|
~EdgeTable() throw();
|
|
|
|
/** Adds edges to the table for a path.
|
|
|
|
This will add horizontal lines to the edge table for any parts of the path
|
|
which lie within the vertical bounds for which this table was created.
|
|
|
|
@param path the path to add
|
|
@param transform an optional transform to apply to the path while it's
|
|
being added
|
|
*/
|
|
void addPath (const Path& path,
|
|
const AffineTransform& transform) throw();
|
|
|
|
/** Reduces the amount of space the table has allocated.
|
|
|
|
This will shrink the table down to use as little memory as possible - useful for
|
|
read-only tables that get stored and re-used for rendering.
|
|
*/
|
|
void optimiseTable() throw();
|
|
|
|
/** Iterates the lines in the table, for rendering.
|
|
|
|
This function will iterate each line in the table, and call a user-defined class
|
|
to render each pixel or continuous line of pixels that the table contains.
|
|
|
|
@param iterationCallback this templated class must contain the following methods:
|
|
@code
|
|
inline void setEdgeTableYPos (int y);
|
|
inline void handleEdgeTablePixel (int x, int alphaLevel) const;
|
|
inline void handleEdgeTableLine (int x, int width, int alphaLevel) const;
|
|
@endcode
|
|
(these don't necessarily have to be 'const', but it might help it go faster)
|
|
@param clipLeft the left-hand edge of the rectangle which should be iterated
|
|
@param clipTop the top edge of the rectangle which should be iterated
|
|
@param clipRight the right-hand edge of the rectangle which should be iterated
|
|
@param clipBottom the bottom edge of the rectangle which should be iterated
|
|
@param subPixelXOffset a fraction of 1 pixel by which to shift the table rightwards, in the range 0 to 255
|
|
*/
|
|
template <class EdgeTableIterationCallback>
|
|
void iterate (EdgeTableIterationCallback& iterationCallback,
|
|
const int clipLeft,
|
|
int clipTop,
|
|
const int clipRight,
|
|
int clipBottom,
|
|
const int subPixelXOffset) const
|
|
{
|
|
if (clipTop < top)
|
|
clipTop = top;
|
|
|
|
if (clipBottom > top + height)
|
|
clipBottom = top + height;
|
|
|
|
const int* singleLine = table + lineStrideElements
|
|
* ((clipTop - top) << (int) oversampling);
|
|
|
|
int mergedLineAllocation = 128;
|
|
MemoryBlock temp (mergedLineAllocation * (2 * sizeof (int)));
|
|
int* mergedLine = (int*) temp.getData();
|
|
|
|
const int timesOverSampling = 1 << (int) oversampling;
|
|
|
|
for (int y = clipTop; y < clipBottom; ++y)
|
|
{
|
|
int numMergedPoints = 0;
|
|
|
|
// sort all the oversampled lines into a single merged line ready to draw..
|
|
for (int over = timesOverSampling; --over >= 0;)
|
|
{
|
|
const int* l = singleLine;
|
|
singleLine += lineStrideElements;
|
|
|
|
int num = *l;
|
|
jassert (num >= 0);
|
|
|
|
if (num > 0)
|
|
{
|
|
if (numMergedPoints + num >= mergedLineAllocation)
|
|
{
|
|
mergedLineAllocation = (numMergedPoints + num + 0x100) & ~0xff;
|
|
temp.setSize (mergedLineAllocation * (2 * sizeof (int)), false);
|
|
mergedLine = (int*) temp.getData();
|
|
}
|
|
|
|
while (--num >= 0)
|
|
{
|
|
const int x = *++l;
|
|
const int winding = *++l;
|
|
|
|
int n = numMergedPoints << 1;
|
|
|
|
while (n > 0)
|
|
{
|
|
const int cx = mergedLine [n - 2];
|
|
|
|
if (cx <= x)
|
|
break;
|
|
|
|
mergedLine [n] = cx;
|
|
--n;
|
|
mergedLine [n + 2] = mergedLine [n];
|
|
--n;
|
|
}
|
|
|
|
mergedLine [n] = x;
|
|
mergedLine [n + 1] = winding;
|
|
|
|
++numMergedPoints;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (--numMergedPoints > 0)
|
|
{
|
|
const int* line = mergedLine;
|
|
int x = subPixelXOffset + *line;
|
|
int level = *++line;
|
|
int levelAccumulator = 0;
|
|
|
|
iterationCallback.setEdgeTableYPos (y);
|
|
|
|
while (--numMergedPoints >= 0)
|
|
{
|
|
const int endX = subPixelXOffset + *++line;
|
|
jassert (endX >= x);
|
|
|
|
const int absLevel = abs (level);
|
|
int endOfRun = (endX >> 8);
|
|
|
|
if (endOfRun == (x >> 8))
|
|
{
|
|
// small segment within the same pixel, so just save it for the next
|
|
// time round..
|
|
levelAccumulator += (endX - x) * absLevel;
|
|
}
|
|
else
|
|
{
|
|
// plot the fist pixel of this segment, including any accumulated
|
|
// levels from smaller segments that haven't been drawn yet
|
|
levelAccumulator += (0xff - (x & 0xff)) * absLevel;
|
|
|
|
levelAccumulator >>= 8;
|
|
if (levelAccumulator > 0xff)
|
|
levelAccumulator = 0xff;
|
|
|
|
x >>= 8;
|
|
|
|
if (x >= clipRight)
|
|
{
|
|
levelAccumulator = 0;
|
|
break;
|
|
}
|
|
|
|
if (x >= clipLeft && x < clipRight && levelAccumulator > 0)
|
|
iterationCallback.handleEdgeTablePixel (x, levelAccumulator);
|
|
|
|
if (++x >= clipRight)
|
|
{
|
|
levelAccumulator = 0;
|
|
break;
|
|
}
|
|
|
|
// if there's a segment of solid pixels, do it all in one go..
|
|
if (absLevel > 0 && endOfRun > x)
|
|
{
|
|
if (x < clipLeft)
|
|
x = clipLeft;
|
|
|
|
if (endOfRun > clipRight)
|
|
endOfRun = clipRight;
|
|
|
|
const int numPix = endOfRun - x;
|
|
|
|
if (numPix > 0)
|
|
iterationCallback.handleEdgeTableLine (x, numPix,
|
|
jmin (absLevel, 0xff));
|
|
}
|
|
|
|
// save the bit at the end to be drawn next time round the loop.
|
|
levelAccumulator = (endX & 0xff) * absLevel;
|
|
}
|
|
|
|
level += *++line;
|
|
x = endX;
|
|
}
|
|
|
|
if (levelAccumulator > 0)
|
|
{
|
|
levelAccumulator >>= 8;
|
|
if (levelAccumulator > 0xff)
|
|
levelAccumulator = 0xff;
|
|
|
|
x >>= 8;
|
|
if (x >= clipLeft && x < clipRight)
|
|
iterationCallback.handleEdgeTablePixel (x, levelAccumulator);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
// table line format: number of points; point0 x, point0 levelDelta, point1 x, point1 levelDelta, etc
|
|
int* table;
|
|
int top, height, maxEdgesPerLine, lineStrideElements;
|
|
OversamplingLevel oversampling;
|
|
|
|
// this will assume that the y co-ord is within bounds, and will avoid checking
|
|
// this for speed.
|
|
void addEdgePoint (const int x, const int y, const int winding) throw();
|
|
|
|
void remapTableForNumEdges (const int newNumEdgesPerLine) throw();
|
|
};
|
|
|
|
#endif // __JUCE_EDGETABLE_JUCEHEADER__
|
|
/********* End of inlined file: juce_EdgeTable.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_GRAPHICS_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_JUSTIFICATION_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_LowLevelGraphicsContext.h *********/
|
|
#ifndef __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__
|
|
#define __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__
|
|
|
|
/**
|
|
Interface class for graphics context objects, used internally by the Graphics class.
|
|
|
|
Users are not supposed to create instances of this class directly - do your drawing
|
|
via the Graphics object instead.
|
|
|
|
It's a base class for different types of graphics context, that may perform software-based
|
|
or OS-accelerated rendering.
|
|
|
|
E.g. the LowLevelGraphicsSoftwareRenderer renders onto an image in memory, but other
|
|
subclasses could render directly to a windows HDC, a Quartz context, or an OpenGL
|
|
context.
|
|
*/
|
|
class JUCE_API LowLevelGraphicsContext
|
|
{
|
|
protected:
|
|
|
|
LowLevelGraphicsContext();
|
|
|
|
public:
|
|
virtual ~LowLevelGraphicsContext();
|
|
|
|
/** Returns true if this device is vector-based, e.g. a printer. */
|
|
virtual bool isVectorDevice() const = 0;
|
|
|
|
/** Moves the origin to a new position.
|
|
|
|
The co-ords are relative to the current origin, and indicate the new position
|
|
of (0, 0).
|
|
*/
|
|
virtual void setOrigin (int x, int y) = 0;
|
|
|
|
/** Cliping co-ords are relative to the origin. */
|
|
virtual bool reduceClipRegion (int x, int y, int w, int h) = 0;
|
|
|
|
/** Cliping co-ords are relative to the origin. */
|
|
virtual bool reduceClipRegion (const RectangleList& clipRegion) = 0;
|
|
|
|
/** Cliping co-ords are relative to the origin. */
|
|
virtual void excludeClipRegion (int x, int y, int w, int h) = 0;
|
|
|
|
virtual void saveState() = 0;
|
|
virtual void restoreState() = 0;
|
|
|
|
virtual bool clipRegionIntersects (int x, int y, int w, int h) = 0;
|
|
virtual const Rectangle getClipBounds() const = 0;
|
|
virtual bool isClipEmpty() const = 0;
|
|
|
|
virtual void fillRectWithColour (int x, int y, int w, int h, const Colour& colour, const bool replaceExistingContents) = 0;
|
|
virtual void fillRectWithGradient (int x, int y, int w, int h, const ColourGradient& gradient) = 0;
|
|
|
|
virtual void fillPathWithColour (const Path& path, const AffineTransform& transform, const Colour& colour, EdgeTable::OversamplingLevel quality) = 0;
|
|
virtual void fillPathWithGradient (const Path& path, const AffineTransform& transform, const ColourGradient& gradient, EdgeTable::OversamplingLevel quality) = 0;
|
|
virtual void fillPathWithImage (const Path& path, const AffineTransform& transform,
|
|
const Image& image, int imageX, int imageY, float alpha, EdgeTable::OversamplingLevel quality) = 0;
|
|
|
|
virtual void fillAlphaChannelWithColour (const Image& alphaImage, int alphaImageX, int alphaImageY, const Colour& colour) = 0;
|
|
virtual void fillAlphaChannelWithGradient (const Image& alphaImage, int alphaImageX, int alphaImageY, const ColourGradient& gradient) = 0;
|
|
virtual void fillAlphaChannelWithImage (const Image& alphaImage, int alphaImageX, int alphaImageY,
|
|
const Image& fillerImage, int fillerImageX, int fillerImageY, float alpha) = 0;
|
|
|
|
virtual void blendImage (const Image& sourceImage,
|
|
int destX, int destY, int destW, int destH, int sourceX, int sourceY,
|
|
float alpha) = 0;
|
|
|
|
virtual void blendImageRescaling (const Image& sourceImage,
|
|
int destX, int destY, int destW, int destH,
|
|
int sourceX, int sourceY, int sourceW, int sourceH,
|
|
float alpha, const Graphics::ResamplingQuality quality) = 0;
|
|
|
|
virtual void blendImageWarping (const Image& sourceImage,
|
|
int srcClipX, int srcClipY, int srcClipW, int srcClipH,
|
|
const AffineTransform& transform,
|
|
float alpha, const Graphics::ResamplingQuality quality) = 0;
|
|
|
|
virtual void drawLine (double x1, double y1, double x2, double y2, const Colour& colour) = 0;
|
|
|
|
virtual void drawVerticalLine (const int x, double top, double bottom, const Colour& col) = 0;
|
|
virtual void drawHorizontalLine (const int y, double left, double right, const Colour& col) = 0;
|
|
};
|
|
|
|
#endif // __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__
|
|
/********* End of inlined file: juce_LowLevelGraphicsContext.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_LowLevelGraphicsPostScriptRenderer.h *********/
|
|
#ifndef __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__
|
|
#define __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__
|
|
|
|
/**
|
|
An implementation of LowLevelGraphicsContext that turns the drawing operations
|
|
into a PostScript document.
|
|
|
|
*/
|
|
class JUCE_API LowLevelGraphicsPostScriptRenderer : public LowLevelGraphicsContext
|
|
{
|
|
public:
|
|
|
|
LowLevelGraphicsPostScriptRenderer (OutputStream& resultingPostScript,
|
|
const String& documentTitle,
|
|
const int totalWidth,
|
|
const int totalHeight);
|
|
|
|
~LowLevelGraphicsPostScriptRenderer();
|
|
|
|
bool isVectorDevice() const;
|
|
void setOrigin (int x, int y);
|
|
|
|
bool reduceClipRegion (int x, int y, int w, int h);
|
|
bool reduceClipRegion (const RectangleList& clipRegion);
|
|
void excludeClipRegion (int x, int y, int w, int h);
|
|
|
|
void saveState();
|
|
void restoreState();
|
|
|
|
bool clipRegionIntersects (int x, int y, int w, int h);
|
|
const Rectangle getClipBounds() const;
|
|
bool isClipEmpty() const;
|
|
|
|
void fillRectWithColour (int x, int y, int w, int h, const Colour& colour, const bool replaceExistingContents);
|
|
void fillRectWithGradient (int x, int y, int w, int h, const ColourGradient& gradient);
|
|
|
|
void fillPathWithColour (const Path& path, const AffineTransform& transform, const Colour& colour, EdgeTable::OversamplingLevel quality);
|
|
void fillPathWithGradient (const Path& path, const AffineTransform& transform, const ColourGradient& gradient, EdgeTable::OversamplingLevel quality);
|
|
void fillPathWithImage (const Path& path, const AffineTransform& transform,
|
|
const Image& image, int imageX, int imageY, float alpha, EdgeTable::OversamplingLevel quality);
|
|
|
|
void fillAlphaChannelWithColour (const Image& alphaImage, int imageX, int imageY, const Colour& colour);
|
|
void fillAlphaChannelWithGradient (const Image& alphaImage, int imageX, int imageY, const ColourGradient& gradient);
|
|
void fillAlphaChannelWithImage (const Image& alphaImage, int alphaImageX, int alphaImageY,
|
|
const Image& fillerImage, int fillerImageX, int fillerImageY, float alpha);
|
|
|
|
void blendImage (const Image& sourceImage, int destX, int destY, int destW, int destH,
|
|
int sourceX, int sourceY, float alpha);
|
|
|
|
void blendImageRescaling (const Image& sourceImage, int destX, int destY, int destW, int destH,
|
|
int sourceX, int sourceY, int sourceW, int sourceH,
|
|
float alpha, const Graphics::ResamplingQuality quality);
|
|
|
|
void blendImageWarping (const Image& sourceImage, int srcClipX, int srcClipY, int srcClipW, int srcClipH,
|
|
const AffineTransform& transform,
|
|
float alpha, const Graphics::ResamplingQuality quality);
|
|
|
|
void drawLine (double x1, double y1, double x2, double y2, const Colour& colour);
|
|
|
|
void drawVerticalLine (const int x, double top, double bottom, const Colour& col);
|
|
void drawHorizontalLine (const int x, double top, double bottom, const Colour& col);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
OutputStream& out;
|
|
RectangleList* clip;
|
|
int totalWidth, totalHeight, xOffset, yOffset;
|
|
bool needToClip;
|
|
Colour lastColour;
|
|
|
|
struct SavedState
|
|
{
|
|
SavedState (RectangleList* const clip, const int xOffset, const int yOffset);
|
|
~SavedState();
|
|
|
|
RectangleList* clip;
|
|
const int xOffset, yOffset;
|
|
|
|
private:
|
|
SavedState (const SavedState&);
|
|
const SavedState& operator= (const SavedState&);
|
|
};
|
|
|
|
OwnedArray <SavedState> stateStack;
|
|
|
|
void writeClip();
|
|
void writeColour (const Colour& colour);
|
|
void writePath (const Path& path) const;
|
|
void writeXY (const float x, const float y) const;
|
|
void writeTransform (const AffineTransform& trans) const;
|
|
void writeImage (const Image& im, const int sx, const int sy, const int maxW, const int maxH) const;
|
|
|
|
LowLevelGraphicsPostScriptRenderer (const LowLevelGraphicsPostScriptRenderer& other);
|
|
const LowLevelGraphicsPostScriptRenderer& operator= (const LowLevelGraphicsPostScriptRenderer&);
|
|
};
|
|
|
|
#endif // __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__
|
|
/********* End of inlined file: juce_LowLevelGraphicsPostScriptRenderer.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_LowLevelGraphicsSoftwareRenderer.h *********/
|
|
#ifndef __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__
|
|
#define __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__
|
|
|
|
/**
|
|
A lowest-common-denominator implementation of LowLevelGraphicsContext that does all
|
|
its rendering in memory.
|
|
|
|
User code is not supposed to create instances of this class directly - do all your
|
|
rendering via the Graphics class instead.
|
|
*/
|
|
class JUCE_API LowLevelGraphicsSoftwareRenderer : public LowLevelGraphicsContext
|
|
{
|
|
public:
|
|
|
|
LowLevelGraphicsSoftwareRenderer (Image& imageToRenderOn);
|
|
~LowLevelGraphicsSoftwareRenderer();
|
|
|
|
bool isVectorDevice() const;
|
|
|
|
void setOrigin (int x, int y);
|
|
|
|
bool reduceClipRegion (int x, int y, int w, int h);
|
|
bool reduceClipRegion (const RectangleList& clipRegion);
|
|
void excludeClipRegion (int x, int y, int w, int h);
|
|
|
|
void saveState();
|
|
void restoreState();
|
|
|
|
bool clipRegionIntersects (int x, int y, int w, int h);
|
|
const Rectangle getClipBounds() const;
|
|
bool isClipEmpty() const;
|
|
|
|
void fillRectWithColour (int x, int y, int w, int h, const Colour& colour, const bool replaceExistingContents);
|
|
void fillRectWithGradient (int x, int y, int w, int h, const ColourGradient& gradient);
|
|
|
|
void fillPathWithColour (const Path& path, const AffineTransform& transform, const Colour& colour, EdgeTable::OversamplingLevel quality);
|
|
void fillPathWithGradient (const Path& path, const AffineTransform& transform, const ColourGradient& gradient, EdgeTable::OversamplingLevel quality);
|
|
void fillPathWithImage (const Path& path, const AffineTransform& transform,
|
|
const Image& image, int imageX, int imageY, float alpha, EdgeTable::OversamplingLevel quality);
|
|
|
|
void fillAlphaChannelWithColour (const Image& alphaImage, int imageX, int imageY, const Colour& colour);
|
|
void fillAlphaChannelWithGradient (const Image& alphaImage, int imageX, int imageY, const ColourGradient& gradient);
|
|
void fillAlphaChannelWithImage (const Image& alphaImage, int alphaImageX, int alphaImageY,
|
|
const Image& fillerImage, int fillerImageX, int fillerImageY, float alpha);
|
|
|
|
void blendImage (const Image& sourceImage, int destX, int destY, int destW, int destH,
|
|
int sourceX, int sourceY, float alpha);
|
|
|
|
void blendImageRescaling (const Image& sourceImage, int destX, int destY, int destW, int destH,
|
|
int sourceX, int sourceY, int sourceW, int sourceH,
|
|
float alpha, const Graphics::ResamplingQuality quality);
|
|
|
|
void blendImageWarping (const Image& sourceImage, int srcClipX, int srcClipY, int srcClipW, int srcClipH,
|
|
const AffineTransform& transform,
|
|
float alpha, const Graphics::ResamplingQuality quality);
|
|
|
|
void drawLine (double x1, double y1, double x2, double y2, const Colour& colour);
|
|
|
|
void drawVerticalLine (const int x, double top, double bottom, const Colour& col);
|
|
void drawHorizontalLine (const int x, double top, double bottom, const Colour& col);
|
|
|
|
RectangleList* getRawClipRegion() throw() { return clip; }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
Image& image;
|
|
RectangleList* clip;
|
|
int xOffset, yOffset;
|
|
|
|
struct SavedState
|
|
{
|
|
SavedState (RectangleList* const clip, const int xOffset, const int yOffset);
|
|
~SavedState();
|
|
|
|
RectangleList* clip;
|
|
const int xOffset, yOffset;
|
|
|
|
private:
|
|
SavedState (const SavedState&);
|
|
const SavedState& operator= (const SavedState&);
|
|
};
|
|
|
|
OwnedArray <SavedState> stateStack;
|
|
|
|
void drawVertical (const int x, const double top, const double bottom, const Colour& col);
|
|
void drawHorizontal (const int y, const double top, const double bottom, const Colour& col);
|
|
|
|
bool getPathBounds (int clipX, int clipY, int clipW, int clipH,
|
|
const Path& path, const AffineTransform& transform,
|
|
int& x, int& y, int& w, int& h) const;
|
|
|
|
void clippedFillRectWithColour (const Rectangle& clipRect, int x, int y, int w, int h, const Colour& colour, const bool replaceExistingContents);
|
|
|
|
void clippedFillPathWithColour (int clipX, int clipY, int clipW, int clipH, const Path& path, const AffineTransform& transform, const Colour& colour, EdgeTable::OversamplingLevel quality);
|
|
void clippedFillPathWithGradient (int clipX, int clipY, int clipW, int clipH, const Path& path, const AffineTransform& transform, const ColourGradient& gradient, EdgeTable::OversamplingLevel quality);
|
|
void clippedFillPathWithImage (int clipX, int clipY, int clipW, int clipH, const Path& path, const AffineTransform& transform,
|
|
const Image& image, int imageX, int imageY, float alpha, EdgeTable::OversamplingLevel quality);
|
|
|
|
void clippedFillAlphaChannelWithColour (int clipX, int clipY, int clipW, int clipH, const Image& alphaImage, int alphaImageX, int alphaImageY, const Colour& colour);
|
|
void clippedFillAlphaChannelWithGradient (int clipX, int clipY, int clipW, int clipH, const Image& alphaImage, int alphaImageX, int alphaImageY, const ColourGradient& gradient);
|
|
void clippedFillAlphaChannelWithImage (int clipX, int clipY, int clipW, int clipH, const Image& alphaImage, int alphaImageX, int alphaImageY,
|
|
const Image& fillerImage, int fillerImageX, int fillerImageY, float alpha);
|
|
|
|
void clippedBlendImage (int clipX, int clipY, int clipW, int clipH, const Image& sourceImage,
|
|
int destX, int destY, int destW, int destH, int sourceX, int sourceY,
|
|
float alpha);
|
|
|
|
void clippedBlendImageWarping (int clipX, int clipY, int clipW, int clipH, const Image& sourceImage,
|
|
int srcClipX, int srcClipY, int srcClipW, int srcClipH,
|
|
const AffineTransform& transform,
|
|
float alpha, const Graphics::ResamplingQuality quality);
|
|
|
|
void clippedDrawLine (int clipX, int clipY, int clipW, int clipH, double x1, double y1, double x2, double y2, const Colour& colour);
|
|
|
|
void clippedDrawVerticalLine (int clipX, int clipY, int clipW, int clipH, const int x, double top, double bottom, const Colour& col);
|
|
void clippedDrawHorizontalLine (int clipX, int clipY, int clipW, int clipH, const int x, double top, double bottom, const Colour& col);
|
|
|
|
LowLevelGraphicsSoftwareRenderer (const LowLevelGraphicsSoftwareRenderer& other);
|
|
const LowLevelGraphicsSoftwareRenderer& operator= (const LowLevelGraphicsSoftwareRenderer&);
|
|
};
|
|
|
|
#endif // __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__
|
|
/********* End of inlined file: juce_LowLevelGraphicsSoftwareRenderer.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_AFFINETRANSFORM_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_BORDERSIZE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_LINE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_PATH_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_PATHITERATOR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PathIterator.h *********/
|
|
#ifndef __JUCE_PATHITERATOR_JUCEHEADER__
|
|
#define __JUCE_PATHITERATOR_JUCEHEADER__
|
|
|
|
/**
|
|
Flattens a Path object into a series of straight-line sections.
|
|
|
|
Use one of these to iterate through a Path object, and it will convert
|
|
all the curves into line sections so it's easy to render or perform
|
|
geometric operations on.
|
|
|
|
@see Path
|
|
*/
|
|
class JUCE_API PathFlatteningIterator
|
|
{
|
|
public:
|
|
|
|
/** Creates a PathFlatteningIterator.
|
|
|
|
After creation, use the next() method to initialise the fields in the
|
|
object with the first line's position.
|
|
|
|
@param path the path to iterate along
|
|
@param transform a transform to apply to each point in the path being iterated
|
|
@param tolerence the amount by which the curves are allowed to deviate from the
|
|
lines into which they are being broken down - a higher tolerence
|
|
is a bit faster, but less smooth.
|
|
*/
|
|
PathFlatteningIterator (const Path& path,
|
|
const AffineTransform& transform = AffineTransform::identity,
|
|
float tolerence = 9.0f) throw();
|
|
|
|
/** Destructor. */
|
|
~PathFlatteningIterator() throw();
|
|
|
|
/** Fetches the next line segment from the path.
|
|
|
|
This will update the member variables x1, y1, x2, y2, subPathIndex and closesSubPath
|
|
so that they describe the new line segment.
|
|
|
|
@returns false when there are no more lines to fetch.
|
|
*/
|
|
bool next() throw();
|
|
|
|
/** The x position of the start of the current line segment. */
|
|
float x1;
|
|
/** The y position of the start of the current line segment. */
|
|
float y1;
|
|
/** The x position of the end of the current line segment. */
|
|
float x2;
|
|
/** The y position of the end of the current line segment. */
|
|
float y2;
|
|
|
|
/** Indicates whether the current line segment is closing a sub-path.
|
|
|
|
If the current line is the one that connects the end of a sub-path
|
|
back to the start again, this will be true.
|
|
*/
|
|
bool closesSubPath;
|
|
|
|
/** The index of the current line within the current sub-path.
|
|
|
|
E.g. you can use this to see whether the line is the first one in the
|
|
subpath by seeing if it's 0.
|
|
*/
|
|
int subPathIndex;
|
|
|
|
/** Returns true if the current segment is the last in the current sub-path. */
|
|
bool isLastInSubpath() const throw() { return stackPos == stackBase
|
|
&& (index >= path.numElements
|
|
|| points [index] == Path::moveMarker); }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
const Path& path;
|
|
const AffineTransform transform;
|
|
float* points;
|
|
float tolerence, subPathCloseX, subPathCloseY;
|
|
bool isIdentityTransform;
|
|
|
|
float* stackBase;
|
|
float* stackPos;
|
|
int index, stackSize;
|
|
|
|
PathFlatteningIterator (const PathFlatteningIterator&);
|
|
const PathFlatteningIterator& operator= (const PathFlatteningIterator&);
|
|
};
|
|
|
|
#endif // __JUCE_PATHITERATOR_JUCEHEADER__
|
|
/********* End of inlined file: juce_PathIterator.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_PATHSTROKETYPE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_POINT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PositionedRectangle.h *********/
|
|
#ifndef __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__
|
|
#define __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__
|
|
|
|
/**
|
|
A rectangle whose co-ordinates can be defined in terms of absolute or
|
|
proportional distances.
|
|
|
|
Designed mainly for storing component positions, this gives you a lot of
|
|
control over how each co-ordinate is stored, either as an absolute position,
|
|
or as a proportion of the size of a parent rectangle.
|
|
|
|
It also allows you to define the anchor points by which the rectangle is
|
|
positioned, so for example you could specify that the top right of the
|
|
rectangle should be an absolute distance from its parent's bottom-right corner.
|
|
|
|
This object can be stored as a string, which takes the form "x y w h", including
|
|
symbols like '%' and letters to indicate the anchor point. See its toString()
|
|
method for more info.
|
|
|
|
Example usage:
|
|
@code
|
|
class MyComponent
|
|
{
|
|
void resized()
|
|
{
|
|
// this will set the child component's x to be 20% of our width, its y
|
|
// to be 30, its width to be 150, and its height to be 50% of our
|
|
// height..
|
|
const PositionedRectangle pos1 ("20% 30 150 50%");
|
|
pos1.applyToComponent (*myChildComponent1);
|
|
|
|
// this will inset the child component with a gap of 10 pixels
|
|
// around each of its edges..
|
|
const PositionedRectangle pos2 ("10 10 20M 20M");
|
|
pos2.applyToComponent (*myChildComponent2);
|
|
}
|
|
};
|
|
@endcode
|
|
*/
|
|
class JUCE_API PositionedRectangle
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty rectangle with all co-ordinates set to zero.
|
|
|
|
The default anchor point is top-left; the default
|
|
*/
|
|
PositionedRectangle() throw();
|
|
|
|
/** Initialises a PositionedRectangle from a saved string version.
|
|
|
|
The string must be in the format generated by toString().
|
|
*/
|
|
PositionedRectangle (const String& stringVersion) throw();
|
|
|
|
/** Creates a copy of another PositionedRectangle. */
|
|
PositionedRectangle (const PositionedRectangle& other) throw();
|
|
|
|
/** Copies another PositionedRectangle. */
|
|
const PositionedRectangle& operator= (const PositionedRectangle& other) throw();
|
|
|
|
/** Destructor. */
|
|
~PositionedRectangle() throw();
|
|
|
|
/** Returns a string version of this position, from which it can later be
|
|
re-generated.
|
|
|
|
The format is four co-ordinates, "x y w h".
|
|
|
|
- If a co-ordinate is absolute, it is stored as an integer, e.g. "100".
|
|
- If a co-ordinate is proportional to its parent's width or height, it is stored
|
|
as a percentage, e.g. "80%".
|
|
- If the X or Y co-ordinate is relative to the parent's right or bottom edge, the
|
|
number has "R" appended to it, e.g. "100R" means a distance of 100 pixels from
|
|
the parent's right-hand edge.
|
|
- If the X or Y co-ordinate is relative to the parent's centre, the number has "C"
|
|
appended to it, e.g. "-50C" would be 50 pixels left of the parent's centre.
|
|
- If the X or Y co-ordinate should be anchored at the component's right or bottom
|
|
edge, then it has "r" appended to it. So "-50Rr" would mean that this component's
|
|
right-hand edge should be 50 pixels left of the parent's right-hand edge.
|
|
- If the X or Y co-ordinate should be anchored at the component's centre, then it
|
|
has "c" appended to it. So "-50Rc" would mean that this component's
|
|
centre should be 50 pixels left of the parent's right-hand edge. "40%c" means that
|
|
this component's centre should be placed 40% across the parent's width.
|
|
- If it's a width or height that should use the parentSizeMinusAbsolute mode, then
|
|
the number has "M" appended to it.
|
|
|
|
To reload a stored string, use the constructor that takes a string parameter.
|
|
*/
|
|
const String toString() const throw();
|
|
|
|
/** Calculates the absolute position, given the size of the space that
|
|
it should go in.
|
|
|
|
This will work out any proportional distances and sizes relative to the
|
|
target rectangle, and will return the absolute position.
|
|
|
|
@see applyToComponent
|
|
*/
|
|
const Rectangle getRectangle (const Rectangle& targetSpaceToBeRelativeTo) const throw();
|
|
|
|
/** Same as getRectangle(), but returning the values as doubles rather than ints.
|
|
*/
|
|
void getRectangleDouble (const Rectangle& targetSpaceToBeRelativeTo,
|
|
double& x,
|
|
double& y,
|
|
double& width,
|
|
double& height) const throw();
|
|
|
|
/** This sets the bounds of the given component to this position.
|
|
|
|
This is equivalent to writing:
|
|
@code
|
|
comp.setBounds (getRectangle (Rectangle (0, 0, comp.getParentWidth(), comp.getParentHeight())));
|
|
@endcode
|
|
|
|
@see getRectangle, updateFromComponent
|
|
*/
|
|
void applyToComponent (Component& comp) const throw();
|
|
|
|
/** Updates this object's co-ordinates to match the given rectangle.
|
|
|
|
This will set all co-ordinates based on the given rectangle, re-calculating
|
|
any proportional distances, and using the current anchor points.
|
|
|
|
So for example if the x co-ordinate mode is currently proportional, this will
|
|
re-calculate x based on the rectangle's relative position within the target
|
|
rectangle's width.
|
|
|
|
If the target rectangle's width or height are zero then it may not be possible
|
|
to re-calculate some proportional co-ordinates. In this case, those co-ordinates
|
|
will not be changed.
|
|
*/
|
|
void updateFrom (const Rectangle& newPosition,
|
|
const Rectangle& targetSpaceToBeRelativeTo) throw();
|
|
|
|
/** Same functionality as updateFrom(), but taking doubles instead of ints.
|
|
*/
|
|
void updateFromDouble (const double x, const double y,
|
|
const double width, const double height,
|
|
const Rectangle& targetSpaceToBeRelativeTo) throw();
|
|
|
|
/** Updates this object's co-ordinates to match the bounds of this component.
|
|
|
|
This is equivalent to calling updateFrom() with the component's bounds and
|
|
it parent size.
|
|
|
|
If the component doesn't currently have a parent, then proportional co-ordinates
|
|
might not be updated because it would need to know the parent's size to do the
|
|
maths for this.
|
|
*/
|
|
void updateFromComponent (const Component& comp) throw();
|
|
|
|
/** Specifies the point within the rectangle, relative to which it should be positioned. */
|
|
enum AnchorPoint
|
|
{
|
|
anchorAtLeftOrTop = 1 << 0, /**< The x or y co-ordinate specifies where the left or top edge of the rectangle should be. */
|
|
anchorAtRightOrBottom = 1 << 1, /**< The x or y co-ordinate specifies where the right or bottom edge of the rectangle should be. */
|
|
anchorAtCentre = 1 << 2 /**< The x or y co-ordinate specifies where the centre of the rectangle should be. */
|
|
};
|
|
|
|
/** Specifies how an x or y co-ordinate should be interpreted. */
|
|
enum PositionMode
|
|
{
|
|
absoluteFromParentTopLeft = 1 << 3, /**< The x or y co-ordinate specifies an absolute distance from the parent's top or left edge. */
|
|
absoluteFromParentBottomRight = 1 << 4, /**< The x or y co-ordinate specifies an absolute distance from the parent's bottom or right edge. */
|
|
absoluteFromParentCentre = 1 << 5, /**< The x or y co-ordinate specifies an absolute distance from the parent's centre. */
|
|
proportionOfParentSize = 1 << 6 /**< The x or y co-ordinate specifies a proportion of the parent's width or height, measured from the parent's top or left. */
|
|
};
|
|
|
|
/** Specifies how the width or height should be interpreted. */
|
|
enum SizeMode
|
|
{
|
|
absoluteSize = 1 << 0, /**< The width or height specifies an absolute size. */
|
|
parentSizeMinusAbsolute = 1 << 1, /**< The width or height is an amount that should be subtracted from the parent's width or height. */
|
|
proportionalSize = 1 << 2, /**< The width or height specifies a proportion of the parent's width or height. */
|
|
};
|
|
|
|
/** Sets all options for all co-ordinates.
|
|
|
|
This requires a reference rectangle to be specified, because if you're changing any
|
|
of the modes from proportional to absolute or vice-versa, then it'll need to convert
|
|
the co-ordinates, and will need to know the parent size so it can calculate this.
|
|
*/
|
|
void setModes (const AnchorPoint xAnchorMode,
|
|
const PositionMode xPositionMode,
|
|
const AnchorPoint yAnchorMode,
|
|
const PositionMode yPositionMode,
|
|
const SizeMode widthMode,
|
|
const SizeMode heightMode,
|
|
const Rectangle& targetSpaceToBeRelativeTo) throw();
|
|
|
|
/** Returns the anchoring mode for the x co-ordinate.
|
|
To change any of the modes, use setModes().
|
|
*/
|
|
AnchorPoint getAnchorPointX() const throw();
|
|
|
|
/** Returns the positioning mode for the x co-ordinate.
|
|
To change any of the modes, use setModes().
|
|
*/
|
|
PositionMode getPositionModeX() const throw();
|
|
|
|
/** Returns the raw x co-ordinate.
|
|
|
|
If the x position mode is absolute, then this will be the absolute value. If it's
|
|
proportional, then this will be a fractional proportion, where 1.0 means the full
|
|
width of the parent space.
|
|
*/
|
|
double getX() const throw() { return x; }
|
|
|
|
/** Sets the raw value of the x co-ordinate.
|
|
|
|
See getX() for the meaning of this value.
|
|
*/
|
|
void setX (const double newX) throw() { x = newX; }
|
|
|
|
/** Returns the anchoring mode for the y co-ordinate.
|
|
To change any of the modes, use setModes().
|
|
*/
|
|
AnchorPoint getAnchorPointY() const throw();
|
|
|
|
/** Returns the positioning mode for the y co-ordinate.
|
|
To change any of the modes, use setModes().
|
|
*/
|
|
PositionMode getPositionModeY() const throw();
|
|
|
|
/** Returns the raw y co-ordinate.
|
|
|
|
If the y position mode is absolute, then this will be the absolute value. If it's
|
|
proportional, then this will be a fractional proportion, where 1.0 means the full
|
|
height of the parent space.
|
|
*/
|
|
double getY() const throw() { return y; }
|
|
|
|
/** Sets the raw value of the y co-ordinate.
|
|
|
|
See getY() for the meaning of this value.
|
|
*/
|
|
void setY (const double newY) throw() { y = newY; }
|
|
|
|
/** Returns the mode used to calculate the width.
|
|
To change any of the modes, use setModes().
|
|
*/
|
|
SizeMode getWidthMode() const throw();
|
|
|
|
/** Returns the raw width value.
|
|
|
|
If the width mode is absolute, then this will be the absolute value. If the mode is
|
|
proportional, then this will be a fractional proportion, where 1.0 means the full
|
|
width of the parent space.
|
|
*/
|
|
double getWidth() const throw() { return w; }
|
|
|
|
/** Sets the raw width value.
|
|
|
|
See getWidth() for the details about what this value means.
|
|
*/
|
|
void setWidth (const double newWidth) throw() { w = newWidth; }
|
|
|
|
/** Returns the mode used to calculate the height.
|
|
To change any of the modes, use setModes().
|
|
*/
|
|
SizeMode getHeightMode() const throw();
|
|
|
|
/** Returns the raw height value.
|
|
|
|
If the height mode is absolute, then this will be the absolute value. If the mode is
|
|
proportional, then this will be a fractional proportion, where 1.0 means the full
|
|
height of the parent space.
|
|
*/
|
|
double getHeight() const throw() { return h; }
|
|
|
|
/** Sets the raw height value.
|
|
|
|
See getHeight() for the details about what this value means.
|
|
*/
|
|
void setHeight (const double newHeight) throw() { h = newHeight; }
|
|
|
|
/** If the size and position are constance, and wouldn't be affected by changes
|
|
in the parent's size, then this will return true.
|
|
*/
|
|
bool isPositionAbsolute() const throw();
|
|
|
|
/** Compares two objects. */
|
|
const bool operator== (const PositionedRectangle& other) const throw();
|
|
|
|
/** Compares two objects. */
|
|
const bool operator!= (const PositionedRectangle& other) const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
double x, y, w, h;
|
|
uint8 xMode, yMode, wMode, hMode;
|
|
|
|
void addPosDescription (String& result, const uint8 mode, const double value) const throw();
|
|
void addSizeDescription (String& result, const uint8 mode, const double value) const throw();
|
|
void decodePosString (const String& s, uint8& mode, double& value) throw();
|
|
void decodeSizeString (const String& s, uint8& mode, double& value) throw();
|
|
void applyPosAndSize (double& xOut, double& wOut, const double x, const double w,
|
|
const uint8 xMode, const uint8 wMode,
|
|
const int parentPos, const int parentSize) const throw();
|
|
void updatePosAndSize (double& xOut, double& wOut, double x, const double w,
|
|
const uint8 xMode, const uint8 wMode,
|
|
const int parentPos, const int parentSize) const throw();
|
|
};
|
|
|
|
#endif // __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__
|
|
/********* End of inlined file: juce_PositionedRectangle.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_RECTANGLE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_CAMERADEVICE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_CameraDevice.h *********/
|
|
#ifndef __JUCE_CAMERADEVICE_JUCEHEADER__
|
|
#define __JUCE_CAMERADEVICE_JUCEHEADER__
|
|
|
|
#if JUCE_USE_CAMERA
|
|
|
|
/**
|
|
Receives callbacks with images from a CameraDevice.
|
|
|
|
@see CameraDevice::addListener
|
|
*/
|
|
class CameraImageListener
|
|
{
|
|
public:
|
|
CameraImageListener() {}
|
|
virtual ~CameraImageListener() {}
|
|
|
|
/** This method is called when a new image arrives.
|
|
|
|
This may be called by any thread, so be careful about thread-safety,
|
|
and make sure that you process the data as quickly as possible to
|
|
avoid glitching!
|
|
*/
|
|
virtual void imageReceived (Image& image) = 0;
|
|
};
|
|
|
|
/**
|
|
Controls any camera capture devices that might be available.
|
|
|
|
Use getAvailableDevices() to list the devices that are attached to the
|
|
system, then call openDevice to open one for use. Once you have a CameraDevice
|
|
object, you can get a viewer component from it, and use its methods to
|
|
stream to a file or capture still-frames.
|
|
*/
|
|
class JUCE_API CameraDevice
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~CameraDevice();
|
|
|
|
/** Returns a list of the available cameras on this machine.
|
|
|
|
You can open one of these devices by calling openDevice().
|
|
*/
|
|
static const StringArray getAvailableDevices();
|
|
|
|
/** Opens a camera device.
|
|
|
|
The index parameter indicates which of the items returned by getAvailableDevices()
|
|
to open.
|
|
|
|
The size constraints allow the method to choose between different resolutions if
|
|
the camera supports this. If the resolution cam't be specified (e.g. on the Mac)
|
|
then these will be ignored.
|
|
*/
|
|
static CameraDevice* openDevice (int deviceIndex,
|
|
int minWidth = 128, int minHeight = 64,
|
|
int maxWidth = 1024, int maxHeight = 768);
|
|
|
|
/** Returns the name of this device */
|
|
const String getName() const throw() { return name; }
|
|
|
|
/** Creates a component that can be used to display a preview of the
|
|
video from this camera.
|
|
*/
|
|
Component* createViewerComponent();
|
|
|
|
/** Starts recording video to the specified file.
|
|
|
|
You should use getFileExtension() to find out the correct extension to
|
|
use for your filename.
|
|
|
|
If the file exists, it will be deleted before the recording starts.
|
|
|
|
This method may not start recording instantly, so if you need to know the
|
|
exact time at which the file begins, you can call getTimeOfFirstRecordedFrame()
|
|
after the recording has finished.
|
|
*/
|
|
void startRecordingToFile (const File& file);
|
|
|
|
/** Stops recording, after a call to startRecordingToFile().
|
|
*/
|
|
void stopRecording();
|
|
|
|
/** Returns the file extension that should be used for the files
|
|
that you pass to startRecordingToFile().
|
|
|
|
This may be platform-specific, e.g. ".mov" or ".avi".
|
|
*/
|
|
static const String getFileExtension();
|
|
|
|
/** After calling stopRecording(), this method can be called to return the timestamp
|
|
of the first frame that was written to the file.
|
|
*/
|
|
const Time getTimeOfFirstRecordedFrame() const;
|
|
|
|
/** Adds a listener to receive images from the camera.
|
|
|
|
Be very careful not to delete the listener without first removing it by calling
|
|
removeListener().
|
|
*/
|
|
void addListener (CameraImageListener* listenerToAdd);
|
|
|
|
/** Removes a listener that was previously added with addListener().
|
|
*/
|
|
void removeListener (CameraImageListener* listenerToRemove);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
CameraDevice (const String& name, int index);
|
|
|
|
private:
|
|
void* internal;
|
|
bool isRecording;
|
|
String name;
|
|
|
|
CameraDevice (const CameraDevice&);
|
|
const CameraDevice& operator= (const CameraDevice&);
|
|
};
|
|
|
|
#endif
|
|
#endif // __JUCE_CAMERADEVICE_JUCEHEADER__
|
|
/********* End of inlined file: juce_CameraDevice.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_IMAGE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_IMAGECACHE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ImageCache.h *********/
|
|
#ifndef __JUCE_IMAGECACHE_JUCEHEADER__
|
|
#define __JUCE_IMAGECACHE_JUCEHEADER__
|
|
|
|
/**
|
|
A global cache of images that have been loaded from files or memory.
|
|
|
|
If you're loading an image and may need to use the image in more than one
|
|
place, this is used to allow the same image to be shared rather than loading
|
|
multiple copies into memory.
|
|
|
|
Another advantage is that after images are released, they will be kept in
|
|
memory for a few seconds before it is actually deleted, so if you're repeatedly
|
|
loading/deleting the same image, it'll reduce the chances of having to reload it
|
|
each time.
|
|
|
|
@see Image, ImageFileFormat
|
|
*/
|
|
class JUCE_API ImageCache : private DeletedAtShutdown,
|
|
private Timer
|
|
{
|
|
public:
|
|
|
|
/** Loads an image from a file, (or just returns the image if it's already cached).
|
|
|
|
If the cache already contains an image that was loaded from this file,
|
|
that image will be returned. Otherwise, this method will try to load the
|
|
file, add it to the cache, and return it.
|
|
|
|
It's very important not to delete the image that is returned - instead use
|
|
the ImageCache::release() method.
|
|
|
|
Also, remember that the image returned is shared, so drawing into it might
|
|
affect other things that are using it!
|
|
|
|
@param file the file to try to load
|
|
@returns the image, or null if it there was an error loading it
|
|
@see release, getFromMemory, getFromCache, ImageFileFormat::loadFrom
|
|
*/
|
|
static Image* getFromFile (const File& file);
|
|
|
|
/** Loads an image from an in-memory image file, (or just returns the image if it's already cached).
|
|
|
|
If the cache already contains an image that was loaded from this block of memory,
|
|
that image will be returned. Otherwise, this method will try to load the
|
|
file, add it to the cache, and return it.
|
|
|
|
It's very important not to delete the image that is returned - instead use
|
|
the ImageCache::release() method.
|
|
|
|
Also, remember that the image returned is shared, so drawing into it might
|
|
affect other things that are using it!
|
|
|
|
@param imageData the block of memory containing the image data
|
|
@param dataSize the data size in bytes
|
|
@returns the image, or null if it there was an error loading it
|
|
@see release, getFromMemory, getFromCache, ImageFileFormat::loadFrom
|
|
*/
|
|
static Image* getFromMemory (const void* imageData,
|
|
const int dataSize);
|
|
|
|
/** Releases an image that was previously created by the ImageCache.
|
|
|
|
If an image has been returned by the getFromFile() or getFromMemory() methods,
|
|
it mustn't be deleted directly, but should be released with this method
|
|
instead.
|
|
|
|
@see getFromFile, getFromMemory
|
|
*/
|
|
static void release (Image* const imageToRelease);
|
|
|
|
/** Checks whether an image is in the cache or not.
|
|
|
|
@returns true if the image is currently in the cache
|
|
*/
|
|
static bool isImageInCache (Image* const imageToLookFor);
|
|
|
|
/** Increments the reference-count for a cached image.
|
|
|
|
If the image isn't in the cache, this method won't do anything.
|
|
*/
|
|
static void incReferenceCount (Image* const image);
|
|
|
|
/** Checks the cache for an image with a particular hashcode.
|
|
|
|
If there's an image in the cache with this hashcode, it will be returned,
|
|
otherwise it will return zero.
|
|
|
|
If an image is returned, it must be released with the release() method
|
|
when no longer needed, to maintain the correct reference counts.
|
|
|
|
@param hashCode the hash code that would have been associated with the
|
|
image by addImageToCache()
|
|
@see addImageToCache
|
|
*/
|
|
static Image* getFromHashCode (const int64 hashCode);
|
|
|
|
/** Adds an image to the cache with a user-defined hash-code.
|
|
|
|
After calling this, responsibilty for deleting the image will be taken
|
|
by the ImageCache.
|
|
|
|
The image will be initially be given a reference count of 1, so call
|
|
the release() method to delete it.
|
|
|
|
@param image the image to add
|
|
@param hashCode the hash-code to associate with it
|
|
@see getFromHashCode
|
|
*/
|
|
static void addImageToCache (Image* const image,
|
|
const int64 hashCode);
|
|
|
|
/** Changes the amount of time before an unused image will be removed from the cache.
|
|
|
|
By default this is about 5 seconds.
|
|
*/
|
|
static void setCacheTimeout (const int millisecs);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
CriticalSection lock;
|
|
VoidArray images;
|
|
|
|
ImageCache() throw();
|
|
ImageCache (const ImageCache&);
|
|
const ImageCache& operator= (const ImageCache&);
|
|
~ImageCache();
|
|
|
|
void timerCallback();
|
|
};
|
|
|
|
#endif // __JUCE_IMAGECACHE_JUCEHEADER__
|
|
/********* End of inlined file: juce_ImageCache.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ImageConvolutionKernel.h *********/
|
|
#ifndef __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__
|
|
#define __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__
|
|
|
|
/**
|
|
Represents a filter kernel to use in convoluting an image.
|
|
|
|
@see Image::applyConvolution
|
|
*/
|
|
class JUCE_API ImageConvolutionKernel
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty convulution kernel.
|
|
|
|
@param size the length of each dimension of the kernel, so e.g. if the size
|
|
is 5, it will create a 5x5 kernel
|
|
*/
|
|
ImageConvolutionKernel (const int size) throw();
|
|
|
|
/** Destructor. */
|
|
~ImageConvolutionKernel() throw();
|
|
|
|
/** Resets all values in the kernel to zero.
|
|
*/
|
|
void clear() throw();
|
|
|
|
/** Sets the value of a specific cell in the kernel.
|
|
|
|
The x and y parameters must be in the range 0 < x < getKernelSize().
|
|
|
|
@see setOverallSum
|
|
*/
|
|
void setKernelValue (const int x,
|
|
const int y,
|
|
const float value) throw();
|
|
|
|
/** Rescales all values in the kernel to make the total add up to a fixed value.
|
|
|
|
This will multiply all values in the kernel by (desiredTotalSum / currentTotalSum).
|
|
*/
|
|
void setOverallSum (const float desiredTotalSum) throw();
|
|
|
|
/** Multiplies all values in the kernel by a value. */
|
|
void rescaleAllValues (const float multiplier) throw();
|
|
|
|
/** Intialises the kernel for a gaussian blur.
|
|
|
|
@param blurRadius this may be larger or smaller than the kernel's actual
|
|
size but this will obviously be wasteful or clip at the
|
|
edges. Ideally the kernel should be just larger than
|
|
(blurRadius * 2).
|
|
*/
|
|
void createGaussianBlur (const float blurRadius) throw();
|
|
|
|
/** Returns the size of the kernel.
|
|
|
|
E.g. if it's a 3x3 kernel, this returns 3.
|
|
*/
|
|
int getKernelSize() const throw() { return size; }
|
|
|
|
/** Returns a 2-dimensional array of the kernel's values.
|
|
|
|
The size of each dimension of the array will be getKernelSize().
|
|
*/
|
|
float** getValues() const throw() { return values; }
|
|
|
|
/** Applies the kernel to an image.
|
|
|
|
@param destImage the image that will receive the resultant convoluted pixels.
|
|
@param sourceImage an optional source image to read from - if this is 0, then the
|
|
destination image will be used as the source. If an image is
|
|
specified, it must be exactly the same size and type as the destination
|
|
image.
|
|
@param x the region of the image to apply the filter to
|
|
@param y the region of the image to apply the filter to
|
|
@param width the region of the image to apply the filter to
|
|
@param height the region of the image to apply the filter to
|
|
*/
|
|
void applyToImage (Image& destImage,
|
|
const Image* sourceImage,
|
|
int x,
|
|
int y,
|
|
int width,
|
|
int height) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
float** values;
|
|
int size;
|
|
|
|
// no reason not to implement these one day..
|
|
ImageConvolutionKernel (const ImageConvolutionKernel&);
|
|
const ImageConvolutionKernel& operator= (const ImageConvolutionKernel&);
|
|
};
|
|
|
|
#endif // __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__
|
|
/********* End of inlined file: juce_ImageConvolutionKernel.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_IMAGEFILEFORMAT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ImageFileFormat.h *********/
|
|
#ifndef __JUCE_IMAGEFILEFORMAT_JUCEHEADER__
|
|
#define __JUCE_IMAGEFILEFORMAT_JUCEHEADER__
|
|
|
|
/**
|
|
Base-class for codecs that can read and write image file formats such
|
|
as PNG, JPEG, etc.
|
|
|
|
This class also contains static methods to make it easy to load images
|
|
from files, streams or from memory.
|
|
|
|
@see Image, ImageCache
|
|
*/
|
|
class JUCE_API ImageFileFormat
|
|
{
|
|
protected:
|
|
|
|
/** Creates an ImageFormat. */
|
|
ImageFileFormat() throw() {}
|
|
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~ImageFileFormat() throw() {}
|
|
|
|
/** Returns a description of this file format.
|
|
|
|
E.g. "JPEG", "PNG"
|
|
*/
|
|
virtual const String getFormatName() = 0;
|
|
|
|
/** Returns true if the given stream seems to contain data that this format
|
|
understands.
|
|
|
|
The format class should only read the first few bytes of the stream and sniff
|
|
for header bytes that it understands.
|
|
|
|
@see decodeImage
|
|
*/
|
|
virtual bool canUnderstand (InputStream& input) = 0;
|
|
|
|
/** Tries to decode and return an image from the given stream.
|
|
|
|
This will be called for an image format after calling its canUnderStand() method
|
|
to see if it can handle the stream.
|
|
|
|
@param input the stream to read the data from. The stream will be positioned
|
|
at the start of the image data (but this may not necessarily
|
|
be position 0)
|
|
@returns the image that was decoded, or 0 if it fails. It's the
|
|
caller's responsibility to delete this image when no longer needed.
|
|
@see loadFrom
|
|
*/
|
|
virtual Image* decodeImage (InputStream& input) = 0;
|
|
|
|
/** Attempts to write an image to a stream.
|
|
|
|
To specify extra information like encoding quality, there will be appropriate parameters
|
|
in the subclasses of the specific file types.
|
|
|
|
@returns true if it nothing went wrong.
|
|
*/
|
|
virtual bool writeImageToStream (const Image& sourceImage,
|
|
OutputStream& destStream) = 0;
|
|
|
|
/** Tries the built-in decoders to see if it can find one to read this stream.
|
|
|
|
There are currently built-in decoders for PNG, JPEG and GIF formats.
|
|
|
|
The object that is returned should not be deleted by the caller.
|
|
|
|
@see canUnderstand, decodeImage, loadFrom
|
|
*/
|
|
static ImageFileFormat* findImageFormatForStream (InputStream& input);
|
|
|
|
/** Tries to load an image from a stream.
|
|
|
|
This will use the findImageFormatForStream() method to locate a suitable
|
|
codec, and use that to load the image.
|
|
|
|
@returns the image that was decoded, or 0 if it fails to load one. It's the
|
|
caller's responsibility to delete this image when no longer needed.
|
|
*/
|
|
static Image* loadFrom (InputStream& input);
|
|
|
|
/** Tries to load an image from a file.
|
|
|
|
This will use the findImageFormatForStream() method to locate a suitable
|
|
codec, and use that to load the image.
|
|
|
|
@returns the image that was decoded, or 0 if it fails to load one. It's the
|
|
caller's responsibility to delete this image when no longer needed.
|
|
*/
|
|
static Image* loadFrom (const File& file);
|
|
|
|
/** Tries to load an image from a block of raw image data.
|
|
|
|
This will use the findImageFormatForStream() method to locate a suitable
|
|
codec, and use that to load the image.
|
|
|
|
@returns the image that was decoded, or 0 if it fails to load one. It's the
|
|
caller's responsibility to delete this image when no longer needed.
|
|
*/
|
|
static Image* loadFrom (const void* rawData,
|
|
const int numBytesOfData);
|
|
|
|
};
|
|
|
|
/**
|
|
A type of ImageFileFormat for reading and writing PNG files.
|
|
|
|
@see ImageFileFormat, JPEGImageFormat
|
|
*/
|
|
class JUCE_API PNGImageFormat : public ImageFileFormat
|
|
{
|
|
public:
|
|
|
|
PNGImageFormat() throw();
|
|
~PNGImageFormat() throw();
|
|
|
|
const String getFormatName();
|
|
bool canUnderstand (InputStream& input);
|
|
|
|
Image* decodeImage (InputStream& input);
|
|
|
|
bool writeImageToStream (const Image& sourceImage, OutputStream& destStream);
|
|
};
|
|
|
|
/**
|
|
A type of ImageFileFormat for reading and writing JPEG files.
|
|
|
|
@see ImageFileFormat, PNGImageFormat
|
|
*/
|
|
class JUCE_API JPEGImageFormat : public ImageFileFormat
|
|
{
|
|
public:
|
|
|
|
JPEGImageFormat() throw();
|
|
~JPEGImageFormat() throw();
|
|
|
|
/** Specifies the quality to be used when writing a JPEG file.
|
|
|
|
@param newQuality a value 0 to 1.0, where 0 is low quality, 1.0 is best, or
|
|
any negative value is "default" quality
|
|
*/
|
|
void setQuality (const float newQuality);
|
|
|
|
const String getFormatName();
|
|
|
|
bool canUnderstand (InputStream& input);
|
|
|
|
Image* decodeImage (InputStream& input);
|
|
|
|
bool writeImageToStream (const Image& sourceImage, OutputStream& destStream);
|
|
|
|
private:
|
|
float quality;
|
|
};
|
|
|
|
#endif // __JUCE_IMAGEFILEFORMAT_JUCEHEADER__
|
|
/********* End of inlined file: juce_ImageFileFormat.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DrawableText.h *********/
|
|
#ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__
|
|
#define __JUCE_DRAWABLETEXT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Drawable.h *********/
|
|
#ifndef __JUCE_DRAWABLE_JUCEHEADER__
|
|
#define __JUCE_DRAWABLE_JUCEHEADER__
|
|
|
|
/**
|
|
The base class for objects which can draw themselves, e.g. polygons, images, etc.
|
|
|
|
@see DrawableComposite, DrawableImage, DrawablePath, DrawableText
|
|
*/
|
|
class JUCE_API Drawable
|
|
{
|
|
protected:
|
|
|
|
/** The base class can't be instantiated directly.
|
|
|
|
@see DrawableComposite, DrawableImage, DrawablePath, DrawableText
|
|
*/
|
|
Drawable();
|
|
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~Drawable();
|
|
|
|
/** Creates a deep copy of this Drawable object.
|
|
|
|
Use this to create a new copy of this and any sub-objects in the tree.
|
|
*/
|
|
virtual Drawable* createCopy() const = 0;
|
|
|
|
/** Renders this Drawable object.
|
|
@see drawWithin
|
|
*/
|
|
void draw (Graphics& g,
|
|
const AffineTransform& transform = AffineTransform::identity) const;
|
|
|
|
/** Renders the Drawable at a given offset within the Graphics context.
|
|
|
|
The co-ordinates passed-in are used to translate the object relative to its own
|
|
origin before drawing it - this is basically a quick way of saying:
|
|
|
|
@code
|
|
draw (g, AffineTransform::translation (x, y)).
|
|
@endcode
|
|
*/
|
|
void drawAt (Graphics& g,
|
|
const float x,
|
|
const float y) const;
|
|
|
|
/** Renders the Drawable within a rectangle, scaling it to fit neatly inside without
|
|
changing its aspect-ratio.
|
|
|
|
The object can placed arbitrarily within the rectangle based on a Justification type,
|
|
and can either be made as big as possible, or just reduced to fit.
|
|
|
|
@param g the graphics context to render onto
|
|
@param destX top-left of the target rectangle to fit it into
|
|
@param destY top-left of the target rectangle to fit it into
|
|
@param destWidth size of the target rectangle to fit the image into
|
|
@param destHeight size of the target rectangle to fit the image into
|
|
@param placement defines the alignment and rescaling to use to fit
|
|
this object within the target rectangle.
|
|
*/
|
|
void drawWithin (Graphics& g,
|
|
const int destX,
|
|
const int destY,
|
|
const int destWidth,
|
|
const int destHeight,
|
|
const RectanglePlacement& placement) const;
|
|
|
|
/** Holds the information needed when telling a drawable to render itself.
|
|
@see Drawable::draw
|
|
*/
|
|
class RenderingContext
|
|
{
|
|
public:
|
|
RenderingContext (Graphics& g, const AffineTransform& transform, const float opacity) throw();
|
|
|
|
Graphics& g;
|
|
AffineTransform transform;
|
|
float opacity;
|
|
|
|
private:
|
|
const RenderingContext& operator= (const RenderingContext&);
|
|
};
|
|
|
|
/** Renders this Drawable object.
|
|
@see draw
|
|
*/
|
|
virtual void render (const RenderingContext& context) const = 0;
|
|
|
|
/** Returns the smallest rectangle that can contain this Drawable object.
|
|
|
|
Co-ordinates are relative to the object's own origin.
|
|
*/
|
|
virtual void getBounds (float& x, float& y, float& width, float& height) const = 0;
|
|
|
|
/** Returns true if the given point is somewhere inside this Drawable.
|
|
|
|
Co-ordinates are relative to the object's own origin.
|
|
*/
|
|
virtual bool hitTest (float x, float y) const = 0;
|
|
|
|
/** Returns the name given to this drawable.
|
|
@see setName
|
|
*/
|
|
const String& getName() const throw() { return name; }
|
|
|
|
/** Assigns a name to this drawable. */
|
|
void setName (const String& newName) throw() { name = newName; }
|
|
|
|
/** Tries to turn some kind of image file into a drawable.
|
|
|
|
The data could be an image that the ImageFileFormat class understands, or it
|
|
could be SVG.
|
|
*/
|
|
static Drawable* createFromImageData (const void* data, const int numBytes);
|
|
|
|
/** Tries to turn a stream containing some kind of image data into a drawable.
|
|
|
|
The data could be an image that the ImageFileFormat class understands, or it
|
|
could be SVG.
|
|
*/
|
|
static Drawable* createFromImageDataStream (InputStream& dataSource);
|
|
|
|
/** Tries to turn a file containing some kind of image data into a drawable.
|
|
|
|
The data could be an image that the ImageFileFormat class understands, or it
|
|
could be SVG.
|
|
*/
|
|
static Drawable* createFromImageFile (const File& file);
|
|
|
|
/** Attempts to parse an SVG (Scalable Vector Graphics) document, and to turn this
|
|
into a Drawable tree.
|
|
|
|
The object returned must be deleted by the caller. If something goes wrong
|
|
while parsing, it may return 0.
|
|
|
|
SVG is a pretty large and complex spec, and this doesn't aim to be a full
|
|
implementation, but it can return the basic vector objects.
|
|
*/
|
|
static Drawable* createFromSVG (const XmlElement& svgDocument);
|
|
|
|
/**
|
|
*/
|
|
static Drawable* readFromBinaryStream (InputStream& input);
|
|
|
|
/**
|
|
*/
|
|
bool writeToBinaryStream (OutputStream& output) const;
|
|
|
|
/**
|
|
*/
|
|
static Drawable* readFromXml (const XmlElement& xml);
|
|
|
|
/**
|
|
*/
|
|
XmlElement* createXml() const;
|
|
|
|
/** @internal */
|
|
virtual bool readBinary (InputStream& input) = 0;
|
|
/** @internal */
|
|
virtual bool writeBinary (OutputStream& output) const = 0;
|
|
/** @internal */
|
|
virtual bool readXml (const XmlElement& xml) = 0;
|
|
/** @internal */
|
|
virtual void writeXml (XmlElement& xml) const = 0;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Drawable (const Drawable&);
|
|
const Drawable& operator= (const Drawable&);
|
|
|
|
String name;
|
|
};
|
|
|
|
#endif // __JUCE_DRAWABLE_JUCEHEADER__
|
|
/********* End of inlined file: juce_Drawable.h *********/
|
|
|
|
/**
|
|
A drawable object which renders a line of text.
|
|
|
|
@see Drawable
|
|
*/
|
|
class JUCE_API DrawableText : public Drawable
|
|
{
|
|
public:
|
|
|
|
/** Creates a DrawableText object. */
|
|
DrawableText();
|
|
|
|
/** Destructor. */
|
|
virtual ~DrawableText();
|
|
|
|
/** Sets the block of text to render */
|
|
void setText (const GlyphArrangement& newText);
|
|
|
|
/** Sets a single line of text to render.
|
|
|
|
This is a convenient method of adding a single line - for
|
|
more complex text, use the setText() that takes a
|
|
GlyphArrangement instead.
|
|
*/
|
|
void setText (const String& newText, const Font& fontToUse);
|
|
|
|
/** Returns the text arrangement that was set with setText(). */
|
|
const GlyphArrangement& getText() const throw() { return text; }
|
|
|
|
/** Sets the colour of the text. */
|
|
void setColour (const Colour& newColour);
|
|
|
|
/** Returns the current text colour. */
|
|
const Colour& getColour() const throw() { return colour; }
|
|
|
|
/** @internal */
|
|
void render (const Drawable::RenderingContext& context) const;
|
|
/** @internal */
|
|
void getBounds (float& x, float& y, float& width, float& height) const;
|
|
/** @internal */
|
|
bool hitTest (float x, float y) const;
|
|
/** @internal */
|
|
Drawable* createCopy() const;
|
|
/** @internal */
|
|
bool readBinary (InputStream& input);
|
|
/** @internal */
|
|
bool writeBinary (OutputStream& output) const;
|
|
/** @internal */
|
|
bool readXml (const XmlElement& xml);
|
|
/** @internal */
|
|
void writeXml (XmlElement& xml) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
GlyphArrangement text;
|
|
Colour colour;
|
|
|
|
DrawableText (const DrawableText&);
|
|
const DrawableText& operator= (const DrawableText&);
|
|
};
|
|
|
|
#endif // __JUCE_DRAWABLETEXT_JUCEHEADER__
|
|
/********* End of inlined file: juce_DrawableText.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DrawablePath.h *********/
|
|
#ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__
|
|
#define __JUCE_DRAWABLEPATH_JUCEHEADER__
|
|
|
|
/**
|
|
A drawable object which renders a filled or outlined shape.
|
|
|
|
@see Drawable
|
|
*/
|
|
class JUCE_API DrawablePath : public Drawable
|
|
{
|
|
public:
|
|
|
|
/** Creates a DrawablePath.
|
|
*/
|
|
DrawablePath();
|
|
|
|
/** Destructor. */
|
|
virtual ~DrawablePath();
|
|
|
|
/** Changes the path that will be drawn.
|
|
|
|
@see setSolidFill, setOutline
|
|
*/
|
|
void setPath (const Path& newPath);
|
|
|
|
/** Returns the current path. */
|
|
const Path& getPath() const throw() { return path; }
|
|
|
|
/** Sets a colour to fill the path with.
|
|
|
|
This colour is used to fill the path - if you don't want the path to be
|
|
filled (e.g. if you're just drawing an outline), set this colour to be
|
|
transparent.
|
|
|
|
@see setPath, setOutline
|
|
*/
|
|
void setSolidFill (const Colour& newColour);
|
|
|
|
/** Sets a custom brush to use to fill the path.
|
|
|
|
@see setSolidFill
|
|
*/
|
|
void setFillBrush (const Brush& newBrush);
|
|
|
|
/** Returns the brush currently being used to fill the shape. */
|
|
Brush* getCurrentBrush() const throw() { return fillBrush; }
|
|
|
|
/** Changes the properties of the outline that will be drawn around the path.
|
|
|
|
If the thickness value is 0, no outline will be drawn. If one is drawn, the
|
|
colour passed-in here will be used for it.
|
|
|
|
@see setPath, setSolidFill
|
|
*/
|
|
void setOutline (const float thickness,
|
|
const Colour& outlineColour);
|
|
|
|
/** Changes the properties of the outline that will be drawn around the path.
|
|
|
|
If the stroke type has 0 thickness, no outline will be drawn.
|
|
|
|
@see setPath, setSolidFill
|
|
*/
|
|
void setOutline (const PathStrokeType& strokeType,
|
|
const Brush& strokeBrush);
|
|
|
|
/** Returns the current outline style. */
|
|
const PathStrokeType& getOutlineStroke() const throw() { return strokeType; }
|
|
|
|
/** Returns the brush currently being used to draw the outline. */
|
|
Brush* getOutlineBrush() const throw() { return strokeBrush; }
|
|
|
|
/** @internal */
|
|
void render (const Drawable::RenderingContext& context) const;
|
|
/** @internal */
|
|
void getBounds (float& x, float& y, float& width, float& height) const;
|
|
/** @internal */
|
|
bool hitTest (float x, float y) const;
|
|
/** @internal */
|
|
Drawable* createCopy() const;
|
|
/** @internal */
|
|
bool readBinary (InputStream& input);
|
|
/** @internal */
|
|
bool writeBinary (OutputStream& output) const;
|
|
/** @internal */
|
|
bool readXml (const XmlElement& xml);
|
|
/** @internal */
|
|
void writeXml (XmlElement& xml) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Path path, outline;
|
|
Brush* fillBrush;
|
|
Brush* strokeBrush;
|
|
PathStrokeType strokeType;
|
|
|
|
void updateOutline();
|
|
|
|
DrawablePath (const DrawablePath&);
|
|
const DrawablePath& operator= (const DrawablePath&);
|
|
};
|
|
|
|
#endif // __JUCE_DRAWABLEPATH_JUCEHEADER__
|
|
/********* End of inlined file: juce_DrawablePath.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DrawableComposite.h *********/
|
|
#ifndef __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__
|
|
#define __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__
|
|
|
|
/**
|
|
A drawable object which acts as a container for a set of other Drawables.
|
|
|
|
@see Drawable
|
|
*/
|
|
class JUCE_API DrawableComposite : public Drawable
|
|
{
|
|
public:
|
|
|
|
/** Creates a composite Drawable.
|
|
*/
|
|
DrawableComposite();
|
|
|
|
/** Destructor. */
|
|
virtual ~DrawableComposite();
|
|
|
|
/** Adds a new sub-drawable to this one.
|
|
|
|
This passes in a Drawable pointer for this object to look after. To add a copy
|
|
of a drawable, use the form of this method that takes a Drawable reference instead.
|
|
|
|
@param drawable the object to add - this will be deleted automatically
|
|
when no longer needed, so the caller mustn't keep any
|
|
pointers to it.
|
|
@param transform the transform to apply to this drawable when it's being
|
|
drawn
|
|
@param index where to insert it in the list of drawables. 0 is the back,
|
|
-1 is the front, or any value from 0 and getNumDrawables()
|
|
can be used
|
|
@see removeDrawable
|
|
*/
|
|
void insertDrawable (Drawable* drawable,
|
|
const AffineTransform& transform = AffineTransform::identity,
|
|
const int index = -1);
|
|
|
|
/** Adds a new sub-drawable to this one.
|
|
|
|
This takes a copy of a Drawable and adds it to this object. To pass in a Drawable
|
|
for this object to look after, use the form of this method that takes a Drawable
|
|
pointer instead.
|
|
|
|
@param drawable the object to add - an internal copy will be made of this object
|
|
@param transform the transform to apply to this drawable when it's being
|
|
drawn
|
|
@param index where to insert it in the list of drawables. 0 is the back,
|
|
-1 is the front, or any value from 0 and getNumDrawables()
|
|
can be used
|
|
@see removeDrawable
|
|
*/
|
|
void insertDrawable (const Drawable& drawable,
|
|
const AffineTransform& transform = AffineTransform::identity,
|
|
const int index = -1);
|
|
|
|
/** Deletes one of the Drawable objects.
|
|
|
|
@param index the index of the drawable to delete, between 0
|
|
and (getNumDrawables() - 1).
|
|
@param deleteDrawable if this is true, the drawable that is removed will also
|
|
be deleted. If false, it'll just be removed.
|
|
@see insertDrawable, getNumDrawables
|
|
*/
|
|
void removeDrawable (const int index, const bool deleteDrawable = true);
|
|
|
|
/** Returns the number of drawables contained inside this one.
|
|
|
|
@see getDrawable
|
|
*/
|
|
int getNumDrawables() const throw() { return drawables.size(); }
|
|
|
|
/** Returns one of the drawables that are contained in this one.
|
|
|
|
Each drawable also has a transform associated with it - you can use getDrawableTransform()
|
|
to find it.
|
|
|
|
The pointer returned is managed by this object and will be deleted when no longer
|
|
needed, so be careful what you do with it.
|
|
|
|
@see getNumDrawables
|
|
*/
|
|
Drawable* getDrawable (const int index) const throw() { return drawables [index]; }
|
|
|
|
/** Returns the transform that applies to one of the drawables that are contained in this one.
|
|
|
|
The pointer returned is managed by this object and will be deleted when no longer
|
|
needed, so be careful what you do with it.
|
|
|
|
@see getNumDrawables
|
|
*/
|
|
const AffineTransform* getDrawableTransform (const int index) const throw() { return transforms [index]; }
|
|
|
|
/** Brings one of the Drawables to the front.
|
|
|
|
@param index the index of the drawable to move, between 0
|
|
and (getNumDrawables() - 1).
|
|
@see insertDrawable, getNumDrawables
|
|
*/
|
|
void bringToFront (const int index);
|
|
|
|
/** @internal */
|
|
void render (const Drawable::RenderingContext& context) const;
|
|
/** @internal */
|
|
void getBounds (float& x, float& y, float& width, float& height) const;
|
|
/** @internal */
|
|
bool hitTest (float x, float y) const;
|
|
/** @internal */
|
|
Drawable* createCopy() const;
|
|
/** @internal */
|
|
bool readBinary (InputStream& input);
|
|
/** @internal */
|
|
bool writeBinary (OutputStream& output) const;
|
|
/** @internal */
|
|
bool readXml (const XmlElement& xml);
|
|
/** @internal */
|
|
void writeXml (XmlElement& xml) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
OwnedArray <Drawable> drawables;
|
|
OwnedArray <AffineTransform> transforms;
|
|
|
|
DrawableComposite (const DrawableComposite&);
|
|
const DrawableComposite& operator= (const DrawableComposite&);
|
|
};
|
|
|
|
#endif // __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__
|
|
/********* End of inlined file: juce_DrawableComposite.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DRAWABLEIMAGE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DrawableImage.h *********/
|
|
#ifndef __JUCE_DRAWABLEIMAGE_JUCEHEADER__
|
|
#define __JUCE_DRAWABLEIMAGE_JUCEHEADER__
|
|
|
|
/**
|
|
A drawable object which is a bitmap image.
|
|
|
|
@see Drawable
|
|
*/
|
|
class JUCE_API DrawableImage : public Drawable
|
|
{
|
|
public:
|
|
|
|
DrawableImage();
|
|
|
|
/** Destructor. */
|
|
virtual ~DrawableImage();
|
|
|
|
/** Sets the image that this drawable will render.
|
|
|
|
An internal copy is made of the image passed-in. If you want to provide an
|
|
image that this object can take charge of without needing to create a copy,
|
|
use the other setImage() method.
|
|
*/
|
|
void setImage (const Image& imageToCopy);
|
|
|
|
/** Sets the image that this drawable will render.
|
|
|
|
An internal copy of this will not be made, so the caller mustn't delete
|
|
the image while it's still being used by this object.
|
|
|
|
A good way to use this is with the ImageCache - if you create an image
|
|
with ImageCache and pass it in here with releaseWhenNotNeeded = true, then
|
|
it'll be released neatly with its reference count being decreased.
|
|
|
|
@param imageToUse the image to render
|
|
@param releaseWhenNotNeeded if false, a simple pointer is kept to the image; if true,
|
|
then the image will be deleted when this object no longer
|
|
needs it - unless the image was created by the ImageCache,
|
|
in which case it will be released with ImageCache::release().
|
|
*/
|
|
void setImage (Image* imageToUse,
|
|
const bool releaseWhenNotNeeded);
|
|
|
|
/** Returns the current image. */
|
|
Image* getImage() const throw() { return image; }
|
|
|
|
/** Clears (and possibly deletes) the currently set image. */
|
|
void clearImage();
|
|
|
|
/** Sets the opacity to use when drawing the image. */
|
|
void setOpacity (const float newOpacity);
|
|
|
|
/** Returns the image's opacity. */
|
|
float getOpacity() const throw() { return opacity; }
|
|
|
|
/** Sets a colour to draw over the image's alpha channel.
|
|
|
|
By default this is transparent so isn't drawn, but if you set a non-transparent
|
|
colour here, then it will be overlaid on the image, using the image's alpha
|
|
channel as a mask.
|
|
|
|
This is handy for doing things like darkening or lightening an image by overlaying
|
|
it with semi-transparent black or white.
|
|
*/
|
|
void setOverlayColour (const Colour& newOverlayColour);
|
|
|
|
/** Returns the overlay colour. */
|
|
const Colour& getOverlayColour() const throw() { return overlayColour; }
|
|
|
|
/** @internal */
|
|
void render (const Drawable::RenderingContext& context) const;
|
|
/** @internal */
|
|
void getBounds (float& x, float& y, float& width, float& height) const;
|
|
/** @internal */
|
|
bool hitTest (float x, float y) const;
|
|
/** @internal */
|
|
Drawable* createCopy() const;
|
|
/** @internal */
|
|
bool readBinary (InputStream& input);
|
|
/** @internal */
|
|
bool writeBinary (OutputStream& output) const;
|
|
/** @internal */
|
|
bool readXml (const XmlElement& xml);
|
|
/** @internal */
|
|
void writeXml (XmlElement& xml) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Image* image;
|
|
bool canDeleteImage;
|
|
float opacity;
|
|
Colour overlayColour;
|
|
|
|
DrawableImage (const DrawableImage&);
|
|
const DrawableImage& operator= (const DrawableImage&);
|
|
};
|
|
|
|
#endif // __JUCE_DRAWABLEIMAGE_JUCEHEADER__
|
|
/********* End of inlined file: juce_DrawableImage.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DRAWABLE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_COMPONENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_COMPONENTLISTENER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_DESKTOP_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_ARROWBUTTON_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ArrowButton.h *********/
|
|
#ifndef __JUCE_ARROWBUTTON_JUCEHEADER__
|
|
#define __JUCE_ARROWBUTTON_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DropShadowEffect.h *********/
|
|
#ifndef __JUCE_DROPSHADOWEFFECT_JUCEHEADER__
|
|
#define __JUCE_DROPSHADOWEFFECT_JUCEHEADER__
|
|
|
|
/**
|
|
An effect filter that adds a drop-shadow behind the image's content.
|
|
|
|
(This will only work on images/components that aren't opaque, of course).
|
|
|
|
When added to a component, this effect will draw a soft-edged
|
|
shadow based on what gets drawn inside it. The shadow will also
|
|
be applied to the component's children.
|
|
|
|
For speed, this doesn't use a proper gaussian blur, but cheats by
|
|
using a simple bilinear filter. If you need a really high-quality
|
|
shadow, check out ImageConvolutionKernel::createGaussianBlur()
|
|
|
|
@see Component::setComponentEffect
|
|
*/
|
|
class JUCE_API DropShadowEffect : public ImageEffectFilter
|
|
{
|
|
public:
|
|
|
|
/** Creates a default drop-shadow effect.
|
|
|
|
To customise the shadow's appearance, use the setShadowProperties()
|
|
method.
|
|
*/
|
|
DropShadowEffect();
|
|
|
|
/** Destructor. */
|
|
~DropShadowEffect();
|
|
|
|
/** Sets up parameters affecting the shadow's appearance.
|
|
|
|
@param newRadius the (approximate) radius of the blur used
|
|
@param newOpacity the opacity with which the shadow is rendered
|
|
@param newShadowOffsetX allows the shadow to be shifted in relation to the
|
|
component's contents
|
|
@param newShadowOffsetY allows the shadow to be shifted in relation to the
|
|
component's contents
|
|
*/
|
|
void setShadowProperties (const float newRadius,
|
|
const float newOpacity,
|
|
const int newShadowOffsetX,
|
|
const int newShadowOffsetY);
|
|
|
|
/** @internal */
|
|
void applyEffect (Image& sourceImage, Graphics& destContext);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int offsetX, offsetY;
|
|
float radius, opacity;
|
|
};
|
|
|
|
#endif // __JUCE_DROPSHADOWEFFECT_JUCEHEADER__
|
|
/********* End of inlined file: juce_DropShadowEffect.h *********/
|
|
|
|
/**
|
|
A button with an arrow in it.
|
|
|
|
@see Button
|
|
*/
|
|
class JUCE_API ArrowButton : public Button
|
|
{
|
|
public:
|
|
|
|
/** Creates an ArrowButton.
|
|
|
|
@param buttonName the name to give the button
|
|
@param arrowDirection the direction the arrow should point in, where 0.0 is
|
|
pointing right, 0.25 is down, 0.5 is left, 0.75 is up
|
|
@param arrowColour the colour to use for the arrow
|
|
*/
|
|
ArrowButton (const String& buttonName,
|
|
float arrowDirection,
|
|
const Colour& arrowColour);
|
|
|
|
/** Destructor. */
|
|
~ArrowButton();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void paintButton (Graphics& g,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
/** @internal */
|
|
void buttonStateChanged();
|
|
|
|
private:
|
|
|
|
Colour colour;
|
|
DropShadowEffect shadow;
|
|
Path path;
|
|
int offset;
|
|
|
|
ArrowButton (const ArrowButton&);
|
|
const ArrowButton& operator= (const ArrowButton&);
|
|
};
|
|
|
|
#endif // __JUCE_ARROWBUTTON_JUCEHEADER__
|
|
/********* End of inlined file: juce_ArrowButton.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_BUTTON_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_DRAWABLEBUTTON_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DrawableButton.h *********/
|
|
#ifndef __JUCE_DRAWABLEBUTTON_JUCEHEADER__
|
|
#define __JUCE_DRAWABLEBUTTON_JUCEHEADER__
|
|
|
|
/**
|
|
A button that displays a Drawable.
|
|
|
|
Up to three Drawable objects can be given to this button, to represent the
|
|
'normal', 'over' and 'down' states.
|
|
|
|
@see Button
|
|
*/
|
|
class JUCE_API DrawableButton : public Button
|
|
{
|
|
public:
|
|
|
|
enum ButtonStyle
|
|
{
|
|
ImageFitted, /**< The button will just display the images, but will resize and centre them to fit inside it. */
|
|
ImageRaw, /**< The button will just display the images in their normal size and position.
|
|
This leaves it up to the caller to make sure the images are the correct size and position for the button. */
|
|
ImageAboveTextLabel, /**< Draws the button as a text label across the bottom with the image resized and scaled to fit above it. */
|
|
ImageOnButtonBackground /**< Draws the button as a standard rounded-rectangle button with the image on top. */
|
|
};
|
|
|
|
/** Creates a DrawableButton.
|
|
|
|
After creating one of these, use setImages() to specify the drawables to use.
|
|
|
|
@param buttonName the name to give the component
|
|
@param buttonStyle the layout to use
|
|
|
|
@see ButtonStyle, setButtonStyle, setImages
|
|
*/
|
|
DrawableButton (const String& buttonName,
|
|
const ButtonStyle buttonStyle);
|
|
|
|
/** Destructor. */
|
|
~DrawableButton();
|
|
|
|
/** Sets up the images to draw for the various button states.
|
|
|
|
The button will keep its own internal copies of these drawables.
|
|
|
|
@param normalImage the thing to draw for the button's 'normal' state. An internal copy
|
|
will be made of the object passed-in if it is non-zero.
|
|
@param overImage the thing to draw for the button's 'over' state - if this is
|
|
zero, the button's normal image will be used when the mouse is
|
|
over it. An internal copy will be made of the object passed-in
|
|
if it is non-zero.
|
|
@param downImage the thing to draw for the button's 'down' state - if this is
|
|
zero, the 'over' image will be used instead (or the normal image
|
|
as a last resort). An internal copy will be made of the object
|
|
passed-in if it is non-zero.
|
|
@param disabledImage an image to draw when the button is disabled. If this is zero,
|
|
the normal image will be drawn with a reduced opacity instead.
|
|
An internal copy will be made of the object passed-in if it is
|
|
non-zero.
|
|
@param normalImageOn same as the normalImage, but this is used when the button's toggle
|
|
state is 'on'. If this is 0, the normal image is used instead
|
|
@param overImageOn same as the overImage, but this is used when the button's toggle
|
|
state is 'on'. If this is 0, the normalImageOn is drawn instead
|
|
@param downImageOn same as the downImage, but this is used when the button's toggle
|
|
state is 'on'. If this is 0, the overImageOn is drawn instead
|
|
@param disabledImageOn same as the disabledImage, but this is used when the button's toggle
|
|
state is 'on'. If this is 0, the normal image will be drawn instead
|
|
with a reduced opacity
|
|
*/
|
|
void setImages (const Drawable* normalImage,
|
|
const Drawable* overImage = 0,
|
|
const Drawable* downImage = 0,
|
|
const Drawable* disabledImage = 0,
|
|
const Drawable* normalImageOn = 0,
|
|
const Drawable* overImageOn = 0,
|
|
const Drawable* downImageOn = 0,
|
|
const Drawable* disabledImageOn = 0);
|
|
|
|
/** Changes the button's style.
|
|
|
|
@see ButtonStyle
|
|
*/
|
|
void setButtonStyle (const ButtonStyle newStyle);
|
|
|
|
/** Changes the button's background colours.
|
|
|
|
The toggledOffColour is the colour to use when the button's toggle state
|
|
is off, and toggledOnColour when it's on.
|
|
|
|
For an ImageOnly or ImageAboveTextLabel style, the background colour is
|
|
used to fill the background of the component.
|
|
|
|
For an ImageOnButtonBackground style, the colour is used to draw the
|
|
button's lozenge shape and exactly how the colour's used will depend
|
|
on the LookAndFeel.
|
|
*/
|
|
void setBackgroundColours (const Colour& toggledOffColour,
|
|
const Colour& toggledOnColour);
|
|
|
|
/** Returns the current background colour being used.
|
|
|
|
@see setBackgroundColour
|
|
*/
|
|
const Colour& getBackgroundColour() const throw();
|
|
|
|
/** Gives the button an optional amount of space around the edge of the drawable.
|
|
|
|
This will only apply to ImageFitted or ImageRaw styles, it won't affect the
|
|
ones on a button background. If the button is too small for the given gap, a
|
|
smaller gap will be used.
|
|
|
|
By default there's a gap of about 3 pixels.
|
|
*/
|
|
void setEdgeIndent (const int numPixelsIndent);
|
|
|
|
/** Returns the image that the button is currently displaying. */
|
|
const Drawable* getCurrentImage() const throw();
|
|
const Drawable* getNormalImage() const throw();
|
|
const Drawable* getOverImage() const throw();
|
|
const Drawable* getDownImage() const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void paintButton (Graphics& g,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
private:
|
|
|
|
ButtonStyle style;
|
|
Drawable* normalImage;
|
|
Drawable* overImage;
|
|
Drawable* downImage;
|
|
Drawable* disabledImage;
|
|
Drawable* normalImageOn;
|
|
Drawable* overImageOn;
|
|
Drawable* downImageOn;
|
|
Drawable* disabledImageOn;
|
|
Colour backgroundOff, backgroundOn;
|
|
int edgeIndent;
|
|
|
|
void deleteImages();
|
|
DrawableButton (const DrawableButton&);
|
|
const DrawableButton& operator= (const DrawableButton&);
|
|
};
|
|
|
|
#endif // __JUCE_DRAWABLEBUTTON_JUCEHEADER__
|
|
/********* End of inlined file: juce_DrawableButton.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_HYPERLINKBUTTON_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_HyperlinkButton.h *********/
|
|
#ifndef __JUCE_HYPERLINKBUTTON_JUCEHEADER__
|
|
#define __JUCE_HYPERLINKBUTTON_JUCEHEADER__
|
|
|
|
/**
|
|
A button showing an underlined weblink, that will launch the link
|
|
when it's clicked.
|
|
|
|
@see Button
|
|
*/
|
|
class JUCE_API HyperlinkButton : public Button
|
|
{
|
|
public:
|
|
|
|
/** Creates a HyperlinkButton.
|
|
|
|
@param linkText the text that will be displayed in the button - this is
|
|
also set as the Component's name, but the text can be
|
|
changed later with the Button::getButtonText() method
|
|
@param linkURL the URL to launch when the user clicks the button
|
|
*/
|
|
HyperlinkButton (const String& linkText,
|
|
const URL& linkURL);
|
|
|
|
/** Destructor. */
|
|
~HyperlinkButton();
|
|
|
|
/** Changes the font to use for the text.
|
|
|
|
If resizeToMatchComponentHeight is true, the font's height will be adjusted
|
|
to match the size of the component.
|
|
*/
|
|
void setFont (const Font& newFont,
|
|
const bool resizeToMatchComponentHeight,
|
|
const Justification& justificationType = Justification::horizontallyCentred);
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the link.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
textColourId = 0x1001f00, /**< The colour to use for the URL text. */
|
|
};
|
|
|
|
/** Changes the URL that the button will trigger. */
|
|
void setURL (const URL& newURL) throw();
|
|
|
|
/** Returns the URL that the button will trigger. */
|
|
const URL& getURL() const throw() { return url; }
|
|
|
|
/** Resizes the button horizontally to fit snugly around the text.
|
|
|
|
This won't affect the button's height.
|
|
*/
|
|
void changeWidthToFitText();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void clicked();
|
|
/** @internal */
|
|
void colourChanged();
|
|
/** @internal */
|
|
void paintButton (Graphics& g,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
private:
|
|
URL url;
|
|
Font font;
|
|
bool resizeFont;
|
|
Justification justification;
|
|
|
|
const Font getFontToUse() const;
|
|
|
|
HyperlinkButton (const HyperlinkButton&);
|
|
const HyperlinkButton& operator= (const HyperlinkButton&);
|
|
};
|
|
|
|
#endif // __JUCE_HYPERLINKBUTTON_JUCEHEADER__
|
|
/********* End of inlined file: juce_HyperlinkButton.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_IMAGEBUTTON_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ImageButton.h *********/
|
|
#ifndef __JUCE_IMAGEBUTTON_JUCEHEADER__
|
|
#define __JUCE_IMAGEBUTTON_JUCEHEADER__
|
|
|
|
/**
|
|
As the title suggests, this is a button containing an image.
|
|
|
|
The colour and transparency of the image can be set to vary when the
|
|
button state changes.
|
|
|
|
@see Button, ShapeButton, TextButton
|
|
*/
|
|
class JUCE_API ImageButton : public Button
|
|
{
|
|
public:
|
|
|
|
/** Creates an ImageButton.
|
|
|
|
Use setImage() to specify the image to use. The colours and opacities that
|
|
are specified here can be changed later using setDrawingOptions().
|
|
|
|
@param name the name to give the component
|
|
*/
|
|
ImageButton (const String& name);
|
|
|
|
/** Destructor. */
|
|
~ImageButton();
|
|
|
|
/** Sets up the images to draw in various states.
|
|
|
|
Important! Bear in mind that if you pass the same image in for more than one of
|
|
these parameters, this button will delete it (or release from the ImageCache)
|
|
multiple times!
|
|
|
|
@param resizeButtonNowToFitThisImage if true, the button will be immediately
|
|
resized to the same dimensions as the normal image
|
|
@param rescaleImagesWhenButtonSizeChanges if true, the image will be rescaled to fit the
|
|
button when the button's size changes
|
|
@param preserveImageProportions if true then any rescaling of the image to fit
|
|
the button will keep the image's x and y proportions
|
|
correct - i.e. it won't distort its shape, although
|
|
this might create gaps around the edges
|
|
@param normalImage the image to use when the button is in its normal state. The
|
|
image passed in will be deleted (or released if it
|
|
was created by the ImageCache class) when the
|
|
button no longer needs it.
|
|
@param imageOpacityWhenNormal the opacity to use when drawing the normal image.
|
|
@param overlayColourWhenNormal an overlay colour to use to fill the alpha channel of the
|
|
normal image - if this colour is transparent, no overlay
|
|
will be drawn. The overlay will be drawn over the top of the
|
|
image, so you can basically add a solid or semi-transparent
|
|
colour to the image to brighten or darken it
|
|
@param overImage the image to use when the mouse is over the button. If
|
|
you want to use the same image as was set in the normalImage
|
|
parameter, this value can be 0. As for normalImage, it
|
|
will be deleted or released by the button when no longer
|
|
needed
|
|
@param imageOpacityWhenOver the opacity to use when drawing the image when the mouse
|
|
is over the button
|
|
@param overlayColourWhenOver an overlay colour to use to fill the alpha channel of the
|
|
image when the mouse is over - if this colour is transparent,
|
|
no overlay will be drawn
|
|
@param downImage an image to use when the button is pressed down. If set
|
|
to zero, the 'over' image will be drawn instead (or the
|
|
normal image if there isn't an 'over' image either). This
|
|
image will be deleted or released by the button when no
|
|
longer needed
|
|
@param imageOpacityWhenDown the opacity to use when drawing the image when the button
|
|
is pressed
|
|
@param overlayColourWhenDown an overlay colour to use to fill the alpha channel of the
|
|
image when the button is pressed down - if this colour is
|
|
transparent, no overlay will be drawn
|
|
@param hitTestAlphaThreshold if set to zero, the mouse is considered to be over the button
|
|
whenever it's inside the button's bounding rectangle. If
|
|
set to values higher than 0, the mouse will only be
|
|
considered to be over the image when the value of the
|
|
image's alpha channel at that position is greater than
|
|
this level.
|
|
*/
|
|
void setImages (const bool resizeButtonNowToFitThisImage,
|
|
const bool rescaleImagesWhenButtonSizeChanges,
|
|
const bool preserveImageProportions,
|
|
Image* const normalImage,
|
|
const float imageOpacityWhenNormal,
|
|
const Colour& overlayColourWhenNormal,
|
|
Image* const overImage,
|
|
const float imageOpacityWhenOver,
|
|
const Colour& overlayColourWhenOver,
|
|
Image* const downImage,
|
|
const float imageOpacityWhenDown,
|
|
const Colour& overlayColourWhenDown,
|
|
const float hitTestAlphaThreshold = 0.0f);
|
|
|
|
/** Returns the currently set 'normal' image. */
|
|
Image* getNormalImage() const throw();
|
|
|
|
/** Returns the image that's drawn when the mouse is over the button.
|
|
|
|
If an 'over' image has been set, this will return it; otherwise it'll
|
|
just return the normal image.
|
|
*/
|
|
Image* getOverImage() const throw();
|
|
|
|
/** Returns the image that's drawn when the button is held down.
|
|
|
|
If a 'down' image has been set, this will return it; otherwise it'll
|
|
return the 'over' image or normal image, depending on what's available.
|
|
*/
|
|
Image* getDownImage() const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
bool hitTest (int x, int y);
|
|
/** @internal */
|
|
void paintButton (Graphics& g,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
private:
|
|
|
|
bool scaleImageToFit, preserveProportions;
|
|
unsigned char alphaThreshold;
|
|
int imageX, imageY, imageW, imageH;
|
|
Image* normalImage;
|
|
Image* overImage;
|
|
Image* downImage;
|
|
float normalOpacity, overOpacity, downOpacity;
|
|
Colour normalOverlay, overOverlay, downOverlay;
|
|
|
|
Image* getCurrentImage() const;
|
|
void deleteImages();
|
|
|
|
ImageButton (const ImageButton&);
|
|
const ImageButton& operator= (const ImageButton&);
|
|
};
|
|
|
|
#endif // __JUCE_IMAGEBUTTON_JUCEHEADER__
|
|
/********* End of inlined file: juce_ImageButton.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_SHAPEBUTTON_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ShapeButton.h *********/
|
|
#ifndef __JUCE_SHAPEBUTTON_JUCEHEADER__
|
|
#define __JUCE_SHAPEBUTTON_JUCEHEADER__
|
|
|
|
/**
|
|
A button that contains a filled shape.
|
|
|
|
@see Button, ImageButton, TextButton, ArrowButton
|
|
*/
|
|
class JUCE_API ShapeButton : public Button
|
|
{
|
|
public:
|
|
|
|
/** Creates a ShapeButton.
|
|
|
|
@param name a name to give the component - see Component::setName()
|
|
@param normalColour the colour to fill the shape with when the mouse isn't over
|
|
@param overColour the colour to use when the mouse is over the shape
|
|
@param downColour the colour to use when the button is in the pressed-down state
|
|
*/
|
|
ShapeButton (const String& name,
|
|
const Colour& normalColour,
|
|
const Colour& overColour,
|
|
const Colour& downColour);
|
|
|
|
/** Destructor. */
|
|
~ShapeButton();
|
|
|
|
/** Sets the shape to use.
|
|
|
|
@param newShape the shape to use
|
|
@param resizeNowToFitThisShape if true, the button will be resized to fit the shape's bounds
|
|
@param maintainShapeProportions if true, the shape's proportions will be kept fixed when
|
|
the button is resized
|
|
@param hasDropShadow if true, the button will be given a drop-shadow effect
|
|
*/
|
|
void setShape (const Path& newShape,
|
|
const bool resizeNowToFitThisShape,
|
|
const bool maintainShapeProportions,
|
|
const bool hasDropShadow);
|
|
|
|
/** Set the colours to use for drawing the shape.
|
|
|
|
@param normalColour the colour to fill the shape with when the mouse isn't over
|
|
@param overColour the colour to use when the mouse is over the shape
|
|
@param downColour the colour to use when the button is in the pressed-down state
|
|
*/
|
|
void setColours (const Colour& normalColour,
|
|
const Colour& overColour,
|
|
const Colour& downColour);
|
|
|
|
/** Sets up an outline to draw around the shape.
|
|
|
|
@param outlineColour the colour to use
|
|
@param outlineStrokeWidth the thickness of line to draw
|
|
*/
|
|
void setOutline (const Colour& outlineColour,
|
|
const float outlineStrokeWidth);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void paintButton (Graphics& g,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
private:
|
|
Colour normalColour, overColour, downColour, outlineColour;
|
|
DropShadowEffect shadow;
|
|
Path shape;
|
|
bool maintainShapeProportions;
|
|
float outlineWidth;
|
|
|
|
ShapeButton (const ShapeButton&);
|
|
const ShapeButton& operator= (const ShapeButton&);
|
|
};
|
|
|
|
#endif // __JUCE_SHAPEBUTTON_JUCEHEADER__
|
|
/********* End of inlined file: juce_ShapeButton.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TEXTBUTTON_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_TOGGLEBUTTON_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ToggleButton.h *********/
|
|
#ifndef __JUCE_TOGGLEBUTTON_JUCEHEADER__
|
|
#define __JUCE_TOGGLEBUTTON_JUCEHEADER__
|
|
|
|
/**
|
|
A button that can be toggled on/off.
|
|
|
|
All buttons can be toggle buttons, but this lets you create one of the
|
|
standard ones which has a tick-box and a text label next to it.
|
|
|
|
@see Button, DrawableButton, TextButton
|
|
*/
|
|
class JUCE_API ToggleButton : public Button
|
|
{
|
|
public:
|
|
|
|
/** Creates a ToggleButton.
|
|
|
|
@param buttonText the text to put in the button (the component's name is also
|
|
initially set to this string, but these can be changed later
|
|
using the setName() and setButtonText() methods)
|
|
*/
|
|
ToggleButton (const String& buttonText);
|
|
|
|
/** Destructor. */
|
|
~ToggleButton();
|
|
|
|
/** Resizes the button to fit neatly around its current text.
|
|
|
|
The button's height won't be affected, only its width.
|
|
*/
|
|
void changeWidthToFitText();
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the button.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
textColourId = 0x1006501 /**< The colour to use for the button's text. */
|
|
};
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void paintButton (Graphics& g,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
/** @internal */
|
|
void colourChanged();
|
|
|
|
private:
|
|
|
|
ToggleButton (const ToggleButton&);
|
|
const ToggleButton& operator= (const ToggleButton&);
|
|
};
|
|
|
|
#endif // __JUCE_TOGGLEBUTTON_JUCEHEADER__
|
|
/********* End of inlined file: juce_ToggleButton.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TOOLBARBUTTON_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ToolbarButton.h *********/
|
|
#ifndef __JUCE_TOOLBARBUTTON_JUCEHEADER__
|
|
#define __JUCE_TOOLBARBUTTON_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ToolbarItemComponent.h *********/
|
|
#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Toolbar.h *********/
|
|
#ifndef __JUCE_TOOLBAR_JUCEHEADER__
|
|
#define __JUCE_TOOLBAR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DragAndDropContainer.h *********/
|
|
#ifndef __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__
|
|
#define __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DragAndDropTarget.h *********/
|
|
#ifndef __JUCE_DRAGANDDROPTARGET_JUCEHEADER__
|
|
#define __JUCE_DRAGANDDROPTARGET_JUCEHEADER__
|
|
|
|
/**
|
|
Components derived from this class can have things dropped onto them by a DragAndDropContainer.
|
|
|
|
To create a component that can receive things drag-and-dropped by a DragAndDropContainer,
|
|
derive your component from this class, and make sure that it is somewhere inside a
|
|
DragAndDropContainer component.
|
|
|
|
Note: If all that you need to do is to respond to files being drag-and-dropped from
|
|
the operating system onto your component, you don't need any of these classes: instead
|
|
see the FileDragAndDropTarget class.
|
|
|
|
@see DragAndDropContainer, FileDragAndDropTarget
|
|
*/
|
|
class JUCE_API DragAndDropTarget
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~DragAndDropTarget() {}
|
|
|
|
/** Callback to check whether this target is interested in the type of object being
|
|
dragged.
|
|
|
|
@param sourceDescription the description string passed into DragAndDropContainer::startDragging()
|
|
@param sourceComponent the component that was passed into DragAndDropContainer::startDragging()
|
|
@returns true if this component wants to receive the other callbacks regarging this
|
|
type of object; if it returns false, no other callbacks will be made.
|
|
*/
|
|
virtual bool isInterestedInDragSource (const String& sourceDescription,
|
|
Component* sourceComponent) = 0;
|
|
|
|
/** Callback to indicate that something is being dragged over this component.
|
|
|
|
This gets called when the user moves the mouse into this component while dragging
|
|
something.
|
|
|
|
Use this callback as a trigger to make your component repaint itself to give the
|
|
user feedback about whether the item can be dropped here or not.
|
|
|
|
@param sourceDescription the description string passed into DragAndDropContainer::startDragging()
|
|
@param sourceComponent the component that was passed into DragAndDropContainer::startDragging()
|
|
@param x the mouse x position, relative to this component
|
|
@param y the mouse y position, relative to this component
|
|
@see itemDragExit
|
|
*/
|
|
virtual void itemDragEnter (const String& sourceDescription,
|
|
Component* sourceComponent,
|
|
int x,
|
|
int y);
|
|
|
|
/** Callback to indicate that the user is dragging something over this component.
|
|
|
|
This gets called when the user moves the mouse over this component while dragging
|
|
something. Normally overriding itemDragEnter() and itemDragExit() are enough, but
|
|
this lets you know what happens in-between.
|
|
|
|
@param sourceDescription the description string passed into DragAndDropContainer::startDragging()
|
|
@param sourceComponent the component that was passed into DragAndDropContainer::startDragging()
|
|
@param x the mouse x position, relative to this component
|
|
@param y the mouse y position, relative to this component
|
|
*/
|
|
virtual void itemDragMove (const String& sourceDescription,
|
|
Component* sourceComponent,
|
|
int x,
|
|
int y);
|
|
|
|
/** Callback to indicate that something has been dragged off the edge of this component.
|
|
|
|
This gets called when the user moves the mouse out of this component while dragging
|
|
something.
|
|
|
|
If you've used itemDragEnter() to repaint your component and give feedback, use this
|
|
as a signal to repaint it in its normal state.
|
|
|
|
@param sourceDescription the description string passed into DragAndDropContainer::startDragging()
|
|
@param sourceComponent the component that was passed into DragAndDropContainer::startDragging()
|
|
@see itemDragEnter
|
|
*/
|
|
virtual void itemDragExit (const String& sourceDescription,
|
|
Component* sourceComponent);
|
|
|
|
/** Callback to indicate that the user has dropped something onto this component.
|
|
|
|
When the user drops an item this get called, and you can use the description to
|
|
work out whether your object wants to deal with it or not.
|
|
|
|
Note that after this is called, the itemDragExit method may not be called, so you should
|
|
clean up in here if there's anything you need to do when the drag finishes.
|
|
|
|
@param sourceDescription the description string passed into DragAndDropContainer::startDragging()
|
|
@param sourceComponent the component that was passed into DragAndDropContainer::startDragging()
|
|
@param x the mouse x position, relative to this component
|
|
@param y the mouse y position, relative to this component
|
|
*/
|
|
virtual void itemDropped (const String& sourceDescription,
|
|
Component* sourceComponent,
|
|
int x,
|
|
int y) = 0;
|
|
|
|
/** Overriding this allows the target to tell the drag container whether to
|
|
draw the drag image while the cursor is over it.
|
|
|
|
By default it returns true, but if you return false, then the normal drag
|
|
image will not be shown when the cursor is over this target.
|
|
*/
|
|
virtual bool shouldDrawDragImageWhenOver();
|
|
};
|
|
|
|
#endif // __JUCE_DRAGANDDROPTARGET_JUCEHEADER__
|
|
/********* End of inlined file: juce_DragAndDropTarget.h *********/
|
|
|
|
/**
|
|
Enables drag-and-drop behaviour for a component and all its sub-components.
|
|
|
|
For a component to be able to make or receive drag-and-drop events, one of its parent
|
|
components must derive from this class. It's probably best for the top-level
|
|
component to implement it.
|
|
|
|
Then to start a drag operation, any sub-component can just call the startDragging()
|
|
method, and this object will take over, tracking the mouse and sending appropriate
|
|
callbacks to any child components derived from DragAndDropTarget which the mouse
|
|
moves over.
|
|
|
|
Note: If all that you need to do is to respond to files being drag-and-dropped from
|
|
the operating system onto your component, you don't need any of these classes: you can do this
|
|
simply by overriding Component::filesDropped().
|
|
|
|
@see DragAndDropTarget
|
|
*/
|
|
class JUCE_API DragAndDropContainer
|
|
{
|
|
public:
|
|
|
|
/** Creates a DragAndDropContainer.
|
|
|
|
The object that derives from this class must also be a Component.
|
|
*/
|
|
DragAndDropContainer();
|
|
|
|
/** Destructor. */
|
|
virtual ~DragAndDropContainer();
|
|
|
|
/** Begins a drag-and-drop operation.
|
|
|
|
This starts a drag-and-drop operation - call it when the user drags the
|
|
mouse in your drag-source component, and this object will track mouse
|
|
movements until the user lets go of the mouse button, and will send
|
|
appropriate messages to DragAndDropTarget objects that the mouse moves
|
|
over.
|
|
|
|
findParentDragContainerFor() is a handy method to call to find the
|
|
drag container to use for a component.
|
|
|
|
@param sourceDescription a string to use as the description of the thing being
|
|
dragged - this will be passed to the objects that might be
|
|
dropped-onto so they can decide if they want to handle it or
|
|
not
|
|
@param sourceComponent the component that is being dragged
|
|
@param dragImage the image to drag around underneath the mouse. If this is
|
|
zero, a snapshot of the sourceComponent will be used instead. An
|
|
image passed-in will be deleted by this object when no longer
|
|
needed.
|
|
@param allowDraggingToOtherJuceWindows if true, the dragged component will appear as a desktop
|
|
window, and can be dragged to DragAndDropTargets that are the
|
|
children of components other than this one.
|
|
*/
|
|
void startDragging (const String& sourceDescription,
|
|
Component* sourceComponent,
|
|
Image* dragImage = 0,
|
|
const bool allowDraggingToOtherJuceWindows = false);
|
|
|
|
/** Returns true if something is currently being dragged. */
|
|
bool isDragAndDropActive() const;
|
|
|
|
/** Returns the description of the thing that's currently being dragged.
|
|
|
|
If nothing's being dragged, this will return an empty string, otherwise it's the
|
|
string that was passed into startDragging().
|
|
|
|
@see startDragging
|
|
*/
|
|
const String getCurrentDragDescription() const;
|
|
|
|
/** Utility to find the DragAndDropContainer for a given Component.
|
|
|
|
This will search up this component's parent hierarchy looking for the first
|
|
parent component which is a DragAndDropContainer.
|
|
|
|
It's useful when a component wants to call startDragging but doesn't know
|
|
the DragAndDropContainer it should to use.
|
|
|
|
Obviously this may return 0 if it doesn't find a suitable component.
|
|
*/
|
|
static DragAndDropContainer* findParentDragContainerFor (Component* childComponent);
|
|
|
|
/** This performs a synchronous drag-and-drop of a set of files to some external
|
|
application.
|
|
|
|
You can call this function in response to a mouseDrag callback, and it will
|
|
block, running its own internal message loop and tracking the mouse, while it
|
|
uses a native operating system drag-and-drop operation to move or copy some
|
|
files to another application.
|
|
|
|
@param files a list of filenames to drag
|
|
@param canMoveFiles if true, the app that receives the files is allowed to move the files to a new location
|
|
(if this is appropriate). If false, the receiver is expected to make a copy of them.
|
|
@returns true if the files were successfully dropped somewhere, or false if it
|
|
was interrupted
|
|
@see performExternalDragDropOfText
|
|
*/
|
|
static bool performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles);
|
|
|
|
/** This performs a synchronous drag-and-drop of a block of text to some external
|
|
application.
|
|
|
|
You can call this function in response to a mouseDrag callback, and it will
|
|
block, running its own internal message loop and tracking the mouse, while it
|
|
uses a native operating system drag-and-drop operation to move or copy some
|
|
text to another application.
|
|
|
|
@param text the text to copy
|
|
@returns true if the text was successfully dropped somewhere, or false if it
|
|
was interrupted
|
|
@see performExternalDragDropOfFiles
|
|
*/
|
|
static bool performExternalDragDropOfText (const String& text);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** Override this if you want to be able to perform an external drag a set of files
|
|
when the user drags outside of this container component.
|
|
|
|
This method will be called when a drag operation moves outside the Juce-based window,
|
|
and if you want it to then perform a file drag-and-drop, add the filenames you want
|
|
to the array passed in, and return true.
|
|
|
|
@param dragSourceDescription the description passed into the startDrag() call when the drag began
|
|
@param dragSourceComponent the component passed into the startDrag() call when the drag began
|
|
@param files on return, the filenames you want to drag
|
|
@param canMoveFiles on return, true if it's ok for the receiver to move the files; false if
|
|
it must make a copy of them (see the performExternalDragDropOfFiles()
|
|
method)
|
|
@see performExternalDragDropOfFiles
|
|
*/
|
|
virtual bool shouldDropFilesWhenDraggedExternally (const String& dragSourceDescription,
|
|
Component* dragSourceComponent,
|
|
StringArray& files,
|
|
bool& canMoveFiles);
|
|
|
|
private:
|
|
friend class DragImageComponent;
|
|
Component* dragImageComponent;
|
|
String currentDragDesc;
|
|
};
|
|
|
|
#endif // __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__
|
|
/********* End of inlined file: juce_DragAndDropContainer.h *********/
|
|
|
|
/********* Start of inlined file: juce_ComponentAnimator.h *********/
|
|
#ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__
|
|
#define __JUCE_COMPONENTANIMATOR_JUCEHEADER__
|
|
|
|
/**
|
|
Animates a set of components, moving it to a new position.
|
|
|
|
To use this, create a ComponentAnimator, and use its animateComponent() method
|
|
to tell it to move components to destination positions. Any number of
|
|
components can be animated by one ComponentAnimator object (if you've got a
|
|
lot of components to move, it's much more efficient to share a single animator
|
|
than to have many animators running at once).
|
|
|
|
You'll need to make sure the animator object isn't deleted before it finishes
|
|
moving the components.
|
|
|
|
The class is a ChangeBroadcaster and sends a notification when any components
|
|
start or finish being animated.
|
|
*/
|
|
class JUCE_API ComponentAnimator : public ChangeBroadcaster,
|
|
private Timer
|
|
{
|
|
public:
|
|
|
|
/** Creates a ComponentAnimator. */
|
|
ComponentAnimator();
|
|
|
|
/** Destructor. */
|
|
~ComponentAnimator();
|
|
|
|
/** Starts a component moving from its current position to a specified position.
|
|
|
|
If the component is already in the middle of an animation, that will be abandoned,
|
|
and a new animation will begin, moving the component from its current location.
|
|
|
|
The start and end speed parameters let you apply some acceleration to the component's
|
|
movement.
|
|
|
|
@param component the component to move
|
|
@param finalPosition the destination position and size to move it to
|
|
@param millisecondsToSpendMoving how long, in milliseconds, it should take
|
|
to arrive at its destination
|
|
@param startSpeed a value to indicate the relative start speed of the
|
|
animation. If this is 0, the component will start
|
|
by accelerating from rest; higher values mean that it
|
|
will have an initial speed greater than zero. If the
|
|
value if greater than 1, it will decelerate towards the
|
|
middle of its journey. To move the component at a constant
|
|
rate for its entire animation, set both the start and
|
|
end speeds to 1.0
|
|
@param endSpeed a relative speed at which the component should be moving
|
|
when the animation finishes. If this is 0, the component
|
|
will decelerate to a standstill at its final position; higher
|
|
values mean the component will still be moving when it stops.
|
|
To move the component at a constant rate for its entire
|
|
animation, set both the start and end speeds to 1.0
|
|
*/
|
|
void animateComponent (Component* const component,
|
|
const Rectangle& finalPosition,
|
|
const int millisecondsToSpendMoving,
|
|
const double startSpeed = 1.0,
|
|
const double endSpeed = 1.0);
|
|
|
|
/** Stops a component if it's currently being animated.
|
|
|
|
If moveComponentToItsFinalPosition is true, then the component will
|
|
be immediately moved to its destination position and size. If false, it will be
|
|
left in whatever location it currently occupies.
|
|
*/
|
|
void cancelAnimation (Component* const component,
|
|
const bool moveComponentToItsFinalPosition);
|
|
|
|
/** Clears all of the active animations.
|
|
|
|
If moveComponentsToTheirFinalPositions is true, all the components will
|
|
be immediately set to their final positions. If false, they will be
|
|
left in whatever locations they currently occupy.
|
|
*/
|
|
void cancelAllAnimations (const bool moveComponentsToTheirFinalPositions);
|
|
|
|
/** Returns the destination position for a component.
|
|
|
|
If the component is being animated, this will return the target position that
|
|
was specified when animateComponent() was called.
|
|
|
|
If the specified component isn't currently being animated, this method will just
|
|
return its current position.
|
|
*/
|
|
const Rectangle getComponentDestination (Component* const component);
|
|
|
|
/** Returns true if the specified component is currently being animated.
|
|
*/
|
|
bool isAnimating (Component* component) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
VoidArray tasks;
|
|
uint32 lastTime;
|
|
|
|
void* findTaskFor (Component* const component) const;
|
|
void timerCallback();
|
|
};
|
|
|
|
#endif // __JUCE_COMPONENTANIMATOR_JUCEHEADER__
|
|
/********* End of inlined file: juce_ComponentAnimator.h *********/
|
|
|
|
class ToolbarItemComponent;
|
|
class ToolbarItemFactory;
|
|
class MissingItemsComponent;
|
|
|
|
/**
|
|
A toolbar component.
|
|
|
|
A toolbar contains a horizontal or vertical strip of ToolbarItemComponents,
|
|
and looks after their order and layout.
|
|
|
|
Items (icon buttons or other custom components) are added to a toolbar using a
|
|
ToolbarItemFactory - each type of item is given a unique ID number, and a
|
|
toolbar might contain more than one instance of a particular item type.
|
|
|
|
Toolbars can be interactively customised, allowing the user to drag the items
|
|
around, and to drag items onto or off the toolbar, using the ToolbarItemPalette
|
|
component as a source of new items.
|
|
|
|
@see ToolbarItemFactory, ToolbarItemComponent, ToolbarItemPalette
|
|
*/
|
|
class JUCE_API Toolbar : public Component,
|
|
public DragAndDropContainer,
|
|
public DragAndDropTarget,
|
|
private ButtonListener
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty toolbar component.
|
|
|
|
To add some icons or other components to your toolbar, you'll need to
|
|
create a ToolbarItemFactory class that can create a suitable set of
|
|
ToolbarItemComponents.
|
|
|
|
@see ToolbarItemFactory, ToolbarItemComponents
|
|
*/
|
|
Toolbar();
|
|
|
|
/** Destructor.
|
|
|
|
Any items on the bar will be deleted when the toolbar is deleted.
|
|
*/
|
|
~Toolbar();
|
|
|
|
/** Changes the bar's orientation.
|
|
@see isVertical
|
|
*/
|
|
void setVertical (const bool shouldBeVertical);
|
|
|
|
/** Returns true if the bar is set to be vertical, or false if it's horizontal.
|
|
|
|
You can change the bar's orientation with setVertical().
|
|
*/
|
|
bool isVertical() const throw() { return vertical; }
|
|
|
|
/** Returns the depth of the bar.
|
|
|
|
If the bar is horizontal, this will return its height; if it's vertical, it
|
|
will return its width.
|
|
|
|
@see getLength
|
|
*/
|
|
int getThickness() const throw();
|
|
|
|
/** Returns the length of the bar.
|
|
|
|
If the bar is horizontal, this will return its width; if it's vertical, it
|
|
will return its height.
|
|
|
|
@see getThickness
|
|
*/
|
|
int getLength() const throw();
|
|
|
|
/** Deletes all items from the bar.
|
|
*/
|
|
void clear();
|
|
|
|
/** Adds an item to the toolbar.
|
|
|
|
The factory's ToolbarItemFactory::createItem() will be called by this method
|
|
to create the component that will actually be added to the bar.
|
|
|
|
The new item will be inserted at the specified index (if the index is -1, it
|
|
will be added to the right-hand or bottom end of the bar).
|
|
|
|
Once added, the component will be automatically deleted by this object when it
|
|
is no longer needed.
|
|
|
|
@see ToolbarItemFactory
|
|
*/
|
|
void addItem (ToolbarItemFactory& factory,
|
|
const int itemId,
|
|
const int insertIndex = -1);
|
|
|
|
/** Deletes one of the items from the bar.
|
|
*/
|
|
void removeToolbarItem (const int itemIndex);
|
|
|
|
/** Returns the number of items currently on the toolbar.
|
|
|
|
@see getItemId, getItemComponent
|
|
*/
|
|
int getNumItems() const throw();
|
|
|
|
/** Returns the ID of the item with the given index.
|
|
|
|
If the index is less than zero or greater than the number of items,
|
|
this will return 0.
|
|
|
|
@see getNumItems
|
|
*/
|
|
int getItemId (const int itemIndex) const throw();
|
|
|
|
/** Returns the component being used for the item with the given index.
|
|
|
|
If the index is less than zero or greater than the number of items,
|
|
this will return 0.
|
|
|
|
@see getNumItems
|
|
*/
|
|
ToolbarItemComponent* getItemComponent (const int itemIndex) const throw();
|
|
|
|
/** Clears this toolbar and adds to it the default set of items that the specified
|
|
factory creates.
|
|
|
|
@see ToolbarItemFactory::getDefaultItemSet
|
|
*/
|
|
void addDefaultItems (ToolbarItemFactory& factoryToUse);
|
|
|
|
/** Options for the way items should be displayed.
|
|
@see setStyle, getStyle
|
|
*/
|
|
enum ToolbarItemStyle
|
|
{
|
|
iconsOnly, /**< Means that the toolbar should just contain icons. */
|
|
iconsWithText, /**< Means that the toolbar should have text labels under each icon. */
|
|
textOnly /**< Means that the toolbar only display text labels for each item. */
|
|
};
|
|
|
|
/** Returns the toolbar's current style.
|
|
@see ToolbarItemStyle, setStyle
|
|
*/
|
|
ToolbarItemStyle getStyle() const throw() { return toolbarStyle; }
|
|
|
|
/** Changes the toolbar's current style.
|
|
@see ToolbarItemStyle, getStyle, ToolbarItemComponent::setStyle
|
|
*/
|
|
void setStyle (const ToolbarItemStyle& newStyle);
|
|
|
|
/** Flags used by the showCustomisationDialog() method. */
|
|
enum CustomisationFlags
|
|
{
|
|
allowIconsOnlyChoice = 1, /**< If this flag is specified, the customisation dialog can
|
|
show the "icons only" option on its choice of toolbar styles. */
|
|
allowIconsWithTextChoice = 2, /**< If this flag is specified, the customisation dialog can
|
|
show the "icons with text" option on its choice of toolbar styles. */
|
|
allowTextOnlyChoice = 4, /**< If this flag is specified, the customisation dialog can
|
|
show the "text only" option on its choice of toolbar styles. */
|
|
showResetToDefaultsButton = 8, /**< If this flag is specified, the customisation dialog can
|
|
show a button to reset the toolbar to its default set of items. */
|
|
|
|
allCustomisationOptionsEnabled = (allowIconsOnlyChoice | allowIconsWithTextChoice | allowTextOnlyChoice | showResetToDefaultsButton)
|
|
};
|
|
|
|
/** Pops up a modal dialog box that allows this toolbar to be customised by the user.
|
|
|
|
The dialog contains a ToolbarItemPalette and various controls for editing other
|
|
aspects of the toolbar. This method will block and run the dialog box modally,
|
|
returning when the user closes it.
|
|
|
|
The factory is used to determine the set of items that will be shown on the
|
|
palette.
|
|
|
|
The optionFlags parameter is a bitwise-or of values from the CustomisationFlags
|
|
enum.
|
|
|
|
@see ToolbarItemPalette
|
|
*/
|
|
void showCustomisationDialog (ToolbarItemFactory& factory,
|
|
const int optionFlags = allCustomisationOptionsEnabled);
|
|
|
|
/** Turns on or off the toolbar's editing mode, in which its items can be
|
|
rearranged by the user.
|
|
|
|
(In most cases it's easier just to use showCustomisationDialog() instead of
|
|
trying to enable editing directly).
|
|
|
|
@see ToolbarItemPalette
|
|
*/
|
|
void setEditingActive (const bool editingEnabled);
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the toolbar.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1003200, /**< A colour to use to fill the toolbar's background. For
|
|
more control over this, override LookAndFeel::paintToolbarBackground(). */
|
|
separatorColourId = 0x1003210, /**< A colour to use to draw the separator lines. */
|
|
|
|
buttonMouseOverBackgroundColourId = 0x1003220, /**< A colour used to paint the background of buttons when the mouse is
|
|
over them. */
|
|
buttonMouseDownBackgroundColourId = 0x1003230, /**< A colour used to paint the background of buttons when the mouse is
|
|
held down on them. */
|
|
|
|
labelTextColourId = 0x1003240, /**< A colour to use for drawing the text under buttons
|
|
when the style is set to iconsWithText or textOnly. */
|
|
|
|
editingModeOutlineColourId = 0x1003250 /**< A colour to use for an outline around buttons when
|
|
the customisation dialog is active and the mouse moves over them. */
|
|
};
|
|
|
|
/** Returns a string that represents the toolbar's current set of items.
|
|
|
|
This lets you later restore the same item layout using restoreFromString().
|
|
|
|
@see restoreFromString
|
|
*/
|
|
const String toString() const;
|
|
|
|
/** Restores a set of items that was previously stored in a string by the toString()
|
|
method.
|
|
|
|
The factory object is used to create any item components that are needed.
|
|
|
|
@see toString
|
|
*/
|
|
bool restoreFromString (ToolbarItemFactory& factoryToUse,
|
|
const String& savedVersion);
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void buttonClicked (Button*);
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent&);
|
|
/** @internal */
|
|
bool isInterestedInDragSource (const String&, Component*);
|
|
/** @internal */
|
|
void itemDragMove (const String&, Component*, int, int);
|
|
/** @internal */
|
|
void itemDragExit (const String&, Component*);
|
|
/** @internal */
|
|
void itemDropped (const String&, Component*, int, int);
|
|
/** @internal */
|
|
void updateAllItemPositions (const bool animate);
|
|
/** @internal */
|
|
static ToolbarItemComponent* createItem (ToolbarItemFactory&, const int itemId);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Button* missingItemsButton;
|
|
bool vertical, isEditingActive;
|
|
ToolbarItemStyle toolbarStyle;
|
|
ComponentAnimator animator;
|
|
friend class MissingItemsComponent;
|
|
Array <ToolbarItemComponent*> items;
|
|
|
|
friend class ItemDragAndDropOverlayComponent;
|
|
static const tchar* const toolbarDragDescriptor;
|
|
|
|
void addItemInternal (ToolbarItemFactory& factory, const int itemId, const int insertIndex);
|
|
|
|
ToolbarItemComponent* getNextActiveComponent (int index, const int delta) const;
|
|
|
|
Toolbar (const Toolbar&);
|
|
const Toolbar& operator= (const Toolbar&);
|
|
};
|
|
|
|
#endif // __JUCE_TOOLBAR_JUCEHEADER__
|
|
/********* End of inlined file: juce_Toolbar.h *********/
|
|
|
|
class ItemDragAndDropOverlayComponent;
|
|
|
|
/**
|
|
A component that can be used as one of the items in a Toolbar.
|
|
|
|
Each of the items on a toolbar must be a component derived from ToolbarItemComponent,
|
|
and these objects are always created by a ToolbarItemFactory - see the ToolbarItemFactory
|
|
class for further info about creating them.
|
|
|
|
The ToolbarItemComponent class is actually a button, but can be used to hold non-button
|
|
components too. To do this, set the value of isBeingUsedAsAButton to false when
|
|
calling the constructor, and override contentAreaChanged(), in which you can position
|
|
any sub-components you need to add.
|
|
|
|
To add basic buttons without writing a special subclass, have a look at the
|
|
ToolbarButton class.
|
|
|
|
@see ToolbarButton, Toolbar, ToolbarItemFactory
|
|
*/
|
|
class JUCE_API ToolbarItemComponent : public Button
|
|
{
|
|
public:
|
|
|
|
/** Constructor.
|
|
|
|
@param itemId the ID of the type of toolbar item which this represents
|
|
@param labelText the text to display if the toolbar's style is set to
|
|
Toolbar::iconsWithText or Toolbar::textOnly
|
|
@param isBeingUsedAsAButton set this to false if you don't want the button
|
|
to draw itself with button over/down states when the mouse
|
|
moves over it or clicks
|
|
*/
|
|
ToolbarItemComponent (const int itemId,
|
|
const String& labelText,
|
|
const bool isBeingUsedAsAButton);
|
|
|
|
/** Destructor. */
|
|
~ToolbarItemComponent();
|
|
|
|
/** Returns the item type ID that this component represents.
|
|
This value is in the constructor.
|
|
*/
|
|
int getItemId() const throw() { return itemId; }
|
|
|
|
/** Returns the toolbar that contains this component, or 0 if it's not currently
|
|
inside one.
|
|
*/
|
|
Toolbar* getToolbar() const;
|
|
|
|
/** Returns true if this component is currently inside a toolbar which is vertical.
|
|
@see Toolbar::isVertical
|
|
*/
|
|
bool isToolbarVertical() const;
|
|
|
|
/** Returns the current style setting of this item.
|
|
|
|
Styles are listed in the Toolbar::ToolbarItemStyle enum.
|
|
@see setStyle, Toolbar::getStyle
|
|
*/
|
|
Toolbar::ToolbarItemStyle getStyle() const throw() { return toolbarStyle; }
|
|
|
|
/** Changes the current style setting of this item.
|
|
|
|
Styles are listed in the Toolbar::ToolbarItemStyle enum, and are automatically updated
|
|
by the toolbar that holds this item.
|
|
|
|
@see setStyle, Toolbar::setStyle
|
|
*/
|
|
virtual void setStyle (const Toolbar::ToolbarItemStyle& newStyle);
|
|
|
|
/** Returns the area of the component that should be used to display the button image or
|
|
other contents of the item.
|
|
|
|
This content area may change when the item's style changes, and may leave a space around the
|
|
edge of the component where the text label can be shown.
|
|
|
|
@see contentAreaChanged
|
|
*/
|
|
const Rectangle getContentArea() const throw() { return contentArea; }
|
|
|
|
/** This method must return the size criteria for this item, based on a given toolbar
|
|
size and orientation.
|
|
|
|
The preferredSize, minSize and maxSize values must all be set by your implementation
|
|
method. If the toolbar is horizontal, these will be the width of the item; for a vertical
|
|
toolbar, they refer to the item's height.
|
|
|
|
The preferredSize is the size that the component would like to be, and this must be
|
|
between the min and max sizes. For a fixed-size item, simply set all three variables to
|
|
the same value.
|
|
|
|
The toolbarThickness parameter tells you the depth of the toolbar - the same as calling
|
|
Toolbar::getThickness().
|
|
|
|
The isToolbarVertical parameter tells you whether the bar is oriented horizontally or
|
|
vertically.
|
|
*/
|
|
virtual bool getToolbarItemSizes (int toolbarThickness,
|
|
bool isToolbarVertical,
|
|
int& preferredSize,
|
|
int& minSize,
|
|
int& maxSize) = 0;
|
|
|
|
/** Your subclass should use this method to draw its content area.
|
|
|
|
The graphics object that is passed-in will have been clipped and had its origin
|
|
moved to fit the content area as specified get getContentArea(). The width and height
|
|
parameters are the width and height of the content area.
|
|
|
|
If the component you're writing isn't a button, you can just do nothing in this method.
|
|
*/
|
|
virtual void paintButtonArea (Graphics& g,
|
|
int width, int height,
|
|
bool isMouseOver, bool isMouseDown) = 0;
|
|
|
|
/** Callback to indicate that the content area of this item has changed.
|
|
|
|
This might be because the component was resized, or because the style changed and
|
|
the space needed for the text label is different.
|
|
|
|
See getContentArea() for a description of what the area is.
|
|
*/
|
|
virtual void contentAreaChanged (const Rectangle& newBounds) = 0;
|
|
|
|
/** Editing modes.
|
|
These are used by setEditingMode(), but will be rarely needed in user code.
|
|
*/
|
|
enum ToolbarEditingMode
|
|
{
|
|
normalMode = 0, /**< Means that the component is active, inside a toolbar. */
|
|
editableOnToolbar, /**< Means that the component is on a toolbar, but the toolbar is in
|
|
customisation mode, and the items can be dragged around. */
|
|
editableOnPalette /**< Means that the component is on an new-item palette, so it can be
|
|
dragged onto a toolbar to add it to that bar.*/
|
|
};
|
|
|
|
/** Changes the editing mode of this component.
|
|
|
|
This is used by the ToolbarItemPalette and related classes for making the items draggable,
|
|
and is unlikely to be of much use in end-user-code.
|
|
*/
|
|
void setEditingMode (const ToolbarEditingMode newMode);
|
|
|
|
/** Returns the current editing mode of this component.
|
|
|
|
This is used by the ToolbarItemPalette and related classes for making the items draggable,
|
|
and is unlikely to be of much use in end-user-code.
|
|
*/
|
|
ToolbarEditingMode getEditingMode() const throw() { return mode; }
|
|
|
|
/** @internal */
|
|
void paintButton (Graphics& g, bool isMouseOver, bool isMouseDown);
|
|
/** @internal */
|
|
void resized();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class Toolbar;
|
|
friend class ItemDragAndDropOverlayComponent;
|
|
const int itemId;
|
|
ToolbarEditingMode mode;
|
|
Toolbar::ToolbarItemStyle toolbarStyle;
|
|
Component* overlayComp;
|
|
int dragOffsetX, dragOffsetY;
|
|
bool isActive, isBeingDragged, isBeingUsedAsAButton;
|
|
Rectangle contentArea;
|
|
|
|
ToolbarItemComponent (const ToolbarItemComponent&);
|
|
const ToolbarItemComponent& operator= (const ToolbarItemComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_ToolbarItemComponent.h *********/
|
|
|
|
/**
|
|
A type of button designed to go on a toolbar.
|
|
|
|
This simple button can have two Drawable objects specified - one for normal
|
|
use and another one (optionally) for the button's "on" state if it's a
|
|
toggle button.
|
|
|
|
@see Toolbar, ToolbarItemFactory, ToolbarItemComponent, Drawable, Button
|
|
*/
|
|
class JUCE_API ToolbarButton : public ToolbarItemComponent
|
|
{
|
|
public:
|
|
|
|
/** Creates a ToolbarButton.
|
|
|
|
@param itemId the ID for this toolbar item type. This is passed through to the
|
|
ToolbarItemComponent constructor
|
|
@param labelText the text to display on the button (if the toolbar is using a style
|
|
that shows text labels). This is passed through to the
|
|
ToolbarItemComponent constructor
|
|
@param normalImage a drawable object that the button should use as its icon. The object
|
|
that is passed-in here will be kept by this object and will be
|
|
deleted when no longer needed or when this button is deleted.
|
|
@param toggledOnImage a drawable object that the button can use as its icon if the button
|
|
is in a toggled-on state (see the Button::getToggleState() method). If
|
|
0 is passed-in here, then the normal image will be used instead, regardless
|
|
of the toggle state. The object that is passed-in here will be kept by
|
|
this object and will be deleted when no longer needed or when this button
|
|
is deleted.
|
|
*/
|
|
ToolbarButton (const int itemId,
|
|
const String& labelText,
|
|
Drawable* const normalImage,
|
|
Drawable* const toggledOnImage);
|
|
|
|
/** Destructor. */
|
|
~ToolbarButton();
|
|
|
|
/** @internal */
|
|
bool getToolbarItemSizes (int toolbarDepth, bool isToolbarVertical, int& preferredSize,
|
|
int& minSize, int& maxSize);
|
|
/** @internal */
|
|
void paintButtonArea (Graphics& g, int width, int height, bool isMouseOver, bool isMouseDown);
|
|
/** @internal */
|
|
void contentAreaChanged (const Rectangle& newBounds);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Drawable* const normalImage;
|
|
Drawable* const toggledOnImage;
|
|
|
|
ToolbarButton (const ToolbarButton&);
|
|
const ToolbarButton& operator= (const ToolbarButton&);
|
|
};
|
|
|
|
#endif // __JUCE_TOOLBARBUTTON_JUCEHEADER__
|
|
/********* End of inlined file: juce_ToolbarButton.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DROPSHADOWEFFECT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_GLOWEFFECT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_GlowEffect.h *********/
|
|
#ifndef __JUCE_GLOWEFFECT_JUCEHEADER__
|
|
#define __JUCE_GLOWEFFECT_JUCEHEADER__
|
|
|
|
/**
|
|
A component effect that adds a coloured blur around the component's contents.
|
|
|
|
(This will only work on non-opaque components).
|
|
|
|
@see Component::setComponentEffect, DropShadowEffect
|
|
*/
|
|
class JUCE_API GlowEffect : public ImageEffectFilter
|
|
{
|
|
public:
|
|
|
|
/** Creates a default 'glow' effect.
|
|
|
|
To customise its appearance, use the setGlowProperties() method.
|
|
*/
|
|
GlowEffect();
|
|
|
|
/** Destructor. */
|
|
~GlowEffect();
|
|
|
|
/** Sets the glow's radius and colour.
|
|
|
|
The radius is how large the blur should be, and the colour is
|
|
used to render it (for a less intense glow, lower the colour's
|
|
opacity).
|
|
*/
|
|
void setGlowProperties (const float newRadius,
|
|
const Colour& newColour);
|
|
|
|
/** @internal */
|
|
void applyEffect (Image& sourceImage, Graphics& destContext);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
float radius;
|
|
Colour colour;
|
|
};
|
|
|
|
#endif // __JUCE_GLOWEFFECT_JUCEHEADER__
|
|
/********* End of inlined file: juce_GlowEffect.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ReduceOpacityEffect.h *********/
|
|
#ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__
|
|
#define __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__
|
|
|
|
/**
|
|
An effect filter that reduces the image's opacity.
|
|
|
|
This can be used to make a component (and its child components) more
|
|
transparent.
|
|
|
|
@see Component::setComponentEffect
|
|
*/
|
|
class JUCE_API ReduceOpacityEffect : public ImageEffectFilter
|
|
{
|
|
public:
|
|
|
|
/** Creates the effect object.
|
|
|
|
The opacity of the component to which the effect is applied will be
|
|
scaled by the given factor (in the range 0 to 1.0f).
|
|
*/
|
|
ReduceOpacityEffect (const float opacity = 1.0f);
|
|
|
|
/** Destructor. */
|
|
~ReduceOpacityEffect();
|
|
|
|
/** Sets how much to scale the component's opacity.
|
|
|
|
@param newOpacity should be between 0 and 1.0f
|
|
*/
|
|
void setOpacity (const float newOpacity);
|
|
|
|
/** @internal */
|
|
void applyEffect (Image& sourceImage, Graphics& destContext);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
float opacity;
|
|
};
|
|
|
|
#endif // __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__
|
|
/********* End of inlined file: juce_ReduceOpacityEffect.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_KEYLISTENER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_KeyMappingEditorComponent.h *********/
|
|
#ifndef __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_KeyPressMappingSet.h *********/
|
|
#ifndef __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__
|
|
#define __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__
|
|
|
|
/**
|
|
Manages and edits a list of keypresses, which it uses to invoke the appropriate
|
|
command in a ApplicationCommandManager.
|
|
|
|
Normally, you won't actually create a KeyPressMappingSet directly, because
|
|
each ApplicationCommandManager contains its own KeyPressMappingSet, so typically
|
|
you'd create yourself an ApplicationCommandManager, and call its
|
|
ApplicationCommandManager::getKeyMappings() method to get a pointer to its
|
|
KeyPressMappingSet.
|
|
|
|
For one of these to actually use keypresses, you'll need to add it as a KeyListener
|
|
to the top-level component for which you want to handle keystrokes. So for example:
|
|
|
|
@code
|
|
class MyMainWindow : public Component
|
|
{
|
|
ApplicationCommandManager* myCommandManager;
|
|
|
|
public:
|
|
MyMainWindow()
|
|
{
|
|
myCommandManager = new ApplicationCommandManager();
|
|
|
|
// first, make sure the command manager has registered all the commands that its
|
|
// targets can perform..
|
|
myCommandManager->registerAllCommandsForTarget (myCommandTarget1);
|
|
myCommandManager->registerAllCommandsForTarget (myCommandTarget2);
|
|
|
|
// this will use the command manager to initialise the KeyPressMappingSet with
|
|
// the default keypresses that were specified when the targets added their commands
|
|
// to the manager.
|
|
myCommandManager->getKeyMappings()->resetToDefaultMappings();
|
|
|
|
// having set up the default key-mappings, you might now want to load the last set
|
|
// of mappings that the user configured.
|
|
myCommandManager->getKeyMappings()->restoreFromXml (lastSavedKeyMappingsXML);
|
|
|
|
// Now tell our top-level window to send any keypresses that arrive to the
|
|
// KeyPressMappingSet, which will use them to invoke the appropriate commands.
|
|
addKeyListener (myCommandManager->getKeyMappings());
|
|
}
|
|
|
|
...
|
|
}
|
|
@endcode
|
|
|
|
KeyPressMappingSet derives from ChangeBroadcaster so that interested parties can
|
|
register to be told when a command or mapping is added, removed, etc.
|
|
|
|
There's also a UI component called KeyMappingEditorComponent that can be used
|
|
to easily edit the key mappings.
|
|
|
|
@see Component::addKeyListener(), KeyMappingEditorComponent, ApplicationCommandManager
|
|
*/
|
|
class JUCE_API KeyPressMappingSet : public KeyListener,
|
|
public ChangeBroadcaster,
|
|
public FocusChangeListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a KeyPressMappingSet for a given command manager.
|
|
|
|
Normally, you won't actually create a KeyPressMappingSet directly, because
|
|
each ApplicationCommandManager contains its own KeyPressMappingSet, so the
|
|
best thing to do is to create your ApplicationCommandManager, and use the
|
|
ApplicationCommandManager::getKeyMappings() method to access its mappings.
|
|
|
|
When a suitable keypress happens, the manager's invoke() method will be
|
|
used to invoke the appropriate command.
|
|
|
|
@see ApplicationCommandManager
|
|
*/
|
|
KeyPressMappingSet (ApplicationCommandManager* const commandManager) throw();
|
|
|
|
/** Creates an copy of a KeyPressMappingSet. */
|
|
KeyPressMappingSet (const KeyPressMappingSet& other) throw();
|
|
|
|
/** Destructor. */
|
|
~KeyPressMappingSet();
|
|
|
|
ApplicationCommandManager* getCommandManager() const throw() { return commandManager; }
|
|
|
|
/** Returns a list of keypresses that are assigned to a particular command.
|
|
|
|
@param commandID the command's ID
|
|
*/
|
|
const Array <KeyPress> getKeyPressesAssignedToCommand (const CommandID commandID) const throw();
|
|
|
|
/** Assigns a keypress to a command.
|
|
|
|
If the keypress is already assigned to a different command, it will first be
|
|
removed from that command, to avoid it triggering multiple functions.
|
|
|
|
@param commandID the ID of the command that you want to add a keypress to. If
|
|
this is 0, the keypress will be removed from anything that it
|
|
was previously assigned to, but not re-assigned
|
|
@param newKeyPress the new key-press
|
|
@param insertIndex if this is less than zero, the key will be appended to the
|
|
end of the list of keypresses; otherwise the new keypress will
|
|
be inserted into the existing list at this index
|
|
*/
|
|
void addKeyPress (const CommandID commandID,
|
|
const KeyPress& newKeyPress,
|
|
int insertIndex = -1) throw();
|
|
|
|
/** Reset all mappings to the defaults, as dictated by the ApplicationCommandManager.
|
|
|
|
@see resetToDefaultMapping
|
|
*/
|
|
void resetToDefaultMappings() throw();
|
|
|
|
/** Resets all key-mappings to the defaults for a particular command.
|
|
|
|
@see resetToDefaultMappings
|
|
*/
|
|
void resetToDefaultMapping (const CommandID commandID) throw();
|
|
|
|
/** Removes all keypresses that are assigned to any commands. */
|
|
void clearAllKeyPresses() throw();
|
|
|
|
/** Removes all keypresses that are assigned to a particular command. */
|
|
void clearAllKeyPresses (const CommandID commandID) throw();
|
|
|
|
/** Removes one of the keypresses that are assigned to a command.
|
|
|
|
See the getKeyPressesAssignedToCommand() for the list of keypresses to
|
|
which the keyPressIndex refers.
|
|
*/
|
|
void removeKeyPress (const CommandID commandID,
|
|
const int keyPressIndex) throw();
|
|
|
|
/** Removes a keypress from any command that it may be assigned to.
|
|
*/
|
|
void removeKeyPress (const KeyPress& keypress) throw();
|
|
|
|
/** Returns true if the given command is linked to this key. */
|
|
bool containsMapping (const CommandID commandID,
|
|
const KeyPress& keyPress) const throw();
|
|
|
|
/** Looks for a command that corresponds to a keypress.
|
|
|
|
@returns the UID of the command or 0 if none was found
|
|
*/
|
|
CommandID findCommandForKeyPress (const KeyPress& keyPress) const throw();
|
|
|
|
/** Tries to recreate the mappings from a previously stored state.
|
|
|
|
The XML passed in must have been created by the createXml() method.
|
|
|
|
If the stored state makes any reference to commands that aren't
|
|
currently available, these will be ignored.
|
|
|
|
If the set of mappings being loaded was a set of differences (using createXml (true)),
|
|
then this will call resetToDefaultMappings() and then merge the saved mappings
|
|
on top. If the saved set was created with createXml (false), then this method
|
|
will first clear all existing mappings and load the saved ones as a complete set.
|
|
|
|
@returns true if it manages to load the XML correctly
|
|
@see createXml
|
|
*/
|
|
bool restoreFromXml (const XmlElement& xmlVersion);
|
|
|
|
/** Creates an XML representation of the current mappings.
|
|
|
|
This will produce a lump of XML that can be later reloaded using
|
|
restoreFromXml() to recreate the current mapping state.
|
|
|
|
The object that is returned must be deleted by the caller.
|
|
|
|
@param saveDifferencesFromDefaultSet if this is false, then all keypresses
|
|
will be saved into the XML. If it's true, then the XML will
|
|
only store the differences between the current mappings and
|
|
the default mappings you'd get from calling resetToDefaultMappings().
|
|
The advantage of saving a set of differences from the default is that
|
|
if you change the default mappings (in a new version of your app, for
|
|
example), then these will be merged into a user's saved preferences.
|
|
|
|
@see restoreFromXml
|
|
*/
|
|
XmlElement* createXml (const bool saveDifferencesFromDefaultSet) const;
|
|
|
|
/** @internal */
|
|
bool keyPressed (const KeyPress& key, Component* originatingComponent);
|
|
/** @internal */
|
|
bool keyStateChanged (const bool isKeyDown, Component* originatingComponent);
|
|
/** @internal */
|
|
void globalFocusChanged (Component* focusedComponent);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
ApplicationCommandManager* commandManager;
|
|
|
|
struct CommandMapping
|
|
{
|
|
CommandID commandID;
|
|
Array <KeyPress> keypresses;
|
|
bool wantsKeyUpDownCallbacks;
|
|
};
|
|
|
|
OwnedArray <CommandMapping> mappings;
|
|
|
|
struct KeyPressTime
|
|
{
|
|
KeyPress key;
|
|
uint32 timeWhenPressed;
|
|
};
|
|
|
|
OwnedArray <KeyPressTime> keysDown;
|
|
|
|
void handleMessage (const Message& message);
|
|
|
|
void invokeCommand (const CommandID commandID,
|
|
const KeyPress& keyPress,
|
|
const bool isKeyDown,
|
|
const int millisecsSinceKeyPressed,
|
|
Component* const originatingComponent) const;
|
|
|
|
const KeyPressMappingSet& operator= (const KeyPressMappingSet&);
|
|
};
|
|
|
|
#endif // __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__
|
|
/********* End of inlined file: juce_KeyPressMappingSet.h *********/
|
|
|
|
/********* Start of inlined file: juce_TreeView.h *********/
|
|
#ifndef __JUCE_TREEVIEW_JUCEHEADER__
|
|
#define __JUCE_TREEVIEW_JUCEHEADER__
|
|
|
|
class TreeView;
|
|
|
|
/**
|
|
An item in a treeview.
|
|
|
|
A TreeViewItem can either be a leaf-node in the tree, or it can contain its
|
|
own sub-items.
|
|
|
|
To implement an item that contains sub-items, override the itemOpennessChanged()
|
|
method so that when it is opened, it adds the new sub-items to itself using the
|
|
addSubItem method. Depending on the nature of the item it might choose to only
|
|
do this the first time it's opened, or it might want to refresh itself each time.
|
|
It also has the option of deleting its sub-items when it is closed, or leaving them
|
|
in place.
|
|
*/
|
|
class JUCE_API TreeViewItem
|
|
{
|
|
public:
|
|
|
|
/** Constructor. */
|
|
TreeViewItem();
|
|
|
|
/** Destructor. */
|
|
virtual ~TreeViewItem();
|
|
|
|
/** Returns the number of sub-items that have been added to this item.
|
|
|
|
Note that this doesn't mean much if the node isn't open.
|
|
|
|
@see getSubItem, mightContainSubItems, addSubItem
|
|
*/
|
|
int getNumSubItems() const throw();
|
|
|
|
/** Returns one of the item's sub-items.
|
|
|
|
Remember that the object returned might get deleted at any time when its parent
|
|
item is closed or refreshed, depending on the nature of the items you're using.
|
|
|
|
@see getNumSubItems
|
|
*/
|
|
TreeViewItem* getSubItem (const int index) const throw();
|
|
|
|
/** Removes any sub-items. */
|
|
void clearSubItems();
|
|
|
|
/** Adds a sub-item.
|
|
|
|
@param newItem the object to add to the item's sub-item list. Once added, these can be
|
|
found using getSubItem(). When the items are later removed with
|
|
removeSubItem() (or when this item is deleted), they will be deleted.
|
|
@param insertPosition the index which the new item should have when it's added. If this
|
|
value is less than 0, the item will be added to the end of the list.
|
|
*/
|
|
void addSubItem (TreeViewItem* const newItem,
|
|
const int insertPosition = -1);
|
|
|
|
/** Removes one of the sub-items.
|
|
|
|
@param index the item to remove
|
|
@param deleteItem if true, the item that is removed will also be deleted.
|
|
*/
|
|
void removeSubItem (const int index,
|
|
const bool deleteItem = true);
|
|
|
|
/** Returns the TreeView to which this item belongs. */
|
|
TreeView* getOwnerView() const throw() { return ownerView; }
|
|
|
|
/** Returns the item within which this item is contained. */
|
|
TreeViewItem* getParentItem() const throw() { return parentItem; }
|
|
|
|
/** True if this item is currently open in the treeview. */
|
|
bool isOpen() const throw();
|
|
|
|
/** Opens or closes the item.
|
|
|
|
When opened or closed, the item's itemOpennessChanged() method will be called,
|
|
and a subclass should use this callback to create and add any sub-items that
|
|
it needs to.
|
|
|
|
@see itemOpennessChanged, mightContainSubItems
|
|
*/
|
|
void setOpen (const bool shouldBeOpen);
|
|
|
|
/** True if this item is currently selected.
|
|
|
|
Use this when painting the node, to decide whether to draw it as selected or not.
|
|
*/
|
|
bool isSelected() const throw();
|
|
|
|
/** Selects or deselects the item.
|
|
|
|
This will cause a callback to itemSelectionChanged()
|
|
*/
|
|
void setSelected (const bool shouldBeSelected,
|
|
const bool deselectOtherItemsFirst);
|
|
|
|
/** Returns the rectangle that this item occupies.
|
|
|
|
If relativeToTreeViewTopLeft is true, the co-ordinates are relative to the
|
|
top-left of the TreeView comp, so this will depend on the scroll-position of
|
|
the tree. If false, it is relative to the top-left of the topmost item in the
|
|
tree (so this would be unaffected by scrolling the view).
|
|
*/
|
|
const Rectangle getItemPosition (const bool relativeToTreeViewTopLeft) const throw();
|
|
|
|
/** Sends a signal to the treeview to make it refresh itself.
|
|
|
|
Call this if your items have changed and you want the tree to update to reflect
|
|
this.
|
|
*/
|
|
void treeHasChanged() const throw();
|
|
|
|
/** Sends a repaint message to redraw just this item.
|
|
|
|
Note that you should only call this if you want to repaint a superficial change. If
|
|
you're altering the tree's nodes, you should instead call treeHasChanged().
|
|
*/
|
|
void repaintItem() const;
|
|
|
|
/** Returns the row number of this item in the tree.
|
|
|
|
The row number of an item will change according to which items are open.
|
|
|
|
@see TreeView::getNumRowsInTree(), TreeView::getItemOnRow()
|
|
*/
|
|
int getRowNumberInTree() const throw();
|
|
|
|
/** Returns true if all the item's parent nodes are open.
|
|
|
|
This is useful to check whether the item might actually be visible or not.
|
|
*/
|
|
bool areAllParentsOpen() const throw();
|
|
|
|
/** Changes whether lines are drawn to connect any sub-items to this item.
|
|
|
|
By default, line-drawing is turned on.
|
|
*/
|
|
void setLinesDrawnForSubItems (const bool shouldDrawLines) throw();
|
|
|
|
/** Tells the tree whether this item can potentially be opened.
|
|
|
|
If your item could contain sub-items, this should return true; if it returns
|
|
false then the tree will not try to open the item. This determines whether or
|
|
not the item will be drawn with a 'plus' button next to it.
|
|
*/
|
|
virtual bool mightContainSubItems() = 0;
|
|
|
|
/** Returns a string to uniquely identify this item.
|
|
|
|
If you're planning on using the TreeView::getOpennessState() method, then
|
|
these strings will be used to identify which nodes are open. The string
|
|
should be unique amongst the item's sibling items, but it's ok for there
|
|
to be duplicates at other levels of the tree.
|
|
|
|
If you're not going to store the state, then it's ok not to bother implementing
|
|
this method.
|
|
*/
|
|
virtual const String getUniqueName() const;
|
|
|
|
/** Called when an item is opened or closed.
|
|
|
|
When setOpen() is called and the item has specified that it might
|
|
have sub-items with the mightContainSubItems() method, this method
|
|
is called to let the item create or manage its sub-items.
|
|
|
|
So when this is called with isNowOpen set to true (i.e. when the item is being
|
|
opened), a subclass might choose to use clearSubItems() and addSubItem() to
|
|
refresh its sub-item list.
|
|
|
|
When this is called with isNowOpen set to false, the subclass might want
|
|
to use clearSubItems() to save on space, or it might choose to leave them,
|
|
depending on the nature of the tree.
|
|
|
|
You could also use this callback as a trigger to start a background process
|
|
which asynchronously creates sub-items and adds them, if that's more
|
|
appropriate for the task in hand.
|
|
|
|
@see mightContainSubItems
|
|
*/
|
|
virtual void itemOpennessChanged (bool isNowOpen);
|
|
|
|
/** Must return the width required by this item.
|
|
|
|
If your item needs to have a particular width in pixels, return that value; if
|
|
you'd rather have it just fill whatever space is available in the treeview,
|
|
return -1.
|
|
|
|
If all your items return -1, no horizontal scrollbar will be shown, but if any
|
|
items have fixed widths and extend beyond the width of the treeview, a
|
|
scrollbar will appear.
|
|
|
|
Each item can be a different width, but if they change width, you should call
|
|
treeHasChanged() to update the tree.
|
|
*/
|
|
virtual int getItemWidth() const { return -1; }
|
|
|
|
/** Must return the height required by this item.
|
|
|
|
This is the height in pixels that the item will take up. Items in the tree
|
|
can be different heights, but if they change height, you should call
|
|
treeHasChanged() to update the tree.
|
|
*/
|
|
virtual int getItemHeight() const { return 20; }
|
|
|
|
/** You can override this method to return false if you don't want to allow the
|
|
user to select this item.
|
|
*/
|
|
virtual bool canBeSelected() const { return true; }
|
|
|
|
/** Creates a component that will be used to represent this item.
|
|
|
|
You don't have to implement this method - if it returns 0 then no component
|
|
will be used for the item, and you can just draw it using the paintItem()
|
|
callback. But if you do return a component, it will be positioned in the
|
|
treeview so that it can be used to represent this item.
|
|
|
|
The component returned will be managed by the treeview, so always return
|
|
a new component, and don't keep a reference to it, as the treeview will
|
|
delete it later when it goes off the screen or is no longer needed. Also
|
|
bear in mind that if the component keeps a reference to the item that
|
|
created it, that item could be deleted before the component. Its position
|
|
and size will be completely managed by the tree, so don't attempt to move it
|
|
around.
|
|
|
|
Something you may want to do with your component is to give it a pointer to
|
|
the TreeView that created it. This is perfectly safe, and there's no danger
|
|
of it becoming a dangling pointer because the TreeView will always delete
|
|
the component before it is itself deleted.
|
|
|
|
As long as you stick to these rules you can return whatever kind of
|
|
component you like. It's most useful if you're doing things like drag-and-drop
|
|
of items, or want to use a Label component to edit item names, etc.
|
|
*/
|
|
virtual Component* createItemComponent() { return 0; }
|
|
|
|
/** Draws the item's contents.
|
|
|
|
You can choose to either implement this method and draw each item, or you
|
|
can use createItemComponent() to create a component that will represent the
|
|
item.
|
|
|
|
If all you need in your tree is to be able to draw the items and detect when
|
|
the user selects or double-clicks one of them, it's probably enough to
|
|
use paintItem(), itemClicked() and itemDoubleClicked(). If you need more
|
|
complicated interactions, you may need to use createItemComponent() instead.
|
|
|
|
@param g the graphics context to draw into
|
|
@param width the width of the area available for drawing
|
|
@param height the height of the area available for drawing
|
|
*/
|
|
virtual void paintItem (Graphics& g, int width, int height);
|
|
|
|
/** Draws the item's open/close button.
|
|
|
|
If you don't implement this method, the default behaviour is to
|
|
call LookAndFeel::drawTreeviewPlusMinusBox(), but you can override
|
|
it for custom effects.
|
|
*/
|
|
virtual void paintOpenCloseButton (Graphics& g, int width, int height, bool isMouseOver);
|
|
|
|
/** Called when the user clicks on this item.
|
|
|
|
If you're using createItemComponent() to create a custom component for the
|
|
item, the mouse-clicks might not make it through to the treeview, but this
|
|
is how you find out about clicks when just drawing each item individually.
|
|
|
|
The associated mouse-event details are passed in, so you can find out about
|
|
which button, where it was, etc.
|
|
|
|
@see itemDoubleClicked
|
|
*/
|
|
virtual void itemClicked (const MouseEvent& e);
|
|
|
|
/** Called when the user double-clicks on this item.
|
|
|
|
If you're using createItemComponent() to create a custom component for the
|
|
item, the mouse-clicks might not make it through to the treeview, but this
|
|
is how you find out about clicks when just drawing each item individually.
|
|
|
|
The associated mouse-event details are passed in, so you can find out about
|
|
which button, where it was, etc.
|
|
|
|
If not overridden, the base class method here will open or close the item as
|
|
if the 'plus' button had been clicked.
|
|
|
|
@see itemClicked
|
|
*/
|
|
virtual void itemDoubleClicked (const MouseEvent& e);
|
|
|
|
/** Called when the item is selected or deselected.
|
|
|
|
Use this if you want to do something special when the item's selectedness
|
|
changes. By default it'll get repainted when this happens.
|
|
*/
|
|
virtual void itemSelectionChanged (bool isNowSelected);
|
|
|
|
/** The item can return a tool tip string here if it wants to.
|
|
@see TooltipClient
|
|
*/
|
|
virtual const String getTooltip();
|
|
|
|
/** To allow items from your treeview to be dragged-and-dropped, implement this method.
|
|
|
|
If this returns a non-empty name then when the user drags an item, the treeview will
|
|
try to find a DragAndDropContainer in its parent hierarchy, and will use it to trigger
|
|
a drag-and-drop operation, using this string as the source description, with the treeview
|
|
itself as the source component.
|
|
|
|
If you need more complex drag-and-drop behaviour, you can use custom components for
|
|
the items, and use those to trigger the drag.
|
|
|
|
@see DragAndDropContainer::startDragging
|
|
*/
|
|
virtual const String getDragSourceDescription();
|
|
|
|
/** Sets a flag to indicate that the item wants to be allowed
|
|
to draw all the way across to the left edge of the treeview.
|
|
|
|
By default this is false, which means that when the paintItem()
|
|
method is called, its graphics context is clipped to only allow
|
|
drawing within the item's rectangle. If this flag is set to true,
|
|
then the graphics context isn't clipped on its left side, so it
|
|
can draw all the way across to the left margin. Note that the
|
|
context will still have its origin in the same place though, so
|
|
the coordinates of anything to its left will be negative. It's
|
|
mostly useful if you want to draw a wider bar behind the
|
|
highlighted item.
|
|
*/
|
|
void setDrawsInLeftMargin (bool canDrawInLeftMargin) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
TreeView* ownerView;
|
|
TreeViewItem* parentItem;
|
|
OwnedArray <TreeViewItem> subItems;
|
|
int y, itemHeight, totalHeight, itemWidth, totalWidth;
|
|
int uid;
|
|
bool selected : 1;
|
|
bool redrawNeeded : 1;
|
|
bool drawLinesInside : 1;
|
|
bool drawsInLeftMargin : 1;
|
|
unsigned int openness : 2;
|
|
|
|
friend class TreeView;
|
|
friend class TreeViewContentComponent;
|
|
|
|
void updatePositions (int newY);
|
|
int getIndentX() const throw();
|
|
void setOwnerView (TreeView* const newOwner) throw();
|
|
void paintRecursively (Graphics& g, int width);
|
|
TreeViewItem* findItemRecursively (int y) throw();
|
|
TreeViewItem* getDeepestOpenParentItem() throw();
|
|
void restoreFromXml (const XmlElement& e);
|
|
XmlElement* createXmlOpenness() const;
|
|
bool isLastOfSiblings() const throw();
|
|
TreeViewItem* getTopLevelItem() throw();
|
|
int getNumRows() const throw();
|
|
TreeViewItem* getItemOnRow (int index) throw();
|
|
void deselectAllRecursively();
|
|
int countSelectedItemsRecursively() const throw();
|
|
TreeViewItem* getSelectedItemWithIndex (int index) throw();
|
|
TreeViewItem* getNextVisibleItem (const bool recurse) const throw();
|
|
|
|
TreeViewItem (const TreeViewItem&);
|
|
const TreeViewItem& operator= (const TreeViewItem&);
|
|
};
|
|
|
|
/**
|
|
A tree-view component.
|
|
|
|
Use one of these to hold and display a structure of TreeViewItem objects.
|
|
|
|
*/
|
|
class JUCE_API TreeView : public Component,
|
|
public SettableTooltipClient,
|
|
private AsyncUpdater
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty treeview.
|
|
|
|
Once you've got a treeview component, you'll need to give it something to
|
|
display, using the setRootItem() method.
|
|
*/
|
|
TreeView (const String& componentName = String::empty);
|
|
|
|
/** Destructor. */
|
|
~TreeView();
|
|
|
|
/** Sets the item that is displayed in the treeview.
|
|
|
|
A tree has a single root item which contains as many sub-items as it needs. If
|
|
you want the tree to contain a number of root items, you should still use a single
|
|
root item above these, but hide it using setRootItemVisible().
|
|
|
|
You can pass in 0 to this method to clear the tree and remove its current root item.
|
|
|
|
The object passed in will not be deleted by the treeview, it's up to the caller
|
|
to delete it when no longer needed. BUT make absolutely sure that you don't delete
|
|
this item until you've removed it from the tree, either by calling setRootItem (0),
|
|
or by deleting the tree first. You can also use deleteRootItem() as a quick way
|
|
to delete it.
|
|
*/
|
|
void setRootItem (TreeViewItem* const newRootItem);
|
|
|
|
/** Returns the tree's root item.
|
|
|
|
This will be the last object passed to setRootItem(), or 0 if none has been set.
|
|
*/
|
|
TreeViewItem* getRootItem() const throw() { return rootItem; }
|
|
|
|
/** This will remove and delete the current root item.
|
|
|
|
It's a convenient way of deleting the item and calling setRootItem (0).
|
|
*/
|
|
void deleteRootItem();
|
|
|
|
/** Changes whether the tree's root item is shown or not.
|
|
|
|
If the root item is hidden, only its sub-items will be shown in the treeview - this
|
|
lets you make the tree look as if it's got many root items. If it's hidden, this call
|
|
will also make sure the root item is open (otherwise the treeview would look empty).
|
|
*/
|
|
void setRootItemVisible (const bool shouldBeVisible);
|
|
|
|
/** Returns true if the root item is visible.
|
|
|
|
@see setRootItemVisible
|
|
*/
|
|
bool isRootItemVisible() const throw() { return rootItemVisible; }
|
|
|
|
/** Sets whether items are open or closed by default.
|
|
|
|
Normally, items are closed until the user opens them, but you can use this
|
|
to make them default to being open until explicitly closed.
|
|
|
|
@see areItemsOpenByDefault
|
|
*/
|
|
void setDefaultOpenness (const bool isOpenByDefault);
|
|
|
|
/** Returns true if the tree's items default to being open.
|
|
|
|
@see setDefaultOpenness
|
|
*/
|
|
bool areItemsOpenByDefault() const throw() { return defaultOpenness; }
|
|
|
|
/** This sets a flag to indicate that the tree can be used for multi-selection.
|
|
|
|
You can always select multiple items internally by calling the
|
|
TreeViewItem::setSelected() method, but this flag indicates whether the user
|
|
is allowed to multi-select by clicking on the tree.
|
|
|
|
By default it is disabled.
|
|
|
|
@see isMultiSelectEnabled
|
|
*/
|
|
void setMultiSelectEnabled (const bool canMultiSelect);
|
|
|
|
/** Returns whether multi-select has been enabled for the tree.
|
|
|
|
@see setMultiSelectEnabled
|
|
*/
|
|
bool isMultiSelectEnabled() const throw() { return multiSelectEnabled; }
|
|
|
|
/** Sets a flag to indicate whether to hide the open/close buttons.
|
|
|
|
@see areOpenCloseButtonsVisible
|
|
*/
|
|
void setOpenCloseButtonsVisible (const bool shouldBeVisible);
|
|
|
|
/** Returns whether open/close buttons are shown.
|
|
|
|
@see setOpenCloseButtonsVisible
|
|
*/
|
|
bool areOpenCloseButtonsVisible() const throw() { return openCloseButtonsVisible; }
|
|
|
|
/** Deselects any items that are currently selected. */
|
|
void clearSelectedItems();
|
|
|
|
/** Returns the number of items that are currently selected.
|
|
|
|
@see getSelectedItem, clearSelectedItems
|
|
*/
|
|
int getNumSelectedItems() const throw();
|
|
|
|
/** Returns one of the selected items in the tree.
|
|
|
|
@param index the index, 0 to (getNumSelectedItems() - 1)
|
|
*/
|
|
TreeViewItem* getSelectedItem (const int index) const throw();
|
|
|
|
/** Returns the number of rows the tree is using.
|
|
|
|
This will depend on which items are open.
|
|
|
|
@see TreeViewItem::getRowNumberInTree()
|
|
*/
|
|
int getNumRowsInTree() const;
|
|
|
|
/** Returns the item on a particular row of the tree.
|
|
|
|
If the index is out of range, this will return 0.
|
|
|
|
@see getNumRowsInTree, TreeViewItem::getRowNumberInTree()
|
|
*/
|
|
TreeViewItem* getItemOnRow (int index) const;
|
|
|
|
/** Tries to scroll the tree so that this item is on-screen somewhere. */
|
|
void scrollToKeepItemVisible (TreeViewItem* item);
|
|
|
|
/** Returns the treeview's Viewport object. */
|
|
Viewport* getViewport() const throw() { return viewport; }
|
|
|
|
/** Returns the number of pixels by which each nested level of the tree is indented.
|
|
@see setIndentSize
|
|
*/
|
|
int getIndentSize() const throw() { return indentSize; }
|
|
|
|
/** Changes the distance by which each nested level of the tree is indented.
|
|
@see getIndentSize
|
|
*/
|
|
void setIndentSize (const int newIndentSize);
|
|
|
|
/** Saves the current state of open/closed nodes so it can be restored later.
|
|
|
|
This takes a snapshot of which nodes have been explicitly opened or closed,
|
|
and records it as XML. To identify node objects it uses the
|
|
TreeViewItem::getUniqueName() method to create named paths. This
|
|
means that the same state of open/closed nodes can be restored to a
|
|
completely different instance of the tree, as long as it contains nodes
|
|
whose unique names are the same.
|
|
|
|
The caller is responsible for deleting the object that is returned.
|
|
|
|
@param alsoIncludeScrollPosition if this is true, the state will also
|
|
include information about where the
|
|
tree has been scrolled to vertically,
|
|
so this can also be restored
|
|
@see restoreOpennessState
|
|
*/
|
|
XmlElement* getOpennessState (const bool alsoIncludeScrollPosition) const;
|
|
|
|
/** Restores a previously saved arrangement of open/closed nodes.
|
|
|
|
This will try to restore a snapshot of the tree's state that was created by
|
|
the getOpennessState() method. If any of the nodes named in the original
|
|
XML aren't present in this tree, they will be ignored.
|
|
|
|
@see getOpennessState
|
|
*/
|
|
void restoreOpennessState (const XmlElement& newState);
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the treeview.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1000500, /**< A background colour to fill the component with. */
|
|
linesColourId = 0x1000501 /**< The colour to draw the lines with.*/
|
|
};
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
bool keyPressed (const KeyPress& key);
|
|
/** @internal */
|
|
void colourChanged();
|
|
/** @internal */
|
|
void enablementChanged();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class TreeViewItem;
|
|
friend class TreeViewContentComponent;
|
|
Viewport* viewport;
|
|
CriticalSection nodeAlterationLock;
|
|
TreeViewItem* rootItem;
|
|
int indentSize;
|
|
bool defaultOpenness : 1;
|
|
bool needsRecalculating : 1;
|
|
bool rootItemVisible : 1;
|
|
bool multiSelectEnabled : 1;
|
|
bool openCloseButtonsVisible : 1;
|
|
|
|
void itemsChanged() throw();
|
|
void handleAsyncUpdate();
|
|
void moveSelectedRow (int delta);
|
|
void updateButtonUnderMouse (const MouseEvent& e);
|
|
|
|
TreeView (const TreeView&);
|
|
const TreeView& operator= (const TreeView&);
|
|
};
|
|
|
|
#endif // __JUCE_TREEVIEW_JUCEHEADER__
|
|
/********* End of inlined file: juce_TreeView.h *********/
|
|
|
|
/**
|
|
A component to allow editing of the keymaps stored by a KeyPressMappingSet
|
|
object.
|
|
|
|
@see KeyPressMappingSet
|
|
*/
|
|
class JUCE_API KeyMappingEditorComponent : public Component,
|
|
public TreeViewItem,
|
|
public ChangeListener,
|
|
private ButtonListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a KeyMappingEditorComponent.
|
|
|
|
@param mappingSet this is the set of mappings to display and
|
|
edit. Make sure the mappings object is not
|
|
deleted before this component!
|
|
@param showResetToDefaultButton if true, then at the bottom of the
|
|
list, the component will include a 'reset to
|
|
defaults' button.
|
|
*/
|
|
KeyMappingEditorComponent (KeyPressMappingSet* const mappingSet,
|
|
const bool showResetToDefaultButton);
|
|
|
|
/** Destructor. */
|
|
virtual ~KeyMappingEditorComponent();
|
|
|
|
/** Sets up the colours to use for parts of the component.
|
|
|
|
@param mainBackground colour to use for most of the background
|
|
@param textColour colour to use for the text
|
|
*/
|
|
void setColours (const Colour& mainBackground,
|
|
const Colour& textColour);
|
|
|
|
/** Returns the KeyPressMappingSet that this component is acting upon.
|
|
*/
|
|
KeyPressMappingSet* getMappings() const throw() { return mappings; }
|
|
|
|
/** Can be overridden if some commands need to be excluded from the list.
|
|
|
|
By default this will use the KeyPressMappingSet's shouldCommandBeVisibleInEditor()
|
|
method to decide what to return, but you can override it to handle special cases.
|
|
*/
|
|
virtual bool shouldCommandBeIncluded (const CommandID commandID);
|
|
|
|
/** Can be overridden to indicate that some commands are shown as read-only.
|
|
|
|
By default this will use the KeyPressMappingSet's shouldCommandBeReadOnlyInEditor()
|
|
method to decide what to return, but you can override it to handle special cases.
|
|
*/
|
|
virtual bool isCommandReadOnly (const CommandID commandID);
|
|
|
|
/** This can be overridden to let you change the format of the string used
|
|
to describe a keypress.
|
|
|
|
This is handy if you're using non-standard KeyPress objects, e.g. for custom
|
|
keys that are triggered by something else externally. If you override the
|
|
method, be sure to let the base class's method handle keys you're not
|
|
interested in.
|
|
*/
|
|
virtual const String getDescriptionForKeyPress (const KeyPress& key);
|
|
|
|
/** @internal */
|
|
void parentHierarchyChanged();
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void changeListenerCallback (void*);
|
|
/** @internal */
|
|
bool mightContainSubItems();
|
|
/** @internal */
|
|
const String getUniqueName() const;
|
|
/** @internal */
|
|
void buttonClicked (Button* button);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
KeyPressMappingSet* mappings;
|
|
TreeView* tree;
|
|
friend class KeyMappingTreeViewItem;
|
|
friend class KeyCategoryTreeViewItem;
|
|
friend class KeyMappingItemComponent;
|
|
friend class KeyMappingChangeButton;
|
|
Colour backgroundColour, textColour;
|
|
TextButton* resetButton;
|
|
|
|
void assignNewKey (const CommandID commandID, int index);
|
|
|
|
KeyMappingEditorComponent (const KeyMappingEditorComponent&);
|
|
const KeyMappingEditorComponent& operator= (const KeyMappingEditorComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_KeyMappingEditorComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_KEYPRESS_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MenuBarComponent.h *********/
|
|
#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_MENUBARCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MenuBarModel.h *********/
|
|
#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__
|
|
#define __JUCE_MENUBARMODEL_JUCEHEADER__
|
|
|
|
class MenuBarModel;
|
|
|
|
/**
|
|
A class to receive callbacks when a MenuBarModel changes.
|
|
|
|
@see MenuBarModel::addListener, MenuBarModel::removeListener, MenuBarModel::menuItemsChanged
|
|
*/
|
|
class JUCE_API MenuBarModelListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~MenuBarModelListener() {}
|
|
|
|
/** This callback is made when items are changed in the menu bar model.
|
|
*/
|
|
virtual void menuBarItemsChanged (MenuBarModel* menuBarModel) = 0;
|
|
|
|
/** This callback is made when an application command is invoked that
|
|
is represented by one of the items in the menu bar model.
|
|
*/
|
|
virtual void menuCommandInvoked (MenuBarModel* menuBarModel,
|
|
const ApplicationCommandTarget::InvocationInfo& info) = 0;
|
|
};
|
|
|
|
/**
|
|
A class for controlling MenuBar components.
|
|
|
|
This class is used to tell a MenuBar what menus to show, and to respond
|
|
to a menu being selected.
|
|
|
|
@see MenuBarModelListener, MenuBarComponent, PopupMenu
|
|
*/
|
|
class JUCE_API MenuBarModel : private AsyncUpdater,
|
|
private ApplicationCommandManagerListener
|
|
{
|
|
public:
|
|
|
|
MenuBarModel() throw();
|
|
|
|
/** Destructor. */
|
|
virtual ~MenuBarModel();
|
|
|
|
/** Call this when some of your menu items have changed.
|
|
|
|
This method will cause a callback to any MenuBarListener objects that
|
|
are registered with this model.
|
|
|
|
If this model is displaying items from an ApplicationCommandManager, you
|
|
can use the setApplicationCommandManagerToWatch() method to cause
|
|
change messages to be sent automatically when the ApplicationCommandManager
|
|
is changed.
|
|
|
|
@see addListener, removeListener, MenuBarListener
|
|
*/
|
|
void menuItemsChanged();
|
|
|
|
/** Tells the menu bar to listen to the specified command manager, and to update
|
|
itself when the commands change.
|
|
|
|
This will also allow it to flash a menu name when a command from that menu
|
|
is invoked using a keystroke.
|
|
*/
|
|
void setApplicationCommandManagerToWatch (ApplicationCommandManager* const manager) throw();
|
|
|
|
/** Registers a listener for callbacks when the menu items in this model change.
|
|
|
|
The listener object will get callbacks when this object's menuItemsChanged()
|
|
method is called.
|
|
|
|
@see removeListener
|
|
*/
|
|
void addListener (MenuBarModelListener* const listenerToAdd) throw();
|
|
|
|
/** Removes a listener.
|
|
|
|
@see addListener
|
|
*/
|
|
void removeListener (MenuBarModelListener* const listenerToRemove) throw();
|
|
|
|
/** This method must return a list of the names of the menus. */
|
|
virtual const StringArray getMenuBarNames() = 0;
|
|
|
|
/** This should return the popup menu to display for a given top-level menu.
|
|
|
|
@param topLevelMenuIndex the index of the top-level menu to show
|
|
@param menuName the name of the top-level menu item to show
|
|
*/
|
|
virtual const PopupMenu getMenuForIndex (int topLevelMenuIndex,
|
|
const String& menuName) = 0;
|
|
|
|
/** This is called when a menu item has been clicked on.
|
|
|
|
@param menuItemID the item ID of the PopupMenu item that was selected
|
|
@param topLevelMenuIndex the index of the top-level menu from which the item was
|
|
chosen (just in case you've used duplicate ID numbers
|
|
on more than one of the popup menus)
|
|
*/
|
|
virtual void menuItemSelected (int menuItemID,
|
|
int topLevelMenuIndex) = 0;
|
|
|
|
#if JUCE_MAC || DOXYGEN
|
|
/** MAC ONLY - Sets the model that is currently being shown as the main
|
|
menu bar at the top of the screen on the Mac.
|
|
|
|
You can pass 0 to stop the current model being displayed. Be careful
|
|
not to delete a model while it is being used.
|
|
|
|
An optional extra menu can be specified, containing items to add to the top of
|
|
the apple menu. (Confusingly, the 'apple' menu isn't the one with a picture of
|
|
an apple, it's the one next to it, with your application's name at the top
|
|
and the services menu etc on it). When one of these items is selected, the
|
|
menu bar model will be used to invoke it, and in the menuItemSelected() callback
|
|
the topLevelMenuIndex parameter will be -1. If you pass in an extraAppleMenuItems
|
|
object then newMenuBarModel must be non-null.
|
|
*/
|
|
static void setMacMainMenu (MenuBarModel* newMenuBarModel,
|
|
const PopupMenu* extraAppleMenuItems = 0) throw();
|
|
|
|
/** MAC ONLY - Returns the menu model that is currently being shown as
|
|
the main menu bar.
|
|
*/
|
|
static MenuBarModel* getMacMainMenu() throw();
|
|
|
|
#endif
|
|
|
|
/** @internal */
|
|
void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info);
|
|
/** @internal */
|
|
void applicationCommandListChanged();
|
|
/** @internal */
|
|
void handleAsyncUpdate();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
ApplicationCommandManager* manager;
|
|
SortedSet <void*> listeners;
|
|
|
|
MenuBarModel (const MenuBarModel&);
|
|
const MenuBarModel& operator= (const MenuBarModel&);
|
|
};
|
|
|
|
#endif // __JUCE_MENUBARMODEL_JUCEHEADER__
|
|
/********* End of inlined file: juce_MenuBarModel.h *********/
|
|
|
|
/**
|
|
A menu bar component.
|
|
|
|
@see MenuBarModel
|
|
*/
|
|
class JUCE_API MenuBarComponent : public Component,
|
|
private MenuBarModelListener,
|
|
private Timer
|
|
{
|
|
public:
|
|
|
|
/** Creates a menu bar.
|
|
|
|
@param model the model object to use to control this bar. You can
|
|
pass 0 into this if you like, and set the model later
|
|
using the setModel() method
|
|
*/
|
|
MenuBarComponent (MenuBarModel* const model);
|
|
|
|
/** Destructor. */
|
|
~MenuBarComponent();
|
|
|
|
/** Changes the model object to use to control the bar.
|
|
|
|
This can be 0, in which case the bar will be empty. Don't delete the object
|
|
that is passed-in while it's still being used by this MenuBar.
|
|
*/
|
|
void setModel (MenuBarModel* const newModel);
|
|
|
|
/** Pops up one of the menu items.
|
|
|
|
This lets you manually open one of the menus - it could be triggered by a
|
|
key shortcut, for example.
|
|
*/
|
|
void showMenu (const int menuIndex);
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void mouseEnter (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseExit (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseUp (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseMove (const MouseEvent& e);
|
|
/** @internal */
|
|
void inputAttemptWhenModal();
|
|
/** @internal */
|
|
void handleCommandMessage (int commandId);
|
|
/** @internal */
|
|
bool keyPressed (const KeyPress& key);
|
|
/** @internal */
|
|
void menuBarItemsChanged (MenuBarModel* menuBarModel);
|
|
/** @internal */
|
|
void menuCommandInvoked (MenuBarModel* menuBarModel,
|
|
const ApplicationCommandTarget::InvocationInfo& info);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
MenuBarModel* model;
|
|
|
|
StringArray menuNames;
|
|
Array <int> xPositions;
|
|
int itemUnderMouse, currentPopupIndex, topLevelIndexClicked, indexToShowAgain;
|
|
int lastMouseX, lastMouseY;
|
|
bool inModalState;
|
|
Component* currentPopup;
|
|
|
|
int getItemAt (int x, int y);
|
|
void updateItemUnderMouse (const int x, const int y);
|
|
void hideCurrentMenu();
|
|
void timerCallback();
|
|
void repaintMenuItem (int index);
|
|
|
|
MenuBarComponent (const MenuBarComponent&);
|
|
const MenuBarComponent& operator= (const MenuBarComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_MENUBARCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_MenuBarComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_POPUPMENU_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ComponentDragger.h *********/
|
|
#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__
|
|
#define __JUCE_COMPONENTDRAGGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ComponentBoundsConstrainer.h *********/
|
|
#ifndef __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__
|
|
#define __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__
|
|
|
|
/**
|
|
A class that imposes restrictions on a Component's size or position.
|
|
|
|
This is used by classes such as ResizableCornerComponent,
|
|
ResizableBorderComponent and ResizableWindow.
|
|
|
|
The base class can impose some basic size and position limits, but you can
|
|
also subclass this for custom uses.
|
|
|
|
@see ResizableCornerComponent, ResizableBorderComponent, ResizableWindow
|
|
*/
|
|
class JUCE_API ComponentBoundsConstrainer
|
|
{
|
|
public:
|
|
|
|
/** When first created, the object will not impose any restrictions on the components. */
|
|
ComponentBoundsConstrainer() throw();
|
|
|
|
/** Destructor. */
|
|
virtual ~ComponentBoundsConstrainer();
|
|
|
|
/** Imposes a minimum width limit. */
|
|
void setMinimumWidth (const int minimumWidth) throw();
|
|
|
|
/** Returns the current minimum width. */
|
|
int getMinimumWidth() const throw() { return minW; }
|
|
|
|
/** Imposes a maximum width limit. */
|
|
void setMaximumWidth (const int maximumWidth) throw();
|
|
|
|
/** Returns the current maximum width. */
|
|
int getMaximumWidth() const throw() { return maxW; }
|
|
|
|
/** Imposes a minimum height limit. */
|
|
void setMinimumHeight (const int minimumHeight) throw();
|
|
|
|
/** Returns the current minimum height. */
|
|
int getMinimumHeight() const throw() { return minH; }
|
|
|
|
/** Imposes a maximum height limit. */
|
|
void setMaximumHeight (const int maximumHeight) throw();
|
|
|
|
/** Returns the current maximum height. */
|
|
int getMaximumHeight() const throw() { return maxH; }
|
|
|
|
/** Imposes a minimum width and height limit. */
|
|
void setMinimumSize (const int minimumWidth,
|
|
const int minimumHeight) throw();
|
|
|
|
/** Imposes a maximum width and height limit. */
|
|
void setMaximumSize (const int maximumWidth,
|
|
const int maximumHeight) throw();
|
|
|
|
/** Set all the maximum and minimum dimensions. */
|
|
void setSizeLimits (const int minimumWidth,
|
|
const int minimumHeight,
|
|
const int maximumWidth,
|
|
const int maximumHeight) throw();
|
|
|
|
/** Sets the amount by which the component is allowed to go off-screen.
|
|
|
|
The values indicate how many pixels must remain on-screen when dragged off
|
|
one of its parent's edges, so e.g. if minimumWhenOffTheTop is set to 10, then
|
|
when the component goes off the top of the screen, its y-position will be
|
|
clipped so that there are always at least 10 pixels on-screen. In other words,
|
|
the lowest y-position it can take would be (10 - the component's height).
|
|
|
|
If you pass 0 or less for one of these amounts, the component is allowed
|
|
to move beyond that edge completely, with no restrictions at all.
|
|
|
|
If you pass a very large number (i.e. larger that the dimensions of the
|
|
component itself), then the component won't be allowed to overlap that
|
|
edge at all. So e.g. setting minimumWhenOffTheLeft to 0xffffff will mean that
|
|
the component will bump into the left side of the screen and go no further.
|
|
*/
|
|
void setMinimumOnscreenAmounts (const int minimumWhenOffTheTop,
|
|
const int minimumWhenOffTheLeft,
|
|
const int minimumWhenOffTheBottom,
|
|
const int minimumWhenOffTheRight) throw();
|
|
|
|
/** Specifies a width-to-height ratio that the resizer should always maintain.
|
|
|
|
If the value is 0, no aspect ratio is enforced. If it's non-zero, the width
|
|
will always be maintained as this multiple of the height.
|
|
|
|
@see setResizeLimits
|
|
*/
|
|
void setFixedAspectRatio (const double widthOverHeight) throw();
|
|
|
|
/** Returns the aspect ratio that was set with setFixedAspectRatio().
|
|
|
|
If no aspect ratio is being enforced, this will return 0.
|
|
*/
|
|
double getFixedAspectRatio() const throw();
|
|
|
|
/** This callback changes the given co-ordinates to impose whatever the current
|
|
constraints are set to be.
|
|
|
|
@param x the x position that should be examined and adjusted
|
|
@param y the y position that should be examined and adjusted
|
|
@param w the width that should be examined and adjusted
|
|
@param h the height that should be examined and adjusted
|
|
@param previousBounds the component's current size
|
|
@param limits the region in which the component can be positioned
|
|
@param isStretchingTop whether the top edge of the component is being resized
|
|
@param isStretchingLeft whether the left edge of the component is being resized
|
|
@param isStretchingBottom whether the bottom edge of the component is being resized
|
|
@param isStretchingRight whether the right edge of the component is being resized
|
|
*/
|
|
virtual void checkBounds (int& x, int& y, int& w, int& h,
|
|
const Rectangle& previousBounds,
|
|
const Rectangle& limits,
|
|
const bool isStretchingTop,
|
|
const bool isStretchingLeft,
|
|
const bool isStretchingBottom,
|
|
const bool isStretchingRight);
|
|
|
|
/** This callback happens when the resizer is about to start dragging. */
|
|
virtual void resizeStart();
|
|
|
|
/** This callback happens when the resizer has finished dragging. */
|
|
virtual void resizeEnd();
|
|
|
|
/** Checks the given bounds, and then sets the component to the corrected size. */
|
|
void setBoundsForComponent (Component* const component,
|
|
int x, int y, int w, int h,
|
|
const bool isStretchingTop,
|
|
const bool isStretchingLeft,
|
|
const bool isStretchingBottom,
|
|
const bool isStretchingRight);
|
|
|
|
/** Performs a check on the current size of a component, and moves or resizes
|
|
it if it fails the constraints.
|
|
*/
|
|
void checkComponentBounds (Component* component);
|
|
|
|
/** Called by setBoundsForComponent() to apply a new constrained size to a
|
|
component.
|
|
|
|
By default this just calls setBounds(), but it virtual in case it's needed for
|
|
extremely cunning purposes.
|
|
*/
|
|
virtual void applyBoundsToComponent (Component* component,
|
|
int x, int y, int w, int h);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int minW, maxW, minH, maxH;
|
|
int minOffTop, minOffLeft, minOffBottom, minOffRight;
|
|
double aspectRatio;
|
|
|
|
ComponentBoundsConstrainer (const ComponentBoundsConstrainer&);
|
|
const ComponentBoundsConstrainer& operator= (const ComponentBoundsConstrainer&);
|
|
};
|
|
|
|
#endif // __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__
|
|
/********* End of inlined file: juce_ComponentBoundsConstrainer.h *********/
|
|
|
|
/**
|
|
An object to take care of the logic for dragging components around with the mouse.
|
|
|
|
Very easy to use - in your mouseDown() callback, call startDraggingComponent(),
|
|
then in your mouseDrag() callback, call dragComponent().
|
|
|
|
When starting a drag, you can give it a ComponentBoundsConstrainer to use
|
|
to limit the component's position and keep it on-screen.
|
|
|
|
e.g. @code
|
|
class MyDraggableComp
|
|
{
|
|
ComponentDragger myDragger;
|
|
|
|
void mouseDown (const MouseEvent& e)
|
|
{
|
|
myDragger.startDraggingComponent (this, 0);
|
|
}
|
|
|
|
void mouseDrag (const MouseEvent& e)
|
|
{
|
|
myDragger.dragComponent (this, e);
|
|
}
|
|
};
|
|
@endcode
|
|
*/
|
|
class JUCE_API ComponentDragger
|
|
{
|
|
public:
|
|
|
|
/** Creates a ComponentDragger. */
|
|
ComponentDragger();
|
|
|
|
/** Destructor. */
|
|
virtual ~ComponentDragger();
|
|
|
|
/** Call this from your component's mouseDown() method, to prepare for dragging.
|
|
|
|
@param componentToDrag the component that you want to drag
|
|
@param constrainer a constrainer object to use to keep the component
|
|
from going offscreen
|
|
@see dragComponent
|
|
*/
|
|
void startDraggingComponent (Component* const componentToDrag,
|
|
ComponentBoundsConstrainer* constrainer);
|
|
|
|
/** Call this from your mouseDrag() callback to move the component.
|
|
|
|
This will move the component, but will first check the validity of the
|
|
component's new position using the checkPosition() method, which you
|
|
can override if you need to enforce special positioning limits on the
|
|
component.
|
|
|
|
@param componentToDrag the component that you want to drag
|
|
@param e the current mouse-drag event
|
|
@see dragComponent
|
|
*/
|
|
void dragComponent (Component* const componentToDrag,
|
|
const MouseEvent& e);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
ComponentBoundsConstrainer* constrainer;
|
|
int originalX, originalY;
|
|
};
|
|
|
|
#endif // __JUCE_COMPONENTDRAGGER_JUCEHEADER__
|
|
/********* End of inlined file: juce_ComponentDragger.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_DRAGANDDROPTARGET_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileDragAndDropTarget.h *********/
|
|
#ifndef __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__
|
|
#define __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__
|
|
|
|
/**
|
|
Components derived from this class can have files dropped onto them by an external application.
|
|
|
|
@see DragAndDropContainer
|
|
*/
|
|
class JUCE_API FileDragAndDropTarget
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~FileDragAndDropTarget() {}
|
|
|
|
/** Callback to check whether this target is interested in the set of files being offered.
|
|
|
|
Note that this will be called repeatedly when the user is dragging the mouse around over your
|
|
component, so don't do anything time-consuming in here, like opening the files to have a look
|
|
inside them!
|
|
|
|
@param files the set of (absolute) pathnames of the files that the user is dragging
|
|
@returns true if this component wants to receive the other callbacks regarging this
|
|
type of object; if it returns false, no other callbacks will be made.
|
|
*/
|
|
virtual bool isInterestedInFileDrag (const StringArray& files) = 0;
|
|
|
|
/** Callback to indicate that some files are being dragged over this component.
|
|
|
|
This gets called when the user moves the mouse into this component while dragging.
|
|
|
|
Use this callback as a trigger to make your component repaint itself to give the
|
|
user feedback about whether the files can be dropped here or not.
|
|
|
|
@param files the set of (absolute) pathnames of the files that the user is dragging
|
|
@param x the mouse x position, relative to this component
|
|
@param y the mouse y position, relative to this component
|
|
*/
|
|
virtual void fileDragEnter (const StringArray& files, int x, int y);
|
|
|
|
/** Callback to indicate that the user is dragging some files over this component.
|
|
|
|
This gets called when the user moves the mouse over this component while dragging.
|
|
Normally overriding itemDragEnter() and itemDragExit() are enough, but
|
|
this lets you know what happens in-between.
|
|
|
|
@param files the set of (absolute) pathnames of the files that the user is dragging
|
|
@param x the mouse x position, relative to this component
|
|
@param y the mouse y position, relative to this component
|
|
*/
|
|
virtual void fileDragMove (const StringArray& files, int x, int y);
|
|
|
|
/** Callback to indicate that the mouse has moved away from this component.
|
|
|
|
This gets called when the user moves the mouse out of this component while dragging
|
|
the files.
|
|
|
|
If you've used fileDragEnter() to repaint your component and give feedback, use this
|
|
as a signal to repaint it in its normal state.
|
|
|
|
@param files the set of (absolute) pathnames of the files that the user is dragging
|
|
*/
|
|
virtual void fileDragExit (const StringArray& files);
|
|
|
|
/** Callback to indicate that the user has dropped the files onto this component.
|
|
|
|
When the user drops the files, this get called, and you can use the files in whatever
|
|
way is appropriate.
|
|
|
|
Note that after this is called, the fileDragExit method may not be called, so you should
|
|
clean up in here if there's anything you need to do when the drag finishes.
|
|
|
|
@param files the set of (absolute) pathnames of the files that the user is dragging
|
|
@param x the mouse x position, relative to this component
|
|
@param y the mouse y position, relative to this component
|
|
*/
|
|
virtual void filesDropped (const StringArray& files, int x, int y) = 0;
|
|
};
|
|
|
|
#endif // __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileDragAndDropTarget.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_LASSOCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_LassoComponent.h *********/
|
|
#ifndef __JUCE_LASSOCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_LASSOCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_SelectedItemSet.h *********/
|
|
#ifndef __JUCE_SELECTEDITEMSET_JUCEHEADER__
|
|
#define __JUCE_SELECTEDITEMSET_JUCEHEADER__
|
|
|
|
/** Manages a list of selectable items.
|
|
|
|
Use one of these to keep a track of things that the user has highlighted, like
|
|
icons or things in a list.
|
|
|
|
The class is templated so that you can use it to hold either a set of pointers
|
|
to objects, or a set of ID numbers or handles, for cases where each item may
|
|
not always have a corresponding object.
|
|
|
|
To be informed when items are selected/deselected, register a ChangeListener with
|
|
this object.
|
|
|
|
@see SelectableObject
|
|
*/
|
|
template <class SelectableItemType>
|
|
class JUCE_API SelectedItemSet : public ChangeBroadcaster
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty set. */
|
|
SelectedItemSet()
|
|
{
|
|
}
|
|
|
|
/** Creates a set based on an array of items. */
|
|
SelectedItemSet (const Array <SelectableItemType>& items)
|
|
: selectedItems (items)
|
|
{
|
|
}
|
|
|
|
/** Creates a copy of another set. */
|
|
SelectedItemSet (const SelectedItemSet& other)
|
|
: selectedItems (other.selectedItems)
|
|
{
|
|
}
|
|
|
|
/** Creates a copy of another set. */
|
|
const SelectedItemSet& operator= (const SelectedItemSet& other)
|
|
{
|
|
if (selectedItems != other.selectedItems)
|
|
{
|
|
selectedItems = other.selectedItems;
|
|
changed();
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
/** Destructor. */
|
|
~SelectedItemSet()
|
|
{
|
|
}
|
|
|
|
/** Clears any other currently selected items, and selects this item.
|
|
|
|
If this item is already the only thing selected, no change notification
|
|
will be sent out.
|
|
|
|
@see addToSelection, addToSelectionBasedOnModifiers
|
|
*/
|
|
void selectOnly (SelectableItemType item)
|
|
{
|
|
if (isSelected (item))
|
|
{
|
|
for (int i = selectedItems.size(); --i >= 0;)
|
|
{
|
|
if (selectedItems.getUnchecked(i) != item)
|
|
{
|
|
deselect (selectedItems.getUnchecked(i));
|
|
i = jmin (i, selectedItems.size());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
deselectAll();
|
|
changed();
|
|
|
|
selectedItems.add (item);
|
|
itemSelected (item);
|
|
}
|
|
}
|
|
|
|
/** Selects an item.
|
|
|
|
If the item is already selected, no change notification will be sent out.
|
|
|
|
@see selectOnly, addToSelectionBasedOnModifiers
|
|
*/
|
|
void addToSelection (SelectableItemType item)
|
|
{
|
|
if (! isSelected (item))
|
|
{
|
|
changed();
|
|
|
|
selectedItems.add (item);
|
|
itemSelected (item);
|
|
}
|
|
}
|
|
|
|
/** Selects or deselects an item.
|
|
|
|
This will use the modifier keys to decide whether to deselect other items
|
|
first.
|
|
|
|
So if the shift key is held down, the item will be added without deselecting
|
|
anything (same as calling addToSelection() )
|
|
|
|
If no modifiers are down, the current selection will be cleared first (same
|
|
as calling selectOnly() )
|
|
|
|
If the ctrl (or command on the Mac) key is held down, the item will be toggled -
|
|
so it'll be added to the set unless it's already there, in which case it'll be
|
|
deselected.
|
|
|
|
If the items that you're selecting can also be dragged, you may need to use the
|
|
addToSelectionOnMouseDown() and addToSelectionOnMouseUp() calls to handle the
|
|
subtleties of this kind of usage.
|
|
|
|
@see selectOnly, addToSelection, addToSelectionOnMouseDown, addToSelectionOnMouseUp
|
|
*/
|
|
void addToSelectionBasedOnModifiers (SelectableItemType item,
|
|
const ModifierKeys& modifiers)
|
|
{
|
|
if (modifiers.isShiftDown())
|
|
{
|
|
addToSelection (item);
|
|
}
|
|
else if (modifiers.isCommandDown())
|
|
{
|
|
if (isSelected (item))
|
|
deselect (item);
|
|
else
|
|
addToSelection (item);
|
|
}
|
|
else
|
|
{
|
|
selectOnly (item);
|
|
}
|
|
}
|
|
|
|
/** Selects or deselects items that can also be dragged, based on a mouse-down event.
|
|
|
|
If you call addToSelectionOnMouseDown() at the start of your mouseDown event,
|
|
and then call addToSelectionOnMouseUp() at the end of your mouseUp event, this
|
|
makes it easy to handle multiple-selection of sets of objects that can also
|
|
be dragged.
|
|
|
|
For example, if you have several items already selected, and you click on
|
|
one of them (without dragging), then you'd expect this to deselect the other, and
|
|
just select the item you clicked on. But if you had clicked on this item and
|
|
dragged it, you'd have expected them all to stay selected.
|
|
|
|
When you call this method, you'll need to store the boolean result, because the
|
|
addToSelectionOnMouseUp() method will need to be know this value.
|
|
|
|
@see addToSelectionOnMouseUp, addToSelectionBasedOnModifiers
|
|
*/
|
|
bool addToSelectionOnMouseDown (SelectableItemType item,
|
|
const ModifierKeys& modifiers)
|
|
{
|
|
if (isSelected (item))
|
|
{
|
|
return ! modifiers.isPopupMenu();
|
|
}
|
|
else
|
|
{
|
|
addToSelectionBasedOnModifiers (item, modifiers);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/** Selects or deselects items that can also be dragged, based on a mouse-up event.
|
|
|
|
Call this during a mouseUp callback, when you have previously called the
|
|
addToSelectionOnMouseDown() method during your mouseDown event.
|
|
|
|
See addToSelectionOnMouseDown() for more info
|
|
|
|
@param item the item to select (or deselect)
|
|
@param modifiers the modifiers from the mouse-up event
|
|
@param wasItemDragged true if your item was dragged during the mouse click
|
|
@param resultOfMouseDownSelectMethod this is the boolean return value that came
|
|
back from the addToSelectionOnMouseDown() call that you
|
|
should have made during the matching mouseDown event
|
|
*/
|
|
void addToSelectionOnMouseUp (SelectableItemType item,
|
|
const ModifierKeys& modifiers,
|
|
const bool wasItemDragged,
|
|
const bool resultOfMouseDownSelectMethod)
|
|
{
|
|
if (resultOfMouseDownSelectMethod && ! wasItemDragged)
|
|
addToSelectionBasedOnModifiers (item, modifiers);
|
|
}
|
|
|
|
/** Deselects an item. */
|
|
void deselect (SelectableItemType item)
|
|
{
|
|
const int i = selectedItems.indexOf (item);
|
|
|
|
if (i >= 0)
|
|
{
|
|
changed();
|
|
itemDeselected (selectedItems.remove (i));
|
|
}
|
|
}
|
|
|
|
/** Deselects all items. */
|
|
void deselectAll()
|
|
{
|
|
if (selectedItems.size() > 0)
|
|
{
|
|
changed();
|
|
|
|
for (int i = selectedItems.size(); --i >= 0;)
|
|
{
|
|
itemDeselected (selectedItems.remove (i));
|
|
i = jmin (i, selectedItems.size());
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Returns the number of currently selected items.
|
|
|
|
@see getSelectedItem
|
|
*/
|
|
int getNumSelected() const throw()
|
|
{
|
|
return selectedItems.size();
|
|
}
|
|
|
|
/** Returns one of the currently selected items.
|
|
|
|
Returns 0 if the index is out-of-range.
|
|
|
|
@see getNumSelected
|
|
*/
|
|
SelectableItemType getSelectedItem (const int index) const throw()
|
|
{
|
|
return selectedItems [index];
|
|
}
|
|
|
|
/** True if this item is currently selected. */
|
|
bool isSelected (const SelectableItemType item) const throw()
|
|
{
|
|
return selectedItems.contains (item);
|
|
}
|
|
|
|
const Array <SelectableItemType>& getItemArray() const throw() { return selectedItems; }
|
|
|
|
/** Can be overridden to do special handling when an item is selected.
|
|
|
|
For example, if the item is an object, you might want to call it and tell
|
|
it that it's being selected.
|
|
*/
|
|
virtual void itemSelected (SelectableItemType item) {}
|
|
|
|
/** Can be overridden to do special handling when an item is deselected.
|
|
|
|
For example, if the item is an object, you might want to call it and tell
|
|
it that it's being deselected.
|
|
*/
|
|
virtual void itemDeselected (SelectableItemType item) {}
|
|
|
|
/** Used internally, but can be called to force a change message to be sent to the ChangeListeners.
|
|
*/
|
|
void changed (const bool synchronous = false)
|
|
{
|
|
if (synchronous)
|
|
sendSynchronousChangeMessage (this);
|
|
else
|
|
sendChangeMessage (this);
|
|
}
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Array <SelectableItemType> selectedItems;
|
|
};
|
|
|
|
#endif // __JUCE_SELECTEDITEMSET_JUCEHEADER__
|
|
/********* End of inlined file: juce_SelectedItemSet.h *********/
|
|
|
|
/**
|
|
A class used by the LassoComponent to manage the things that it selects.
|
|
|
|
This allows the LassoComponent to find out which items are within the lasso,
|
|
and to change the list of selected items.
|
|
|
|
@see LassoComponent, SelectedItemSet
|
|
*/
|
|
template <class SelectableItemType>
|
|
class LassoSource
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~LassoSource() {}
|
|
|
|
/** Returns the set of items that lie within a given lassoable region.
|
|
|
|
Your implementation of this method must find all the relevent items that lie
|
|
within the given rectangle. and add them to the itemsFound array.
|
|
|
|
The co-ordinates are relative to the top-left of the lasso component's parent
|
|
component. (i.e. they are the same as the size and position of the lasso
|
|
component itself).
|
|
*/
|
|
virtual void findLassoItemsInArea (Array <SelectableItemType>& itemsFound,
|
|
int x, int y, int width, int height) = 0;
|
|
|
|
/** Returns the SelectedItemSet that the lasso should update.
|
|
|
|
This set will be continuously updated by the LassoComponent as it gets
|
|
dragged around, so make sure that you've got a ChangeListener attached to
|
|
the set so that your UI objects will know when the selection changes and
|
|
be able to update themselves appropriately.
|
|
*/
|
|
virtual SelectedItemSet <SelectableItemType>& getLassoSelection() = 0;
|
|
};
|
|
|
|
/**
|
|
A component that acts as a rectangular selection region, which you drag with
|
|
the mouse to select groups of objects (in conjunction with a SelectedItemSet).
|
|
|
|
To use one of these:
|
|
|
|
- In your mouseDown or mouseDrag event, add the LassoComponent to your parent
|
|
component, and call its beginLasso() method, giving it a
|
|
suitable LassoSource object that it can use to find out which items are in
|
|
the active area.
|
|
|
|
- Each time your parent component gets a mouseDrag event, call dragLasso()
|
|
to update the lasso's position - it will use its LassoSource to calculate and
|
|
update the current selection.
|
|
|
|
- After the drag has finished and you get a mouseUp callback, you should call
|
|
endLasso() to clean up. This will make the lasso component invisible, and you
|
|
can remove it from the parent component, or delete it.
|
|
|
|
The class takes into account the modifier keys that are being held down while
|
|
the lasso is being dragged, so if shift is pressed, then any lassoed items will
|
|
be added to the original selection; if ctrl or command is pressed, they will be
|
|
xor'ed with any previously selected items.
|
|
|
|
@see LassoSource, SelectedItemSet
|
|
*/
|
|
template <class SelectableItemType>
|
|
class LassoComponent : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates a Lasso component.
|
|
|
|
The fill colour is used to fill the lasso'ed rectangle, and the outline
|
|
colour is used to draw a line around its edge.
|
|
*/
|
|
LassoComponent (const int outlineThickness_ = 1)
|
|
: source (0),
|
|
outlineThickness (outlineThickness_)
|
|
{
|
|
}
|
|
|
|
/** Destructor. */
|
|
~LassoComponent()
|
|
{
|
|
}
|
|
|
|
/** Call this in your mouseDown event, to initialise a drag.
|
|
|
|
Pass in a suitable LassoSource object which the lasso will use to find
|
|
the items and change the selection.
|
|
|
|
After using this method to initialise the lasso, repeatedly call dragLasso()
|
|
in your component's mouseDrag callback.
|
|
|
|
@see dragLasso, endLasso, LassoSource
|
|
*/
|
|
void beginLasso (const MouseEvent& e,
|
|
LassoSource <SelectableItemType>* const lassoSource)
|
|
{
|
|
jassert (source == 0); // this suggests that you didn't call endLasso() after the last drag...
|
|
jassert (lassoSource != 0); // the source can't be null!
|
|
jassert (getParentComponent() != 0); // you need to add this to a parent component for it to work!
|
|
|
|
source = lassoSource;
|
|
|
|
if (lassoSource != 0)
|
|
originalSelection = lassoSource->getLassoSelection().getItemArray();
|
|
|
|
setSize (0, 0);
|
|
}
|
|
|
|
/** Call this in your mouseDrag event, to update the lasso's position.
|
|
|
|
This must be repeatedly calling when the mouse is dragged, after you've
|
|
first initialised the lasso with beginLasso().
|
|
|
|
This method takes into account the modifier keys that are being held down, so
|
|
if shift is pressed, then the lassoed items will be added to any that were
|
|
previously selected; if ctrl or command is pressed, then they will be xor'ed
|
|
with previously selected items.
|
|
|
|
@see beginLasso, endLasso
|
|
*/
|
|
void dragLasso (const MouseEvent& e)
|
|
{
|
|
if (source != 0)
|
|
{
|
|
const int x1 = e.getMouseDownX();
|
|
const int y1 = e.getMouseDownY();
|
|
|
|
setBounds (jmin (x1, e.x), jmin (y1, e.y), abs (e.x - x1), abs (e.y - y1));
|
|
setVisible (true);
|
|
|
|
Array <SelectableItemType> itemsInLasso;
|
|
source->findLassoItemsInArea (itemsInLasso, getX(), getY(), getWidth(), getHeight());
|
|
|
|
if (e.mods.isShiftDown())
|
|
{
|
|
itemsInLasso.removeValuesIn (originalSelection); // to avoid duplicates
|
|
itemsInLasso.addArray (originalSelection);
|
|
}
|
|
else if (e.mods.isCommandDown() || e.mods.isAltDown())
|
|
{
|
|
Array <SelectableItemType> originalMinusNew (originalSelection);
|
|
originalMinusNew.removeValuesIn (itemsInLasso);
|
|
|
|
itemsInLasso.removeValuesIn (originalSelection);
|
|
itemsInLasso.addArray (originalMinusNew);
|
|
}
|
|
|
|
source->getLassoSelection() = SelectedItemSet <SelectableItemType> (itemsInLasso);
|
|
}
|
|
}
|
|
|
|
/** Call this in your mouseUp event, after the lasso has been dragged.
|
|
|
|
@see beginLasso, dragLasso
|
|
*/
|
|
void endLasso()
|
|
{
|
|
source = 0;
|
|
originalSelection.clear();
|
|
setVisible (false);
|
|
}
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the label.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
Note that you can also use the constants from TextEditor::ColourIds to change the
|
|
colour of the text editor that is opened when a label is editable.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
lassoFillColourId = 0x1000440, /**< The colour to fill the lasso rectangle with. */
|
|
lassoOutlineColourId = 0x1000441, /**< The colour to draw the outline with. */
|
|
};
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g)
|
|
{
|
|
g.fillAll (findColour (lassoFillColourId));
|
|
|
|
g.setColour (findColour (lassoOutlineColourId));
|
|
g.drawRect (0, 0, getWidth(), getHeight(), outlineThickness);
|
|
|
|
// this suggests that you've left a lasso comp lying around after the
|
|
// mouse drag has finished.. Be careful to call endLasso() when you get a
|
|
// mouse-up event.
|
|
jassert (isMouseButtonDownAnywhere());
|
|
}
|
|
|
|
/** @internal */
|
|
bool hitTest (int x, int y) { return false; }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Array <SelectableItemType> originalSelection;
|
|
LassoSource <SelectableItemType>* source;
|
|
int outlineThickness;
|
|
};
|
|
|
|
#endif // __JUCE_LASSOCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_LassoComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MOUSECURSOR_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MOUSEEVENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MouseHoverDetector.h *********/
|
|
#ifndef __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__
|
|
#define __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__
|
|
|
|
/**
|
|
Monitors a component for mouse activity, and triggers a callback
|
|
when the mouse hovers in one place for a specified length of time.
|
|
|
|
To use a hover-detector, just create one and call its setHoverComponent()
|
|
method to start it watching a component. You can call setHoverComponent (0)
|
|
to make it inactive.
|
|
|
|
(Be careful not to delete a component that's being monitored without first
|
|
stopping or deleting the hover detector).
|
|
*/
|
|
class JUCE_API MouseHoverDetector
|
|
{
|
|
public:
|
|
|
|
/** Creates a hover detector.
|
|
|
|
Initially the object is inactive, and you need to tell it which component
|
|
to monitor, using the setHoverComponent() method.
|
|
|
|
@param hoverTimeMillisecs the number of milliseconds for which the mouse
|
|
needs to stay still before the mouseHovered() method
|
|
is invoked. You can change this setting later with
|
|
the setHoverTimeMillisecs() method
|
|
*/
|
|
MouseHoverDetector (const int hoverTimeMillisecs = 400);
|
|
|
|
/** Destructor. */
|
|
virtual ~MouseHoverDetector();
|
|
|
|
/** Changes the time for which the mouse has to stay still before it's considered
|
|
to be hovering.
|
|
*/
|
|
void setHoverTimeMillisecs (const int newTimeInMillisecs);
|
|
|
|
/** Changes the component that's being monitored for hovering.
|
|
|
|
Be careful not to delete a component that's being monitored without first
|
|
stopping or deleting the hover detector.
|
|
*/
|
|
void setHoverComponent (Component* const newSourceComponent);
|
|
|
|
protected:
|
|
|
|
/** Called back when the mouse hovers.
|
|
|
|
After the mouse has stayed still over the component for the length of time
|
|
specified by setHoverTimeMillisecs(), this method will be invoked.
|
|
|
|
When the mouse is first moved after this callback has occurred, the
|
|
mouseMovedAfterHover() method will be called.
|
|
|
|
@param mouseX the mouse's X position relative to the component being monitored
|
|
@param mouseY the mouse's Y position relative to the component being monitored
|
|
*/
|
|
virtual void mouseHovered (int mouseX,
|
|
int mouseY) = 0;
|
|
|
|
/** Called when the mouse is moved away after just having hovered. */
|
|
virtual void mouseMovedAfterHover() = 0;
|
|
|
|
private:
|
|
|
|
class JUCE_API HoverDetectorInternal : public MouseListener,
|
|
public Timer
|
|
{
|
|
public:
|
|
MouseHoverDetector* owner;
|
|
int lastX, lastY;
|
|
|
|
void timerCallback();
|
|
void mouseEnter (const MouseEvent&);
|
|
void mouseExit (const MouseEvent&);
|
|
void mouseDown (const MouseEvent&);
|
|
void mouseUp (const MouseEvent&);
|
|
void mouseMove (const MouseEvent&);
|
|
void mouseWheelMove (const MouseEvent&, float, float);
|
|
|
|
} internalTimer;
|
|
|
|
friend class HoverDetectorInternal;
|
|
|
|
Component* source;
|
|
int hoverTimeMillisecs;
|
|
bool hasJustHovered;
|
|
|
|
void hoverTimerCallback();
|
|
void checkJustHoveredCallback();
|
|
};
|
|
|
|
#endif // __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__
|
|
/********* End of inlined file: juce_MouseHoverDetector.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MOUSELISTENER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_COMBOBOX_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_LABEL_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_LISTBOX_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_PROGRESSBAR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ProgressBar.h *********/
|
|
#ifndef __JUCE_PROGRESSBAR_JUCEHEADER__
|
|
#define __JUCE_PROGRESSBAR_JUCEHEADER__
|
|
|
|
/**
|
|
A progress bar component.
|
|
|
|
To use this, just create one and make it visible. It'll run its own timer
|
|
to keep an eye on a variable that you give it, and will automatically
|
|
redraw itself when the variable changes.
|
|
|
|
For an easy way of running a background task with a dialog box showing its
|
|
progress, see the ThreadWithProgressWindow class.
|
|
|
|
@see ThreadWithProgressWindow
|
|
*/
|
|
class JUCE_API ProgressBar : public Component,
|
|
public SettableTooltipClient,
|
|
private Timer
|
|
{
|
|
public:
|
|
|
|
/** Creates a ProgressBar.
|
|
|
|
@param progress pass in a reference to a double that you're going to
|
|
update with your task's progress. The ProgressBar will
|
|
monitor the value of this variable and will redraw itself
|
|
when the value changes. The range is from 0 to 1.0. Obviously
|
|
you'd better be careful not to delete this variable while the
|
|
ProgressBar still exists!
|
|
*/
|
|
ProgressBar (double& progress);
|
|
|
|
/** Destructor. */
|
|
~ProgressBar();
|
|
|
|
/** Turns the percentage display on or off.
|
|
|
|
By default this is on, and the progress bar will display a text string showing
|
|
its current percentage.
|
|
*/
|
|
void setPercentageDisplay (const bool shouldDisplayPercentage);
|
|
|
|
/** Gives the progress bar a string to display inside it.
|
|
|
|
If you call this, it will turn off the percentage display.
|
|
@see setPercentageDisplay
|
|
*/
|
|
void setTextToDisplay (const String& text);
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the bar.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1001900, /**< The background colour, behind the bar. */
|
|
foregroundColourId = 0x1001a00, /**< The colour to use to draw the bar itself. LookAndFeel
|
|
classes will probably use variations on this colour. */
|
|
};
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void lookAndFeelChanged();
|
|
/** @internal */
|
|
void visibilityChanged();
|
|
/** @internal */
|
|
void colourChanged();
|
|
|
|
private:
|
|
double& progress;
|
|
double currentValue;
|
|
bool displayPercentage;
|
|
String displayedMessage, currentMessage;
|
|
uint32 lastCallbackTime;
|
|
|
|
void timerCallback();
|
|
|
|
ProgressBar (const ProgressBar&);
|
|
const ProgressBar& operator= (const ProgressBar&);
|
|
};
|
|
|
|
#endif // __JUCE_PROGRESSBAR_JUCEHEADER__
|
|
/********* End of inlined file: juce_ProgressBar.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_SLIDER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_Slider.h *********/
|
|
#ifndef __JUCE_SLIDER_JUCEHEADER__
|
|
#define __JUCE_SLIDER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_SliderListener.h *********/
|
|
#ifndef __JUCE_SLIDERLISTENER_JUCEHEADER__
|
|
#define __JUCE_SLIDERLISTENER_JUCEHEADER__
|
|
|
|
class Slider;
|
|
|
|
/**
|
|
A class for receiving callbacks from a Slider.
|
|
|
|
To be told when a slider's value changes, you can register a SliderListener
|
|
object using Slider::addListener().
|
|
|
|
@see Slider::addListener, Slider::removeListener
|
|
*/
|
|
class JUCE_API SliderListener
|
|
{
|
|
public:
|
|
|
|
/** Destructor. */
|
|
virtual ~SliderListener() {}
|
|
|
|
/** Called when the slider's value is changed.
|
|
|
|
This may be caused by dragging it, or by typing in its text entry box,
|
|
or by a call to Slider::setValue().
|
|
|
|
You can find out the new value using Slider::getValue().
|
|
|
|
@see Slider::valueChanged
|
|
*/
|
|
virtual void sliderValueChanged (Slider* slider) = 0;
|
|
|
|
/** Called when the slider is about to be dragged.
|
|
|
|
This is called when a drag begins, then it's followed by multiple calls
|
|
to sliderValueChanged(), and then sliderDragEnded() is called after the
|
|
user lets go.
|
|
|
|
@see sliderDragEnded, Slider::startedDragging
|
|
*/
|
|
virtual void sliderDragStarted (Slider* slider);
|
|
|
|
/** Called after a drag operation has finished.
|
|
|
|
@see sliderDragStarted, Slider::stoppedDragging
|
|
*/
|
|
virtual void sliderDragEnded (Slider* slider);
|
|
};
|
|
|
|
#endif // __JUCE_SLIDERLISTENER_JUCEHEADER__
|
|
/********* End of inlined file: juce_SliderListener.h *********/
|
|
|
|
/**
|
|
A slider control for changing a value.
|
|
|
|
The slider can be horizontal, vertical, or rotary, and can optionally have
|
|
a text-box inside it to show an editable display of the current value.
|
|
|
|
To use it, create a Slider object and use the setSliderStyle() method
|
|
to set up the type you want. To set up the text-entry box, use setTextBoxStyle().
|
|
|
|
To define the values that it can be set to, see the setRange() and setValue() methods.
|
|
|
|
There are also lots of custom tweaks you can do by subclassing and overriding
|
|
some of the virtual methods, such as changing the scaling, changing the format of
|
|
the text display, custom ways of limiting the values, etc.
|
|
|
|
You can register SliderListeners with a slider, which will be informed when the value
|
|
changes, or a subclass can override valueChanged() to be informed synchronously.
|
|
|
|
@see SliderListener
|
|
*/
|
|
class JUCE_API Slider : public Component,
|
|
public SettableTooltipClient,
|
|
private AsyncUpdater,
|
|
private ButtonListener,
|
|
private LabelListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a slider.
|
|
|
|
When created, you'll need to set up the slider's style and range with setSliderStyle(),
|
|
setRange(), etc.
|
|
*/
|
|
Slider (const String& componentName);
|
|
|
|
/** Destructor. */
|
|
~Slider();
|
|
|
|
/** The types of slider available.
|
|
|
|
@see setSliderStyle, setRotaryParameters
|
|
*/
|
|
enum SliderStyle
|
|
{
|
|
LinearHorizontal, /**< A traditional horizontal slider. */
|
|
LinearVertical, /**< A traditional vertical slider. */
|
|
LinearBar, /**< A horizontal bar slider with the text label drawn on top of it. */
|
|
Rotary, /**< A rotary control that you move by dragging the mouse in a circular motion, like a knob.
|
|
@see setRotaryParameters */
|
|
RotaryHorizontalDrag, /**< A rotary control that you move by dragging the mouse left-to-right.
|
|
@see setRotaryParameters */
|
|
RotaryVerticalDrag, /**< A rotary control that you move by dragging the mouse up-and-down.
|
|
@see setRotaryParameters */
|
|
IncDecButtons, /**< A pair of buttons that increment or decrement the slider's value by the increment set in setRange(). */
|
|
|
|
TwoValueHorizontal, /**< A horizontal slider that has two thumbs instead of one, so it can show a minimum and maximum value.
|
|
@see setMinValue, setMaxValue */
|
|
TwoValueVertical, /**< A vertical slider that has two thumbs instead of one, so it can show a minimum and maximum value.
|
|
@see setMinValue, setMaxValue */
|
|
|
|
ThreeValueHorizontal, /**< A horizontal slider that has three thumbs instead of one, so it can show a minimum and maximum
|
|
value, with the current value being somewhere between them.
|
|
@see setMinValue, setMaxValue */
|
|
ThreeValueVertical, /**< A vertical slider that has three thumbs instead of one, so it can show a minimum and maximum
|
|
value, with the current value being somewhere between them.
|
|
@see setMinValue, setMaxValue */
|
|
};
|
|
|
|
/** Changes the type of slider interface being used.
|
|
|
|
@param newStyle the type of interface
|
|
@see setRotaryParameters, setVelocityBasedMode,
|
|
*/
|
|
void setSliderStyle (const SliderStyle newStyle);
|
|
|
|
/** Returns the slider's current style.
|
|
|
|
@see setSliderStyle
|
|
*/
|
|
SliderStyle getSliderStyle() const throw() { return style; }
|
|
|
|
/** Changes the properties of a rotary slider.
|
|
|
|
@param startAngleRadians the angle (in radians, clockwise from the top) at which
|
|
the slider's minimum value is represented
|
|
@param endAngleRadians the angle (in radians, clockwise from the top) at which
|
|
the slider's maximum value is represented. This must be
|
|
greater than startAngleRadians
|
|
@param stopAtEnd if true, then when the slider is dragged around past the
|
|
minimum or maximum, it'll stop there; if false, it'll wrap
|
|
back to the opposite value
|
|
*/
|
|
void setRotaryParameters (const float startAngleRadians,
|
|
const float endAngleRadians,
|
|
const bool stopAtEnd);
|
|
|
|
/** Sets the distance the mouse has to move to drag the slider across
|
|
the full extent of its range.
|
|
|
|
This only applies when in modes like RotaryHorizontalDrag, where it's using
|
|
relative mouse movements to adjust the slider.
|
|
*/
|
|
void setMouseDragSensitivity (const int distanceForFullScaleDrag);
|
|
|
|
/** Changes the way the the mouse is used when dragging the slider.
|
|
|
|
If true, this will turn on velocity-sensitive dragging, so that
|
|
the faster the mouse moves, the bigger the movement to the slider. This
|
|
helps when making accurate adjustments if the slider's range is quite large.
|
|
|
|
If false, the slider will just try to snap to wherever the mouse is.
|
|
*/
|
|
void setVelocityBasedMode (const bool isVelocityBased) throw();
|
|
|
|
/** Changes aspects of the scaling used when in velocity-sensitive mode.
|
|
|
|
These apply when you've used setVelocityBasedMode() to turn on velocity mode,
|
|
or if you're holding down ctrl.
|
|
|
|
@param sensitivity higher values than 1.0 increase the range of acceleration used
|
|
@param threshold the minimum number of pixels that the mouse needs to move for it
|
|
to be treated as a movement
|
|
@param offset values greater than 0.0 increase the minimum speed that will be used when
|
|
the threshold is reached
|
|
@param userCanPressKeyToSwapMode if true, then the user can hold down the ctrl or command
|
|
key to toggle velocity-sensitive mode
|
|
*/
|
|
void setVelocityModeParameters (const double sensitivity = 1.0,
|
|
const int threshold = 1,
|
|
const double offset = 0.0,
|
|
const bool userCanPressKeyToSwapMode = true) throw();
|
|
|
|
/** Sets up a skew factor to alter the way values are distributed.
|
|
|
|
You may want to use a range of values on the slider where more accuracy
|
|
is required towards one end of the range, so this will logarithmically
|
|
spread the values across the length of the slider.
|
|
|
|
If the factor is < 1.0, the lower end of the range will fill more of the
|
|
slider's length; if the factor is > 1.0, the upper end of the range
|
|
will be expanded instead. A factor of 1.0 doesn't skew it at all.
|
|
|
|
To set the skew position by using a mid-point, use the setSkewFactorFromMidPoint()
|
|
method instead.
|
|
|
|
@see getSkewFactor, setSkewFactorFromMidPoint
|
|
*/
|
|
void setSkewFactor (const double factor) throw();
|
|
|
|
/** Sets up a skew factor to alter the way values are distributed.
|
|
|
|
This allows you to specify the slider value that should appear in the
|
|
centre of the slider's visible range.
|
|
|
|
@see setSkewFactor, getSkewFactor
|
|
*/
|
|
void setSkewFactorFromMidPoint (const double sliderValueToShowAtMidPoint) throw();
|
|
|
|
/** Returns the current skew factor.
|
|
|
|
See setSkewFactor for more info.
|
|
|
|
@see setSkewFactor, setSkewFactorFromMidPoint
|
|
*/
|
|
double getSkewFactor() const throw() { return skewFactor; }
|
|
|
|
/** Used by setIncDecButtonsMode().
|
|
*/
|
|
enum IncDecButtonMode
|
|
{
|
|
incDecButtonsNotDraggable,
|
|
incDecButtonsDraggable_AutoDirection,
|
|
incDecButtonsDraggable_Horizontal,
|
|
incDecButtonsDraggable_Vertical
|
|
};
|
|
|
|
/** When the style is IncDecButtons, this lets you turn on a mode where the mouse
|
|
can be dragged on the buttons to drag the values.
|
|
|
|
By default this is turned off. When enabled, clicking on the buttons still works
|
|
them as normal, but by holding down the mouse on a button and dragging it a little
|
|
distance, it flips into a mode where the value can be dragged. The drag direction can
|
|
either be set explicitly to be vertical or horizontal, or can be set to
|
|
incDecButtonsDraggable_AutoDirection so that it depends on whether the buttons
|
|
are side-by-side or above each other.
|
|
*/
|
|
void setIncDecButtonsMode (const IncDecButtonMode mode);
|
|
|
|
/** The position of the slider's text-entry box.
|
|
|
|
@see setTextBoxStyle
|
|
*/
|
|
enum TextEntryBoxPosition
|
|
{
|
|
NoTextBox, /**< Doesn't display a text box. */
|
|
TextBoxLeft, /**< Puts the text box to the left of the slider, vertically centred. */
|
|
TextBoxRight, /**< Puts the text box to the right of the slider, vertically centred. */
|
|
TextBoxAbove, /**< Puts the text box above the slider, horizontally centred. */
|
|
TextBoxBelow /**< Puts the text box below the slider, horizontally centred. */
|
|
};
|
|
|
|
/** Changes the location and properties of the text-entry box.
|
|
|
|
@param newPosition where it should go (or NoTextBox to not have one at all)
|
|
@param isReadOnly if true, it's a read-only display
|
|
@param textEntryBoxWidth the width of the text-box in pixels. Make sure this leaves enough
|
|
room for the slider as well!
|
|
@param textEntryBoxHeight the height of the text-box in pixels. Make sure this leaves enough
|
|
room for the slider as well!
|
|
|
|
@see setTextBoxIsEditable, getValueFromText, getTextFromValue
|
|
*/
|
|
void setTextBoxStyle (const TextEntryBoxPosition newPosition,
|
|
const bool isReadOnly,
|
|
const int textEntryBoxWidth,
|
|
const int textEntryBoxHeight);
|
|
|
|
/** Returns the status of the text-box.
|
|
@see setTextBoxStyle
|
|
*/
|
|
const TextEntryBoxPosition getTextBoxPosition() const throw() { return textBoxPos; }
|
|
|
|
/** Returns the width used for the text-box.
|
|
@see setTextBoxStyle
|
|
*/
|
|
int getTextBoxWidth() const throw() { return textBoxWidth; }
|
|
|
|
/** Returns the height used for the text-box.
|
|
@see setTextBoxStyle
|
|
*/
|
|
int getTextBoxHeight() const throw() { return textBoxHeight; }
|
|
|
|
/** Makes the text-box editable.
|
|
|
|
By default this is true, and the user can enter values into the textbox,
|
|
but it can be turned off if that's not suitable.
|
|
|
|
@see setTextBoxStyle, getValueFromText, getTextFromValue
|
|
*/
|
|
void setTextBoxIsEditable (const bool shouldBeEditable) throw();
|
|
|
|
/** Returns true if the text-box is read-only.
|
|
@see setTextBoxStyle
|
|
*/
|
|
bool isTextBoxEditable() const throw() { return editableText; }
|
|
|
|
/** If the text-box is editable, this will give it the focus so that the user can
|
|
type directly into it.
|
|
|
|
This is basically the effect as the user clicking on it.
|
|
*/
|
|
void showTextBox();
|
|
|
|
/** If the text-box currently has focus and is being edited, this resets it and takes keyboard
|
|
focus away from it.
|
|
|
|
@param discardCurrentEditorContents if true, the slider's value will be left
|
|
unchanged; if false, the current contents of the
|
|
text editor will be used to set the slider position
|
|
before it is hidden.
|
|
*/
|
|
void hideTextBox (const bool discardCurrentEditorContents);
|
|
|
|
/** Changes the slider's current value.
|
|
|
|
This will trigger a callback to SliderListener::sliderValueChanged() for any listeners
|
|
that are registered, and will synchronously call the valueChanged() method in case subclasses
|
|
want to handle it.
|
|
|
|
@param newValue the new value to set - this will be restricted by the
|
|
minimum and maximum range, and will be snapped to the
|
|
nearest interval if one has been set
|
|
@param sendUpdateMessage if false, a change to the value will not trigger a call to
|
|
any SliderListeners or the valueChanged() method
|
|
@param sendMessageSynchronously if true, then a call to the SliderListeners will be made
|
|
synchronously; if false, it will be asynchronous
|
|
*/
|
|
void setValue (double newValue,
|
|
const bool sendUpdateMessage = true,
|
|
const bool sendMessageSynchronously = false);
|
|
|
|
/** Returns the slider's current value. */
|
|
double getValue() const throw();
|
|
|
|
/** Sets the limits that the slider's value can take.
|
|
|
|
@param newMinimum the lowest value allowed
|
|
@param newMaximum the highest value allowed
|
|
@param newInterval the steps in which the value is allowed to increase - if this
|
|
is not zero, the value will always be (newMinimum + (newInterval * an integer)).
|
|
*/
|
|
void setRange (const double newMinimum,
|
|
const double newMaximum,
|
|
const double newInterval = 0);
|
|
|
|
/** Returns the current maximum value.
|
|
@see setRange
|
|
*/
|
|
double getMaximum() const throw() { return maximum; }
|
|
|
|
/** Returns the current minimum value.
|
|
@see setRange
|
|
*/
|
|
double getMinimum() const throw() { return minimum; }
|
|
|
|
/** Returns the current step-size for values.
|
|
@see setRange
|
|
*/
|
|
double getInterval() const throw() { return interval; }
|
|
|
|
/** For a slider with two or three thumbs, this returns the lower of its values.
|
|
|
|
For a two-value slider, the values are controlled with getMinValue() and getMaxValue().
|
|
A slider with three values also uses the normal getValue() and setValue() methods to
|
|
control the middle value.
|
|
|
|
@see setMinValue, getMaxValue, TwoValueHorizontal, TwoValueVertical, ThreeValueHorizontal, ThreeValueVertical
|
|
*/
|
|
double getMinValue() const throw();
|
|
|
|
/** For a slider with two or three thumbs, this sets the lower of its values.
|
|
|
|
This will trigger a callback to SliderListener::sliderValueChanged() for any listeners
|
|
that are registered, and will synchronously call the valueChanged() method in case subclasses
|
|
want to handle it.
|
|
|
|
@param newValue the new value to set - this will be restricted by the
|
|
minimum and maximum range, and will be snapped to the nearest
|
|
interval if one has been set.
|
|
@param sendUpdateMessage if false, a change to the value will not trigger a call to
|
|
any SliderListeners or the valueChanged() method
|
|
@param sendMessageSynchronously if true, then a call to the SliderListeners will be made
|
|
synchronously; if false, it will be asynchronous
|
|
@param allowNudgingOfOtherValues if false, this value will be restricted to being below the
|
|
max value (in a two-value slider) or the mid value (in a three-value
|
|
slider). If false, then if this value goes beyond those values,
|
|
it will push them along with it.
|
|
@see getMinValue, setMaxValue, setValue
|
|
*/
|
|
void setMinValue (double newValue,
|
|
const bool sendUpdateMessage = true,
|
|
const bool sendMessageSynchronously = false,
|
|
const bool allowNudgingOfOtherValues = false);
|
|
|
|
/** For a slider with two or three thumbs, this returns the higher of its values.
|
|
|
|
For a two-value slider, the values are controlled with getMinValue() and getMaxValue().
|
|
A slider with three values also uses the normal getValue() and setValue() methods to
|
|
control the middle value.
|
|
|
|
@see getMinValue, TwoValueHorizontal, TwoValueVertical, ThreeValueHorizontal, ThreeValueVertical
|
|
*/
|
|
double getMaxValue() const throw();
|
|
|
|
/** For a slider with two or three thumbs, this sets the lower of its values.
|
|
|
|
This will trigger a callback to SliderListener::sliderValueChanged() for any listeners
|
|
that are registered, and will synchronously call the valueChanged() method in case subclasses
|
|
want to handle it.
|
|
|
|
@param newValue the new value to set - this will be restricted by the
|
|
minimum and maximum range, and will be snapped to the nearest
|
|
interval if one has been set.
|
|
@param sendUpdateMessage if false, a change to the value will not trigger a call to
|
|
any SliderListeners or the valueChanged() method
|
|
@param sendMessageSynchronously if true, then a call to the SliderListeners will be made
|
|
synchronously; if false, it will be asynchronous
|
|
@param allowNudgingOfOtherValues if false, this value will be restricted to being above the
|
|
min value (in a two-value slider) or the mid value (in a three-value
|
|
slider). If false, then if this value goes beyond those values,
|
|
it will push them along with it.
|
|
@see getMaxValue, setMinValue, setValue
|
|
*/
|
|
void setMaxValue (double newValue,
|
|
const bool sendUpdateMessage = true,
|
|
const bool sendMessageSynchronously = false,
|
|
const bool allowNudgingOfOtherValues = false);
|
|
|
|
/** Adds a listener to be called when this slider's value changes. */
|
|
void addListener (SliderListener* const listener) throw();
|
|
|
|
/** Removes a previously-registered listener. */
|
|
void removeListener (SliderListener* const listener) throw();
|
|
|
|
/** This lets you choose whether double-clicking moves the slider to a given position.
|
|
|
|
By default this is turned off, but it's handy if you want a double-click to act
|
|
as a quick way of resetting a slider. Just pass in the value you want it to
|
|
go to when double-clicked.
|
|
|
|
@see getDoubleClickReturnValue
|
|
*/
|
|
void setDoubleClickReturnValue (const bool isDoubleClickEnabled,
|
|
const double valueToSetOnDoubleClick) throw();
|
|
|
|
/** Returns the values last set by setDoubleClickReturnValue() method.
|
|
|
|
Sets isEnabled to true if double-click is enabled, and returns the value
|
|
that was set.
|
|
|
|
@see setDoubleClickReturnValue
|
|
*/
|
|
double getDoubleClickReturnValue (bool& isEnabled) const throw();
|
|
|
|
/** Tells the slider whether to keep sending change messages while the user
|
|
is dragging the slider.
|
|
|
|
If set to true, a change message will only be sent when the user has
|
|
dragged the slider and let go. If set to false (the default), then messages
|
|
will be continuously sent as they drag it while the mouse button is still
|
|
held down.
|
|
*/
|
|
void setChangeNotificationOnlyOnRelease (const bool onlyNotifyOnRelease) throw();
|
|
|
|
/** This lets you change whether the slider thumb jumps to the mouse position
|
|
when you click.
|
|
|
|
By default, this is true. If it's false, then the slider moves with relative
|
|
motion when you drag it.
|
|
|
|
This only applies to linear bars, and won't affect two- or three- value
|
|
sliders.
|
|
*/
|
|
void setSliderSnapsToMousePosition (const bool shouldSnapToMouse) throw();
|
|
|
|
/** If enabled, this gives the slider a pop-up bubble which appears while the
|
|
slider is being dragged.
|
|
|
|
This can be handy if your slider doesn't have a text-box, so that users can
|
|
see the value just when they're changing it.
|
|
|
|
If you pass a component as the parentComponentToUse parameter, the pop-up
|
|
bubble will be added as a child of that component when it's needed. If you
|
|
pass 0, the pop-up will be placed on the desktop instead (note that it's a
|
|
transparent window, so if you're using an OS that can't do transparent windows
|
|
you'll have to add it to a parent component instead).
|
|
*/
|
|
void setPopupDisplayEnabled (const bool isEnabled,
|
|
Component* const parentComponentToUse) throw();
|
|
|
|
/** If this is set to true, then right-clicking on the slider will pop-up
|
|
a menu to let the user change the way it works.
|
|
|
|
By default this is turned off, but when turned on, the menu will include
|
|
things like velocity sensitivity, and for rotary sliders, whether they
|
|
use a linear or rotary mouse-drag to move them.
|
|
*/
|
|
void setPopupMenuEnabled (const bool menuEnabled) throw();
|
|
|
|
/** This can be used to stop the mouse scroll-wheel from moving the slider.
|
|
|
|
By default it's enabled.
|
|
*/
|
|
void setScrollWheelEnabled (const bool enabled) throw();
|
|
|
|
/** Returns a number to indicate which thumb is currently being dragged by the
|
|
mouse.
|
|
|
|
This will return 0 for the main thumb, 1 for the minimum-value thumb, 2 for
|
|
the maximum-value thumb, or -1 if none is currently down.
|
|
*/
|
|
int getThumbBeingDragged() const throw() { return sliderBeingDragged; }
|
|
|
|
/** Callback to indicate that the user is about to start dragging the slider.
|
|
|
|
@see SliderListener::sliderDragStarted
|
|
*/
|
|
virtual void startedDragging();
|
|
|
|
/** Callback to indicate that the user has just stopped dragging the slider.
|
|
|
|
@see SliderListener::sliderDragEnded
|
|
*/
|
|
virtual void stoppedDragging();
|
|
|
|
/** Callback to indicate that the user has just moved the slider.
|
|
|
|
@see SliderListener::sliderValueChanged
|
|
*/
|
|
virtual void valueChanged();
|
|
|
|
/** Callback to indicate that the user has just moved the slider.
|
|
Note - the valueChanged() method has changed its format and now no longer has
|
|
any parameters. Update your code to use the new version.
|
|
This version has been left here with an int as its return value to cause
|
|
a syntax error if you've got existing code that uses the old version.
|
|
*/
|
|
virtual int valueChanged (double) { jassertfalse; return 0; }
|
|
|
|
/** Subclasses can override this to convert a text string to a value.
|
|
|
|
When the user enters something into the text-entry box, this method is
|
|
called to convert it to a value.
|
|
|
|
The default routine just tries to convert it to a double.
|
|
|
|
@see getTextFromValue
|
|
*/
|
|
virtual double getValueFromText (const String& text);
|
|
|
|
/** Turns the slider's current value into a text string.
|
|
|
|
Subclasses can override this to customise the formatting of the text-entry box.
|
|
|
|
The default implementation just turns the value into a string, using
|
|
a number of decimal places based on the range interval. If a suffix string
|
|
has been set using setTextValueSuffix(), this will be appended to the text.
|
|
|
|
@see getValueFromText
|
|
*/
|
|
virtual const String getTextFromValue (double value);
|
|
|
|
/** Sets a suffix to append to the end of the numeric value when it's displayed as
|
|
a string.
|
|
|
|
This is used by the default implementation of getTextFromValue(), and is just
|
|
appended to the numeric value. For more advanced formatting, you can override
|
|
getTextFromValue() and do something else.
|
|
*/
|
|
void setTextValueSuffix (const String& suffix);
|
|
|
|
/** Allows a user-defined mapping of distance along the slider to its value.
|
|
|
|
The default implementation for this performs the skewing operation that
|
|
can be set up in the setSkewFactor() method. Override it if you need
|
|
some kind of custom mapping instead, but make sure you also implement the
|
|
inverse function in valueToProportionOfLength().
|
|
|
|
@param proportion a value 0 to 1.0, indicating a distance along the slider
|
|
@returns the slider value that is represented by this position
|
|
@see valueToProportionOfLength
|
|
*/
|
|
virtual double proportionOfLengthToValue (double proportion);
|
|
|
|
/** Allows a user-defined mapping of value to the position of the slider along its length.
|
|
|
|
The default implementation for this performs the skewing operation that
|
|
can be set up in the setSkewFactor() method. Override it if you need
|
|
some kind of custom mapping instead, but make sure you also implement the
|
|
inverse function in proportionOfLengthToValue().
|
|
|
|
@param value a valid slider value, between the range of values specified in
|
|
setRange()
|
|
@returns a value 0 to 1.0 indicating the distance along the slider that
|
|
represents this value
|
|
@see proportionOfLengthToValue
|
|
*/
|
|
virtual double valueToProportionOfLength (double value);
|
|
|
|
/** Returns the X or Y coordinate of a value along the slider's length.
|
|
|
|
If the slider is horizontal, this will be the X coordinate of the given
|
|
value, relative to the left of the slider. If it's vertical, then this will
|
|
be the Y coordinate, relative to the top of the slider.
|
|
|
|
If the slider is rotary, this will throw an assertion and return 0. If the
|
|
value is out-of-range, it will be constrained to the length of the slider.
|
|
*/
|
|
float getPositionOfValue (const double value);
|
|
|
|
/** This can be overridden to allow the slider to snap to user-definable values.
|
|
|
|
If overridden, it will be called when the user tries to move the slider to
|
|
a given position, and allows a subclass to sanity-check this value, possibly
|
|
returning a different value to use instead.
|
|
|
|
@param attemptedValue the value the user is trying to enter
|
|
@param userIsDragging true if the user is dragging with the mouse; false if
|
|
they are entering the value using the text box
|
|
@returns the value to use instead
|
|
*/
|
|
virtual double snapValue (double attemptedValue, const bool userIsDragging);
|
|
|
|
/** This can be called to force the text box to update its contents.
|
|
|
|
(Not normally needed, as this is done automatically).
|
|
*/
|
|
void updateText();
|
|
|
|
/** True if the slider moves horizontally. */
|
|
bool isHorizontal() const throw();
|
|
/** True if the slider moves vertically. */
|
|
bool isVertical() const throw();
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the slider.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1001200, /**< A colour to use to fill the slider's background. */
|
|
thumbColourId = 0x1001300, /**< The colour to draw the thumb with. It's up to the look
|
|
and feel class how this is used. */
|
|
trackColourId = 0x1001310, /**< The colour to draw the groove that the thumb moves along. */
|
|
rotarySliderFillColourId = 0x1001311, /**< For rotary sliders, this colour fills the outer curve. */
|
|
rotarySliderOutlineColourId = 0x1001312, /**< For rotary sliders, this colour is used to draw the outer curve's outline. */
|
|
|
|
textBoxTextColourId = 0x1001400, /**< The colour for the text in the text-editor box used for editing the value. */
|
|
textBoxBackgroundColourId = 0x1001500, /**< The background colour for the text-editor box. */
|
|
textBoxHighlightColourId = 0x1001600, /**< The text highlight colour for the text-editor box. */
|
|
textBoxOutlineColourId = 0x1001700 /**< The colour to use for a border around the text-editor box. */
|
|
};
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void labelTextChanged (Label*);
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseUp (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDoubleClick (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
|
|
/** @internal */
|
|
void modifierKeysChanged (const ModifierKeys& modifiers);
|
|
/** @internal */
|
|
void buttonClicked (Button* button);
|
|
/** @internal */
|
|
void lookAndFeelChanged();
|
|
/** @internal */
|
|
void enablementChanged();
|
|
/** @internal */
|
|
void focusOfChildComponentChanged (FocusChangeType cause);
|
|
/** @internal */
|
|
void handleAsyncUpdate();
|
|
/** @internal */
|
|
void colourChanged();
|
|
|
|
private:
|
|
SortedSet <void*> listeners;
|
|
double currentValue, valueMin, valueMax;
|
|
double minimum, maximum, interval, doubleClickReturnValue;
|
|
double valueWhenLastDragged, valueOnMouseDown, skewFactor, lastAngle;
|
|
double velocityModeSensitivity, velocityModeOffset, minMaxDiff;
|
|
int velocityModeThreshold;
|
|
float rotaryStart, rotaryEnd;
|
|
int numDecimalPlaces, mouseXWhenLastDragged, mouseYWhenLastDragged;
|
|
int mouseDragStartX, mouseDragStartY;
|
|
int sliderRegionStart, sliderRegionSize;
|
|
int sliderBeingDragged;
|
|
int pixelsForFullDragExtent;
|
|
Rectangle sliderRect;
|
|
String textSuffix;
|
|
|
|
SliderStyle style;
|
|
TextEntryBoxPosition textBoxPos;
|
|
int textBoxWidth, textBoxHeight;
|
|
IncDecButtonMode incDecButtonMode;
|
|
|
|
bool editableText : 1, doubleClickToValue : 1;
|
|
bool isVelocityBased : 1, userKeyOverridesVelocity : 1, rotaryStop : 1;
|
|
bool incDecButtonsSideBySide : 1, sendChangeOnlyOnRelease : 1, popupDisplayEnabled : 1;
|
|
bool menuEnabled : 1, menuShown : 1, mouseWasHidden : 1, incDecDragged : 1;
|
|
bool scrollWheelEnabled : 1, snapsToMousePos : 1;
|
|
Font font;
|
|
Label* valueBox;
|
|
Button* incButton;
|
|
Button* decButton;
|
|
Component* popupDisplay;
|
|
Component* parentForPopupDisplay;
|
|
|
|
float getLinearSliderPos (const double value);
|
|
void restoreMouseIfHidden();
|
|
void sendDragStart();
|
|
void sendDragEnd();
|
|
double constrainedValue (double value) const throw();
|
|
void triggerChangeMessage (const bool synchronous);
|
|
bool incDecDragDirectionIsHorizontal() const throw();
|
|
|
|
Slider (const Slider&);
|
|
const Slider& operator= (const Slider&);
|
|
};
|
|
|
|
#endif // __JUCE_SLIDER_JUCEHEADER__
|
|
/********* End of inlined file: juce_Slider.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_SLIDERLISTENER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_TableHeaderComponent.h *********/
|
|
#ifndef __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__
|
|
|
|
class TableHeaderComponent;
|
|
|
|
/**
|
|
Receives events from a TableHeaderComponent when columns are resized, moved, etc.
|
|
|
|
You can register one of these objects for table events using TableHeaderComponent::addListener()
|
|
and TableHeaderComponent::removeListener().
|
|
|
|
@see TableHeaderComponent
|
|
*/
|
|
class JUCE_API TableHeaderListener
|
|
{
|
|
public:
|
|
|
|
TableHeaderListener() {}
|
|
|
|
/** Destructor. */
|
|
virtual ~TableHeaderListener() {}
|
|
|
|
/** This is called when some of the table's columns are added, removed, hidden,
|
|
or rearranged.
|
|
*/
|
|
virtual void tableColumnsChanged (TableHeaderComponent* tableHeader) = 0;
|
|
|
|
/** This is called when one or more of the table's columns are resized.
|
|
*/
|
|
virtual void tableColumnsResized (TableHeaderComponent* tableHeader) = 0;
|
|
|
|
/** This is called when the column by which the table should be sorted is changed.
|
|
*/
|
|
virtual void tableSortOrderChanged (TableHeaderComponent* tableHeader) = 0;
|
|
|
|
/** This is called when the user begins or ends dragging one of the columns around.
|
|
|
|
When the user starts dragging a column, this is called with the ID of that
|
|
column. When they finish dragging, it is called again with 0 as the ID.
|
|
*/
|
|
virtual void tableColumnDraggingChanged (TableHeaderComponent* tableHeader,
|
|
int columnIdNowBeingDragged);
|
|
};
|
|
|
|
/**
|
|
A component that displays a strip of column headings for a table, and allows these
|
|
to be resized, dragged around, etc.
|
|
|
|
This is just the component that goes at the top of a table. You can use it
|
|
directly for custom components, or to create a simple table, use the
|
|
TableListBox class.
|
|
|
|
To use one of these, create it and use addColumn() to add all the columns that you need.
|
|
Each column must be given a unique ID number that's used to refer to it.
|
|
|
|
@see TableListBox, TableHeaderListener
|
|
*/
|
|
class JUCE_API TableHeaderComponent : public Component,
|
|
private AsyncUpdater
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty table header.
|
|
*/
|
|
TableHeaderComponent();
|
|
|
|
/** Destructor. */
|
|
~TableHeaderComponent();
|
|
|
|
/** A combination of these flags are passed into the addColumn() method to specify
|
|
the properties of a column.
|
|
*/
|
|
enum ColumnPropertyFlags
|
|
{
|
|
visible = 1, /**< If this is set, the column will be shown; if not, it will be hidden until the user enables it with the pop-up menu. */
|
|
resizable = 2, /**< If this is set, the column can be resized by dragging it. */
|
|
draggable = 4, /**< If this is set, the column can be dragged around to change its order in the table. */
|
|
appearsOnColumnMenu = 8, /**< If this is set, the column will be shown on the pop-up menu allowing it to be hidden/shown. */
|
|
sortable = 16, /**< If this is set, then clicking on the column header will set it to be the sort column, and clicking again will reverse the order. */
|
|
sortedForwards = 32, /**< If this is set, the column is currently the one by which the table is sorted (forwards). */
|
|
sortedBackwards = 64, /**< If this is set, the column is currently the one by which the table is sorted (backwards). */
|
|
|
|
/** This set of default flags is used as the default parameter value in addColumn(). */
|
|
defaultFlags = (visible | resizable | draggable | appearsOnColumnMenu | sortable),
|
|
|
|
/** A quick way of combining flags for a column that's not resizable. */
|
|
notResizable = (visible | draggable | appearsOnColumnMenu | sortable),
|
|
|
|
/** A quick way of combining flags for a column that's not resizable or sortable. */
|
|
notResizableOrSortable = (visible | draggable | appearsOnColumnMenu),
|
|
|
|
/** A quick way of combining flags for a column that's not sortable. */
|
|
notSortable = (visible | resizable | draggable | appearsOnColumnMenu)
|
|
};
|
|
|
|
/** Adds a column to the table.
|
|
|
|
This will add a column, and asynchronously call the tableColumnsChanged() method of any
|
|
registered listeners.
|
|
|
|
@param columnName the name of the new column. It's ok to have two or more columns with the same name
|
|
@param columnId an ID for this column. The ID can be any number apart from 0, but every column must have
|
|
a unique ID. This is used to identify the column later on, after the user may have
|
|
changed the order that they appear in
|
|
@param width the initial width of the column, in pixels
|
|
@param maximumWidth a maximum width that the column can take when the user is resizing it. This only applies
|
|
if the 'resizable' flag is specified for this column
|
|
@param minimumWidth a minimum width that the column can take when the user is resizing it. This only applies
|
|
if the 'resizable' flag is specified for this column
|
|
@param propertyFlags a combination of some of the values from the ColumnPropertyFlags enum, to define the
|
|
properties of this column
|
|
@param insertIndex the index at which the column should be added. A value of 0 puts it at the start (left-hand side)
|
|
and -1 puts it at the end (right-hand size) of the table. Note that the index the index within
|
|
all columns, not just the index amongst those that are currently visible
|
|
*/
|
|
void addColumn (const String& columnName,
|
|
const int columnId,
|
|
const int width,
|
|
const int minimumWidth = 30,
|
|
const int maximumWidth = -1,
|
|
const int propertyFlags = defaultFlags,
|
|
const int insertIndex = -1);
|
|
|
|
/** Removes a column with the given ID.
|
|
|
|
If there is such a column, this will asynchronously call the tableColumnsChanged() method of any
|
|
registered listeners.
|
|
*/
|
|
void removeColumn (const int columnIdToRemove);
|
|
|
|
/** Deletes all columns from the table.
|
|
|
|
If there are any columns to remove, this will asynchronously call the tableColumnsChanged() method of any
|
|
registered listeners.
|
|
*/
|
|
void removeAllColumns();
|
|
|
|
/** Returns the number of columns in the table.
|
|
|
|
If onlyCountVisibleColumns is true, this will return the number of visible columns; otherwise it'll
|
|
return the total number of columns, including hidden ones.
|
|
|
|
@see isColumnVisible
|
|
*/
|
|
int getNumColumns (const bool onlyCountVisibleColumns) const throw();
|
|
|
|
/** Returns the name for a column.
|
|
@see setColumnName
|
|
*/
|
|
const String getColumnName (const int columnId) const throw();
|
|
|
|
/** Changes the name of a column. */
|
|
void setColumnName (const int columnId, const String& newName);
|
|
|
|
/** Moves a column to a different index in the table.
|
|
|
|
@param columnId the column to move
|
|
@param newVisibleIndex the target index for it, from 0 to the number of columns currently visible.
|
|
*/
|
|
void moveColumn (const int columnId, int newVisibleIndex);
|
|
|
|
/** Changes the width of a column.
|
|
|
|
This will cause an asynchronous callback to the tableColumnsResized() method of any registered listeners.
|
|
*/
|
|
void setColumnWidth (const int columnId, const int newWidth);
|
|
|
|
/** Shows or hides a column.
|
|
|
|
This can cause an asynchronous callback to the tableColumnsChanged() method of any registered listeners.
|
|
@see isColumnVisible
|
|
*/
|
|
void setColumnVisible (const int columnId, const bool shouldBeVisible);
|
|
|
|
/** Returns true if this column is currently visible.
|
|
@see setColumnVisible
|
|
*/
|
|
bool isColumnVisible (const int columnId) const;
|
|
|
|
/** Changes the column which is the sort column.
|
|
|
|
This can cause an asynchronous callback to the tableSortOrderChanged() method of any registered listeners.
|
|
|
|
If this method doesn't actually change the column ID, then no re-sort will take place (you can
|
|
call reSortTable() to force a re-sort to happen if you've modified the table's contents).
|
|
|
|
@see getSortColumnId, isSortedForwards, reSortTable
|
|
*/
|
|
void setSortColumnId (const int columnId, const bool sortForwards);
|
|
|
|
/** Returns the column ID by which the table is currently sorted, or 0 if it is unsorted.
|
|
|
|
@see setSortColumnId, isSortedForwards
|
|
*/
|
|
int getSortColumnId() const throw();
|
|
|
|
/** Returns true if the table is currently sorted forwards, or false if it's backwards.
|
|
@see setSortColumnId
|
|
*/
|
|
bool isSortedForwards() const throw();
|
|
|
|
/** Triggers a re-sort of the table according to the current sort-column.
|
|
|
|
If you modifiy the table's contents, you can call this to signal that the table needs
|
|
to be re-sorted.
|
|
|
|
(This doesn't do any sorting synchronously - it just asynchronously sends a call to the
|
|
tableSortOrderChanged() method of any listeners).
|
|
*/
|
|
void reSortTable();
|
|
|
|
/** Returns the total width of all the visible columns in the table.
|
|
*/
|
|
int getTotalWidth() const throw();
|
|
|
|
/** Returns the index of a given column.
|
|
|
|
If there's no such column ID, this will return -1.
|
|
|
|
If onlyCountVisibleColumns is true, this will return the index amoungst the visible columns;
|
|
otherwise it'll return the index amongst all the columns, including any hidden ones.
|
|
*/
|
|
int getIndexOfColumnId (const int columnId, const bool onlyCountVisibleColumns) const throw();
|
|
|
|
/** Returns the ID of the column at a given index.
|
|
|
|
If onlyCountVisibleColumns is true, this will count the index amoungst the visible columns;
|
|
otherwise it'll count it amongst all the columns, including any hidden ones.
|
|
|
|
If the index is out-of-range, it'll return 0.
|
|
*/
|
|
int getColumnIdOfIndex (int index, const bool onlyCountVisibleColumns) const throw();
|
|
|
|
/** Returns the rectangle containing of one of the columns.
|
|
|
|
The index is an index from 0 to the number of columns that are currently visible (hidden
|
|
ones are not counted). It returns a rectangle showing the position of the column relative
|
|
to this component's top-left. If the index is out-of-range, an empty rectangle is retrurned.
|
|
*/
|
|
const Rectangle getColumnPosition (const int index) const throw();
|
|
|
|
/** Finds the column ID at a given x-position in the component.
|
|
|
|
If there is a column at this point this returns its ID, or if not, it will return 0.
|
|
*/
|
|
int getColumnIdAtX (const int xToFind) const throw();
|
|
|
|
/** If set to true, this indicates that the columns should be expanded or shrunk to fill the
|
|
entire width of the component.
|
|
|
|
By default this is disabled. Turning it on also means that when resizing a column, those
|
|
on the right will be squashed to fit.
|
|
*/
|
|
void setStretchToFitActive (const bool shouldStretchToFit);
|
|
|
|
/** Returns true if stretch-to-fit has been enabled.
|
|
@see setStretchToFitActive
|
|
*/
|
|
bool isStretchToFitActive() const throw();
|
|
|
|
/** If stretch-to-fit is enabled, this will resize all the columns to make them fit into the
|
|
specified width, keeping their relative proportions the same.
|
|
|
|
If the minimum widths of the columns are too wide to fit into this space, it may
|
|
actually end up wider.
|
|
*/
|
|
void resizeAllColumnsToFit (int targetTotalWidth);
|
|
|
|
/** Enables or disables the pop-up menu.
|
|
|
|
The default menu allows the user to show or hide columns. You can add custom
|
|
items to this menu by overloading the addMenuItems() and reactToMenuItem() methods.
|
|
|
|
By default the menu is enabled.
|
|
|
|
@see isPopupMenuActive, addMenuItems, reactToMenuItem
|
|
*/
|
|
void setPopupMenuActive (const bool hasMenu);
|
|
|
|
/** Returns true if the pop-up menu is enabled.
|
|
@see setPopupMenuActive
|
|
*/
|
|
bool isPopupMenuActive() const throw();
|
|
|
|
/** Returns a string that encapsulates the table's current layout.
|
|
|
|
This can be restored later using restoreFromString(). It saves the order of
|
|
the columns, the currently-sorted column, and the widths.
|
|
|
|
@see restoreFromString
|
|
*/
|
|
const String toString() const;
|
|
|
|
/** Restores the state of the table, based on a string previously created with
|
|
toString().
|
|
|
|
@see toString
|
|
*/
|
|
void restoreFromString (const String& storedVersion);
|
|
|
|
/** Adds a listener to be informed about things that happen to the header. */
|
|
void addListener (TableHeaderListener* const newListener) throw();
|
|
|
|
/** Removes a previously-registered listener. */
|
|
void removeListener (TableHeaderListener* const listenerToRemove) throw();
|
|
|
|
/** This can be overridden to handle a mouse-click on one of the column headers.
|
|
|
|
The default implementation will use this click to call getSortColumnId() and
|
|
change the sort order.
|
|
*/
|
|
virtual void columnClicked (int columnId, const ModifierKeys& mods);
|
|
|
|
/** This can be overridden to add custom items to the pop-up menu.
|
|
|
|
If you override this, you should call the superclass's method to add its
|
|
column show/hide items, if you want them on the menu as well.
|
|
|
|
Then to handle the result, override reactToMenuItem().
|
|
|
|
@see reactToMenuItem
|
|
*/
|
|
virtual void addMenuItems (PopupMenu& menu, const int columnIdClicked);
|
|
|
|
/** Override this to handle any custom items that you have added to the
|
|
pop-up menu with an addMenuItems() override.
|
|
|
|
If the menuReturnId isn't one of your own custom menu items, you'll need to
|
|
call TableHeaderComponent::reactToMenuItem() to allow the base class to
|
|
handle the items that it had added.
|
|
|
|
@see addMenuItems
|
|
*/
|
|
virtual void reactToMenuItem (const int menuReturnId, const int columnIdClicked);
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void mouseMove (const MouseEvent&);
|
|
/** @internal */
|
|
void mouseEnter (const MouseEvent&);
|
|
/** @internal */
|
|
void mouseExit (const MouseEvent&);
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent&);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent&);
|
|
/** @internal */
|
|
void mouseUp (const MouseEvent&);
|
|
/** @internal */
|
|
const MouseCursor getMouseCursor();
|
|
|
|
/** Can be overridden for more control over the pop-up menu behaviour. */
|
|
virtual void showColumnChooserMenu (const int columnIdClicked);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
struct ColumnInfo
|
|
{
|
|
String name;
|
|
int id, propertyFlags, width, minimumWidth, maximumWidth;
|
|
double lastDeliberateWidth;
|
|
|
|
bool isVisible() const throw();
|
|
};
|
|
|
|
OwnedArray <ColumnInfo> columns;
|
|
Array <TableHeaderListener*> listeners;
|
|
Component* dragOverlayComp;
|
|
|
|
bool columnsChanged, columnsResized, sortChanged, menuActive, stretchToFit;
|
|
int columnIdBeingResized, columnIdBeingDragged, initialColumnWidth;
|
|
int columnIdUnderMouse, draggingColumnOffset, draggingColumnOriginalIndex, lastDeliberateWidth;
|
|
|
|
ColumnInfo* getInfoForId (const int columnId) const throw();
|
|
int visibleIndexToTotalIndex (const int visibleIndex) const throw();
|
|
void sendColumnsChanged();
|
|
void handleAsyncUpdate();
|
|
void beginDrag (const MouseEvent&);
|
|
void endDrag (const int finalIndex);
|
|
int getResizeDraggerAt (const int mouseX) const throw();
|
|
void updateColumnUnderMouse (int x, int y);
|
|
void resizeColumnsToFit (int firstColumnIndex, int targetTotalWidth);
|
|
|
|
TableHeaderComponent (const TableHeaderComponent&);
|
|
const TableHeaderComponent operator= (const TableHeaderComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_TableHeaderComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TABLELISTBOX_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_TableListBox.h *********/
|
|
#ifndef __JUCE_TABLELISTBOX_JUCEHEADER__
|
|
#define __JUCE_TABLELISTBOX_JUCEHEADER__
|
|
|
|
/**
|
|
One of these is used by a TableListBox as the data model for the table's contents.
|
|
|
|
The virtual methods that you override in this class take care of drawing the
|
|
table cells, and reacting to events.
|
|
|
|
@see TableListBox
|
|
*/
|
|
class JUCE_API TableListBoxModel
|
|
{
|
|
public:
|
|
|
|
TableListBoxModel() {}
|
|
|
|
/** Destructor. */
|
|
virtual ~TableListBoxModel() {}
|
|
|
|
/** This must return the number of rows currently in the table.
|
|
|
|
If the number of rows changes, you must call TableListBox::updateContent() to
|
|
cause it to refresh the list.
|
|
*/
|
|
virtual int getNumRows() = 0;
|
|
|
|
/** This must draw the background behind one of the rows in the table.
|
|
|
|
The graphics context has its origin at the row's top-left, and your method
|
|
should fill the area specified by the width and height parameters.
|
|
*/
|
|
virtual void paintRowBackground (Graphics& g,
|
|
int rowNumber,
|
|
int width, int height,
|
|
bool rowIsSelected) = 0;
|
|
|
|
/** This must draw one of the cells.
|
|
|
|
The graphics context's origin will already be set to the top-left of the cell,
|
|
whose size is specified by (width, height).
|
|
*/
|
|
virtual void paintCell (Graphics& g,
|
|
int rowNumber,
|
|
int columnId,
|
|
int width, int height,
|
|
bool rowIsSelected) = 0;
|
|
|
|
/** This is used to create or update a custom component to go in a cell.
|
|
|
|
Any cell may contain a custom component, or can just be drawn with the paintCell() method
|
|
and handle mouse clicks with cellClicked().
|
|
|
|
This method will be called whenever a custom component might need to be updated - e.g.
|
|
when the table is changed, or TableListBox::updateContent() is called.
|
|
|
|
If you don't need a custom component for the specified cell, then return 0.
|
|
|
|
If you do want a custom component, and the existingComponentToUpdate is null, then
|
|
this method must create a new component suitable for the cell, and return it.
|
|
|
|
If the existingComponentToUpdate is non-null, it will be a pointer to a component previously created
|
|
by this method. In this case, the method must either update it to make sure it's correctly representing
|
|
the given cell (which may be different from the one that the component was created for), or it can
|
|
delete this component and return a new one.
|
|
*/
|
|
virtual Component* refreshComponentForCell (int rowNumber, int columnId, bool isRowSelected,
|
|
Component* existingComponentToUpdate);
|
|
|
|
/** This callback is made when the user clicks on one of the cells in the table.
|
|
|
|
The mouse event's coordinates will be relative to the entire table row.
|
|
@see cellDoubleClicked, backgroundClicked
|
|
*/
|
|
virtual void cellClicked (int rowNumber, int columnId, const MouseEvent& e);
|
|
|
|
/** This callback is made when the user clicks on one of the cells in the table.
|
|
|
|
The mouse event's coordinates will be relative to the entire table row.
|
|
@see cellClicked, backgroundClicked
|
|
*/
|
|
virtual void cellDoubleClicked (int rowNumber, int columnId, const MouseEvent& e);
|
|
|
|
/** This can be overridden to react to the user double-clicking on a part of the list where
|
|
there are no rows.
|
|
|
|
@see cellClicked
|
|
*/
|
|
virtual void backgroundClicked();
|
|
|
|
/** This callback is made when the table's sort order is changed.
|
|
|
|
This could be because the user has clicked a column header, or because the
|
|
TableHeaderComponent::setSortColumnId() method was called.
|
|
|
|
If you implement this, your method should re-sort the table using the given
|
|
column as the key.
|
|
*/
|
|
virtual void sortOrderChanged (int newSortColumnId, const bool isForwards);
|
|
|
|
/** Returns the best width for one of the columns.
|
|
|
|
If you implement this method, you should measure the width of all the items
|
|
in this column, and return the best size.
|
|
|
|
Returning 0 means that the column shouldn't be changed.
|
|
|
|
This is used by TableListBox::autoSizeColumn() and TableListBox::autoSizeAllColumns().
|
|
*/
|
|
virtual int getColumnAutoSizeWidth (int columnId);
|
|
|
|
/** Override this to be informed when rows are selected or deselected.
|
|
|
|
@see ListBox::selectedRowsChanged()
|
|
*/
|
|
virtual void selectedRowsChanged (int lastRowSelected);
|
|
|
|
/** Override this to be informed when the delete key is pressed.
|
|
|
|
@see ListBox::deleteKeyPressed()
|
|
*/
|
|
virtual void deleteKeyPressed (int lastRowSelected);
|
|
|
|
/** Override this to be informed when the return key is pressed.
|
|
|
|
@see ListBox::returnKeyPressed()
|
|
*/
|
|
virtual void returnKeyPressed (int lastRowSelected);
|
|
|
|
/** Override this to be informed when the list is scrolled.
|
|
|
|
This might be caused by the user moving the scrollbar, or by programmatic changes
|
|
to the list position.
|
|
*/
|
|
virtual void listWasScrolled();
|
|
|
|
/** To allow rows from your table to be dragged-and-dropped, implement this method.
|
|
|
|
If this returns a non-empty name then when the user drags a row, the table will try to
|
|
find a DragAndDropContainer in its parent hierarchy, and will use it to trigger a
|
|
drag-and-drop operation, using this string as the source description, and the listbox
|
|
itself as the source component.
|
|
|
|
@see DragAndDropContainer::startDragging
|
|
*/
|
|
virtual const String getDragSourceDescription (const SparseSet<int>& currentlySelectedRows);
|
|
};
|
|
|
|
/**
|
|
A table of cells, using a TableHeaderComponent as its header.
|
|
|
|
This component makes it easy to create a table by providing a TableListBoxModel as
|
|
the data source.
|
|
|
|
@see TableListBoxModel, TableHeaderComponent
|
|
*/
|
|
class JUCE_API TableListBox : public ListBox,
|
|
private ListBoxModel,
|
|
private TableHeaderListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a TableListBox.
|
|
|
|
The model pointer passed-in can be null, in which case you can set it later
|
|
with setModel().
|
|
*/
|
|
TableListBox (const String& componentName,
|
|
TableListBoxModel* const model);
|
|
|
|
/** Destructor. */
|
|
~TableListBox();
|
|
|
|
/** Changes the TableListBoxModel that is being used for this table.
|
|
*/
|
|
void setModel (TableListBoxModel* const newModel);
|
|
|
|
/** Returns the model currently in use. */
|
|
TableListBoxModel* getModel() const throw() { return model; }
|
|
|
|
/** Returns the header component being used in this table. */
|
|
TableHeaderComponent* getHeader() const throw() { return header; }
|
|
|
|
/** Changes the height of the table header component.
|
|
@see getHeaderHeight
|
|
*/
|
|
void setHeaderHeight (const int newHeight);
|
|
|
|
/** Returns the height of the table header.
|
|
@see setHeaderHeight
|
|
*/
|
|
int getHeaderHeight() const throw();
|
|
|
|
/** Resizes a column to fit its contents.
|
|
|
|
This uses TableListBoxModel::getColumnAutoSizeWidth() to find the best width,
|
|
and applies that to the column.
|
|
|
|
@see autoSizeAllColumns, TableHeaderComponent::setColumnWidth
|
|
*/
|
|
void autoSizeColumn (const int columnId);
|
|
|
|
/** Calls autoSizeColumn() for all columns in the table. */
|
|
void autoSizeAllColumns();
|
|
|
|
/** Enables or disables the auto size options on the popup menu.
|
|
|
|
By default, these are enabled.
|
|
*/
|
|
void setAutoSizeMenuOptionShown (const bool shouldBeShown);
|
|
|
|
/** True if the auto-size options should be shown on the menu.
|
|
@see setAutoSizeMenuOptionsShown
|
|
*/
|
|
bool isAutoSizeMenuOptionShown() const throw();
|
|
|
|
/** Returns the position of one of the cells in the table.
|
|
|
|
If relativeToComponentTopLeft is true, the co-ordinates are relative to
|
|
the table component's top-left. The row number isn't checked to see if it's
|
|
in-range, but the column ID must exist or this will return an empty rectangle.
|
|
|
|
If relativeToComponentTopLeft is false, the co-ords are relative to the
|
|
top-left of the table's top-left cell.
|
|
*/
|
|
const Rectangle getCellPosition (const int columnId,
|
|
const int rowNumber,
|
|
const bool relativeToComponentTopLeft) const;
|
|
|
|
/** Scrolls horizontally if necessary to make sure that a particular column is visible.
|
|
|
|
@see ListBox::scrollToEnsureRowIsOnscreen
|
|
*/
|
|
void scrollToEnsureColumnIsOnscreen (const int columnId);
|
|
|
|
/** @internal */
|
|
int getNumRows();
|
|
/** @internal */
|
|
void paintListBoxItem (int, Graphics&, int, int, bool);
|
|
/** @internal */
|
|
Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate);
|
|
/** @internal */
|
|
void selectedRowsChanged (int lastRowSelected);
|
|
/** @internal */
|
|
void deleteKeyPressed (int currentSelectedRow);
|
|
/** @internal */
|
|
void returnKeyPressed (int currentSelectedRow);
|
|
/** @internal */
|
|
void backgroundClicked();
|
|
/** @internal */
|
|
void listWasScrolled();
|
|
/** @internal */
|
|
void tableColumnsChanged (TableHeaderComponent*);
|
|
/** @internal */
|
|
void tableColumnsResized (TableHeaderComponent*);
|
|
/** @internal */
|
|
void tableSortOrderChanged (TableHeaderComponent*);
|
|
/** @internal */
|
|
void tableColumnDraggingChanged (TableHeaderComponent*, int);
|
|
/** @internal */
|
|
void resized();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
TableHeaderComponent* header;
|
|
TableListBoxModel* model;
|
|
int columnIdNowBeingDragged;
|
|
bool autoSizeOptionsShown;
|
|
|
|
void updateColumnComponents() const;
|
|
|
|
TableListBox (const TableListBox&);
|
|
const TableListBox& operator= (const TableListBox&);
|
|
};
|
|
|
|
#endif // __JUCE_TABLELISTBOX_JUCEHEADER__
|
|
/********* End of inlined file: juce_TableListBox.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_TOOLBAR_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ToolbarItemFactory.h *********/
|
|
#ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__
|
|
#define __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__
|
|
|
|
/**
|
|
A factory object which can create ToolbarItemComponent objects.
|
|
|
|
A subclass of ToolbarItemFactory publishes a set of types of toolbar item
|
|
that it can create.
|
|
|
|
Each type of item is identified by a unique ID, and multiple instances of an
|
|
item type can exist at once (even on the same toolbar, e.g. spacers or separator
|
|
bars).
|
|
|
|
@see Toolbar, ToolbarItemComponent, ToolbarButton
|
|
*/
|
|
class JUCE_API ToolbarItemFactory
|
|
{
|
|
public:
|
|
|
|
ToolbarItemFactory();
|
|
|
|
/** Destructor. */
|
|
virtual ~ToolbarItemFactory();
|
|
|
|
/** A set of reserved item ID values, used for the built-in item types.
|
|
*/
|
|
enum SpecialItemIds
|
|
{
|
|
separatorBarId = -1, /**< The item ID for a vertical (or horizontal) separator bar that
|
|
can be placed between sets of items to break them into groups. */
|
|
spacerId = -2, /**< The item ID for a fixed-width space that can be placed between
|
|
items.*/
|
|
flexibleSpacerId = -3 /**< The item ID for a gap that pushes outwards against the things on
|
|
either side of it, filling any available space. */
|
|
};
|
|
|
|
/** Must return a list of the IDs for all the item types that this factory can create.
|
|
|
|
The ids should be added to the array that is passed-in.
|
|
|
|
An item ID can be any integer you choose, except for 0, which is considered a null ID,
|
|
and the predefined IDs in the SpecialItemIds enum.
|
|
|
|
You should also add the built-in types (separatorBarId, spacerId and flexibleSpacerId)
|
|
to this list if you want your toolbar to be able to contain those items.
|
|
|
|
The list returned here is used by the ToolbarItemPalette class to obtain its list
|
|
of available items, and their order on the palette will reflect the order in which
|
|
they appear on this list.
|
|
|
|
@see ToolbarItemPalette
|
|
*/
|
|
virtual void getAllToolbarItemIds (Array <int>& ids) = 0;
|
|
|
|
/** Must return the set of items that should be added to a toolbar as its default set.
|
|
|
|
This method is used by Toolbar::addDefaultItems() to determine which items to
|
|
create.
|
|
|
|
The items that your method adds to the array that is passed-in will be added to the
|
|
toolbar in the same order. Items can appear in the list more than once.
|
|
*/
|
|
virtual void getDefaultItemSet (Array <int>& ids) = 0;
|
|
|
|
/** Must create an instance of one of the items that the factory lists in its
|
|
getAllToolbarItemIds() method.
|
|
|
|
The itemId parameter can be any of the values listed by your getAllToolbarItemIds()
|
|
method, except for the built-in item types from the SpecialItemIds enum, which
|
|
are created internally by the toolbar code.
|
|
|
|
Try not to keep a pointer to the object that is returned, as it will be deleted
|
|
automatically by the toolbar, and remember that multiple instances of the same
|
|
item type are likely to exist at the same time.
|
|
*/
|
|
virtual ToolbarItemComponent* createItem (const int itemId) = 0;
|
|
};
|
|
|
|
#endif // __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__
|
|
/********* End of inlined file: juce_ToolbarItemFactory.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ToolbarItemPalette.h *********/
|
|
#ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__
|
|
#define __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__
|
|
|
|
/**
|
|
A component containing a list of toolbar items, which the user can drag onto
|
|
a toolbar to add them.
|
|
|
|
You can use this class directly, but it's a lot easier to call Toolbar::showCustomisationDialog(),
|
|
which automatically shows one of these in a dialog box with lots of extra controls.
|
|
|
|
@see Toolbar
|
|
*/
|
|
class JUCE_API ToolbarItemPalette : public Component,
|
|
public DragAndDropContainer
|
|
{
|
|
public:
|
|
|
|
/** Creates a palette of items for a given factory, with the aim of adding them
|
|
to the specified toolbar.
|
|
|
|
The ToolbarItemFactory::getAllToolbarItemIds() method is used to create the
|
|
set of items that are shown in this palette.
|
|
|
|
The toolbar and factory must not be deleted while this object exists.
|
|
*/
|
|
ToolbarItemPalette (ToolbarItemFactory& factory,
|
|
Toolbar* const toolbar);
|
|
|
|
/** Destructor. */
|
|
~ToolbarItemPalette();
|
|
|
|
/** @internal */
|
|
void resized();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
ToolbarItemFactory& factory;
|
|
Toolbar* toolbar;
|
|
Viewport* viewport;
|
|
|
|
friend class Toolbar;
|
|
void replaceComponent (ToolbarItemComponent* const comp);
|
|
|
|
ToolbarItemPalette (const ToolbarItemPalette&);
|
|
const ToolbarItemPalette& operator= (const ToolbarItemPalette&);
|
|
};
|
|
|
|
#endif // __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__
|
|
/********* End of inlined file: juce_ToolbarItemPalette.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TREEVIEW_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_BooleanPropertyComponent.h *********/
|
|
#ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A PropertyComponent that contains an on/off toggle button.
|
|
|
|
This type of property component can be used if you have a boolean value to
|
|
toggle on/off.
|
|
|
|
@see PropertyComponent
|
|
*/
|
|
class JUCE_API BooleanPropertyComponent : public PropertyComponent,
|
|
private ButtonListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a button component.
|
|
|
|
@param propertyName the property name to be passed to the PropertyComponent
|
|
@param buttonTextWhenTrue the text shown in the button when the value is true
|
|
@param buttonTextWhenFalse the text shown in the button when the value is false
|
|
*/
|
|
BooleanPropertyComponent (const String& propertyName,
|
|
const String& buttonTextWhenTrue,
|
|
const String& buttonTextWhenFalse);
|
|
|
|
/** Destructor. */
|
|
~BooleanPropertyComponent();
|
|
|
|
/** Called to change the state of the boolean value. */
|
|
virtual void setState (const bool newState) = 0;
|
|
|
|
/** Must return the current value of the property. */
|
|
virtual bool getState() const = 0;
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void refresh();
|
|
/** @internal */
|
|
void buttonClicked (Button*);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
ToggleButton* button;
|
|
String onText, offText;
|
|
};
|
|
|
|
#endif // __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_BooleanPropertyComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ButtonPropertyComponent.h *********/
|
|
#ifndef __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A PropertyComponent that contains a button.
|
|
|
|
This type of property component can be used if you need a button to trigger some
|
|
kind of action.
|
|
|
|
@see PropertyComponent
|
|
*/
|
|
class JUCE_API ButtonPropertyComponent : public PropertyComponent,
|
|
private ButtonListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a button component.
|
|
|
|
@param propertyName the property name to be passed to the PropertyComponent
|
|
@param triggerOnMouseDown this is passed to the Button::setTriggeredOnMouseDown() method
|
|
*/
|
|
ButtonPropertyComponent (const String& propertyName,
|
|
const bool triggerOnMouseDown);
|
|
|
|
/** Destructor. */
|
|
~ButtonPropertyComponent();
|
|
|
|
/** Called when the user clicks the button.
|
|
*/
|
|
virtual void buttonClicked() = 0;
|
|
|
|
/** Returns the string that should be displayed in the button.
|
|
|
|
If you need to change this string, call refresh() to update the component.
|
|
*/
|
|
virtual const String getButtonText() const = 0;
|
|
|
|
/** @internal */
|
|
void refresh();
|
|
/** @internal */
|
|
void buttonClicked (Button*);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
TextButton* button;
|
|
};
|
|
|
|
#endif // __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_ButtonPropertyComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ChoicePropertyComponent.h *********/
|
|
#ifndef __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A PropertyComponent that shows its value as a combo box.
|
|
|
|
This type of property component contains a list of options and has a
|
|
combo box to choose one.
|
|
|
|
Your subclass's constructor must add some strings to the choices StringArray
|
|
and these are shown in the list.
|
|
|
|
The getIndex() method will be called to find out which option is the currently
|
|
selected one. If you call refresh() it will call getIndex() to check whether
|
|
the value has changed, and will update the combo box if needed.
|
|
|
|
If the user selects a different item from the list, setIndex() will be
|
|
called to let your class process this.
|
|
|
|
@see PropertyComponent, PropertyPanel
|
|
*/
|
|
class JUCE_API ChoicePropertyComponent : public PropertyComponent,
|
|
private ComboBoxListener
|
|
{
|
|
public:
|
|
/** Creates the component.
|
|
|
|
Your subclass's constructor must add a list of options to the choices
|
|
member variable.
|
|
*/
|
|
ChoicePropertyComponent (const String& propertyName);
|
|
|
|
/** Destructor. */
|
|
~ChoicePropertyComponent();
|
|
|
|
/** Called when the user selects an item from the combo box.
|
|
|
|
Your subclass must use this callback to update the value that this component
|
|
represents. The index is the index of the chosen item in the choices
|
|
StringArray.
|
|
*/
|
|
virtual void setIndex (const int newIndex) = 0;
|
|
|
|
/** Returns the index of the item that should currently be shown.
|
|
|
|
This is the index of the item in the choices StringArray that will be
|
|
shown.
|
|
*/
|
|
virtual int getIndex() const = 0;
|
|
|
|
/** Returns the list of options. */
|
|
const StringArray& getChoices() const throw();
|
|
|
|
/** @internal */
|
|
void refresh();
|
|
/** @internal */
|
|
void comboBoxChanged (ComboBox*);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** The list of options that will be shown in the combo box.
|
|
|
|
Your subclass must populate this array in its constructor. If any empty
|
|
strings are added, these will be replaced with horizontal separators (see
|
|
ComboBox::addSeparator() for more info).
|
|
*/
|
|
StringArray choices;
|
|
|
|
private:
|
|
ComboBox* comboBox;
|
|
};
|
|
|
|
#endif // __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_ChoicePropertyComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_PROPERTYCOMPONENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_PROPERTYPANEL_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_SliderPropertyComponent.h *********/
|
|
#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A PropertyComponent that shows its value as a slider.
|
|
|
|
@see PropertyComponent, Slider
|
|
*/
|
|
class JUCE_API SliderPropertyComponent : public PropertyComponent,
|
|
private SliderListener
|
|
{
|
|
public:
|
|
|
|
/** Creates the property component.
|
|
|
|
The ranges, interval and skew factor are passed to the Slider component.
|
|
|
|
If you need to customise the slider in other ways, your constructor can
|
|
access the slider member variable and change it directly.
|
|
*/
|
|
SliderPropertyComponent (const String& propertyName,
|
|
const double rangeMin,
|
|
const double rangeMax,
|
|
const double interval,
|
|
const double skewFactor = 1.0);
|
|
|
|
/** Destructor. */
|
|
~SliderPropertyComponent();
|
|
|
|
/** Called when the user moves the slider to change its value.
|
|
|
|
Your subclass must use this method to update whatever item this property
|
|
represents.
|
|
*/
|
|
virtual void setValue (const double newValue) = 0;
|
|
|
|
/** Returns the value that the slider should show. */
|
|
virtual const double getValue() const = 0;
|
|
|
|
/** @internal */
|
|
void refresh();
|
|
/** @internal */
|
|
void changeListenerCallback (void*);
|
|
/** @internal */
|
|
void sliderValueChanged (Slider*);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
/** The slider component being used in this component.
|
|
|
|
Your subclass has access to this in case it needs to customise it in some way.
|
|
*/
|
|
Slider* slider;
|
|
};
|
|
|
|
#endif // __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_SliderPropertyComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_TextPropertyComponent.h *********/
|
|
#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A PropertyComponent that shows its value as editable text.
|
|
|
|
@see PropertyComponent
|
|
*/
|
|
class JUCE_API TextPropertyComponent : public PropertyComponent
|
|
{
|
|
public:
|
|
|
|
/** Creates a text property component.
|
|
|
|
The maxNumChars is used to set the length of string allowable, and isMultiLine
|
|
sets whether the text editor allows carriage returns.
|
|
|
|
@see TextEditor
|
|
*/
|
|
TextPropertyComponent (const String& propertyName,
|
|
const int maxNumChars,
|
|
const bool isMultiLine);
|
|
|
|
/** Destructor. */
|
|
~TextPropertyComponent();
|
|
|
|
/** Called when the user edits the text.
|
|
|
|
Your subclass must use this callback to change the value of whatever item
|
|
this property component represents.
|
|
*/
|
|
virtual void setText (const String& newText) = 0;
|
|
|
|
/** Returns the text that should be shown in the text editor.
|
|
*/
|
|
virtual const String getText() const = 0;
|
|
|
|
/** @internal */
|
|
void refresh();
|
|
/** @internal */
|
|
void textWasEdited();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Label* textEditor;
|
|
};
|
|
|
|
#endif // __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_TextPropertyComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ComponentMovementWatcher.h *********/
|
|
#ifndef __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__
|
|
#define __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__
|
|
|
|
/** An object that watches for any movement of a component or any of its parent components.
|
|
|
|
This makes it easy to check when a component is moved relative to its top-level
|
|
peer window. The normal Component::moved() method is only called when a component
|
|
moves relative to its immediate parent, and sometimes you want to know if any of
|
|
components higher up the tree have moved (which of course will affect the overall
|
|
position of all their sub-components).
|
|
|
|
It also includes a callback that lets you know when the top-level peer is changed.
|
|
|
|
This class is used by specialised components like OpenGLComponent or QuickTimeComponent
|
|
because they need to keep their custom windows in the right place and respond to
|
|
changes in the peer.
|
|
*/
|
|
class JUCE_API ComponentMovementWatcher : public ComponentListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a ComponentMovementWatcher to watch a given target component. */
|
|
ComponentMovementWatcher (Component* const component);
|
|
|
|
/** Destructor. */
|
|
~ComponentMovementWatcher();
|
|
|
|
/** This callback happens when the component that is being watched is moved
|
|
relative to its top-level peer window, or when it is resized.
|
|
*/
|
|
virtual void componentMovedOrResized (bool wasMoved, bool wasResized) = 0;
|
|
|
|
/** This callback happens when the component's top-level peer is changed.
|
|
*/
|
|
virtual void componentPeerChanged() = 0;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
/** @internal */
|
|
void componentParentHierarchyChanged (Component& component);
|
|
/** @internal */
|
|
void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized);
|
|
|
|
private:
|
|
|
|
Component* const component;
|
|
ComponentPeer* lastPeer;
|
|
VoidArray registeredParentComps;
|
|
bool reentrant;
|
|
int lastX, lastY, lastWidth, lastHeight;
|
|
#ifdef JUCE_DEBUG
|
|
ComponentDeletionWatcher* deletionWatcher;
|
|
#endif
|
|
|
|
void unregister() throw();
|
|
void registerWithParentComps() throw();
|
|
|
|
ComponentMovementWatcher (const ComponentMovementWatcher&);
|
|
const ComponentMovementWatcher& operator= (const ComponentMovementWatcher&);
|
|
};
|
|
|
|
#endif // __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__
|
|
/********* End of inlined file: juce_ComponentMovementWatcher.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_GroupComponent.h *********/
|
|
#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_GROUPCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A component that draws an outline around itself and has an optional title at
|
|
the top, for drawing an outline around a group of controls.
|
|
|
|
*/
|
|
class JUCE_API GroupComponent : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates a GroupComponent.
|
|
|
|
@param componentName the name to give the component
|
|
@param labelText the text to show at the top of the outline
|
|
*/
|
|
GroupComponent (const String& componentName,
|
|
const String& labelText);
|
|
|
|
/** Destructor. */
|
|
~GroupComponent();
|
|
|
|
/** Changes the text that's shown at the top of the component. */
|
|
void setText (const String& newText) throw();
|
|
|
|
/** Returns the currently displayed text label. */
|
|
const String getText() const throw();
|
|
|
|
/** Sets the positioning of the text label.
|
|
|
|
(The default is Justification::left)
|
|
|
|
@see getTextLabelPosition
|
|
*/
|
|
void setTextLabelPosition (const Justification& justification);
|
|
|
|
/** Returns the current text label position.
|
|
|
|
@see setTextLabelPosition
|
|
*/
|
|
const Justification getTextLabelPosition() const throw() { return justification; }
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the component.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
outlineColourId = 0x1005400, /**< The colour to use for drawing the line around the edge. */
|
|
textColourId = 0x1005410 /**< The colour to use to draw the text label. */
|
|
};
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void enablementChanged();
|
|
/** @internal */
|
|
void colourChanged();
|
|
|
|
private:
|
|
String text;
|
|
Justification justification;
|
|
|
|
GroupComponent (const GroupComponent&);
|
|
const GroupComponent& operator= (const GroupComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_GROUPCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_GroupComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MultiDocumentPanel.h *********/
|
|
#ifndef __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__
|
|
#define __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_TabbedComponent.h *********/
|
|
#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_TABBEDCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_TabbedButtonBar.h *********/
|
|
#ifndef __JUCE_TABBEDBUTTONBAR_JUCEHEADER__
|
|
#define __JUCE_TABBEDBUTTONBAR_JUCEHEADER__
|
|
|
|
class TabbedButtonBar;
|
|
|
|
/** In a TabbedButtonBar, this component is used for each of the buttons.
|
|
|
|
If you want to create a TabbedButtonBar with custom tab components, derive
|
|
your component from this class, and override the TabbedButtonBar::createTabButton()
|
|
method to create it instead of the default one.
|
|
|
|
@see TabbedButtonBar
|
|
*/
|
|
class JUCE_API TabBarButton : public Button
|
|
{
|
|
public:
|
|
|
|
/** Creates the tab button. */
|
|
TabBarButton (const String& name,
|
|
TabbedButtonBar* const ownerBar,
|
|
const int tabIndex);
|
|
|
|
/** Destructor. */
|
|
~TabBarButton();
|
|
|
|
/** Chooses the best length for the tab, given the specified depth.
|
|
|
|
If the tab is horizontal, this should return its width, and the depth
|
|
specifies its height. If it's vertical, it should return the height, and
|
|
the depth is actually its width.
|
|
*/
|
|
virtual int getBestTabLength (const int depth);
|
|
|
|
void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown);
|
|
void clicked (const ModifierKeys& mods);
|
|
bool hitTest (int x, int y);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
friend class TabbedButtonBar;
|
|
TabbedButtonBar* const owner;
|
|
int tabIndex, overlapPixels;
|
|
DropShadowEffect shadow;
|
|
|
|
/** Returns an area of the component that's safe to draw in.
|
|
|
|
This deals with the orientation of the tabs, which affects which side is
|
|
touching the tabbed box's content component.
|
|
*/
|
|
void getActiveArea (int& x, int& y, int& w, int& h);
|
|
|
|
private:
|
|
TabBarButton (const TabBarButton&);
|
|
const TabBarButton& operator= (const TabBarButton&);
|
|
};
|
|
|
|
/**
|
|
A vertical or horizontal bar containing tabs that you can select.
|
|
|
|
You can use one of these to generate things like a dialog box that has
|
|
tabbed pages you can flip between. Attach a ChangeListener to the
|
|
button bar to be told when the user changes the page.
|
|
|
|
An easier method than doing this is to use a TabbedComponent, which
|
|
contains its own TabbedButtonBar and which takes care of the layout
|
|
and other housekeeping.
|
|
|
|
@see TabbedComponent
|
|
*/
|
|
class JUCE_API TabbedButtonBar : public Component,
|
|
public ChangeBroadcaster,
|
|
public ButtonListener
|
|
{
|
|
public:
|
|
|
|
/** The placement of the tab-bar
|
|
|
|
@see setOrientation, getOrientation
|
|
*/
|
|
enum Orientation
|
|
{
|
|
TabsAtTop,
|
|
TabsAtBottom,
|
|
TabsAtLeft,
|
|
TabsAtRight
|
|
};
|
|
|
|
/** Creates a TabbedButtonBar with a given placement.
|
|
|
|
You can change the orientation later if you need to.
|
|
*/
|
|
TabbedButtonBar (const Orientation orientation);
|
|
|
|
/** Destructor. */
|
|
~TabbedButtonBar();
|
|
|
|
/** Changes the bar's orientation.
|
|
|
|
This won't change the bar's actual size - you'll need to do that yourself,
|
|
but this determines which direction the tabs go in, and which side they're
|
|
stuck to.
|
|
*/
|
|
void setOrientation (const Orientation orientation);
|
|
|
|
/** Returns the current orientation.
|
|
|
|
@see setOrientation
|
|
*/
|
|
Orientation getOrientation() const throw() { return orientation; }
|
|
|
|
/** Deletes all the tabs from the bar.
|
|
|
|
@see addTab
|
|
*/
|
|
void clearTabs();
|
|
|
|
/** Adds a tab to the bar.
|
|
|
|
Tabs are added in left-to-right reading order.
|
|
|
|
If this is the first tab added, it'll also be automatically selected.
|
|
*/
|
|
void addTab (const String& tabName,
|
|
const Colour& tabBackgroundColour,
|
|
int insertIndex = -1);
|
|
|
|
/** Changes the name of one of the tabs. */
|
|
void setTabName (const int tabIndex,
|
|
const String& newName);
|
|
|
|
/** Gets rid of one of the tabs. */
|
|
void removeTab (const int tabIndex);
|
|
|
|
/** Moves a tab to a new index in the list.
|
|
|
|
Pass -1 as the index to move it to the end of the list.
|
|
*/
|
|
void moveTab (const int currentIndex,
|
|
const int newIndex);
|
|
|
|
/** Returns the number of tabs in the bar. */
|
|
int getNumTabs() const;
|
|
|
|
/** Returns a list of all the tab names in the bar. */
|
|
const StringArray getTabNames() const;
|
|
|
|
/** Changes the currently selected tab.
|
|
|
|
This will send a change message and cause a synchronous callback to
|
|
the currentTabChanged() method. (But if the given tab is already selected,
|
|
nothing will be done).
|
|
|
|
To deselect all the tabs, use an index of -1.
|
|
*/
|
|
void setCurrentTabIndex (int newTabIndex, const bool sendChangeMessage = true);
|
|
|
|
/** Returns the name of the currently selected tab.
|
|
|
|
This could be an empty string if none are selected.
|
|
*/
|
|
const String& getCurrentTabName() const throw() { return tabs [currentTabIndex]; }
|
|
|
|
/** Returns the index of the currently selected tab.
|
|
|
|
This could return -1 if none are selected.
|
|
*/
|
|
int getCurrentTabIndex() const throw() { return currentTabIndex; }
|
|
|
|
/** Returns the button for a specific tab.
|
|
|
|
The button that is returned may be deleted later by this component, so don't hang
|
|
on to the pointer that is returned. A null pointer may be returned if the index is
|
|
out of range.
|
|
*/
|
|
TabBarButton* getTabButton (const int index) const;
|
|
|
|
/** Callback method to indicate the selected tab has been changed.
|
|
|
|
@see setCurrentTabIndex
|
|
*/
|
|
virtual void currentTabChanged (const int newCurrentTabIndex,
|
|
const String& newCurrentTabName);
|
|
|
|
/** Callback method to indicate that the user has right-clicked on a tab.
|
|
|
|
(Or ctrl-clicked on the Mac)
|
|
*/
|
|
virtual void popupMenuClickOnTab (const int tabIndex,
|
|
const String& tabName);
|
|
|
|
/** Returns the colour of a tab.
|
|
|
|
This is the colour that was specified in addTab().
|
|
*/
|
|
const Colour getTabBackgroundColour (const int tabIndex);
|
|
|
|
/** Changes the background colour of a tab.
|
|
|
|
@see addTab, getTabBackgroundColour
|
|
*/
|
|
void setTabBackgroundColour (const int tabIndex, const Colour& newColour);
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the component.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
tabOutlineColourId = 0x1005812, /**< The colour to use to draw an outline around the tabs. */
|
|
tabTextColourId = 0x1005813, /**< The colour to use to draw the tab names. If this isn't specified,
|
|
the look and feel will choose an appropriate colour. */
|
|
frontOutlineColourId = 0x1005814, /**< The colour to use to draw an outline around the currently-selected tab. */
|
|
frontTextColourId = 0x1005815, /**< The colour to use to draw the currently-selected tab name. If
|
|
this isn't specified, the look and feel will choose an appropriate
|
|
colour. */
|
|
};
|
|
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void buttonClicked (Button* button);
|
|
/** @internal */
|
|
void lookAndFeelChanged();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
/** This creates one of the tabs.
|
|
|
|
If you need to use custom tab components, you can override this method and
|
|
return your own class instead of the default.
|
|
*/
|
|
virtual TabBarButton* createTabButton (const String& tabName,
|
|
const int tabIndex);
|
|
|
|
private:
|
|
Orientation orientation;
|
|
|
|
StringArray tabs;
|
|
Array <Colour> tabColours;
|
|
int currentTabIndex;
|
|
Component* behindFrontTab;
|
|
Button* extraTabsButton;
|
|
|
|
TabbedButtonBar (const TabbedButtonBar&);
|
|
const TabbedButtonBar& operator= (const TabbedButtonBar&);
|
|
};
|
|
|
|
#endif // __JUCE_TABBEDBUTTONBAR_JUCEHEADER__
|
|
/********* End of inlined file: juce_TabbedButtonBar.h *********/
|
|
|
|
/**
|
|
A component with a TabbedButtonBar along one of its sides.
|
|
|
|
This makes it easy to create a set of tabbed pages, just add a bunch of tabs
|
|
with addTab(), and this will take care of showing the pages for you when the
|
|
user clicks on a different tab.
|
|
|
|
@see TabbedButtonBar
|
|
*/
|
|
class JUCE_API TabbedComponent : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates a TabbedComponent, specifying where the tabs should be placed.
|
|
|
|
Once created, add some tabs with the addTab() method.
|
|
*/
|
|
TabbedComponent (const TabbedButtonBar::Orientation orientation);
|
|
|
|
/** Destructor. */
|
|
~TabbedComponent();
|
|
|
|
/** Changes the placement of the tabs.
|
|
|
|
This will rearrange the layout to place the tabs along the appropriate
|
|
side of this component, and will shift the content component accordingly.
|
|
|
|
@see TabbedButtonBar::setOrientation
|
|
*/
|
|
void setOrientation (const TabbedButtonBar::Orientation orientation);
|
|
|
|
/** Returns the current tab placement.
|
|
|
|
@see setOrientation, TabbedButtonBar::getOrientation
|
|
*/
|
|
TabbedButtonBar::Orientation getOrientation() const throw();
|
|
|
|
/** Specifies how many pixels wide or high the tab-bar should be.
|
|
|
|
If the tabs are placed along the top or bottom, this specified the height
|
|
of the bar; if they're along the left or right edges, it'll be the width
|
|
of the bar.
|
|
*/
|
|
void setTabBarDepth (const int newDepth);
|
|
|
|
/** Returns the current thickness of the tab bar.
|
|
|
|
@see setTabBarDepth
|
|
*/
|
|
int getTabBarDepth() const throw() { return tabDepth; }
|
|
|
|
/** Specifies the thickness of an outline that should be drawn around the content component.
|
|
|
|
If this thickness is > 0, a line will be drawn around the three sides of the content
|
|
component which don't touch the tab-bar, and the content component will be inset by this amount.
|
|
|
|
To set the colour of the line, use setColour (outlineColourId, ...).
|
|
*/
|
|
void setOutline (const int newThickness);
|
|
|
|
/** Specifies a gap to leave around the edge of the content component.
|
|
|
|
Each edge of the content component will be indented by the given number of pixels.
|
|
*/
|
|
void setIndent (const int indentThickness);
|
|
|
|
/** Removes all the tabs from the bar.
|
|
|
|
@see TabbedButtonBar::clearTabs
|
|
*/
|
|
void clearTabs();
|
|
|
|
/** Adds a tab to the tab-bar.
|
|
|
|
The component passed in will be shown for the tab, and if deleteComponentWhenNotNeeded
|
|
is true, it will be deleted when the tab is removed or when this object is
|
|
deleted.
|
|
|
|
@see TabbedButtonBar::addTab
|
|
*/
|
|
void addTab (const String& tabName,
|
|
const Colour& tabBackgroundColour,
|
|
Component* const contentComponent,
|
|
const bool deleteComponentWhenNotNeeded,
|
|
const int insertIndex = -1);
|
|
|
|
/** Changes the name of one of the tabs. */
|
|
void setTabName (const int tabIndex,
|
|
const String& newName);
|
|
|
|
/** Gets rid of one of the tabs. */
|
|
void removeTab (const int tabIndex);
|
|
|
|
/** Returns the number of tabs in the bar. */
|
|
int getNumTabs() const;
|
|
|
|
/** Returns a list of all the tab names in the bar. */
|
|
const StringArray getTabNames() const;
|
|
|
|
/** Returns the content component that was added for the given index.
|
|
|
|
Be sure not to use or delete the components that are returned, as this may interfere
|
|
with the TabbedComponent's use of them.
|
|
*/
|
|
Component* getTabContentComponent (const int tabIndex) const throw();
|
|
|
|
/** Returns the colour of one of the tabs. */
|
|
const Colour getTabBackgroundColour (const int tabIndex) const throw();
|
|
|
|
/** Changes the background colour of one of the tabs. */
|
|
void setTabBackgroundColour (const int tabIndex, const Colour& newColour);
|
|
|
|
/** Changes the currently-selected tab.
|
|
|
|
To deselect all the tabs, pass -1 as the index.
|
|
|
|
@see TabbedButtonBar::setCurrentTabIndex
|
|
*/
|
|
void setCurrentTabIndex (const int newTabIndex, const bool sendChangeMessage = true);
|
|
|
|
/** Returns the index of the currently selected tab.
|
|
|
|
@see addTab, TabbedButtonBar::getCurrentTabIndex()
|
|
*/
|
|
int getCurrentTabIndex() const;
|
|
|
|
/** Returns the name of the currently selected tab.
|
|
|
|
@see addTab, TabbedButtonBar::getCurrentTabName()
|
|
*/
|
|
const String& getCurrentTabName() const;
|
|
|
|
/** Returns the current component that's filling the panel.
|
|
|
|
This will return 0 if there isn't one.
|
|
*/
|
|
Component* getCurrentContentComponent() const throw() { return panelComponent; }
|
|
|
|
/** Callback method to indicate the selected tab has been changed.
|
|
|
|
@see setCurrentTabIndex
|
|
*/
|
|
virtual void currentTabChanged (const int newCurrentTabIndex,
|
|
const String& newCurrentTabName);
|
|
|
|
/** Callback method to indicate that the user has right-clicked on a tab.
|
|
|
|
(Or ctrl-clicked on the Mac)
|
|
*/
|
|
virtual void popupMenuClickOnTab (const int tabIndex,
|
|
const String& tabName);
|
|
|
|
/** Returns the tab button bar component that is being used.
|
|
*/
|
|
TabbedButtonBar& getTabbedButtonBar() const throw() { return *tabs; }
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the component.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1005800, /**< The colour to fill the background behind the tabs. */
|
|
outlineColourId = 0x1005801, /**< The colour to use to draw an outline around the content.
|
|
(See setOutline) */
|
|
};
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void lookAndFeelChanged();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
|
|
TabbedButtonBar* tabs;
|
|
|
|
/** This creates one of the tab buttons.
|
|
|
|
If you need to use custom tab components, you can override this method and
|
|
return your own class instead of the default.
|
|
*/
|
|
virtual TabBarButton* createTabButton (const String& tabName,
|
|
const int tabIndex);
|
|
|
|
private:
|
|
|
|
Array <Component*> contentComponents;
|
|
Component* panelComponent;
|
|
int tabDepth;
|
|
int outlineThickness, edgeIndent;
|
|
|
|
friend class TabCompButtonBar;
|
|
void changeCallback (const int newCurrentTabIndex, const String& newTabName);
|
|
|
|
TabbedComponent (const TabbedComponent&);
|
|
const TabbedComponent& operator= (const TabbedComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_TABBEDCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_TabbedComponent.h *********/
|
|
|
|
/********* Start of inlined file: juce_DocumentWindow.h *********/
|
|
#ifndef __JUCE_DOCUMENTWINDOW_JUCEHEADER__
|
|
#define __JUCE_DOCUMENTWINDOW_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ResizableWindow.h *********/
|
|
#ifndef __JUCE_RESIZABLEWINDOW_JUCEHEADER__
|
|
#define __JUCE_RESIZABLEWINDOW_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_TopLevelWindow.h *********/
|
|
#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__
|
|
#define __JUCE_TOPLEVELWINDOW_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DropShadower.h *********/
|
|
#ifndef __JUCE_DROPSHADOWER_JUCEHEADER__
|
|
#define __JUCE_DROPSHADOWER_JUCEHEADER__
|
|
|
|
/**
|
|
Adds a drop-shadow to a component.
|
|
|
|
This object creates and manages a set of components which sit around a
|
|
component, creating a gaussian shadow around it. The components will track
|
|
the position of the component and if it's brought to the front they'll also
|
|
follow this.
|
|
|
|
For desktop windows you don't need to use this class directly - just
|
|
set the Component::windowHasDropShadow flag when calling
|
|
Component::addToDesktop(), and the system will create one of these if it's
|
|
needed (which it obviously isn't on the Mac, for example).
|
|
*/
|
|
class JUCE_API DropShadower : public ComponentListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a DropShadower.
|
|
|
|
@param alpha the opacity of the shadows, from 0 to 1.0
|
|
@param xOffset the horizontal displacement of the shadow, in pixels
|
|
@param yOffset the vertical displacement of the shadow, in pixels
|
|
@param blurRadius the radius of the blur to use for creating the shadow
|
|
*/
|
|
DropShadower (const float alpha = 0.5f,
|
|
const int xOffset = 1,
|
|
const int yOffset = 5,
|
|
const float blurRadius = 10.0f);
|
|
|
|
/** Destructor. */
|
|
virtual ~DropShadower();
|
|
|
|
/** Attaches the DropShadower to the component you want to shadow. */
|
|
void setOwner (Component* componentToFollow);
|
|
|
|
/** @internal */
|
|
void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized);
|
|
/** @internal */
|
|
void componentBroughtToFront (Component& component);
|
|
/** @internal */
|
|
void componentChildrenChanged (Component& component);
|
|
/** @internal */
|
|
void componentParentHierarchyChanged (Component& component);
|
|
/** @internal */
|
|
void componentVisibilityChanged (Component& component);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
Component* owner;
|
|
int numShadows;
|
|
Component* shadowWindows[4];
|
|
Image* shadowImageSections[12];
|
|
const int shadowEdge, xOffset, yOffset;
|
|
const float alpha, blurRadius;
|
|
bool inDestructor, reentrant;
|
|
|
|
void updateShadows();
|
|
void setShadowImage (Image* const src,
|
|
const int num,
|
|
const int w, const int h,
|
|
const int sx, const int sy) throw();
|
|
|
|
void bringShadowWindowsToFront();
|
|
void deleteShadowWindows();
|
|
|
|
DropShadower (const DropShadower&);
|
|
const DropShadower& operator= (const DropShadower&);
|
|
};
|
|
|
|
#endif // __JUCE_DROPSHADOWER_JUCEHEADER__
|
|
/********* End of inlined file: juce_DropShadower.h *********/
|
|
|
|
/**
|
|
A base class for top-level windows.
|
|
|
|
This class is used for components that are considered a major part of your
|
|
application - e.g. ResizableWindow, DocumentWindow, DialogWindow, AlertWindow,
|
|
etc. Things like menus that pop up briefly aren't derived from it.
|
|
|
|
A TopLevelWindow is probably on the desktop, but this isn't mandatory - it
|
|
could itself be the child of another component.
|
|
|
|
The class manages a list of all instances of top-level windows that are in use,
|
|
and each one is also given the concept of being "active". The active window is
|
|
one that is actively being used by the user. This isn't quite the same as the
|
|
component with the keyboard focus, because there may be a popup menu or other
|
|
temporary window which gets keyboard focus while the active top level window is
|
|
unchanged.
|
|
|
|
A top-level window also has an optional drop-shadow.
|
|
|
|
@see ResizableWindow, DocumentWindow, DialogWindow
|
|
*/
|
|
class JUCE_API TopLevelWindow : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates a TopLevelWindow.
|
|
|
|
@param name the name to give the component
|
|
@param addToDesktop if true, the window will be automatically added to the
|
|
desktop; if false, you can use it as a child component
|
|
*/
|
|
TopLevelWindow (const String& name,
|
|
const bool addToDesktop);
|
|
|
|
/** Destructor. */
|
|
~TopLevelWindow();
|
|
|
|
/** True if this is currently the TopLevelWindow that is actively being used.
|
|
|
|
This isn't quite the same as having keyboard focus, because the focus may be
|
|
on a child component or a temporary pop-up menu, etc, while this window is
|
|
still considered to be active.
|
|
|
|
@see activeWindowStatusChanged
|
|
*/
|
|
bool isActiveWindow() const throw() { return windowIsActive_; }
|
|
|
|
/** This will set the bounds of the window so that it's centred in front of another
|
|
window.
|
|
|
|
If your app has a few windows open and want to pop up a dialog box for one of
|
|
them, you can use this to show it in front of the relevent parent window, which
|
|
is a bit neater than just having it appear in the middle of the screen.
|
|
|
|
If componentToCentreAround is 0, then the currently active TopLevelWindow will
|
|
be used instead. If no window is focused, it'll just default to the middle of the
|
|
screen.
|
|
*/
|
|
void centreAroundComponent (Component* componentToCentreAround,
|
|
const int width, const int height);
|
|
|
|
/** Turns the drop-shadow on and off. */
|
|
void setDropShadowEnabled (const bool useShadow);
|
|
|
|
/** Sets whether an OS-native title bar will be used, or a Juce one.
|
|
|
|
@see isUsingNativeTitleBar
|
|
*/
|
|
void setUsingNativeTitleBar (const bool useNativeTitleBar);
|
|
|
|
/** Returns true if the window is currently using an OS-native title bar.
|
|
|
|
@see setUsingNativeTitleBar
|
|
*/
|
|
bool isUsingNativeTitleBar() const throw() { return useNativeTitleBar && isOnDesktop(); }
|
|
|
|
/** Returns the number of TopLevelWindow objects currently in use.
|
|
|
|
@see getTopLevelWindow
|
|
*/
|
|
static int getNumTopLevelWindows() throw();
|
|
|
|
/** Returns one of the TopLevelWindow objects currently in use.
|
|
|
|
The index is 0 to (getNumTopLevelWindows() - 1).
|
|
*/
|
|
static TopLevelWindow* getTopLevelWindow (const int index) throw();
|
|
|
|
/** Returns the currently-active top level window.
|
|
|
|
There might not be one, of course, so this can return 0.
|
|
*/
|
|
static TopLevelWindow* getActiveTopLevelWindow() throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
/** @internal */
|
|
virtual void addToDesktop (int windowStyleFlags, void* nativeWindowToAttachTo = 0);
|
|
|
|
protected:
|
|
|
|
/** This callback happens when this window becomes active or inactive.
|
|
|
|
@see isActiveWindow
|
|
*/
|
|
virtual void activeWindowStatusChanged();
|
|
|
|
/** @internal */
|
|
void focusOfChildComponentChanged (FocusChangeType cause);
|
|
/** @internal */
|
|
void parentHierarchyChanged();
|
|
/** @internal */
|
|
void visibilityChanged();
|
|
/** @internal */
|
|
virtual int getDesktopWindowStyleFlags() const;
|
|
/** @internal */
|
|
void recreateDesktopWindow();
|
|
|
|
private:
|
|
friend class TopLevelWindowManager;
|
|
bool useDropShadow, useNativeTitleBar, windowIsActive_;
|
|
DropShadower* shadower;
|
|
|
|
void setWindowActive (const bool isNowActive) throw();
|
|
|
|
TopLevelWindow (const TopLevelWindow&);
|
|
const TopLevelWindow& operator= (const TopLevelWindow&);
|
|
};
|
|
|
|
#endif // __JUCE_TOPLEVELWINDOW_JUCEHEADER__
|
|
/********* End of inlined file: juce_TopLevelWindow.h *********/
|
|
|
|
/********* Start of inlined file: juce_ResizableBorderComponent.h *********/
|
|
#ifndef __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A component that resizes its parent window when dragged.
|
|
|
|
This component forms a frame around the edge of a component, allowing it to
|
|
be dragged by the edges or corners to resize it - like the way windows are
|
|
resized in MSWindows or Linux.
|
|
|
|
To use it, just add it to your component, making it fill the entire parent component
|
|
(there's a mouse hit-test that only traps mouse-events which land around the
|
|
edge of the component, so it's even ok to put it on top of any other components
|
|
you're using). Make sure you rescale the resizer component to fill the parent
|
|
each time the parent's size changes.
|
|
|
|
@see ResizableCornerComponent
|
|
*/
|
|
class JUCE_API ResizableBorderComponent : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates a resizer.
|
|
|
|
Pass in the target component which you want to be resized when this one is
|
|
dragged.
|
|
|
|
The target component will usually be a parent of the resizer component, but this
|
|
isn't mandatory.
|
|
|
|
Remember that when the target component is resized, it'll need to move and
|
|
resize this component to keep it in place, as this won't happen automatically.
|
|
|
|
If the constrainer parameter is non-zero, then this object will be used to enforce
|
|
limits on the size and position that the component can be stretched to. Make sure
|
|
that the constrainer isn't deleted while still in use by this object.
|
|
|
|
@see ComponentBoundsConstrainer
|
|
*/
|
|
ResizableBorderComponent (Component* const componentToResize,
|
|
ComponentBoundsConstrainer* const constrainer);
|
|
|
|
/** Destructor. */
|
|
~ResizableBorderComponent();
|
|
|
|
/** Specifies how many pixels wide the draggable edges of this component are.
|
|
|
|
@see getBorderThickness
|
|
*/
|
|
void setBorderThickness (const BorderSize& newBorderSize) throw();
|
|
|
|
/** Returns the number of pixels wide that the draggable edges of this component are.
|
|
|
|
@see setBorderThickness
|
|
*/
|
|
const BorderSize getBorderThickness() const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void mouseEnter (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseMove (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseUp (const MouseEvent& e);
|
|
/** @internal */
|
|
bool hitTest (int x, int y);
|
|
|
|
private:
|
|
Component* const component;
|
|
ComponentBoundsConstrainer* constrainer;
|
|
BorderSize borderSize;
|
|
int originalX, originalY, originalW, originalH;
|
|
int mouseZone;
|
|
|
|
void updateMouseZone (const MouseEvent& e) throw();
|
|
|
|
ResizableBorderComponent (const ResizableBorderComponent&);
|
|
const ResizableBorderComponent& operator= (const ResizableBorderComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_ResizableBorderComponent.h *********/
|
|
|
|
/********* Start of inlined file: juce_ResizableCornerComponent.h *********/
|
|
#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__
|
|
|
|
/** A component that resizes a parent window when dragged.
|
|
|
|
This is the small triangular stripey resizer component you get in the bottom-right
|
|
of windows (more commonly on the Mac than Windows). Put one in the corner of
|
|
a larger component and it will automatically resize its parent when it gets dragged
|
|
around.
|
|
|
|
@see ResizableFrameComponent
|
|
*/
|
|
class JUCE_API ResizableCornerComponent : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates a resizer.
|
|
|
|
Pass in the target component which you want to be resized when this one is
|
|
dragged.
|
|
|
|
The target component will usually be a parent of the resizer component, but this
|
|
isn't mandatory.
|
|
|
|
Remember that when the target component is resized, it'll need to move and
|
|
resize this component to keep it in place, as this won't happen automatically.
|
|
|
|
If the constrainer parameter is non-zero, then this object will be used to enforce
|
|
limits on the size and position that the component can be stretched to. Make sure
|
|
that the constrainer isn't deleted while still in use by this object. If you
|
|
pass a zero in here, no limits will be put on the sizes it can be stretched to.
|
|
|
|
@see ComponentBoundsConstrainer
|
|
*/
|
|
ResizableCornerComponent (Component* const componentToResize,
|
|
ComponentBoundsConstrainer* const constrainer);
|
|
|
|
/** Destructor. */
|
|
~ResizableCornerComponent();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseUp (const MouseEvent& e);
|
|
/** @internal */
|
|
bool hitTest (int x, int y);
|
|
|
|
private:
|
|
|
|
Component* const component;
|
|
ComponentBoundsConstrainer* constrainer;
|
|
int originalX, originalY, originalW, originalH;
|
|
|
|
ResizableCornerComponent (const ResizableCornerComponent&);
|
|
const ResizableCornerComponent& operator= (const ResizableCornerComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_ResizableCornerComponent.h *********/
|
|
|
|
/**
|
|
A base class for top-level windows that can be dragged around and resized.
|
|
|
|
To add content to the window, use its setContentComponent() method to
|
|
give it a component that will remain positioned inside it (leaving a gap around
|
|
the edges for a border).
|
|
|
|
It's not advisable to add child components directly to a ResizableWindow: put them
|
|
inside your content component instead. And overriding methods like resized(), moved(), etc
|
|
is also not recommended - instead override these methods for your content component.
|
|
(If for some obscure reason you do need to override these methods, always remember to
|
|
call the super-class's resized() method too, otherwise it'll fail to lay out the window
|
|
decorations correctly).
|
|
|
|
By default resizing isn't enabled - use the setResizable() method to enable it and
|
|
to choose the style of resizing to use.
|
|
|
|
@see TopLevelWindow
|
|
*/
|
|
class JUCE_API ResizableWindow : public TopLevelWindow
|
|
{
|
|
public:
|
|
|
|
/** Creates a ResizableWindow.
|
|
|
|
This constructor doesn't specify a background colour, so the LookAndFeel's default
|
|
background colour will be used.
|
|
|
|
@param name the name to give the component
|
|
@param addToDesktop if true, the window will be automatically added to the
|
|
desktop; if false, you can use it as a child component
|
|
*/
|
|
ResizableWindow (const String& name,
|
|
const bool addToDesktop);
|
|
|
|
/** Creates a ResizableWindow.
|
|
|
|
@param name the name to give the component
|
|
@param backgroundColour the colour to use for filling the window's background.
|
|
@param addToDesktop if true, the window will be automatically added to the
|
|
desktop; if false, you can use it as a child component
|
|
*/
|
|
ResizableWindow (const String& name,
|
|
const Colour& backgroundColour,
|
|
const bool addToDesktop);
|
|
|
|
/** Destructor.
|
|
|
|
If a content component has been set with setContentComponent(), it
|
|
will be deleted.
|
|
*/
|
|
~ResizableWindow();
|
|
|
|
/** Returns the colour currently being used for the window's background.
|
|
|
|
As a convenience the window will fill itself with this colour, but you
|
|
can override the paint() method if you need more customised behaviour.
|
|
|
|
This method is the same as retrieving the colour for ResizableWindow::backgroundColourId.
|
|
|
|
@see setBackgroundColour
|
|
*/
|
|
const Colour getBackgroundColour() const throw();
|
|
|
|
/** Changes the colour currently being used for the window's background.
|
|
|
|
As a convenience the window will fill itself with this colour, but you
|
|
can override the paint() method if you need more customised behaviour.
|
|
|
|
Note that the opaque state of this window is altered by this call to reflect
|
|
the opacity of the colour passed-in. On window systems which can't support
|
|
semi-transparent windows this might cause problems, (though it's unlikely you'll
|
|
be using this class as a base for a semi-transparent component anyway).
|
|
|
|
You can also use the ResizableWindow::backgroundColourId colour id to set
|
|
this colour.
|
|
|
|
@see getBackgroundColour
|
|
*/
|
|
void setBackgroundColour (const Colour& newColour);
|
|
|
|
/** Make the window resizable or fixed.
|
|
|
|
@param shouldBeResizable whether it's resizable at all
|
|
@param useBottomRightCornerResizer if true, it'll add a ResizableCornerComponent at the
|
|
bottom-right; if false, it'll use a ResizableBorderComponent
|
|
around the edge
|
|
@see setResizeLimits, isResizable
|
|
*/
|
|
void setResizable (const bool shouldBeResizable,
|
|
const bool useBottomRightCornerResizer);
|
|
|
|
/** True if resizing is enabled.
|
|
|
|
@see setResizable
|
|
*/
|
|
bool isResizable() const throw();
|
|
|
|
/** This sets the maximum and minimum sizes for the window.
|
|
|
|
If the window's current size is outside these limits, it will be resized to
|
|
make sure it's within them.
|
|
|
|
Calling setBounds() on the component will bypass any size checking - it's only when
|
|
the window is being resized by the user that these values are enforced.
|
|
|
|
@see setResizable, setFixedAspectRatio
|
|
*/
|
|
void setResizeLimits (const int newMinimumWidth,
|
|
const int newMinimumHeight,
|
|
const int newMaximumWidth,
|
|
const int newMaximumHeight) throw();
|
|
|
|
/** Returns the bounds constrainer object that this window is using.
|
|
|
|
You can access this to change its properties.
|
|
*/
|
|
ComponentBoundsConstrainer* getConstrainer() throw() { return constrainer; }
|
|
|
|
/** Sets the bounds-constrainer object to use for resizing and dragging this window.
|
|
|
|
A pointer to the object you pass in will be kept, but it won't be deleted
|
|
by this object, so it's the caller's responsiblity to manage it.
|
|
|
|
If you pass 0, then no contraints will be placed on the positioning of the window.
|
|
*/
|
|
void setConstrainer (ComponentBoundsConstrainer* newConstrainer);
|
|
|
|
/** Calls the window's setBounds method, after first checking these bounds
|
|
with the current constrainer.
|
|
|
|
@see setConstrainer
|
|
*/
|
|
void setBoundsConstrained (int x, int y, int width, int height);
|
|
|
|
/** Returns true if the window is currently in full-screen mode.
|
|
|
|
@see setFullScreen
|
|
*/
|
|
bool isFullScreen() const;
|
|
|
|
/** Puts the window into full-screen mode, or restores it to its normal size.
|
|
|
|
If true, the window will become full-screen; if false, it will return to the
|
|
last size it was before being made full-screen.
|
|
|
|
@see isFullScreen
|
|
*/
|
|
void setFullScreen (const bool shouldBeFullScreen);
|
|
|
|
/** Returns true if the window is currently minimised.
|
|
|
|
@see setMinimised
|
|
*/
|
|
bool isMinimised() const;
|
|
|
|
/** Minimises the window, or restores it to its previous position and size.
|
|
|
|
When being un-minimised, it'll return to the last position and size it
|
|
was in before being minimised.
|
|
|
|
@see isMinimised
|
|
*/
|
|
void setMinimised (const bool shouldMinimise);
|
|
|
|
/** Returns a string which encodes the window's current size and position.
|
|
|
|
This string will encapsulate the window's size, position, and whether it's
|
|
in full-screen mode. It's intended for letting your application save and
|
|
restore a window's position.
|
|
|
|
Use the restoreWindowStateFromString() to restore from a saved state.
|
|
|
|
@see restoreWindowStateFromString
|
|
*/
|
|
const String getWindowStateAsString();
|
|
|
|
/** Restores the window to a previously-saved size and position.
|
|
|
|
This restores the window's size, positon and full-screen status from an
|
|
string that was previously created with the getWindowStateAsString()
|
|
method.
|
|
|
|
@returns false if the string wasn't a valid window state
|
|
@see getWindowStateAsString
|
|
*/
|
|
bool restoreWindowStateFromString (const String& previousState);
|
|
|
|
/** Returns the current content component.
|
|
|
|
This will be the component set by setContentComponent(), or 0 if none
|
|
has yet been specified.
|
|
|
|
@see setContentComponent
|
|
*/
|
|
Component* getContentComponent() const throw() { return contentComponent; }
|
|
|
|
/** Changes the current content component.
|
|
|
|
This sets a component that will be placed in the centre of the ResizableWindow,
|
|
(leaving a space around the edge for the border).
|
|
|
|
You should never add components directly to a ResizableWindow (or any of its subclasses)
|
|
with addChildComponent(). Instead, add them to the content component.
|
|
|
|
@param newContentComponent the new component to use (or null to not use one) - this
|
|
component will be deleted either when replaced by another call
|
|
to this method, or when the ResizableWindow is deleted.
|
|
To remove a content component without deleting it, use
|
|
setContentComponent (0, false).
|
|
@param deleteOldOne if true, the previous content component will be deleted; if
|
|
false, the previous component will just be removed without
|
|
deleting it.
|
|
@param resizeToFit if true, the ResizableWindow will maintain its size such that
|
|
it always fits around the size of the content component. If false, the
|
|
new content will be resized to fit the current space available.
|
|
*/
|
|
void setContentComponent (Component* const newContentComponent,
|
|
const bool deleteOldOne = true,
|
|
const bool resizeToFit = false);
|
|
|
|
/** Changes the window so that the content component ends up with the specified size.
|
|
|
|
This is basically a setSize call on the window, but which adds on the borders,
|
|
so you can specify the content component's target size.
|
|
*/
|
|
void setContentComponentSize (int width, int height);
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the window.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1005700, /**< A colour to use to fill the window's background. */
|
|
};
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** (if overriding this, make sure you call ResizableWindow::resized() in your subclass) */
|
|
void moved();
|
|
/** (if overriding this, make sure you call ResizableWindow::resized() in your subclass) */
|
|
void resized();
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent& e);
|
|
/** @internal */
|
|
void lookAndFeelChanged();
|
|
/** @internal */
|
|
void childBoundsChanged (Component* child);
|
|
/** @internal */
|
|
void parentSizeChanged();
|
|
/** @internal */
|
|
void visibilityChanged();
|
|
/** @internal */
|
|
void activeWindowStatusChanged();
|
|
/** @internal */
|
|
int getDesktopWindowStyleFlags() const;
|
|
|
|
/** Returns the width of the border to use around the window.
|
|
|
|
@see getContentComponentBorder
|
|
*/
|
|
virtual const BorderSize getBorderThickness();
|
|
|
|
/** Returns the insets to use when positioning the content component.
|
|
|
|
@see getBorderThickness
|
|
*/
|
|
virtual const BorderSize getContentComponentBorder();
|
|
|
|
#ifdef JUCE_DEBUG
|
|
/** Overridden to warn people about adding components directly to this component
|
|
instead of using setContentComponent().
|
|
|
|
If you know what you're doing and are sure you really want to add a component, specify
|
|
a base-class method call to Component::addAndMakeVisible(), to side-step this warning.
|
|
*/
|
|
void addChildComponent (Component* const child, int zOrder = -1);
|
|
/** Overridden to warn people about adding components directly to this component
|
|
instead of using setContentComponent().
|
|
|
|
If you know what you're doing and are sure you really want to add a component, specify
|
|
a base-class method call to Component::addAndMakeVisible(), to side-step this warning.
|
|
*/
|
|
void addAndMakeVisible (Component* const child, int zOrder = -1);
|
|
|
|
#endif
|
|
|
|
ResizableCornerComponent* resizableCorner;
|
|
ResizableBorderComponent* resizableBorder;
|
|
|
|
private:
|
|
Component* contentComponent;
|
|
bool resizeToFitContent, fullscreen;
|
|
ComponentDragger dragger;
|
|
Rectangle lastNonFullScreenPos;
|
|
ComponentBoundsConstrainer defaultConstrainer;
|
|
ComponentBoundsConstrainer* constrainer;
|
|
#ifdef JUCE_DEBUG
|
|
bool hasBeenResized;
|
|
#endif
|
|
|
|
void updateLastPos();
|
|
|
|
ResizableWindow (const ResizableWindow&);
|
|
const ResizableWindow& operator= (const ResizableWindow&);
|
|
|
|
// (xxx remove these eventually)
|
|
// temporarily here to stop old code compiling, as the parameters for these methods have changed..
|
|
void getBorderThickness (int& left, int& top, int& right, int& bottom);
|
|
// temporarily here to stop old code compiling, as the parameters for these methods have changed..
|
|
void getContentComponentBorder (int& left, int& top, int& right, int& bottom);
|
|
};
|
|
|
|
#endif // __JUCE_RESIZABLEWINDOW_JUCEHEADER__
|
|
/********* End of inlined file: juce_ResizableWindow.h *********/
|
|
|
|
/**
|
|
A resizable window with a title bar and maximise, minimise and close buttons.
|
|
|
|
This subclass of ResizableWindow creates a fairly standard type of window with
|
|
a title bar and various buttons. The name of the component is shown in the
|
|
title bar, and an icon can optionally be specified with setIcon().
|
|
|
|
All the methods available to a ResizableWindow are also available to this,
|
|
so it can easily be made resizable, minimised, maximised, etc.
|
|
|
|
It's not advisable to add child components directly to a DocumentWindow: put them
|
|
inside your content component instead. And overriding methods like resized(), moved(), etc
|
|
is also not recommended - instead override these methods for your content component.
|
|
(If for some obscure reason you do need to override these methods, always remember to
|
|
call the super-class's resized() method too, otherwise it'll fail to lay out the window
|
|
decorations correctly).
|
|
|
|
You can also automatically add a menu bar to the window, using the setMenuBar()
|
|
method.
|
|
|
|
@see ResizableWindow, DialogWindow
|
|
*/
|
|
class JUCE_API DocumentWindow : public ResizableWindow
|
|
{
|
|
public:
|
|
|
|
/** The set of available button-types that can be put on the title bar.
|
|
|
|
@see setTitleBarButtonsRequired
|
|
*/
|
|
enum TitleBarButtons
|
|
{
|
|
minimiseButton = 1,
|
|
maximiseButton = 2,
|
|
closeButton = 4,
|
|
|
|
/** A combination of all the buttons above. */
|
|
allButtons = 7
|
|
};
|
|
|
|
/** Creates a DocumentWindow.
|
|
|
|
@param name the name to give the component - this is also
|
|
the title shown at the top of the window. To change
|
|
this later, use setName()
|
|
@param backgroundColour the colour to use for filling the window's background.
|
|
@param requiredButtons specifies which of the buttons (close, minimise, maximise)
|
|
should be shown on the title bar. This value is a bitwise
|
|
combination of values from the TitleBarButtons enum. Note
|
|
that it can be "allButtons" to get them all. You
|
|
can change this later with the setTitleBarButtonsRequired()
|
|
method, which can also specify where they are positioned.
|
|
@param addToDesktop if true, the window will be automatically added to the
|
|
desktop; if false, you can use it as a child component
|
|
@see TitleBarButtons
|
|
*/
|
|
DocumentWindow (const String& name,
|
|
const Colour& backgroundColour,
|
|
const int requiredButtons,
|
|
const bool addToDesktop = true);
|
|
|
|
/** Destructor.
|
|
|
|
If a content component has been set with setContentComponent(), it
|
|
will be deleted.
|
|
*/
|
|
~DocumentWindow();
|
|
|
|
/** Changes the component's name.
|
|
|
|
(This is overridden from Component::setName() to cause a repaint, as
|
|
the name is what gets drawn across the window's title bar).
|
|
*/
|
|
void setName (const String& newName);
|
|
|
|
/** Sets an icon to show in the title bar, next to the title.
|
|
|
|
A copy is made internally of the image, so the caller can delete the
|
|
image after calling this. If 0 is passed-in, any existing icon will be
|
|
removed.
|
|
*/
|
|
void setIcon (const Image* imageToUse);
|
|
|
|
/** Changes the height of the title-bar. */
|
|
void setTitleBarHeight (const int newHeight);
|
|
|
|
/** Returns the current title bar height. */
|
|
int getTitleBarHeight() const;
|
|
|
|
/** Changes the set of title-bar buttons being shown.
|
|
|
|
@param requiredButtons specifies which of the buttons (close, minimise, maximise)
|
|
should be shown on the title bar. This value is a bitwise
|
|
combination of values from the TitleBarButtons enum. Note
|
|
that it can be "allButtons" to get them all.
|
|
@param positionTitleBarButtonsOnLeft if true, the buttons should go at the
|
|
left side of the bar; if false, they'll be placed at the right
|
|
*/
|
|
void setTitleBarButtonsRequired (const int requiredButtons,
|
|
const bool positionTitleBarButtonsOnLeft);
|
|
|
|
/** Sets whether the title should be centred within the window.
|
|
|
|
If true, the title text is shown in the middle of the title-bar; if false,
|
|
it'll be shown at the left of the bar.
|
|
*/
|
|
void setTitleBarTextCentred (const bool textShouldBeCentred);
|
|
|
|
/** Creates a menu inside this window.
|
|
|
|
@param menuBarModel this specifies a MenuBarModel that should be used to
|
|
generate the contents of a menu bar that will be placed
|
|
just below the title bar, and just above any content
|
|
component. If this value is zero, any existing menu bar
|
|
will be removed from the component; if non-zero, one will
|
|
be added if it's required.
|
|
@param menuBarHeight the height of the menu bar component, if one is needed. Pass a value of zero
|
|
or less to use the look-and-feel's default size.
|
|
*/
|
|
void setMenuBar (MenuBarModel* menuBarModel,
|
|
const int menuBarHeight = 0);
|
|
|
|
/** This method is called when the user tries to close the window.
|
|
|
|
This is triggered by the user clicking the close button, or using some other
|
|
OS-specific key shortcut or OS menu for getting rid of a window.
|
|
|
|
If the window is just a pop-up, you should override this closeButtonPressed()
|
|
method and make it delete the window in whatever way is appropriate for your
|
|
app. E.g. you might just want to call "delete this".
|
|
|
|
If your app is centred around this window such that the whole app should quit when
|
|
the window is closed, then you will probably want to use this method as an opportunity
|
|
to call JUCEApplication::quit(), and leave the window to be deleted later by your
|
|
JUCEApplication::shutdown() method. (Doing it this way means that your window will
|
|
still get cleaned-up if the app is quit by some other means (e.g. a cmd-Q on the mac
|
|
or closing it via the taskbar icon on Windows).
|
|
|
|
(Note that the DocumentWindow class overrides Component::userTriedToCloseWindow() and
|
|
redirects it to call this method, so any methods of closing the window that are
|
|
caught by userTriedToCloseWindow() will also end up here).
|
|
*/
|
|
virtual void closeButtonPressed();
|
|
|
|
/** Callback that is triggered when the minimise button is pressed.
|
|
|
|
The default implementation of this calls ResizableWindow::setMinimised(), but
|
|
you can override it to do more customised behaviour.
|
|
*/
|
|
virtual void minimiseButtonPressed();
|
|
|
|
/** Callback that is triggered when the maximise button is pressed, or when the
|
|
title-bar is double-clicked.
|
|
|
|
The default implementation of this calls ResizableWindow::setFullScreen(), but
|
|
you can override it to do more customised behaviour.
|
|
*/
|
|
virtual void maximiseButtonPressed();
|
|
|
|
/** Returns the close button, (or 0 if there isn't one). */
|
|
Button* getCloseButton() const throw();
|
|
|
|
/** Returns the minimise button, (or 0 if there isn't one). */
|
|
Button* getMinimiseButton() const throw();
|
|
|
|
/** Returns the maximise button, (or 0 if there isn't one). */
|
|
Button* getMaximiseButton() const throw();
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the window.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
textColourId = 0x1005701, /**< The colour to draw any text with. It's up to the look
|
|
and feel class how this is used. */
|
|
};
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void lookAndFeelChanged();
|
|
/** @internal */
|
|
const BorderSize getBorderThickness();
|
|
/** @internal */
|
|
const BorderSize getContentComponentBorder();
|
|
/** @internal */
|
|
void mouseDoubleClick (const MouseEvent& e);
|
|
/** @internal */
|
|
void userTriedToCloseWindow();
|
|
/** @internal */
|
|
void activeWindowStatusChanged();
|
|
/** @internal */
|
|
int getDesktopWindowStyleFlags() const;
|
|
/** @internal */
|
|
void parentHierarchyChanged();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int titleBarHeight, menuBarHeight, requiredButtons;
|
|
bool positionTitleBarButtonsOnLeft, drawTitleTextCentred;
|
|
Button* titleBarButtons [3];
|
|
Image* titleBarIcon;
|
|
MenuBarComponent* menuBar;
|
|
MenuBarModel* menuBarModel;
|
|
|
|
class ButtonListenerProxy : public ButtonListener
|
|
{
|
|
public:
|
|
ButtonListenerProxy();
|
|
void buttonClicked (Button* button);
|
|
|
|
DocumentWindow* owner;
|
|
|
|
} buttonListener;
|
|
|
|
int getBorderSize() const;
|
|
void repaintTitleBar();
|
|
|
|
DocumentWindow (const DocumentWindow&);
|
|
const DocumentWindow& operator= (const DocumentWindow&);
|
|
};
|
|
|
|
#endif // __JUCE_DOCUMENTWINDOW_JUCEHEADER__
|
|
/********* End of inlined file: juce_DocumentWindow.h *********/
|
|
|
|
class MultiDocumentPanel;
|
|
class MDITabbedComponentInternal;
|
|
|
|
/**
|
|
This is a derivative of DocumentWindow that is used inside a MultiDocumentPanel
|
|
component.
|
|
|
|
It's like a normal DocumentWindow but has some extra functionality to make sure
|
|
everything works nicely inside a MultiDocumentPanel.
|
|
|
|
@see MultiDocumentPanel
|
|
*/
|
|
class JUCE_API MultiDocumentPanelWindow : public DocumentWindow
|
|
{
|
|
public:
|
|
|
|
/**
|
|
*/
|
|
MultiDocumentPanelWindow (const Colour& backgroundColour);
|
|
|
|
/** Destructor. */
|
|
~MultiDocumentPanelWindow();
|
|
|
|
/** @internal */
|
|
void maximiseButtonPressed();
|
|
/** @internal */
|
|
void closeButtonPressed();
|
|
/** @internal */
|
|
void activeWindowStatusChanged();
|
|
/** @internal */
|
|
void broughtToFront();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
void updateOrder();
|
|
MultiDocumentPanel* getOwner() const throw();
|
|
};
|
|
|
|
/**
|
|
A component that contains a set of other components either in floating windows
|
|
or tabs.
|
|
|
|
This acts as a panel that can be used to hold a set of open document windows, with
|
|
different layout modes.
|
|
|
|
Use addDocument() and closeDocument() to add or remove components from the
|
|
panel - never use any of the Component methods to access the panel's child
|
|
components directly, as these are managed internally.
|
|
*/
|
|
class JUCE_API MultiDocumentPanel : public Component,
|
|
private ComponentListener
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty panel.
|
|
|
|
Use addDocument() and closeDocument() to add or remove components from the
|
|
panel - never use any of the Component methods to access the panel's child
|
|
components directly, as these are managed internally.
|
|
*/
|
|
MultiDocumentPanel();
|
|
|
|
/** Destructor.
|
|
|
|
When deleted, this will call closeAllDocuments (false) to make sure all its
|
|
components are deleted. If you need to make sure all documents are saved
|
|
before closing, then you should call closeAllDocuments (true) and check that
|
|
it returns true before deleting the panel.
|
|
*/
|
|
~MultiDocumentPanel();
|
|
|
|
/** Tries to close all the documents.
|
|
|
|
If checkItsOkToCloseFirst is true, then the tryToCloseDocument() method will
|
|
be called for each open document, and any of these calls fails, this method
|
|
will stop and return false, leaving some documents still open.
|
|
|
|
If checkItsOkToCloseFirst is false, then all documents will be closed
|
|
unconditionally.
|
|
|
|
@see closeDocument
|
|
*/
|
|
bool closeAllDocuments (const bool checkItsOkToCloseFirst);
|
|
|
|
/** Adds a document component to the panel.
|
|
|
|
If the number of documents would exceed the limit set by setMaximumNumDocuments() then
|
|
this will fail and return false. (If it does fail, the component passed-in will not be
|
|
deleted, even if deleteWhenRemoved was set to true).
|
|
|
|
The MultiDocumentPanel will deal with creating a window border to go around your component,
|
|
so just pass in the bare content component here, no need to give it a ResizableWindow
|
|
or DocumentWindow.
|
|
|
|
@param component the component to add
|
|
@param backgroundColour the background colour to use to fill the component's
|
|
window or tab
|
|
@param deleteWhenRemoved if true, then when the component is removed by closeDocument()
|
|
or closeAllDocuments(), then it will be deleted. If false, then
|
|
the caller must handle the component's deletion
|
|
*/
|
|
bool addDocument (Component* const component,
|
|
const Colour& backgroundColour,
|
|
const bool deleteWhenRemoved);
|
|
|
|
/** Closes one of the documents.
|
|
|
|
If checkItsOkToCloseFirst is true, then the tryToCloseDocument() method will
|
|
be called, and if it fails, this method will return false without closing the
|
|
document.
|
|
|
|
If checkItsOkToCloseFirst is false, then the documents will be closed
|
|
unconditionally.
|
|
|
|
The component will be deleted if the deleteWhenRemoved parameter was set to
|
|
true when it was added with addDocument.
|
|
|
|
@see addDocument, closeAllDocuments
|
|
*/
|
|
bool closeDocument (Component* component,
|
|
const bool checkItsOkToCloseFirst);
|
|
|
|
/** Returns the number of open document windows.
|
|
|
|
@see getDocument
|
|
*/
|
|
int getNumDocuments() const throw();
|
|
|
|
/** Returns one of the open documents.
|
|
|
|
The order of the documents in this array may change when they are added, removed
|
|
or moved around.
|
|
|
|
@see getNumDocuments
|
|
*/
|
|
Component* getDocument (const int index) const throw();
|
|
|
|
/** Returns the document component that is currently focused or on top.
|
|
|
|
If currently using floating windows, then this will be the component in the currently
|
|
active window, or the top component if none are active.
|
|
|
|
If it's currently in tabbed mode, then it'll return the component in the active tab.
|
|
|
|
@see setActiveDocument
|
|
*/
|
|
Component* getActiveDocument() const throw();
|
|
|
|
/** Makes one of the components active and brings it to the top.
|
|
|
|
@see getActiveDocument
|
|
*/
|
|
void setActiveDocument (Component* component);
|
|
|
|
/** Callback which gets invoked when the currently-active document changes. */
|
|
virtual void activeDocumentChanged();
|
|
|
|
/** Sets a limit on how many windows can be open at once.
|
|
|
|
If this is zero or less there's no limit (the default). addDocument() will fail
|
|
if this number is exceeded.
|
|
*/
|
|
void setMaximumNumDocuments (const int maximumNumDocuments);
|
|
|
|
/** Sets an option to make the document fullscreen if there's only one document open.
|
|
|
|
If set to true, then if there's only one document, it'll fill the whole of this
|
|
component without tabs or a window border. If false, then tabs or a window
|
|
will always be shown, even if there's only one document. If there's more than
|
|
one document open, then this option makes no difference.
|
|
*/
|
|
void useFullscreenWhenOneDocument (const bool shouldUseTabs);
|
|
|
|
/** Returns the result of the last time useFullscreenWhenOneDocument() was called.
|
|
*/
|
|
bool isFullscreenWhenOneDocument() const throw();
|
|
|
|
/** The different layout modes available. */
|
|
enum LayoutMode
|
|
{
|
|
FloatingWindows, /**< In this mode, there are overlapping DocumentWindow components for each document. */
|
|
MaximisedWindowsWithTabs /**< In this mode, a TabbedComponent is used to show one document at a time. */
|
|
};
|
|
|
|
/** Changes the panel's mode.
|
|
|
|
@see LayoutMode, getLayoutMode
|
|
*/
|
|
void setLayoutMode (const LayoutMode newLayoutMode);
|
|
|
|
/** Returns the current layout mode. */
|
|
LayoutMode getLayoutMode() const throw() { return mode; }
|
|
|
|
/** Sets the background colour for the whole panel.
|
|
|
|
Each document has its own background colour, but this is the one used to fill the areas
|
|
behind them.
|
|
*/
|
|
void setBackgroundColour (const Colour& newBackgroundColour);
|
|
|
|
/** Returns the current background colour.
|
|
|
|
@see setBackgroundColour
|
|
*/
|
|
const Colour& getBackgroundColour() const throw() { return backgroundColour; }
|
|
|
|
/** A subclass must override this to say whether its currently ok for a document
|
|
to be closed.
|
|
|
|
This method is called by closeDocument() and closeAllDocuments() to indicate that
|
|
a document should be saved if possible, ready for it to be closed.
|
|
|
|
If this method returns true, then it means the document is ok and can be closed.
|
|
|
|
If it returns false, then it means that the closeDocument() method should stop
|
|
and not close.
|
|
|
|
Normally, you'd use this method to ask the user if they want to save any changes,
|
|
then return true if the save operation went ok. If the user cancelled the save
|
|
operation you could return false here to abort the close operation.
|
|
|
|
If your component is based on the FileBasedDocument class, then you'd probably want
|
|
to call FileBasedDocument::saveIfNeededAndUserAgrees() and return true if this returned
|
|
FileBasedDocument::savedOk
|
|
|
|
@see closeDocument, FileBasedDocument::saveIfNeededAndUserAgrees()
|
|
*/
|
|
virtual bool tryToCloseDocument (Component* component) = 0;
|
|
|
|
/** Creates a new window to be used for a document.
|
|
|
|
The default implementation of this just returns a basic MultiDocumentPanelWindow object,
|
|
but you might want to override it to return a custom component.
|
|
*/
|
|
virtual MultiDocumentPanelWindow* createNewDocumentWindow();
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void componentNameChanged (Component&);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
LayoutMode mode;
|
|
Array <Component*> components;
|
|
TabbedComponent* tabComponent;
|
|
Colour backgroundColour;
|
|
int maximumNumDocuments, numDocsBeforeTabsUsed;
|
|
|
|
friend class MultiDocumentPanelWindow;
|
|
friend class MDITabbedComponentInternal;
|
|
|
|
Component* getContainerComp (Component* c) const;
|
|
void updateOrder();
|
|
|
|
void addWindow (Component* component);
|
|
};
|
|
|
|
#endif // __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__
|
|
/********* End of inlined file: juce_MultiDocumentPanel.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_SCROLLBAR_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_StretchableLayoutManager.h *********/
|
|
#ifndef __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__
|
|
#define __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__
|
|
|
|
/**
|
|
For laying out a set of components, where the components have preferred sizes
|
|
and size limits, but where they are allowed to stretch to fill the available
|
|
space.
|
|
|
|
For example, if you have a component containing several other components, and
|
|
each one should be given a share of the total size, you could use one of these
|
|
to resize the child components when the parent component is resized. Then
|
|
you could add a StretchableLayoutResizerBar to easily let the user rescale them.
|
|
|
|
A StretchableLayoutManager operates only in one dimension, so if you have a set
|
|
of components stacked vertically on top of each other, you'd use one to manage their
|
|
heights. To build up complex arrangements of components, e.g. for applications
|
|
with multiple nested panels, you would use more than one StretchableLayoutManager.
|
|
E.g. by using two (one vertical, one horizontal), you could create a resizable
|
|
spreadsheet-style table.
|
|
|
|
E.g.
|
|
@code
|
|
class MyComp : public Component
|
|
{
|
|
StretchableLayoutManager myLayout;
|
|
|
|
MyComp()
|
|
{
|
|
myLayout.setItemLayout (0, // for item 0
|
|
50, 100, // must be between 50 and 100 pixels in size
|
|
-0.6); // and its preferred size is 60% of the total available space
|
|
|
|
myLayout.setItemLayout (1, // for item 1
|
|
-0.2, -0.6, // size must be between 20% and 60% of the available space
|
|
50); // and its preferred size is 50 pixels
|
|
}
|
|
|
|
void resized()
|
|
{
|
|
// make a list of two of our child components that we want to reposition
|
|
Component* comps[] = { myComp1, myComp2 };
|
|
|
|
// this will position the 2 components, one above the other, to fit
|
|
// vertically into the rectangle provided.
|
|
myLayout.layOutComponents (comps, 2,
|
|
0, 0, getWidth(), getHeight(),
|
|
true);
|
|
}
|
|
};
|
|
@endcode
|
|
|
|
@see StretchableLayoutResizerBar
|
|
*/
|
|
class JUCE_API StretchableLayoutManager
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty layout.
|
|
|
|
You'll need to add some item properties to the layout before it can be used
|
|
to resize things - see setItemLayout().
|
|
*/
|
|
StretchableLayoutManager();
|
|
|
|
/** Destructor. */
|
|
~StretchableLayoutManager();
|
|
|
|
/** For a numbered item, this sets its size limits and preferred size.
|
|
|
|
@param itemIndex the index of the item to change.
|
|
@param minimumSize the minimum size that this item is allowed to be - a positive number
|
|
indicates an absolute size in pixels. A negative number indicates a
|
|
proportion of the available space (e.g -0.5 is 50%)
|
|
@param maximumSize the maximum size that this item is allowed to be - a positive number
|
|
indicates an absolute size in pixels. A negative number indicates a
|
|
proportion of the available space
|
|
@param preferredSize the size that this item would like to be, if there's enough room. A
|
|
positive number indicates an absolute size in pixels. A negative number
|
|
indicates a proportion of the available space
|
|
@see getItemLayout
|
|
*/
|
|
void setItemLayout (const int itemIndex,
|
|
const double minimumSize,
|
|
const double maximumSize,
|
|
const double preferredSize);
|
|
|
|
/** For a numbered item, this returns its size limits and preferred size.
|
|
|
|
@param itemIndex the index of the item.
|
|
@param minimumSize the minimum size that this item is allowed to be - a positive number
|
|
indicates an absolute size in pixels. A negative number indicates a
|
|
proportion of the available space (e.g -0.5 is 50%)
|
|
@param maximumSize the maximum size that this item is allowed to be - a positive number
|
|
indicates an absolute size in pixels. A negative number indicates a
|
|
proportion of the available space
|
|
@param preferredSize the size that this item would like to be, if there's enough room. A
|
|
positive number indicates an absolute size in pixels. A negative number
|
|
indicates a proportion of the available space
|
|
@returns false if the item's properties hadn't been set
|
|
@see setItemLayout
|
|
*/
|
|
bool getItemLayout (const int itemIndex,
|
|
double& minimumSize,
|
|
double& maximumSize,
|
|
double& preferredSize) const;
|
|
|
|
/** Clears all the properties that have been set with setItemLayout() and resets
|
|
this object to its initial state.
|
|
*/
|
|
void clearAllItems();
|
|
|
|
/** Takes a set of components that correspond to the layout's items, and positions
|
|
them to fill a space.
|
|
|
|
This will try to give each item its preferred size, whether that's a relative size
|
|
or an absolute one.
|
|
|
|
@param components an array of components that correspond to each of the
|
|
numbered items that the StretchableLayoutManager object
|
|
has been told about with setItemLayout()
|
|
@param numComponents the number of components in the array that is passed-in. This
|
|
should be the same as the number of items this object has been
|
|
told about.
|
|
@param x the left of the rectangle in which the components should
|
|
be laid out
|
|
@param y the top of the rectangle in which the components should
|
|
be laid out
|
|
@param width the width of the rectangle in which the components should
|
|
be laid out
|
|
@param height the height of the rectangle in which the components should
|
|
be laid out
|
|
@param vertically if true, the components will be positioned in a vertical stack,
|
|
so that they fill the height of the rectangle. If false, they
|
|
will be placed side-by-side in a horizontal line, filling the
|
|
available width
|
|
@param resizeOtherDimension if true, this means that the components will have their
|
|
other dimension resized to fit the space - i.e. if the 'vertically'
|
|
parameter is true, their x-positions and widths are adjusted to fit
|
|
the x and width parameters; if 'vertically' is false, their y-positions
|
|
and heights are adjusted to fit the y and height parameters.
|
|
*/
|
|
void layOutComponents (Component** const components,
|
|
int numComponents,
|
|
int x, int y, int width, int height,
|
|
const bool vertically,
|
|
const bool resizeOtherDimension);
|
|
|
|
/** Returns the current position of one of the items.
|
|
|
|
This is only a valid call after layOutComponents() has been called, as it
|
|
returns the last position that this item was placed at. If the layout was
|
|
vertical, the value returned will be the y position of the top of the item,
|
|
relative to the top of the rectangle in which the items were placed (so for
|
|
example, item 0 will always have position of 0, even in the rectangle passed
|
|
in to layOutComponents() wasn't at y = 0). If the layout was done horizontally,
|
|
the position returned is the item's left-hand position, again relative to the
|
|
x position of the rectangle used.
|
|
|
|
@see getItemCurrentSize, setItemPosition
|
|
*/
|
|
int getItemCurrentPosition (const int itemIndex) const;
|
|
|
|
/** Returns the current size of one of the items.
|
|
|
|
This is only meaningful after layOutComponents() has been called, as it
|
|
returns the last size that this item was given. If the layout was done
|
|
vertically, it'll return the item's height in pixels; if it was horizontal,
|
|
it'll return its width.
|
|
|
|
@see getItemCurrentRelativeSize
|
|
*/
|
|
int getItemCurrentAbsoluteSize (const int itemIndex) const;
|
|
|
|
/** Returns the current size of one of the items.
|
|
|
|
This is only meaningful after layOutComponents() has been called, as it
|
|
returns the last size that this item was given. If the layout was done
|
|
vertically, it'll return a negative value representing the item's height relative
|
|
to the last size used for laying the components out; if the layout was done
|
|
horizontally it'll be the proportion of its width.
|
|
|
|
@see getItemCurrentAbsoluteSize
|
|
*/
|
|
double getItemCurrentRelativeSize (const int itemIndex) const;
|
|
|
|
/** Moves one of the items, shifting along any other items as necessary in
|
|
order to get it to the desired position.
|
|
|
|
Calling this method will also update the preferred sizes of the items it
|
|
shuffles along, so that they reflect their new positions.
|
|
|
|
(This is the method that a StretchableLayoutResizerBar uses to shift the items
|
|
about when it's dragged).
|
|
|
|
@param itemIndex the item to move
|
|
@param newPosition the absolute position that you'd like this item to move
|
|
to. The item might not be able to always reach exactly this position,
|
|
because other items may have minimum sizes that constrain how
|
|
far it can go
|
|
*/
|
|
void setItemPosition (const int itemIndex,
|
|
int newPosition);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
struct ItemLayoutProperties
|
|
{
|
|
int itemIndex;
|
|
int currentSize;
|
|
double minSize, maxSize, preferredSize;
|
|
};
|
|
|
|
OwnedArray <ItemLayoutProperties> items;
|
|
int totalSize;
|
|
|
|
static int sizeToRealSize (double size, int totalSpace);
|
|
|
|
ItemLayoutProperties* getInfoFor (const int itemIndex) const;
|
|
|
|
void setTotalSize (const int newTotalSize);
|
|
|
|
int fitComponentsIntoSpace (const int startIndex,
|
|
const int endIndex,
|
|
const int availableSpace,
|
|
int startPos);
|
|
|
|
int getMinimumSizeOfItems (const int startIndex, const int endIndex) const;
|
|
int getMaximumSizeOfItems (const int startIndex, const int endIndex) const;
|
|
|
|
void updatePrefSizesToMatchCurrentPositions();
|
|
|
|
StretchableLayoutManager (const StretchableLayoutManager&);
|
|
const StretchableLayoutManager& operator= (const StretchableLayoutManager&);
|
|
};
|
|
|
|
#endif // __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__
|
|
/********* End of inlined file: juce_StretchableLayoutManager.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_StretchableLayoutResizerBar.h *********/
|
|
#ifndef __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__
|
|
#define __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__
|
|
|
|
/**
|
|
A component that acts as one of the vertical or horizontal bars you see being
|
|
used to resize panels in a window.
|
|
|
|
One of these acts with a StretchableLayoutManager to resize the other components.
|
|
|
|
@see StretchableLayoutManager
|
|
*/
|
|
class JUCE_API StretchableLayoutResizerBar : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates a resizer bar for use on a specified layout.
|
|
|
|
@param layoutToUse the layout that will be affected when this bar
|
|
is dragged
|
|
@param itemIndexInLayout the item index in the layout that corresponds to
|
|
this bar component. You'll need to set up the item
|
|
properties in a suitable way for a divider bar, e.g.
|
|
for an 8-pixel wide bar which, you could call
|
|
myLayout->setItemLayout (barIndex, 8, 8, 8)
|
|
@param isBarVertical true if it's an upright bar that you drag left and
|
|
right; false for a horizontal one that you drag up and
|
|
down
|
|
*/
|
|
StretchableLayoutResizerBar (StretchableLayoutManager* const layoutToUse,
|
|
const int itemIndexInLayout,
|
|
const bool isBarVertical);
|
|
|
|
/** Destructor. */
|
|
~StretchableLayoutResizerBar();
|
|
|
|
/** This is called when the bar is dragged.
|
|
|
|
This method must update the positions of any components whose position is
|
|
determined by the StretchableLayoutManager, because they might have just
|
|
moved.
|
|
|
|
The default implementation calls the resized() method of this component's
|
|
parent component, because that's often where you're likely to apply the
|
|
layout, but it can be overridden for more specific needs.
|
|
*/
|
|
virtual void hasBeenMoved();
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent& e);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
StretchableLayoutManager* layout;
|
|
int itemIndex, mouseDownPos;
|
|
bool isVertical;
|
|
|
|
StretchableLayoutResizerBar (const StretchableLayoutResizerBar&);
|
|
const StretchableLayoutResizerBar& operator= (const StretchableLayoutResizerBar&);
|
|
};
|
|
|
|
#endif // __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__
|
|
/********* End of inlined file: juce_StretchableLayoutResizerBar.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_StretchableObjectResizer.h *********/
|
|
#ifndef __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__
|
|
#define __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__
|
|
|
|
/**
|
|
A utility class for fitting a set of objects whose sizes can vary between
|
|
a minimum and maximum size, into a space.
|
|
|
|
This is a trickier algorithm than it would first seem, so I've put it in this
|
|
class to allow it to be shared by various bits of code.
|
|
|
|
To use it, create one of these objects, call addItem() to add the list of items
|
|
you need, then call resizeToFit(), which will change all their sizes. You can
|
|
then retrieve the new sizes with getItemSize() and getNumItems().
|
|
|
|
It's currently used by the TableHeaderComponent for stretching out the table
|
|
headings to fill the table's width.
|
|
*/
|
|
class StretchableObjectResizer
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty object resizer. */
|
|
StretchableObjectResizer();
|
|
|
|
/** Destructor. */
|
|
~StretchableObjectResizer();
|
|
|
|
/** Adds an item to the list.
|
|
|
|
The order parameter lets you specify groups of items that are resized first when some
|
|
space needs to be found. Those items with an order of 0 will be the first ones to be
|
|
resized, and if that doesn't provide enough space to meet the requirements, the algorithm
|
|
will then try resizing the items with an order of 1, then 2, and so on.
|
|
*/
|
|
void addItem (const double currentSize,
|
|
const double minSize,
|
|
const double maxSize,
|
|
const int order = 0);
|
|
|
|
/** Resizes all the items to fit this amount of space.
|
|
|
|
This will attempt to fit them in without exceeding each item's miniumum and
|
|
maximum sizes. In cases where none of the items can be expanded or enlarged any
|
|
further, the final size may be greater or less than the size passed in.
|
|
|
|
After calling this method, you can retrieve the new sizes with the getItemSize()
|
|
method.
|
|
*/
|
|
void resizeToFit (const double targetSize);
|
|
|
|
/** Returns the number of items that have been added. */
|
|
int getNumItems() const throw() { return items.size(); }
|
|
|
|
/** Returns the size of one of the items. */
|
|
double getItemSize (const int index) const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
struct Item
|
|
{
|
|
double size;
|
|
double minSize;
|
|
double maxSize;
|
|
int order;
|
|
};
|
|
|
|
OwnedArray <Item> items;
|
|
|
|
StretchableObjectResizer (const StretchableObjectResizer&);
|
|
const StretchableObjectResizer& operator= (const StretchableObjectResizer&);
|
|
};
|
|
|
|
#endif // __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__
|
|
/********* End of inlined file: juce_StretchableObjectResizer.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TABBEDBUTTONBAR_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_VIEWPORT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DirectoryContentsDisplayComponent.h *********/
|
|
#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DirectoryContentsList.h *********/
|
|
#ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__
|
|
#define __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileFilter.h *********/
|
|
#ifndef __JUCE_FILEFILTER_JUCEHEADER__
|
|
#define __JUCE_FILEFILTER_JUCEHEADER__
|
|
|
|
/**
|
|
Interface for deciding which files are suitable for something.
|
|
|
|
For example, this is used by DirectoryContentsList to select which files
|
|
go into the list.
|
|
|
|
@see WildcardFileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent
|
|
*/
|
|
class JUCE_API FileFilter
|
|
{
|
|
public:
|
|
|
|
/** Creates a filter with the given description.
|
|
|
|
The description can be returned later with the getDescription() method.
|
|
*/
|
|
FileFilter (const String& filterDescription);
|
|
|
|
/** Destructor. */
|
|
virtual ~FileFilter();
|
|
|
|
/** Returns the description that the filter was created with. */
|
|
const String& getDescription() const throw();
|
|
|
|
/** Should return true if this file is suitable for inclusion in whatever context
|
|
the object is being used.
|
|
*/
|
|
virtual bool isFileSuitable (const File& file) const = 0;
|
|
|
|
/** Should return true if this directory is suitable for inclusion in whatever context
|
|
the object is being used.
|
|
*/
|
|
virtual bool isDirectorySuitable (const File& file) const = 0;
|
|
|
|
protected:
|
|
|
|
String description;
|
|
};
|
|
|
|
#endif // __JUCE_FILEFILTER_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileFilter.h *********/
|
|
|
|
/**
|
|
A class to asynchronously scan for details about the files in a directory.
|
|
|
|
This keeps a list of files and some information about them, using a background
|
|
thread to scan for more files. As files are found, it broadcasts change messages
|
|
to tell any listeners.
|
|
|
|
@see FileListComponent, FileBrowserComponent
|
|
*/
|
|
class JUCE_API DirectoryContentsList : public ChangeBroadcaster,
|
|
public TimeSliceClient
|
|
{
|
|
public:
|
|
|
|
/** Creates a directory list.
|
|
|
|
To set the directory it should point to, use setDirectory(), which will
|
|
also start it scanning for files on the background thread.
|
|
|
|
When the background thread finds and adds new files to this list, the
|
|
ChangeBroadcaster class will send a change message, so you can register
|
|
listeners and update them when the list changes.
|
|
|
|
@param fileFilter an optional filter to select which files are
|
|
included in the list. If this is 0, then all files
|
|
and directories are included. Make sure that the
|
|
filter doesn't get deleted during the lifetime of this
|
|
object
|
|
@param threadToUse a thread object that this list can use
|
|
to scan for files as a background task. Make sure
|
|
that the thread you give it has been started, or you
|
|
won't get any files!
|
|
*/
|
|
DirectoryContentsList (const FileFilter* const fileFilter,
|
|
TimeSliceThread& threadToUse);
|
|
|
|
/** Destructor. */
|
|
~DirectoryContentsList();
|
|
|
|
/** Sets the directory to look in for files.
|
|
|
|
If the directory that's passed in is different to the current one, this will
|
|
also start the background thread scanning it for files.
|
|
*/
|
|
void setDirectory (const File& directory,
|
|
const bool includeDirectories,
|
|
const bool includeFiles);
|
|
|
|
/** Returns the directory that's currently being used. */
|
|
const File& getDirectory() const throw();
|
|
|
|
/** Clears the list, and stops the thread scanning for files. */
|
|
void clear();
|
|
|
|
/** Clears the list and restarts scanning the directory for files. */
|
|
void refresh();
|
|
|
|
/** True if the background thread hasn't yet finished scanning for files. */
|
|
bool isStillLoading() const;
|
|
|
|
/** Tells the list whether or not to ignore hidden files.
|
|
|
|
By default these are ignored.
|
|
*/
|
|
void setIgnoresHiddenFiles (const bool shouldIgnoreHiddenFiles);
|
|
|
|
/** Returns true if hidden files are ignored.
|
|
@see setIgnoresHiddenFiles
|
|
*/
|
|
bool ignoresHiddenFiles() const throw() { return ignoreHiddenFiles; }
|
|
|
|
/** Contains cached information about one of the files in a DirectoryContentsList.
|
|
*/
|
|
struct FileInfo
|
|
{
|
|
|
|
/** The filename.
|
|
|
|
This isn't a full pathname, it's just the last part of the path, same as you'd
|
|
get from File::getFileName().
|
|
|
|
To get the full pathname, use DirectoryContentsList::getDirectory().getChildFile (filename).
|
|
*/
|
|
String filename;
|
|
|
|
/** File size in bytes. */
|
|
int64 fileSize;
|
|
|
|
/** File modification time.
|
|
|
|
As supplied by File::getLastModificationTime().
|
|
*/
|
|
Time modificationTime;
|
|
|
|
/** File creation time.
|
|
|
|
As supplied by File::getCreationTime().
|
|
*/
|
|
Time creationTime;
|
|
|
|
/** True if the file is a directory. */
|
|
bool isDirectory;
|
|
|
|
/** True if the file is read-only. */
|
|
bool isReadOnly;
|
|
};
|
|
|
|
/** Returns the number of files currently available in the list.
|
|
|
|
The info about one of these files can be retrieved with getFileInfo() or
|
|
getFile().
|
|
|
|
Obviously as the background thread runs and scans the directory for files, this
|
|
number will change.
|
|
|
|
@see getFileInfo, getFile
|
|
*/
|
|
int getNumFiles() const;
|
|
|
|
/** Returns the cached information about one of the files in the list.
|
|
|
|
If the index is in-range, this will return true and will copy the file's details
|
|
to the structure that is passed-in.
|
|
|
|
If it returns false, then the index wasn't in range, and the structure won't
|
|
be affected.
|
|
|
|
@see getNumFiles, getFile
|
|
*/
|
|
bool getFileInfo (const int index,
|
|
FileInfo& resultInfo) const;
|
|
|
|
/** Returns one of the files in the list.
|
|
|
|
@param index should be less than getNumFiles(). If this is out-of-range, the
|
|
return value will be File::nonexistent
|
|
@see getNumFiles, getFileInfo
|
|
*/
|
|
const File getFile (const int index) const;
|
|
|
|
/** Returns the file filter being used.
|
|
|
|
The filter is specified in the constructor.
|
|
*/
|
|
const FileFilter* getFilter() const throw() { return fileFilter; }
|
|
|
|
/** @internal */
|
|
bool useTimeSlice();
|
|
/** @internal */
|
|
TimeSliceThread& getTimeSliceThread() throw() { return thread; }
|
|
/** @internal */
|
|
static int compareElements (const DirectoryContentsList::FileInfo* const first,
|
|
const DirectoryContentsList::FileInfo* const second) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
File root;
|
|
const FileFilter* fileFilter;
|
|
TimeSliceThread& thread;
|
|
bool includeDirectories, includeFiles, ignoreHiddenFiles;
|
|
|
|
CriticalSection fileListLock;
|
|
OwnedArray <FileInfo> files;
|
|
|
|
void* volatile fileFindHandle;
|
|
bool volatile shouldStop;
|
|
|
|
void changed();
|
|
bool checkNextFile (bool& hasChanged);
|
|
bool addFile (const String& filename, const bool isDir, const bool isHidden,
|
|
const int64 fileSize, const Time& modTime,
|
|
const Time& creationTime, const bool isReadOnly);
|
|
|
|
DirectoryContentsList (const DirectoryContentsList&);
|
|
const DirectoryContentsList& operator= (const DirectoryContentsList&);
|
|
};
|
|
|
|
#endif // __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__
|
|
/********* End of inlined file: juce_DirectoryContentsList.h *********/
|
|
|
|
/********* Start of inlined file: juce_FileBrowserListener.h *********/
|
|
#ifndef __JUCE_FILEBROWSERLISTENER_JUCEHEADER__
|
|
#define __JUCE_FILEBROWSERLISTENER_JUCEHEADER__
|
|
|
|
/**
|
|
A listener for user selection events in a file browser.
|
|
|
|
This is used by a FileBrowserComponent or FileListComponent.
|
|
*/
|
|
class JUCE_API FileBrowserListener
|
|
{
|
|
public:
|
|
|
|
/** Destructor. */
|
|
virtual ~FileBrowserListener();
|
|
|
|
/** Callback when the user selects a different file in the browser. */
|
|
virtual void selectionChanged() = 0;
|
|
|
|
/** Callback when the user clicks on a file in the browser. */
|
|
virtual void fileClicked (const File& file, const MouseEvent& e) = 0;
|
|
|
|
/** Callback when the user double-clicks on a file in the browser. */
|
|
virtual void fileDoubleClicked (const File& file) = 0;
|
|
};
|
|
|
|
#endif // __JUCE_FILEBROWSERLISTENER_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileBrowserListener.h *********/
|
|
|
|
/**
|
|
A base class for components that display a list of the files in a directory.
|
|
|
|
@see DirectoryContentsList
|
|
*/
|
|
class JUCE_API DirectoryContentsDisplayComponent
|
|
{
|
|
public:
|
|
|
|
/**
|
|
*/
|
|
DirectoryContentsDisplayComponent (DirectoryContentsList& listToShow);
|
|
|
|
/** Destructor. */
|
|
virtual ~DirectoryContentsDisplayComponent();
|
|
|
|
/** Returns the file that the user has currently selected.
|
|
|
|
Returns File::nonexistent if none is selected.
|
|
*/
|
|
virtual const File getSelectedFile() const = 0;
|
|
|
|
/** Scrolls this view to the top. */
|
|
virtual void scrollToTop() = 0;
|
|
|
|
/** Adds a listener to be told when files are selected or clicked.
|
|
|
|
@see removeListener
|
|
*/
|
|
void addListener (FileBrowserListener* const listener) throw();
|
|
|
|
/** Removes a listener.
|
|
|
|
@see addListener
|
|
*/
|
|
void removeListener (FileBrowserListener* const listener) throw();
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the label.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
Note that you can also use the constants from TextEditor::ColourIds to change the
|
|
colour of the text editor that is opened when a label is editable.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
highlightColourId = 0x1000540, /**< The colour to use to fill a highlighted row of the list. */
|
|
textColourId = 0x1000541, /**< The colour for the text. */
|
|
};
|
|
|
|
/** @internal */
|
|
void sendSelectionChangeMessage();
|
|
/** @internal */
|
|
void sendDoubleClickMessage (const File& file);
|
|
/** @internal */
|
|
void sendMouseClickMessage (const File& file, const MouseEvent& e);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
DirectoryContentsList& fileList;
|
|
SortedSet <void*> listeners;
|
|
|
|
DirectoryContentsDisplayComponent (const DirectoryContentsDisplayComponent&);
|
|
const DirectoryContentsDisplayComponent& operator= (const DirectoryContentsDisplayComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_DirectoryContentsDisplayComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileBrowserComponent.h *********/
|
|
#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FilePreviewComponent.h *********/
|
|
#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
Base class for components that live inside a file chooser dialog box and
|
|
show previews of the files that get selected.
|
|
|
|
One of these allows special extra information to be displayed for files
|
|
in a dialog box as the user selects them. Each time the current file or
|
|
directory is changed, the selectedFileChanged() method will be called
|
|
to allow it to update itself appropriately.
|
|
|
|
@see FileChooser, ImagePreviewComponent
|
|
*/
|
|
class JUCE_API FilePreviewComponent : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates a FilePreviewComponent. */
|
|
FilePreviewComponent();
|
|
|
|
/** Destructor. */
|
|
~FilePreviewComponent();
|
|
|
|
/** Called to indicate that the user's currently selected file has changed.
|
|
|
|
@param newSelectedFile the newly selected file or directory, which may be
|
|
File::nonexistent if none is selected.
|
|
*/
|
|
virtual void selectedFileChanged (const File& newSelectedFile) = 0;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
FilePreviewComponent (const FilePreviewComponent&);
|
|
const FilePreviewComponent& operator= (const FilePreviewComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_FilePreviewComponent.h *********/
|
|
|
|
/**
|
|
A component for browsing and selecting a file or directory to open or save.
|
|
|
|
This contains a FileListComponent and adds various boxes and controls for
|
|
navigating and selecting a file. It can work in different modes so that it can
|
|
be used for loading or saving a file, or for choosing a directory.
|
|
|
|
@see FileChooserDialogBox, FileChooser, FileListComponent
|
|
*/
|
|
class JUCE_API FileBrowserComponent : public Component,
|
|
public ChangeBroadcaster,
|
|
private FileBrowserListener,
|
|
private TextEditorListener,
|
|
private ButtonListener,
|
|
private ComboBoxListener
|
|
{
|
|
public:
|
|
|
|
/** Various modes that the browser can be used in.
|
|
|
|
One of these is passed into the constructor.
|
|
*/
|
|
enum FileChooserMode
|
|
{
|
|
loadFileMode, /**< the component should allow the user to choose an existing
|
|
file with the intention of opening it. */
|
|
saveFileMode, /**< the component should allow the user to specify the name of
|
|
a file that will be used to save something. */
|
|
chooseDirectoryMode /**< the component should allow the user to select an existing
|
|
directory. */
|
|
};
|
|
|
|
/** Creates a FileBrowserComponent.
|
|
|
|
@param browserMode The intended purpose for the browser - see the
|
|
FileChooserMode enum for the various options
|
|
@param initialFileOrDirectory The file or directory that should be selected when
|
|
the component begins. If this is File::nonexistent,
|
|
a default directory will be chosen.
|
|
@param fileFilter an optional filter to use to determine which files
|
|
are shown. If this is 0 then all files are displayed. Note
|
|
that a pointer is kept internally to this object, so
|
|
make sure that it is not deleted before the browser object
|
|
is deleted.
|
|
@param previewComp an optional preview component that will be used to
|
|
show previews of files that the user selects
|
|
@param useTreeView if this is false, the files are shown in a list; if true,
|
|
they are shown in a treeview
|
|
@param filenameTextBoxIsReadOnly if true, the user won't be allowed to type their own
|
|
text into the filename box.
|
|
*/
|
|
FileBrowserComponent (FileChooserMode browserMode,
|
|
const File& initialFileOrDirectory,
|
|
const FileFilter* fileFilter,
|
|
FilePreviewComponent* previewComp,
|
|
const bool useTreeView = false,
|
|
const bool filenameTextBoxIsReadOnly = false);
|
|
|
|
/** Destructor. */
|
|
~FileBrowserComponent();
|
|
|
|
/**
|
|
*/
|
|
const File getCurrentFile() const throw();
|
|
|
|
/** Returns true if the current file is usable.
|
|
|
|
This can be used to decide whether the user can press "ok" for the
|
|
current file. What it does depends on the mode, so for example in an "open"
|
|
mode, the current file is only valid if one has been selected and if the file
|
|
exists. In a "save" mode, a non-existent file would also be valid.
|
|
*/
|
|
bool currentFileIsValid() const;
|
|
|
|
/** Returns the directory whose contents are currently being shown in the listbox. */
|
|
const File getRoot() const;
|
|
|
|
/** Changes the directory that's being shown in the listbox. */
|
|
void setRoot (const File& newRootDirectory);
|
|
|
|
/** Equivalent to pressing the "up" button to browse the parent directory. */
|
|
void goUp();
|
|
|
|
/** Refreshes the directory that's currently being listed. */
|
|
void refresh();
|
|
|
|
/** Returns the browser's current mode. */
|
|
FileChooserMode getMode() const throw() { return mode; }
|
|
|
|
/** Returns a verb to describe what should happen when the file is accepted.
|
|
|
|
E.g. if browsing in "load file" mode, this will be "Open", if in "save file"
|
|
mode, it'll be "Save", etc.
|
|
*/
|
|
virtual const String getActionVerb() const;
|
|
|
|
/** Adds a listener to be told when the user selects and clicks on files.
|
|
|
|
@see removeListener
|
|
*/
|
|
void addListener (FileBrowserListener* const listener) throw();
|
|
|
|
/** Removes a listener.
|
|
|
|
@see addListener
|
|
*/
|
|
void removeListener (FileBrowserListener* const listener) throw();
|
|
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void buttonClicked (Button* b);
|
|
/** @internal */
|
|
void comboBoxChanged (ComboBox*);
|
|
/** @internal */
|
|
void textEditorTextChanged (TextEditor& editor);
|
|
/** @internal */
|
|
void textEditorReturnKeyPressed (TextEditor& editor);
|
|
/** @internal */
|
|
void textEditorEscapeKeyPressed (TextEditor& editor);
|
|
/** @internal */
|
|
void textEditorFocusLost (TextEditor& editor);
|
|
/** @internal */
|
|
bool keyPressed (const KeyPress& key);
|
|
/** @internal */
|
|
void selectionChanged();
|
|
/** @internal */
|
|
void fileClicked (const File& f, const MouseEvent& e);
|
|
/** @internal */
|
|
void fileDoubleClicked (const File& f);
|
|
|
|
/** @internal */
|
|
FilePreviewComponent* getPreviewComponent() const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
virtual const BitArray getRoots (StringArray& rootNames, StringArray& rootPaths);
|
|
|
|
private:
|
|
|
|
DirectoryContentsList* fileList;
|
|
FileFilter* directoriesOnlyFilter;
|
|
|
|
FileChooserMode mode;
|
|
File currentRoot;
|
|
SortedSet <void*> listeners;
|
|
|
|
DirectoryContentsDisplayComponent* fileListComponent;
|
|
FilePreviewComponent* previewComp;
|
|
ComboBox* currentPathBox;
|
|
TextEditor* filenameBox;
|
|
Button* goUpButton;
|
|
|
|
TimeSliceThread thread;
|
|
|
|
void sendListenerChangeMessage();
|
|
|
|
FileBrowserComponent (const FileBrowserComponent&);
|
|
const FileBrowserComponent& operator= (const FileBrowserComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileBrowserComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILEBROWSERLISTENER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILECHOOSER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileChooser.h *********/
|
|
#ifndef __JUCE_FILECHOOSER_JUCEHEADER__
|
|
#define __JUCE_FILECHOOSER_JUCEHEADER__
|
|
|
|
/**
|
|
Creates a dialog box to choose a file or directory to load or save.
|
|
|
|
To use a FileChooser:
|
|
- create one (as a local stack variable is the neatest way)
|
|
- call one of its browseFor.. methods
|
|
- if this returns true, the user has selected a file, so you can retrieve it
|
|
with the getResult() method.
|
|
|
|
e.g. @code
|
|
void loadMooseFile()
|
|
{
|
|
FileChooser myChooser ("Please select the moose you want to load...",
|
|
File::getSpecialLocation (File::userHomeDirectory),
|
|
"*.moose");
|
|
|
|
if (myChooser.browseForFileToOpen())
|
|
{
|
|
File mooseFile (myChooser.getResult());
|
|
|
|
loadMoose (mooseFile);
|
|
}
|
|
}
|
|
@endcode
|
|
*/
|
|
class JUCE_API FileChooser
|
|
{
|
|
public:
|
|
|
|
/** Creates a FileChooser.
|
|
|
|
After creating one of these, use one of the browseFor... methods to display it.
|
|
|
|
@param dialogBoxTitle a text string to display in the dialog box to
|
|
tell the user what's going on
|
|
@param initialFileOrDirectory the file or directory that should be selected when
|
|
the dialog box opens. If this parameter is set to
|
|
File::nonexistent, a sensible default directory
|
|
will be used instead.
|
|
@param filePatternsAllowed a set of file patterns to specify which files can be
|
|
selected - each pattern should be separated by a
|
|
comma or semi-colon, e.g. "*" or "*.jpg;*.gif". An
|
|
empty string means that all files are allowed
|
|
@param useOSNativeDialogBox if true, then a native dialog box will be used if
|
|
possible; if false, then a Juce-based browser dialog
|
|
box will always be used
|
|
@see browseForFileToOpen, browseForFileToSave, browseForDirectory
|
|
*/
|
|
FileChooser (const String& dialogBoxTitle,
|
|
const File& initialFileOrDirectory = File::nonexistent,
|
|
const String& filePatternsAllowed = String::empty,
|
|
const bool useOSNativeDialogBox = true);
|
|
|
|
/** Destructor. */
|
|
~FileChooser();
|
|
|
|
/** Shows a dialog box to choose a file to open.
|
|
|
|
This will display the dialog box modally, using an "open file" mode, so that
|
|
it won't allow non-existent files or directories to be chosen.
|
|
|
|
@param previewComponent an optional component to display inside the dialog
|
|
box to show special info about the files that the user
|
|
is browsing. The component will not be deleted by this
|
|
object, so the caller must take care of it.
|
|
@returns true if the user selected a file, in which case, use the getResult()
|
|
method to find out what it was. Returns false if they cancelled instead.
|
|
@see browseForFileToSave, browseForDirectory
|
|
*/
|
|
bool browseForFileToOpen (FilePreviewComponent* previewComponent = 0);
|
|
|
|
/** Same as browseForFileToOpen, but allows the user to select multiple files.
|
|
|
|
The files that are returned can be obtained by calling getResults(). See
|
|
browseForFileToOpen() for more info about the behaviour of this method.
|
|
*/
|
|
bool browseForMultipleFilesToOpen (FilePreviewComponent* previewComponent = 0);
|
|
|
|
/** Shows a dialog box to choose a file to save.
|
|
|
|
This will display the dialog box modally, using an "save file" mode, so it
|
|
will allow non-existent files to be chosen, but not directories.
|
|
|
|
@param warnAboutOverwritingExistingFiles if true, the dialog box will ask
|
|
the user if they're sure they want to overwrite a file that already
|
|
exists
|
|
@returns true if the user chose a file and pressed 'ok', in which case, use
|
|
the getResult() method to find out what the file was. Returns false
|
|
if they cancelled instead.
|
|
@see browseForFileToOpen, browseForDirectory
|
|
*/
|
|
bool browseForFileToSave (const bool warnAboutOverwritingExistingFiles);
|
|
|
|
/** Shows a dialog box to choose a directory.
|
|
|
|
This will display the dialog box modally, using an "open directory" mode, so it
|
|
will only allow directories to be returned, not files.
|
|
|
|
@returns true if the user chose a directory and pressed 'ok', in which case, use
|
|
the getResult() method to find out what they chose. Returns false
|
|
if they cancelled instead.
|
|
@see browseForFileToOpen, browseForFileToSave
|
|
*/
|
|
bool browseForDirectory();
|
|
|
|
/** Returns the last file that was chosen by one of the browseFor methods.
|
|
|
|
After calling the appropriate browseFor... method, this method lets you
|
|
find out what file or directory they chose.
|
|
|
|
Note that the file returned is only valid if the browse method returned true (i.e.
|
|
if the user pressed 'ok' rather than cancelling).
|
|
|
|
If you're using a multiple-file select, then use the getResults() method instead,
|
|
to obtain the list of all files chosen.
|
|
|
|
@see getResults
|
|
*/
|
|
const File getResult() const;
|
|
|
|
/** Returns a list of all the files that were chosen during the last call to a
|
|
browse method.
|
|
|
|
This array may be empty if no files were chosen, or can contain multiple entries
|
|
if multiple files were chosen.
|
|
|
|
@see getResult
|
|
*/
|
|
const OwnedArray <File>& getResults() const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
String title, filters;
|
|
File startingFile;
|
|
OwnedArray <File> results;
|
|
bool useNativeDialogBox;
|
|
|
|
bool showDialog (const bool isDirectory,
|
|
const bool isSave,
|
|
const bool warnAboutOverwritingExistingFiles,
|
|
const bool selectMultipleFiles,
|
|
FilePreviewComponent* const previewComponent);
|
|
|
|
static void showPlatformDialog (OwnedArray<File>& results,
|
|
const String& title,
|
|
const File& file,
|
|
const String& filters,
|
|
bool isDirectory,
|
|
bool isSave,
|
|
bool warnAboutOverwritingExistingFiles,
|
|
bool selectMultipleFiles,
|
|
FilePreviewComponent* previewComponent);
|
|
};
|
|
|
|
#endif // __JUCE_FILECHOOSER_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileChooser.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileChooserDialogBox.h *********/
|
|
#ifndef __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__
|
|
#define __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__
|
|
|
|
/**
|
|
A file open/save dialog box.
|
|
|
|
This is a Juce-based file dialog box; to use a native file chooser, see the
|
|
FileChooser class.
|
|
|
|
To use one of these, create it and call its show() method. e.g.
|
|
|
|
@code
|
|
{
|
|
WildcardFileFilter wildcardFilter (T("*.foo"), T("Foo files"));
|
|
|
|
FileBrowserComponent browser (FileBrowserComponent::loadFileMode,
|
|
File::nonexistent,
|
|
&wildcardFilter,
|
|
0);
|
|
|
|
FileChooserDialogBox dialogBox (T("Open some kind of file"),
|
|
T("Please choose some kind of file that you want to open..."),
|
|
browser,
|
|
getLookAndFeel().alertWindowBackground);
|
|
|
|
if (dialogBox.show())
|
|
{
|
|
File selectedFile = browser.getCurrentFile();
|
|
...
|
|
}
|
|
}
|
|
@endcode
|
|
|
|
@see FileChooser
|
|
*/
|
|
class JUCE_API FileChooserDialogBox : public ResizableWindow,
|
|
public ButtonListener,
|
|
public FileBrowserListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a file chooser box.
|
|
|
|
@param title the main title to show at the top of the box
|
|
@param instructions an optional longer piece of text to show below the title in
|
|
a smaller font, describing in more detail what's required.
|
|
@param browserComponent a FileBrowserComponent that will be shown inside this dialog
|
|
box. Make sure you delete this after (but not before!) the
|
|
dialog box has been deleted.
|
|
@param warnAboutOverwritingExistingFiles if true, then the user will be asked to confirm
|
|
if they try to select a file that already exists. (This
|
|
flag is only used when saving files)
|
|
@param backgroundColour the background colour for the top level window
|
|
|
|
@see FileBrowserComponent, FilePreviewComponent
|
|
*/
|
|
FileChooserDialogBox (const String& title,
|
|
const String& instructions,
|
|
FileBrowserComponent& browserComponent,
|
|
const bool warnAboutOverwritingExistingFiles,
|
|
const Colour& backgroundColour);
|
|
|
|
/** Destructor. */
|
|
~FileChooserDialogBox();
|
|
|
|
/** Displays and runs the dialog box modally.
|
|
|
|
This will show the box with the specified size, returning true if the user
|
|
pressed 'ok', or false if they cancelled.
|
|
|
|
Leave the width or height as 0 to use the default size
|
|
*/
|
|
bool show (int width = 0,int height = 0);
|
|
|
|
/** @internal */
|
|
void buttonClicked (Button* button);
|
|
/** @internal */
|
|
void closeButtonPressed();
|
|
/** @internal */
|
|
void selectionChanged();
|
|
/** @internal */
|
|
void fileClicked (const File& file, const MouseEvent& e);
|
|
/** @internal */
|
|
void fileDoubleClicked (const File& file);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
class ContentComponent : public Component
|
|
{
|
|
public:
|
|
ContentComponent();
|
|
~ContentComponent();
|
|
|
|
void paint (Graphics& g);
|
|
void resized();
|
|
|
|
String instructions;
|
|
GlyphArrangement text;
|
|
|
|
FileBrowserComponent* chooserComponent;
|
|
FilePreviewComponent* previewComponent;
|
|
TextButton* okButton;
|
|
TextButton* cancelButton;
|
|
};
|
|
|
|
ContentComponent* content;
|
|
const bool warnAboutOverwritingExistingFiles;
|
|
|
|
FileChooserDialogBox (const FileChooserDialogBox&);
|
|
const FileChooserDialogBox& operator= (const FileChooserDialogBox&);
|
|
};
|
|
|
|
#endif // __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileChooserDialogBox.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILEFILTER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileListComponent.h *********/
|
|
#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_FILELISTCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A component that displays the files in a directory as a listbox.
|
|
|
|
This implements the DirectoryContentsDisplayComponent base class so that
|
|
it can be used in a FileBrowserComponent.
|
|
|
|
To attach a listener to it, use its DirectoryContentsDisplayComponent base
|
|
class and the FileBrowserListener class.
|
|
|
|
@see DirectoryContentsList, FileTreeComponent
|
|
*/
|
|
class JUCE_API FileListComponent : public ListBox,
|
|
public DirectoryContentsDisplayComponent,
|
|
private ListBoxModel,
|
|
private ChangeListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a listbox to show the contents of a specified directory.
|
|
*/
|
|
FileListComponent (DirectoryContentsList& listToShow);
|
|
|
|
/** Destructor. */
|
|
~FileListComponent();
|
|
|
|
/** Returns the file that the user has currently selected.
|
|
|
|
Returns File::nonexistent if none is selected.
|
|
*/
|
|
const File getSelectedFile() const;
|
|
|
|
/** Scrolls to the top of the list. */
|
|
void scrollToTop();
|
|
|
|
/** @internal */
|
|
void changeListenerCallback (void*);
|
|
/** @internal */
|
|
int getNumRows();
|
|
/** @internal */
|
|
void paintListBoxItem (int, Graphics&, int, int, bool);
|
|
/** @internal */
|
|
Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate);
|
|
/** @internal */
|
|
void selectedRowsChanged (int lastRowSelected);
|
|
/** @internal */
|
|
void deleteKeyPressed (int currentSelectedRow);
|
|
/** @internal */
|
|
void returnKeyPressed (int currentSelectedRow);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
FileListComponent (const FileListComponent&);
|
|
const FileListComponent& operator= (const FileListComponent&);
|
|
|
|
File lastDirectory;
|
|
};
|
|
|
|
#endif // __JUCE_FILELISTCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileListComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileSearchPathListComponent.h *********/
|
|
#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
Shows a set of file paths in a list, allowing them to be added, removed or
|
|
re-ordered.
|
|
|
|
@see FileSearchPath
|
|
*/
|
|
class JUCE_API FileSearchPathListComponent : public Component,
|
|
public SettableTooltipClient,
|
|
public FileDragAndDropTarget,
|
|
private ButtonListener,
|
|
private ListBoxModel
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty FileSearchPathListComponent.
|
|
|
|
*/
|
|
FileSearchPathListComponent();
|
|
|
|
/** Destructor. */
|
|
~FileSearchPathListComponent();
|
|
|
|
/** Returns the path as it is currently shown. */
|
|
const FileSearchPath& getPath() const throw() { return path; }
|
|
|
|
/** Changes the current path. */
|
|
void setPath (const FileSearchPath& newPath);
|
|
|
|
/** Sets a file or directory to be the default starting point for the browser to show.
|
|
|
|
This is only used if the current file hasn't been set.
|
|
*/
|
|
void setDefaultBrowseTarget (const File& newDefaultDirectory) throw();
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the label.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1004100, /**< The background colour to fill the component with.
|
|
Make this transparent if you don't want the background to be filled. */
|
|
};
|
|
|
|
/** @internal */
|
|
int getNumRows();
|
|
/** @internal */
|
|
void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected);
|
|
/** @internal */
|
|
void deleteKeyPressed (int lastRowSelected);
|
|
/** @internal */
|
|
void returnKeyPressed (int lastRowSelected);
|
|
/** @internal */
|
|
void listBoxItemDoubleClicked (int row, const MouseEvent&);
|
|
/** @internal */
|
|
void selectedRowsChanged (int lastRowSelected);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
bool isInterestedInFileDrag (const StringArray& files);
|
|
/** @internal */
|
|
void filesDropped (const StringArray& files, int, int);
|
|
/** @internal */
|
|
void buttonClicked (Button* button);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
FileSearchPath path;
|
|
File defaultBrowseTarget;
|
|
|
|
ListBox* listBox;
|
|
Button* addButton;
|
|
Button* removeButton;
|
|
Button* changeButton;
|
|
Button* upButton;
|
|
Button* downButton;
|
|
|
|
void changed() throw();
|
|
void updateButtons() throw();
|
|
|
|
FileSearchPathListComponent (const FileSearchPathListComponent&);
|
|
const FileSearchPathListComponent& operator= (const FileSearchPathListComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileSearchPathListComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileTreeComponent.h *********/
|
|
#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__
|
|
#define __JUCE_FILETREECOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A component that displays the files in a directory as a treeview.
|
|
|
|
This implements the DirectoryContentsDisplayComponent base class so that
|
|
it can be used in a FileBrowserComponent.
|
|
|
|
To attach a listener to it, use its DirectoryContentsDisplayComponent base
|
|
class and the FileBrowserListener class.
|
|
|
|
@see DirectoryContentsList, FileListComponent
|
|
*/
|
|
class JUCE_API FileTreeComponent : public TreeView,
|
|
public DirectoryContentsDisplayComponent
|
|
{
|
|
public:
|
|
|
|
/** Creates a listbox to show the contents of a specified directory.
|
|
*/
|
|
FileTreeComponent (DirectoryContentsList& listToShow);
|
|
|
|
/** Destructor. */
|
|
~FileTreeComponent();
|
|
|
|
/** Returns the number of selected files in the tree.
|
|
*/
|
|
int getNumSelectedFiles() const throw() { return TreeView::getNumSelectedItems(); }
|
|
|
|
/** Returns one of the files that the user has currently selected.
|
|
|
|
Returns File::nonexistent if none is selected.
|
|
*/
|
|
const File getSelectedFile (int index) const throw();
|
|
|
|
/** Returns the first of the files that the user has currently selected.
|
|
|
|
Returns File::nonexistent if none is selected.
|
|
*/
|
|
const File getSelectedFile() const;
|
|
|
|
/** Scrolls the list to the top. */
|
|
void scrollToTop();
|
|
|
|
/** Setting a name for this allows tree items to be dragged.
|
|
|
|
The string that you pass in here will be returned by the getDragSourceDescription()
|
|
of the items in the tree. For more info, see TreeViewItem::getDragSourceDescription().
|
|
*/
|
|
void setDragAndDropDescription (const String& description) throw();
|
|
|
|
/** Returns the last value that was set by setDragAndDropDescription().
|
|
*/
|
|
const String& getDragAndDropDescription() const throw() { return dragAndDropDescription; }
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
String dragAndDropDescription;
|
|
|
|
FileTreeComponent (const FileTreeComponent&);
|
|
const FileTreeComponent& operator= (const FileTreeComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_FILETREECOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileTreeComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FilenameComponent.h *********/
|
|
#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__
|
|
#define __JUCE_FILENAMECOMPONENT_JUCEHEADER__
|
|
|
|
class FilenameComponent;
|
|
|
|
/**
|
|
Listens for events happening to a FilenameComponent.
|
|
|
|
Use FilenameComponent::addListener() and FilenameComponent::removeListener() to
|
|
register one of these objects for event callbacks when the filename is changed.
|
|
|
|
@see FilenameComponent
|
|
*/
|
|
class JUCE_API FilenameComponentListener
|
|
{
|
|
public:
|
|
/** Destructor. */
|
|
virtual ~FilenameComponentListener() {}
|
|
|
|
/** This method is called after the FilenameComponent's file has been changed. */
|
|
virtual void filenameComponentChanged (FilenameComponent* fileComponentThatHasChanged) = 0;
|
|
};
|
|
|
|
/**
|
|
Shows a filename as an editable text box, with a 'browse' button and a
|
|
drop-down list for recently selected files.
|
|
|
|
A handy component for dialogue boxes where you want the user to be able to
|
|
select a file or directory.
|
|
|
|
Attach an FilenameComponentListener using the addListener() method, and it will
|
|
get called each time the user changes the filename, either by browsing for a file
|
|
and clicking 'ok', or by typing a new filename into the box and pressing return.
|
|
|
|
@see FileChooser, ComboBox
|
|
*/
|
|
class JUCE_API FilenameComponent : public Component,
|
|
public SettableTooltipClient,
|
|
public FileDragAndDropTarget,
|
|
private AsyncUpdater,
|
|
private ButtonListener,
|
|
private ComboBoxListener
|
|
{
|
|
public:
|
|
|
|
/** Creates a FilenameComponent.
|
|
|
|
@param name the name for this component.
|
|
@param currentFile the file to initially show in the box
|
|
@param canEditFilename if true, the user can manually edit the filename; if false,
|
|
they can only change it by browsing for a new file
|
|
@param isDirectory if true, the file will be treated as a directory, and
|
|
an appropriate directory browser used
|
|
@param isForSaving if true, the file browser will allow non-existent files to
|
|
be picked, as the file is assumed to be used for saving rather
|
|
than loading
|
|
@param fileBrowserWildcard a wildcard pattern to use in the file browser - e.g. "*.txt;*.foo".
|
|
If an empty string is passed in, then the pattern is assumed to be "*"
|
|
@param enforcedSuffix if this is non-empty, it is treated as a suffix that will be added
|
|
to any filenames that are entered or chosen
|
|
@param textWhenNothingSelected the message to display in the box before any filename is entered. (This
|
|
will only appear if the initial file isn't valid)
|
|
*/
|
|
FilenameComponent (const String& name,
|
|
const File& currentFile,
|
|
const bool canEditFilename,
|
|
const bool isDirectory,
|
|
const bool isForSaving,
|
|
const String& fileBrowserWildcard,
|
|
const String& enforcedSuffix,
|
|
const String& textWhenNothingSelected);
|
|
|
|
/** Destructor. */
|
|
~FilenameComponent();
|
|
|
|
/** Returns the currently displayed filename. */
|
|
const File getCurrentFile() const;
|
|
|
|
/** Changes the current filename.
|
|
|
|
If addToRecentlyUsedList is true, the filename will also be added to the
|
|
drop-down list of recent files.
|
|
|
|
If sendChangeNotification is false, then the listeners won't be told of the
|
|
change.
|
|
*/
|
|
void setCurrentFile (File newFile,
|
|
const bool addToRecentlyUsedList,
|
|
const bool sendChangeNotification = true);
|
|
|
|
/** Changes whether the use can type into the filename box.
|
|
*/
|
|
void setFilenameIsEditable (const bool shouldBeEditable);
|
|
|
|
/** Sets a file or directory to be the default starting point for the browser to show.
|
|
|
|
This is only used if the current file hasn't been set.
|
|
*/
|
|
void setDefaultBrowseTarget (const File& newDefaultDirectory) throw();
|
|
|
|
/** Returns all the entries on the recent files list.
|
|
|
|
This can be used in conjunction with setRecentlyUsedFilenames() for saving the
|
|
state of this list.
|
|
|
|
@see setRecentlyUsedFilenames
|
|
*/
|
|
const StringArray getRecentlyUsedFilenames() const;
|
|
|
|
/** Sets all the entries on the recent files list.
|
|
|
|
This can be used in conjunction with getRecentlyUsedFilenames() for saving the
|
|
state of this list.
|
|
|
|
@see getRecentlyUsedFilenames, addRecentlyUsedFile
|
|
*/
|
|
void setRecentlyUsedFilenames (const StringArray& filenames);
|
|
|
|
/** Adds an entry to the recently-used files dropdown list.
|
|
|
|
If the file is already in the list, it will be moved to the top. A limit
|
|
is also placed on the number of items that are kept in the list.
|
|
|
|
@see getRecentlyUsedFilenames, setRecentlyUsedFilenames, setMaxNumberOfRecentFiles
|
|
*/
|
|
void addRecentlyUsedFile (const File& file);
|
|
|
|
/** Changes the limit for the number of files that will be stored in the recent-file list.
|
|
*/
|
|
void setMaxNumberOfRecentFiles (const int newMaximum);
|
|
|
|
/** Changes the text shown on the 'browse' button.
|
|
|
|
By default this button just says "..." but you can change it. The button itself
|
|
can be changed using the look-and-feel classes, so it might not actually have any
|
|
text on it.
|
|
*/
|
|
void setBrowseButtonText (const String& browseButtonText);
|
|
|
|
/** Adds a listener that will be called when the selected file is changed. */
|
|
void addListener (FilenameComponentListener* const listener) throw();
|
|
|
|
/** Removes a previously-registered listener. */
|
|
void removeListener (FilenameComponentListener* const listener) throw();
|
|
|
|
/** Gives the component a tooltip. */
|
|
void setTooltip (const String& newTooltip);
|
|
|
|
/** @internal */
|
|
void paintOverChildren (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void lookAndFeelChanged();
|
|
/** @internal */
|
|
bool isInterestedInFileDrag (const StringArray& files);
|
|
/** @internal */
|
|
void filesDropped (const StringArray& files, int, int);
|
|
/** @internal */
|
|
void fileDragEnter (const StringArray& files, int, int);
|
|
/** @internal */
|
|
void fileDragExit (const StringArray& files);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
ComboBox* filenameBox;
|
|
String lastFilename;
|
|
Button* browseButton;
|
|
int maxRecentFiles;
|
|
bool isDir, isSaving, isFileDragOver;
|
|
String wildcard, enforcedSuffix, browseButtonText;
|
|
SortedSet <void*> listeners;
|
|
File defaultBrowseFile;
|
|
|
|
void comboBoxChanged (ComboBox*);
|
|
void buttonClicked (Button* button);
|
|
void handleAsyncUpdate();
|
|
|
|
FilenameComponent (const FilenameComponent&);
|
|
const FilenameComponent& operator= (const FilenameComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_FILENAMECOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_FilenameComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ImagePreviewComponent.h *********/
|
|
#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A simple preview component that shows thumbnails of image files.
|
|
|
|
@see FileChooserDialogBox, FilePreviewComponent
|
|
*/
|
|
class JUCE_API ImagePreviewComponent : public FilePreviewComponent,
|
|
private Timer
|
|
{
|
|
public:
|
|
|
|
/** Creates an ImagePreviewComponent. */
|
|
ImagePreviewComponent();
|
|
|
|
/** Destructor. */
|
|
~ImagePreviewComponent();
|
|
|
|
/** @internal */
|
|
void selectedFileChanged (const File& newSelectedFile);
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void timerCallback();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
File fileToLoad;
|
|
Image* currentThumbnail;
|
|
String currentDetails;
|
|
|
|
void getThumbSize (int& w, int& h) const;
|
|
|
|
ImagePreviewComponent (const ImagePreviewComponent&);
|
|
const ImagePreviewComponent& operator= (const ImagePreviewComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_ImagePreviewComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_WildcardFileFilter.h *********/
|
|
#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__
|
|
#define __JUCE_WILDCARDFILEFILTER_JUCEHEADER__
|
|
|
|
/**
|
|
A type of FileFilter that works by wildcard pattern matching.
|
|
|
|
This filter only allows files that match one of the specified patterns, but
|
|
allows all directories through.
|
|
|
|
@see FileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent
|
|
*/
|
|
class JUCE_API WildcardFileFilter : public FileFilter
|
|
{
|
|
public:
|
|
|
|
/**
|
|
Creates a wildcard filter for one or more patterns.
|
|
|
|
The wildcardPatterns parameter is a comma or semicolon-delimited set of
|
|
patterns, e.g. "*.wav;*.aiff" would look for files ending in either .wav
|
|
or .aiff.
|
|
|
|
The description is a name to show the user in a list of possible patterns, so
|
|
for the wav/aiff example, your description might be "audio files".
|
|
*/
|
|
WildcardFileFilter (const String& wildcardPatterns,
|
|
const String& description);
|
|
|
|
/** Destructor. */
|
|
~WildcardFileFilter();
|
|
|
|
/** Returns true if the filename matches one of the patterns specified. */
|
|
bool isFileSuitable (const File& file) const;
|
|
|
|
/** This always returns true. */
|
|
bool isDirectorySuitable (const File& file) const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
StringArray wildcards;
|
|
};
|
|
|
|
#endif // __JUCE_WILDCARDFILEFILTER_JUCEHEADER__
|
|
/********* End of inlined file: juce_WildcardFileFilter.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_ALERTWINDOW_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AlertWindow.h *********/
|
|
#ifndef __JUCE_ALERTWINDOW_JUCEHEADER__
|
|
#define __JUCE_ALERTWINDOW_JUCEHEADER__
|
|
|
|
/** A window that displays a message and has buttons for the user to react to it.
|
|
|
|
For simple dialog boxes with just a couple of buttons on them, there are
|
|
some static methods for running these.
|
|
|
|
For more complex dialogs, an AlertWindow can be created, then it can have some
|
|
buttons and components added to it, and its runModalLoop() method is then used to
|
|
show it. The value returned by runModalLoop() shows which button the
|
|
user pressed to dismiss the box.
|
|
|
|
@see ThreadWithProgressWindow
|
|
*/
|
|
class JUCE_API AlertWindow : public TopLevelWindow,
|
|
private ButtonListener
|
|
{
|
|
public:
|
|
|
|
/** The type of icon to show in the dialog box. */
|
|
enum AlertIconType
|
|
{
|
|
NoIcon, /**< No icon will be shown on the dialog box. */
|
|
QuestionIcon, /**< A question-mark icon, for dialog boxes that need the
|
|
user to answer a question. */
|
|
WarningIcon, /**< An exclamation mark to indicate that the dialog is a
|
|
warning about something and shouldn't be ignored. */
|
|
InfoIcon /**< An icon that indicates that the dialog box is just
|
|
giving the user some information, which doesn't require
|
|
a response from them. */
|
|
};
|
|
|
|
/** Creates an AlertWindow.
|
|
|
|
@param title the headline to show at the top of the dialog box
|
|
@param message a longer, more descriptive message to show underneath the
|
|
headline
|
|
@param iconType the type of icon to display
|
|
@param associatedComponent if this is non-zero, it specifies the component that the
|
|
alert window should be associated with. Depending on the look
|
|
and feel, this might be used for positioning of the alert window.
|
|
*/
|
|
AlertWindow (const String& title,
|
|
const String& message,
|
|
AlertIconType iconType,
|
|
Component* associatedComponent = 0);
|
|
|
|
/** Destroys the AlertWindow */
|
|
~AlertWindow();
|
|
|
|
/** Returns the type of alert icon that was specified when the window
|
|
was created. */
|
|
AlertIconType getAlertType() const throw() { return alertIconType; }
|
|
|
|
/** Changes the dialog box's message.
|
|
|
|
This will also resize the window to fit the new message if required.
|
|
*/
|
|
void setMessage (const String& message);
|
|
|
|
/** Adds a button to the window.
|
|
|
|
@param name the text to show on the button
|
|
@param returnValue the value that should be returned from runModalLoop()
|
|
if this is the button that the user presses.
|
|
@param shortcutKey1 an optional key that can be pressed to trigger this button
|
|
@param shortcutKey2 a second optional key that can be pressed to trigger this button
|
|
*/
|
|
void addButton (const String& name,
|
|
const int returnValue,
|
|
const KeyPress& shortcutKey1 = KeyPress(),
|
|
const KeyPress& shortcutKey2 = KeyPress());
|
|
|
|
/** Returns the number of buttons that the window currently has. */
|
|
int getNumButtons() const;
|
|
|
|
/** Adds a textbox to the window for entering strings.
|
|
|
|
@param name an internal name for the text-box. This is the name to pass to
|
|
the getTextEditorContents() method to find out what the
|
|
user typed-in.
|
|
@param initialContents a string to show in the text box when it's first shown
|
|
@param onScreenLabel if this is non-empty, it will be displayed next to the
|
|
text-box to label it.
|
|
@param isPasswordBox if true, the text editor will display asterisks instead of
|
|
the actual text
|
|
@see getTextEditorContents
|
|
*/
|
|
void addTextEditor (const String& name,
|
|
const String& initialContents,
|
|
const String& onScreenLabel = String::empty,
|
|
const bool isPasswordBox = false);
|
|
|
|
/** Returns the contents of a named textbox.
|
|
|
|
After showing an AlertWindow that contains a text editor, this can be
|
|
used to find out what the user has typed into it.
|
|
|
|
@param nameOfTextEditor the name of the text box that you're interested in
|
|
@see addTextEditor
|
|
*/
|
|
const String getTextEditorContents (const String& nameOfTextEditor) const;
|
|
|
|
/** Adds a drop-down list of choices to the box.
|
|
|
|
After the box has been shown, the getComboBoxComponent() method can
|
|
be used to find out which item the user picked.
|
|
|
|
@param name the label to use for the drop-down list
|
|
@param items the list of items to show in it
|
|
@param onScreenLabel if this is non-empty, it will be displayed next to the
|
|
combo-box to label it.
|
|
@see getComboBoxComponent
|
|
*/
|
|
void addComboBox (const String& name,
|
|
const StringArray& items,
|
|
const String& onScreenLabel = String::empty);
|
|
|
|
/** Returns a drop-down list that was added to the AlertWindow.
|
|
|
|
@param nameOfList the name that was passed into the addComboBox() method
|
|
when creating the drop-down
|
|
@returns the ComboBox component, or 0 if none was found for the given name.
|
|
*/
|
|
ComboBox* getComboBoxComponent (const String& nameOfList) const;
|
|
|
|
/** Adds a block of text.
|
|
|
|
This is handy for adding a multi-line note next to a textbox or combo-box,
|
|
to provide more details about what's going on.
|
|
*/
|
|
void addTextBlock (const String& text);
|
|
|
|
/** Adds a progress-bar to the window.
|
|
|
|
@param progressValue a variable that will be repeatedly checked while the
|
|
dialog box is visible, to see how far the process has
|
|
got. The value should be in the range 0 to 1.0
|
|
*/
|
|
void addProgressBarComponent (double& progressValue);
|
|
|
|
/** Adds a user-defined component to the dialog box.
|
|
|
|
@param component the component to add - its size should be set up correctly
|
|
before it is passed in. The caller is responsible for deleting
|
|
the component later on - the AlertWindow won't delete it.
|
|
*/
|
|
void addCustomComponent (Component* const component);
|
|
|
|
/** Returns the number of custom components in the dialog box.
|
|
|
|
@see getCustomComponent, addCustomComponent
|
|
*/
|
|
int getNumCustomComponents() const;
|
|
|
|
/** Returns one of the custom components in the dialog box.
|
|
|
|
@param index a value 0 to (getNumCustomComponents() - 1). Out-of-range indexes
|
|
will return 0
|
|
@see getNumCustomComponents, addCustomComponent
|
|
*/
|
|
Component* getCustomComponent (const int index) const;
|
|
|
|
/** Removes one of the custom components in the dialog box.
|
|
|
|
Note that this won't delete it, it just removes the component from the window
|
|
|
|
@param index a value 0 to (getNumCustomComponents() - 1). Out-of-range indexes
|
|
will return 0
|
|
@returns the component that was removed (or zero)
|
|
@see getNumCustomComponents, addCustomComponent
|
|
*/
|
|
Component* removeCustomComponent (const int index);
|
|
|
|
/** Returns true if the window contains any components other than just buttons.*/
|
|
bool containsAnyExtraComponents() const;
|
|
|
|
// easy-to-use message box functions:
|
|
|
|
/** Shows a dialog box that just has a message and a single button to get rid of it.
|
|
|
|
The box is shown modally, and the method returns after the user
|
|
has clicked the button (or pressed the escape or return keys).
|
|
|
|
@param iconType the type of icon to show
|
|
@param title the headline to show at the top of the box
|
|
@param message a longer, more descriptive message to show underneath the
|
|
headline
|
|
@param buttonText the text to show in the button - if this string is empty, the
|
|
default string "ok" (or a localised version) will be used.
|
|
@param associatedComponent if this is non-zero, it specifies the component that the
|
|
alert window should be associated with. Depending on the look
|
|
and feel, this might be used for positioning of the alert window.
|
|
*/
|
|
static void JUCE_CALLTYPE showMessageBox (AlertIconType iconType,
|
|
const String& title,
|
|
const String& message,
|
|
const String& buttonText = String::empty,
|
|
Component* associatedComponent = 0);
|
|
|
|
/** Shows a dialog box with two buttons.
|
|
|
|
Ideal for ok/cancel or yes/no choices. The return key can also be used
|
|
to trigger the first button, and the escape key for the second button.
|
|
|
|
@param iconType the type of icon to show
|
|
@param title the headline to show at the top of the box
|
|
@param message a longer, more descriptive message to show underneath the
|
|
headline
|
|
@param button1Text the text to show in the first button - if this string is
|
|
empty, the default string "ok" (or a localised version of it)
|
|
will be used.
|
|
@param button2Text the text to show in the second button - if this string is
|
|
empty, the default string "cancel" (or a localised version of it)
|
|
will be used.
|
|
@param associatedComponent if this is non-zero, it specifies the component that the
|
|
alert window should be associated with. Depending on the look
|
|
and feel, this might be used for positioning of the alert window.
|
|
@returns true if button 1 was clicked, false if it was button 2
|
|
*/
|
|
static bool JUCE_CALLTYPE showOkCancelBox (AlertIconType iconType,
|
|
const String& title,
|
|
const String& message,
|
|
const String& button1Text = String::empty,
|
|
const String& button2Text = String::empty,
|
|
Component* associatedComponent = 0);
|
|
|
|
/** Shows a dialog box with three buttons.
|
|
|
|
Ideal for yes/no/cancel boxes.
|
|
|
|
The escape key can be used to trigger the third button.
|
|
|
|
@param iconType the type of icon to show
|
|
@param title the headline to show at the top of the box
|
|
@param message a longer, more descriptive message to show underneath the
|
|
headline
|
|
@param button1Text the text to show in the first button - if an empty string, then
|
|
"yes" will be used (or a localised version of it)
|
|
@param button2Text the text to show in the first button - if an empty string, then
|
|
"no" will be used (or a localised version of it)
|
|
@param button3Text the text to show in the first button - if an empty string, then
|
|
"cancel" will be used (or a localised version of it)
|
|
@param associatedComponent if this is non-zero, it specifies the component that the
|
|
alert window should be associated with. Depending on the look
|
|
and feel, this might be used for positioning of the alert window.
|
|
|
|
@returns one of the following values:
|
|
- 0 if the third button was pressed (normally used for 'cancel')
|
|
- 1 if the first button was pressed (normally used for 'yes')
|
|
- 2 if the middle button was pressed (normally used for 'no')
|
|
*/
|
|
static int JUCE_CALLTYPE showYesNoCancelBox (AlertIconType iconType,
|
|
const String& title,
|
|
const String& message,
|
|
const String& button1Text = String::empty,
|
|
const String& button2Text = String::empty,
|
|
const String& button3Text = String::empty,
|
|
Component* associatedComponent = 0);
|
|
|
|
/** Shows an operating-system native dialog box.
|
|
|
|
@param title the title to use at the top
|
|
@param bodyText the longer message to show
|
|
@param isOkCancel if true, this will show an ok/cancel box, if false,
|
|
it'll show a box with just an ok button
|
|
@returns true if the ok button was pressed, false if they pressed cancel.
|
|
*/
|
|
static bool JUCE_CALLTYPE showNativeDialogBox (const String& title,
|
|
const String& bodyText,
|
|
bool isOkCancel);
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the alert box.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1001800, /**< The background colour for the window. */
|
|
textColourId = 0x1001810, /**< The colour for the text. */
|
|
outlineColourId = 0x1001820 /**< An optional colour to use to draw a border around the window. */
|
|
};
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent& e);
|
|
/** @internal */
|
|
bool keyPressed (const KeyPress& key);
|
|
/** @internal */
|
|
void buttonClicked (Button* button);
|
|
/** @internal */
|
|
void lookAndFeelChanged();
|
|
/** @internal */
|
|
void userTriedToCloseWindow();
|
|
/** @internal */
|
|
int getDesktopWindowStyleFlags() const;
|
|
|
|
private:
|
|
String text;
|
|
TextLayout textLayout;
|
|
AlertIconType alertIconType;
|
|
ComponentBoundsConstrainer constrainer;
|
|
ComponentDragger dragger;
|
|
Rectangle textArea;
|
|
VoidArray buttons, textBoxes, comboBoxes;
|
|
VoidArray progressBars, customComps, textBlocks, allComps;
|
|
StringArray textboxNames, comboBoxNames;
|
|
Font font;
|
|
Component* associatedComponent;
|
|
|
|
void updateLayout (const bool onlyIncreaseSize);
|
|
|
|
// disable copy constructor
|
|
AlertWindow (const AlertWindow&);
|
|
const AlertWindow& operator= (const AlertWindow&);
|
|
};
|
|
|
|
#endif // __JUCE_ALERTWINDOW_JUCEHEADER__
|
|
/********* End of inlined file: juce_AlertWindow.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_COMPONENTPEER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_DIALOGWINDOW_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_DialogWindow.h *********/
|
|
#ifndef __JUCE_DIALOGWINDOW_JUCEHEADER__
|
|
#define __JUCE_DIALOGWINDOW_JUCEHEADER__
|
|
|
|
/**
|
|
A dialog-box style window.
|
|
|
|
This class is a convenient way of creating a DocumentWindow with a close button
|
|
that can be triggered by pressing the escape key.
|
|
|
|
Any of the methods available to a DocumentWindow or ResizableWindow are also
|
|
available to this, so it can be made resizable, have a menu bar, etc.
|
|
|
|
To add items to the box, see the ResizableWindow::setContentComponent() method.
|
|
Don't add components directly to this class - always put them in a content component!
|
|
|
|
You'll need to override the DocumentWindow::closeButtonPressed() method to handle
|
|
the user clicking the close button - for more info, see the DocumentWindow
|
|
help.
|
|
|
|
@see DocumentWindow, ResizableWindow
|
|
*/
|
|
class JUCE_API DialogWindow : public DocumentWindow
|
|
{
|
|
public:
|
|
|
|
/** Creates a DialogWindow.
|
|
|
|
@param name the name to give the component - this is also
|
|
the title shown at the top of the window. To change
|
|
this later, use setName()
|
|
@param backgroundColour the colour to use for filling the window's background.
|
|
@param escapeKeyTriggersCloseButton if true, then pressing the escape key will cause the
|
|
close button to be triggered
|
|
@param addToDesktop if true, the window will be automatically added to the
|
|
desktop; if false, you can use it as a child component
|
|
*/
|
|
DialogWindow (const String& name,
|
|
const Colour& backgroundColour,
|
|
const bool escapeKeyTriggersCloseButton,
|
|
const bool addToDesktop = true);
|
|
|
|
/** Destructor.
|
|
|
|
If a content component has been set with setContentComponent(), it
|
|
will be deleted.
|
|
*/
|
|
~DialogWindow();
|
|
|
|
/** Easy way of quickly showing a dialog box containing a given component.
|
|
|
|
This will open and display a DialogWindow containing a given component, returning
|
|
when the user clicks its close button.
|
|
|
|
It returns the value that was returned by the dialog box's runModalLoop() call.
|
|
|
|
To close the dialog programatically, you should call exitModalState (returnValue) on
|
|
the DialogWindow that is created. To find a pointer to this window from your
|
|
contentComponent, you can do something like this:
|
|
@code
|
|
Dialogwindow* dw = contentComponent->findParentComponentOfClass ((DialogWindow*) 0);
|
|
|
|
if (dw != 0)
|
|
dw->exitModalState (1234);
|
|
@endcode
|
|
|
|
@param dialogTitle the dialog box's title
|
|
@param contentComponent the content component for the dialog box. Make sure
|
|
that this has been set to the size you want it to
|
|
be before calling this method. The component won't
|
|
be deleted by this call, so you can re-use it or delete
|
|
it afterwards
|
|
@param componentToCentreAround if this is non-zero, it indicates a component that
|
|
you'd like to show this dialog box in front of. See the
|
|
DocumentWindow::centreAroundComponent() method for more
|
|
info on this parameter
|
|
@param backgroundColour a colour to use for the dialog box's background colour
|
|
@param escapeKeyTriggersCloseButton if true, then pressing the escape key will cause the
|
|
close button to be triggered
|
|
@param shouldBeResizable if true, the dialog window has either a resizable border, or
|
|
a corner resizer
|
|
@param useBottomRightCornerResizer if shouldBeResizable is true, this indicates whether
|
|
to use a border or corner resizer component. See ResizableWindow::setResizable()
|
|
*/
|
|
static int showModalDialog (const String& dialogTitle,
|
|
Component* contentComponent,
|
|
Component* componentToCentreAround,
|
|
const Colour& backgroundColour,
|
|
const bool escapeKeyTriggersCloseButton,
|
|
const bool shouldBeResizable = false,
|
|
const bool useBottomRightCornerResizer = false);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
/** @internal */
|
|
void resized();
|
|
|
|
private:
|
|
bool escapeKeyTriggersCloseButton;
|
|
|
|
DialogWindow (const DialogWindow&);
|
|
const DialogWindow& operator= (const DialogWindow&);
|
|
};
|
|
|
|
#endif // __JUCE_DIALOGWINDOW_JUCEHEADER__
|
|
/********* End of inlined file: juce_DialogWindow.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DOCUMENTWINDOW_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_RESIZABLEWINDOW_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_SPLASHSCREEN_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_SplashScreen.h *********/
|
|
#ifndef __JUCE_SPLASHSCREEN_JUCEHEADER__
|
|
#define __JUCE_SPLASHSCREEN_JUCEHEADER__
|
|
|
|
/** A component for showing a splash screen while your app starts up.
|
|
|
|
This will automatically position itself, and delete itself when the app has
|
|
finished initialising (it uses the JUCEApplication::isInitialising() to detect
|
|
this).
|
|
|
|
To use it, just create one of these in your JUCEApplication::initialise() method,
|
|
call its show() method and let the object delete itself later.
|
|
|
|
E.g. @code
|
|
|
|
void MyApp::initialise (const String& commandLine)
|
|
{
|
|
SplashScreen* splash = new SplashScreen();
|
|
|
|
splash->show (T("welcome to my app"),
|
|
ImageCache::getFromFile (File ("/foobar/splash.jpg")),
|
|
4000, false);
|
|
|
|
.. no need to delete the splash screen - it'll do that itself.
|
|
}
|
|
|
|
@endcode
|
|
*/
|
|
class JUCE_API SplashScreen : public Component,
|
|
public Timer,
|
|
private DeletedAtShutdown
|
|
{
|
|
public:
|
|
|
|
/** Creates a SplashScreen object.
|
|
|
|
After creating one of these (or your subclass of it), call one of the show()
|
|
methods to display it.
|
|
*/
|
|
SplashScreen();
|
|
|
|
/** Destructor. */
|
|
~SplashScreen();
|
|
|
|
/** Creates a SplashScreen object that will display an image.
|
|
|
|
As soon as this is called, the SplashScreen will be displayed in the centre of the
|
|
screen. This method will also dispatch any pending messages to make sure that when
|
|
it returns, the splash screen has been completely drawn, and your initialisation
|
|
code can carry on.
|
|
|
|
@param title the name to give the component
|
|
@param backgroundImage an image to draw on the component. The component's size
|
|
will be set to the size of this image, and if the image is
|
|
semi-transparent, the component will be made semi-transparent
|
|
too. This image will be deleted (or released from the ImageCache
|
|
if that's how it was created) by the splash screen object when
|
|
it is itself deleted.
|
|
@param minimumTimeToDisplayFor how long (in milliseconds) the splash screen
|
|
should stay visible for. If the initialisation takes longer than
|
|
this time, the splash screen will wait for it to finish before
|
|
disappearing, but if initialisation is very quick, this lets
|
|
you make sure that people get a good look at your splash.
|
|
@param useDropShadow if true, the window will have a drop shadow
|
|
@param removeOnMouseClick if true, the window will go away as soon as the user clicks
|
|
the mouse (anywhere)
|
|
*/
|
|
void show (const String& title,
|
|
Image* const backgroundImage,
|
|
const int minimumTimeToDisplayFor,
|
|
const bool useDropShadow,
|
|
const bool removeOnMouseClick = true);
|
|
|
|
/** Creates a SplashScreen object with a specified size.
|
|
|
|
For a custom splash screen, you can use this method to display it at a certain size
|
|
and then override the paint() method yourself to do whatever's necessary.
|
|
|
|
As soon as this is called, the SplashScreen will be displayed in the centre of the
|
|
screen. This method will also dispatch any pending messages to make sure that when
|
|
it returns, the splash screen has been completely drawn, and your initialisation
|
|
code can carry on.
|
|
|
|
@param title the name to give the component
|
|
@param width the width to use
|
|
@param height the height to use
|
|
@param minimumTimeToDisplayFor how long (in milliseconds) the splash screen
|
|
should stay visible for. If the initialisation takes longer than
|
|
this time, the splash screen will wait for it to finish before
|
|
disappearing, but if initialisation is very quick, this lets
|
|
you make sure that people get a good look at your splash.
|
|
@param useDropShadow if true, the window will have a drop shadow
|
|
@param removeOnMouseClick if true, the window will go away as soon as the user clicks
|
|
the mouse (anywhere)
|
|
*/
|
|
void show (const String& title,
|
|
const int width,
|
|
const int height,
|
|
const int minimumTimeToDisplayFor,
|
|
const bool useDropShadow,
|
|
const bool removeOnMouseClick = true);
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void timerCallback();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Image* backgroundImage;
|
|
Time earliestTimeToDelete;
|
|
int originalClickCounter;
|
|
bool isImageInCache;
|
|
|
|
SplashScreen (const SplashScreen&);
|
|
const SplashScreen& operator= (const SplashScreen&);
|
|
};
|
|
|
|
#endif // __JUCE_SPLASHSCREEN_JUCEHEADER__
|
|
/********* End of inlined file: juce_SplashScreen.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ThreadWithProgressWindow.h *********/
|
|
#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__
|
|
#define __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__
|
|
|
|
/**
|
|
A thread that automatically pops up a modal dialog box with a progress bar
|
|
and cancel button while it's busy running.
|
|
|
|
These are handy for performing some sort of task while giving the user feedback
|
|
about how long there is to go, etc.
|
|
|
|
E.g. @code
|
|
class MyTask : public ThreadWithProgressWindow
|
|
{
|
|
public:
|
|
MyTask() : ThreadWithProgressWindow (T("busy..."), true, true)
|
|
{
|
|
}
|
|
|
|
~MyTask()
|
|
{
|
|
}
|
|
|
|
void run()
|
|
{
|
|
for (int i = 0; i < thingsToDo; ++i)
|
|
{
|
|
// must check this as often as possible, because this is
|
|
// how we know if the user's pressed 'cancel'
|
|
if (threadShouldExit())
|
|
break;
|
|
|
|
// this will update the progress bar on the dialog box
|
|
setProgress (i / (double) thingsToDo);
|
|
|
|
// ... do the business here...
|
|
}
|
|
}
|
|
};
|
|
|
|
void doTheTask()
|
|
{
|
|
MyTask m;
|
|
|
|
if (m.runThread())
|
|
{
|
|
// thread finished normally..
|
|
}
|
|
else
|
|
{
|
|
// user pressed the cancel button..
|
|
}
|
|
}
|
|
|
|
@endcode
|
|
|
|
@see Thread, AlertWindow
|
|
*/
|
|
class JUCE_API ThreadWithProgressWindow : public Thread,
|
|
private Timer
|
|
{
|
|
public:
|
|
|
|
/** Creates the thread.
|
|
|
|
Initially, the dialog box won't be visible, it'll only appear when the
|
|
runThread() method is called.
|
|
|
|
@param windowTitle the title to go at the top of the dialog box
|
|
@param hasProgressBar whether the dialog box should have a progress bar (see
|
|
setProgress() )
|
|
@param hasCancelButton whether the dialog box should have a cancel button
|
|
@param timeOutMsWhenCancelling when 'cancel' is pressed, this is how long to wait for
|
|
the thread to stop before killing it forcibly (see
|
|
Thread::stopThread() )
|
|
@param cancelButtonText the text that should be shown in the cancel button
|
|
(if it has one)
|
|
*/
|
|
ThreadWithProgressWindow (const String& windowTitle,
|
|
const bool hasProgressBar,
|
|
const bool hasCancelButton,
|
|
const int timeOutMsWhenCancelling = 10000,
|
|
const String& cancelButtonText = JUCE_T("Cancel"));
|
|
|
|
/** Destructor. */
|
|
~ThreadWithProgressWindow();
|
|
|
|
/** Starts the thread and waits for it to finish.
|
|
|
|
This will start the thread, make the dialog box appear, and wait until either
|
|
the thread finishes normally, or until the cancel button is pressed.
|
|
|
|
Before returning, the dialog box will be hidden.
|
|
|
|
@param threadPriority the priority to use when starting the thread - see
|
|
Thread::startThread() for values
|
|
@returns true if the thread finished normally; false if the user pressed cancel
|
|
*/
|
|
bool runThread (const int threadPriority = 5);
|
|
|
|
/** The thread should call this periodically to update the position of the progress bar.
|
|
|
|
@param newProgress the progress, from 0.0 to 1.0
|
|
@see setStatusMessage
|
|
*/
|
|
void setProgress (const double newProgress);
|
|
|
|
/** The thread can call this to change the message that's displayed in the dialog box.
|
|
*/
|
|
void setStatusMessage (const String& newStatusMessage);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
void timerCallback();
|
|
|
|
double progress;
|
|
AlertWindow* alertWindow;
|
|
String message;
|
|
CriticalSection messageLock;
|
|
const int timeOutMsWhenCancelling;
|
|
|
|
ThreadWithProgressWindow (const ThreadWithProgressWindow&);
|
|
const ThreadWithProgressWindow& operator= (const ThreadWithProgressWindow&);
|
|
};
|
|
|
|
#endif // __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__
|
|
/********* End of inlined file: juce_ThreadWithProgressWindow.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ActiveXControlComponent.h *********/
|
|
#ifndef __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__
|
|
|
|
#if JUCE_WIN32 || DOXYGEN
|
|
|
|
/**
|
|
A Windows-specific class that can create and embed an ActiveX control inside
|
|
itself.
|
|
|
|
To use it, create one of these, put it in place and make sure it's visible in a
|
|
window, then use createControl() to instantiate an ActiveX control. The control
|
|
will then be moved and resized to follow the movements of this component.
|
|
|
|
Of course, since the control is a heavyweight window, it'll obliterate any
|
|
juce components that may overlap this component, but that's life.
|
|
*/
|
|
class JUCE_API ActiveXControlComponent : public Component
|
|
{
|
|
public:
|
|
|
|
/** Create an initially-empty container. */
|
|
ActiveXControlComponent();
|
|
|
|
/** Destructor. */
|
|
~ActiveXControlComponent();
|
|
|
|
/** Tries to create an ActiveX control and embed it in this peer.
|
|
|
|
The peer controlIID is a pointer to an IID structure - it's treated
|
|
as a void* because when including the Juce headers, you might not always
|
|
have included windows.h first, in which case IID wouldn't be defined.
|
|
|
|
e.g. @code
|
|
const IID myIID = __uuidof (QTControl);
|
|
myControlComp->createControl (&myIID);
|
|
@endcode
|
|
*/
|
|
bool createControl (const void* controlIID);
|
|
|
|
/** Deletes the ActiveX control, if one has been created.
|
|
*/
|
|
void deleteControl();
|
|
|
|
/** Returns true if a control is currently in use. */
|
|
bool isControlOpen() const throw() { return control != 0; }
|
|
|
|
/** Does a QueryInterface call on the embedded control object.
|
|
|
|
This allows you to cast the control to whatever type of COM object you need.
|
|
|
|
The iid parameter is a pointer to an IID structure - it's treated
|
|
as a void* because when including the Juce headers, you might not always
|
|
have included windows.h first, in which case IID wouldn't be defined, but
|
|
you should just pass a pointer to an IID.
|
|
|
|
e.g. @code
|
|
const IID iid = __uuidof (IOleWindow);
|
|
|
|
IOleWindow* oleWindow = (IOleWindow*) myControlComp->queryInterface (&iid);
|
|
|
|
if (oleWindow != 0)
|
|
{
|
|
HWND hwnd;
|
|
oleWindow->GetWindow (&hwnd);
|
|
|
|
...
|
|
|
|
oleWindow->Release();
|
|
}
|
|
@endcode
|
|
*/
|
|
void* queryInterface (const void* iid) const;
|
|
|
|
/** Set this to false to stop mouse events being allowed through to the control.
|
|
*/
|
|
void setMouseEventsAllowed (const bool eventsCanReachControl);
|
|
|
|
/** Returns true if mouse events are allowed to get through to the control.
|
|
*/
|
|
bool areMouseEventsAllowed() const throw() { return mouseEventsAllowed; }
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void* originalWndProc;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class ActiveXControlData;
|
|
void* control;
|
|
bool mouseEventsAllowed;
|
|
|
|
ActiveXControlComponent (const ActiveXControlComponent&);
|
|
const ActiveXControlComponent& operator= (const ActiveXControlComponent&);
|
|
|
|
void setControlBounds (const Rectangle& bounds) const;
|
|
void setControlVisible (const bool b) const;
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif // __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_ActiveXControlComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_AUDIODEVICESELECTORCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_AudioDeviceSelectorComponent.h *********/
|
|
#ifndef __JUCE_AUDIODEVICESELECTORCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_AUDIODEVICESELECTORCOMPONENT_JUCEHEADER__
|
|
|
|
class MidiInputSelectorComponentListBox;
|
|
|
|
/**
|
|
A component containing controls to let the user change the audio settings of
|
|
an AudioDeviceManager object.
|
|
|
|
Very easy to use - just create one of these and show it to the user.
|
|
|
|
@see AudioDeviceManager
|
|
*/
|
|
class JUCE_API AudioDeviceSelectorComponent : public Component,
|
|
public ComboBoxListener,
|
|
public ButtonListener,
|
|
public ChangeListener
|
|
{
|
|
public:
|
|
|
|
/** Creates the component.
|
|
|
|
If your app needs only output channels, you might ask for a maximum of 0 input
|
|
channels, and the component won't display any options for choosing the input
|
|
channels. And likewise if you're doing an input-only app.
|
|
|
|
@param deviceManager the device manager that this component should control
|
|
@param minAudioInputChannels the minimum number of audio input channels that the application needs
|
|
@param maxAudioInputChannels the maximum number of audio input channels that the application needs
|
|
@param minAudioOutputChannels the minimum number of audio output channels that the application needs
|
|
@param maxAudioOutputChannels the maximum number of audio output channels that the application needs
|
|
@param showMidiInputOptions if true, the component will allow the user to select which midi inputs are enabled
|
|
@param showMidiOutputSelector if true, the component will let the user choose a default midi output device
|
|
@param showChannelsAsStereoPairs if true, channels will be treated as pairs; if false, channels will be
|
|
treated as a set of separate mono channels.
|
|
@param hideAdvancedOptionsWithButton if true, only the minimum amount of UI components
|
|
are shown, with an "advanced" button that shows the rest of them
|
|
*/
|
|
AudioDeviceSelectorComponent (AudioDeviceManager& deviceManager,
|
|
const int minAudioInputChannels,
|
|
const int maxAudioInputChannels,
|
|
const int minAudioOutputChannels,
|
|
const int maxAudioOutputChannels,
|
|
const bool showMidiInputOptions,
|
|
const bool showMidiOutputSelector,
|
|
const bool showChannelsAsStereoPairs,
|
|
const bool hideAdvancedOptionsWithButton);
|
|
|
|
/** Destructor */
|
|
~AudioDeviceSelectorComponent();
|
|
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void comboBoxChanged (ComboBox*);
|
|
/** @internal */
|
|
void buttonClicked (Button*);
|
|
/** @internal */
|
|
void changeListenerCallback (void*);
|
|
/** @internal */
|
|
void childBoundsChanged (Component*);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
AudioDeviceManager& deviceManager;
|
|
ComboBox* deviceTypeDropDown;
|
|
Label* deviceTypeDropDownLabel;
|
|
Component* audioDeviceSettingsComp;
|
|
String audioDeviceSettingsCompType;
|
|
const int minOutputChannels, maxOutputChannels, minInputChannels, maxInputChannels;
|
|
const bool showChannelsAsStereoPairs;
|
|
const bool hideAdvancedOptionsWithButton;
|
|
|
|
MidiInputSelectorComponentListBox* midiInputsList;
|
|
Label* midiInputsLabel;
|
|
ComboBox* midiOutputSelector;
|
|
Label* midiOutputLabel;
|
|
|
|
AudioDeviceSelectorComponent (const AudioDeviceSelectorComponent&);
|
|
const AudioDeviceSelectorComponent& operator= (const AudioDeviceSelectorComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_AUDIODEVICESELECTORCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_AudioDeviceSelectorComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_BUBBLECOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_BubbleComponent.h *********/
|
|
#ifndef __JUCE_BUBBLECOMPONENT_JUCEHEADER__
|
|
#define __JUCE_BUBBLECOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A component for showing a message or other graphics inside a speech-bubble-shaped
|
|
outline, pointing at a location on the screen.
|
|
|
|
This is a base class that just draws and positions the bubble shape, but leaves
|
|
the drawing of any content up to a subclass. See BubbleMessageComponent for a subclass
|
|
that draws a text message.
|
|
|
|
To use it, create your subclass, then either add it to a parent component or
|
|
put it on the desktop with addToDesktop (0), use setPosition() to
|
|
resize and position it, then make it visible.
|
|
|
|
@see BubbleMessageComponent
|
|
*/
|
|
class JUCE_API BubbleComponent : public Component
|
|
{
|
|
protected:
|
|
|
|
/** Creates a BubbleComponent.
|
|
|
|
Your subclass will need to implement the getContentSize() and paintContent()
|
|
methods to draw the bubble's contents.
|
|
*/
|
|
BubbleComponent();
|
|
|
|
public:
|
|
/** Destructor. */
|
|
~BubbleComponent();
|
|
|
|
/** A list of permitted placements for the bubble, relative to the co-ordinates
|
|
at which it should be pointing.
|
|
|
|
@see setAllowedPlacement
|
|
*/
|
|
enum BubblePlacement
|
|
{
|
|
above = 1,
|
|
below = 2,
|
|
left = 4,
|
|
right = 8
|
|
};
|
|
|
|
/** Tells the bubble which positions it's allowed to put itself in, relative to the
|
|
point at which it's pointing.
|
|
|
|
By default when setPosition() is called, the bubble will place itself either
|
|
above, below, left, or right of the target area. You can pass in a bitwise-'or' of
|
|
the values in BubblePlacement to restrict this choice.
|
|
|
|
E.g. if you only want your bubble to appear above or below the target area,
|
|
use setAllowedPlacement (above | below);
|
|
|
|
@see BubblePlacement
|
|
*/
|
|
void setAllowedPlacement (const int newPlacement);
|
|
|
|
/** Moves and resizes the bubble to point at a given component.
|
|
|
|
This will resize the bubble to fit its content, then find a position for it
|
|
so that it's next to, but doesn't overlap the given component.
|
|
|
|
It'll put itself either above, below, or to the side of the component depending
|
|
on where there's the most space, honouring any restrictions that were set
|
|
with setAllowedPlacement().
|
|
*/
|
|
void setPosition (Component* componentToPointTo);
|
|
|
|
/** Moves and resizes the bubble to point at a given point.
|
|
|
|
This will resize the bubble to fit its content, then position it
|
|
so that the tip of the bubble points to the given co-ordinate. The co-ordinates
|
|
are relative to either the bubble component's parent component if it has one, or
|
|
they are screen co-ordinates if not.
|
|
|
|
It'll put itself either above, below, or to the side of this point, depending
|
|
on where there's the most space, honouring any restrictions that were set
|
|
with setAllowedPlacement().
|
|
*/
|
|
void setPosition (const int arrowTipX,
|
|
const int arrowTipY);
|
|
|
|
/** Moves and resizes the bubble to point at a given rectangle.
|
|
|
|
This will resize the bubble to fit its content, then find a position for it
|
|
so that it's next to, but doesn't overlap the given rectangle. The rectangle's
|
|
co-ordinates are relative to either the bubble component's parent component
|
|
if it has one, or they are screen co-ordinates if not.
|
|
|
|
It'll put itself either above, below, or to the side of the component depending
|
|
on where there's the most space, honouring any restrictions that were set
|
|
with setAllowedPlacement().
|
|
*/
|
|
void setPosition (const Rectangle& rectangleToPointTo);
|
|
|
|
protected:
|
|
|
|
/** Subclasses should override this to return the size of the content they
|
|
want to draw inside the bubble.
|
|
*/
|
|
virtual void getContentSize (int& width, int& height) = 0;
|
|
|
|
/** Subclasses should override this to draw their bubble's contents.
|
|
|
|
The graphics object's clip region and the dimensions passed in here are
|
|
set up to paint just the rectangle inside the bubble.
|
|
*/
|
|
virtual void paintContent (Graphics& g, int width, int height) = 0;
|
|
|
|
public:
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
Rectangle content;
|
|
int side, allowablePlacements;
|
|
float arrowTipX, arrowTipY;
|
|
DropShadowEffect shadow;
|
|
|
|
BubbleComponent (const BubbleComponent&);
|
|
const BubbleComponent& operator= (const BubbleComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_BUBBLECOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_BubbleComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_COLOURSELECTOR_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_ColourSelector.h *********/
|
|
#ifndef __JUCE_COLOURSELECTOR_JUCEHEADER__
|
|
#define __JUCE_COLOURSELECTOR_JUCEHEADER__
|
|
|
|
/**
|
|
A component that lets the user choose a colour.
|
|
|
|
This shows RGB sliders and a colourspace that the user can pick colours from.
|
|
|
|
This class is also a ChangeBroadcaster, so listeners can register to be told
|
|
when the colour changes.
|
|
*/
|
|
class JUCE_API ColourSelector : public Component,
|
|
public ChangeBroadcaster,
|
|
protected SliderListener
|
|
{
|
|
public:
|
|
|
|
/** Options for the type of selector to show. These are passed into the constructor. */
|
|
enum ColourSelectorOptions
|
|
{
|
|
showAlphaChannel = 1 << 0, /**< if set, the colour's alpha channel can be changed as well as its RGB. */
|
|
|
|
showColourAtTop = 1 << 1, /**< if set, a swatch of the colour is shown at the top of the component. */
|
|
showSliders = 1 << 2, /**< if set, RGB sliders are shown at the bottom of the component. */
|
|
showColourspace = 1 << 3 /**< if set, a big HSV selector is shown. */
|
|
};
|
|
|
|
/** Creates a ColourSelector object.
|
|
|
|
The flags are a combination of values from the ColourSelectorOptions enum, specifying
|
|
which of the selector's features should be visible.
|
|
|
|
The edgeGap value specifies the amount of space to leave around the edge.
|
|
|
|
gapAroundColourSpaceComponent indicates how much of a gap to put around the
|
|
colourspace and hue selector components.
|
|
*/
|
|
ColourSelector (const int sectionsToShow = (showAlphaChannel | showColourAtTop | showSliders | showColourspace),
|
|
const int edgeGap = 4,
|
|
const int gapAroundColourSpaceComponent = 7);
|
|
|
|
/** Destructor. */
|
|
~ColourSelector();
|
|
|
|
/** Returns the colour that the user has currently selected.
|
|
|
|
The ColourSelector class is also a ChangeBroadcaster, so listeners can
|
|
register to be told when the colour changes.
|
|
|
|
@see setCurrentColour
|
|
*/
|
|
const Colour getCurrentColour() const;
|
|
|
|
/** Changes the colour that is currently being shown.
|
|
*/
|
|
void setCurrentColour (const Colour& newColour);
|
|
|
|
/** Tells the selector how many preset colour swatches you want to have on the component.
|
|
|
|
To enable swatches, you'll need to override getNumSwatches(), getSwatchColour(), and
|
|
setSwatchColour(), to return the number of colours you want, and to set and retrieve
|
|
their values.
|
|
*/
|
|
virtual int getNumSwatches() const;
|
|
|
|
/** Called by the selector to find out the colour of one of the swatches.
|
|
|
|
Your subclass should return the colour of the swatch with the given index.
|
|
|
|
To enable swatches, you'll need to override getNumSwatches(), getSwatchColour(), and
|
|
setSwatchColour(), to return the number of colours you want, and to set and retrieve
|
|
their values.
|
|
*/
|
|
virtual const Colour getSwatchColour (const int index) const;
|
|
|
|
/** Called by the selector when the user puts a new colour into one of the swatches.
|
|
|
|
Your subclass should change the colour of the swatch with the given index.
|
|
|
|
To enable swatches, you'll need to override getNumSwatches(), getSwatchColour(), and
|
|
setSwatchColour(), to return the number of colours you want, and to set and retrieve
|
|
their values.
|
|
*/
|
|
virtual void setSwatchColour (const int index, const Colour& newColour) const;
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the keyboard.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
backgroundColourId = 0x1007000, /**< the colour used to fill the component's background. */
|
|
labelTextColourId = 0x1007001 /**< the colour used for the labels next to the sliders. */
|
|
};
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class ColourSpaceView;
|
|
friend class HueSelectorComp;
|
|
Colour colour;
|
|
float h, s, v;
|
|
Slider* sliders[4];
|
|
Component* colourSpace;
|
|
Component* hueSelector;
|
|
VoidArray swatchComponents;
|
|
const int flags;
|
|
int topSpace, edgeGap;
|
|
|
|
void setHue (float newH);
|
|
void setSV (float newS, float newV);
|
|
void updateHSV();
|
|
void update();
|
|
void sliderValueChanged (Slider*);
|
|
void paint (Graphics& g);
|
|
void resized();
|
|
|
|
ColourSelector (const ColourSelector&);
|
|
const ColourSelector& operator= (const ColourSelector&);
|
|
|
|
// this constructor is here temporarily to prevent old code compiling, because the parameters
|
|
// have changed - if you get an error here, update your code to use the new constructor instead..
|
|
// (xxx - note to self: remember to remove this at some point in the future)
|
|
ColourSelector (const bool);
|
|
};
|
|
|
|
#endif // __JUCE_COLOURSELECTOR_JUCEHEADER__
|
|
/********* End of inlined file: juce_ColourSelector.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_BUBBLEMESSAGECOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_BubbleMessageComponent.h *********/
|
|
#ifndef __JUCE_BUBBLEMESSAGECOMPONENT_JUCEHEADER__
|
|
#define __JUCE_BUBBLEMESSAGECOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A speech-bubble component that displays a short message.
|
|
|
|
This can be used to show a message with the tail of the speech bubble
|
|
pointing to a particular component or location on the screen.
|
|
|
|
@see BubbleComponent
|
|
*/
|
|
class JUCE_API BubbleMessageComponent : public BubbleComponent,
|
|
private Timer
|
|
{
|
|
public:
|
|
|
|
/** Creates a bubble component.
|
|
|
|
After creating one a BubbleComponent, do the following:
|
|
- add it to an appropriate parent component, or put it on the
|
|
desktop with Component::addToDesktop (0).
|
|
- use the showAt() method to show a message.
|
|
- it will make itself invisible after it times-out (and can optionally
|
|
also delete itself), or you can reuse it somewhere else by calling
|
|
showAt() again.
|
|
*/
|
|
BubbleMessageComponent (const int fadeOutLengthMs = 150);
|
|
|
|
/** Destructor. */
|
|
~BubbleMessageComponent();
|
|
|
|
/** Shows a message bubble at a particular position.
|
|
|
|
This shows the bubble with its stem pointing to the given location
|
|
(co-ordinates being relative to its parent component).
|
|
|
|
For details about exactly how it decides where to position itself, see
|
|
BubbleComponent::updatePosition().
|
|
|
|
@param x the x co-ordinate of end of the bubble's tail
|
|
@param y the y co-ordinate of end of the bubble's tail
|
|
@param message the text to display
|
|
@param numMillisecondsBeforeRemoving how long to leave it on the screen before removing itself
|
|
from its parent compnent. If this is 0 or less, it
|
|
will stay there until manually removed.
|
|
@param removeWhenMouseClicked if this is true, the bubble will disappear as soon as a
|
|
mouse button is pressed (anywhere on the screen)
|
|
@param deleteSelfAfterUse if true, then the component will delete itself after
|
|
it becomes invisible
|
|
*/
|
|
void showAt (int x, int y,
|
|
const String& message,
|
|
const int numMillisecondsBeforeRemoving,
|
|
const bool removeWhenMouseClicked = true,
|
|
const bool deleteSelfAfterUse = false);
|
|
|
|
/** Shows a message bubble next to a particular component.
|
|
|
|
This shows the bubble with its stem pointing at the given component.
|
|
|
|
For details about exactly how it decides where to position itself, see
|
|
BubbleComponent::updatePosition().
|
|
|
|
@param component the component that you want to point at
|
|
@param message the text to display
|
|
@param numMillisecondsBeforeRemoving how long to leave it on the screen before removing itself
|
|
from its parent compnent. If this is 0 or less, it
|
|
will stay there until manually removed.
|
|
@param removeWhenMouseClicked if this is true, the bubble will disappear as soon as a
|
|
mouse button is pressed (anywhere on the screen)
|
|
@param deleteSelfAfterUse if true, then the component will delete itself after
|
|
it becomes invisible
|
|
*/
|
|
void showAt (Component* const component,
|
|
const String& message,
|
|
const int numMillisecondsBeforeRemoving,
|
|
const bool removeWhenMouseClicked = true,
|
|
const bool deleteSelfAfterUse = false);
|
|
|
|
/** @internal */
|
|
void getContentSize (int& w, int& h);
|
|
/** @internal */
|
|
void paintContent (Graphics& g, int w, int h);
|
|
/** @internal */
|
|
void timerCallback();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
int fadeOutLength, mouseClickCounter;
|
|
TextLayout textLayout;
|
|
int64 expiryTime;
|
|
bool deleteAfterUse;
|
|
|
|
void init (const int numMillisecondsBeforeRemoving,
|
|
const bool removeWhenMouseClicked,
|
|
const bool deleteSelfAfterUse);
|
|
|
|
BubbleMessageComponent (const BubbleMessageComponent&);
|
|
const BubbleMessageComponent& operator= (const BubbleMessageComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_BUBBLEMESSAGECOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_BubbleMessageComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DROPSHADOWER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MagnifierComponent.h *********/
|
|
#ifndef __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A component that contains another component, and can magnify or shrink it.
|
|
|
|
This component will continually update its size so that it fits the zoomed
|
|
version of the content component that you put inside it, so don't try to
|
|
change the size of this component directly - instead change that of the
|
|
content component.
|
|
|
|
To make it all work, the magnifier uses extremely cunning ComponentPeer tricks
|
|
to remap mouse events correctly. This means that the content component won't
|
|
appear to be a direct child of this component, and instead will think its
|
|
on the desktop.
|
|
*/
|
|
class JUCE_API MagnifierComponent : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates a MagnifierComponent.
|
|
|
|
This component will continually update its size so that it fits the zoomed
|
|
version of the content component that you put inside it, so don't try to
|
|
change the size of this component directly - instead change that of the
|
|
content component.
|
|
|
|
@param contentComponent the component to add as the magnified one
|
|
@param deleteContentCompWhenNoLongerNeeded if true, the content component will
|
|
be deleted when this component is deleted. If false,
|
|
it's the caller's responsibility to delete it later.
|
|
*/
|
|
MagnifierComponent (Component* const contentComponent,
|
|
const bool deleteContentCompWhenNoLongerNeeded);
|
|
|
|
/** Destructor. */
|
|
~MagnifierComponent();
|
|
|
|
/** Returns the current content component. */
|
|
Component* getContentComponent() const throw() { return content; }
|
|
|
|
/** Changes the zoom level.
|
|
|
|
The scale factor must be greater than zero. Values less than 1 will shrink the
|
|
image; values greater than 1 will multiply its size by this amount.
|
|
|
|
When this is called, this component will change its size to fit the full extent
|
|
of the newly zoomed content.
|
|
*/
|
|
void setScaleFactor (double newScaleFactor);
|
|
|
|
/** Returns the current zoom factor. */
|
|
double getScaleFactor() const throw() { return scaleFactor; }
|
|
|
|
/** Changes the quality setting used to rescale the graphics.
|
|
*/
|
|
void setResamplingQuality (Graphics::ResamplingQuality newQuality);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
/** @internal */
|
|
void childBoundsChanged (Component*);
|
|
|
|
private:
|
|
Component* content;
|
|
Component* holderComp;
|
|
double scaleFactor;
|
|
ComponentPeer* peer;
|
|
bool deleteContent;
|
|
Graphics::ResamplingQuality quality;
|
|
|
|
void paint (Graphics& g);
|
|
void mouseDown (const MouseEvent& e);
|
|
void mouseUp (const MouseEvent& e);
|
|
void mouseDrag (const MouseEvent& e);
|
|
void mouseMove (const MouseEvent& e);
|
|
void mouseEnter (const MouseEvent& e);
|
|
void mouseExit (const MouseEvent& e);
|
|
void mouseWheelMove (const MouseEvent& e, float, float);
|
|
|
|
int scaleInt (const int n) const throw();
|
|
|
|
MagnifierComponent (const MagnifierComponent&);
|
|
const MagnifierComponent& operator= (const MagnifierComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_MagnifierComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_NSVIEWCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_NSViewComponent.h *********/
|
|
#ifndef __JUCE_NSVIEWCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_NSVIEWCOMPONENT_JUCEHEADER__
|
|
|
|
#if ! DOXYGEN
|
|
class NSViewComponentInternal;
|
|
#endif
|
|
|
|
#if JUCE_MAC || DOXYGEN
|
|
|
|
/**
|
|
A Mac-specific class that can create and embed an NSView inside itself.
|
|
|
|
To use it, create one of these, put it in place and make sure it's visible in a
|
|
window, then use setView() to assign an NSView to it. The view will then be
|
|
moved and resized to follow the movements of this component.
|
|
|
|
Of course, since the view is a native object, it'll obliterate any
|
|
juce components that may overlap this component, but that's life.
|
|
*/
|
|
class JUCE_API NSViewComponent : public Component
|
|
{
|
|
public:
|
|
|
|
/** Create an initially-empty container. */
|
|
NSViewComponent();
|
|
|
|
/** Destructor. */
|
|
~NSViewComponent();
|
|
|
|
/** Assigns an NSView to this peer.
|
|
|
|
The view will be retained and released by this component for as long as
|
|
it is needed. To remove the current view, just call setView (0).
|
|
|
|
Note: a void* is used here to avoid including the cocoa headers as
|
|
part of the juce.h, but the method expects an NSView*.
|
|
*/
|
|
void setView (void* nsView);
|
|
|
|
/** Returns the current NSView.
|
|
|
|
Note: a void* is returned here to avoid including the cocoa headers as
|
|
a requirement of juce.h, so you should just cast the object to an NSView*.
|
|
*/
|
|
void* getView() const;
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class NSViewComponentInternal;
|
|
NSViewComponentInternal* info;
|
|
|
|
NSViewComponent (const NSViewComponent&);
|
|
const NSViewComponent& operator= (const NSViewComponent&);
|
|
};
|
|
|
|
#endif
|
|
|
|
#endif // __JUCE_NSVIEWCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_NSViewComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_MIDIKEYBOARDCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_MidiKeyboardComponent.h *********/
|
|
#ifndef __JUCE_MIDIKEYBOARDCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_MIDIKEYBOARDCOMPONENT_JUCEHEADER__
|
|
|
|
/**
|
|
A component that displays a piano keyboard, whose notes can be clicked on.
|
|
|
|
This component will mimic a physical midi keyboard, showing the current state of
|
|
a MidiKeyboardState object. When the on-screen keys are clicked on, it will play these
|
|
notes by calling the noteOn() and noteOff() methods of its MidiKeyboardState object.
|
|
|
|
Another feature is that the computer keyboard can also be used to play notes. By
|
|
default it maps the top two rows of a standard querty keyboard to the notes, but
|
|
these can be remapped if needed. It will only respond to keypresses when it has
|
|
the keyboard focus, so to disable this feature you can call setWantsKeyboardFocus (false).
|
|
|
|
The component is also a ChangeBroadcaster, so if you want to be informed when the
|
|
keyboard is scrolled, you can register a ChangeListener for callbacks.
|
|
|
|
@see MidiKeyboardState
|
|
*/
|
|
class JUCE_API MidiKeyboardComponent : public Component,
|
|
public MidiKeyboardStateListener,
|
|
public ChangeBroadcaster,
|
|
private Timer,
|
|
private AsyncUpdater
|
|
{
|
|
public:
|
|
|
|
/** The direction of the keyboard.
|
|
|
|
@see setOrientation
|
|
*/
|
|
enum Orientation
|
|
{
|
|
horizontalKeyboard,
|
|
verticalKeyboardFacingLeft,
|
|
verticalKeyboardFacingRight,
|
|
};
|
|
|
|
/** Creates a MidiKeyboardComponent.
|
|
|
|
@param state the midi keyboard model that this component will represent
|
|
@param orientation whether the keyboard is horizonal or vertical
|
|
*/
|
|
MidiKeyboardComponent (MidiKeyboardState& state,
|
|
const Orientation orientation);
|
|
|
|
/** Destructor. */
|
|
~MidiKeyboardComponent();
|
|
|
|
/** Changes the velocity used in midi note-on messages that are triggered by clicking
|
|
on the component.
|
|
|
|
Values are 0 to 1.0, where 1.0 is the heaviest.
|
|
|
|
@see setMidiChannel
|
|
*/
|
|
void setVelocity (const float velocity);
|
|
|
|
/** Changes the midi channel number that will be used for events triggered by clicking
|
|
on the component.
|
|
|
|
The channel must be between 1 and 16 (inclusive). This is the channel that will be
|
|
passed on to the MidiKeyboardState::noteOn() method when the user clicks the component.
|
|
|
|
Although this is the channel used for outgoing events, the component can display
|
|
incoming events from more than one channel - see setMidiChannelsToDisplay()
|
|
|
|
@see setVelocity
|
|
*/
|
|
void setMidiChannel (const int midiChannelNumber);
|
|
|
|
/** Returns the midi channel that the keyboard is using for midi messages.
|
|
|
|
@see setMidiChannel
|
|
*/
|
|
int getMidiChannel() const throw() { return midiChannel; }
|
|
|
|
/** Sets a mask to indicate which incoming midi channels should be represented by
|
|
key movements.
|
|
|
|
The mask is a set of bits, where bit 0 = midi channel 1, bit 1 = midi channel 2, etc.
|
|
|
|
If the MidiKeyboardState has a key down for any of the channels whose bits are set
|
|
in this mask, the on-screen keys will also go down.
|
|
|
|
By default, this mask is set to 0xffff (all channels displayed).
|
|
|
|
@see setMidiChannel
|
|
*/
|
|
void setMidiChannelsToDisplay (const int midiChannelMask);
|
|
|
|
/** Returns the current set of midi channels represented by the component.
|
|
|
|
This is the value that was set with setMidiChannelsToDisplay().
|
|
*/
|
|
int getMidiChannelsToDisplay() const throw() { return midiInChannelMask; }
|
|
|
|
/** Changes the width used to draw the white keys. */
|
|
void setKeyWidth (const float widthInPixels);
|
|
|
|
/** Returns the width that was set by setKeyWidth(). */
|
|
float getKeyWidth() const throw() { return keyWidth; }
|
|
|
|
/** Changes the keyboard's current direction. */
|
|
void setOrientation (const Orientation newOrientation);
|
|
|
|
/** Returns the keyboard's current direction. */
|
|
const Orientation getOrientation() const throw() { return orientation; }
|
|
|
|
/** Sets the range of midi notes that the keyboard will be limited to.
|
|
|
|
By default the range is 0 to 127 (inclusive), but you can limit this if you
|
|
only want a restricted set of the keys to be shown.
|
|
|
|
Note that the values here are inclusive and must be between 0 and 127.
|
|
*/
|
|
void setAvailableRange (const int lowestNote,
|
|
const int highestNote);
|
|
|
|
/** Returns the first note in the available range.
|
|
|
|
@see setAvailableRange
|
|
*/
|
|
int getRangeStart() const throw() { return rangeStart; }
|
|
|
|
/** Returns the last note in the available range.
|
|
|
|
@see setAvailableRange
|
|
*/
|
|
int getRangeEnd() const throw() { return rangeEnd; }
|
|
|
|
/** If the keyboard extends beyond the size of the component, this will scroll
|
|
it to show the given key at the start.
|
|
|
|
Whenever the keyboard's position is changed, this will use the ChangeBroadcaster
|
|
base class to send a callback to any ChangeListeners that have been registered.
|
|
*/
|
|
void setLowestVisibleKey (int noteNumber);
|
|
|
|
/** Returns the number of the first key shown in the component.
|
|
|
|
@see setLowestVisibleKey
|
|
*/
|
|
int getLowestVisibleKey() const throw() { return firstKey; }
|
|
|
|
/** Returns the length of the black notes.
|
|
|
|
This will be their vertical or horizontal length, depending on the keyboard's orientation.
|
|
*/
|
|
int getBlackNoteLength() const throw() { return blackNoteLength; }
|
|
|
|
/** If set to true, then scroll buttons will appear at either end of the keyboard
|
|
if there are too many notes to fit them all in the component at once.
|
|
*/
|
|
void setScrollButtonsVisible (const bool canScroll);
|
|
|
|
/** A set of colour IDs to use to change the colour of various aspects of the keyboard.
|
|
|
|
These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
|
|
methods.
|
|
|
|
@see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
|
|
*/
|
|
enum ColourIds
|
|
{
|
|
whiteNoteColourId = 0x1005000,
|
|
blackNoteColourId = 0x1005001,
|
|
keySeparatorLineColourId = 0x1005002,
|
|
mouseOverKeyOverlayColourId = 0x1005003, /**< This colour will be overlaid on the normal note colour. */
|
|
keyDownOverlayColourId = 0x1005004, /**< This colour will be overlaid on the normal note colour. */
|
|
textLabelColourId = 0x1005005,
|
|
upDownButtonBackgroundColourId = 0x1005006,
|
|
upDownButtonArrowColourId = 0x1005007
|
|
};
|
|
|
|
/** Returns the position within the component of the left-hand edge of a key.
|
|
|
|
Depending on the keyboard's orientation, this may be a horizontal or vertical
|
|
distance, in either direction.
|
|
*/
|
|
int getKeyStartPosition (const int midiNoteNumber) const;
|
|
|
|
/** Deletes all key-mappings.
|
|
|
|
@see setKeyPressForNote
|
|
*/
|
|
void clearKeyMappings();
|
|
|
|
/** Maps a key-press to a given note.
|
|
|
|
@param key the key that should trigger the note
|
|
@param midiNoteOffsetFromC how many semitones above C the triggered note should
|
|
be. The actual midi note that gets played will be
|
|
this value + (12 * the current base octave). To change
|
|
the base octave, see setKeyPressBaseOctave()
|
|
*/
|
|
void setKeyPressForNote (const KeyPress& key,
|
|
const int midiNoteOffsetFromC);
|
|
|
|
/** Removes any key-mappings for a given note.
|
|
|
|
For a description of what the note number means, see setKeyPressForNote().
|
|
*/
|
|
void removeKeyPressForNote (const int midiNoteOffsetFromC);
|
|
|
|
/** Changes the base note above which key-press-triggered notes are played.
|
|
|
|
The set of key-mappings that trigger notes can be moved up and down to cover
|
|
the entire scale using this method.
|
|
|
|
The value passed in is an octave number between 0 and 10 (inclusive), and
|
|
indicates which C is the base note to which the key-mapped notes are
|
|
relative.
|
|
*/
|
|
void setKeyPressBaseOctave (const int newOctaveNumber);
|
|
|
|
/** This sets the octave number which is shown as the octave number for middle C.
|
|
|
|
This affects only the default implementation of getWhiteNoteText(), which
|
|
passes this octave number to MidiMessage::getMidiNoteName() in order to
|
|
get the note text. See MidiMessage::getMidiNoteName() for more info about
|
|
the parameter.
|
|
|
|
By default this value is set to 3.
|
|
|
|
@see getOctaveForMiddleC
|
|
*/
|
|
void setOctaveForMiddleC (const int octaveNumForMiddleC) throw();
|
|
|
|
/** This returns the value set by setOctaveForMiddleC().
|
|
@see setOctaveForMiddleC
|
|
*/
|
|
int getOctaveForMiddleC() const throw() { return octaveNumForMiddleC; }
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void mouseMove (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDrag (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseDown (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseUp (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseEnter (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseExit (const MouseEvent& e);
|
|
/** @internal */
|
|
void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
|
|
/** @internal */
|
|
void timerCallback();
|
|
/** @internal */
|
|
bool keyStateChanged (const bool isKeyDown);
|
|
/** @internal */
|
|
void focusLost (FocusChangeType cause);
|
|
/** @internal */
|
|
void handleNoteOn (MidiKeyboardState* source, int midiChannel, int midiNoteNumber, float velocity);
|
|
/** @internal */
|
|
void handleNoteOff (MidiKeyboardState* source, int midiChannel, int midiNoteNumber);
|
|
/** @internal */
|
|
void handleAsyncUpdate();
|
|
/** @internal */
|
|
void colourChanged();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
friend class MidiKeyboardUpDownButton;
|
|
|
|
/** Draws a white note in the given rectangle.
|
|
|
|
isOver indicates whether the mouse is over the key, isDown indicates whether the key is
|
|
currently pressed down.
|
|
|
|
When doing this, be sure to note the keyboard's orientation.
|
|
*/
|
|
virtual void drawWhiteNote (int midiNoteNumber,
|
|
Graphics& g,
|
|
int x, int y, int w, int h,
|
|
bool isDown, bool isOver,
|
|
const Colour& lineColour,
|
|
const Colour& textColour);
|
|
|
|
/** Draws a black note in the given rectangle.
|
|
|
|
isOver indicates whether the mouse is over the key, isDown indicates whether the key is
|
|
currently pressed down.
|
|
|
|
When doing this, be sure to note the keyboard's orientation.
|
|
*/
|
|
virtual void drawBlackNote (int midiNoteNumber,
|
|
Graphics& g,
|
|
int x, int y, int w, int h,
|
|
bool isDown, bool isOver,
|
|
const Colour& noteFillColour);
|
|
|
|
/** Allows text to be drawn on the white notes.
|
|
|
|
By default this is used to label the C in each octave, but could be used for other things.
|
|
|
|
@see setOctaveForMiddleC
|
|
*/
|
|
virtual const String getWhiteNoteText (const int midiNoteNumber);
|
|
|
|
/** Draws the up and down buttons that change the base note. */
|
|
virtual void drawUpDownButton (Graphics& g, int w, int h,
|
|
const bool isMouseOver,
|
|
const bool isButtonPressed,
|
|
const bool movesOctavesUp);
|
|
|
|
/** Callback when the mouse is clicked on a key.
|
|
|
|
You could use this to do things like handle right-clicks on keys, etc.
|
|
|
|
Return true if you want the click to trigger the note, or false if you
|
|
want to handle it yourself and not have the note played.
|
|
|
|
@see mouseDraggedToKey
|
|
*/
|
|
virtual bool mouseDownOnKey (int midiNoteNumber, const MouseEvent& e);
|
|
|
|
/** Callback when the mouse is dragged from one key onto another.
|
|
|
|
@see mouseDownOnKey
|
|
*/
|
|
virtual void mouseDraggedToKey (int midiNoteNumber, const MouseEvent& e);
|
|
|
|
/** Calculates the positon of a given midi-note.
|
|
|
|
This can be overridden to create layouts with custom key-widths.
|
|
|
|
@param midiNoteNumber the note to find
|
|
@param keyWidth the desired width in pixels of one key - see setKeyWidth()
|
|
@param x the x position of the left-hand edge of the key (this method
|
|
always works in terms of a horizontal keyboard)
|
|
@param w the width of the key
|
|
*/
|
|
virtual void getKeyPosition (int midiNoteNumber, float keyWidth,
|
|
int& x, int& w) const;
|
|
|
|
private:
|
|
|
|
MidiKeyboardState& state;
|
|
int xOffset, blackNoteLength;
|
|
float keyWidth;
|
|
Orientation orientation;
|
|
|
|
int midiChannel, midiInChannelMask;
|
|
float velocity;
|
|
int noteUnderMouse, mouseDownNote;
|
|
BitArray keysPressed, keysCurrentlyDrawnDown;
|
|
|
|
int rangeStart, rangeEnd, firstKey;
|
|
bool canScroll, mouseDragging;
|
|
Button* scrollDown;
|
|
Button* scrollUp;
|
|
|
|
Array <KeyPress> keyPresses;
|
|
Array <int> keyPressNotes;
|
|
int keyMappingOctave;
|
|
int octaveNumForMiddleC;
|
|
|
|
void getKeyPos (int midiNoteNumber, int& x, int& w) const;
|
|
int xyToNote (int x, int y);
|
|
int remappedXYToNote (int x, int y) const;
|
|
void resetAnyKeysInUse();
|
|
void updateNoteUnderMouse (int x, int y);
|
|
void repaintNote (const int midiNoteNumber);
|
|
|
|
MidiKeyboardComponent (const MidiKeyboardComponent&);
|
|
const MidiKeyboardComponent& operator= (const MidiKeyboardComponent&);
|
|
};
|
|
|
|
#endif // __JUCE_MIDIKEYBOARDCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_MidiKeyboardComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_OPENGLCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_OpenGLComponent.h *********/
|
|
#ifndef __JUCE_OPENGLCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_OPENGLCOMPONENT_JUCEHEADER__
|
|
|
|
// this is used to disable OpenGL, and is defined in juce_Config.h
|
|
#if JUCE_OPENGL || DOXYGEN
|
|
|
|
class OpenGLComponentWatcher;
|
|
|
|
/**
|
|
Represents the various properties of an OpenGL bitmap format.
|
|
|
|
@see OpenGLComponent::setPixelFormat
|
|
*/
|
|
struct OpenGLPixelFormat
|
|
{
|
|
|
|
/** Creates an OpenGLPixelFormat.
|
|
|
|
The default constructor just initialises the object as a simple 8-bit
|
|
RGBA format.
|
|
*/
|
|
OpenGLPixelFormat (const int bitsPerRGBComponent = 8,
|
|
const int alphaBits = 8,
|
|
const int depthBufferBits = 16,
|
|
const int stencilBufferBits = 0) throw();
|
|
|
|
int redBits; /**< The number of bits per pixel to use for the red channel. */
|
|
int greenBits; /**< The number of bits per pixel to use for the green channel. */
|
|
int blueBits; /**< The number of bits per pixel to use for the blue channel. */
|
|
int alphaBits; /**< The number of bits per pixel to use for the alpha channel. */
|
|
|
|
int depthBufferBits; /**< The number of bits per pixel to use for a depth buffer. */
|
|
int stencilBufferBits; /**< The number of bits per pixel to use for a stencil buffer. */
|
|
|
|
int accumulationBufferRedBits; /**< The number of bits per pixel to use for an accumulation buffer's red channel. */
|
|
int accumulationBufferGreenBits; /**< The number of bits per pixel to use for an accumulation buffer's green channel. */
|
|
int accumulationBufferBlueBits; /**< The number of bits per pixel to use for an accumulation buffer's blue channel. */
|
|
int accumulationBufferAlphaBits; /**< The number of bits per pixel to use for an accumulation buffer's alpha channel. */
|
|
|
|
uint8 fullSceneAntiAliasingNumSamples; /**< The number of samples to use in full-scene anti-aliasing (if available). */
|
|
|
|
/** Returns a list of all the pixel formats that can be used in this system.
|
|
|
|
A reference component is needed in case there are multiple screens with different
|
|
capabilities - in which case, the one that the component is on will be used.
|
|
*/
|
|
static void getAvailablePixelFormats (Component* component,
|
|
OwnedArray <OpenGLPixelFormat>& results);
|
|
|
|
bool operator== (const OpenGLPixelFormat&) const throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
};
|
|
|
|
/**
|
|
A base class for types of OpenGL context.
|
|
|
|
An OpenGLComponent will supply its own context for drawing in its window.
|
|
*/
|
|
class OpenGLContext
|
|
{
|
|
public:
|
|
|
|
/** Destructor. */
|
|
virtual ~OpenGLContext();
|
|
|
|
/** Makes this context the currently active one. */
|
|
virtual bool makeActive() const throw() = 0;
|
|
/** If this context is currently active, it is disactivated. */
|
|
virtual bool makeInactive() const throw() = 0;
|
|
/** Returns true if this context is currently active. */
|
|
virtual bool isActive() const throw() = 0;
|
|
|
|
/** Swaps the buffers (if the context can do this). */
|
|
virtual void swapBuffers() = 0;
|
|
|
|
/** Sets whether the context checks the vertical sync before swapping.
|
|
|
|
The value is the number of frames to allow between buffer-swapping. This is
|
|
fairly system-dependent, but 0 turns off syncing, 1 makes it swap on frame-boundaries,
|
|
and greater numbers indicate that it should swap less often.
|
|
|
|
Returns true if it sets the value successfully.
|
|
*/
|
|
virtual bool setSwapInterval (const int numFramesPerSwap) = 0;
|
|
|
|
/** Returns the current swap-sync interval.
|
|
See setSwapInterval() for info about the value returned.
|
|
*/
|
|
virtual int getSwapInterval() const = 0;
|
|
|
|
/** Returns the pixel format being used by this context. */
|
|
virtual const OpenGLPixelFormat getPixelFormat() const = 0;
|
|
|
|
/** For windowed contexts, this moves the context within the bounds of
|
|
its parent window.
|
|
*/
|
|
virtual void updateWindowPosition (int x, int y, int w, int h, int outerWindowHeight) = 0;
|
|
|
|
/** For windowed contexts, this triggers a repaint of the window.
|
|
|
|
(Not relevent on all platforms).
|
|
*/
|
|
virtual void repaint() = 0;
|
|
|
|
/** Returns an OS-dependent handle to the raw GL context.
|
|
|
|
On win32, this will be a HGLRC; on the Mac, an AGLContext; on Linux,
|
|
a GLXContext.
|
|
*/
|
|
virtual void* getRawContext() const throw() = 0;
|
|
|
|
/** This tries to create a context that can be used for drawing into the
|
|
area occupied by the specified component.
|
|
|
|
Note that you probably shouldn't use this method directly unless you know what
|
|
you're doing - the OpenGLComponent calls this and manages the context for you.
|
|
*/
|
|
static OpenGLContext* createContextForWindow (Component* componentToDrawTo,
|
|
const OpenGLPixelFormat& pixelFormat,
|
|
const OpenGLContext* const contextToShareWith);
|
|
|
|
/** Returns the context that's currently in active use by the calling thread.
|
|
|
|
Returns 0 if there isn't an active context.
|
|
*/
|
|
static OpenGLContext* getCurrentContext();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
OpenGLContext() throw();
|
|
};
|
|
|
|
/**
|
|
A component that contains an OpenGL canvas.
|
|
|
|
Override this, add it to whatever component you want to, and use the renderOpenGL()
|
|
method to draw its contents.
|
|
|
|
*/
|
|
class JUCE_API OpenGLComponent : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates an OpenGLComponent.
|
|
*/
|
|
OpenGLComponent();
|
|
|
|
/** Destructor. */
|
|
~OpenGLComponent();
|
|
|
|
/** Changes the pixel format used by this component.
|
|
|
|
@see OpenGLPixelFormat::getAvailablePixelFormats()
|
|
*/
|
|
void setPixelFormat (const OpenGLPixelFormat& formatToUse);
|
|
|
|
/** Returns the pixel format that this component is currently using. */
|
|
const OpenGLPixelFormat getPixelFormat() const;
|
|
|
|
/** Specifies an OpenGL context which should be shared with the one that this
|
|
component is using.
|
|
|
|
This is an OpenGL feature that lets two contexts share their texture data.
|
|
|
|
Note that this pointer is stored by the component, and when the component
|
|
needs to recreate its internal context for some reason, the same context
|
|
will be used again to share lists. So if you pass a context in here,
|
|
don't delete the context while this component is still using it! You can
|
|
call shareWith (0) to stop this component from sharing with it.
|
|
*/
|
|
void shareWith (OpenGLContext* contextToShareListsWith);
|
|
|
|
/** Returns the context that this component is sharing with.
|
|
@see shareWith
|
|
*/
|
|
OpenGLContext* getShareContext() const throw() { return contextToShareListsWith; }
|
|
|
|
/** Flips the openGL buffers over. */
|
|
void swapBuffers();
|
|
|
|
/** This replaces the normal paint() callback - use it to draw your openGL stuff.
|
|
|
|
When this is called, makeCurrentContextActive() will already have been called
|
|
for you, so you just need to draw.
|
|
*/
|
|
virtual void renderOpenGL() = 0;
|
|
|
|
/** This method is called when the component creates a new OpenGL context.
|
|
|
|
A new context may be created when the component is first used, or when it
|
|
is moved to a different window, or when the window is hidden and re-shown,
|
|
etc.
|
|
|
|
You can use this callback as an opportunity to set up things like textures
|
|
that your context needs.
|
|
|
|
New contexts are created on-demand by the makeCurrentContextActive() method - so
|
|
if the context is deleted, e.g. by changing the pixel format or window, no context
|
|
will be created until the next call to makeCurrentContextActive(), which will
|
|
synchronously create one and call this method. This means that if you're using
|
|
a non-GUI thread for rendering, you can make sure this method is be called by
|
|
your renderer thread.
|
|
|
|
When this callback happens, the context will already have been made current
|
|
using the makeCurrentContextActive() method, so there's no need to call it
|
|
again in your code.
|
|
*/
|
|
virtual void newOpenGLContextCreated() = 0;
|
|
|
|
/** Returns the context that will draw into this component.
|
|
|
|
This may return 0 if the component is currently invisible or hasn't currently
|
|
got a context. The context object can be deleted and a new one created during
|
|
the lifetime of this component, and there may be times when it doesn't have one.
|
|
|
|
@see newOpenGLContextCreated()
|
|
*/
|
|
OpenGLContext* getCurrentContext() const throw() { return context; }
|
|
|
|
/** Makes this component the current openGL context.
|
|
|
|
You might want to use this in things like your resize() method, before calling
|
|
GL commands.
|
|
|
|
If this returns false, then the context isn't active, so you should avoid
|
|
making any calls.
|
|
|
|
This call may actually create a context if one isn't currently initialised. If
|
|
it does this, it will also synchronously call the newOpenGLContextCreated()
|
|
method to let you initialise it as necessary.
|
|
|
|
@see OpenGLContext::makeActive
|
|
*/
|
|
bool makeCurrentContextActive();
|
|
|
|
/** Stops the current component being the active OpenGL context.
|
|
|
|
This is the opposite of makeCurrentContextActive()
|
|
|
|
@see OpenGLContext::makeInactive
|
|
*/
|
|
void makeCurrentContextInactive();
|
|
|
|
/** Returns true if this component is the active openGL context for the
|
|
current thread.
|
|
|
|
@see OpenGLContext::isActive
|
|
*/
|
|
bool isActiveContext() const throw();
|
|
|
|
/** Calls the rendering callback, and swaps the buffers afterwards.
|
|
|
|
This is called automatically by paint() when the component needs to be rendered.
|
|
|
|
It can be overridden if you need to decouple the rendering from the paint callback
|
|
and render with a custom thread.
|
|
|
|
Returns true if the operation succeeded.
|
|
*/
|
|
virtual bool renderAndSwapBuffers();
|
|
|
|
/** This returns a critical section that can be used to lock the current context.
|
|
|
|
Because the context that is used by this component can change, e.g. when the
|
|
component is shown or hidden, then if you're rendering to it on a background
|
|
thread, this allows you to lock the context for the duration of your rendering
|
|
routine.
|
|
*/
|
|
CriticalSection& getContextLock() throw() { return contextLock; }
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
|
|
/** Returns the native handle of an embedded heavyweight window, if there is one.
|
|
|
|
E.g. On windows, this will return the HWND of the sub-window containing
|
|
the opengl context, on the mac it'll be the NSOpenGLView.
|
|
*/
|
|
void* getNativeWindowHandle() const;
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
friend class OpenGLComponentWatcher;
|
|
OpenGLComponentWatcher* componentWatcher;
|
|
|
|
OpenGLContext* context;
|
|
OpenGLContext* contextToShareListsWith;
|
|
|
|
CriticalSection contextLock;
|
|
OpenGLPixelFormat preferredPixelFormat;
|
|
bool needToUpdateViewport;
|
|
|
|
void deleteContext();
|
|
void updateContextPosition();
|
|
void internalRepaint (int x, int y, int w, int h);
|
|
|
|
OpenGLComponent (const OpenGLComponent&);
|
|
const OpenGLComponent& operator= (const OpenGLComponent&);
|
|
};
|
|
|
|
#endif
|
|
#endif // __JUCE_OPENGLCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_OpenGLComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_PREFERENCESPANEL_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_PreferencesPanel.h *********/
|
|
#ifndef __JUCE_PREFERENCESPANEL_JUCEHEADER__
|
|
#define __JUCE_PREFERENCESPANEL_JUCEHEADER__
|
|
|
|
/**
|
|
A component with a set of buttons at the top for changing between pages of
|
|
preferences.
|
|
|
|
This is just a handy way of writing a Mac-style preferences panel where you
|
|
have a row of buttons along the top for the different preference categories,
|
|
each button having an icon above its name. Clicking these will show an
|
|
appropriate prefs page below it.
|
|
|
|
You can either put one of these inside your own component, or just use the
|
|
showInDialogBox() method to show it in a window and run it modally.
|
|
|
|
To use it, just add a set of named pages with the addSettingsPage() method,
|
|
and implement the createComponentForPage() method to create suitable components
|
|
for each of these pages.
|
|
*/
|
|
class JUCE_API PreferencesPanel : public Component,
|
|
private ButtonListener
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty panel.
|
|
|
|
Use addSettingsPage() to add some pages to it in your constructor.
|
|
*/
|
|
PreferencesPanel();
|
|
|
|
/** Destructor. */
|
|
~PreferencesPanel();
|
|
|
|
/** Creates a page using a set of drawables to define the page's icon.
|
|
|
|
Note that the other version of this method is much easier if you're using
|
|
an image instead of a custom drawable.
|
|
|
|
@param pageTitle the name of this preferences page - you'll need to
|
|
make sure your createComponentForPage() method creates
|
|
a suitable component when it is passed this name
|
|
@param normalIcon the drawable to display in the page's button normally
|
|
@param overIcon the drawable to display in the page's button when the mouse is over
|
|
@param downIcon the drawable to display in the page's button when the button is down
|
|
@see DrawableButton
|
|
*/
|
|
void addSettingsPage (const String& pageTitle,
|
|
const Drawable* normalIcon,
|
|
const Drawable* overIcon,
|
|
const Drawable* downIcon);
|
|
|
|
/** Creates a page using a set of drawables to define the page's icon.
|
|
|
|
The other version of this method gives you more control over the icon, but this
|
|
one is much easier if you're just loading it from a file.
|
|
|
|
@param pageTitle the name of this preferences page - you'll need to
|
|
make sure your createComponentForPage() method creates
|
|
a suitable component when it is passed this name
|
|
@param imageData a block of data containing an image file, e.g. a jpeg, png or gif.
|
|
For this to look good, you'll probably want to use a nice
|
|
transparent png file.
|
|
@param imageDataSize the size of the image data, in bytes
|
|
*/
|
|
void addSettingsPage (const String& pageTitle,
|
|
const char* imageData,
|
|
const int imageDataSize);
|
|
|
|
/** Utility method to display this panel in a DialogWindow.
|
|
|
|
Calling this will create a DialogWindow containing this panel with the
|
|
given size and title, and will run it modally, returning when the user
|
|
closes the dialog box.
|
|
*/
|
|
void showInDialogBox (const String& dialogtitle,
|
|
int dialogWidth,
|
|
int dialogHeight,
|
|
const Colour& backgroundColour = Colours::white);
|
|
|
|
/** Subclasses must override this to return a component for each preferences page.
|
|
|
|
The subclass should return a pointer to a new component representing the named
|
|
page, which the panel will then display.
|
|
|
|
The panel will delete the component later when the user goes to another page
|
|
or deletes the panel.
|
|
*/
|
|
virtual Component* createComponentForPage (const String& pageName) = 0;
|
|
|
|
/** Changes the current page being displayed. */
|
|
void setCurrentPage (const String& pageName);
|
|
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void buttonClicked (Button* button);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
String currentPageName;
|
|
Component* currentPage;
|
|
int buttonSize;
|
|
|
|
PreferencesPanel (const PreferencesPanel&);
|
|
const PreferencesPanel& operator= (const PreferencesPanel&);
|
|
};
|
|
|
|
#endif // __JUCE_PREFERENCESPANEL_JUCEHEADER__
|
|
/********* End of inlined file: juce_PreferencesPanel.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_QuickTimeMovieComponent.h *********/
|
|
#ifndef __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__
|
|
#define __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__
|
|
|
|
// this is used to disable QuickTime, and is defined in juce_Config.h
|
|
#if JUCE_QUICKTIME || DOXYGEN
|
|
|
|
#if JUCE_WIN32
|
|
|
|
typedef ActiveXControlComponent QTCompBaseClass;
|
|
#else
|
|
|
|
typedef NSViewComponent QTCompBaseClass;
|
|
#endif
|
|
|
|
/**
|
|
A window that can play back a QuickTime movie.
|
|
|
|
*/
|
|
class JUCE_API QuickTimeMovieComponent : public QTCompBaseClass
|
|
{
|
|
public:
|
|
|
|
/** Creates a QuickTimeMovieComponent, initially blank.
|
|
|
|
Use the loadMovie() method to load a movie once you've added the
|
|
component to a window, (or put it on the desktop as a heavyweight window).
|
|
Loading a movie when the component isn't visible can cause problems, as
|
|
QuickTime needs a window handle to initialise properly.
|
|
*/
|
|
QuickTimeMovieComponent();
|
|
|
|
/** Destructor. */
|
|
~QuickTimeMovieComponent();
|
|
|
|
/** Returns true if QT is installed and working on this machine.
|
|
*/
|
|
static bool isQuickTimeAvailable() throw();
|
|
|
|
/** Tries to load a QuickTime movie into the player.
|
|
|
|
It's best to call this function once you've added the component to a window,
|
|
(or put it on the desktop as a heavyweight window). Loading a movie when the
|
|
component isn't visible can cause problems, because QuickTime needs a window
|
|
handle to do its stuff.
|
|
|
|
@param movieFile the .mov file to open
|
|
@param isControllerVisible whether to show a controller bar at the bottom
|
|
@returns true if the movie opens successfully
|
|
*/
|
|
bool loadMovie (const File& movieFile,
|
|
const bool isControllerVisible);
|
|
|
|
bool loadMovie (InputStream* movieStream,
|
|
const bool isControllerVisible);
|
|
|
|
/** Closes the movie, if one is open. */
|
|
void closeMovie();
|
|
|
|
/** Returns the movie file that is currently open.
|
|
|
|
If there isn't one, this returns File::nonexistent
|
|
*/
|
|
const File getCurrentMovieFile() const;
|
|
|
|
/** Returns true if there's currently a movie open. */
|
|
bool isMovieOpen() const;
|
|
|
|
/** Returns the length of the movie, in seconds. */
|
|
double getMovieDuration() const;
|
|
|
|
/** Returns the movie's natural size, in pixels.
|
|
|
|
You can use this to resize the component to show the movie at its preferred
|
|
scale.
|
|
|
|
If no movie is loaded, the size returned will be 0 x 0.
|
|
*/
|
|
void getMovieNormalSize (int& width, int& height) const;
|
|
|
|
/** This will position the component within a given area, keeping its aspect
|
|
ratio correct according to the movie's normal size.
|
|
|
|
The component will be made as large as it can go within the space, and will
|
|
be aligned according to the justification value if this means there are gaps at
|
|
the top or sides.
|
|
*/
|
|
void setBoundsWithCorrectAspectRatio (const Rectangle& spaceToFitWithin,
|
|
const RectanglePlacement& placement);
|
|
|
|
/** Starts the movie playing. */
|
|
void play();
|
|
|
|
/** Stops the movie playing. */
|
|
void stop();
|
|
|
|
/** Returns true if the movie is currently playing. */
|
|
bool isPlaying() const;
|
|
|
|
/** Moves the movie's position back to the start. */
|
|
void goToStart();
|
|
|
|
/** Sets the movie's position to a given time. */
|
|
void setPosition (const double seconds);
|
|
|
|
/** Returns the current play position of the movie. */
|
|
double getPosition() const;
|
|
|
|
/** Changes the movie playback rate.
|
|
|
|
A value of 1 is normal speed, greater values play it proportionately faster,
|
|
smaller values play it slower.
|
|
*/
|
|
void setSpeed (const float newSpeed);
|
|
|
|
/** Changes the movie's playback volume.
|
|
|
|
@param newVolume the volume in the range 0 (silent) to 1.0 (full)
|
|
*/
|
|
void setMovieVolume (const float newVolume);
|
|
|
|
/** Returns the movie's playback volume.
|
|
|
|
@returns the volume in the range 0 (silent) to 1.0 (full)
|
|
*/
|
|
float getMovieVolume() const;
|
|
|
|
/** Tells the movie whether it should loop. */
|
|
void setLooping (const bool shouldLoop);
|
|
|
|
/** Returns true if the movie is currently looping.
|
|
|
|
@see setLooping
|
|
*/
|
|
bool isLooping() const;
|
|
|
|
/** True if the native QuickTime controller bar is shown in the window.
|
|
|
|
@see loadMovie
|
|
*/
|
|
bool isControllerVisible() const;
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
File movieFile;
|
|
bool movieLoaded, controllerVisible, looping;
|
|
|
|
#if JUCE_WIN32
|
|
/** @internal */
|
|
void parentHierarchyChanged();
|
|
/** @internal */
|
|
void visibilityChanged();
|
|
|
|
void createControlIfNeeded();
|
|
bool isControlCreated() const;
|
|
void* internal;
|
|
#else
|
|
void* movie;
|
|
#endif
|
|
|
|
QuickTimeMovieComponent (const QuickTimeMovieComponent&);
|
|
const QuickTimeMovieComponent& operator= (const QuickTimeMovieComponent&);
|
|
};
|
|
|
|
#endif
|
|
#endif // __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_QuickTimeMovieComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_WebBrowserComponent.h *********/
|
|
#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__
|
|
|
|
#if JUCE_WEB_BROWSER || DOXYGEN
|
|
|
|
#if ! DOXYGEN
|
|
class WebBrowserComponentInternal;
|
|
#endif
|
|
|
|
/**
|
|
A component that displays an embedded web browser.
|
|
|
|
The browser itself will be platform-dependent. On the Mac, probably Safari, on
|
|
Windows, probably IE.
|
|
|
|
*/
|
|
class JUCE_API WebBrowserComponent : public Component
|
|
{
|
|
public:
|
|
|
|
/** Creates a WebBrowserComponent.
|
|
|
|
Once it's created and visible, send the browser to a URL using goToURL().
|
|
|
|
@param unloadPageWhenBrowserIsHidden if this is true, then when the browser
|
|
component is taken offscreen, it'll clear the current page
|
|
and replace it with a blank page - this can be handy to stop
|
|
the browser using resources in the background when it's not
|
|
actually being used.
|
|
*/
|
|
WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden = true);
|
|
|
|
/** Destructor. */
|
|
~WebBrowserComponent();
|
|
|
|
/** Sends the browser to a particular URL.
|
|
|
|
@param url the URL to go to.
|
|
@param headers an optional set of parameters to put in the HTTP header. If
|
|
you supply this, it should be a set of string in the form
|
|
"HeaderKey: HeaderValue"
|
|
@param postData an optional block of data that will be attached to the HTTP
|
|
POST request
|
|
*/
|
|
void goToURL (const String& url,
|
|
const StringArray* headers = 0,
|
|
const MemoryBlock* postData = 0);
|
|
|
|
/** Stops the current page loading.
|
|
*/
|
|
void stop();
|
|
|
|
/** Sends the browser back one page.
|
|
*/
|
|
void goBack();
|
|
|
|
/** Sends the browser forward one page.
|
|
*/
|
|
void goForward();
|
|
|
|
/** Refreshes the browser.
|
|
*/
|
|
void refresh();
|
|
|
|
/** This callback is called when the browser is about to navigate
|
|
to a new location.
|
|
|
|
You can override this method to perform some action when the user
|
|
tries to go to a particular URL. To allow the operation to carry on,
|
|
return true, or return false to stop the navigation happening.
|
|
*/
|
|
virtual bool pageAboutToLoad (const String& newURL);
|
|
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
/** @internal */
|
|
void resized();
|
|
/** @internal */
|
|
void parentHierarchyChanged();
|
|
/** @internal */
|
|
void visibilityChanged();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
WebBrowserComponentInternal* browser;
|
|
bool blankPageShown, unloadPageWhenBrowserIsHidden;
|
|
String lastURL;
|
|
StringArray lastHeaders;
|
|
MemoryBlock lastPostData;
|
|
|
|
void reloadLastURL();
|
|
void checkWindowAssociation();
|
|
|
|
WebBrowserComponent (const WebBrowserComponent&);
|
|
const WebBrowserComponent& operator= (const WebBrowserComponent&);
|
|
};
|
|
|
|
#endif
|
|
#endif // __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_WebBrowserComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_SystemTrayIconComponent.h *********/
|
|
#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__
|
|
#define __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__
|
|
|
|
#if JUCE_WIN32 || JUCE_LINUX || DOXYGEN
|
|
|
|
/**
|
|
On Windows only, this component sits in the taskbar tray as a small icon.
|
|
|
|
To use it, just create one of these components, but don't attempt to make it
|
|
visible, add it to a parent, or put it on the desktop.
|
|
|
|
You can then call setIconImage() to create an icon for it in the taskbar.
|
|
|
|
To change the icon's tooltip, you can use setIconTooltip().
|
|
|
|
To respond to mouse-events, you can override the normal mouseDown(),
|
|
mouseUp(), mouseDoubleClick() and mouseMove() methods, and although the x, y
|
|
position will not be valid, you can use this to respond to clicks. Traditionally
|
|
you'd use a left-click to show your application's window, and a right-click
|
|
to show a pop-up menu.
|
|
*/
|
|
class JUCE_API SystemTrayIconComponent : public Component
|
|
{
|
|
public:
|
|
|
|
SystemTrayIconComponent();
|
|
|
|
/** Destructor. */
|
|
~SystemTrayIconComponent();
|
|
|
|
/** Changes the image shown in the taskbar.
|
|
*/
|
|
void setIconImage (const Image& newImage);
|
|
|
|
/** Changes the tooltip that Windows shows above the icon. */
|
|
void setIconTooltip (const String& tooltip);
|
|
|
|
#if JUCE_LINUX
|
|
/** @internal */
|
|
void paint (Graphics& g);
|
|
#endif
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
SystemTrayIconComponent (const SystemTrayIconComponent&);
|
|
const SystemTrayIconComponent& operator= (const SystemTrayIconComponent&);
|
|
};
|
|
|
|
#endif
|
|
#endif // __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_SystemTrayIconComponent.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_LookAndFeel.h *********/
|
|
#ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__
|
|
#define __JUCE_LOOKANDFEEL_JUCEHEADER__
|
|
|
|
class ToggleButton;
|
|
class TextButton;
|
|
class AlertWindow;
|
|
class TextLayout;
|
|
class ScrollBar;
|
|
class BubbleComponent;
|
|
class ComboBox;
|
|
class Button;
|
|
class FilenameComponent;
|
|
class DocumentWindow;
|
|
class ResizableWindow;
|
|
class GroupComponent;
|
|
class MenuBarComponent;
|
|
class DropShadower;
|
|
class GlyphArrangement;
|
|
class PropertyComponent;
|
|
class TableHeaderComponent;
|
|
class Toolbar;
|
|
class ToolbarItemComponent;
|
|
class PopupMenu;
|
|
class ProgressBar;
|
|
class FileBrowserComponent;
|
|
class DirectoryContentsDisplayComponent;
|
|
class FilePreviewComponent;
|
|
class ImageButton;
|
|
|
|
/**
|
|
LookAndFeel objects define the appearance of all the JUCE widgets, and subclasses
|
|
can be used to apply different 'skins' to the application.
|
|
|
|
*/
|
|
class JUCE_API LookAndFeel
|
|
{
|
|
public:
|
|
|
|
/** Creates the default JUCE look and feel. */
|
|
LookAndFeel();
|
|
|
|
/** Destructor. */
|
|
virtual ~LookAndFeel();
|
|
|
|
/** Returns the current default look-and-feel for a component to use when it
|
|
hasn't got one explicitly set.
|
|
|
|
@see setDefaultLookAndFeel
|
|
*/
|
|
static LookAndFeel& getDefaultLookAndFeel() throw();
|
|
|
|
/** Changes the default look-and-feel.
|
|
|
|
@param newDefaultLookAndFeel the new look-and-feel object to use - if this is
|
|
set to 0, it will revert to using the default one. The
|
|
object passed-in must be deleted by the caller when
|
|
it's no longer needed.
|
|
@see getDefaultLookAndFeel
|
|
*/
|
|
static void setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel) throw();
|
|
|
|
/** Looks for a colour that has been registered with the given colour ID number.
|
|
|
|
If a colour has been set for this ID number using setColour(), then it is
|
|
returned. If none has been set, it will just return Colours::black.
|
|
|
|
The colour IDs for various purposes are stored as enums in the components that
|
|
they are relevent to - for an example, see Slider::ColourIds,
|
|
Label::ColourIds, TextEditor::ColourIds, TreeView::ColourIds, etc.
|
|
|
|
If you're looking up a colour for use in drawing a component, it's usually
|
|
best not to call this directly, but to use the Component::findColour() method
|
|
instead. That will first check whether a suitable colour has been registered
|
|
directly with the component, and will fall-back on calling the component's
|
|
LookAndFeel's findColour() method if none is found.
|
|
|
|
@see setColour, Component::findColour, Component::setColour
|
|
*/
|
|
const Colour findColour (const int colourId) const throw();
|
|
|
|
/** Registers a colour to be used for a particular purpose.
|
|
|
|
For more details, see the comments for findColour().
|
|
|
|
@see findColour, Component::findColour, Component::setColour
|
|
*/
|
|
void setColour (const int colourId, const Colour& colour) throw();
|
|
|
|
/** Returns true if the specified colour ID has been explicitly set using the
|
|
setColour() method.
|
|
*/
|
|
bool isColourSpecified (const int colourId) const throw();
|
|
|
|
virtual const Typeface::Ptr getTypefaceForFont (const Font& font);
|
|
|
|
/** Allows you to change the default sans-serif font.
|
|
|
|
If you need to supply your own Typeface object for any of the default fonts, rather
|
|
than just supplying the name (e.g. if you want to use an embedded font), then
|
|
you should instead override getTypefaceForFont() to create and return the typeface.
|
|
*/
|
|
void setDefaultSansSerifTypefaceName (const String& newName);
|
|
|
|
/** Draws the lozenge-shaped background for a standard button. */
|
|
virtual void drawButtonBackground (Graphics& g,
|
|
Button& button,
|
|
const Colour& backgroundColour,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
virtual const Font getFontForTextButton (TextButton& button);
|
|
|
|
/** Draws the text for a TextButton. */
|
|
virtual void drawButtonText (Graphics& g,
|
|
TextButton& button,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
/** Draws the contents of a standard ToggleButton. */
|
|
virtual void drawToggleButton (Graphics& g,
|
|
ToggleButton& button,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
virtual void changeToggleButtonWidthToFitText (ToggleButton& button);
|
|
|
|
virtual void drawTickBox (Graphics& g,
|
|
Component& component,
|
|
int x, int y, int w, int h,
|
|
const bool ticked,
|
|
const bool isEnabled,
|
|
const bool isMouseOverButton,
|
|
const bool isButtonDown);
|
|
|
|
/* AlertWindow handling..
|
|
*/
|
|
virtual AlertWindow* createAlertWindow (const String& title,
|
|
const String& message,
|
|
const String& button1,
|
|
const String& button2,
|
|
const String& button3,
|
|
AlertWindow::AlertIconType iconType,
|
|
int numButtons,
|
|
Component* associatedComponent);
|
|
|
|
virtual void drawAlertBox (Graphics& g,
|
|
AlertWindow& alert,
|
|
const Rectangle& textArea,
|
|
TextLayout& textLayout);
|
|
|
|
virtual int getAlertBoxWindowFlags();
|
|
|
|
virtual int getAlertWindowButtonHeight();
|
|
|
|
virtual const Font getAlertWindowFont();
|
|
|
|
/** Draws a progress bar.
|
|
|
|
If the progress value is less than 0 or greater than 1.0, this should draw a spinning
|
|
bar that fills the whole space (i.e. to say that the app is still busy but the progress
|
|
isn't known). It can use the current time as a basis for playing an animation.
|
|
|
|
(Used by progress bars in AlertWindow).
|
|
*/
|
|
virtual void drawProgressBar (Graphics& g, ProgressBar& progressBar,
|
|
int width, int height,
|
|
double progress, const String& textToShow);
|
|
|
|
// Draws a small image that spins to indicate that something's happening..
|
|
// This method should use the current time to animate itself, so just keep
|
|
// repainting it every so often.
|
|
virtual void drawSpinningWaitAnimation (Graphics& g, int x, int y, int w, int h);
|
|
|
|
/** Draws one of the buttons on a scrollbar.
|
|
|
|
@param g the context to draw into
|
|
@param scrollbar the bar itself
|
|
@param width the width of the button
|
|
@param height the height of the button
|
|
@param buttonDirection the direction of the button, where 0 = up, 1 = right, 2 = down, 3 = left
|
|
@param isScrollbarVertical true if it's a vertical bar, false if horizontal
|
|
@param isMouseOverButton whether the mouse is currently over the button (also true if it's held down)
|
|
@param isButtonDown whether the mouse button's held down
|
|
*/
|
|
virtual void drawScrollbarButton (Graphics& g,
|
|
ScrollBar& scrollbar,
|
|
int width, int height,
|
|
int buttonDirection,
|
|
bool isScrollbarVertical,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
/** Draws the thumb area of a scrollbar.
|
|
|
|
@param g the context to draw into
|
|
@param scrollbar the bar itself
|
|
@param x the x position of the left edge of the thumb area to draw in
|
|
@param y the y position of the top edge of the thumb area to draw in
|
|
@param width the width of the thumb area to draw in
|
|
@param height the height of the thumb area to draw in
|
|
@param isScrollbarVertical true if it's a vertical bar, false if horizontal
|
|
@param thumbStartPosition for vertical bars, the y co-ordinate of the top of the
|
|
thumb, or its x position for horizontal bars
|
|
@param thumbSize for vertical bars, the height of the thumb, or its width for
|
|
horizontal bars. This may be 0 if the thumb shouldn't be drawn.
|
|
@param isMouseOver whether the mouse is over the thumb area, also true if the mouse is
|
|
currently dragging the thumb
|
|
@param isMouseDown whether the mouse is currently dragging the scrollbar
|
|
*/
|
|
virtual void drawScrollbar (Graphics& g,
|
|
ScrollBar& scrollbar,
|
|
int x, int y,
|
|
int width, int height,
|
|
bool isScrollbarVertical,
|
|
int thumbStartPosition,
|
|
int thumbSize,
|
|
bool isMouseOver,
|
|
bool isMouseDown);
|
|
|
|
/** Returns the component effect to use for a scrollbar */
|
|
virtual ImageEffectFilter* getScrollbarEffect();
|
|
|
|
/** Returns the minimum length in pixels to use for a scrollbar thumb. */
|
|
virtual int getMinimumScrollbarThumbSize (ScrollBar& scrollbar);
|
|
|
|
/** Returns the default thickness to use for a scrollbar. */
|
|
virtual int getDefaultScrollbarWidth();
|
|
|
|
/** Returns the length in pixels to use for a scrollbar button. */
|
|
virtual int getScrollbarButtonSize (ScrollBar& scrollbar);
|
|
|
|
/** Returns a tick shape for use in yes/no boxes, etc. */
|
|
virtual const Path getTickShape (const float height);
|
|
/** Returns a cross shape for use in yes/no boxes, etc. */
|
|
virtual const Path getCrossShape (const float height);
|
|
|
|
/** Draws the + or - box in a treeview. */
|
|
virtual void drawTreeviewPlusMinusBox (Graphics& g, int x, int y, int w, int h, bool isPlus, bool isMouseOver);
|
|
|
|
virtual void fillTextEditorBackground (Graphics& g, int width, int height, TextEditor& textEditor);
|
|
virtual void drawTextEditorOutline (Graphics& g, int width, int height, TextEditor& textEditor);
|
|
|
|
// these return an image from the ImageCache, so use ImageCache::release() to free it
|
|
virtual Image* getDefaultFolderImage();
|
|
virtual Image* getDefaultDocumentFileImage();
|
|
|
|
virtual void createFileChooserHeaderText (const String& title,
|
|
const String& instructions,
|
|
GlyphArrangement& destArrangement,
|
|
int width);
|
|
|
|
virtual void drawFileBrowserRow (Graphics& g, int width, int height,
|
|
const String& filename, Image* icon,
|
|
const String& fileSizeDescription,
|
|
const String& fileTimeDescription,
|
|
const bool isDirectory,
|
|
const bool isItemSelected,
|
|
const int itemIndex);
|
|
|
|
virtual Button* createFileBrowserGoUpButton();
|
|
|
|
virtual void layoutFileBrowserComponent (FileBrowserComponent& browserComp,
|
|
DirectoryContentsDisplayComponent* fileListComponent,
|
|
FilePreviewComponent* previewComp,
|
|
ComboBox* currentPathBox,
|
|
TextEditor* filenameBox,
|
|
Button* goUpButton);
|
|
|
|
virtual void drawBubble (Graphics& g,
|
|
float tipX, float tipY,
|
|
float boxX, float boxY, float boxW, float boxH);
|
|
|
|
/** Fills the background of a popup menu component. */
|
|
virtual void drawPopupMenuBackground (Graphics& g, int width, int height);
|
|
|
|
/** Draws one of the items in a popup menu. */
|
|
virtual void drawPopupMenuItem (Graphics& g,
|
|
int width, int height,
|
|
const bool isSeparator,
|
|
const bool isActive,
|
|
const bool isHighlighted,
|
|
const bool isTicked,
|
|
const bool hasSubMenu,
|
|
const String& text,
|
|
const String& shortcutKeyText,
|
|
Image* image,
|
|
const Colour* const textColour);
|
|
|
|
/** Returns the size and style of font to use in popup menus. */
|
|
virtual const Font getPopupMenuFont();
|
|
|
|
virtual void drawPopupMenuUpDownArrow (Graphics& g,
|
|
int width, int height,
|
|
bool isScrollUpArrow);
|
|
|
|
/** Finds the best size for an item in a popup menu. */
|
|
virtual void getIdealPopupMenuItemSize (const String& text,
|
|
const bool isSeparator,
|
|
int standardMenuItemHeight,
|
|
int& idealWidth,
|
|
int& idealHeight);
|
|
|
|
virtual int getMenuWindowFlags();
|
|
|
|
virtual void drawMenuBarBackground (Graphics& g, int width, int height,
|
|
bool isMouseOverBar,
|
|
MenuBarComponent& menuBar);
|
|
|
|
virtual int getMenuBarItemWidth (MenuBarComponent& menuBar, int itemIndex, const String& itemText);
|
|
|
|
virtual const Font getMenuBarFont (MenuBarComponent& menuBar, int itemIndex, const String& itemText);
|
|
|
|
virtual void drawMenuBarItem (Graphics& g,
|
|
int width, int height,
|
|
int itemIndex,
|
|
const String& itemText,
|
|
bool isMouseOverItem,
|
|
bool isMenuOpen,
|
|
bool isMouseOverBar,
|
|
MenuBarComponent& menuBar);
|
|
|
|
virtual void drawComboBox (Graphics& g, int width, int height,
|
|
const bool isButtonDown,
|
|
int buttonX, int buttonY,
|
|
int buttonW, int buttonH,
|
|
ComboBox& box);
|
|
|
|
virtual const Font getComboBoxFont (ComboBox& box);
|
|
|
|
virtual Label* createComboBoxTextBox (ComboBox& box);
|
|
|
|
virtual void positionComboBoxText (ComboBox& box, Label& labelToPosition);
|
|
|
|
virtual void drawLabel (Graphics& g, Label& label);
|
|
|
|
virtual void drawLinearSlider (Graphics& g,
|
|
int x, int y,
|
|
int width, int height,
|
|
float sliderPos,
|
|
float minSliderPos,
|
|
float maxSliderPos,
|
|
const Slider::SliderStyle style,
|
|
Slider& slider);
|
|
|
|
virtual void drawLinearSliderBackground (Graphics& g,
|
|
int x, int y,
|
|
int width, int height,
|
|
float sliderPos,
|
|
float minSliderPos,
|
|
float maxSliderPos,
|
|
const Slider::SliderStyle style,
|
|
Slider& slider);
|
|
|
|
virtual void drawLinearSliderThumb (Graphics& g,
|
|
int x, int y,
|
|
int width, int height,
|
|
float sliderPos,
|
|
float minSliderPos,
|
|
float maxSliderPos,
|
|
const Slider::SliderStyle style,
|
|
Slider& slider);
|
|
|
|
virtual int getSliderThumbRadius (Slider& slider);
|
|
|
|
virtual void drawRotarySlider (Graphics& g,
|
|
int x, int y,
|
|
int width, int height,
|
|
float sliderPosProportional,
|
|
const float rotaryStartAngle,
|
|
const float rotaryEndAngle,
|
|
Slider& slider);
|
|
|
|
virtual Button* createSliderButton (const bool isIncrement);
|
|
virtual Label* createSliderTextBox (Slider& slider);
|
|
|
|
virtual ImageEffectFilter* getSliderEffect();
|
|
|
|
virtual void getTooltipSize (const String& tipText, int& width, int& height);
|
|
|
|
virtual void drawTooltip (Graphics& g, const String& text, int width, int height);
|
|
|
|
virtual Button* createFilenameComponentBrowseButton (const String& text);
|
|
|
|
virtual void layoutFilenameComponent (FilenameComponent& filenameComp,
|
|
ComboBox* filenameBox, Button* browseButton);
|
|
|
|
virtual void drawCornerResizer (Graphics& g,
|
|
int w, int h,
|
|
bool isMouseOver,
|
|
bool isMouseDragging);
|
|
|
|
virtual void drawResizableFrame (Graphics& g,
|
|
int w, int h,
|
|
const BorderSize& borders);
|
|
|
|
virtual void fillResizableWindowBackground (Graphics& g, int w, int h,
|
|
const BorderSize& border,
|
|
ResizableWindow& window);
|
|
|
|
virtual void drawResizableWindowBorder (Graphics& g,
|
|
int w, int h,
|
|
const BorderSize& border,
|
|
ResizableWindow& window);
|
|
|
|
virtual void drawDocumentWindowTitleBar (DocumentWindow& window,
|
|
Graphics& g, int w, int h,
|
|
int titleSpaceX, int titleSpaceW,
|
|
const Image* icon,
|
|
bool drawTitleTextOnLeft);
|
|
|
|
virtual Button* createDocumentWindowButton (int buttonType);
|
|
|
|
virtual void positionDocumentWindowButtons (DocumentWindow& window,
|
|
int titleBarX, int titleBarY,
|
|
int titleBarW, int titleBarH,
|
|
Button* minimiseButton,
|
|
Button* maximiseButton,
|
|
Button* closeButton,
|
|
bool positionTitleBarButtonsOnLeft);
|
|
|
|
virtual int getDefaultMenuBarHeight();
|
|
|
|
virtual DropShadower* createDropShadowerForComponent (Component* component);
|
|
|
|
virtual void drawStretchableLayoutResizerBar (Graphics& g,
|
|
int w, int h,
|
|
bool isVerticalBar,
|
|
bool isMouseOver,
|
|
bool isMouseDragging);
|
|
|
|
virtual void drawGroupComponentOutline (Graphics& g, int w, int h,
|
|
const String& text,
|
|
const Justification& position,
|
|
GroupComponent& group);
|
|
|
|
virtual void createTabButtonShape (Path& p,
|
|
int width, int height,
|
|
int tabIndex,
|
|
const String& text,
|
|
Button& button,
|
|
TabbedButtonBar::Orientation orientation,
|
|
const bool isMouseOver,
|
|
const bool isMouseDown,
|
|
const bool isFrontTab);
|
|
|
|
virtual void fillTabButtonShape (Graphics& g,
|
|
const Path& path,
|
|
const Colour& preferredBackgroundColour,
|
|
int tabIndex,
|
|
const String& text,
|
|
Button& button,
|
|
TabbedButtonBar::Orientation orientation,
|
|
const bool isMouseOver,
|
|
const bool isMouseDown,
|
|
const bool isFrontTab);
|
|
|
|
virtual void drawTabButtonText (Graphics& g,
|
|
int x, int y, int w, int h,
|
|
const Colour& preferredBackgroundColour,
|
|
int tabIndex,
|
|
const String& text,
|
|
Button& button,
|
|
TabbedButtonBar::Orientation orientation,
|
|
const bool isMouseOver,
|
|
const bool isMouseDown,
|
|
const bool isFrontTab);
|
|
|
|
virtual int getTabButtonOverlap (int tabDepth);
|
|
virtual int getTabButtonSpaceAroundImage();
|
|
|
|
virtual int getTabButtonBestWidth (int tabIndex,
|
|
const String& text,
|
|
int tabDepth,
|
|
Button& button);
|
|
|
|
virtual void drawTabButton (Graphics& g,
|
|
int w, int h,
|
|
const Colour& preferredColour,
|
|
int tabIndex,
|
|
const String& text,
|
|
Button& button,
|
|
TabbedButtonBar::Orientation orientation,
|
|
const bool isMouseOver,
|
|
const bool isMouseDown,
|
|
const bool isFrontTab);
|
|
|
|
virtual void drawTabAreaBehindFrontButton (Graphics& g,
|
|
int w, int h,
|
|
TabbedButtonBar& tabBar,
|
|
TabbedButtonBar::Orientation orientation);
|
|
|
|
virtual Button* createTabBarExtrasButton();
|
|
|
|
virtual void drawImageButton (Graphics& g, Image* image,
|
|
int imageX, int imageY, int imageW, int imageH,
|
|
const Colour& overlayColour,
|
|
float imageOpacity,
|
|
ImageButton& button);
|
|
|
|
virtual void drawTableHeaderBackground (Graphics& g, TableHeaderComponent& header);
|
|
|
|
virtual void drawTableHeaderColumn (Graphics& g, const String& columnName, int columnId,
|
|
int width, int height,
|
|
bool isMouseOver, bool isMouseDown,
|
|
int columnFlags);
|
|
|
|
virtual void paintToolbarBackground (Graphics& g, int width, int height, Toolbar& toolbar);
|
|
|
|
virtual Button* createToolbarMissingItemsButton (Toolbar& toolbar);
|
|
|
|
virtual void paintToolbarButtonBackground (Graphics& g, int width, int height,
|
|
bool isMouseOver, bool isMouseDown,
|
|
ToolbarItemComponent& component);
|
|
|
|
virtual void paintToolbarButtonLabel (Graphics& g, int x, int y, int width, int height,
|
|
const String& text, ToolbarItemComponent& component);
|
|
|
|
virtual void drawPropertyPanelSectionHeader (Graphics& g, const String& name,
|
|
bool isOpen, int width, int height);
|
|
|
|
virtual void drawPropertyComponentBackground (Graphics& g, int width, int height,
|
|
PropertyComponent& component);
|
|
|
|
virtual void drawPropertyComponentLabel (Graphics& g, int width, int height,
|
|
PropertyComponent& component);
|
|
|
|
virtual const Rectangle getPropertyComponentContentPosition (PropertyComponent& component);
|
|
|
|
virtual void drawLevelMeter (Graphics& g, int width, int height, float level);
|
|
|
|
/**
|
|
*/
|
|
virtual void playAlertSound();
|
|
|
|
/** Utility function to draw a shiny, glassy circle (for round LED-type buttons). */
|
|
static void drawGlassSphere (Graphics& g,
|
|
const float x, const float y,
|
|
const float diameter,
|
|
const Colour& colour,
|
|
const float outlineThickness) throw();
|
|
|
|
static void drawGlassPointer (Graphics& g,
|
|
const float x, const float y,
|
|
const float diameter,
|
|
const Colour& colour, const float outlineThickness,
|
|
const int direction) throw();
|
|
|
|
/** Utility function to draw a shiny, glassy oblong (for text buttons). */
|
|
static void drawGlassLozenge (Graphics& g,
|
|
const float x, const float y,
|
|
const float width, const float height,
|
|
const Colour& colour,
|
|
const float outlineThickness,
|
|
const float cornerSize,
|
|
const bool flatOnLeft, const bool flatOnRight,
|
|
const bool flatOnTop, const bool flatOnBottom) throw();
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
protected:
|
|
// xxx the following methods are only here to cause a compiler error, because they've been
|
|
// deprecated or their parameters have changed. Hopefully these definitions should cause an
|
|
// error if you try to build a subclass with the old versions.
|
|
virtual int drawTickBox (Graphics&, int, int, int, int, bool, const bool, const bool, const bool) { return 0; }
|
|
virtual int drawProgressBar (Graphics&, int, int, int, int, float) { return 0; }
|
|
virtual int drawProgressBar (Graphics&, ProgressBar&, int, int, int, int, float) { return 0; }
|
|
virtual void getTabButtonBestWidth (int, const String&, int) {}
|
|
virtual int drawTreeviewPlusMinusBox (Graphics&, int, int, int, int, bool) { return 0; }
|
|
|
|
private:
|
|
friend void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI();
|
|
static void clearDefaultLookAndFeel() throw(); // called at shutdown
|
|
|
|
Array <int> colourIds;
|
|
Array <Colour> colours;
|
|
|
|
// default typeface names
|
|
String defaultSans, defaultSerif, defaultFixed;
|
|
|
|
void drawShinyButtonShape (Graphics& g,
|
|
float x, float y, float w, float h, float maxCornerSize,
|
|
const Colour& baseColour,
|
|
const float strokeWidth,
|
|
const bool flatOnLeft,
|
|
const bool flatOnRight,
|
|
const bool flatOnTop,
|
|
const bool flatOnBottom) throw();
|
|
|
|
LookAndFeel (const LookAndFeel&);
|
|
const LookAndFeel& operator= (const LookAndFeel&);
|
|
};
|
|
|
|
#endif // __JUCE_LOOKANDFEEL_JUCEHEADER__
|
|
/********* End of inlined file: juce_LookAndFeel.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_OldSchoolLookAndFeel.h *********/
|
|
#ifndef __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__
|
|
#define __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__
|
|
|
|
/**
|
|
The original Juce look-and-feel.
|
|
|
|
*/
|
|
class JUCE_API OldSchoolLookAndFeel : public LookAndFeel
|
|
{
|
|
public:
|
|
|
|
/** Creates the default JUCE look and feel. */
|
|
OldSchoolLookAndFeel();
|
|
|
|
/** Destructor. */
|
|
virtual ~OldSchoolLookAndFeel();
|
|
|
|
/** Draws the lozenge-shaped background for a standard button. */
|
|
virtual void drawButtonBackground (Graphics& g,
|
|
Button& button,
|
|
const Colour& backgroundColour,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
/** Draws the contents of a standard ToggleButton. */
|
|
virtual void drawToggleButton (Graphics& g,
|
|
ToggleButton& button,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
virtual void drawTickBox (Graphics& g,
|
|
Component& component,
|
|
int x, int y, int w, int h,
|
|
const bool ticked,
|
|
const bool isEnabled,
|
|
const bool isMouseOverButton,
|
|
const bool isButtonDown);
|
|
|
|
virtual void drawProgressBar (Graphics& g, ProgressBar& progressBar,
|
|
int width, int height,
|
|
double progress, const String& textToShow);
|
|
|
|
virtual void drawScrollbarButton (Graphics& g,
|
|
ScrollBar& scrollbar,
|
|
int width, int height,
|
|
int buttonDirection,
|
|
bool isScrollbarVertical,
|
|
bool isMouseOverButton,
|
|
bool isButtonDown);
|
|
|
|
virtual void drawScrollbar (Graphics& g,
|
|
ScrollBar& scrollbar,
|
|
int x, int y,
|
|
int width, int height,
|
|
bool isScrollbarVertical,
|
|
int thumbStartPosition,
|
|
int thumbSize,
|
|
bool isMouseOver,
|
|
bool isMouseDown);
|
|
|
|
virtual ImageEffectFilter* getScrollbarEffect();
|
|
|
|
virtual void drawTextEditorOutline (Graphics& g,
|
|
int width, int height,
|
|
TextEditor& textEditor);
|
|
|
|
/** Fills the background of a popup menu component. */
|
|
virtual void drawPopupMenuBackground (Graphics& g, int width, int height);
|
|
|
|
virtual void drawMenuBarBackground (Graphics& g, int width, int height,
|
|
bool isMouseOverBar,
|
|
MenuBarComponent& menuBar);
|
|
|
|
virtual void drawComboBox (Graphics& g, int width, int height,
|
|
const bool isButtonDown,
|
|
int buttonX, int buttonY,
|
|
int buttonW, int buttonH,
|
|
ComboBox& box);
|
|
|
|
virtual const Font getComboBoxFont (ComboBox& box);
|
|
|
|
virtual void drawLinearSlider (Graphics& g,
|
|
int x, int y,
|
|
int width, int height,
|
|
float sliderPos,
|
|
float minSliderPos,
|
|
float maxSliderPos,
|
|
const Slider::SliderStyle style,
|
|
Slider& slider);
|
|
|
|
virtual int getSliderThumbRadius (Slider& slider);
|
|
|
|
virtual Button* createSliderButton (const bool isIncrement);
|
|
|
|
virtual ImageEffectFilter* getSliderEffect();
|
|
|
|
virtual void drawCornerResizer (Graphics& g,
|
|
int w, int h,
|
|
bool isMouseOver,
|
|
bool isMouseDragging);
|
|
|
|
virtual Button* createDocumentWindowButton (int buttonType);
|
|
|
|
virtual void positionDocumentWindowButtons (DocumentWindow& window,
|
|
int titleBarX, int titleBarY,
|
|
int titleBarW, int titleBarH,
|
|
Button* minimiseButton,
|
|
Button* maximiseButton,
|
|
Button* closeButton,
|
|
bool positionTitleBarButtonsOnLeft);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
DropShadowEffect scrollbarShadow;
|
|
|
|
OldSchoolLookAndFeel (const OldSchoolLookAndFeel&);
|
|
const OldSchoolLookAndFeel& operator= (const OldSchoolLookAndFeel&);
|
|
};
|
|
|
|
#endif // __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__
|
|
/********* End of inlined file: juce_OldSchoolLookAndFeel.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_FILEBASEDDOCUMENT_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_FileBasedDocument.h *********/
|
|
#ifndef __JUCE_FILEBASEDDOCUMENT_JUCEHEADER__
|
|
#define __JUCE_FILEBASEDDOCUMENT_JUCEHEADER__
|
|
|
|
/**
|
|
A class to take care of the logic involved with the loading/saving of some kind
|
|
of document.
|
|
|
|
There's quite a lot of tedious logic involved in writing all the load/save/save-as
|
|
functions you need for documents that get saved to a file, so this class attempts
|
|
to abstract most of the boring stuff.
|
|
|
|
Your subclass should just implement all the pure virtual methods, and you can
|
|
then use the higher-level public methods to do the load/save dialogs, to warn the user
|
|
about overwriting files, etc.
|
|
|
|
The document object keeps track of whether it has changed since it was last saved or
|
|
loaded, so when you change something, call its changed() method. This will set a
|
|
flag so it knows it needs saving, and will also broadcast a change message using the
|
|
ChangeBroadcaster base class.
|
|
|
|
@see ChangeBroadcaster
|
|
*/
|
|
class JUCE_API FileBasedDocument : public ChangeBroadcaster
|
|
{
|
|
public:
|
|
/** Creates a FileBasedDocument.
|
|
|
|
@param fileExtension the extension to use when loading/saving files, e.g. ".doc"
|
|
@param fileWildCard the wildcard to use in file dialogs, e.g. "*.doc"
|
|
@param openFileDialogTitle the title to show on an open-file dialog, e.g. "Choose a file to open.."
|
|
@param saveFileDialogTitle the title to show on an save-file dialog, e.g. "Choose a file to save as.."
|
|
*/
|
|
FileBasedDocument (const String& fileExtension,
|
|
const String& fileWildCard,
|
|
const String& openFileDialogTitle,
|
|
const String& saveFileDialogTitle);
|
|
|
|
/** Destructor. */
|
|
virtual ~FileBasedDocument();
|
|
|
|
/** Returns true if the changed() method has been called since the file was
|
|
last saved or loaded.
|
|
|
|
@see resetChangedFlag, changed
|
|
*/
|
|
bool hasChangedSinceSaved() const throw() { return changedSinceSave; }
|
|
|
|
/** Called to indicate that the document has changed and needs saving.
|
|
|
|
This method will also trigger a change message to be sent out using the
|
|
ChangeBroadcaster base class.
|
|
|
|
After calling the method, the hasChangedSinceSaved() method will return true, until
|
|
it is reset either by saving to a file or using the resetChangedFlag() method.
|
|
|
|
@see hasChangedSinceSaved, resetChangedFlag
|
|
*/
|
|
virtual void changed();
|
|
|
|
/** Sets the state of the 'changed' flag.
|
|
|
|
The 'changed' flag is set to true when the changed() method is called - use this method
|
|
to reset it or to set it without also broadcasting a change message.
|
|
|
|
@see changed, hasChangedSinceSaved
|
|
*/
|
|
void setChangedFlag (const bool hasChanged);
|
|
|
|
/** Tries to open a file.
|
|
|
|
If the file opens correctly, the document's file (see the getFile() method) is set
|
|
to this new one; if it fails, the document's file is left unchanged, and optionally
|
|
a message box is shown telling the user there was an error.
|
|
|
|
@returns true if the new file loaded successfully
|
|
@see loadDocument, loadFromUserSpecifiedFile
|
|
*/
|
|
bool loadFrom (const File& fileToLoadFrom,
|
|
const bool showMessageOnFailure);
|
|
|
|
/** Asks the user for a file and tries to load it.
|
|
|
|
This will pop up a dialog box using the title, file extension and
|
|
wildcard specified in the document's constructor, and asks the user
|
|
for a file. If they pick one, the loadFrom() method is used to
|
|
try to load it, optionally showing a message if it fails.
|
|
|
|
@returns true if a file was loaded; false if the user cancelled or if they
|
|
picked a file which failed to load correctly
|
|
@see loadFrom
|
|
*/
|
|
bool loadFromUserSpecifiedFile (const bool showMessageOnFailure);
|
|
|
|
/** A set of possible outcomes of one of the save() methods
|
|
*/
|
|
enum SaveResult
|
|
{
|
|
savedOk = 0, /**< indicates that a file was saved successfully. */
|
|
userCancelledSave, /**< indicates that the user aborted the save operation. */
|
|
failedToWriteToFile /**< indicates that it tried to write to a file but this failed. */
|
|
};
|
|
|
|
/** Tries to save the document to the last file it was saved or loaded from.
|
|
|
|
This will always try to write to the file, even if the document isn't flagged as
|
|
having changed.
|
|
|
|
@param askUserForFileIfNotSpecified if there's no file currently specified and this is
|
|
true, it will prompt the user to pick a file, as if
|
|
saveAsInteractive() was called.
|
|
@param showMessageOnFailure if true it will show a warning message when if the
|
|
save operation fails
|
|
@see saveIfNeededAndUserAgrees, saveAs, saveAsInteractive
|
|
*/
|
|
SaveResult save (const bool askUserForFileIfNotSpecified,
|
|
const bool showMessageOnFailure);
|
|
|
|
/** If the file needs saving, it'll ask the user if that's what they want to do, and save
|
|
it if they say yes.
|
|
|
|
If you've got a document open and want to close it (e.g. to quit the app), this is the
|
|
method to call.
|
|
|
|
If the document doesn't need saving it'll return the value savedOk so
|
|
you can go ahead and delete the document.
|
|
|
|
If it does need saving it'll prompt the user, and if they say "discard changes" it'll
|
|
return savedOk, so again, you can safely delete the document.
|
|
|
|
If the user clicks "cancel", it'll return userCancelledSave, so if you can abort the
|
|
close-document operation.
|
|
|
|
And if they click "save changes", it'll try to save and either return savedOk, or
|
|
failedToWriteToFile if there was a problem.
|
|
|
|
@see save, saveAs, saveAsInteractive
|
|
*/
|
|
SaveResult saveIfNeededAndUserAgrees();
|
|
|
|
/** Tries to save the document to a specified file.
|
|
|
|
If this succeeds, it'll also change the document's internal file (as returned by
|
|
the getFile() method). If it fails, the file will be left unchanged.
|
|
|
|
@param newFile the file to try to write to
|
|
@param warnAboutOverwritingExistingFiles if true and the file exists, it'll ask
|
|
the user first if they want to overwrite it
|
|
@param askUserForFileIfNotSpecified if the file is non-existent and this is true, it'll
|
|
use the saveAsInteractive() method to ask the user for a
|
|
filename
|
|
@param showMessageOnFailure if true and the write operation fails, it'll show
|
|
a message box to warn the user
|
|
@see saveIfNeededAndUserAgrees, save, saveAsInteractive
|
|
*/
|
|
SaveResult saveAs (const File& newFile,
|
|
const bool warnAboutOverwritingExistingFiles,
|
|
const bool askUserForFileIfNotSpecified,
|
|
const bool showMessageOnFailure);
|
|
|
|
/** Prompts the user for a filename and tries to save to it.
|
|
|
|
This will pop up a dialog box using the title, file extension and
|
|
wildcard specified in the document's constructor, and asks the user
|
|
for a file. If they pick one, the saveAs() method is used to try to save
|
|
to this file.
|
|
|
|
@param warnAboutOverwritingExistingFiles if true and the file exists, it'll ask
|
|
the user first if they want to overwrite it
|
|
@see saveIfNeededAndUserAgrees, save, saveAs
|
|
*/
|
|
SaveResult saveAsInteractive (const bool warnAboutOverwritingExistingFiles);
|
|
|
|
/** Returns the file that this document was last successfully saved or loaded from.
|
|
|
|
When the document object is created, this will be set to File::nonexistent.
|
|
|
|
It is changed when one of the load or save methods is used, or when setFile()
|
|
is used to explicitly set it.
|
|
*/
|
|
const File getFile() const throw() { return documentFile; }
|
|
|
|
/** Sets the file that this document thinks it was loaded from.
|
|
|
|
This won't actually load anything - it just changes the file stored internally.
|
|
|
|
@see getFile
|
|
*/
|
|
void setFile (const File& newFile);
|
|
|
|
protected:
|
|
|
|
/** Overload this to return the title of the document.
|
|
|
|
This is used in message boxes, filenames and file choosers, so it should be
|
|
something sensible.
|
|
*/
|
|
virtual const String getDocumentTitle() = 0;
|
|
|
|
/** This method should try to load your document from the given file.
|
|
|
|
If it fails, it should return an error message. If it succeeds, it should return
|
|
an empty string.
|
|
*/
|
|
virtual const String loadDocument (const File& file) = 0;
|
|
|
|
/** This method should try to write your document to the given file.
|
|
|
|
If it fails, it should return an error message. If it succeeds, it should return
|
|
an empty string.
|
|
*/
|
|
virtual const String saveDocument (const File& file) = 0;
|
|
|
|
/** This is used for dialog boxes to make them open at the last folder you
|
|
were using.
|
|
|
|
getLastDocumentOpened() and setLastDocumentOpened() are used to store
|
|
the last document that was used - you might want to store this value
|
|
in a static variable, or even in your application's properties. It should
|
|
be a global setting rather than a property of this object.
|
|
|
|
This method works very well in conjunction with a RecentlyOpenedFilesList
|
|
object to manage your recent-files list.
|
|
|
|
As a default value, it's ok to return File::nonexistent, and the document
|
|
object will use a sensible one instead.
|
|
|
|
@see RecentlyOpenedFilesList
|
|
*/
|
|
virtual const File getLastDocumentOpened() = 0;
|
|
|
|
/** This is used for dialog boxes to make them open at the last folder you
|
|
were using.
|
|
|
|
getLastDocumentOpened() and setLastDocumentOpened() are used to store
|
|
the last document that was used - you might want to store this value
|
|
in a static variable, or even in your application's properties. It should
|
|
be a global setting rather than a property of this object.
|
|
|
|
This method works very well in conjunction with a RecentlyOpenedFilesList
|
|
object to manage your recent-files list.
|
|
|
|
@see RecentlyOpenedFilesList
|
|
*/
|
|
virtual void setLastDocumentOpened (const File& file) = 0;
|
|
|
|
public:
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
File documentFile;
|
|
bool changedSinceSave;
|
|
String fileExtension, fileWildcard, openFileDialogTitle, saveFileDialogTitle;
|
|
|
|
FileBasedDocument (const FileBasedDocument&);
|
|
const FileBasedDocument& operator= (const FileBasedDocument&);
|
|
};
|
|
|
|
#endif // __JUCE_FILEBASEDDOCUMENT_JUCEHEADER__
|
|
/********* End of inlined file: juce_FileBasedDocument.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_PROPERTIESFILE_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_RECENTLYOPENEDFILESLIST_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_RecentlyOpenedFilesList.h *********/
|
|
#ifndef __JUCE_RECENTLYOPENEDFILESLIST_JUCEHEADER__
|
|
#define __JUCE_RECENTLYOPENEDFILESLIST_JUCEHEADER__
|
|
|
|
/**
|
|
Manages a set of files for use as a list of recently-opened documents.
|
|
|
|
This is a handy class for holding your list of recently-opened documents, with
|
|
helpful methods for things like purging any non-existent files, automatically
|
|
adding them to a menu, and making persistence easy.
|
|
|
|
@see File, FileBasedDocument
|
|
*/
|
|
class JUCE_API RecentlyOpenedFilesList
|
|
{
|
|
public:
|
|
|
|
/** Creates an empty list.
|
|
*/
|
|
RecentlyOpenedFilesList();
|
|
|
|
/** Destructor. */
|
|
~RecentlyOpenedFilesList();
|
|
|
|
/** Sets a limit for the number of files that will be stored in the list.
|
|
|
|
When addFile() is called, then if there is no more space in the list, the
|
|
least-recently added file will be dropped.
|
|
|
|
@see getMaxNumberOfItems
|
|
*/
|
|
void setMaxNumberOfItems (const int newMaxNumber);
|
|
|
|
/** Returns the number of items that this list will store.
|
|
@see setMaxNumberOfItems
|
|
*/
|
|
int getMaxNumberOfItems() const throw() { return maxNumberOfItems; }
|
|
|
|
/** Returns the number of files in the list.
|
|
|
|
The most recently added file is always at index 0.
|
|
*/
|
|
int getNumFiles() const;
|
|
|
|
/** Returns one of the files in the list.
|
|
|
|
The most recently added file is always at index 0.
|
|
*/
|
|
const File getFile (const int index) const;
|
|
|
|
/** Returns an array of all the absolute pathnames in the list.
|
|
*/
|
|
const StringArray& getAllFilenames() const throw() { return files; }
|
|
|
|
/** Clears all the files from the list. */
|
|
void clear();
|
|
|
|
/** Adds a file to the list.
|
|
|
|
The file will be added at index 0. If this file is already in the list, it will
|
|
be moved up to index 0, but a file can only appear once in the list.
|
|
|
|
If the list already contains the maximum number of items that is permitted, the
|
|
least-recently added file will be dropped from the end.
|
|
*/
|
|
void addFile (const File& file);
|
|
|
|
/** Checks each of the files in the list, removing any that don't exist.
|
|
|
|
You might want to call this after reloading a list of files, or before putting them
|
|
on a menu.
|
|
*/
|
|
void removeNonExistentFiles();
|
|
|
|
/** Adds entries to a menu, representing each of the files in the list.
|
|
|
|
This is handy for creating an "open recent file..." menu in your app. The
|
|
menu items are numbered consecutively starting with the baseItemId value,
|
|
and can either be added as complete pathnames, or just the last part of the
|
|
filename.
|
|
|
|
If dontAddNonExistentFiles is true, then each file will be checked and only those
|
|
that exist will be added.
|
|
|
|
If filesToAvoid is non-zero, then it is considered to be a zero-terminated array of
|
|
pointers to file objects. Any files that appear in this list will not be added to the
|
|
menu - the reason for this is that you might have a number of files already open, so
|
|
might not want these to be shown in the menu.
|
|
|
|
It returns the number of items that were added.
|
|
*/
|
|
int createPopupMenuItems (PopupMenu& menuToAddItemsTo,
|
|
const int baseItemId,
|
|
const bool showFullPaths,
|
|
const bool dontAddNonExistentFiles,
|
|
const File** filesToAvoid = 0);
|
|
|
|
/** Returns a string that encapsulates all the files in the list.
|
|
|
|
The string that is returned can later be passed into restoreFromString() in
|
|
order to recreate the list. This is handy for persisting your list, e.g. in
|
|
a PropertiesFile object.
|
|
|
|
@see restoreFromString
|
|
*/
|
|
const String toString() const;
|
|
|
|
/** Restores the list from a previously stringified version of the list.
|
|
|
|
Pass in a stringified version created with toString() in order to persist/restore
|
|
your list.
|
|
|
|
@see toString
|
|
*/
|
|
void restoreFromString (const String& stringifiedVersion);
|
|
|
|
juce_UseDebuggingNewOperator
|
|
|
|
private:
|
|
|
|
StringArray files;
|
|
int maxNumberOfItems;
|
|
};
|
|
|
|
#endif // __JUCE_RECENTLYOPENEDFILESLIST_JUCEHEADER__
|
|
/********* End of inlined file: juce_RecentlyOpenedFilesList.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_SELECTEDITEMSET_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_SYSTEMCLIPBOARD_JUCEHEADER__
|
|
|
|
/********* Start of inlined file: juce_SystemClipboard.h *********/
|
|
#ifndef __JUCE_SYSTEMCLIPBOARD_JUCEHEADER__
|
|
#define __JUCE_SYSTEMCLIPBOARD_JUCEHEADER__
|
|
|
|
/**
|
|
Handles reading/writing to the system's clipboard.
|
|
*/
|
|
class JUCE_API SystemClipboard
|
|
{
|
|
public:
|
|
/** Copies a string of text onto the clipboard */
|
|
static void copyTextToClipboard (const String& text) throw();
|
|
|
|
/** Gets the current clipboard's contents.
|
|
|
|
Obviously this might have come from another app, so could contain
|
|
anything..
|
|
*/
|
|
static const String getTextFromClipboard() throw();
|
|
};
|
|
|
|
#endif // __JUCE_SYSTEMCLIPBOARD_JUCEHEADER__
|
|
/********* End of inlined file: juce_SystemClipboard.h *********/
|
|
|
|
#endif
|
|
#ifndef __JUCE_UNDOMANAGER_JUCEHEADER__
|
|
|
|
#endif
|
|
#ifndef __JUCE_UNDOABLEACTION_JUCEHEADER__
|
|
|
|
#endif
|
|
|
|
#endif
|
|
/********* End of inlined file: juce_app_includes.h *********/
|
|
|
|
#endif
|
|
|
|
#if JUCE_MSVC
|
|
#pragma warning (pop)
|
|
#pragma pack (pop)
|
|
#endif
|
|
|
|
#if JUCE_MAC
|
|
#pragma align=reset
|
|
#endif
|
|
|
|
END_JUCE_NAMESPACE
|
|
|
|
#ifndef DONT_SET_USING_JUCE_NAMESPACE
|
|
#ifdef JUCE_NAMESPACE
|
|
|
|
// this will obviously save a lot of typing, but can be disabled by
|
|
// defining DONT_SET_USING_JUCE_NAMESPACE, in case there are conflicts.
|
|
using namespace JUCE_NAMESPACE;
|
|
|
|
/* On the Mac, these symbols are defined in the Mac libraries, so
|
|
these macros make it easier to reference them without writing out
|
|
the namespace every time.
|
|
|
|
If you run into difficulties where these macros interfere with the contents
|
|
of 3rd party header files, you may need to use the juce_WithoutMacros.h file - see
|
|
the comments in that file for more information.
|
|
*/
|
|
#if JUCE_MAC && ! JUCE_DONT_DEFINE_MACROS
|
|
#define Component JUCE_NAMESPACE::Component
|
|
#define MemoryBlock JUCE_NAMESPACE::MemoryBlock
|
|
#define Point JUCE_NAMESPACE::Point
|
|
#define Button JUCE_NAMESPACE::Button
|
|
#endif
|
|
|
|
/* "Rectangle" is defined in some of the newer windows header files, so this makes
|
|
it easier to use the juce version explicitly.
|
|
|
|
If you run into difficulties where this macro interferes with other 3rd party header
|
|
files, you may need to use the juce_WithoutMacros.h file - see the comments in that
|
|
file for more information.
|
|
*/
|
|
#if JUCE_WIN32 && ! JUCE_DONT_DEFINE_MACROS
|
|
#define Rectangle JUCE_NAMESPACE::Rectangle
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
/* Easy autolinking to the right JUCE libraries under win32.
|
|
|
|
Note that this can be disabled by defining DONT_AUTOLINK_TO_JUCE_LIBRARY before
|
|
including this header file.
|
|
*/
|
|
#if JUCE_MSVC
|
|
|
|
#ifndef DONT_AUTOLINK_TO_JUCE_LIBRARY
|
|
|
|
/** If you want your application to link to Juce as a DLL instead of
|
|
a static library (on win32), just define the JUCE_DLL macro before
|
|
including juce.h
|
|
*/
|
|
#ifdef JUCE_DLL
|
|
#ifdef JUCE_DEBUG
|
|
#define AUTOLINKEDLIB "JUCE_debug.lib"
|
|
#else
|
|
#define AUTOLINKEDLIB "JUCE.lib"
|
|
#endif
|
|
#else
|
|
#ifdef JUCE_DEBUG
|
|
#ifdef _WIN64
|
|
#define AUTOLINKEDLIB "jucelib_static_x64_debug.lib"
|
|
#else
|
|
#define AUTOLINKEDLIB "jucelib_static_Win32_debug.lib"
|
|
#endif
|
|
#else
|
|
#ifdef _WIN64
|
|
#define AUTOLINKEDLIB "jucelib_static_x64.lib"
|
|
#else
|
|
#define AUTOLINKEDLIB "jucelib_static_Win32.lib"
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#pragma comment(lib, AUTOLINKEDLIB)
|
|
|
|
#if ! DONT_LIST_JUCE_AUTOLINKEDLIBS
|
|
#pragma message("JUCE! Library to link to: " AUTOLINKEDLIB)
|
|
#endif
|
|
|
|
// Auto-link the other win32 libs that are needed by library calls..
|
|
#if ! (defined (DONT_AUTOLINK_TO_WIN32_LIBRARIES) || defined (JUCE_DLL))
|
|
|
|
/********* Start of inlined file: juce_win32_AutoLinkLibraries.h *********/
|
|
// Auto-links to various win32 libs that are needed by library calls..
|
|
#pragma comment(lib, "kernel32.lib")
|
|
#pragma comment(lib, "user32.lib")
|
|
#pragma comment(lib, "shell32.lib")
|
|
#pragma comment(lib, "gdi32.lib")
|
|
#pragma comment(lib, "vfw32.lib")
|
|
#pragma comment(lib, "comdlg32.lib")
|
|
#pragma comment(lib, "winmm.lib")
|
|
#pragma comment(lib, "wininet.lib")
|
|
#pragma comment(lib, "ole32.lib")
|
|
#pragma comment(lib, "advapi32.lib")
|
|
#pragma comment(lib, "ws2_32.lib")
|
|
#pragma comment(lib, "comsupp.lib")
|
|
#pragma comment(lib, "version.lib")
|
|
|
|
#if JUCE_OPENGL
|
|
#pragma comment(lib, "OpenGL32.Lib")
|
|
#pragma comment(lib, "GlU32.Lib")
|
|
#endif
|
|
|
|
#if JUCE_QUICKTIME
|
|
#pragma comment (lib, "QTMLClient.lib")
|
|
#endif
|
|
|
|
#if JUCE_USE_CAMERA
|
|
#pragma comment (lib, "Strmiids.lib")
|
|
#endif
|
|
/********* End of inlined file: juce_win32_AutoLinkLibraries.h *********/
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/*
|
|
To start a JUCE app, use this macro: START_JUCE_APPLICATION (AppSubClass) where
|
|
AppSubClass is the name of a class derived from JUCEApplication.
|
|
|
|
See the JUCEApplication class documentation (juce_Application.h) for more details.
|
|
|
|
*/
|
|
#if defined (JUCE_GCC) || defined (__MWERKS__)
|
|
|
|
#define START_JUCE_APPLICATION(AppClass) \
|
|
int main (int argc, char* argv[]) \
|
|
{ \
|
|
return JUCE_NAMESPACE::JUCEApplication::main (argc, argv, new AppClass()); \
|
|
}
|
|
|
|
#elif JUCE_WIN32
|
|
|
|
#ifdef _CONSOLE
|
|
#define START_JUCE_APPLICATION(AppClass) \
|
|
int main (int, char* argv[]) \
|
|
{ \
|
|
JUCE_NAMESPACE::String commandLineString (JUCE_NAMESPACE::PlatformUtilities::getCurrentCommandLineParams()); \
|
|
return JUCE_NAMESPACE::JUCEApplication::main (commandLineString, new AppClass()); \
|
|
}
|
|
#elif ! defined (_AFXDLL)
|
|
#ifdef _WINDOWS_
|
|
#define START_JUCE_APPLICATION(AppClass) \
|
|
int WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int) \
|
|
{ \
|
|
JUCE_NAMESPACE::String commandLineString (JUCE_NAMESPACE::PlatformUtilities::getCurrentCommandLineParams()); \
|
|
return JUCE_NAMESPACE::JUCEApplication::main (commandLineString, new AppClass()); \
|
|
}
|
|
#else
|
|
#define START_JUCE_APPLICATION(AppClass) \
|
|
int __stdcall WinMain (int, int, const char*, int) \
|
|
{ \
|
|
JUCE_NAMESPACE::String commandLineString (JUCE_NAMESPACE::PlatformUtilities::getCurrentCommandLineParams()); \
|
|
return JUCE_NAMESPACE::JUCEApplication::main (commandLineString, new AppClass()); \
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif // __JUCE_JUCEHEADER__
|
|
/********* End of inlined file: juce.h *********/
|
|
|
|
#endif // __JUCE_AMALGAMATED_TEMPLATE_JUCEHEADER__
|