@@ -26,11 +26,11 @@ | |||
#include "jucer_TextButton.h" | |||
#include "jucer_ToggleButton.h" | |||
#include "jucer_TextEditor.h" | |||
#include "jucer_Viewport.h" | |||
#include "jucer_Label.h" | |||
#include "jucer_ComboBox.h" | |||
#include "jucer_Slider.h" | |||
#include "jucer_GroupComponent.h" | |||
#include "jucer_Viewport.h" | |||
#include "jucer_TabbedComponent.h" | |||
#include "jucer_JucerComponent.h" | |||
#include "jucer_GenericComponent.h" | |||
#include "jucer_Label.h" | |||
#include "jucer_Slider.h" | |||
#include "jucer_TabbedComponent.h" |
@@ -29,6 +29,7 @@ | |||
#include "../jucer_ComponentDocument.h" | |||
//============================================================================== | |||
class TextButtonHandler : public ComponentTypeHelper<TextButton> | |||
{ | |||
@@ -443,3 +443,19 @@ UndoManager* ComponentDocument::getUndoManager() | |||
{ | |||
return &undoManager; | |||
} | |||
//============================================================================== | |||
void ComponentDocument::createClassProperties (Array <PropertyComponent*>& props) | |||
{ | |||
props.add (new TextPropertyComponent (getClassName(), "Class Name", 256, false)); | |||
props.getLast()->setTooltip ("The C++ class name for the component class."); | |||
props.add (new TextPropertyComponent (getClassDescription(), "Description", 512, false)); | |||
props.getLast()->setTooltip ("A freeform description of the component."); | |||
props.add (new SliderPropertyComponent (getCanvasWidth(), "Initial Width", 1.0, 8192.0, 1.0)); | |||
props.getLast()->setTooltip ("The initial width of the component when it is created."); | |||
props.add (new SliderPropertyComponent (getCanvasHeight(), "Initial Height", 1.0, 8192.0, 1.0)); | |||
props.getLast()->setTooltip ("The initial height of the component when it is created."); | |||
} |
@@ -48,11 +48,13 @@ public: | |||
typedef SelectedItemSet<uint32> SelectedItems; | |||
//============================================================================== | |||
Value getClassName() { return getRootValue ("className"); } | |||
Value getClassDescription() { return getRootValue ("classDesc"); } | |||
Value getClassName() { return getRootValueNonUndoable ("className"); } | |||
Value getClassDescription() { return getRootValueNonUndoable ("classDesc"); } | |||
Value getCanvasWidth() { return root.getPropertyAsValue ("width", 0); } // (deliberately not undoable) | |||
Value getCanvasHeight() { return root.getPropertyAsValue ("height", 0); } | |||
Value getCanvasWidth() { return getRootValueNonUndoable ("width"); } | |||
Value getCanvasHeight() { return getRootValueNonUndoable ("height"); } | |||
void createClassProperties (Array <PropertyComponent*>& props); | |||
const String getNonExistentMemberName (String suggestedName); | |||
@@ -103,7 +105,9 @@ private: | |||
void checkRootObject(); | |||
ValueTree getComponentGroup() const; | |||
Value getRootValue (const var::identifier& name) { return root.getPropertyAsValue (name, getUndoManager()); } | |||
Value getRootValueUndoable (const var::identifier& name) { return root.getPropertyAsValue (name, getUndoManager()); } | |||
Value getRootValueNonUndoable (const var::identifier& name) { return root.getPropertyAsValue (name, 0); } | |||
void writeCode (OutputStream& cpp, OutputStream& header); | |||
void writeMetadata (OutputStream& out); | |||
@@ -1086,52 +1086,152 @@ private: | |||
}; | |||
//============================================================================== | |||
class ComponentEditor::InfoPanel : public Component, | |||
public ChangeListener | |||
class ComponentEditor::ClassInfoHolder : public Component | |||
{ | |||
public: | |||
InfoPanel (ComponentEditor& editor_) | |||
: editor (editor_) | |||
ClassInfoHolder (ComponentEditor& editor_) | |||
: editor (editor_) | |||
{ | |||
setOpaque (true); | |||
addAndMakeVisible (panel = new PropertyPanelWithTooltips()); | |||
Array <PropertyComponent*> props; | |||
editor.getDocument().createClassProperties (props); | |||
panel->getPanel()->addSection ("Component Properties", props, true); | |||
} | |||
addAndMakeVisible (props = new PropertyPanel()); | |||
~ClassInfoHolder() | |||
{ | |||
deleteAllChildren(); | |||
} | |||
editor.getCanvas()->getSelection().addChangeListener (this); | |||
void resized() | |||
{ | |||
panel->setBounds (getLocalBounds()); | |||
} | |||
~InfoPanel() | |||
private: | |||
ComponentEditor& editor; | |||
PropertyPanelWithTooltips* panel; | |||
}; | |||
//============================================================================== | |||
class ComponentEditor::LayoutEditorHolder : public Component | |||
{ | |||
public: | |||
LayoutEditorHolder (ComponentEditor& editor_) | |||
: editor (editor_), infoPanel (0) | |||
{ | |||
editor.getCanvas()->getSelection().removeChangeListener (this); | |||
addAndMakeVisible (viewport = new Viewport()); | |||
} | |||
props->clear(); | |||
~LayoutEditorHolder() | |||
{ | |||
deleteAndZero (infoPanel); | |||
deleteAllChildren(); | |||
} | |||
void changeListenerCallback (void*) | |||
void createCanvas() | |||
{ | |||
Array <PropertyComponent*> newComps; | |||
editor.getCanvas()->getSelectedItemProperties (newComps); | |||
viewport->setViewedComponent (new Canvas (editor)); | |||
addAndMakeVisible (infoPanel = new InfoPanel (editor)); | |||
} | |||
props->clear(); | |||
props->addProperties (newComps); | |||
void resized() | |||
{ | |||
const int infoPanelWidth = 200; | |||
viewport->setBounds (0, 0, getWidth() - infoPanelWidth, getHeight()); | |||
if (infoPanel != 0) | |||
infoPanel->setBounds (getWidth() - infoPanelWidth, 0, infoPanelWidth, getHeight()); | |||
} | |||
void paint (Graphics& g) | |||
Viewport* getViewport() const { return viewport; } | |||
private: | |||
class InfoPanel : public Component, | |||
public ChangeListener | |||
{ | |||
public: | |||
InfoPanel (ComponentEditor& editor_) | |||
: editor (editor_) | |||
{ | |||
setOpaque (true); | |||
addAndMakeVisible (props = new PropertyPanel()); | |||
editor.getCanvas()->getSelection().addChangeListener (this); | |||
} | |||
~InfoPanel() | |||
{ | |||
editor.getCanvas()->getSelection().removeChangeListener (this); | |||
props->clear(); | |||
deleteAllChildren(); | |||
} | |||
void changeListenerCallback (void*) | |||
{ | |||
Array <PropertyComponent*> newComps; | |||
editor.getCanvas()->getSelectedItemProperties (newComps); | |||
props->clear(); | |||
props->addProperties (newComps); | |||
} | |||
void paint (Graphics& g) | |||
{ | |||
g.fillAll (Colour::greyLevel (0.92f)); | |||
} | |||
void resized() | |||
{ | |||
props->setSize (getWidth(), getHeight()); | |||
} | |||
private: | |||
ComponentEditor& editor; | |||
PropertyPanel* props; | |||
}; | |||
ComponentEditor& editor; | |||
Viewport* viewport; | |||
InfoPanel* infoPanel; | |||
}; | |||
//============================================================================== | |||
class ComponentEditor::BackgroundEditorHolder : public Component | |||
{ | |||
public: | |||
BackgroundEditorHolder (ComponentEditor& editor_) | |||
: editor (editor_) | |||
{ | |||
g.fillAll (Colour::greyLevel (0.92f)); | |||
} | |||
void resized() | |||
~BackgroundEditorHolder() | |||
{ | |||
props->setSize (getWidth(), getHeight()); | |||
} | |||
private: | |||
ComponentEditor& editor; | |||
PropertyPanel* props; | |||
}; | |||
//============================================================================== | |||
class ComponentEditor::CodeEditorHolder : public Component | |||
{ | |||
public: | |||
CodeEditorHolder (ComponentEditor& editor_) | |||
: editor (editor_) | |||
{ | |||
} | |||
~CodeEditorHolder() | |||
{ | |||
} | |||
private: | |||
ComponentEditor& editor; | |||
}; | |||
//============================================================================== | |||
ComponentEditor::ComponentEditor (OpenDocumentManager::Document* document, | |||
@@ -1139,22 +1239,35 @@ ComponentEditor::ComponentEditor (OpenDocumentManager::Document* document, | |||
: DocumentEditorComponent (document), | |||
project (project_), | |||
componentDocument (componentDocument_), | |||
infoPanel (0) | |||
classInfoHolder (0), | |||
layoutEditorHolder (0), | |||
backgroundEditorHolder (0), | |||
codeEditorHolder (0) | |||
{ | |||
setOpaque (true); | |||
addAndMakeVisible (viewport = new Viewport()); | |||
if (document != 0) | |||
if (componentDocument != 0) | |||
{ | |||
viewport->setViewedComponent (new Canvas (*this)); | |||
addAndMakeVisible (infoPanel = new InfoPanel (*this)); | |||
classInfoHolder = new ClassInfoHolder (*this); | |||
layoutEditorHolder = new LayoutEditorHolder (*this); | |||
backgroundEditorHolder = new BackgroundEditorHolder (*this); | |||
codeEditorHolder = new CodeEditorHolder (*this); | |||
layoutEditorHolder->createCanvas(); | |||
} | |||
addAndMakeVisible (tabs = new TabbedComponent (TabbedButtonBar::TabsAtRight)); | |||
tabs->setTabBarDepth (22); | |||
tabs->addTab ("Class Settings", Colour::greyLevel (0.88f), classInfoHolder, true); | |||
tabs->addTab ("Components", Colours::white, layoutEditorHolder, true); | |||
tabs->addTab ("Background", Colours::white, backgroundEditorHolder, true); | |||
tabs->addTab ("Source Code", Colours::white, codeEditorHolder, true); | |||
tabs->setCurrentTabIndex (1); | |||
} | |||
ComponentEditor::~ComponentEditor() | |||
{ | |||
deleteAndZero (infoPanel); | |||
deleteAllChildren(); | |||
} | |||
@@ -1165,16 +1278,17 @@ void ComponentEditor::paint (Graphics& g) | |||
void ComponentEditor::resized() | |||
{ | |||
const int infoPanelWidth = 200; | |||
viewport->setBounds (0, 0, getWidth() - infoPanelWidth, getHeight()); | |||
if (infoPanel != 0) | |||
infoPanel->setBounds (getWidth() - infoPanelWidth, 0, infoPanelWidth, getHeight()); | |||
tabs->setBounds (getLocalBounds()); | |||
} | |||
ComponentEditor::Canvas* ComponentEditor::getCanvas() const | |||
{ | |||
return dynamic_cast <Canvas*> (viewport->getViewedComponent()); | |||
return dynamic_cast <Canvas*> (getViewport()->getViewedComponent()); | |||
} | |||
Viewport* ComponentEditor::getViewport() const | |||
{ | |||
return layoutEditorHolder->getViewport(); | |||
} | |||
void ComponentEditor::getAllCommands (Array <CommandID>& commands) | |||
@@ -53,19 +53,25 @@ public: | |||
ComponentDocument& getDocument() const { return *componentDocument; } | |||
Viewport* getViewport() const throw() { return viewport; } | |||
Viewport* getViewport() const; | |||
class Canvas; | |||
Canvas* getCanvas() const; | |||
private: | |||
class InfoPanel; | |||
class ClassInfoHolder; | |||
class LayoutEditorHolder; | |||
class BackgroundEditorHolder; | |||
class CodeEditorHolder; | |||
Project* project; | |||
ComponentDocument* componentDocument; | |||
Viewport* viewport; | |||
InfoPanel* infoPanel; | |||
TabbedComponent* tabs; | |||
ClassInfoHolder* classInfoHolder; | |||
LayoutEditorHolder* layoutEditorHolder; | |||
BackgroundEditorHolder* backgroundEditorHolder; | |||
CodeEditorHolder* codeEditorHolder; | |||
}; | |||
@@ -27,27 +27,21 @@ | |||
//[MiscUserDefs] You can add your own user definitions and misc code here... | |||
class PropertiesWithHelpComponent : public Component, | |||
public Timer | |||
class PropertiesWithHelpComponent : public PropertyPanelWithTooltips | |||
{ | |||
public: | |||
PropertiesWithHelpComponent (Project& project_, int tabIndex_) | |||
: project (project_), lastComp (0), tabIndex (tabIndex_) | |||
: project (project_), tabIndex (tabIndex_) | |||
{ | |||
addAndMakeVisible (panel = new PropertyPanel()); | |||
startTimer (150); | |||
} | |||
~PropertiesWithHelpComponent() | |||
{ | |||
deleteAllChildren(); | |||
} | |||
PropertyPanel* getPanel() const { return panel; } | |||
void rebuildProperties() | |||
{ | |||
panel->clear(); | |||
getPanel()->clear(); | |||
Array <PropertyComponent*> props; | |||
if (tabIndex == 0) | |||
@@ -91,7 +85,7 @@ public: | |||
exp->createPropertyEditors (props); | |||
} | |||
panel->addProperties (props); | |||
getPanel()->addProperties (props); | |||
} | |||
void visibilityChanged() | |||
@@ -100,71 +94,9 @@ public: | |||
rebuildProperties(); | |||
} | |||
void paint (Graphics& g) | |||
{ | |||
g.setColour (Colour::greyLevel (0.15f)); | |||
g.setFont (13.0f); | |||
TextLayout tl; | |||
tl.appendText (lastTip, Font (14.0f)); | |||
tl.layout (getWidth() - 10, Justification::left, true); // try to make it look nice | |||
if (tl.getNumLines() > 3) | |||
tl.layout (getWidth() - 10, Justification::left, false); // too big, so just squash it in.. | |||
tl.drawWithin (g, 5, panel->getBottom() + 2, getWidth() - 10, | |||
getHeight() - panel->getBottom() - 4, | |||
Justification::centredLeft); | |||
} | |||
void resized() | |||
{ | |||
panel->setBounds (0, 0, getWidth(), jmax (getHeight() - 60, proportionOfHeight (0.6f))); | |||
} | |||
void timerCallback() | |||
{ | |||
Component* const newComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse(); | |||
if (newComp != lastComp) | |||
{ | |||
lastComp = newComp; | |||
String newTip (findTip (newComp)); | |||
if (newTip != lastTip) | |||
{ | |||
lastTip = newTip; | |||
repaint (0, panel->getBottom(), getWidth(), getHeight()); | |||
} | |||
} | |||
} | |||
private: | |||
Project& project; | |||
PropertyPanel* panel; | |||
TextLayout layout; | |||
Component* lastComp; | |||
String lastTip; | |||
int tabIndex; | |||
const String findTip (Component* c) | |||
{ | |||
while (c != 0 && c != this) | |||
{ | |||
TooltipClient* tc = dynamic_cast <TooltipClient*> (c); | |||
if (tc != 0) | |||
{ | |||
String tip (tc->getTooltip()); | |||
if (tip.isNotEmpty()) | |||
return tip; | |||
} | |||
c = c->getParentComponent(); | |||
} | |||
return String::empty; | |||
} | |||
}; | |||
//[/MiscUserDefs] | |||
@@ -349,21 +349,21 @@ const String makeValidCppIdentifier (String s, | |||
n = "_" + n; | |||
// make sure it's not a reserved c++ keyword.. | |||
static const tchar* const reservedWords[] = | |||
static const char* const reservedWords[] = | |||
{ | |||
T("auto"), T("const"), T("double"), T("float"), T("int"), T("short"), T("struct"), | |||
T("return"), T("static"), T("union"), T("while"), T("asm"), T("dynamic_cast"), | |||
T("unsigned"), T("break"), T("continue"), T("else"), T("for"), T("long"), T("signed"), | |||
T("switch"), T("void"), T("case"), T("default"), T("enum"), T("goto"), T("register"), | |||
T("sizeof"), T("typedef"), T("volatile"), T("char"), T("do"), T("extern"), T("if"), | |||
T("namespace"), T("reinterpret_cast"), T("try"), T("bool"), T("explicit"), T("new"), | |||
T("static_cast"), T("typeid"), T("catch"), T("false"), T("operator"), T("template"), | |||
T("typename"), T("class"), T("friend"), T("private"), T("this"), T("using"), T("const_cast"), | |||
T("inline"), T("public"), T("throw"), T("virtual"), T("delete"), T("mutable"), T("protected"), | |||
T("true"), T("wchar_t"), T("and"), T("bitand"), T("compl"), T("not_eq"), T("or_eq"), | |||
T("xor_eq"), T("and_eq"), T("bitor"), T("not"), T("or"), T("xor"), T("cin"), T("endl"), | |||
T("INT_MIN"), T("iomanip"), T("main"), T("npos"), T("std"), T("cout"), T("include"), | |||
T("INT_MAX"), T("iostream"), T("MAX_RAND"), T("NULL"), T("string"), T("id") | |||
"auto", "const", "double", "float", "int", "short", "struct", | |||
"return", "static", "union", "while", "asm", "dynamic_cast", | |||
"unsigned", "break", "continue", "else", "for", "long", "signed", | |||
"switch", "void", "case", "default", "enum", "goto", "register", | |||
"sizeof", "typedef", "volatile", "char", "do", "extern", "if", | |||
"namespace", "reinterpret_cast", "try", "bool", "explicit", "new", | |||
"static_cast", "typeid", "catch", "false", "operator", "template", | |||
"typename", "class", "friend", "private", "this", "using", "const_cast", | |||
"inline", "public", "throw", "virtual", "delete", "mutable", "protected", | |||
"true", "wchar_t", "and", "bitand", "compl", "not_eq", "or_eq", | |||
"xor_eq", "and_eq", "bitor", "not", "or", "xor", "cin", "endl", | |||
"INT_MIN", "iomanip", "main", "npos", "std", "cout", "include", | |||
"INT_MAX", "iostream", "MAX_RAND", "NULL", "string", "id", "std" | |||
}; | |||
for (i = 0; i < numElementsInArray (reservedWords); ++i) | |||
@@ -503,3 +503,75 @@ int indexOfLineStartingWith (const StringArray& lines, const String& text, int s | |||
return -1; | |||
} | |||
//============================================================================== | |||
PropertyPanelWithTooltips::PropertyPanelWithTooltips() | |||
: lastComp (0) | |||
{ | |||
addAndMakeVisible (panel = new PropertyPanel()); | |||
startTimer (150); | |||
} | |||
PropertyPanelWithTooltips::~PropertyPanelWithTooltips() | |||
{ | |||
deleteAllChildren(); | |||
} | |||
void PropertyPanelWithTooltips::paint (Graphics& g) | |||
{ | |||
g.setColour (Colour::greyLevel (0.15f)); | |||
g.setFont (13.0f); | |||
TextLayout tl; | |||
tl.appendText (lastTip, Font (14.0f)); | |||
tl.layout (getWidth() - 10, Justification::left, true); // try to make it look nice | |||
if (tl.getNumLines() > 3) | |||
tl.layout (getWidth() - 10, Justification::left, false); // too big, so just squash it in.. | |||
tl.drawWithin (g, 5, panel->getBottom() + 2, getWidth() - 10, | |||
getHeight() - panel->getBottom() - 4, | |||
Justification::centredLeft); | |||
} | |||
void PropertyPanelWithTooltips::resized() | |||
{ | |||
panel->setBounds (0, 0, getWidth(), jmax (getHeight() - 60, proportionOfHeight (0.6f))); | |||
} | |||
void PropertyPanelWithTooltips::timerCallback() | |||
{ | |||
Component* const newComp = Desktop::getInstance().getMainMouseSource().getComponentUnderMouse(); | |||
if (newComp != lastComp) | |||
{ | |||
lastComp = newComp; | |||
String newTip (findTip (newComp)); | |||
if (newTip != lastTip) | |||
{ | |||
lastTip = newTip; | |||
repaint (0, panel->getBottom(), getWidth(), getHeight()); | |||
} | |||
} | |||
} | |||
const String PropertyPanelWithTooltips::findTip (Component* c) | |||
{ | |||
while (c != 0 && c != this) | |||
{ | |||
TooltipClient* const tc = dynamic_cast <TooltipClient*> (c); | |||
if (tc != 0) | |||
{ | |||
const String tip (tc->getTooltip()); | |||
if (tip.isNotEmpty()) | |||
return tip; | |||
} | |||
c = c->getParentComponent(); | |||
} | |||
return String::empty; | |||
} |
@@ -109,6 +109,30 @@ private: | |||
int64 fileHashCode, fileSize; | |||
}; | |||
//============================================================================== | |||
class PropertyPanelWithTooltips : public Component, | |||
public Timer | |||
{ | |||
public: | |||
PropertyPanelWithTooltips(); | |||
~PropertyPanelWithTooltips(); | |||
PropertyPanel* getPanel() const { return panel; } | |||
void paint (Graphics& g); | |||
void resized(); | |||
void timerCallback(); | |||
private: | |||
PropertyPanel* panel; | |||
TextLayout layout; | |||
Component* lastComp; | |||
String lastTip; | |||
const String findTip (Component* c); | |||
}; | |||
//============================================================================== | |||
static const double tickSizes[] = { 1.0, 2.0, 5.0, | |||
10.0, 20.0, 50.0, | |||
@@ -110,9 +110,6 @@ void removeSubWindow (void* nsWindow, Component* comp) | |||
[hostWindow removeChildWindow: pluginWindow]; | |||
comp->removeFromDesktop(); | |||
[hostWindow release]; | |||
for (int i = 20; --i >= 0;) | |||
MessageManager::getInstance()->runDispatchLoopUntil (1); | |||
} | |||
static bool isJuceWindow (WindowRef w) | |||
@@ -184,7 +184,15 @@ public: | |||
delete juceFilter; | |||
if (--numInstances == 0) | |||
{ | |||
#if JUCE_MAC | |||
// Hack to allow any NSWindows to clear themselves up before returning to PT.. | |||
for (int i = 20; --i >= 0;) | |||
MessageManager::getInstance()->runDispatchLoopUntil (1); | |||
#endif | |||
shutdownJuce_GUI(); | |||
} | |||
} | |||
//============================================================================== | |||
@@ -15900,6 +15900,11 @@ const var& ValueTree::SharedObject::getProperty (const var::identifier& name) co | |||
return properties [name]; | |||
} | |||
const var ValueTree::SharedObject::getProperty (const var::identifier& name, const var& defaultReturnValue) const | |||
{ | |||
return properties.getWithDefault (name, defaultReturnValue); | |||
} | |||
void ValueTree::SharedObject::setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager) | |||
{ | |||
if (undoManager == 0) | |||
@@ -16137,6 +16142,11 @@ const var& ValueTree::getProperty (const var::identifier& name) const | |||
return object == 0 ? var::null : object->getProperty (name); | |||
} | |||
const var ValueTree::getProperty (const var::identifier& name, const var& defaultReturnValue) const | |||
{ | |||
return object == 0 ? defaultReturnValue : object->getProperty (name, defaultReturnValue); | |||
} | |||
void ValueTree::setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager) | |||
{ | |||
jassert (name.name.isNotEmpty()); | |||
@@ -16167,10 +16177,10 @@ int ValueTree::getNumProperties() const | |||
return object == 0 ? 0 : object->properties.size(); | |||
} | |||
const var::identifier ValueTree::getPropertyName (int index) const | |||
const var::identifier ValueTree::getPropertyName (const int index) const | |||
{ | |||
return (object == 0) ? var::identifier() | |||
: object->properties.getName (index); | |||
return object == 0 ? var::identifier() | |||
: object->properties.getName (index); | |||
} | |||
class ValueTreePropertyValueSource : public Value::ValueSource, | |||
@@ -41179,10 +41189,10 @@ void Component::moveKeyboardFocusToSibling (const bool moveToNext) | |||
{ | |||
if (nextComp->isCurrentlyBlockedByAnotherModalComponent()) | |||
{ | |||
SafePointer<Component> safePointer (this); | |||
SafePointer<Component> nextCompPointer (nextComp); | |||
internalModalInputAttempt(); | |||
if (safePointer == 0 || nextComp->isCurrentlyBlockedByAnotherModalComponent()) | |||
if (nextCompPointer == 0 || nextComp->isCurrentlyBlockedByAnotherModalComponent()) | |||
return; | |||
} | |||
@@ -46567,7 +46577,7 @@ void Label::showEditor() | |||
editorShown (editor); | |||
enterModalState(); | |||
enterModalState (false); | |||
editor->grabKeyboardFocus(); | |||
} | |||
} | |||
@@ -71032,7 +71042,7 @@ SliderPropertyComponent::SliderPropertyComponent (const String& name, | |||
slider->addListener (this); | |||
} | |||
SliderPropertyComponent::SliderPropertyComponent (Value& valueToControl, | |||
SliderPropertyComponent::SliderPropertyComponent (const Value& valueToControl, | |||
const String& name, | |||
const double rangeMin, | |||
const double rangeMax, | |||
@@ -3135,24 +3135,7 @@ private: | |||
Atomic& operator= (const Atomic&); | |||
}; | |||
// If we've got gcc4.2 or later, we can use its atomic intrinsics... | |||
#if JUCE_GCC && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) | |||
inline void Atomic::increment (int32& variable) { __sync_add_and_fetch (&variable, 1); } | |||
inline int32 Atomic::incrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, 1); } | |||
inline void Atomic::decrement (int32& variable) { __sync_add_and_fetch (&variable, -1); } | |||
inline int32 Atomic::decrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, -1); } | |||
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue) | |||
{ return __sync_val_compare_and_swap (&destination, oldValue, newValue); } | |||
inline void* Atomic::swapPointers (void* volatile* value1, void* value2) | |||
{ | |||
void* currentVal = *value1; | |||
while (! __sync_bool_compare_and_swap (value1, currentVal, value2)) { currentVal = *value1; } | |||
return currentVal; | |||
} | |||
#elif (JUCE_MAC || JUCE_IPHONE) // Older Mac builds using gcc4.0 or earlier... | |||
#if JUCE_MAC && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)) // Older Mac builds using gcc4.1 or earlier... | |||
inline void Atomic::increment (int32& variable) { OSAtomicIncrement32 (static_cast <int32_t*> (&variable)); } | |||
inline int32 Atomic::incrementAndReturn (int32& variable) { return OSAtomicIncrement32 (static_cast <int32_t*> (&variable)); } | |||
@@ -3184,9 +3167,8 @@ private: | |||
return currentVal; | |||
} | |||
#elif JUCE_LINUX // Linux with compilers other than gcc4.2 or later... | |||
#elif JUCE_LINUX && __INTEL_COMPILER // Linux with Intel compiler... | |||
#if __INTEL_COMPILER | |||
inline void Atomic::increment (int32& variable) { _InterlockedIncrement (&variable); } | |||
inline int32 Atomic::incrementAndReturn (int32& variable) { return _InterlockedIncrement (&variable); } | |||
inline void Atomic::decrement (int32& variable) { _InterlockedDecrement (&variable); } | |||
@@ -3203,9 +3185,21 @@ private: | |||
#endif | |||
} | |||
#else | |||
#error "Linux build requires gcc4.2 or later for atomic operations" | |||
#endif | |||
#elif JUCE_GCC // On GCC, use intrinsics... | |||
inline void Atomic::increment (int32& variable) { __sync_add_and_fetch (&variable, 1); } | |||
inline int32 Atomic::incrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, 1); } | |||
inline void Atomic::decrement (int32& variable) { __sync_add_and_fetch (&variable, -1); } | |||
inline int32 Atomic::decrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, -1); } | |||
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue) | |||
{ return __sync_val_compare_and_swap (&destination, oldValue, newValue); } | |||
inline void* Atomic::swapPointers (void* volatile* value1, void* value2) | |||
{ | |||
void* currentVal = *value1; | |||
while (! __sync_bool_compare_and_swap (value1, currentVal, value2)) { currentVal = *value1; } | |||
return currentVal; | |||
} | |||
#elif JUCE_USE_INTRINSICS // Windows... | |||
@@ -6726,6 +6720,8 @@ public: | |||
const var& getProperty (const var::identifier& name) const; | |||
const var getProperty (const var::identifier& name, const var& defaultReturnValue) const; | |||
const var& operator[] (const var::identifier& name) const; | |||
void setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager); | |||
@@ -6825,6 +6821,7 @@ private: | |||
void sendChildChangeMessage (ValueTree& tree); | |||
void sendParentChangeMessage(); | |||
const var& getProperty (const var::identifier& name) const; | |||
const var getProperty (const var::identifier& name, const var& defaultReturnValue) const; | |||
void setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager); | |||
bool hasProperty (const var::identifier& name) const; | |||
void removeProperty (const var::identifier& name, UndoManager* const undoManager); | |||
@@ -26101,7 +26098,7 @@ protected: | |||
public: | |||
SliderPropertyComponent (Value& valueToControl, | |||
SliderPropertyComponent (const Value& valueToControl, | |||
const String& propertyName, | |||
double rangeMin, | |||
double rangeMax, | |||
@@ -232,6 +232,11 @@ const var& ValueTree::SharedObject::getProperty (const var::identifier& name) co | |||
return properties [name]; | |||
} | |||
const var ValueTree::SharedObject::getProperty (const var::identifier& name, const var& defaultReturnValue) const | |||
{ | |||
return properties.getWithDefault (name, defaultReturnValue); | |||
} | |||
void ValueTree::SharedObject::setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager) | |||
{ | |||
if (undoManager == 0) | |||
@@ -471,6 +476,11 @@ const var& ValueTree::getProperty (const var::identifier& name) const | |||
return object == 0 ? var::null : object->getProperty (name); | |||
} | |||
const var ValueTree::getProperty (const var::identifier& name, const var& defaultReturnValue) const | |||
{ | |||
return object == 0 ? defaultReturnValue : object->getProperty (name, defaultReturnValue); | |||
} | |||
void ValueTree::setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager) | |||
{ | |||
jassert (name.name.isNotEmpty()); | |||
@@ -501,10 +511,10 @@ int ValueTree::getNumProperties() const | |||
return object == 0 ? 0 : object->properties.size(); | |||
} | |||
const var::identifier ValueTree::getPropertyName (int index) const | |||
const var::identifier ValueTree::getPropertyName (const int index) const | |||
{ | |||
return (object == 0) ? var::identifier() | |||
: object->properties.getName (index); | |||
return object == 0 ? var::identifier() | |||
: object->properties.getName (index); | |||
} | |||
//============================================================================== | |||
@@ -130,6 +130,13 @@ public: | |||
*/ | |||
const var& getProperty (const var::identifier& name) const; | |||
/** Returns the value of a named property, or a user-specified default if the property doesn't exist. | |||
If no such property has been set, this will return the value of defaultReturnValue. | |||
You can also use operator[] and getProperty to get a property. | |||
@see var, getProperty, setProperty, hasProperty | |||
*/ | |||
const var getProperty (const var::identifier& name, const var& defaultReturnValue) const; | |||
/** Returns the value of a named property. | |||
If no such property has been set, this will return a void variant. This is the same as | |||
calling getProperty(). | |||
@@ -406,6 +413,7 @@ private: | |||
void sendChildChangeMessage (ValueTree& tree); | |||
void sendParentChangeMessage(); | |||
const var& getProperty (const var::identifier& name) const; | |||
const var getProperty (const var::identifier& name, const var& defaultReturnValue) const; | |||
void setProperty (const var::identifier& name, const var& newValue, UndoManager* const undoManager); | |||
bool hasProperty (const var::identifier& name) const; | |||
void removeProperty (const var::identifier& name, UndoManager* const undoManager); | |||
@@ -62,24 +62,7 @@ private: | |||
//============================================================================== | |||
// If we've got gcc4.2 or later, we can use its atomic intrinsics... | |||
#if JUCE_GCC && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) | |||
inline void Atomic::increment (int32& variable) { __sync_add_and_fetch (&variable, 1); } | |||
inline int32 Atomic::incrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, 1); } | |||
inline void Atomic::decrement (int32& variable) { __sync_add_and_fetch (&variable, -1); } | |||
inline int32 Atomic::decrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, -1); } | |||
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue) | |||
{ return __sync_val_compare_and_swap (&destination, oldValue, newValue); } | |||
inline void* Atomic::swapPointers (void* volatile* value1, void* value2) | |||
{ | |||
void* currentVal = *value1; | |||
while (! __sync_bool_compare_and_swap (value1, currentVal, value2)) { currentVal = *value1; } | |||
return currentVal; | |||
} | |||
#elif (JUCE_MAC || JUCE_IPHONE) // Older Mac builds using gcc4.0 or earlier... | |||
#if JUCE_MAC && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)) // Older Mac builds using gcc4.1 or earlier... | |||
inline void Atomic::increment (int32& variable) { OSAtomicIncrement32 (static_cast <int32_t*> (&variable)); } | |||
inline int32 Atomic::incrementAndReturn (int32& variable) { return OSAtomicIncrement32 (static_cast <int32_t*> (&variable)); } | |||
@@ -112,9 +95,8 @@ private: | |||
} | |||
//============================================================================== | |||
#elif JUCE_LINUX // Linux with compilers other than gcc4.2 or later... | |||
#elif JUCE_LINUX && __INTEL_COMPILER // Linux with Intel compiler... | |||
#if __INTEL_COMPILER | |||
inline void Atomic::increment (int32& variable) { _InterlockedIncrement (&variable); } | |||
inline int32 Atomic::incrementAndReturn (int32& variable) { return _InterlockedIncrement (&variable); } | |||
inline void Atomic::decrement (int32& variable) { _InterlockedDecrement (&variable); } | |||
@@ -131,9 +113,22 @@ private: | |||
#endif | |||
} | |||
#else | |||
#error "Linux build requires gcc4.2 or later for atomic operations" | |||
#endif | |||
//============================================================================== | |||
#elif JUCE_GCC // On GCC, use intrinsics... | |||
inline void Atomic::increment (int32& variable) { __sync_add_and_fetch (&variable, 1); } | |||
inline int32 Atomic::incrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, 1); } | |||
inline void Atomic::decrement (int32& variable) { __sync_add_and_fetch (&variable, -1); } | |||
inline int32 Atomic::decrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, -1); } | |||
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue) | |||
{ return __sync_val_compare_and_swap (&destination, oldValue, newValue); } | |||
inline void* Atomic::swapPointers (void* volatile* value1, void* value2) | |||
{ | |||
void* currentVal = *value1; | |||
while (! __sync_bool_compare_and_swap (value1, currentVal, value2)) { currentVal = *value1; } | |||
return currentVal; | |||
} | |||
//============================================================================== | |||
#elif JUCE_USE_INTRINSICS // Windows... | |||
@@ -218,7 +218,7 @@ void Label::showEditor() | |||
editorShown (editor); | |||
enterModalState(); | |||
enterModalState (false); | |||
editor->grabKeyboardFocus(); | |||
} | |||
} | |||
@@ -3072,10 +3072,10 @@ void Component::moveKeyboardFocusToSibling (const bool moveToNext) | |||
{ | |||
if (nextComp->isCurrentlyBlockedByAnotherModalComponent()) | |||
{ | |||
SafePointer<Component> safePointer (this); | |||
SafePointer<Component> nextCompPointer (nextComp); | |||
internalModalInputAttempt(); | |||
if (safePointer == 0 || nextComp->isCurrentlyBlockedByAnotherModalComponent()) | |||
if (nextCompPointer == 0 || nextComp->isCurrentlyBlockedByAnotherModalComponent()) | |||
return; | |||
} | |||
@@ -47,7 +47,7 @@ SliderPropertyComponent::SliderPropertyComponent (const String& name, | |||
slider->addListener (this); | |||
} | |||
SliderPropertyComponent::SliderPropertyComponent (Value& valueToControl, | |||
SliderPropertyComponent::SliderPropertyComponent (const Value& valueToControl, | |||
const String& name, | |||
const double rangeMin, | |||
const double rangeMax, | |||
@@ -63,7 +63,7 @@ public: | |||
If you need to customise the slider in other ways, your constructor can | |||
access the slider member variable and change it directly. | |||
*/ | |||
SliderPropertyComponent (Value& valueToControl, | |||
SliderPropertyComponent (const Value& valueToControl, | |||
const String& propertyName, | |||
double rangeMin, | |||
double rangeMax, | |||