diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_JucerComponent.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_JucerComponent.h index a9a1151fdd..d9ba66110d 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_JucerComponent.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_JucerComponent.h @@ -35,16 +35,22 @@ class JucerComponent : public Component public: JucerComponent() { + addAndMakeVisible (comp = new ComponentDocument::TestComponent (0, File::nonexistent)); } - void paint (Graphics& g) + void resized() { - g.setColour (Colours::grey); - g.drawRect (getLocalBounds()); - - g.drawLine (0.5f, 0.5f, getWidth() - 0.5f, getHeight() - 0.5f); - g.drawLine (0.5f, getHeight() - 0.5f, getWidth() - 0.5f, 0.5f); + comp->setBounds (getLocalBounds()); } + + void setJucerComp (ComponentDocument& document, const File& cppFile) + { + addAndMakeVisible (comp = new ComponentDocument::TestComponent (document.getProject(), cppFile)); + resized(); + } + +private: + ScopedPointer comp; }; //============================================================================== diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h index 7b65d013ab..f89a4d499d 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Label.h @@ -71,17 +71,7 @@ public: props.add (new TextPropertyComponent (getValue ("text", state, document), "Text", 16384, true)); props.getLast()->setTooltip ("The label's text."); - const char* const layouts[] = { "Centred", "Centred-left", "Centred-right", "Centred-top", "Centred-bottom", "Top-left", - "Top-right", "Bottom-left", "Bottom-right", 0 }; - const int justifications[] = { Justification::centred, Justification::centredLeft, Justification::centredRight, - Justification::centredTop, Justification::centredBottom, Justification::topLeft, - Justification::topRight, Justification::bottomLeft, Justification::bottomRight, 0 }; - - ValueRemapperSource* remapper = new ValueRemapperSource (state.getPropertyAsValue ("justification", document.getUndoManager())); - for (int i = 0; i < numElementsInArray (justifications) - 1; ++i) - remapper->addMapping (justifications[i], i + 1); - - props.add (new ChoicePropertyComponent (Value (remapper), "Layout", StringArray (layouts))); + props.add (createJustificationProperty ("Layout", state.getPropertyAsValue ("justification", document.getUndoManager()), false)); const char* const editModes[] = { "Read-only", "Edit on Single-Click", "Edit on Double-Click", 0 }; props.add (new ChoicePropertyComponent (state.getPropertyAsValue ("editMode", document.getUndoManager()), diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Slider.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Slider.h index dcba56a069..ab5c255260 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Slider.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Slider.h @@ -52,18 +52,50 @@ public: Component* createComponent() { return new Slider (String::empty); } const Rectangle getDefaultSize() { return Rectangle (0, 0, 200, 24); } - void update (ComponentDocument& document, Slider* comp, const ValueTree& state) - { - } - void initialiseNew (ComponentDocument& document, ValueTree& state) { + state.setProperty ("min", 0, 0); + state.setProperty ("max", 100, 0); + state.setProperty ("interval", 1, 0); + state.setProperty ("type", 1 + Slider::LinearHorizontal, 0); + state.setProperty ("textBoxPos", 2, 0); + state.setProperty ("editable", true, 0); + state.setProperty ("textBoxWidth", 80, 0); + state.setProperty ("textBoxHeight", 20, 0); + state.setProperty ("skew", 1, 0); + } + + void update (ComponentDocument& document, Slider* comp, const ValueTree& state) + { + comp->setRange ((double) state ["min"], (double) state ["max"], (double) state ["interval"]); + comp->setSliderStyle ((Slider::SliderStyle) ((int) state ["type"] - 1)); + comp->setTextBoxStyle ((Slider::TextEntryBoxPosition) ((int) state ["textBoxPos"] - 1), + ! (bool) state ["editable"], + (int) state ["textBoxWidth"], (int) state ["textBoxHeight"]); + comp->setSkewFactor ((double) state ["skew"]); } void createProperties (ComponentDocument& document, ValueTree& state, Array & props) { addTooltipProperty (document, state, props); addFocusOrderProperty (document, state, props); + + props.add (new TextPropertyComponent (Value (new NumericValueSource (getValue ("min", state, document))), "Minimum", 16, false)); + props.add (new TextPropertyComponent (Value (new NumericValueSource (getValue ("max", state, document))), "Maximum", 16, false)); + props.add (new TextPropertyComponent (Value (new NumericValueSource (getValue ("interval", state, document))), "Interval", 16, false)); + + const char* const types[] = { "LinearHorizontal", "LinearVertical", "LinearBar", "Rotary", "RotaryHorizontalDrag", "RotaryVerticalDrag", + "IncDecButtons", "TwoValueHorizontal", "TwoValueVertical", "ThreeValueHorizontal", "ThreeValueVertical", 0 }; + props.add (new ChoicePropertyComponent (state.getPropertyAsValue ("type", document.getUndoManager()), "Type", StringArray (types))); + + const char* const textBoxPositions[] = { "NoTextBox", "TextBoxLeft", "TextBoxRight", "TextBoxAbove", "TextBoxBelow", 0 }; + props.add (new ChoicePropertyComponent (state.getPropertyAsValue ("textBoxPos", document.getUndoManager()), "Text Box", StringArray (textBoxPositions))); + + props.add (new BooleanPropertyComponent (getValue ("editable", state, document), "Editable", "Value can be edited")); + props.add (new TextPropertyComponent (Value (new NumericValueSource (getValue ("textBoxWidth", state, document))), "Text Box Width", 8, false)); + props.add (new TextPropertyComponent (Value (new NumericValueSource (getValue ("textBoxHeight", state, document))), "Text Box Height", 8, false)); + + props.add (new TextPropertyComponent (Value (new NumericValueSource (getValue ("skew", state, document))), "Skew Factor", 16, false)); addEditableColourProperties (document, state, props); } }; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextButton.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextButton.h index db2c9bb23d..56789799f8 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextButton.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextButton.h @@ -45,20 +45,6 @@ public: Component* createComponent() { return new TextButton (String::empty); } const Rectangle getDefaultSize() { return Rectangle (0, 0, 150, 24); } - void update (ComponentDocument& document, TextButton* comp, const ValueTree& state) - { - comp->setButtonText (state ["text"].toString()); - comp->setRadioGroupId (state ["radioGroup"]); - - int connected = 0; - if (state ["connectedLeft"]) connected |= TextButton::ConnectedOnLeft; - if (state ["connectedRight"]) connected |= TextButton::ConnectedOnRight; - if (state ["connectedTop"]) connected |= TextButton::ConnectedOnTop; - if (state ["connectedBottom"]) connected |= TextButton::ConnectedOnBottom; - - comp->setConnectedEdges (connected); - } - void initialiseNew (ComponentDocument& document, ValueTree& state) { state.setProperty ("text", "New Button", 0); @@ -69,6 +55,20 @@ public: state.setProperty ("connectedBottom", false, 0); } + void update (ComponentDocument& document, TextButton* comp, const ValueTree& state) + { + comp->setButtonText (state ["text"].toString()); + comp->setRadioGroupId (state ["radioGroup"]); + + int connected = 0; + if (state ["connectedLeft"]) connected |= TextButton::ConnectedOnLeft; + if (state ["connectedRight"]) connected |= TextButton::ConnectedOnRight; + if (state ["connectedTop"]) connected |= TextButton::ConnectedOnTop; + if (state ["connectedBottom"]) connected |= TextButton::ConnectedOnBottom; + + comp->setConnectedEdges (connected); + } + void createProperties (ComponentDocument& document, ValueTree& state, Array & props) { addTooltipProperty (document, state, props); @@ -77,7 +77,7 @@ public: props.add (new TextPropertyComponent (getValue ("text", state, document), "Button Text", 1024, false)); props.getLast()->setTooltip ("The button's text."); - props.add (new TextPropertyComponent (Value (new IntegerValueSource (getValue ("radioGroup", state, document))), "Radio Group", 8, false)); + props.add (new TextPropertyComponent (Value (new NumericValueSource (getValue ("radioGroup", state, document))), "Radio Group", 8, false)); props.getLast()->setTooltip ("The radio group that this button is a member of."); props.add (new BooleanPropertyComponent (getValue ("connectedLeft", state, document), "Connected left", "Connected")); diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextEditor.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextEditor.h index 9c1bd43c6b..b16be843e4 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextEditor.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_TextEditor.h @@ -51,14 +51,26 @@ public: Component* createComponent() { return new TextEditor(); } const Rectangle getDefaultSize() { return Rectangle (0, 0, 180, 24); } - void update (ComponentDocument& document, TextEditor* comp, const ValueTree& state) - { - comp->setText (state ["text"].toString()); - } - void initialiseNew (ComponentDocument& document, ValueTree& state) { state.setProperty ("text", "Text Editor Content", 0); + state.setProperty ("readOnly", false, 0); + state.setProperty ("scrollbarsShown", true, 0); + state.setProperty ("caretVisible", true, 0); + state.setProperty ("popupMenuEnabled", true, 0); + state.setProperty ("mode", 1, 0); + } + + void update (ComponentDocument& document, TextEditor* comp, const ValueTree& state) + { + comp->setReadOnly (state["readOnly"]); + comp->setScrollbarsShown (state ["scrollbarsShown"]); + comp->setCaretVisible (state ["caretVisible"]); + comp->setPopupMenuEnabled (state ["popupMenuEnabled"]); + int mode = state ["mode"]; + comp->setMultiLine (mode > 1, true); + comp->setReturnKeyStartsNewLine (mode != 3); + comp->setText (state ["text"].toString()); } void createProperties (ComponentDocument& document, ValueTree& state, Array & props) @@ -69,6 +81,14 @@ public: props.add (new TextPropertyComponent (getValue ("text", state, document), "Text", 16384, true)); props.getLast()->setTooltip ("The editor's initial content."); + const char* const modes[] = { "Single-Line", "Multi-Line (Return key starts new line)", "Multi-Line (Return key disabled)", 0 }; + props.add (new ChoicePropertyComponent (getValue ("mode", state, document), "Mode", StringArray (modes))); + + props.add (new BooleanPropertyComponent (getValue ("readOnly", state, document), "Read-Only", "Read-Only")); + props.add (new BooleanPropertyComponent (getValue ("scrollbarsShown", state, document), "Scrollbars", "Scrollbars Shown")); + props.add (new BooleanPropertyComponent (getValue ("caretVisible", state, document), "Caret", "Caret Visible")); + props.add (new BooleanPropertyComponent (getValue ("popupMenuEnabled", state, document), "Popup Menu", "Popup Menu Enabled")); + addEditableColourProperties (document, state, props); } }; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ToggleButton.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ToggleButton.h index 0d063f6cb6..7482c1a09f 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ToggleButton.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ToggleButton.h @@ -44,14 +44,16 @@ public: Component* createComponent() { return new ToggleButton (String::empty); } const Rectangle getDefaultSize() { return Rectangle (0, 0, 180, 24); } - void update (ComponentDocument& document, ToggleButton* comp, const ValueTree& state) - { - comp->setButtonText (state ["text"].toString()); - } - void initialiseNew (ComponentDocument& document, ValueTree& state) { state.setProperty ("text", "New Toggle Button", 0); + state.setProperty ("initialState", false, 0); + } + + void update (ComponentDocument& document, ToggleButton* comp, const ValueTree& state) + { + comp->setButtonText (state ["text"].toString()); + comp->setToggleState (state ["initialState"], false); } void createProperties (ComponentDocument& document, ValueTree& state, Array & props) @@ -62,6 +64,8 @@ public: props.add (new TextPropertyComponent (getValue ("text", state, document), "Button Text", 1024, false)); props.getLast()->setTooltip ("The button's text."); + props.add (new BooleanPropertyComponent (getValue ("initialState", state, document), "Initial State", "Enabled initially")); + addEditableColourProperties (document, state, props); } }; diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Viewport.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Viewport.h index 0efcb68aef..d3b4f4ca02 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Viewport.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_Viewport.h @@ -37,19 +37,47 @@ public: ViewportHandler() : ComponentTypeHelper ("Viewport", "VIEWPORT", "viewport") {} ~ViewportHandler() {} - Component* createComponent() { return new Viewport(); } - const Rectangle getDefaultSize() { return Rectangle (0, 0, 300, 200); } - - void update (ComponentDocument& document, Viewport* comp, const ValueTree& state) + class DemoContentComponent : public Component { + public: + DemoContentComponent() { setSize (1000, 1000); } + ~DemoContentComponent() {} + + void paint (Graphics& g) + { + g.fillCheckerBoard (0, 0, getWidth(), getHeight(), 40, 40, + Colours::grey.withAlpha (0.7f), + Colours::white.withAlpha (0.7f)); + } + }; + + Component* createComponent() + { + Viewport* v = new Viewport(); + v->setViewedComponent (new DemoContentComponent()); + return v; } + const Rectangle getDefaultSize() { return Rectangle (0, 0, 300, 200); } + void initialiseNew (ComponentDocument& document, ValueTree& state) { + state.setProperty ("scrollBarV", true, 0); + state.setProperty ("scrollBarH", true, 0); + state.setProperty ("scrollbarWidth", 18, 0); + } + + void update (ComponentDocument& document, Viewport* comp, const ValueTree& state) + { + comp->setScrollBarsShown (state ["scrollBarV"], state ["scrollBarH"]); + comp->setScrollBarThickness (state ["scrollbarWidth"]); } void createProperties (ComponentDocument& document, ValueTree& state, Array & props) { + props.add (new BooleanPropertyComponent (getValue ("scrollBarV", state, document), "Scrollbar V", "Vertical scrollbar shown")); + props.add (new BooleanPropertyComponent (getValue ("scrollBarH", state, document), "Scrollbar H", "Horizontal scrollbar shown")); + props.add (new SliderPropertyComponent (getValue ("scrollbarWidth", state, document), "Scrollbar Thickness", 3, 40, 1)); } }; diff --git a/extras/Jucer (experimental)/Source/ui/jucer_OpenDocumentManager.cpp b/extras/Jucer (experimental)/Source/ui/jucer_OpenDocumentManager.cpp index 8e213c4edc..491c8ff9b0 100644 --- a/extras/Jucer (experimental)/Source/ui/jucer_OpenDocumentManager.cpp +++ b/extras/Jucer (experimental)/Source/ui/jucer_OpenDocumentManager.cpp @@ -74,7 +74,11 @@ public: return false; out = 0; - return temp.overwriteTargetFileWithTemporary(); + if (! temp.overwriteTargetFileWithTemporary()) + return false; + + modDetector.updateHash(); + return true; } Component* createEditor() @@ -141,7 +145,13 @@ public: bool save() { - return componentDoc->save(); + if (componentDoc->save()) + { + modDetector.updateHash(); + return true; + } + + return false; } Component* createEditor() @@ -202,7 +212,13 @@ public: bool save() { - return drawableDoc->save (modDetector.getFile()); + if (drawableDoc->save (modDetector.getFile())) + { + modDetector.updateHash(); + return true; + } + + return false; } Component* createEditor() diff --git a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp b/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp index 5286487bd8..69ae1f9ebd 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp +++ b/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.cpp @@ -351,27 +351,8 @@ const String makeValidCppIdentifier (String s, if (CharacterFunctions::isDigit (n[0])) n = "_" + n; - // make sure it's not a reserved c++ keyword.. - static const char* const reservedWords[] = - { - "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) - if (n == reservedWords[i]) - n << '_'; + if (CPlusPlusCodeTokeniser::isReservedKeyword (n)) + n << '_'; return n; } @@ -387,6 +368,20 @@ void autoScrollForMouseEvent (const MouseEvent& e) } } +void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text) +{ + g.fillAll (Colours::white.withAlpha (0.4f)); + g.setColour (Colours::grey); + g.drawRect (0, 0, w, h); + + g.drawLine (0.5f, 0.5f, w - 0.5f, h - 0.5f); + g.drawLine (0.5f, h - 0.5f, w - 0.5f, 0.5f); + + g.setColour (Colours::black); + g.setFont (11.0f); + g.drawFittedText (text, 2, 2, w - 4, h - 4, Justification::centredTop, 2); +} + //============================================================================== const String floatToCode (const float v) { @@ -740,3 +735,35 @@ void createFontProperties (Array & props, const ValueTree& s props.add (StringListValueSource::create ("Font Style", state.getPropertyAsValue (fontStyle, undoManager), StringArray (fontStyles))); } + +PropertyComponent* createJustificationProperty (const String& name, const Value& value, bool onlyHorizontal) +{ + ValueRemapperSource* remapper = new ValueRemapperSource (value); + StringArray strings; + + if (onlyHorizontal) + { + const char* const layouts[] = { "Left", "Centred", "Right", 0 }; + const int justifications[] = { Justification::left, Justification::centred, Justification::right, 0 }; + + for (int i = 0; i < numElementsInArray (justifications) - 1; ++i) + remapper->addMapping (justifications[i], i + 1); + + strings = StringArray (layouts); + } + else + { + const char* const layouts[] = { "Centred", "Centred-left", "Centred-right", "Centred-top", "Centred-bottom", "Top-left", + "Top-right", "Bottom-left", "Bottom-right", 0 }; + const int justifications[] = { Justification::centred, Justification::centredLeft, Justification::centredRight, + Justification::centredTop, Justification::centredBottom, Justification::topLeft, + Justification::topRight, Justification::bottomLeft, Justification::bottomRight, 0 }; + + for (int i = 0; i < numElementsInArray (justifications) - 1; ++i) + remapper->addMapping (justifications[i], i + 1); + + strings = StringArray (layouts); + } + + return new ChoicePropertyComponent (Value (remapper), name, strings); +} diff --git a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h b/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h index e95241b77f..66a3c5cfc3 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h +++ b/extras/Jucer (experimental)/Source/utility/jucer_UtilityFunctions.h @@ -80,6 +80,8 @@ int indexOfLineStartingWith (const StringArray& lines, const String& text, int s void autoScrollForMouseEvent (const MouseEvent& e); +void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text); + //============================================================================== const Font getFontFromState (const ValueTree& state, const var::identifier& fontName, @@ -92,6 +94,8 @@ void createFontProperties (Array & props, const ValueTree& s const var::identifier& fontStyle, UndoManager* undoManager); +PropertyComponent* createJustificationProperty (const String& name, const Value& value, bool onlyHorizontal); + //============================================================================== class FileModificationDetector { diff --git a/extras/Jucer (experimental)/Source/utility/jucer_ValueRemapperSource.h b/extras/Jucer (experimental)/Source/utility/jucer_ValueRemapperSource.h index 47916584f0..9480b40ab8 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_ValueRemapperSource.h +++ b/extras/Jucer (experimental)/Source/utility/jucer_ValueRemapperSource.h @@ -153,44 +153,38 @@ protected: //============================================================================== /** */ -class IntegerValueSource : public Value::ValueSource, +template +class NumericValueSource : public Value::ValueSource, public Value::Listener { public: - IntegerValueSource (const Value& sourceValue_) + NumericValueSource (const Value& sourceValue_) : sourceValue (sourceValue_) { sourceValue.addListener (this); } - ~IntegerValueSource() {} + ~NumericValueSource() {} - const var getValue() const - { - return (int) sourceValue.getValue(); - } + void valueChanged (Value&) { sendChangeMessage (true); } + const var getValue() const { return (Type) sourceValue.getValue(); } void setValue (const var& newValue) { - const int newVal = (int) newValue; + const Type newVal = (Type) newValue; - if (newVal != (int) getValue()) // this test is important, because if a property is missing, it won't + if (newVal != (Type) getValue()) // this test is important, because if a property is missing, it won't sourceValue = newVal; // create it (causing an unwanted undo action) when a control sets it to 0 } - void valueChanged (Value&) - { - sendChangeMessage (true); - } - //============================================================================== juce_UseDebuggingNewOperator protected: Value sourceValue; - IntegerValueSource (const IntegerValueSource&); - const IntegerValueSource& operator= (const IntegerValueSource&); + NumericValueSource (const NumericValueSource&); + const NumericValueSource& operator= (const NumericValueSource&); };