1 /*
2   ==============================================================================
3 
4    This file is part of the JUCE library.
5    Copyright (c) 2020 - Raw Material Software Limited
6 
7    JUCE is an open source library subject to commercial or open-source
8    licensing.
9 
10    By using JUCE, you agree to the terms of both the JUCE 6 End-User License
11    Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
12 
13    End User License Agreement: www.juce.com/juce-6-licence
14    Privacy Policy: www.juce.com/juce-privacy-policy
15 
16    Or: You may also use this code under the terms of the GPL v3 (see
17    www.gnu.org/licenses).
18 
19    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21    DISCLAIMED.
22 
23   ==============================================================================
24 */
25 
26 namespace juce
27 {
28 
29 //==============================================================================
30 /**
31     A PropertyComponent that shows its value as editable text.
32 
33     @see PropertyComponent
34 
35     @tags{GUI}
36 */
37 class JUCE_API  TextPropertyComponent  : public PropertyComponent
38 {
39 protected:
40     //==============================================================================
41     /** Creates a text property component.
42 
43         @param propertyName  The name of the property
44         @param maxNumChars   If not zero, then this specifies the maximum allowable length of
45                              the string. If zero, then the string will have no length limit.
46         @param isMultiLine   Sets whether the text editor allows carriage returns.
47         @param isEditable    Sets whether the text editor is editable. The default is true.
48 
49         @see TextEditor, setEditable
50     */
51     TextPropertyComponent (const String& propertyName,
52                            int maxNumChars,
53                            bool isMultiLine,
54                            bool isEditable = true);
55 
56 public:
57     /** Creates a text property component.
58 
59         @param valueToControl The Value that is controlled by the TextPropertyComponent
60         @param propertyName   The name of the property
61         @param maxNumChars    If not zero, then this specifies the maximum allowable length of
62                               the string. If zero, then the string will have no length limit.
63         @param isMultiLine    Sets whether the text editor allows carriage returns.
64         @param isEditable     Sets whether the text editor is editable. The default is true.
65 
66         @see TextEditor, setEditable
67     */
68     TextPropertyComponent (const Value& valueToControl,
69                            const String& propertyName,
70                            int maxNumChars,
71                            bool isMultiLine,
72                            bool isEditable = true);
73 
74     /** Creates a text property component with a default value.
75 
76         @param valueToControl The ValueWithDefault that is controlled by the TextPropertyComponent.
77         @param propertyName   The name of the property
78         @param maxNumChars    If not zero, then this specifies the maximum allowable length of
79                               the string. If zero, then the string will have no length limit.
80         @param isMultiLine    Sets whether the text editor allows carriage returns.
81         @param isEditable     Sets whether the text editor is editable. The default is true.
82 
83         @see TextEditor, setEditable
84     */
85     TextPropertyComponent (ValueWithDefault& valueToControl,
86                            const String& propertyName,
87                            int maxNumChars,
88                            bool isMultiLine,
89                            bool isEditable = true);
90 
91     /** Destructor. */
92     ~TextPropertyComponent() override;
93 
94     //==============================================================================
95     /** Called when the user edits the text.
96 
97         Your subclass must use this callback to change the value of whatever item
98         this property component represents.
99     */
100     virtual void setText (const String& newText);
101 
102     /** Returns the text that should be shown in the text editor. */
103     virtual String getText() const;
104 
105     /** Returns the text that should be shown in the text editor as a Value object. */
106     Value& getValue() const;
107 
108     //==============================================================================
109     /** Returns true if the text editor allows carriage returns. */
isTextEditorMultiLine()110     bool isTextEditorMultiLine() const noexcept    { return isMultiLine; }
111 
112     //==============================================================================
113     /** A set of colour IDs to use to change the colour of various aspects of the component.
114 
115         These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
116         methods.
117 
118         @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
119     */
120     enum ColourIds
121     {
122         backgroundColourId          = 0x100e401,    /**< The colour to fill the background of the text area. */
123         textColourId                = 0x100e402,    /**< The colour to use for the editable text. */
124         outlineColourId             = 0x100e403,    /**< The colour to use to draw an outline around the text area. */
125     };
126 
127     void colourChanged() override;
128 
129     //==============================================================================
130     /** Used to receive callbacks for text changes */
131     class JUCE_API Listener
132     {
133     public:
134         /** Destructor. */
135         virtual ~Listener() = default;
136 
137         /** Called when text has finished being entered (i.e. not per keypress) has changed. */
138         virtual void textPropertyComponentChanged (TextPropertyComponent*) = 0;
139     };
140 
141     /** Registers a listener to receive events when this button's state changes.
142         If the listener is already registered, this will not register it again.
143         @see removeListener
144     */
145     void addListener (Listener* newListener);
146 
147     /** Removes a previously-registered button listener
148         @see addListener
149     */
150     void removeListener (Listener* listener);
151 
152     //==============================================================================
153     /** Sets whether the text property component can have files dropped onto it by an external application.
154 
155         The default setting for this is true but you may want to disable this behaviour if you derive
156         from this class and want your subclass to respond to the file drag.
157     */
158     void setInterestedInFileDrag (bool isInterested);
159 
160     /** Sets whether the text editor is editable. The default setting for this is true. */
161     void setEditable (bool isEditable);
162 
163     //==============================================================================
164     /** @internal */
165     void refresh() override;
166     /** @internal */
167     virtual void textWasEdited();
168 
169 private:
170     class RemapperValueSourceWithDefault;
171     class LabelComp;
172     friend class LabelComp;
173 
174     //==============================================================================
175     void callListeners();
176     void createEditor (int maxNumChars, bool isEditable);
177 
178     //==============================================================================
179     bool isMultiLine;
180 
181     std::unique_ptr<LabelComp> textEditor;
182     ListenerList<Listener> listenerList;
183 
184     WeakReference<ValueWithDefault> valueWithDefault;
185 
186     //==============================================================================
187     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextPropertyComponent)
188 };
189 
190 
191 } // namespace juce
192