| @@ -34,7 +34,15 @@ | |||||
| class ComboBoxHandler : public ComponentTypeHelper<ComboBox> | class ComboBoxHandler : public ComponentTypeHelper<ComboBox> | ||||
| { | { | ||||
| public: | public: | ||||
| ComboBoxHandler() : ComponentTypeHelper<ComboBox> ("ComboBox", "COMBOBOX", "comboBox") {} | |||||
| ComboBoxHandler() : ComponentTypeHelper<ComboBox> ("ComboBox", "COMBOBOX", "comboBox") | |||||
| { | |||||
| addEditableColour (ComboBox::backgroundColourId, "Background", "backgroundColour"); | |||||
| addEditableColour (ComboBox::textColourId, "Text", "textColour"); | |||||
| addEditableColour (ComboBox::outlineColourId, "Outline", "outlineColour"); | |||||
| addEditableColour (ComboBox::buttonColourId, "Button", "buttonColour"); | |||||
| addEditableColour (ComboBox::arrowColourId, "Arrow", "arrowColour"); | |||||
| } | |||||
| ~ComboBoxHandler() {} | ~ComboBoxHandler() {} | ||||
| Component* createComponent() { return new ComboBox (String::empty); } | Component* createComponent() { return new ComboBox (String::empty); } | ||||
| @@ -50,6 +58,9 @@ public: | |||||
| 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); | |||||
| addEditableColourProperties (document, state, props); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -175,6 +175,12 @@ void ComponentTypeHandler::updateComponent (ComponentDocument& document, Compone | |||||
| comp->setBounds (pos.resolve (document)); | comp->setBounds (pos.resolve (document)); | ||||
| comp->setName (state [ComponentDocument::compNameProperty]); | comp->setName (state [ComponentDocument::compNameProperty]); | ||||
| comp->setExplicitFocusOrder (state [ComponentDocument::compFocusOrderProperty]); | |||||
| SettableTooltipClient* tooltipClient = dynamic_cast <SettableTooltipClient*> (comp); | |||||
| if (tooltipClient != 0) | |||||
| tooltipClient->setTooltip (state [ComponentDocument::compTooltipProperty]); | |||||
| } | } | ||||
| void ComponentTypeHandler::initialiseNewItem (ComponentDocument& document, ValueTree& state) | void ComponentTypeHandler::initialiseNewItem (ComponentDocument& document, ValueTree& state) | ||||
| @@ -28,6 +28,7 @@ | |||||
| #include "../../jucer_Headers.h" | #include "../../jucer_Headers.h" | ||||
| #include "../jucer_ComponentDocument.h" | #include "../jucer_ComponentDocument.h" | ||||
| #include "../../utility/jucer_ColourEditorComponent.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -92,6 +93,7 @@ template <class ComponentClass> | |||||
| class ComponentTypeHelper : public ComponentTypeHandler | class ComponentTypeHelper : public ComponentTypeHandler | ||||
| { | { | ||||
| public: | public: | ||||
| //============================================================================== | |||||
| ComponentTypeHelper (const String& name_, const String& xmlTag_, const String& memberNameRoot_) | ComponentTypeHelper (const String& name_, const String& xmlTag_, const String& memberNameRoot_) | ||||
| : ComponentTypeHandler (name_, xmlTag_, memberNameRoot_) | : ComponentTypeHandler (name_, xmlTag_, memberNameRoot_) | ||||
| { | { | ||||
| @@ -105,6 +107,7 @@ public: | |||||
| ComponentClass* const c = dynamic_cast <ComponentClass*> (comp); | ComponentClass* const c = dynamic_cast <ComponentClass*> (comp); | ||||
| jassert (c != 0); | jassert (c != 0); | ||||
| updateComponentColours (state, c); | |||||
| update (document, c, state); | update (document, c, state); | ||||
| } | } | ||||
| @@ -123,9 +126,67 @@ public: | |||||
| ComponentTypeHandler::createPropertyEditors (document, state, props); | ComponentTypeHandler::createPropertyEditors (document, state, props); | ||||
| createProperties (document, state, props); | createProperties (document, state, props); | ||||
| } | } | ||||
| }; | |||||
| protected: | |||||
| //============================================================================== | |||||
| void addTooltipProperty (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||||
| { | |||||
| props.add (new TextPropertyComponent (getValue (ComponentDocument::compTooltipProperty, state, document), | |||||
| "Tooltip", 4096, false)); | |||||
| } | |||||
| void addFocusOrderProperty (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||||
| { | |||||
| props.add (new TextPropertyComponent (Value (new IntegerValueSource (getValue (ComponentDocument::compFocusOrderProperty, | |||||
| state, document))), | |||||
| "Focus Order", 10, false)); | |||||
| } | |||||
| //============================================================================== | |||||
| struct EditableColour | |||||
| { | |||||
| int colourId; | |||||
| String name, propertyName; | |||||
| PropertyComponent* createProperty (ComponentTypeHelper& type, ComponentDocument& document, ValueTree& state) | |||||
| { | |||||
| return new ColourPropertyComponent (document, name, type.getValue (propertyName, state, document), | |||||
| LookAndFeel::getDefaultLookAndFeel().findColour (colourId), true); | |||||
| } | |||||
| void updateComponent (const ValueTree& state, Component* component) | |||||
| { | |||||
| const String colour (state [propertyName].toString()); | |||||
| if (colour.isNotEmpty()) | |||||
| component->setColour (colourId, Colour::fromString (colour)); | |||||
| else | |||||
| component->removeColour (colourId); | |||||
| } | |||||
| }; | |||||
| Array <EditableColour> editableColours; | |||||
| void addEditableColour (int colourId, const String& displayName, const String& propertyName) | |||||
| { | |||||
| EditableColour ec; | |||||
| ec.colourId = colourId; | |||||
| ec.name = displayName; | |||||
| ec.propertyName = propertyName; | |||||
| editableColours.add (ec); | |||||
| } | |||||
| void addEditableColourProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | |||||
| { | |||||
| for (int i = 0; i < editableColours.size(); ++i) | |||||
| props.add (editableColours.getReference(i).createProperty (*this, document, state)); | |||||
| } | |||||
| void updateComponentColours (const ValueTree& state, Component* component) | |||||
| { | |||||
| for (int i = 0; i < editableColours.size(); ++i) | |||||
| editableColours.getReference(i).updateComponent (state, component); | |||||
| } | |||||
| }; | |||||
| #endif // __JUCER_COMPONENTTYPEMANAGER_H_734EBF1__ | #endif // __JUCER_COMPONENTTYPEMANAGER_H_734EBF1__ | ||||
| @@ -34,7 +34,12 @@ | |||||
| class GroupComponentHandler : public ComponentTypeHelper<GroupComponent> | class GroupComponentHandler : public ComponentTypeHelper<GroupComponent> | ||||
| { | { | ||||
| public: | public: | ||||
| GroupComponentHandler() : ComponentTypeHelper<GroupComponent> ("GroupComponent", "GROUPCOMPONENT", "group") {} | |||||
| GroupComponentHandler() : ComponentTypeHelper<GroupComponent> ("GroupComponent", "GROUPCOMPONENT", "group") | |||||
| { | |||||
| addEditableColour (GroupComponent::outlineColourId, "Outline", "outlineColour"); | |||||
| addEditableColour (GroupComponent::textColourId, "Text Colour", "textColour"); | |||||
| } | |||||
| ~GroupComponentHandler() {} | ~GroupComponentHandler() {} | ||||
| Component* createComponent() { return new GroupComponent (String::empty, String::empty); } | Component* createComponent() { return new GroupComponent (String::empty, String::empty); } | ||||
| @@ -50,6 +55,7 @@ public: | |||||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | ||||
| { | { | ||||
| addEditableColourProperties (document, state, props); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -34,7 +34,13 @@ | |||||
| class LabelHandler : public ComponentTypeHelper<Label> | class LabelHandler : public ComponentTypeHelper<Label> | ||||
| { | { | ||||
| public: | public: | ||||
| LabelHandler() : ComponentTypeHelper<Label> ("Label", "LABEL", "label") {} | |||||
| LabelHandler() : ComponentTypeHelper<Label> ("Label", "LABEL", "label") | |||||
| { | |||||
| addEditableColour (Label::backgroundColourId, "Background", "backgroundColour"); | |||||
| addEditableColour (Label::textColourId, "Text Colour", "textColour"); | |||||
| addEditableColour (Label::outlineColourId, "Outline Colour", "outlineColour"); | |||||
| } | |||||
| ~LabelHandler() {} | ~LabelHandler() {} | ||||
| Component* createComponent() { return new Label (String::empty, String::empty); } | Component* createComponent() { return new Label (String::empty, String::empty); } | ||||
| @@ -52,8 +58,13 @@ public: | |||||
| 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), "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."); | ||||
| addEditableColourProperties (document, state, props); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -34,7 +34,19 @@ | |||||
| class SliderHandler : public ComponentTypeHelper<Slider> | class SliderHandler : public ComponentTypeHelper<Slider> | ||||
| { | { | ||||
| public: | public: | ||||
| SliderHandler() : ComponentTypeHelper<Slider> ("Slider", "SLIDER", "slider") {} | |||||
| SliderHandler() : ComponentTypeHelper<Slider> ("Slider", "SLIDER", "slider") | |||||
| { | |||||
| addEditableColour (Slider::backgroundColourId, "Background", "backgroundColour"); | |||||
| addEditableColour (Slider::thumbColourId, "Thumb", "thumbColour"); | |||||
| addEditableColour (Slider::trackColourId, "Track", "trackColour"); | |||||
| addEditableColour (Slider::rotarySliderFillColourId, "Rotary Fill", "rotaryFillColour"); | |||||
| addEditableColour (Slider::rotarySliderOutlineColourId, "Rotary Outline", "rotaryOutlineColour"); | |||||
| addEditableColour (Slider::textBoxTextColourId, "Text", "textColour"); | |||||
| addEditableColour (Slider::textBoxBackgroundColourId, "Text Background", "textBackgroundColour"); | |||||
| addEditableColour (Slider::textBoxHighlightColourId, "Text Highlight", "textHighlightColour"); | |||||
| addEditableColour (Slider::textBoxOutlineColourId, "Textbox Outline", "textboxOutlineColour"); | |||||
| } | |||||
| ~SliderHandler() {} | ~SliderHandler() {} | ||||
| Component* createComponent() { return new Slider (String::empty); } | Component* createComponent() { return new Slider (String::empty); } | ||||
| @@ -50,6 +62,9 @@ public: | |||||
| 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); | |||||
| addEditableColourProperties (document, state, props); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -34,7 +34,12 @@ | |||||
| class TabbedComponentHandler : public ComponentTypeHelper<TabbedComponent> | class TabbedComponentHandler : public ComponentTypeHelper<TabbedComponent> | ||||
| { | { | ||||
| public: | public: | ||||
| TabbedComponentHandler() : ComponentTypeHelper<TabbedComponent> ("TabbedComponent", "TABBEDCOMPONENT", "tabbedComponent") {} | |||||
| TabbedComponentHandler() : ComponentTypeHelper<TabbedComponent> ("TabbedComponent", "TABBEDCOMPONENT", "tabbedComponent") | |||||
| { | |||||
| addEditableColour (TabbedComponent::backgroundColourId, "Background", "backgroundColour"); | |||||
| addEditableColour (TabbedComponent::outlineColourId, "Outline", "outlineColour"); | |||||
| } | |||||
| ~TabbedComponentHandler() {} | ~TabbedComponentHandler() {} | ||||
| Component* createComponent() { return new TabbedComponent (TabbedButtonBar::TabsAtTop); } | Component* createComponent() { return new TabbedComponent (TabbedButtonBar::TabsAtTop); } | ||||
| @@ -50,6 +55,7 @@ public: | |||||
| void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | void createProperties (ComponentDocument& document, ValueTree& state, Array <PropertyComponent*>& props) | ||||
| { | { | ||||
| addEditableColourProperties (document, state, props); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -34,7 +34,12 @@ | |||||
| class TextButtonHandler : public ComponentTypeHelper<TextButton> | class TextButtonHandler : public ComponentTypeHelper<TextButton> | ||||
| { | { | ||||
| public: | public: | ||||
| TextButtonHandler() : ComponentTypeHelper<TextButton> ("TextButton", "TEXTBUTTON", "textButton") {} | |||||
| TextButtonHandler() : ComponentTypeHelper<TextButton> ("TextButton", "TEXTBUTTON", "textButton") | |||||
| { | |||||
| addEditableColour (TextButton::buttonColourId, "Background", "backgroundColour"); | |||||
| addEditableColour (TextButton::textColourOffId, "Text Colour", "textColour"); | |||||
| } | |||||
| ~TextButtonHandler() {} | ~TextButtonHandler() {} | ||||
| Component* createComponent() { return new TextButton (String::empty); } | Component* createComponent() { return new TextButton (String::empty); } | ||||
| @@ -52,9 +57,15 @@ public: | |||||
| 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), "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."); | ||||
| addEditableColourProperties (document, state, props); | |||||
| } | } | ||||
| }; | }; | ||||
| #endif | #endif | ||||
| @@ -34,7 +34,18 @@ | |||||
| class TextEditorHandler : public ComponentTypeHelper<TextEditor> | class TextEditorHandler : public ComponentTypeHelper<TextEditor> | ||||
| { | { | ||||
| public: | public: | ||||
| TextEditorHandler() : ComponentTypeHelper<TextEditor> ("TextEditor", "TEXTEDITOR", "textEditor") {} | |||||
| TextEditorHandler() : ComponentTypeHelper<TextEditor> ("TextEditor", "TEXTEDITOR", "textEditor") | |||||
| { | |||||
| addEditableColour (TextEditor::backgroundColourId, "Background", "backgroundColour"); | |||||
| addEditableColour (TextEditor::textColourId, "Text", "textColour"); | |||||
| addEditableColour (TextEditor::highlightColourId, "Highlight", "highlightColour"); | |||||
| addEditableColour (TextEditor::highlightedTextColourId, "Highlighted Text", "highlightedTextColour"); | |||||
| addEditableColour (TextEditor::caretColourId, "Caret", "caretColour"); | |||||
| addEditableColour (TextEditor::outlineColourId, "Outline", "outlineColour"); | |||||
| addEditableColour (TextEditor::focusedOutlineColourId, "Outline (focused)", "focusedOutlineColour"); | |||||
| addEditableColour (TextEditor::shadowColourId, "Shadow", "shadowColour"); | |||||
| } | |||||
| ~TextEditorHandler() {} | ~TextEditorHandler() {} | ||||
| Component* createComponent() { return new TextEditor(); } | Component* createComponent() { return new TextEditor(); } | ||||
| @@ -52,8 +63,13 @@ public: | |||||
| 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), "Text", 16384, true)); | props.add (new TextPropertyComponent (getValue ("text", state, document), "Text", 16384, true)); | ||||
| props.getLast()->setTooltip ("The editor's initial content."); | props.getLast()->setTooltip ("The editor's initial content."); | ||||
| addEditableColourProperties (document, state, props); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -34,7 +34,11 @@ | |||||
| class ToggleButtonHandler : public ComponentTypeHelper<ToggleButton> | class ToggleButtonHandler : public ComponentTypeHelper<ToggleButton> | ||||
| { | { | ||||
| public: | public: | ||||
| ToggleButtonHandler() : ComponentTypeHelper<ToggleButton> ("ToggleButton", "TOGGLEBUTTON", "toggleButton") {} | |||||
| ToggleButtonHandler() : ComponentTypeHelper<ToggleButton> ("ToggleButton", "TOGGLEBUTTON", "toggleButton") | |||||
| { | |||||
| addEditableColour (ToggleButton::textColourId, "Text Colour", "textColour"); | |||||
| } | |||||
| ~ToggleButtonHandler() {} | ~ToggleButtonHandler() {} | ||||
| Component* createComponent() { return new ToggleButton (String::empty); } | Component* createComponent() { return new ToggleButton (String::empty); } | ||||
| @@ -52,8 +56,13 @@ public: | |||||
| 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), "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."); | ||||
| addEditableColourProperties (document, state, props); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -42,6 +42,8 @@ const char* const ComponentDocument::idProperty = "id"; | |||||
| const char* const ComponentDocument::compBoundsProperty = "position"; | const char* const ComponentDocument::compBoundsProperty = "position"; | ||||
| const char* const ComponentDocument::memberNameProperty = "memberName"; | const char* const ComponentDocument::memberNameProperty = "memberName"; | ||||
| const char* const ComponentDocument::compNameProperty = "name"; | const char* const ComponentDocument::compNameProperty = "name"; | ||||
| const char* const ComponentDocument::compTooltipProperty = "tooltip"; | |||||
| const char* const ComponentDocument::compFocusOrderProperty = "focusOrder"; | |||||
| const char* const ComponentDocument::markerNameProperty = "name"; | const char* const ComponentDocument::markerNameProperty = "name"; | ||||
| const char* const ComponentDocument::markerPosProperty = "position"; | const char* const ComponentDocument::markerPosProperty = "position"; | ||||
| @@ -178,8 +180,7 @@ void ComponentDocument::writeMetadata (OutputStream& out) | |||||
| if (xml != 0) | if (xml != 0) | ||||
| xml->writeToStream (out, String::empty, false, false); | xml->writeToStream (out, String::empty, false, false); | ||||
| out << newLine | |||||
| << metadataTagEnd << newLine; | |||||
| out << newLine << metadataTagEnd; | |||||
| } | } | ||||
| bool ComponentDocument::save() | bool ComponentDocument::save() | ||||
| @@ -160,6 +160,8 @@ public: | |||||
| static const char* const compBoundsProperty; | static const char* const compBoundsProperty; | ||||
| static const char* const memberNameProperty; | static const char* const memberNameProperty; | ||||
| static const char* const compNameProperty; | static const char* const compNameProperty; | ||||
| static const char* const compTooltipProperty; | |||||
| static const char* const compFocusOrderProperty; | |||||
| static const char* const markerNameProperty; | static const char* const markerNameProperty; | ||||
| static const char* const markerPosProperty; | static const char* const markerPosProperty; | ||||
| @@ -292,6 +292,7 @@ public: | |||||
| private: | private: | ||||
| ComponentDocument document; | ComponentDocument document; | ||||
| ComponentEditorCanvas::SelectedItems selected; | ComponentEditorCanvas::SelectedItems selected; | ||||
| TooltipWindow tooltipWindow; | |||||
| }; | }; | ||||
| void ComponentEditor::test() | void ComponentEditor::test() | ||||
| @@ -33,22 +33,28 @@ | |||||
| a colour selector when you click it. | a colour selector when you click it. | ||||
| */ | */ | ||||
| class ColourEditorComponent : public Component, | class ColourEditorComponent : public Component, | ||||
| public ChangeListener | |||||
| public ChangeListener, | |||||
| public Value::Listener | |||||
| { | { | ||||
| public: | public: | ||||
| ColourEditorComponent (const bool canResetToDefault_) | |||||
| : canResetToDefault (canResetToDefault_) | |||||
| ColourEditorComponent (ComponentDocument& document_, const Value& colourValue_, | |||||
| const Colour& defaultColour_, const bool canResetToDefault_) | |||||
| : document (document_), colourValue (colourValue_), defaultColour (defaultColour_), | |||||
| canResetToDefault (canResetToDefault_) | |||||
| { | { | ||||
| colourValue.addListener (this); | |||||
| } | } | ||||
| ~ColourEditorComponent() | ~ColourEditorComponent() | ||||
| { | { | ||||
| colourValue.removeListener (this); | |||||
| } | } | ||||
| void paint (Graphics& g) | void paint (Graphics& g) | ||||
| { | { | ||||
| g.fillAll (Colours::grey); | |||||
| const Colour colour (getColour()); | |||||
| g.fillAll (Colours::grey); | |||||
| g.fillCheckerBoard (2, 2, getWidth() - 4, getHeight() - 4, | g.fillCheckerBoard (2, 2, getWidth() - 4, getHeight() - 4, | ||||
| 10, 10, | 10, 10, | ||||
| Colour (0xffdddddd).overlaidWith (colour), | Colour (0xffdddddd).overlaidWith (colour), | ||||
| @@ -61,43 +67,85 @@ public: | |||||
| Justification::centred, 1); | Justification::centred, 1); | ||||
| } | } | ||||
| virtual void setColour (const Colour& newColour) = 0; | |||||
| virtual void resetToDefault() = 0; | |||||
| virtual const Colour getColour() const = 0; | |||||
| const Colour getColour() const | |||||
| { | |||||
| if (colourValue.toString().isEmpty()) | |||||
| return defaultColour; | |||||
| return Colour::fromString (colourValue.toString()); | |||||
| } | |||||
| void setColour (const Colour& newColour) | |||||
| { | |||||
| if (getColour() != newColour) | |||||
| { | |||||
| if (newColour == defaultColour && canResetToDefault) | |||||
| colourValue = var(); | |||||
| else | |||||
| colourValue = newColour.toDisplayString (true); | |||||
| } | |||||
| } | |||||
| void resetToDefault() | |||||
| { | |||||
| setColour (defaultColour); | |||||
| } | |||||
| void refresh() | void refresh() | ||||
| { | { | ||||
| const Colour col (getColour()); | const Colour col (getColour()); | ||||
| if (col != colour) | |||||
| if (col != lastColour) | |||||
| { | { | ||||
| colour = col; | |||||
| lastColour = col; | |||||
| repaint(); | repaint(); | ||||
| } | } | ||||
| } | } | ||||
| void mouseDown (const MouseEvent& e) | void mouseDown (const MouseEvent& e) | ||||
| { | { | ||||
| ColourSelectorComp colourSelector (this, canResetToDefault); | |||||
| SafePointer<Component> deletionChecker (this); | |||||
| { | |||||
| ColourSelectorComp colourSelector (this, canResetToDefault); | |||||
| PopupMenu m; | |||||
| m.addCustomItem (1234, &colourSelector, 300, 400, false); | |||||
| m.showAt (this); | |||||
| if (deletionChecker == 0) | |||||
| return; | |||||
| } | |||||
| const Colour newColour (getColour()); | |||||
| document.getUndoManager()->undoCurrentTransactionOnly(); | |||||
| setColour (newColour); | |||||
| } | |||||
| PopupMenu m; | |||||
| m.addCustomItem (1234, &colourSelector, 300, 400, false); | |||||
| m.showAt (this); | |||||
| void valueChanged (Value&) | |||||
| { | |||||
| refresh(); | |||||
| } | } | ||||
| void changeListenerCallback (void* source) | void changeListenerCallback (void* source) | ||||
| { | { | ||||
| const ColourSelector* const cs = (const ColourSelector*) source; | |||||
| ColourSelector* cs = static_cast <ColourSelector*> (source); | |||||
| if (cs->getCurrentColour() != getColour()) | if (cs->getCurrentColour() != getColour()) | ||||
| { | |||||
| document.getUndoManager()->undoCurrentTransactionOnly(); | |||||
| setColour (cs->getCurrentColour()); | setColour (cs->getCurrentColour()); | ||||
| } | |||||
| } | } | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| Colour colour; | |||||
| bool canResetToDefault; | |||||
| ComponentDocument& document; | |||||
| Value colourValue; | |||||
| Colour lastColour; | |||||
| const Colour defaultColour; | |||||
| const bool canResetToDefault; | |||||
| class ColourSelectorComp : public Component, | class ColourSelectorComp : public Component, | ||||
| public ButtonListener | public ButtonListener | ||||
| @@ -106,36 +154,35 @@ private: | |||||
| ColourSelectorComp (ColourEditorComponent* owner_, | ColourSelectorComp (ColourEditorComponent* owner_, | ||||
| const bool canResetToDefault) | const bool canResetToDefault) | ||||
| : owner (owner_), | : owner (owner_), | ||||
| defaultButton (0) | |||||
| defaultButton ("Reset to Default") | |||||
| { | { | ||||
| addAndMakeVisible (selector = new ColourSelectorWithSwatches()); | |||||
| selector->setName ("Colour"); | |||||
| selector->setCurrentColour (owner->getColour()); | |||||
| selector->addChangeListener (owner); | |||||
| addAndMakeVisible (&selector); | |||||
| selector.setName ("Colour"); | |||||
| selector.setCurrentColour (owner->getColour()); | |||||
| selector.addChangeListener (owner); | |||||
| if (canResetToDefault) | if (canResetToDefault) | ||||
| { | { | ||||
| addAndMakeVisible (defaultButton = new TextButton ("Reset to Default")); | |||||
| defaultButton->addButtonListener (this); | |||||
| addAndMakeVisible (&defaultButton); | |||||
| defaultButton.addButtonListener (this); | |||||
| } | } | ||||
| } | } | ||||
| ~ColourSelectorComp() | ~ColourSelectorComp() | ||||
| { | { | ||||
| deleteAllChildren(); | |||||
| } | } | ||||
| void resized() | void resized() | ||||
| { | { | ||||
| if (defaultButton != 0) | |||||
| if (defaultButton.isVisible()) | |||||
| { | { | ||||
| selector->setBounds (0, 0, getWidth(), getHeight() - 30); | |||||
| defaultButton->changeWidthToFitText (22); | |||||
| defaultButton->setTopLeftPosition (10, getHeight() - 26); | |||||
| selector.setBounds (0, 0, getWidth(), getHeight() - 30); | |||||
| defaultButton.changeWidthToFitText (22); | |||||
| defaultButton.setTopLeftPosition (10, getHeight() - 26); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| selector->setBounds (0, 0, getWidth(), getHeight()); | |||||
| selector.setBounds (0, 0, getWidth(), getHeight()); | |||||
| } | } | ||||
| } | } | ||||
| @@ -143,7 +190,7 @@ private: | |||||
| { | { | ||||
| owner->resetToDefault(); | owner->resetToDefault(); | ||||
| owner->refresh(); | owner->refresh(); | ||||
| selector->setCurrentColour (owner->getColour()); | |||||
| selector.setCurrentColour (owner->getColour()); | |||||
| } | } | ||||
| private: | private: | ||||
| @@ -154,10 +201,6 @@ private: | |||||
| { | { | ||||
| } | } | ||||
| ~ColourSelectorWithSwatches() | |||||
| { | |||||
| } | |||||
| int getNumSwatches() const | int getNumSwatches() const | ||||
| { | { | ||||
| return StoredSettings::getInstance()->swatchColours.size(); | return StoredSettings::getInstance()->swatchColours.size(); | ||||
| @@ -175,10 +218,38 @@ private: | |||||
| }; | }; | ||||
| ColourEditorComponent* owner; | ColourEditorComponent* owner; | ||||
| ColourSelectorWithSwatches* selector; | |||||
| TextButton* defaultButton; | |||||
| ColourSelectorWithSwatches selector; | |||||
| TextButton defaultButton; | |||||
| }; | }; | ||||
| }; | }; | ||||
| //============================================================================== | |||||
| class ColourPropertyComponent : public PropertyComponent | |||||
| { | |||||
| public: | |||||
| //============================================================================== | |||||
| ColourPropertyComponent (ComponentDocument& document, const String& name, const Value& colour, | |||||
| const Colour& defaultColour, bool canResetToDefault) | |||||
| : PropertyComponent (name), | |||||
| colourEditor (document, colour, defaultColour, canResetToDefault) | |||||
| { | |||||
| addAndMakeVisible (&colourEditor); | |||||
| } | |||||
| ~ColourPropertyComponent() | |||||
| { | |||||
| } | |||||
| void resized() | |||||
| { | |||||
| colourEditor.setBounds (getLookAndFeel().getPropertyComponentContentPosition (*this)); | |||||
| } | |||||
| void refresh() {} | |||||
| protected: | |||||
| ColourEditorComponent colourEditor; | |||||
| }; | |||||
| #endif // __JUCER_COLOUREDITORCOMPONENT_JUCEHEADER__ | #endif // __JUCER_COLOUREDITORCOMPONENT_JUCEHEADER__ | ||||
| @@ -78,6 +78,26 @@ void StoredSettings::flush() | |||||
| // recent files... | // recent files... | ||||
| recentFiles.restoreFromString (props->getValue ("recentFiles")); | recentFiles.restoreFromString (props->getValue ("recentFiles")); | ||||
| recentFiles.removeNonExistentFiles(); | recentFiles.removeNonExistentFiles(); | ||||
| // swatch colours... | |||||
| swatchColours.clear(); | |||||
| #define COL(col) Colours::col, | |||||
| const Colour colours[] = | |||||
| { | |||||
| #include "jucer_Colours.h" | |||||
| Colours::transparentBlack | |||||
| }; | |||||
| #undef COL | |||||
| for (int i = 0; i < numSwatchColours; ++i) | |||||
| { | |||||
| Colour defaultCol (colours [2 + i]); | |||||
| swatchColours.add (Colour (props->getValue ("swatchColour" + String (i), | |||||
| hexString8Digits (defaultCol.getARGB())).getHexValue32())); | |||||
| } | |||||
| } | } | ||||
| const File StoredSettings::getLastProject() const | const File StoredSettings::getLastProject() const | ||||
| @@ -53,6 +53,8 @@ public: | |||||
| const File getLastKnownJuceFolder() const; | const File getLastKnownJuceFolder() const; | ||||
| void setLastKnownJuceFolder (const File& file); | void setLastKnownJuceFolder (const File& file); | ||||
| Array <Colour> swatchColours; | |||||
| //============================================================================== | //============================================================================== | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| @@ -108,5 +108,48 @@ protected: | |||||
| const ValueRemapperSource& operator= (const ValueRemapperSource&); | const ValueRemapperSource& operator= (const ValueRemapperSource&); | ||||
| }; | }; | ||||
| //============================================================================== | |||||
| /** | |||||
| */ | |||||
| class IntegerValueSource : public Value::ValueSource, | |||||
| public Value::Listener | |||||
| { | |||||
| public: | |||||
| IntegerValueSource (const Value& sourceValue_) | |||||
| : sourceValue (sourceValue_) | |||||
| { | |||||
| sourceValue.addListener (this); | |||||
| } | |||||
| ~IntegerValueSource() {} | |||||
| const var getValue() const | |||||
| { | |||||
| return (int) sourceValue.getValue(); | |||||
| } | |||||
| void setValue (const var& newValue) | |||||
| { | |||||
| const var newVal ((int) newValue); | |||||
| if (newVal != sourceValue) | |||||
| sourceValue = newVal; | |||||
| } | |||||
| void valueChanged (Value&) | |||||
| { | |||||
| sendChangeMessage (true); | |||||
| } | |||||
| //============================================================================== | |||||
| juce_UseDebuggingNewOperator | |||||
| protected: | |||||
| Value sourceValue; | |||||
| IntegerValueSource (const IntegerValueSource&); | |||||
| const IntegerValueSource& operator= (const IntegerValueSource&); | |||||
| }; | |||||
| #endif // __JUCER_VALUEREMAPPERSOURCE_JUCEHEADER__ | #endif // __JUCER_VALUEREMAPPERSOURCE_JUCEHEADER__ | ||||
| @@ -174,11 +174,11 @@ | |||||
| #endif | #endif | ||||
| #ifndef JUCE_ASIO | #ifndef JUCE_ASIO | ||||
| #define JUCE_ASIO 1 | |||||
| #define JUCE_ASIO 0 | |||||
| #endif | #endif | ||||
| #ifndef JUCE_WASAPI | #ifndef JUCE_WASAPI | ||||
| #define JUCE_WASAPI 1 | |||||
| #define JUCE_WASAPI 0 | |||||
| #endif | #endif | ||||
| #ifndef JUCE_DIRECTSOUND | #ifndef JUCE_DIRECTSOUND | ||||
| @@ -190,11 +190,11 @@ | |||||
| #endif | #endif | ||||
| #ifndef JUCE_JACK | #ifndef JUCE_JACK | ||||
| #define JUCE_JACK 1 | |||||
| #define JUCE_JACK 0 | |||||
| #endif | #endif | ||||
| #if ! (defined (JUCE_QUICKTIME) || JUCE_LINUX || JUCE_IPHONE || (JUCE_WINDOWS && ! JUCE_MSVC)) | #if ! (defined (JUCE_QUICKTIME) || JUCE_LINUX || JUCE_IPHONE || (JUCE_WINDOWS && ! JUCE_MSVC)) | ||||
| #define JUCE_QUICKTIME 1 | |||||
| #define JUCE_QUICKTIME 0 | |||||
| #endif | #endif | ||||
| #if (JUCE_IPHONE || JUCE_LINUX) && JUCE_QUICKTIME | #if (JUCE_IPHONE || JUCE_LINUX) && JUCE_QUICKTIME | ||||
| @@ -214,15 +214,15 @@ | |||||
| #endif | #endif | ||||
| #if (! defined (JUCE_USE_CDBURNER)) && ! (JUCE_WINDOWS && ! JUCE_MSVC) | #if (! defined (JUCE_USE_CDBURNER)) && ! (JUCE_WINDOWS && ! JUCE_MSVC) | ||||
| #define JUCE_USE_CDBURNER 1 | |||||
| #define JUCE_USE_CDBURNER 0 | |||||
| #endif | #endif | ||||
| #ifndef JUCE_USE_CDREADER | #ifndef JUCE_USE_CDREADER | ||||
| #define JUCE_USE_CDREADER 1 | |||||
| #define JUCE_USE_CDREADER 0 | |||||
| #endif | #endif | ||||
| #if (JUCE_QUICKTIME || JUCE_WINDOWS) && ! defined (JUCE_USE_CAMERA) | #if (JUCE_QUICKTIME || JUCE_WINDOWS) && ! defined (JUCE_USE_CAMERA) | ||||
| #define JUCE_USE_CAMERA 1 | |||||
| #define JUCE_USE_CAMERA 0 | |||||
| #endif | #endif | ||||
| #ifndef JUCE_ENABLE_REPAINT_DEBUGGING | #ifndef JUCE_ENABLE_REPAINT_DEBUGGING | ||||
| @@ -44260,6 +44260,11 @@ void CodeEditorComponent::loadContent (const String& newContent) | |||||
| scrollToLine (0); | scrollToLine (0); | ||||
| } | } | ||||
| bool CodeEditorComponent::isTextInputActive() const | |||||
| { | |||||
| return true; | |||||
| } | |||||
| void CodeEditorComponent::codeDocumentChanged (const CodeDocument::Position& affectedTextStart, | void CodeEditorComponent::codeDocumentChanged (const CodeDocument::Position& affectedTextStart, | ||||
| const CodeDocument::Position& affectedTextEnd) | const CodeDocument::Position& affectedTextEnd) | ||||
| { | { | ||||
| @@ -51628,6 +51633,11 @@ bool TextEditor::isReadOnly() const | |||||
| return readOnly || ! isEnabled(); | return readOnly || ! isEnabled(); | ||||
| } | } | ||||
| bool TextEditor::isTextInputActive() const | |||||
| { | |||||
| return ! isReadOnly(); | |||||
| } | |||||
| void TextEditor::setReturnKeyStartsNewLine (const bool shouldStartNewLine) | void TextEditor::setReturnKeyStartsNewLine (const bool shouldStartNewLine) | ||||
| { | { | ||||
| returnKeyStartsNewLine = shouldStartNewLine; | returnKeyStartsNewLine = shouldStartNewLine; | ||||
| @@ -69646,7 +69656,8 @@ public: | |||||
| MouseInputSourceInternal (MouseInputSource& source_, const int index_, const bool isMouseDevice_) | MouseInputSourceInternal (MouseInputSource& source_, const int index_, const bool isMouseDevice_) | ||||
| : index (index_), isMouseDevice (isMouseDevice_), source (source_), lastPeer (0), lastTime (0), | : index (index_), isMouseDevice (isMouseDevice_), source (source_), lastPeer (0), lastTime (0), | ||||
| isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false), currentCursorHandle (0) | |||||
| isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false), currentCursorHandle (0), | |||||
| mouseEventCounter (0) | |||||
| { | { | ||||
| zerostruct (mouseDowns); | zerostruct (mouseDowns); | ||||
| } | } | ||||
| @@ -69742,42 +69753,47 @@ public: | |||||
| comp->internalMouseWheel (source, comp->globalPositionToRelative (screenPos), time, x, y); | comp->internalMouseWheel (source, comp->globalPositionToRelative (screenPos), time, x, y); | ||||
| } | } | ||||
| void setButtons (const Point<int>& screenPos, const int64 time, const ModifierKeys& newButtonState) | |||||
| // (returns true if the button change caused a modal event loop) | |||||
| bool setButtons (const Point<int>& screenPos, const int64 time, const ModifierKeys& newButtonState) | |||||
| { | { | ||||
| if (buttonState != newButtonState) | |||||
| if (buttonState == newButtonState) | |||||
| return false; | |||||
| // (ignore secondary clicks when there's already a button down) | |||||
| if (buttonState.isAnyMouseButtonDown() == newButtonState.isAnyMouseButtonDown()) | |||||
| { | { | ||||
| // (ignore secondary clicks when there's already a button down) | |||||
| if (buttonState.isAnyMouseButtonDown() == newButtonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| buttonState = newButtonState; | |||||
| return; | |||||
| } | |||||
| buttonState = newButtonState; | |||||
| return false; | |||||
| } | |||||
| if (buttonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| Component* const current = getComponentUnderMouse(); | |||||
| const int lastCounter = mouseEventCounter; | |||||
| if (current != 0) | |||||
| sendMouseUp (current, screenPos + unboundedMouseOffset, time); | |||||
| if (buttonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| Component* const current = getComponentUnderMouse(); | |||||
| enableUnboundedMouseMovement (false, false); | |||||
| } | |||||
| if (current != 0) | |||||
| sendMouseUp (current, screenPos + unboundedMouseOffset, time); | |||||
| buttonState = newButtonState; | |||||
| enableUnboundedMouseMovement (false, false); | |||||
| } | |||||
| if (buttonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| Desktop::getInstance().incrementMouseClickCounter(); | |||||
| buttonState = newButtonState; | |||||
| Component* const current = getComponentUnderMouse(); | |||||
| if (buttonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| Desktop::getInstance().incrementMouseClickCounter(); | |||||
| if (current != 0) | |||||
| { | |||||
| registerMouseDown (screenPos, time, current); | |||||
| sendMouseDown (current, screenPos, time); | |||||
| } | |||||
| Component* const current = getComponentUnderMouse(); | |||||
| if (current != 0) | |||||
| { | |||||
| registerMouseDown (screenPos, time, current); | |||||
| sendMouseDown (current, screenPos, time); | |||||
| } | } | ||||
| } | } | ||||
| return lastCounter != mouseEventCounter; | |||||
| } | } | ||||
| void setComponentUnderMouse (Component* const newComponent, const Point<int>& screenPos, const int64 time) | void setComponentUnderMouse (Component* const newComponent, const Point<int>& screenPos, const int64 time) | ||||
| @@ -69855,6 +69871,7 @@ public: | |||||
| { | { | ||||
| jassert (newPeer != 0); | jassert (newPeer != 0); | ||||
| lastTime = time; | lastTime = time; | ||||
| ++mouseEventCounter; | |||||
| const Point<int> screenPos (newPeer->relativePositionToGlobal (positionWithinPeer)); | const Point<int> screenPos (newPeer->relativePositionToGlobal (positionWithinPeer)); | ||||
| if (isDragging() && newMods.isAnyMouseButtonDown()) | if (isDragging() && newMods.isAnyMouseButtonDown()) | ||||
| @@ -69868,11 +69885,12 @@ public: | |||||
| ComponentPeer* peer = getPeer(); | ComponentPeer* peer = getPeer(); | ||||
| if (peer != 0) | if (peer != 0) | ||||
| { | { | ||||
| setButtons (screenPos, time, newMods); | |||||
| if (setButtons (screenPos, time, newMods)) | |||||
| return; // some modal events have been dispatched, so the current event is now out-of-date | |||||
| peer = getPeer(); | peer = getPeer(); | ||||
| if (peer != 0) | if (peer != 0) | ||||
| setScreenPos (peer->relativePositionToGlobal (positionWithinPeer), time, false); | |||||
| setScreenPos (screenPos, time, false); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -69881,6 +69899,7 @@ public: | |||||
| { | { | ||||
| jassert (peer != 0); | jassert (peer != 0); | ||||
| lastTime = time; | lastTime = time; | ||||
| ++mouseEventCounter; | |||||
| const Point<int> screenPos (peer->relativePositionToGlobal (positionWithinPeer)); | const Point<int> screenPos (peer->relativePositionToGlobal (positionWithinPeer)); | ||||
| setPeer (peer, screenPos, time); | setPeer (peer, screenPos, time); | ||||
| @@ -70036,6 +70055,7 @@ private: | |||||
| Point<int> unboundedMouseOffset; | Point<int> unboundedMouseOffset; | ||||
| bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen; | bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen; | ||||
| void* currentCursorHandle; | void* currentCursorHandle; | ||||
| int mouseEventCounter; | |||||
| struct RecentMouseDown | struct RecentMouseDown | ||||
| { | { | ||||
| @@ -75919,7 +75939,11 @@ TextInputTarget* ComponentPeer::findCurrentTextInputTarget() | |||||
| { | { | ||||
| Component* const c = Component::getCurrentlyFocusedComponent(); | Component* const c = Component::getCurrentlyFocusedComponent(); | ||||
| if (component->isParentOf (c)) | if (component->isParentOf (c)) | ||||
| return dynamic_cast <TextInputTarget*> (c); | |||||
| { | |||||
| TextInputTarget* const ti = dynamic_cast <TextInputTarget*> (c); | |||||
| if (ti != 0 && ti->isTextInputActive()) | |||||
| return ti; | |||||
| } | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -233523,10 +233547,10 @@ public: | |||||
| return true; | return true; | ||||
| } | } | ||||
| bool write (AudioSampleBuffer& outputChannels, const int numSamples) | |||||
| bool write (AudioSampleBuffer& outputChannelBuffer, const int numSamples) | |||||
| { | { | ||||
| jassert (numChannelsRunning <= outputChannels.getNumChannels()); | |||||
| float** const data = outputChannels.getArrayOfChannels(); | |||||
| jassert (numChannelsRunning <= outputChannelBuffer.getNumChannels()); | |||||
| float** const data = outputChannelBuffer.getArrayOfChannels(); | |||||
| if (isInterleaved) | if (isInterleaved) | ||||
| { | { | ||||
| @@ -233564,10 +233588,10 @@ public: | |||||
| return true; | return true; | ||||
| } | } | ||||
| bool read (AudioSampleBuffer& inputChannels, const int numSamples) | |||||
| bool read (AudioSampleBuffer& inputChannelBuffer, const int numSamples) | |||||
| { | { | ||||
| jassert (numChannelsRunning <= inputChannels.getNumChannels()); | |||||
| float** const data = inputChannels.getArrayOfChannels(); | |||||
| jassert (numChannelsRunning <= inputChannelBuffer.getNumChannels()); | |||||
| float** const data = inputChannelBuffer.getArrayOfChannels(); | |||||
| if (isInterleaved) | if (isInterleaved) | ||||
| { | { | ||||
| @@ -233642,8 +233666,8 @@ public: | |||||
| outputDevice (0), | outputDevice (0), | ||||
| inputDevice (0), | inputDevice (0), | ||||
| numCallbacks (0), | numCallbacks (0), | ||||
| inputChannels (1, 1), | |||||
| outputChannels (1, 1) | |||||
| inputChannelBuffer (1, 1), | |||||
| outputChannelBuffer (1, 1) | |||||
| { | { | ||||
| initialiseRatesAndChannels(); | initialiseRatesAndChannels(); | ||||
| } | } | ||||
| @@ -233664,8 +233688,8 @@ public: | |||||
| sampleRate = sampleRate_; | sampleRate = sampleRate_; | ||||
| bufferSize = bufferSize_; | bufferSize = bufferSize_; | ||||
| inputChannels.setSize (jmax ((int) minChansIn, inputChannels.getHighestBit()) + 1, bufferSize); | |||||
| inputChannels.clear(); | |||||
| inputChannelBuffer.setSize (jmax ((int) minChansIn, inputChannels.getHighestBit()) + 1, bufferSize); | |||||
| inputChannelBuffer.clear(); | |||||
| inputChannelDataForCallback.clear(); | inputChannelDataForCallback.clear(); | ||||
| currentInputChans.clear(); | currentInputChans.clear(); | ||||
| @@ -233675,14 +233699,14 @@ public: | |||||
| { | { | ||||
| if (inputChannels[i]) | if (inputChannels[i]) | ||||
| { | { | ||||
| inputChannelDataForCallback.add (inputChannels.getSampleData (i)); | |||||
| inputChannelDataForCallback.add (inputChannelBuffer.getSampleData (i)); | |||||
| currentInputChans.setBit (i); | currentInputChans.setBit (i); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| outputChannels.setSize (jmax ((int) minChansOut, outputChannels.getHighestBit()) + 1, bufferSize); | |||||
| outputChannels.clear(); | |||||
| outputChannelBuffer.setSize (jmax ((int) minChansOut, outputChannels.getHighestBit()) + 1, bufferSize); | |||||
| outputChannelBuffer.clear(); | |||||
| outputChannelDataForCallback.clear(); | outputChannelDataForCallback.clear(); | ||||
| currentOutputChans.clear(); | currentOutputChans.clear(); | ||||
| @@ -233692,7 +233716,7 @@ public: | |||||
| { | { | ||||
| if (outputChannels[i]) | if (outputChannels[i]) | ||||
| { | { | ||||
| outputChannelDataForCallback.add (outputChannels.getSampleData (i)); | |||||
| outputChannelDataForCallback.add (outputChannelBuffer.getSampleData (i)); | |||||
| currentOutputChans.setBit (i); | currentOutputChans.setBit (i); | ||||
| } | } | ||||
| } | } | ||||
| @@ -233784,8 +233808,8 @@ public: | |||||
| deleteAndZero (inputDevice); | deleteAndZero (inputDevice); | ||||
| deleteAndZero (outputDevice); | deleteAndZero (outputDevice); | ||||
| inputChannels.setSize (1, 1); | |||||
| outputChannels.setSize (1, 1); | |||||
| inputChannelBuffer.setSize (1, 1); | |||||
| outputChannelBuffer.setSize (1, 1); | |||||
| numCallbacks = 0; | numCallbacks = 0; | ||||
| } | } | ||||
| @@ -233802,7 +233826,7 @@ public: | |||||
| { | { | ||||
| if (inputDevice != 0) | if (inputDevice != 0) | ||||
| { | { | ||||
| if (! inputDevice->read (inputChannels, bufferSize)) | |||||
| if (! inputDevice->read (inputChannelBuffer, bufferSize)) | |||||
| { | { | ||||
| DBG ("ALSA: read failure"); | DBG ("ALSA: read failure"); | ||||
| break; | break; | ||||
| @@ -233826,7 +233850,7 @@ public: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| for (int i = 0; i < totalNumOutputChannels; ++i) | |||||
| for (int i = 0; i < outputChannelDataForCallback.size(); ++i) | |||||
| zeromem (outputChannelDataForCallback[i], sizeof (float) * bufferSize); | zeromem (outputChannelDataForCallback[i], sizeof (float) * bufferSize); | ||||
| } | } | ||||
| } | } | ||||
| @@ -233840,7 +233864,7 @@ public: | |||||
| failed (snd_pcm_avail_update (outputDevice->handle)); | failed (snd_pcm_avail_update (outputDevice->handle)); | ||||
| if (! outputDevice->write (outputChannelData, bufferSize)) | |||||
| if (! outputDevice->write (outputChannelBuffer, bufferSize)) | |||||
| { | { | ||||
| DBG ("ALSA: write failure"); | DBG ("ALSA: write failure"); | ||||
| break; | break; | ||||
| @@ -233880,7 +233904,7 @@ private: | |||||
| CriticalSection callbackLock; | CriticalSection callbackLock; | ||||
| AudioSampleBuffer inputChannels, outputChannels; | |||||
| AudioSampleBuffer inputChannelBuffer, outputChannelBuffer; | |||||
| Array<float*> inputChannelDataForCallback, outputChannelDataForCallback; | Array<float*> inputChannelDataForCallback, outputChannelDataForCallback; | ||||
| unsigned int minChansOut, maxChansOut; | unsigned int minChansOut, maxChansOut; | ||||
| @@ -43,7 +43,7 @@ | |||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
| #define JUCE_BUILDNUMBER 0 | |||||
| #define JUCE_BUILDNUMBER 1 | |||||
| #define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8) + JUCE_BUILDNUMBER) | #define JUCE_VERSION ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8) + JUCE_BUILDNUMBER) | ||||
| @@ -195,11 +195,11 @@ | |||||
| #endif | #endif | ||||
| #ifndef JUCE_ASIO | #ifndef JUCE_ASIO | ||||
| #define JUCE_ASIO 1 | |||||
| #define JUCE_ASIO 0 | |||||
| #endif | #endif | ||||
| #ifndef JUCE_WASAPI | #ifndef JUCE_WASAPI | ||||
| #define JUCE_WASAPI 1 | |||||
| #define JUCE_WASAPI 0 | |||||
| #endif | #endif | ||||
| #ifndef JUCE_DIRECTSOUND | #ifndef JUCE_DIRECTSOUND | ||||
| @@ -211,11 +211,11 @@ | |||||
| #endif | #endif | ||||
| #ifndef JUCE_JACK | #ifndef JUCE_JACK | ||||
| #define JUCE_JACK 1 | |||||
| #define JUCE_JACK 0 | |||||
| #endif | #endif | ||||
| #if ! (defined (JUCE_QUICKTIME) || JUCE_LINUX || JUCE_IPHONE || (JUCE_WINDOWS && ! JUCE_MSVC)) | #if ! (defined (JUCE_QUICKTIME) || JUCE_LINUX || JUCE_IPHONE || (JUCE_WINDOWS && ! JUCE_MSVC)) | ||||
| #define JUCE_QUICKTIME 1 | |||||
| #define JUCE_QUICKTIME 0 | |||||
| #endif | #endif | ||||
| #if (JUCE_IPHONE || JUCE_LINUX) && JUCE_QUICKTIME | #if (JUCE_IPHONE || JUCE_LINUX) && JUCE_QUICKTIME | ||||
| @@ -235,15 +235,15 @@ | |||||
| #endif | #endif | ||||
| #if (! defined (JUCE_USE_CDBURNER)) && ! (JUCE_WINDOWS && ! JUCE_MSVC) | #if (! defined (JUCE_USE_CDBURNER)) && ! (JUCE_WINDOWS && ! JUCE_MSVC) | ||||
| #define JUCE_USE_CDBURNER 1 | |||||
| #define JUCE_USE_CDBURNER 0 | |||||
| #endif | #endif | ||||
| #ifndef JUCE_USE_CDREADER | #ifndef JUCE_USE_CDREADER | ||||
| #define JUCE_USE_CDREADER 1 | |||||
| #define JUCE_USE_CDREADER 0 | |||||
| #endif | #endif | ||||
| #if (JUCE_QUICKTIME || JUCE_WINDOWS) && ! defined (JUCE_USE_CAMERA) | #if (JUCE_QUICKTIME || JUCE_WINDOWS) && ! defined (JUCE_USE_CAMERA) | ||||
| #define JUCE_USE_CAMERA 1 | |||||
| #define JUCE_USE_CAMERA 0 | |||||
| #endif | #endif | ||||
| #ifndef JUCE_ENABLE_REPAINT_DEBUGGING | #ifndef JUCE_ENABLE_REPAINT_DEBUGGING | ||||
| @@ -3594,6 +3594,11 @@ public: | |||||
| : static_cast <ObjectClass*> (0); | : static_cast <ObjectClass*> (0); | ||||
| } | } | ||||
| inline ObjectClass** getRawDataPointer() throw() | |||||
| { | |||||
| return data.elements; | |||||
| } | |||||
| int indexOf (const ObjectClass* const objectToLookFor) const throw() | int indexOf (const ObjectClass* const objectToLookFor) const throw() | ||||
| { | { | ||||
| const ScopedLockType lock (getLock()); | const ScopedLockType lock (getLock()); | ||||
| @@ -12411,7 +12416,7 @@ public: | |||||
| int getNumRectangles() const throw() { return rects.size(); } | int getNumRectangles() const throw() { return rects.size(); } | ||||
| const Rectangle<int> getRectangle (const int index) const throw(); | |||||
| const Rectangle<int> getRectangle (int index) const throw(); | |||||
| void clear(); | void clear(); | ||||
| @@ -16719,6 +16724,8 @@ public: | |||||
| virtual ~TextInputTarget() {} | virtual ~TextInputTarget() {} | ||||
| virtual bool isTextInputActive() const = 0; | |||||
| virtual const Range<int> getHighlightedRegion() const = 0; | virtual const Range<int> getHighlightedRegion() const = 0; | ||||
| virtual void setHighlightedRegion (const Range<int>& newRange) = 0; | virtual void setHighlightedRegion (const Range<int>& newRange) = 0; | ||||
| @@ -16907,6 +16914,7 @@ public: | |||||
| void resized(); | void resized(); | ||||
| void enablementChanged(); | void enablementChanged(); | ||||
| void colourChanged(); | void colourChanged(); | ||||
| bool isTextInputActive() const; | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| @@ -21226,6 +21234,7 @@ public: | |||||
| void handleAsyncUpdate(); | void handleAsyncUpdate(); | ||||
| void codeDocumentChanged (const CodeDocument::Position& affectedTextStart, | void codeDocumentChanged (const CodeDocument::Position& affectedTextStart, | ||||
| const CodeDocument::Position& affectedTextEnd); | const CodeDocument::Position& affectedTextEnd); | ||||
| bool isTextInputActive() const; | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
| #define JUCE_BUILDNUMBER 0 | |||||
| #define JUCE_BUILDNUMBER 1 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -42,7 +42,8 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| MouseInputSourceInternal (MouseInputSource& source_, const int index_, const bool isMouseDevice_) | MouseInputSourceInternal (MouseInputSource& source_, const int index_, const bool isMouseDevice_) | ||||
| : index (index_), isMouseDevice (isMouseDevice_), source (source_), lastPeer (0), lastTime (0), | : index (index_), isMouseDevice (isMouseDevice_), source (source_), lastPeer (0), lastTime (0), | ||||
| isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false), currentCursorHandle (0) | |||||
| isUnboundedMouseModeOn (false), isCursorVisibleUntilOffscreen (false), currentCursorHandle (0), | |||||
| mouseEventCounter (0) | |||||
| { | { | ||||
| zerostruct (mouseDowns); | zerostruct (mouseDowns); | ||||
| } | } | ||||
| @@ -141,42 +142,47 @@ public: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void setButtons (const Point<int>& screenPos, const int64 time, const ModifierKeys& newButtonState) | |||||
| // (returns true if the button change caused a modal event loop) | |||||
| bool setButtons (const Point<int>& screenPos, const int64 time, const ModifierKeys& newButtonState) | |||||
| { | { | ||||
| if (buttonState != newButtonState) | |||||
| if (buttonState == newButtonState) | |||||
| return false; | |||||
| // (ignore secondary clicks when there's already a button down) | |||||
| if (buttonState.isAnyMouseButtonDown() == newButtonState.isAnyMouseButtonDown()) | |||||
| { | { | ||||
| // (ignore secondary clicks when there's already a button down) | |||||
| if (buttonState.isAnyMouseButtonDown() == newButtonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| buttonState = newButtonState; | |||||
| return; | |||||
| } | |||||
| buttonState = newButtonState; | |||||
| return false; | |||||
| } | |||||
| if (buttonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| Component* const current = getComponentUnderMouse(); | |||||
| const int lastCounter = mouseEventCounter; | |||||
| if (current != 0) | |||||
| sendMouseUp (current, screenPos + unboundedMouseOffset, time); | |||||
| if (buttonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| Component* const current = getComponentUnderMouse(); | |||||
| enableUnboundedMouseMovement (false, false); | |||||
| } | |||||
| if (current != 0) | |||||
| sendMouseUp (current, screenPos + unboundedMouseOffset, time); | |||||
| buttonState = newButtonState; | |||||
| enableUnboundedMouseMovement (false, false); | |||||
| } | |||||
| if (buttonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| Desktop::getInstance().incrementMouseClickCounter(); | |||||
| buttonState = newButtonState; | |||||
| Component* const current = getComponentUnderMouse(); | |||||
| if (buttonState.isAnyMouseButtonDown()) | |||||
| { | |||||
| Desktop::getInstance().incrementMouseClickCounter(); | |||||
| if (current != 0) | |||||
| { | |||||
| registerMouseDown (screenPos, time, current); | |||||
| sendMouseDown (current, screenPos, time); | |||||
| } | |||||
| Component* const current = getComponentUnderMouse(); | |||||
| if (current != 0) | |||||
| { | |||||
| registerMouseDown (screenPos, time, current); | |||||
| sendMouseDown (current, screenPos, time); | |||||
| } | } | ||||
| } | } | ||||
| return lastCounter != mouseEventCounter; | |||||
| } | } | ||||
| void setComponentUnderMouse (Component* const newComponent, const Point<int>& screenPos, const int64 time) | void setComponentUnderMouse (Component* const newComponent, const Point<int>& screenPos, const int64 time) | ||||
| @@ -255,6 +261,7 @@ public: | |||||
| { | { | ||||
| jassert (newPeer != 0); | jassert (newPeer != 0); | ||||
| lastTime = time; | lastTime = time; | ||||
| ++mouseEventCounter; | |||||
| const Point<int> screenPos (newPeer->relativePositionToGlobal (positionWithinPeer)); | const Point<int> screenPos (newPeer->relativePositionToGlobal (positionWithinPeer)); | ||||
| if (isDragging() && newMods.isAnyMouseButtonDown()) | if (isDragging() && newMods.isAnyMouseButtonDown()) | ||||
| @@ -268,11 +275,12 @@ public: | |||||
| ComponentPeer* peer = getPeer(); | ComponentPeer* peer = getPeer(); | ||||
| if (peer != 0) | if (peer != 0) | ||||
| { | { | ||||
| setButtons (screenPos, time, newMods); | |||||
| if (setButtons (screenPos, time, newMods)) | |||||
| return; // some modal events have been dispatched, so the current event is now out-of-date | |||||
| peer = getPeer(); | peer = getPeer(); | ||||
| if (peer != 0) | if (peer != 0) | ||||
| setScreenPos (peer->relativePositionToGlobal (positionWithinPeer), time, false); | |||||
| setScreenPos (screenPos, time, false); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -281,6 +289,7 @@ public: | |||||
| { | { | ||||
| jassert (peer != 0); | jassert (peer != 0); | ||||
| lastTime = time; | lastTime = time; | ||||
| ++mouseEventCounter; | |||||
| const Point<int> screenPos (peer->relativePositionToGlobal (positionWithinPeer)); | const Point<int> screenPos (peer->relativePositionToGlobal (positionWithinPeer)); | ||||
| setPeer (peer, screenPos, time); | setPeer (peer, screenPos, time); | ||||
| @@ -441,6 +450,7 @@ private: | |||||
| Point<int> unboundedMouseOffset; | Point<int> unboundedMouseOffset; | ||||
| bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen; | bool isUnboundedMouseModeOn, isCursorVisibleUntilOffscreen; | ||||
| void* currentCursorHandle; | void* currentCursorHandle; | ||||
| int mouseEventCounter; | |||||
| struct RecentMouseDown | struct RecentMouseDown | ||||
| { | { | ||||
| @@ -71,7 +71,7 @@ public: | |||||
| @returns the rectangle at the index, or an empty rectangle if the | @returns the rectangle at the index, or an empty rectangle if the | ||||
| index is out-of-range. | index is out-of-range. | ||||
| */ | */ | ||||
| const Rectangle<int> getRectangle (const int index) const throw(); | |||||
| const Rectangle<int> getRectangle (int index) const throw(); | |||||
| //============================================================================== | //============================================================================== | ||||