|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2015 - ROLI Ltd.
-
- Permission is granted to use this software under the terms of either:
- a) the GPL v2 (or any later version)
- b) the Affero GPL v3
-
- Details of these licenses can be found at: www.gnu.org/licenses
-
- JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- ------------------------------------------------------------------------------
-
- To release a closed-source product which uses JUCE, commercial licenses are
- available: visit www.juce.com for more information.
-
- ==============================================================================
- */
-
- #ifndef JUCE_LIVECONSTANTEDITOR_H_INCLUDED
- #define JUCE_LIVECONSTANTEDITOR_H_INCLUDED
-
- #if JUCE_ENABLE_LIVE_CONSTANT_EDITOR && ! DOXYGEN
-
- //==============================================================================
- /** You can safely ignore all the stuff in this namespace - it's a bunch of boilerplate
- code used to implement the JUCE_LIVE_CONSTANT functionality.
- */
- namespace LiveConstantEditor
- {
- int64 parseInt (String);
- double parseDouble (const String&);
- String intToString (int, bool preferHex);
- String intToString (int64, bool preferHex);
-
- template <typename Type>
- static void setFromString (Type& v, const String& s) { v = static_cast<Type> (s); }
- inline void setFromString (char& v, const String& s) { v = (char) parseInt (s); }
- inline void setFromString (unsigned char& v, const String& s) { v = (unsigned char) parseInt (s); }
- inline void setFromString (short& v, const String& s) { v = (short) parseInt (s); }
- inline void setFromString (unsigned short& v, const String& s) { v = (unsigned short) parseInt (s); }
- inline void setFromString (int& v, const String& s) { v = (int) parseInt (s); }
- inline void setFromString (unsigned int& v, const String& s) { v = (unsigned int) parseInt (s); }
- inline void setFromString (long& v, const String& s) { v = (long) parseInt (s); }
- inline void setFromString (unsigned long& v, const String& s) { v = (unsigned long) parseInt (s); }
- inline void setFromString (int64& v, const String& s) { v = (int64) parseInt (s); }
- inline void setFromString (uint64& v, const String& s) { v = (uint64) parseInt (s); }
- inline void setFromString (double& v, const String& s) { v = parseDouble (s); }
- inline void setFromString (float& v, const String& s) { v = (float) parseDouble (s); }
- inline void setFromString (String& v, const String& s) { v = s; }
- inline void setFromString (Colour& v, const String& s) { v = Colour ((uint32) parseInt (s)); }
-
- template <typename Type>
- inline String getAsString (const Type& v, bool) { return String (v); }
- inline String getAsString (char v, bool preferHex) { return intToString ((int) v, preferHex); }
- inline String getAsString (unsigned char v, bool preferHex) { return intToString ((int) v, preferHex); }
- inline String getAsString (short v, bool preferHex) { return intToString ((int) v, preferHex); }
- inline String getAsString (unsigned short v, bool preferHex) { return intToString ((int) v, preferHex); }
- inline String getAsString (int v, bool preferHex) { return intToString ((int) v, preferHex); }
- inline String getAsString (unsigned int v, bool preferHex) { return intToString ((int) v, preferHex); }
- inline String getAsString (int64 v, bool preferHex) { return intToString ((int64) v, preferHex); }
- inline String getAsString (uint64 v, bool preferHex) { return intToString ((int64) v, preferHex); }
- inline String getAsString (Colour v, bool) { return intToString ((int) v.getARGB(), true); }
-
- template <typename Type> struct isStringType { enum { value = 0 }; };
- template <> struct isStringType<String> { enum { value = 1 }; };
-
- template <typename Type>
- inline String getAsCode (Type& v, bool preferHex) { return getAsString (v, preferHex); }
- inline String getAsCode (Colour v, bool) { return "Colour (0x" + String::toHexString ((int) v.getARGB()).paddedLeft ('0', 8) + ")"; }
- inline String getAsCode (const String& v, bool) { return CppTokeniserFunctions::addEscapeChars(v).quoted(); }
- inline String getAsCode (const char* v, bool) { return getAsCode (String (v), false); }
-
- template <typename Type>
- inline const char* castToCharPointer (const Type&) { return ""; }
- inline const char* castToCharPointer (const String& s) { return s.toRawUTF8(); }
-
- struct LivePropertyEditorBase;
-
- //==============================================================================
- struct JUCE_API LiveValueBase
- {
- LiveValueBase (const char* file, int line);
- virtual ~LiveValueBase();
-
- virtual LivePropertyEditorBase* createPropertyComponent (CodeDocument&) = 0;
- virtual String getStringValue (bool preferHex) const = 0;
- virtual String getCodeValue (bool preferHex) const = 0;
- virtual void setStringValue (const String&) = 0;
- virtual String getOriginalStringValue (bool preferHex) const = 0;
- virtual bool isString() const = 0;
-
- String name, sourceFile;
- int sourceLine;
-
- JUCE_DECLARE_NON_COPYABLE (LiveValueBase)
- };
-
- //==============================================================================
- struct JUCE_API LivePropertyEditorBase : public Component,
- private TextEditor::Listener,
- private ButtonListener
- {
- LivePropertyEditorBase (LiveValueBase&, CodeDocument&);
-
- void paint (Graphics&) override;
- void resized() override;
- void textEditorTextChanged (TextEditor&) override;
- void buttonClicked (Button*) override;
-
- void applyNewValue (const String&);
- void selectOriginalValue();
- void findOriginalValueInCode();
-
- LiveValueBase& value;
- Label name;
- TextEditor valueEditor;
- TextButton resetButton;
- CodeDocument& document;
- CPlusPlusCodeTokeniser tokeniser;
- CodeEditorComponent sourceEditor;
- CodeDocument::Position valueStart, valueEnd;
- ScopedPointer<Component> customComp;
- bool wasHex;
-
- JUCE_DECLARE_NON_COPYABLE (LivePropertyEditorBase)
- };
-
- //==============================================================================
- Component* createColourEditor (LivePropertyEditorBase&);
- Component* createIntegerSlider (LivePropertyEditorBase&);
- Component* createFloatSlider (LivePropertyEditorBase&);
-
- template <typename Type> struct CustomEditor { static Component* create (LivePropertyEditorBase&) { return nullptr; } };
- template<> struct CustomEditor<char> { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
- template<> struct CustomEditor<unsigned char> { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
- template<> struct CustomEditor<int> { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
- template<> struct CustomEditor<unsigned int> { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
- template<> struct CustomEditor<short> { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
- template<> struct CustomEditor<unsigned short> { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
- template<> struct CustomEditor<int64> { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
- template<> struct CustomEditor<uint64> { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
- template<> struct CustomEditor<float> { static Component* create (LivePropertyEditorBase& e) { return createFloatSlider (e); } };
- template<> struct CustomEditor<double> { static Component* create (LivePropertyEditorBase& e) { return createFloatSlider (e); } };
- template<> struct CustomEditor<Colour> { static Component* create (LivePropertyEditorBase& e) { return createColourEditor (e); } };
-
- template <typename Type>
- struct LivePropertyEditor : public LivePropertyEditorBase
- {
- template <typename ValueType>
- LivePropertyEditor (ValueType& v, CodeDocument& d) : LivePropertyEditorBase (v, d)
- {
- addAndMakeVisible (customComp = CustomEditor<Type>::create (*this));
- }
- };
-
- //==============================================================================
- template <typename Type>
- struct LiveValue : public LiveValueBase
- {
- LiveValue (const char* file, int line, const Type& initialValue)
- : LiveValueBase (file, line), value (initialValue), originalValue (initialValue)
- {}
-
- operator Type() const noexcept { return value; }
- operator const char*() const { return castToCharPointer (value); }
-
- LivePropertyEditorBase* createPropertyComponent (CodeDocument& doc) override
- {
- return new LivePropertyEditor<Type> (*this, doc);
- }
-
- String getStringValue (bool preferHex) const override { return getAsString (value, preferHex); }
- String getCodeValue (bool preferHex) const override { return getAsCode (value, preferHex); }
- String getOriginalStringValue (bool preferHex) const override { return getAsString (originalValue, preferHex); }
- void setStringValue (const String& s) override { setFromString (value, s); }
- bool isString() const override { return isStringType<Type>::value; }
-
- Type value, originalValue;
-
- JUCE_DECLARE_NON_COPYABLE (LiveValue)
- };
-
- //==============================================================================
- class JUCE_API ValueList : private AsyncUpdater,
- private DeletedAtShutdown
- {
- public:
- ValueList();
- ~ValueList();
-
- juce_DeclareSingleton (ValueList, false)
-
- template <typename Type>
- LiveValue<Type>& getValue (const char* file, int line, const Type& initialValue)
- {
- const ScopedLock sl (lock);
- typedef LiveValue<Type> ValueType;
-
- for (int i = 0; i < values.size(); ++i)
- {
- LiveValueBase* v = values.getUnchecked(i);
-
- if (v->sourceLine == line && v->sourceFile == file)
- return *static_cast<ValueType*> (v);
- }
-
- ValueType* v = new ValueType (file, line, initialValue);
- addValue (v);
- return *v;
- }
-
- private:
- OwnedArray<LiveValueBase> values;
- OwnedArray<CodeDocument> documents;
- Array<File> documentFiles;
- class EditorWindow;
- friend class EditorWindow;
- friend struct ContainerDeletePolicy<EditorWindow>;
- Component::SafePointer<EditorWindow> editorWindow;
- CriticalSection lock;
-
- CodeDocument& getDocument (const File&);
- void addValue (LiveValueBase*);
- void handleAsyncUpdate() override;
- };
-
- template <typename Type>
- inline LiveValue<Type>& getValue (const char* file, int line, const Type& initialValue)
- {
- return ValueList::getInstance()->getValue (file, line, initialValue);
- }
-
- inline LiveValue<String>& getValue (const char* file, int line, const char* initialValue)
- {
- return getValue (file, line, String (initialValue));
- }
- }
-
- #endif
-
- //==============================================================================
- #if JUCE_ENABLE_LIVE_CONSTANT_EDITOR || DOXYGEN
- /**
- This macro wraps a primitive constant value in some cunning boilerplate code that allows
- its value to be interactively tweaked in a popup window while your application is running.
-
- In a release build, this macro disappears and is replaced by only the constant that it
- wraps, but if JUCE_ENABLE_LIVE_CONSTANT_EDITOR is enabled, it injects a class wrapper
- that automatically pops-up a window containing an editor that allows the value to be
- tweaked at run-time. The editor window will also force all visible components to be
- resized and repainted whenever a value is changed, so that if you use this to wrap
- a colour or layout parameter, you'll be able to immediately see the effects of changing it.
-
- The editor will also load the original source-file that contains each JUCE_LIVE_CONSTANT
- macro, and will display a preview of the modified source code as you adjust the values.
-
- Things to note:
-
- - Only one of these per line! The __FILE__ and __LINE__ macros are used to identify
- the value, so things will get confused if you have more than one per line
- - Obviously because it needs to load the source code based on the __FILE__ macro,
- it'll only work if the source files are stored locally in the same location as they
- were when you compiled the program.
- - It's only designed to cope with simple types: primitives, string literals, and
- the Colour class, so if you try using it for other classes or complex expressions,
- good luck!
- - The editor window will get popped up whenever a new value is used for the first
- time. You can close the window, but there's no way to get it back without restarting
- the app!
-
- e.g. in this example the colours, font size, and text used in the paint method can
- all be adjusted live:
- @code
- void MyComp::paint (Graphics& g) override
- {
- g.fillAll (JUCE_LIVE_CONSTANT (Colour (0xffddddff)));
-
- Colour fontColour = JUCE_LIVE_CONSTANT (Colour (0xff005500));
- float fontSize = JUCE_LIVE_CONSTANT (16.0f);
-
- g.setColour (fontColour);
- g.setFont (fontSize);
-
- g.drawFittedText (JUCE_LIVE_CONSTANT ("Hello world!"),
- getLocalBounds(), Justification::centred, 2);
- }
- @endcode
- */
- #define JUCE_LIVE_CONSTANT(initialValue) \
- (juce::LiveConstantEditor::getValue (__FILE__, __LINE__ - 1, initialValue))
- #else
- #define JUCE_LIVE_CONSTANT(initialValue) \
- (initialValue)
- #endif
-
-
- #endif // JUCE_LIVECONSTANTEDITOR_H_INCLUDED
|