@@ -52,8 +52,8 @@ public: | |||
Value getValue (const var::identifier& name, ValueTree& state, ComponentDocument& document) const; | |||
//============================================================================== | |||
protected: | |||
//============================================================================== | |||
const String name, xmlTag, memberNameRoot; | |||
private: | |||
@@ -81,7 +81,6 @@ public: | |||
ComponentTypeHandler* getHandlerFor (const String& type); | |||
const StringArray getTypeNames() const; | |||
private: | |||
//============================================================================== | |||
OwnedArray <ComponentTypeHandler> handlers; | |||
@@ -47,14 +47,22 @@ public: | |||
void update (ComponentDocument& document, GroupComponent* comp, const ValueTree& state) | |||
{ | |||
comp->setText (state ["text"].toString()); | |||
} | |||
void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
{ | |||
state.setProperty ("text", "Group", 0); | |||
} | |||
void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
{ | |||
addTooltipProperty (document, state, props); | |||
addFocusOrderProperty (document, state, props); | |||
props.add (new TextPropertyComponent (getValue ("text", state, document), "Label", 512, false)); | |||
props.getLast()->setTooltip ("The group's display name."); | |||
addEditableColourProperties (document, state, props); | |||
} | |||
}; | |||
@@ -49,11 +49,18 @@ public: | |||
void update (ComponentDocument& document, Label* comp, const ValueTree& state) | |||
{ | |||
comp->setText (state ["text"].toString(), false); | |||
comp->setFont (getFontFromState (state, "fontName", "fontSize", "fontStyle")); | |||
int editMode = (int) state ["editMode"]; | |||
comp->setEditable (editMode == 2, editMode == 3, false); | |||
comp->setJustificationType ((int) state ["justification"]); | |||
} | |||
void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
{ | |||
state.setProperty ("text", "New Label", 0); | |||
state.setProperty ("fontSize", 14, 0); | |||
state.setProperty ("editMode", 1, 0); | |||
state.setProperty ("justification", (int) Justification::centredLeft, 0); | |||
} | |||
void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
@@ -64,6 +71,24 @@ public: | |||
props.add (new TextPropertyComponent (getValue ("text", state, document), "Text", 16384, true)); | |||
props.getLast()->setTooltip ("The label's text."); | |||
const char* const layouts[] = { "Centred", "Centred-left", "Centred-right", "Centred-top", "Centred-bottom", "Top-left", | |||
"Top-right", "Bottom-left", "Bottom-right", 0 }; | |||
const int justifications[] = { Justification::centred, Justification::centredLeft, Justification::centredRight, | |||
Justification::centredTop, Justification::centredBottom, Justification::topLeft, | |||
Justification::topRight, Justification::bottomLeft, Justification::bottomRight, 0 }; | |||
ValueRemapperSource* remapper = new ValueRemapperSource (state.getPropertyAsValue ("justification", document.getUndoManager())); | |||
for (int i = 0; i < numElementsInArray (justifications) - 1; ++i) | |||
remapper->addMapping (justifications[i], i + 1); | |||
props.add (new ChoicePropertyComponent (Value (remapper), "Layout", StringArray (layouts))); | |||
const char* const editModes[] = { "Read-only", "Edit on Single-Click", "Edit on Double-Click", 0 }; | |||
props.add (new ChoicePropertyComponent (state.getPropertyAsValue ("editMode", document.getUndoManager()), | |||
"Edit Mode", StringArray (editModes))); | |||
createFontProperties (props, state, "fontName", "fontSize", "fontStyle", document.getUndoManager()); | |||
addEditableColourProperties (document, state, props); | |||
} | |||
}; | |||
@@ -48,11 +48,25 @@ public: | |||
void update (ComponentDocument& document, TextButton* comp, const ValueTree& state) | |||
{ | |||
comp->setButtonText (state ["text"].toString()); | |||
comp->setRadioGroupId (state ["radioGroup"]); | |||
int connected = 0; | |||
if (state ["connectedLeft"]) connected |= TextButton::ConnectedOnLeft; | |||
if (state ["connectedRight"]) connected |= TextButton::ConnectedOnRight; | |||
if (state ["connectedTop"]) connected |= TextButton::ConnectedOnTop; | |||
if (state ["connectedBottom"]) connected |= TextButton::ConnectedOnBottom; | |||
comp->setConnectedEdges (connected); | |||
} | |||
void initialiseNew (ComponentDocument& document, ValueTree& state) | |||
{ | |||
state.setProperty ("text", "New Button", 0); | |||
state.setProperty ("radioGroup", 0, 0); | |||
state.setProperty ("connectedLeft", false, 0); | |||
state.setProperty ("connectedRight", false, 0); | |||
state.setProperty ("connectedTop", false, 0); | |||
state.setProperty ("connectedBottom", false, 0); | |||
} | |||
void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||
@@ -63,6 +77,14 @@ public: | |||
props.add (new TextPropertyComponent (getValue ("text", state, document), "Button Text", 1024, false)); | |||
props.getLast()->setTooltip ("The button's text."); | |||
props.add (new TextPropertyComponent (Value (new IntegerValueSource (getValue ("radioGroup", state, document))), "Radio Group", 8, false)); | |||
props.getLast()->setTooltip ("The radio group that this button is a member of."); | |||
props.add (new BooleanPropertyComponent (getValue ("connectedLeft", state, document), "Connected left", "Connected")); | |||
props.add (new BooleanPropertyComponent (getValue ("connectedRight", state, document), "Connected right", "Connected")); | |||
props.add (new BooleanPropertyComponent (getValue ("connectedTop", state, document), "Connected top", "Connected")); | |||
props.add (new BooleanPropertyComponent (getValue ("connectedBottom", state, document), "Connected bottom", "Connected")); | |||
addEditableColourProperties (document, state, props); | |||
} | |||
}; | |||
@@ -93,10 +93,11 @@ void Project::setMissingDefaultValues() | |||
if (! projectRoot.getChildWithName (Tags::projectMainGroup).isValid()) | |||
{ | |||
Item mainGroup (*this, ValueTree (Tags::projectMainGroup)); | |||
mainGroup.createUIDIfMissing(); | |||
projectRoot.addChild (mainGroup.getNode(), 0, 0); | |||
} | |||
getMainGroup().initialiseNodeValues(); | |||
if (getDocumentTitle().isEmpty()) | |||
setTitle ("Juce Project"); | |||
@@ -407,7 +408,7 @@ Project::Item Project::getMainGroup() | |||
Project::Item Project::createNewGroup() | |||
{ | |||
Item item (*this, ValueTree (Tags::group)); | |||
item.createUIDIfMissing(); | |||
item.initialiseNodeValues(); | |||
item.getName() = "New Group"; | |||
return item; | |||
} | |||
@@ -415,7 +416,7 @@ Project::Item Project::createNewGroup() | |||
Project::Item Project::createNewItem (const File& file) | |||
{ | |||
Item item (*this, ValueTree (Tags::file)); | |||
item.createUIDIfMissing(); | |||
item.initialiseNodeValues(); | |||
item.getName() = file.getFileName(); | |||
item.getShouldCompileValue() = file.hasFileExtension ("cpp;mm;c;m"); | |||
item.getShouldAddToResourceValue() = shouldBeAddedToBinaryResourcesByDefault (file); | |||
@@ -490,7 +491,10 @@ const File Project::Item::getFile() const | |||
void Project::Item::setFile (const File& file) | |||
{ | |||
jassert (isFile()); | |||
node.setProperty ("file", project.getRelativePathForFile (file), getUndoManager()); | |||
node.setProperty ("name", file.getFileName(), getUndoManager()); | |||
jassert (getFile() == file); | |||
} | |||
@@ -559,10 +563,20 @@ const File Project::Item::determineGroupFolder() const | |||
return f; | |||
} | |||
void Project::Item::createUIDIfMissing() | |||
void Project::Item::initialiseNodeValues() | |||
{ | |||
if (! node.hasProperty ("id")) | |||
node.setProperty ("id", createAlphaNumericUID(), getUndoManager()); | |||
node.setProperty ("id", createAlphaNumericUID(), 0); | |||
if (isFile()) | |||
{ | |||
node.setProperty ("name", getFile().getFileName(), 0); | |||
} | |||
else if (isGroup()) | |||
{ | |||
for (int i = getNumChildren(); --i >= 0;) | |||
getChild(i).initialiseNodeValues(); | |||
} | |||
} | |||
Value Project::Item::getName() const | |||
@@ -156,6 +156,8 @@ public: | |||
Item (const Item& other); | |||
~Item(); | |||
void initialiseNodeValues(); | |||
//============================================================================== | |||
bool isValid() const { return node.isValid(); } | |||
const ValueTree& getNode() const throw() { return node; } | |||
@@ -170,7 +172,6 @@ public: | |||
bool isMainGroup() const; | |||
const String getID() const; | |||
void createUIDIfMissing(); | |||
//============================================================================== | |||
Value getName() const; | |||
@@ -188,7 +189,7 @@ public: | |||
//============================================================================== | |||
bool canContain (const Item& child) const; | |||
int getNumChildren() const { return node.getNumChildren(); } | |||
const Item getChild (int index) const { return Item (project, node.getChild (index)); } | |||
Item getChild (int index) const { return Item (project, node.getChild (index)); } | |||
void addChild (const Item& newChild, int insertIndex); | |||
bool addFile (const File& file, int insertIndex); | |||
void removeItemFromProject(); | |||
@@ -394,10 +394,12 @@ bool ComponentEditor::perform (const InvocationInfo& info) | |||
switch (info.commandID) | |||
{ | |||
case CommandIDs::undo: | |||
getDocument().getUndoManager()->beginNewTransaction(); | |||
getDocument().getUndoManager()->undo(); | |||
return true; | |||
case CommandIDs::redo: | |||
getDocument().getUndoManager()->beginNewTransaction(); | |||
getDocument().getUndoManager()->redo(); | |||
return true; | |||
@@ -32,7 +32,6 @@ ProjectTreeViewBase::ProjectTreeViewBase (const Project::Item& item_) | |||
: item (item_), isFileMissing (false) | |||
{ | |||
item.getNode().addListener (this); | |||
item.createUIDIfMissing(); | |||
} | |||
ProjectTreeViewBase::~ProjectTreeViewBase() | |||
@@ -197,24 +197,11 @@ private: | |||
class ColourSelectorWithSwatches : public ColourSelector | |||
{ | |||
public: | |||
ColourSelectorWithSwatches() | |||
{ | |||
} | |||
int getNumSwatches() const | |||
{ | |||
return StoredSettings::getInstance()->swatchColours.size(); | |||
} | |||
ColourSelectorWithSwatches() {} | |||
const Colour getSwatchColour (int index) const | |||
{ | |||
return StoredSettings::getInstance()->swatchColours [index]; | |||
} | |||
void setSwatchColour (int index, const Colour& newColour) const | |||
{ | |||
StoredSettings::getInstance()->swatchColours.set (index, newColour); | |||
} | |||
int getNumSwatches() const { return StoredSettings::getInstance()->swatchColours.size(); } | |||
const Colour getSwatchColour (int index) const { return StoredSettings::getInstance()->swatchColours [index]; } | |||
void setSwatchColour (int index, const Colour& newColour) const { StoredSettings::getInstance()->swatchColours.set (index, newColour); } | |||
}; | |||
ColourEditorComponent* owner; | |||
@@ -126,3 +126,11 @@ void StoredSettings::setLastKnownJuceFolder (const File& file) | |||
jassert (isJuceFolder (file)); | |||
props->setValue ("lastJuceFolder", file.getFullPathName()); | |||
} | |||
const StringArray& StoredSettings::getFontNames() | |||
{ | |||
if (fontNames.size() == 0) | |||
fontNames = Font::findAllTypefaceNames(); | |||
return fontNames; | |||
} |
@@ -55,11 +55,14 @@ public: | |||
Array <Colour> swatchColours; | |||
const StringArray& getFontNames(); | |||
//============================================================================== | |||
juce_UseDebuggingNewOperator | |||
private: | |||
ScopedPointer<PropertiesFile> props; | |||
StringArray fontNames; | |||
}; | |||
@@ -641,3 +641,102 @@ void FloatingLabelComponent::paint (Graphics& g) | |||
g.setColour (colour); | |||
glyphs.draw (g, AffineTransform::translation (1.0f, 1.0f)); | |||
} | |||
//============================================================================== | |||
class FontNameValueSource : public Value::ValueSource, | |||
public Value::Listener | |||
{ | |||
public: | |||
FontNameValueSource (const Value& source) | |||
: sourceValue (source) | |||
{ | |||
sourceValue.addListener (this); | |||
} | |||
~FontNameValueSource() {} | |||
void valueChanged (Value&) { sendChangeMessage (true); } | |||
const var getValue() const | |||
{ | |||
const String fontName (sourceValue.toString()); | |||
const int index = StoredSettings::getInstance()->getFontNames().indexOf (fontName); | |||
if (index >= 0) return 5 + index; | |||
else if (fontName == getDefaultFontName()) return 1; | |||
else if (fontName == getDefaultSansFontName()) return 2; | |||
else if (fontName == getDefaultSerifFontName()) return 3; | |||
else if (fontName == getDefaultMonospacedFontName()) return 4; | |||
return 1; | |||
} | |||
void setValue (const var& newValue) | |||
{ | |||
const int index = newValue; | |||
if (index <= 1) sourceValue = getDefaultFontName(); | |||
else if (index == 2) sourceValue = getDefaultSansFontName(); | |||
else if (index == 3) sourceValue = getDefaultSerifFontName(); | |||
else if (index == 4) sourceValue = getDefaultMonospacedFontName(); | |||
else sourceValue = StoredSettings::getInstance()->getFontNames() [index - 5]; | |||
} | |||
static ChoicePropertyComponent* createProperty (const String& title, const Value& value) | |||
{ | |||
StringArray fontNames; | |||
fontNames.add (getDefaultFontName()); | |||
fontNames.add (getDefaultSansFontName()); | |||
fontNames.add (getDefaultSerifFontName()); | |||
fontNames.add (getDefaultMonospacedFontName()); | |||
fontNames.add (String::empty); | |||
fontNames.addArray (StoredSettings::getInstance()->getFontNames()); | |||
return new ChoicePropertyComponent (Value (new FontNameValueSource (value)), title, fontNames); | |||
} | |||
static void applyToFont (Font& font, const String& fontName) | |||
{ | |||
if (fontName.isEmpty() || fontName == getDefaultFontName() || fontName == getDefaultSansFontName()) | |||
return; | |||
font.setTypefaceName (fontName == getDefaultSerifFontName() ? Font::getDefaultSerifFontName() | |||
: (fontName == getDefaultMonospacedFontName() ? Font::getDefaultMonospacedFontName() | |||
: fontName)); | |||
} | |||
static const char* getDefaultFontName() throw() { return "Default Font"; } | |||
static const char* getDefaultSansFontName() throw() { return "Default Sans-Serif Font"; } | |||
static const char* getDefaultSerifFontName() throw() { return "Default Serif Font"; } | |||
static const char* getDefaultMonospacedFontName() throw() { return "Default Monospaced Font"; } | |||
private: | |||
Value sourceValue; | |||
FontNameValueSource (const FontNameValueSource&); | |||
const FontNameValueSource& operator= (const FontNameValueSource&); | |||
}; | |||
static const char* const fontStyles[] = { "Normal", "Bold", "Italic", "Bold + Italic", 0 }; | |||
const Font getFontFromState (const ValueTree& state, const var::identifier& fontName, const var::identifier& fontSize, const var::identifier& fontStyle) | |||
{ | |||
const String styleString (state.getProperty (fontStyle).toString()); | |||
const int fontFlags = styleString == fontStyles[1] ? Font::bold | |||
: (styleString == fontStyles[2] ? Font::italic | |||
: (styleString == fontStyles[3] ? (Font::italic | Font::bold) | |||
: 0)); | |||
Font f (state.getProperty (fontSize, 14), fontFlags); | |||
FontNameValueSource::applyToFont (f, state.getProperty (fontName)); | |||
return f; | |||
} | |||
void createFontProperties (Array <PropertyComponent*>& props, const ValueTree& state, | |||
const var::identifier& fontName, const var::identifier& fontSize, const var::identifier& fontStyle, | |||
UndoManager* undoManager) | |||
{ | |||
props.add (FontNameValueSource::createProperty ("Font", state.getPropertyAsValue (fontName, undoManager))); | |||
props.add (new SliderPropertyComponent (state.getPropertyAsValue (fontSize, undoManager), "Font Size", 1.0, 150.0, 0.1, 0.5)); | |||
props.add (StringListValueSource::create ("Font Style", state.getPropertyAsValue (fontStyle, undoManager), StringArray (fontStyles))); | |||
} |
@@ -80,6 +80,18 @@ int indexOfLineStartingWith (const StringArray& lines, const String& text, int s | |||
void autoScrollForMouseEvent (const MouseEvent& e); | |||
//============================================================================== | |||
const Font getFontFromState (const ValueTree& state, | |||
const var::identifier& fontName, | |||
const var::identifier& fontSize, | |||
const var::identifier& fontStyle); | |||
void createFontProperties (Array <PropertyComponent*>& props, const ValueTree& state, | |||
const var::identifier& fontName, | |||
const var::identifier& fontSize, | |||
const var::identifier& fontStyle, | |||
UndoManager* undoManager); | |||
//============================================================================== | |||
class FileModificationDetector | |||
{ | |||
@@ -49,7 +49,7 @@ public: | |||
~ValueRemapperSource() {} | |||
void addMappings (const char** values) | |||
void addMappings (const char* const* values) | |||
{ | |||
while (values[0] != 0 && values[1] != 0) | |||
{ | |||
@@ -108,6 +108,48 @@ protected: | |||
const ValueRemapperSource& operator= (const ValueRemapperSource&); | |||
}; | |||
//============================================================================== | |||
/** A ValueSource that converts strings into an ID suitable for a combo box. | |||
*/ | |||
class StringListValueSource : public Value::ValueSource, | |||
public Value::Listener | |||
{ | |||
public: | |||
StringListValueSource (const Value& sourceValue_, const StringArray& strings_) | |||
: sourceValue (sourceValue_), strings (strings_) | |||
{ | |||
sourceValue.addListener (this); | |||
} | |||
~StringListValueSource() {} | |||
const var getValue() const { return jmax (0, strings.indexOf (sourceValue.toString())) + 1; } | |||
void setValue (const var& newValue) | |||
{ | |||
const String newVal (strings [((int) newValue) - 1]); | |||
if (newVal != getValue().toString()) // this test is important, because if a property is missing, it won't | |||
sourceValue = newVal; // create it (causing an unwanted undo action) when a control sets it to empty | |||
} | |||
void valueChanged (Value&) { sendChangeMessage (true); } | |||
static ChoicePropertyComponent* create (const String& title, const Value& value, const StringArray& strings) | |||
{ | |||
return new ChoicePropertyComponent (Value (new StringListValueSource (value, strings)), title, strings); | |||
} | |||
//============================================================================== | |||
juce_UseDebuggingNewOperator | |||
protected: | |||
Value sourceValue; | |||
StringArray strings; | |||
StringListValueSource (const StringListValueSource&); | |||
const StringListValueSource& operator= (const StringListValueSource&); | |||
}; | |||
//============================================================================== | |||
/** | |||
*/ | |||
@@ -130,10 +172,10 @@ public: | |||
void setValue (const var& newValue) | |||
{ | |||
const var newVal ((int) newValue); | |||
const int newVal = (int) newValue; | |||
if (newVal != sourceValue) | |||
sourceValue = newVal; | |||
if (newVal != (int) getValue()) // this test is important, because if a property is missing, it won't | |||
sourceValue = newVal; // create it (causing an unwanted undo action) when a control sets it to 0 | |||
} | |||
void valueChanged (Value&) | |||
@@ -12365,21 +12365,21 @@ StringArray::StringArray (const String& firstValue) | |||
strings.add (firstValue); | |||
} | |||
StringArray::StringArray (const juce_wchar** const initialStrings, | |||
StringArray::StringArray (const juce_wchar* const* const initialStrings, | |||
const int numberOfStrings) | |||
{ | |||
for (int i = 0; i < numberOfStrings; ++i) | |||
strings.add (initialStrings [i]); | |||
} | |||
StringArray::StringArray (const char** const initialStrings, | |||
StringArray::StringArray (const char* const* const initialStrings, | |||
const int numberOfStrings) | |||
{ | |||
for (int i = 0; i < numberOfStrings; ++i) | |||
strings.add (initialStrings [i]); | |||
} | |||
StringArray::StringArray (const juce_wchar** const initialStrings) | |||
StringArray::StringArray (const juce_wchar* const* const initialStrings) | |||
{ | |||
int i = 0; | |||
@@ -12387,7 +12387,7 @@ StringArray::StringArray (const juce_wchar** const initialStrings) | |||
strings.add (initialStrings [i++]); | |||
} | |||
StringArray::StringArray (const char** const initialStrings) | |||
StringArray::StringArray (const char* const* const initialStrings) | |||
{ | |||
int i = 0; | |||
@@ -18758,7 +18758,7 @@ END_JUCE_NAMESPACE | |||
BEGIN_JUCE_NAMESPACE | |||
static const char* const aiffFormatName = "AIFF file"; | |||
static const juce_wchar* const aiffExtensions[] = { T(".aiff"), T(".aif"), 0 }; | |||
static const char* const aiffExtensions[] = { ".aiff", ".aif", 0 }; | |||
class AiffAudioFormatReader : public AudioFormatReader | |||
{ | |||
@@ -19460,7 +19460,7 @@ public: | |||
}; | |||
AiffAudioFormat::AiffAudioFormat() | |||
: AudioFormat (TRANS (aiffFormatName), (const juce_wchar**) aiffExtensions) | |||
: AudioFormat (TRANS (aiffFormatName), StringArray (aiffExtensions)) | |||
{ | |||
} | |||
@@ -20226,7 +20226,7 @@ bool AudioFormatWriter::writeFromAudioSource (AudioSource& source, | |||
} | |||
AudioFormat::AudioFormat (const String& name, | |||
const juce_wchar** const extensions) | |||
const StringArray& extensions) | |||
: formatName (name), | |||
fileExtensions (extensions) | |||
{ | |||
@@ -21163,7 +21163,7 @@ BEGIN_JUCE_NAMESPACE | |||
bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle); | |||
static const char* const quickTimeFormatName = "QuickTime file"; | |||
static const juce_wchar* const quickTimeExtensions[] = { T(".mov"), T(".mp3"), T(".mp4"), 0 }; | |||
static const char* const quickTimeExtensions[] = { ".mov", ".mp3", ".mp4", 0 }; | |||
class QTAudioReader : public AudioFormatReader | |||
{ | |||
@@ -21423,7 +21423,7 @@ private: | |||
}; | |||
QuickTimeAudioFormat::QuickTimeAudioFormat() | |||
: AudioFormat (TRANS (quickTimeFormatName), (const juce_wchar**) quickTimeExtensions) | |||
: AudioFormat (TRANS (quickTimeFormatName), StringArray (quickTimeExtensions)) | |||
{ | |||
} | |||
@@ -21486,7 +21486,7 @@ END_JUCE_NAMESPACE | |||
BEGIN_JUCE_NAMESPACE | |||
static const char* const wavFormatName = "WAV file"; | |||
static const juce_wchar* const wavExtensions[] = { T(".wav"), T(".bwf"), 0 }; | |||
static const char* const wavExtensions[] = { ".wav", ".bwf", 0 }; | |||
const char* const WavAudioFormat::bwavDescription = "bwav description"; | |||
const char* const WavAudioFormat::bwavOriginator = "bwav originator"; | |||
@@ -22255,7 +22255,7 @@ public: | |||
}; | |||
WavAudioFormat::WavAudioFormat() | |||
: AudioFormat (TRANS (wavFormatName), (const juce_wchar**) wavExtensions) | |||
: AudioFormat (TRANS (wavFormatName), StringArray (wavExtensions)) | |||
{ | |||
} | |||
@@ -42077,7 +42077,9 @@ void Button::setToggleState (const bool shouldBeOn, | |||
{ | |||
if (shouldBeOn != lastToggleState) | |||
{ | |||
isOn = shouldBeOn; | |||
if (isOn != shouldBeOn) // this test means that if the value is void rather than explicitly set to | |||
isOn = shouldBeOn; // false, it won't be changed unless the required value is true. | |||
lastToggleState = shouldBeOn; | |||
repaint(); | |||
@@ -70750,12 +70752,11 @@ void BooleanPropertyComponent::paint (Graphics& g) | |||
{ | |||
PropertyComponent::paint (g); | |||
const Rectangle<int> r (button->getBounds()); | |||
g.setColour (Colours::white); | |||
g.fillRect (r); | |||
g.fillRect (button->getBounds()); | |||
g.setColour (findColour (ComboBox::outlineColourId)); | |||
g.drawRect (r.getX(), r.getY(), r.getWidth(), r.getHeight()); | |||
g.drawRect (button->getBounds()); | |||
} | |||
void BooleanPropertyComponent::refresh() | |||
@@ -70838,10 +70839,12 @@ void ChoicePropertyComponent::createComboBox (const Array <int>* choiceIDs) | |||
addAndMakeVisible (comboBox = new ComboBox (String::empty)); | |||
int itemId = 0; | |||
for (int i = 0; i < choices.size(); ++i) | |||
{ | |||
if (choices[i].isNotEmpty()) | |||
comboBox->addItem (choices[i], choiceIDs == 0 ? (i + 1) | |||
comboBox->addItem (choices[i], choiceIDs == 0 ? ++itemId | |||
: ((*choiceIDs)[i])); | |||
else | |||
comboBox->addSeparator(); | |||
@@ -75608,6 +75611,20 @@ int AlertWindow::getNumButtons() const | |||
return buttons.size(); | |||
} | |||
void AlertWindow::triggerButtonClick (const String& buttonName) | |||
{ | |||
for (int i = buttons.size(); --i >= 0;) | |||
{ | |||
TextButton* const b = (TextButton*) buttons[i]; | |||
if (buttonName == b->getName()) | |||
{ | |||
b->triggerClick(); | |||
break; | |||
} | |||
} | |||
} | |||
void AlertWindow::addTextEditor (const String& name, | |||
const String& initialContents, | |||
const String& onScreenLabel, | |||
@@ -124118,7 +124135,7 @@ void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L) | |||
BEGIN_JUCE_NAMESPACE | |||
static const char* const flacFormatName = "FLAC file"; | |||
static const juce_wchar* const flacExtensions[] = { T(".flac"), 0 }; | |||
static const char* const flacExtensions[] = { ".flac", 0 }; | |||
class FlacReader : public AudioFormatReader | |||
{ | |||
@@ -124519,7 +124536,7 @@ private: | |||
}; | |||
FlacAudioFormat::FlacAudioFormat() | |||
: AudioFormat (TRANS (flacFormatName), (const juce_wchar**) flacExtensions) | |||
: AudioFormat (TRANS (flacFormatName), StringArray (flacExtensions)) | |||
{ | |||
} | |||
@@ -183232,7 +183249,7 @@ void _vorbis_apply_window(float *d,int *winno,long *blocksizes, | |||
BEGIN_JUCE_NAMESPACE | |||
static const char* const oggFormatName = "Ogg-Vorbis file"; | |||
static const juce_wchar* const oggExtensions[] = { T(".ogg"), 0 }; | |||
static const char* const oggExtensions[] = { ".ogg", 0 }; | |||
class OggReader : public AudioFormatReader | |||
{ | |||
@@ -183534,7 +183551,7 @@ public: | |||
}; | |||
OggVorbisAudioFormat::OggVorbisAudioFormat() | |||
: AudioFormat (TRANS (oggFormatName), (const juce_wchar**) oggExtensions) | |||
: AudioFormat (TRANS (oggFormatName), StringArray (oggExtensions)) | |||
{ | |||
} | |||
@@ -259850,7 +259867,7 @@ void File::findFileSystemRoots (Array<File>& destArray) | |||
destArray.add (File ("/")); | |||
} | |||
static bool isFileOnDriveType (const File& f, const char** types) | |||
static bool isFileOnDriveType (const File& f, const char* const* types) | |||
{ | |||
struct statfs buf; | |||
@@ -259868,16 +259885,16 @@ static bool isFileOnDriveType (const File& f, const char** types) | |||
bool File::isOnCDRomDrive() const | |||
{ | |||
static const char* const cdTypes[] = { "cd9660", "cdfs", "cddafs", "udf", 0 }; | |||
const char* const cdTypes[] = { "cd9660", "cdfs", "cddafs", "udf", 0 }; | |||
return isFileOnDriveType (*this, (const char**) cdTypes); | |||
return isFileOnDriveType (*this, cdTypes); | |||
} | |||
bool File::isOnHardDisk() const | |||
{ | |||
static const char* const nonHDTypes[] = { "nfs", "smbfs", "ramfs", 0 }; | |||
const char* const nonHDTypes[] = { "nfs", "smbfs", "ramfs", 0 }; | |||
return ! (isOnCDRomDrive() || isFileOnDriveType (*this, (const char**) nonHDTypes)); | |||
return ! (isOnCDRomDrive() || isFileOnDriveType (*this, nonHDTypes)); | |||
} | |||
bool File::isOnRemovableDrive() const | |||
@@ -1120,7 +1120,7 @@ inline double juce_hypot (double a, double b) | |||
/** Using juce_hypot and juce_hypotf is easier than dealing with all the different | |||
versions of these functions of various platforms and compilers. */ | |||
inline float juce_hypotf (float a, float b) | |||
inline float juce_hypotf (float a, float b) throw() | |||
{ | |||
#if JUCE_WINDOWS | |||
return (float) _hypot (a, b); | |||
@@ -1130,11 +1130,25 @@ inline float juce_hypotf (float a, float b) | |||
} | |||
/** 64-bit abs function. */ | |||
inline int64 abs64 (const int64 n) | |||
inline int64 abs64 (const int64 n) throw() | |||
{ | |||
return (n >= 0) ? n : -n; | |||
} | |||
/** This templated negate function will negate pointers as well as integers */ | |||
template <typename Type> | |||
inline Type juce_negate (Type n) throw() | |||
{ | |||
return -n; | |||
} | |||
/** This templated negate function will negate pointers as well as integers */ | |||
template <typename Type> | |||
inline Type* juce_negate (Type* n) throw() | |||
{ | |||
return (Type*) -(pointer_sized_int) n; | |||
} | |||
/** A predefined value for Pi, at double-precision. | |||
@see float_Pi | |||
@@ -5798,8 +5812,7 @@ inline Type Atomic<Type>::operator+= (const Type amountToAdd) throw() | |||
template <typename Type> | |||
inline Type Atomic<Type>::operator-= (const Type amountToSubtract) throw() | |||
{ | |||
return operator+= (sizeof (Type) == 4 ? (Type) (-(int32) amountToSubtract) | |||
: (Type) (-(int64) amountToSubtract)); | |||
return operator+= (juce_negate (amountToSubtract)); | |||
} | |||
template <typename Type> | |||
@@ -7092,27 +7105,27 @@ public: | |||
treated as empty strings | |||
@param numberOfStrings how many items there are in the array | |||
*/ | |||
StringArray (const juce_wchar** strings, int numberOfStrings); | |||
StringArray (const juce_wchar* const* strings, int numberOfStrings); | |||
/** 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** strings, int numberOfStrings); | |||
StringArray (const char* const* strings, int numberOfStrings); | |||
/** 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. | |||
*/ | |||
explicit StringArray (const juce_wchar** strings); | |||
explicit StringArray (const juce_wchar* const* strings); | |||
/** 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. | |||
*/ | |||
explicit StringArray (const char** strings); | |||
explicit StringArray (const char* const* strings); | |||
/** Destructor. */ | |||
~StringArray(); | |||
@@ -11999,10 +12012,9 @@ private: | |||
object - this means that multiple Value objects can all refer to the same piece of | |||
data, allowing all of them to be notified when any of them changes it. | |||
The base class of Value contains a simple var object, but subclasses can be | |||
created that map a Value onto any kind of underlying data, e.g. | |||
ValueTree::getPropertyAsValue() returns a Value object that is a wrapper | |||
for one of its properties. | |||
When you create a Value with its default constructor, it acts as a wrapper around a | |||
simple var object, but by creating a Value that refers to a custom subclass of ValueSource, | |||
you can map the Value onto any kind of underlying data. | |||
*/ | |||
class JUCE_API Value | |||
{ | |||
@@ -12110,10 +12122,10 @@ public: | |||
@see removeListener | |||
*/ | |||
void addListener (Listener* const listener); | |||
void addListener (Listener* listener); | |||
/** Removes a listener that was previously added with addListener(). */ | |||
void removeListener (Listener* const listener); | |||
void removeListener (Listener* listener); | |||
/** | |||
Used internally by the Value class as the base class for its shared value objects. | |||
@@ -12131,6 +12143,7 @@ public: | |||
/** Returns the current value of this object. */ | |||
virtual const var getValue() const = 0; | |||
/** Changes the current value. | |||
This must also trigger a change message if the value actually changes. | |||
*/ | |||
@@ -12142,7 +12155,7 @@ public: | |||
If dispatchSynchronously is true, the method will call all the listeners | |||
before returning; otherwise it'll dispatch a message and make the call later. | |||
*/ | |||
void sendChangeMessage (const bool dispatchSynchronously); | |||
void sendChangeMessage (bool dispatchSynchronously); | |||
juce_UseDebuggingNewOperator | |||
@@ -12156,10 +12169,11 @@ public: | |||
ValueSource& operator= (const ValueSource&); | |||
}; | |||
/** @internal */ | |||
explicit Value (ValueSource* const valueSource); | |||
/** @internal */ | |||
ValueSource& getValueSource() { return *value; } | |||
/** Creates a Value object that uses this valueSource object as its underlying data. */ | |||
explicit Value (ValueSource* valueSource); | |||
/** Returns the ValueSource that this value is referring to. */ | |||
ValueSource& getValueSource() throw() { return *value; } | |||
juce_UseDebuggingNewOperator | |||
@@ -29187,7 +29201,7 @@ protected: | |||
be returned by getFileExtension() | |||
*/ | |||
AudioFormat (const String& formatName, | |||
const juce_wchar** const fileExtensions); | |||
const StringArray& fileExtensions); | |||
private: | |||
@@ -52029,6 +52043,9 @@ public: | |||
/** Returns the number of buttons that the window currently has. */ | |||
int getNumButtons() const; | |||
/** Invokes a click of one of the buttons. */ | |||
void triggerButtonClick (const String& buttonName); | |||
/** 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 | |||
@@ -34,7 +34,7 @@ BEGIN_JUCE_NAMESPACE | |||
//============================================================================== | |||
static const char* const aiffFormatName = "AIFF file"; | |||
static const juce_wchar* const aiffExtensions[] = { T(".aiff"), T(".aif"), 0 }; | |||
static const char* const aiffExtensions[] = { ".aiff", ".aif", 0 }; | |||
//============================================================================== | |||
@@ -743,7 +743,7 @@ public: | |||
//============================================================================== | |||
AiffAudioFormat::AiffAudioFormat() | |||
: AudioFormat (TRANS (aiffFormatName), (const juce_wchar**) aiffExtensions) | |||
: AudioFormat (TRANS (aiffFormatName), StringArray (aiffExtensions)) | |||
{ | |||
} | |||
@@ -512,7 +512,7 @@ bool AudioFormatWriter::writeFromAudioSource (AudioSource& source, | |||
//============================================================================== | |||
AudioFormat::AudioFormat (const String& name, | |||
const juce_wchar** const extensions) | |||
const StringArray& extensions) | |||
: formatName (name), | |||
fileExtensions (extensions) | |||
{ | |||
@@ -161,7 +161,7 @@ protected: | |||
be returned by getFileExtension() | |||
*/ | |||
AudioFormat (const String& formatName, | |||
const juce_wchar** const fileExtensions); | |||
const StringArray& fileExtensions); | |||
private: | |||
//============================================================================== | |||
@@ -86,7 +86,7 @@ BEGIN_JUCE_NAMESPACE | |||
//============================================================================== | |||
static const char* const flacFormatName = "FLAC file"; | |||
static const juce_wchar* const flacExtensions[] = { T(".flac"), 0 }; | |||
static const char* const flacExtensions[] = { ".flac", 0 }; | |||
//============================================================================== | |||
@@ -496,7 +496,7 @@ private: | |||
//============================================================================== | |||
FlacAudioFormat::FlacAudioFormat() | |||
: AudioFormat (TRANS (flacFormatName), (const juce_wchar**) flacExtensions) | |||
: AudioFormat (TRANS (flacFormatName), StringArray (flacExtensions)) | |||
{ | |||
} | |||
@@ -85,7 +85,7 @@ BEGIN_JUCE_NAMESPACE | |||
//============================================================================== | |||
static const char* const oggFormatName = "Ogg-Vorbis file"; | |||
static const juce_wchar* const oggExtensions[] = { T(".ogg"), 0 }; | |||
static const char* const oggExtensions[] = { ".ogg", 0 }; | |||
//============================================================================== | |||
class OggReader : public AudioFormatReader | |||
@@ -395,7 +395,7 @@ public: | |||
//============================================================================== | |||
OggVorbisAudioFormat::OggVorbisAudioFormat() | |||
: AudioFormat (TRANS (oggFormatName), (const juce_wchar**) oggExtensions) | |||
: AudioFormat (TRANS (oggFormatName), StringArray (oggExtensions)) | |||
{ | |||
} | |||
@@ -70,7 +70,7 @@ BEGIN_JUCE_NAMESPACE | |||
bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle); | |||
static const char* const quickTimeFormatName = "QuickTime file"; | |||
static const juce_wchar* const quickTimeExtensions[] = { T(".mov"), T(".mp3"), T(".mp4"), 0 }; | |||
static const char* const quickTimeExtensions[] = { ".mov", ".mp3", ".mp4", 0 }; | |||
//============================================================================== | |||
class QTAudioReader : public AudioFormatReader | |||
@@ -334,7 +334,7 @@ private: | |||
//============================================================================== | |||
QuickTimeAudioFormat::QuickTimeAudioFormat() | |||
: AudioFormat (TRANS (quickTimeFormatName), (const juce_wchar**) quickTimeExtensions) | |||
: AudioFormat (TRANS (quickTimeFormatName), StringArray (quickTimeExtensions)) | |||
{ | |||
} | |||
@@ -36,7 +36,7 @@ BEGIN_JUCE_NAMESPACE | |||
//============================================================================== | |||
static const char* const wavFormatName = "WAV file"; | |||
static const juce_wchar* const wavExtensions[] = { T(".wav"), T(".bwf"), 0 }; | |||
static const char* const wavExtensions[] = { ".wav", ".bwf", 0 }; | |||
//============================================================================== | |||
@@ -820,7 +820,7 @@ public: | |||
//============================================================================== | |||
WavAudioFormat::WavAudioFormat() | |||
: AudioFormat (TRANS (wavFormatName), (const juce_wchar**) wavExtensions) | |||
: AudioFormat (TRANS (wavFormatName), StringArray (wavExtensions)) | |||
{ | |||
} | |||
@@ -44,10 +44,9 @@ | |||
object - this means that multiple Value objects can all refer to the same piece of | |||
data, allowing all of them to be notified when any of them changes it. | |||
The base class of Value contains a simple var object, but subclasses can be | |||
created that map a Value onto any kind of underlying data, e.g. | |||
ValueTree::getPropertyAsValue() returns a Value object that is a wrapper | |||
for one of its properties. | |||
When you create a Value with its default constructor, it acts as a wrapper around a | |||
simple var object, but by creating a Value that refers to a custom subclass of ValueSource, | |||
you can map the Value onto any kind of underlying data. | |||
*/ | |||
class JUCE_API Value | |||
{ | |||
@@ -157,10 +156,10 @@ public: | |||
@see removeListener | |||
*/ | |||
void addListener (Listener* const listener); | |||
void addListener (Listener* listener); | |||
/** Removes a listener that was previously added with addListener(). */ | |||
void removeListener (Listener* const listener); | |||
void removeListener (Listener* listener); | |||
//============================================================================== | |||
@@ -180,6 +179,7 @@ public: | |||
/** Returns the current value of this object. */ | |||
virtual const var getValue() const = 0; | |||
/** Changes the current value. | |||
This must also trigger a change message if the value actually changes. | |||
*/ | |||
@@ -191,7 +191,7 @@ public: | |||
If dispatchSynchronously is true, the method will call all the listeners | |||
before returning; otherwise it'll dispatch a message and make the call later. | |||
*/ | |||
void sendChangeMessage (const bool dispatchSynchronously); | |||
void sendChangeMessage (bool dispatchSynchronously); | |||
//============================================================================== | |||
juce_UseDebuggingNewOperator | |||
@@ -208,11 +208,14 @@ public: | |||
//============================================================================== | |||
/** @internal */ | |||
explicit Value (ValueSource* const valueSource); | |||
/** @internal */ | |||
ValueSource& getValueSource() { return *value; } | |||
/** Creates a Value object that uses this valueSource object as its underlying data. */ | |||
explicit Value (ValueSource* valueSource); | |||
/** Returns the ValueSource that this value is referring to. */ | |||
ValueSource& getValueSource() throw() { return *value; } | |||
//============================================================================== | |||
juce_UseDebuggingNewOperator | |||
private: | |||
@@ -251,8 +251,7 @@ inline Type Atomic<Type>::operator+= (const Type amountToAdd) throw() | |||
template <typename Type> | |||
inline Type Atomic<Type>::operator-= (const Type amountToSubtract) throw() | |||
{ | |||
return operator+= (sizeof (Type) == 4 ? (Type) (-(int32) amountToSubtract) | |||
: (Type) (-(int64) amountToSubtract)); | |||
return operator+= (juce_negate (amountToSubtract)); | |||
} | |||
template <typename Type> | |||
@@ -191,7 +191,7 @@ inline double juce_hypot (double a, double b) | |||
/** Using juce_hypot and juce_hypotf is easier than dealing with all the different | |||
versions of these functions of various platforms and compilers. */ | |||
inline float juce_hypotf (float a, float b) | |||
inline float juce_hypotf (float a, float b) throw() | |||
{ | |||
#if JUCE_WINDOWS | |||
return (float) _hypot (a, b); | |||
@@ -201,11 +201,25 @@ inline float juce_hypotf (float a, float b) | |||
} | |||
/** 64-bit abs function. */ | |||
inline int64 abs64 (const int64 n) | |||
inline int64 abs64 (const int64 n) throw() | |||
{ | |||
return (n >= 0) ? n : -n; | |||
} | |||
/** This templated negate function will negate pointers as well as integers */ | |||
template <typename Type> | |||
inline Type juce_negate (Type n) throw() | |||
{ | |||
return -n; | |||
} | |||
/** This templated negate function will negate pointers as well as integers */ | |||
template <typename Type> | |||
inline Type* juce_negate (Type* n) throw() | |||
{ | |||
return (Type*) -(pointer_sized_int) n; | |||
} | |||
//============================================================================== | |||
/** A predefined value for Pi, at double-precision. | |||
@@ -143,7 +143,9 @@ void Button::setToggleState (const bool shouldBeOn, | |||
{ | |||
if (shouldBeOn != lastToggleState) | |||
{ | |||
isOn = shouldBeOn; | |||
if (isOn != shouldBeOn) // this test means that if the value is void rather than explicitly set to | |||
isOn = shouldBeOn; // false, it won't be changed unless the required value is true. | |||
lastToggleState = shouldBeOn; | |||
repaint(); | |||
@@ -81,12 +81,11 @@ void BooleanPropertyComponent::paint (Graphics& g) | |||
{ | |||
PropertyComponent::paint (g); | |||
const Rectangle<int> r (button->getBounds()); | |||
g.setColour (Colours::white); | |||
g.fillRect (r); | |||
g.fillRect (button->getBounds()); | |||
g.setColour (findColour (ComboBox::outlineColourId)); | |||
g.drawRect (r.getX(), r.getY(), r.getWidth(), r.getHeight()); | |||
g.drawRect (button->getBounds()); | |||
} | |||
void BooleanPropertyComponent::refresh() | |||
@@ -63,10 +63,12 @@ void ChoicePropertyComponent::createComboBox (const Array <int>* choiceIDs) | |||
addAndMakeVisible (comboBox = new ComboBox (String::empty)); | |||
int itemId = 0; | |||
for (int i = 0; i < choices.size(); ++i) | |||
{ | |||
if (choices[i].isNotEmpty()) | |||
comboBox->addItem (choices[i], choiceIDs == 0 ? (i + 1) | |||
comboBox->addItem (choices[i], choiceIDs == 0 ? ++itemId | |||
: ((*choiceIDs)[i])); | |||
else | |||
comboBox->addSeparator(); | |||
@@ -192,6 +192,20 @@ int AlertWindow::getNumButtons() const | |||
return buttons.size(); | |||
} | |||
void AlertWindow::triggerButtonClick (const String& buttonName) | |||
{ | |||
for (int i = buttons.size(); --i >= 0;) | |||
{ | |||
TextButton* const b = (TextButton*) buttons[i]; | |||
if (buttonName == b->getName()) | |||
{ | |||
b->triggerClick(); | |||
break; | |||
} | |||
} | |||
} | |||
//============================================================================== | |||
void AlertWindow::addTextEditor (const String& name, | |||
const String& initialContents, | |||
@@ -111,6 +111,9 @@ public: | |||
/** Returns the number of buttons that the window currently has. */ | |||
int getNumButtons() const; | |||
/** Invokes a click of one of the buttons. */ | |||
void triggerButtonClick (const String& buttonName); | |||
//============================================================================== | |||
/** Adds a textbox to the window for entering strings. | |||
@@ -57,7 +57,7 @@ void File::findFileSystemRoots (Array<File>& destArray) | |||
//============================================================================== | |||
static bool isFileOnDriveType (const File& f, const char** types) | |||
static bool isFileOnDriveType (const File& f, const char* const* types) | |||
{ | |||
struct statfs buf; | |||
@@ -75,16 +75,16 @@ static bool isFileOnDriveType (const File& f, const char** types) | |||
bool File::isOnCDRomDrive() const | |||
{ | |||
static const char* const cdTypes[] = { "cd9660", "cdfs", "cddafs", "udf", 0 }; | |||
const char* const cdTypes[] = { "cd9660", "cdfs", "cddafs", "udf", 0 }; | |||
return isFileOnDriveType (*this, (const char**) cdTypes); | |||
return isFileOnDriveType (*this, cdTypes); | |||
} | |||
bool File::isOnHardDisk() const | |||
{ | |||
static const char* const nonHDTypes[] = { "nfs", "smbfs", "ramfs", 0 }; | |||
const char* const nonHDTypes[] = { "nfs", "smbfs", "ramfs", 0 }; | |||
return ! (isOnCDRomDrive() || isFileOnDriveType (*this, (const char**) nonHDTypes)); | |||
return ! (isOnCDRomDrive() || isFileOnDriveType (*this, nonHDTypes)); | |||
} | |||
bool File::isOnRemovableDrive() const | |||
@@ -46,21 +46,21 @@ StringArray::StringArray (const String& firstValue) | |||
strings.add (firstValue); | |||
} | |||
StringArray::StringArray (const juce_wchar** const initialStrings, | |||
StringArray::StringArray (const juce_wchar* const* const initialStrings, | |||
const int numberOfStrings) | |||
{ | |||
for (int i = 0; i < numberOfStrings; ++i) | |||
strings.add (initialStrings [i]); | |||
} | |||
StringArray::StringArray (const char** const initialStrings, | |||
StringArray::StringArray (const char* const* const initialStrings, | |||
const int numberOfStrings) | |||
{ | |||
for (int i = 0; i < numberOfStrings; ++i) | |||
strings.add (initialStrings [i]); | |||
} | |||
StringArray::StringArray (const juce_wchar** const initialStrings) | |||
StringArray::StringArray (const juce_wchar* const* const initialStrings) | |||
{ | |||
int i = 0; | |||
@@ -68,7 +68,7 @@ StringArray::StringArray (const juce_wchar** const initialStrings) | |||
strings.add (initialStrings [i++]); | |||
} | |||
StringArray::StringArray (const char** const initialStrings) | |||
StringArray::StringArray (const char* const* const initialStrings) | |||
{ | |||
int i = 0; | |||
@@ -54,27 +54,27 @@ public: | |||
treated as empty strings | |||
@param numberOfStrings how many items there are in the array | |||
*/ | |||
StringArray (const juce_wchar** strings, int numberOfStrings); | |||
StringArray (const juce_wchar* const* strings, int numberOfStrings); | |||
/** 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** strings, int numberOfStrings); | |||
StringArray (const char* const* strings, int numberOfStrings); | |||
/** 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. | |||
*/ | |||
explicit StringArray (const juce_wchar** strings); | |||
explicit StringArray (const juce_wchar* const* strings); | |||
/** 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. | |||
*/ | |||
explicit StringArray (const char** strings); | |||
explicit StringArray (const char* const* strings); | |||
/** Destructor. */ | |||
~StringArray(); | |||