@@ -52,8 +52,8 @@ public: | |||||
Value getValue (const var::identifier& name, ValueTree& state, ComponentDocument& document) const; | Value getValue (const var::identifier& name, ValueTree& state, ComponentDocument& document) const; | ||||
//============================================================================== | |||||
protected: | protected: | ||||
//============================================================================== | |||||
const String name, xmlTag, memberNameRoot; | const String name, xmlTag, memberNameRoot; | ||||
private: | private: | ||||
@@ -81,7 +81,6 @@ public: | |||||
ComponentTypeHandler* getHandlerFor (const String& type); | ComponentTypeHandler* getHandlerFor (const String& type); | ||||
const StringArray getTypeNames() const; | const StringArray getTypeNames() const; | ||||
private: | private: | ||||
//============================================================================== | //============================================================================== | ||||
OwnedArray <ComponentTypeHandler> handlers; | OwnedArray <ComponentTypeHandler> handlers; | ||||
@@ -47,14 +47,22 @@ public: | |||||
void update (ComponentDocument& document, GroupComponent* comp, const ValueTree& state) | void update (ComponentDocument& document, GroupComponent* comp, const ValueTree& state) | ||||
{ | { | ||||
comp->setText (state ["text"].toString()); | |||||
} | } | ||||
void initialiseNew (ComponentDocument& document, ValueTree& state) | void initialiseNew (ComponentDocument& document, ValueTree& state) | ||||
{ | { | ||||
state.setProperty ("text", "Group", 0); | |||||
} | } | ||||
void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | 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); | addEditableColourProperties (document, state, props); | ||||
} | } | ||||
}; | }; | ||||
@@ -49,11 +49,18 @@ public: | |||||
void update (ComponentDocument& document, Label* comp, const ValueTree& state) | void update (ComponentDocument& document, Label* comp, const ValueTree& state) | ||||
{ | { | ||||
comp->setText (state ["text"].toString(), false); | 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) | void initialiseNew (ComponentDocument& document, ValueTree& state) | ||||
{ | { | ||||
state.setProperty ("text", "New Label", 0); | 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) | 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.add (new TextPropertyComponent (getValue ("text", state, document), "Text", 16384, true)); | ||||
props.getLast()->setTooltip ("The label's text."); | 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); | addEditableColourProperties (document, state, props); | ||||
} | } | ||||
}; | }; | ||||
@@ -48,11 +48,25 @@ public: | |||||
void update (ComponentDocument& document, TextButton* comp, const ValueTree& state) | void update (ComponentDocument& document, TextButton* comp, const ValueTree& state) | ||||
{ | { | ||||
comp->setButtonText (state ["text"].toString()); | 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) | void initialiseNew (ComponentDocument& document, ValueTree& state) | ||||
{ | { | ||||
state.setProperty ("text", "New Button", 0); | 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) | 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.add (new TextPropertyComponent (getValue ("text", state, document), "Button Text", 1024, false)); | ||||
props.getLast()->setTooltip ("The button's text."); | 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); | addEditableColourProperties (document, state, props); | ||||
} | } | ||||
}; | }; | ||||
@@ -93,10 +93,11 @@ void Project::setMissingDefaultValues() | |||||
if (! projectRoot.getChildWithName (Tags::projectMainGroup).isValid()) | if (! projectRoot.getChildWithName (Tags::projectMainGroup).isValid()) | ||||
{ | { | ||||
Item mainGroup (*this, ValueTree (Tags::projectMainGroup)); | Item mainGroup (*this, ValueTree (Tags::projectMainGroup)); | ||||
mainGroup.createUIDIfMissing(); | |||||
projectRoot.addChild (mainGroup.getNode(), 0, 0); | projectRoot.addChild (mainGroup.getNode(), 0, 0); | ||||
} | } | ||||
getMainGroup().initialiseNodeValues(); | |||||
if (getDocumentTitle().isEmpty()) | if (getDocumentTitle().isEmpty()) | ||||
setTitle ("Juce Project"); | setTitle ("Juce Project"); | ||||
@@ -407,7 +408,7 @@ Project::Item Project::getMainGroup() | |||||
Project::Item Project::createNewGroup() | Project::Item Project::createNewGroup() | ||||
{ | { | ||||
Item item (*this, ValueTree (Tags::group)); | Item item (*this, ValueTree (Tags::group)); | ||||
item.createUIDIfMissing(); | |||||
item.initialiseNodeValues(); | |||||
item.getName() = "New Group"; | item.getName() = "New Group"; | ||||
return item; | return item; | ||||
} | } | ||||
@@ -415,7 +416,7 @@ Project::Item Project::createNewGroup() | |||||
Project::Item Project::createNewItem (const File& file) | Project::Item Project::createNewItem (const File& file) | ||||
{ | { | ||||
Item item (*this, ValueTree (Tags::file)); | Item item (*this, ValueTree (Tags::file)); | ||||
item.createUIDIfMissing(); | |||||
item.initialiseNodeValues(); | |||||
item.getName() = file.getFileName(); | item.getName() = file.getFileName(); | ||||
item.getShouldCompileValue() = file.hasFileExtension ("cpp;mm;c;m"); | item.getShouldCompileValue() = file.hasFileExtension ("cpp;mm;c;m"); | ||||
item.getShouldAddToResourceValue() = shouldBeAddedToBinaryResourcesByDefault (file); | item.getShouldAddToResourceValue() = shouldBeAddedToBinaryResourcesByDefault (file); | ||||
@@ -490,7 +491,10 @@ const File Project::Item::getFile() const | |||||
void Project::Item::setFile (const File& file) | void Project::Item::setFile (const File& file) | ||||
{ | { | ||||
jassert (isFile()); | |||||
node.setProperty ("file", project.getRelativePathForFile (file), getUndoManager()); | node.setProperty ("file", project.getRelativePathForFile (file), getUndoManager()); | ||||
node.setProperty ("name", file.getFileName(), getUndoManager()); | |||||
jassert (getFile() == file); | jassert (getFile() == file); | ||||
} | } | ||||
@@ -559,10 +563,20 @@ const File Project::Item::determineGroupFolder() const | |||||
return f; | return f; | ||||
} | } | ||||
void Project::Item::createUIDIfMissing() | |||||
void Project::Item::initialiseNodeValues() | |||||
{ | { | ||||
if (! node.hasProperty ("id")) | 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 | Value Project::Item::getName() const | ||||
@@ -156,6 +156,8 @@ public: | |||||
Item (const Item& other); | Item (const Item& other); | ||||
~Item(); | ~Item(); | ||||
void initialiseNodeValues(); | |||||
//============================================================================== | //============================================================================== | ||||
bool isValid() const { return node.isValid(); } | bool isValid() const { return node.isValid(); } | ||||
const ValueTree& getNode() const throw() { return node; } | const ValueTree& getNode() const throw() { return node; } | ||||
@@ -170,7 +172,6 @@ public: | |||||
bool isMainGroup() const; | bool isMainGroup() const; | ||||
const String getID() const; | const String getID() const; | ||||
void createUIDIfMissing(); | |||||
//============================================================================== | //============================================================================== | ||||
Value getName() const; | Value getName() const; | ||||
@@ -188,7 +189,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
bool canContain (const Item& child) const; | bool canContain (const Item& child) const; | ||||
int getNumChildren() const { return node.getNumChildren(); } | 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); | void addChild (const Item& newChild, int insertIndex); | ||||
bool addFile (const File& file, int insertIndex); | bool addFile (const File& file, int insertIndex); | ||||
void removeItemFromProject(); | void removeItemFromProject(); | ||||
@@ -394,10 +394,12 @@ bool ComponentEditor::perform (const InvocationInfo& info) | |||||
switch (info.commandID) | switch (info.commandID) | ||||
{ | { | ||||
case CommandIDs::undo: | case CommandIDs::undo: | ||||
getDocument().getUndoManager()->beginNewTransaction(); | |||||
getDocument().getUndoManager()->undo(); | getDocument().getUndoManager()->undo(); | ||||
return true; | return true; | ||||
case CommandIDs::redo: | case CommandIDs::redo: | ||||
getDocument().getUndoManager()->beginNewTransaction(); | |||||
getDocument().getUndoManager()->redo(); | getDocument().getUndoManager()->redo(); | ||||
return true; | return true; | ||||
@@ -32,7 +32,6 @@ ProjectTreeViewBase::ProjectTreeViewBase (const Project::Item& item_) | |||||
: item (item_), isFileMissing (false) | : item (item_), isFileMissing (false) | ||||
{ | { | ||||
item.getNode().addListener (this); | item.getNode().addListener (this); | ||||
item.createUIDIfMissing(); | |||||
} | } | ||||
ProjectTreeViewBase::~ProjectTreeViewBase() | ProjectTreeViewBase::~ProjectTreeViewBase() | ||||
@@ -197,24 +197,11 @@ private: | |||||
class ColourSelectorWithSwatches : public ColourSelector | class ColourSelectorWithSwatches : public ColourSelector | ||||
{ | { | ||||
public: | 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; | ColourEditorComponent* owner; | ||||
@@ -126,3 +126,11 @@ void StoredSettings::setLastKnownJuceFolder (const File& file) | |||||
jassert (isJuceFolder (file)); | jassert (isJuceFolder (file)); | ||||
props->setValue ("lastJuceFolder", file.getFullPathName()); | 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; | Array <Colour> swatchColours; | ||||
const StringArray& getFontNames(); | |||||
//============================================================================== | //============================================================================== | ||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
private: | private: | ||||
ScopedPointer<PropertiesFile> props; | ScopedPointer<PropertiesFile> props; | ||||
StringArray fontNames; | |||||
}; | }; | ||||
@@ -641,3 +641,102 @@ void FloatingLabelComponent::paint (Graphics& g) | |||||
g.setColour (colour); | g.setColour (colour); | ||||
glyphs.draw (g, AffineTransform::translation (1.0f, 1.0f)); | 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); | 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 | class FileModificationDetector | ||||
{ | { | ||||
@@ -49,7 +49,7 @@ public: | |||||
~ValueRemapperSource() {} | ~ValueRemapperSource() {} | ||||
void addMappings (const char** values) | |||||
void addMappings (const char* const* values) | |||||
{ | { | ||||
while (values[0] != 0 && values[1] != 0) | while (values[0] != 0 && values[1] != 0) | ||||
{ | { | ||||
@@ -108,6 +108,48 @@ protected: | |||||
const ValueRemapperSource& operator= (const ValueRemapperSource&); | 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) | 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&) | void valueChanged (Value&) | ||||
@@ -12365,21 +12365,21 @@ StringArray::StringArray (const String& firstValue) | |||||
strings.add (firstValue); | strings.add (firstValue); | ||||
} | } | ||||
StringArray::StringArray (const juce_wchar** const initialStrings, | |||||
StringArray::StringArray (const juce_wchar* const* const initialStrings, | |||||
const int numberOfStrings) | const int numberOfStrings) | ||||
{ | { | ||||
for (int i = 0; i < numberOfStrings; ++i) | for (int i = 0; i < numberOfStrings; ++i) | ||||
strings.add (initialStrings [i]); | strings.add (initialStrings [i]); | ||||
} | } | ||||
StringArray::StringArray (const char** const initialStrings, | |||||
StringArray::StringArray (const char* const* const initialStrings, | |||||
const int numberOfStrings) | const int numberOfStrings) | ||||
{ | { | ||||
for (int i = 0; i < numberOfStrings; ++i) | for (int i = 0; i < numberOfStrings; ++i) | ||||
strings.add (initialStrings [i]); | strings.add (initialStrings [i]); | ||||
} | } | ||||
StringArray::StringArray (const juce_wchar** const initialStrings) | |||||
StringArray::StringArray (const juce_wchar* const* const initialStrings) | |||||
{ | { | ||||
int i = 0; | int i = 0; | ||||
@@ -12387,7 +12387,7 @@ StringArray::StringArray (const juce_wchar** const initialStrings) | |||||
strings.add (initialStrings [i++]); | strings.add (initialStrings [i++]); | ||||
} | } | ||||
StringArray::StringArray (const char** const initialStrings) | |||||
StringArray::StringArray (const char* const* const initialStrings) | |||||
{ | { | ||||
int i = 0; | int i = 0; | ||||
@@ -18758,7 +18758,7 @@ END_JUCE_NAMESPACE | |||||
BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
static const char* const aiffFormatName = "AIFF file"; | 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 | class AiffAudioFormatReader : public AudioFormatReader | ||||
{ | { | ||||
@@ -19460,7 +19460,7 @@ public: | |||||
}; | }; | ||||
AiffAudioFormat::AiffAudioFormat() | 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, | AudioFormat::AudioFormat (const String& name, | ||||
const juce_wchar** const extensions) | |||||
const StringArray& extensions) | |||||
: formatName (name), | : formatName (name), | ||||
fileExtensions (extensions) | fileExtensions (extensions) | ||||
{ | { | ||||
@@ -21163,7 +21163,7 @@ BEGIN_JUCE_NAMESPACE | |||||
bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle); | bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle); | ||||
static const char* const quickTimeFormatName = "QuickTime file"; | 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 | class QTAudioReader : public AudioFormatReader | ||||
{ | { | ||||
@@ -21423,7 +21423,7 @@ private: | |||||
}; | }; | ||||
QuickTimeAudioFormat::QuickTimeAudioFormat() | QuickTimeAudioFormat::QuickTimeAudioFormat() | ||||
: AudioFormat (TRANS (quickTimeFormatName), (const juce_wchar**) quickTimeExtensions) | |||||
: AudioFormat (TRANS (quickTimeFormatName), StringArray (quickTimeExtensions)) | |||||
{ | { | ||||
} | } | ||||
@@ -21486,7 +21486,7 @@ END_JUCE_NAMESPACE | |||||
BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
static const char* const wavFormatName = "WAV file"; | 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::bwavDescription = "bwav description"; | ||||
const char* const WavAudioFormat::bwavOriginator = "bwav originator"; | const char* const WavAudioFormat::bwavOriginator = "bwav originator"; | ||||
@@ -22255,7 +22255,7 @@ public: | |||||
}; | }; | ||||
WavAudioFormat::WavAudioFormat() | 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) | 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; | lastToggleState = shouldBeOn; | ||||
repaint(); | repaint(); | ||||
@@ -70750,12 +70752,11 @@ void BooleanPropertyComponent::paint (Graphics& g) | |||||
{ | { | ||||
PropertyComponent::paint (g); | PropertyComponent::paint (g); | ||||
const Rectangle<int> r (button->getBounds()); | |||||
g.setColour (Colours::white); | g.setColour (Colours::white); | ||||
g.fillRect (r); | |||||
g.fillRect (button->getBounds()); | |||||
g.setColour (findColour (ComboBox::outlineColourId)); | g.setColour (findColour (ComboBox::outlineColourId)); | ||||
g.drawRect (r.getX(), r.getY(), r.getWidth(), r.getHeight()); | |||||
g.drawRect (button->getBounds()); | |||||
} | } | ||||
void BooleanPropertyComponent::refresh() | void BooleanPropertyComponent::refresh() | ||||
@@ -70838,10 +70839,12 @@ void ChoicePropertyComponent::createComboBox (const Array <int>* choiceIDs) | |||||
addAndMakeVisible (comboBox = new ComboBox (String::empty)); | addAndMakeVisible (comboBox = new ComboBox (String::empty)); | ||||
int itemId = 0; | |||||
for (int i = 0; i < choices.size(); ++i) | for (int i = 0; i < choices.size(); ++i) | ||||
{ | { | ||||
if (choices[i].isNotEmpty()) | if (choices[i].isNotEmpty()) | ||||
comboBox->addItem (choices[i], choiceIDs == 0 ? (i + 1) | |||||
comboBox->addItem (choices[i], choiceIDs == 0 ? ++itemId | |||||
: ((*choiceIDs)[i])); | : ((*choiceIDs)[i])); | ||||
else | else | ||||
comboBox->addSeparator(); | comboBox->addSeparator(); | ||||
@@ -75608,6 +75611,20 @@ int AlertWindow::getNumButtons() const | |||||
return buttons.size(); | 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, | void AlertWindow::addTextEditor (const String& name, | ||||
const String& initialContents, | const String& initialContents, | ||||
const String& onScreenLabel, | const String& onScreenLabel, | ||||
@@ -124118,7 +124135,7 @@ void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L) | |||||
BEGIN_JUCE_NAMESPACE | BEGIN_JUCE_NAMESPACE | ||||
static const char* const flacFormatName = "FLAC file"; | 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 | class FlacReader : public AudioFormatReader | ||||
{ | { | ||||
@@ -124519,7 +124536,7 @@ private: | |||||
}; | }; | ||||
FlacAudioFormat::FlacAudioFormat() | 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 | BEGIN_JUCE_NAMESPACE | ||||
static const char* const oggFormatName = "Ogg-Vorbis file"; | 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 | class OggReader : public AudioFormatReader | ||||
{ | { | ||||
@@ -183534,7 +183551,7 @@ public: | |||||
}; | }; | ||||
OggVorbisAudioFormat::OggVorbisAudioFormat() | 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 ("/")); | 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; | struct statfs buf; | ||||
@@ -259868,16 +259885,16 @@ static bool isFileOnDriveType (const File& f, const char** types) | |||||
bool File::isOnCDRomDrive() const | 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 | 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 | 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 | /** Using juce_hypot and juce_hypotf is easier than dealing with all the different | ||||
versions of these functions of various platforms and compilers. */ | 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 | #if JUCE_WINDOWS | ||||
return (float) _hypot (a, b); | return (float) _hypot (a, b); | ||||
@@ -1130,11 +1130,25 @@ inline float juce_hypotf (float a, float b) | |||||
} | } | ||||
/** 64-bit abs function. */ | /** 64-bit abs function. */ | ||||
inline int64 abs64 (const int64 n) | |||||
inline int64 abs64 (const int64 n) throw() | |||||
{ | { | ||||
return (n >= 0) ? n : -n; | 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. | /** A predefined value for Pi, at double-precision. | ||||
@see float_Pi | @see float_Pi | ||||
@@ -5798,8 +5812,7 @@ inline Type Atomic<Type>::operator+= (const Type amountToAdd) throw() | |||||
template <typename Type> | template <typename Type> | ||||
inline Type Atomic<Type>::operator-= (const Type amountToSubtract) throw() | 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> | template <typename Type> | ||||
@@ -7092,27 +7105,27 @@ public: | |||||
treated as empty strings | treated as empty strings | ||||
@param numberOfStrings how many items there are in the array | @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. | /** Creates a copy of an array of string literals. | ||||
@param strings an array of strings to add. Null pointers in the array will be | @param strings an array of strings to add. Null pointers in the array will be | ||||
treated as empty strings | treated as empty strings | ||||
@param numberOfStrings how many items there are in the array | @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. | /** 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, | Each item from the array passed-in is added, until it encounters a null pointer, | ||||
at which point it stops. | 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. | /** 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, | Each item from the array passed-in is added, until it encounters a null pointer, | ||||
at which point it stops. | at which point it stops. | ||||
*/ | */ | ||||
explicit StringArray (const char** strings); | |||||
explicit StringArray (const char* const* strings); | |||||
/** Destructor. */ | /** Destructor. */ | ||||
~StringArray(); | ~StringArray(); | ||||
@@ -11999,10 +12012,9 @@ private: | |||||
object - this means that multiple Value objects can all refer to the same piece of | 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. | 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 | class JUCE_API Value | ||||
{ | { | ||||
@@ -12110,10 +12122,10 @@ public: | |||||
@see removeListener | @see removeListener | ||||
*/ | */ | ||||
void addListener (Listener* const listener); | |||||
void addListener (Listener* listener); | |||||
/** Removes a listener that was previously added with addListener(). */ | /** 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. | 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. */ | /** Returns the current value of this object. */ | ||||
virtual const var getValue() const = 0; | virtual const var getValue() const = 0; | ||||
/** Changes the current value. | /** Changes the current value. | ||||
This must also trigger a change message if the value actually changes. | 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 | If dispatchSynchronously is true, the method will call all the listeners | ||||
before returning; otherwise it'll dispatch a message and make the call later. | before returning; otherwise it'll dispatch a message and make the call later. | ||||
*/ | */ | ||||
void sendChangeMessage (const bool dispatchSynchronously); | |||||
void sendChangeMessage (bool dispatchSynchronously); | |||||
juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
@@ -12156,10 +12169,11 @@ public: | |||||
ValueSource& operator= (const ValueSource&); | 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 | juce_UseDebuggingNewOperator | ||||
@@ -29187,7 +29201,7 @@ protected: | |||||
be returned by getFileExtension() | be returned by getFileExtension() | ||||
*/ | */ | ||||
AudioFormat (const String& formatName, | AudioFormat (const String& formatName, | ||||
const juce_wchar** const fileExtensions); | |||||
const StringArray& fileExtensions); | |||||
private: | private: | ||||
@@ -52029,6 +52043,9 @@ public: | |||||
/** Returns the number of buttons that the window currently has. */ | /** Returns the number of buttons that the window currently has. */ | ||||
int getNumButtons() const; | 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. | /** 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 | @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 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() | 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, | AudioFormat::AudioFormat (const String& name, | ||||
const juce_wchar** const extensions) | |||||
const StringArray& extensions) | |||||
: formatName (name), | : formatName (name), | ||||
fileExtensions (extensions) | fileExtensions (extensions) | ||||
{ | { | ||||
@@ -161,7 +161,7 @@ protected: | |||||
be returned by getFileExtension() | be returned by getFileExtension() | ||||
*/ | */ | ||||
AudioFormat (const String& formatName, | AudioFormat (const String& formatName, | ||||
const juce_wchar** const fileExtensions); | |||||
const StringArray& fileExtensions); | |||||
private: | private: | ||||
//============================================================================== | //============================================================================== | ||||
@@ -86,7 +86,7 @@ BEGIN_JUCE_NAMESPACE | |||||
//============================================================================== | //============================================================================== | ||||
static const char* const flacFormatName = "FLAC file"; | 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() | 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 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 | class OggReader : public AudioFormatReader | ||||
@@ -395,7 +395,7 @@ public: | |||||
//============================================================================== | //============================================================================== | ||||
OggVorbisAudioFormat::OggVorbisAudioFormat() | 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); | bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle); | ||||
static const char* const quickTimeFormatName = "QuickTime file"; | 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 | class QTAudioReader : public AudioFormatReader | ||||
@@ -334,7 +334,7 @@ private: | |||||
//============================================================================== | //============================================================================== | ||||
QuickTimeAudioFormat::QuickTimeAudioFormat() | 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 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() | 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 | 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. | 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 | class JUCE_API Value | ||||
{ | { | ||||
@@ -157,10 +156,10 @@ public: | |||||
@see removeListener | @see removeListener | ||||
*/ | */ | ||||
void addListener (Listener* const listener); | |||||
void addListener (Listener* listener); | |||||
/** Removes a listener that was previously added with addListener(). */ | /** 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. */ | /** Returns the current value of this object. */ | ||||
virtual const var getValue() const = 0; | virtual const var getValue() const = 0; | ||||
/** Changes the current value. | /** Changes the current value. | ||||
This must also trigger a change message if the value actually changes. | 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 | If dispatchSynchronously is true, the method will call all the listeners | ||||
before returning; otherwise it'll dispatch a message and make the call later. | before returning; otherwise it'll dispatch a message and make the call later. | ||||
*/ | */ | ||||
void sendChangeMessage (const bool dispatchSynchronously); | |||||
void sendChangeMessage (bool dispatchSynchronously); | |||||
//============================================================================== | //============================================================================== | ||||
juce_UseDebuggingNewOperator | 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 | juce_UseDebuggingNewOperator | ||||
private: | private: | ||||
@@ -251,8 +251,7 @@ inline Type Atomic<Type>::operator+= (const Type amountToAdd) throw() | |||||
template <typename Type> | template <typename Type> | ||||
inline Type Atomic<Type>::operator-= (const Type amountToSubtract) throw() | 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> | 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 | /** Using juce_hypot and juce_hypotf is easier than dealing with all the different | ||||
versions of these functions of various platforms and compilers. */ | 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 | #if JUCE_WINDOWS | ||||
return (float) _hypot (a, b); | return (float) _hypot (a, b); | ||||
@@ -201,11 +201,25 @@ inline float juce_hypotf (float a, float b) | |||||
} | } | ||||
/** 64-bit abs function. */ | /** 64-bit abs function. */ | ||||
inline int64 abs64 (const int64 n) | |||||
inline int64 abs64 (const int64 n) throw() | |||||
{ | { | ||||
return (n >= 0) ? n : -n; | 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. | /** A predefined value for Pi, at double-precision. | ||||
@@ -143,7 +143,9 @@ void Button::setToggleState (const bool shouldBeOn, | |||||
{ | { | ||||
if (shouldBeOn != lastToggleState) | 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; | lastToggleState = shouldBeOn; | ||||
repaint(); | repaint(); | ||||
@@ -81,12 +81,11 @@ void BooleanPropertyComponent::paint (Graphics& g) | |||||
{ | { | ||||
PropertyComponent::paint (g); | PropertyComponent::paint (g); | ||||
const Rectangle<int> r (button->getBounds()); | |||||
g.setColour (Colours::white); | g.setColour (Colours::white); | ||||
g.fillRect (r); | |||||
g.fillRect (button->getBounds()); | |||||
g.setColour (findColour (ComboBox::outlineColourId)); | g.setColour (findColour (ComboBox::outlineColourId)); | ||||
g.drawRect (r.getX(), r.getY(), r.getWidth(), r.getHeight()); | |||||
g.drawRect (button->getBounds()); | |||||
} | } | ||||
void BooleanPropertyComponent::refresh() | void BooleanPropertyComponent::refresh() | ||||
@@ -63,10 +63,12 @@ void ChoicePropertyComponent::createComboBox (const Array <int>* choiceIDs) | |||||
addAndMakeVisible (comboBox = new ComboBox (String::empty)); | addAndMakeVisible (comboBox = new ComboBox (String::empty)); | ||||
int itemId = 0; | |||||
for (int i = 0; i < choices.size(); ++i) | for (int i = 0; i < choices.size(); ++i) | ||||
{ | { | ||||
if (choices[i].isNotEmpty()) | if (choices[i].isNotEmpty()) | ||||
comboBox->addItem (choices[i], choiceIDs == 0 ? (i + 1) | |||||
comboBox->addItem (choices[i], choiceIDs == 0 ? ++itemId | |||||
: ((*choiceIDs)[i])); | : ((*choiceIDs)[i])); | ||||
else | else | ||||
comboBox->addSeparator(); | comboBox->addSeparator(); | ||||
@@ -192,6 +192,20 @@ int AlertWindow::getNumButtons() const | |||||
return buttons.size(); | 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, | void AlertWindow::addTextEditor (const String& name, | ||||
const String& initialContents, | const String& initialContents, | ||||
@@ -111,6 +111,9 @@ public: | |||||
/** Returns the number of buttons that the window currently has. */ | /** Returns the number of buttons that the window currently has. */ | ||||
int getNumButtons() const; | 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. | /** 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; | struct statfs buf; | ||||
@@ -75,16 +75,16 @@ static bool isFileOnDriveType (const File& f, const char** types) | |||||
bool File::isOnCDRomDrive() const | 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 | 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 | bool File::isOnRemovableDrive() const | ||||
@@ -46,21 +46,21 @@ StringArray::StringArray (const String& firstValue) | |||||
strings.add (firstValue); | strings.add (firstValue); | ||||
} | } | ||||
StringArray::StringArray (const juce_wchar** const initialStrings, | |||||
StringArray::StringArray (const juce_wchar* const* const initialStrings, | |||||
const int numberOfStrings) | const int numberOfStrings) | ||||
{ | { | ||||
for (int i = 0; i < numberOfStrings; ++i) | for (int i = 0; i < numberOfStrings; ++i) | ||||
strings.add (initialStrings [i]); | strings.add (initialStrings [i]); | ||||
} | } | ||||
StringArray::StringArray (const char** const initialStrings, | |||||
StringArray::StringArray (const char* const* const initialStrings, | |||||
const int numberOfStrings) | const int numberOfStrings) | ||||
{ | { | ||||
for (int i = 0; i < numberOfStrings; ++i) | for (int i = 0; i < numberOfStrings; ++i) | ||||
strings.add (initialStrings [i]); | strings.add (initialStrings [i]); | ||||
} | } | ||||
StringArray::StringArray (const juce_wchar** const initialStrings) | |||||
StringArray::StringArray (const juce_wchar* const* const initialStrings) | |||||
{ | { | ||||
int i = 0; | int i = 0; | ||||
@@ -68,7 +68,7 @@ StringArray::StringArray (const juce_wchar** const initialStrings) | |||||
strings.add (initialStrings [i++]); | strings.add (initialStrings [i++]); | ||||
} | } | ||||
StringArray::StringArray (const char** const initialStrings) | |||||
StringArray::StringArray (const char* const* const initialStrings) | |||||
{ | { | ||||
int i = 0; | int i = 0; | ||||
@@ -54,27 +54,27 @@ public: | |||||
treated as empty strings | treated as empty strings | ||||
@param numberOfStrings how many items there are in the array | @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. | /** Creates a copy of an array of string literals. | ||||
@param strings an array of strings to add. Null pointers in the array will be | @param strings an array of strings to add. Null pointers in the array will be | ||||
treated as empty strings | treated as empty strings | ||||
@param numberOfStrings how many items there are in the array | @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. | /** 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, | Each item from the array passed-in is added, until it encounters a null pointer, | ||||
at which point it stops. | 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. | /** 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, | Each item from the array passed-in is added, until it encounters a null pointer, | ||||
at which point it stops. | at which point it stops. | ||||
*/ | */ | ||||
explicit StringArray (const char** strings); | |||||
explicit StringArray (const char* const* strings); | |||||
/** Destructor. */ | /** Destructor. */ | ||||
~StringArray(); | ~StringArray(); | ||||