mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-04 03:40:07 +00:00
ResizableBorderComponent fix. Jucer development.
This commit is contained in:
parent
cc5f0a50b9
commit
00ac238956
13 changed files with 433 additions and 88 deletions
|
|
@ -58,6 +58,8 @@
|
|||
D9FB1A5365FEEB854A0FF7BF = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = System/Library/Frameworks/QuickTime.framework; sourceTree = SDKROOT; };
|
||||
12E1601866B3489844AFD645 = { isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Jucer.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F4C5CF1AA7EB9298043D89D3 = { isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Info.plist; sourceTree = SOURCE_ROOT; };
|
||||
A6FAA90B494DCD7CA5911196 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ToggleButton.h; path = "../../Source/model/Component Types/jucer_ToggleButton.h"; sourceTree = SOURCE_ROOT; };
|
||||
E18C99BDD4EF3DFD767F3770 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_TextButton.h; path = "../../Source/model/Component Types/jucer_TextButton.h"; sourceTree = SOURCE_ROOT; };
|
||||
2D6D6985B452EA0B67A18914 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_ComponentDocument.cpp; path = ../../Source/model/jucer_ComponentDocument.cpp; sourceTree = SOURCE_ROOT; };
|
||||
E6CC3A04349F6B227FDAB26F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ComponentDocument.h; path = ../../Source/model/jucer_ComponentDocument.h; sourceTree = SOURCE_ROOT; };
|
||||
FF625CB50FB5C3536BA40604 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_DrawableDocument.cpp; path = ../../Source/model/jucer_DrawableDocument.cpp; sourceTree = SOURCE_ROOT; };
|
||||
|
|
@ -135,7 +137,11 @@
|
|||
DD6476FF0F8BE833CD54C01F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = JuceLibraryCode2.mm; path = ../../JuceLibraryCode/JuceLibraryCode2.mm; sourceTree = SOURCE_ROOT; };
|
||||
268B4FFB1C675B679138545F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = JuceLibraryCode3.mm; path = ../../JuceLibraryCode/JuceLibraryCode3.mm; sourceTree = SOURCE_ROOT; };
|
||||
60A217F62952DE8A752BD79F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = JuceLibraryCode4.mm; path = ../../JuceLibraryCode/JuceLibraryCode4.mm; sourceTree = SOURCE_ROOT; };
|
||||
D3D6EC2C17524688F2E803EB = { isa = PBXGroup; children = (
|
||||
A6FAA90B494DCD7CA5911196,
|
||||
E18C99BDD4EF3DFD767F3770 ); name = "Component Types"; sourceTree = "<group>"; };
|
||||
BF6238C9155879B9A9C47213 = { isa = PBXGroup; children = (
|
||||
D3D6EC2C17524688F2E803EB,
|
||||
2D6D6985B452EA0B67A18914,
|
||||
E6CC3A04349F6B227FDAB26F,
|
||||
FF625CB50FB5C3536BA40604,
|
||||
|
|
|
|||
|
|
@ -133,6 +133,10 @@
|
|||
<Files>
|
||||
<Filter Name="The Jucer">
|
||||
<Filter Name="Model">
|
||||
<Filter Name="Component Types">
|
||||
<File RelativePath="..\..\Source\model\Component Types\jucer_ToggleButton.h"/>
|
||||
<File RelativePath="..\..\Source\model\Component Types\jucer_TextButton.h"/>
|
||||
</Filter>
|
||||
<File RelativePath="..\..\Source\model\jucer_ComponentDocument.cpp"/>
|
||||
<File RelativePath="..\..\Source\model\jucer_ComponentDocument.h"/>
|
||||
<File RelativePath="..\..\Source\model\jucer_DrawableDocument.cpp"/>
|
||||
|
|
|
|||
|
|
@ -133,6 +133,10 @@
|
|||
<Files>
|
||||
<Filter Name="The Jucer">
|
||||
<Filter Name="Model">
|
||||
<Filter Name="Component Types">
|
||||
<File RelativePath="..\..\Source\model\Component Types\jucer_ToggleButton.h"/>
|
||||
<File RelativePath="..\..\Source\model\Component Types\jucer_TextButton.h"/>
|
||||
</Filter>
|
||||
<File RelativePath="..\..\Source\model\jucer_ComponentDocument.cpp"/>
|
||||
<File RelativePath="..\..\Source\model\jucer_ComponentDocument.h"/>
|
||||
<File RelativePath="..\..\Source\model\jucer_DrawableDocument.cpp"/>
|
||||
|
|
|
|||
|
|
@ -27,6 +27,12 @@
|
|||
</CONFIGURATIONS>
|
||||
<MAINGROUP name="The Jucer" id="NhrJq66R">
|
||||
<GROUP id="EmpOiUg6" name="Model">
|
||||
<GROUP id="7IAOlGP0H" name="Component Types">
|
||||
<FILE id="EOwXntvc" name="jucer_ToggleButton.h" compile="0" resource="0"
|
||||
file="Source/model/Component Types/jucer_ToggleButton.h"/>
|
||||
<FILE id="lO2yuwiGR" name="jucer_TextButton.h" compile="0" resource="0"
|
||||
file="Source/model/Component Types/jucer_TextButton.h"/>
|
||||
</GROUP>
|
||||
<FILE id="e6IQOUwvq" name="jucer_ComponentDocument.cpp" compile="1"
|
||||
resource="0" file="Source/model/jucer_ComponentDocument.cpp"/>
|
||||
<FILE id="u5n6JTb4z" name="jucer_ComponentDocument.h" compile="0" resource="0"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-9 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online 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.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "jucer_ComponentDocument.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class TextButtonHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
TextButtonHandler() : ComponentTypeHandler ("TextButton", "TEXTBUTTON", "textButton") {}
|
||||
~TextButtonHandler() {}
|
||||
|
||||
Component* createComponent() { return new TextButton (String::empty); }
|
||||
const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 150, 24); }
|
||||
|
||||
void updateComponent (Component* comp, const ValueTree& state)
|
||||
{
|
||||
TextButton* tb = dynamic_cast <TextButton*> (comp);
|
||||
jassert (tb != 0);
|
||||
|
||||
ComponentTypeHandler::updateComponent (comp, state);
|
||||
tb->setButtonText (state ["text"].toString());
|
||||
}
|
||||
|
||||
const ValueTree createNewItem (ComponentDocument& document)
|
||||
{
|
||||
ValueTree v (ComponentTypeHandler::createNewItem (document));
|
||||
v.setProperty ("text", "New Toggle Button", 0);
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
||||
Copyright 2004-9 by Raw Material Software Ltd.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
JUCE can be redistributed and/or modified under the terms of the GNU General
|
||||
Public License (Version 2), as published by the Free Software Foundation.
|
||||
A copy of the license is included in the JUCE distribution, or can be found
|
||||
online 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.rawmaterialsoftware.com/juce for more information.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#include "jucer_ComponentDocument.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ToggleButtonHandler : public ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
ToggleButtonHandler() : ComponentTypeHandler ("ToggleButton", "TOGGLEBUTTON", "toggleButton") {}
|
||||
~ToggleButtonHandler() {}
|
||||
|
||||
Component* createComponent() { return new ToggleButton (String::empty); }
|
||||
const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 180, 24); }
|
||||
|
||||
void updateComponent (Component* comp, const ValueTree& state)
|
||||
{
|
||||
ToggleButton* tb = dynamic_cast <ToggleButton*> (comp);
|
||||
jassert (tb != 0);
|
||||
|
||||
ComponentTypeHandler::updateComponent (comp, state);
|
||||
tb->setButtonText (state ["text"].toString());
|
||||
}
|
||||
|
||||
const ValueTree createNewItem (ComponentDocument& document)
|
||||
{
|
||||
ValueTree v (ComponentTypeHandler::createNewItem (document));
|
||||
v.setProperty ("text", "New Toggle Button", 0);
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
|
@ -24,6 +24,8 @@
|
|||
*/
|
||||
|
||||
#include "jucer_ComponentDocument.h"
|
||||
#include "Component Types/jucer_TextButton.h"
|
||||
#include "Component Types/jucer_ToggleButton.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -32,6 +34,11 @@ static const char* const componentGroupTag = "COMPONENTS";
|
|||
|
||||
static const char* const idProperty = "id";
|
||||
static const char* const compBoundsProperty = "position";
|
||||
static const char* const memberNameProperty = "memberName";
|
||||
static const char* const compNameProperty = "name";
|
||||
|
||||
static const char* const metadataTagStart = "JUCER_" "COMPONENT_METADATA_START"; // written like this to avoid thinking this file is a component!
|
||||
static const char* const metadataTagEnd = "JUCER_" "COMPONENT_METADATA_END";
|
||||
|
||||
//==============================================================================
|
||||
static const String componentBoundsToString (const Rectangle<int>& bounds)
|
||||
|
|
@ -45,66 +52,35 @@ static const Rectangle<int> stringToComponentBounds (const String& s)
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
class ComponentTypeHandler
|
||||
ComponentTypeHandler::ComponentTypeHandler (const String& name_, const String& xmlTag_,
|
||||
const String& memberNameRoot_)
|
||||
: name (name_), xmlTag (xmlTag_),
|
||||
memberNameRoot (memberNameRoot_)
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
ComponentTypeHandler (const String& name_, const String& tag_)
|
||||
: name (name_), tag (tag_)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~ComponentTypeHandler()
|
||||
{
|
||||
}
|
||||
|
||||
const String& getName() const { return name; }
|
||||
const String& getTag() const { return tag; }
|
||||
|
||||
virtual Component* createComponent() = 0;
|
||||
virtual const Rectangle<int> getDefaultSize() = 0;
|
||||
|
||||
virtual void updateComponent (Component* comp, const ValueTree& state)
|
||||
{
|
||||
comp->setBounds (stringToComponentBounds (state [compBoundsProperty]));
|
||||
}
|
||||
|
||||
virtual const ValueTree createNewItem()
|
||||
{
|
||||
ValueTree v (tag);
|
||||
v.setProperty (idProperty, createAlphaNumericUID(), 0);
|
||||
v.setProperty (compBoundsProperty,
|
||||
componentBoundsToString (getDefaultSize().withPosition (Point<int> (Random::getSystemRandom().nextInt (100) + 100,
|
||||
Random::getSystemRandom().nextInt (100) + 100))), 0);
|
||||
return v;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
protected:
|
||||
const String name, tag;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class TextButtonHandler : public ComponentTypeHandler
|
||||
ComponentTypeHandler::~ComponentTypeHandler()
|
||||
{
|
||||
public:
|
||||
TextButtonHandler() : ComponentTypeHandler ("TextButton", "TEXTBUTTON") {}
|
||||
~TextButtonHandler() {}
|
||||
}
|
||||
|
||||
Component* createComponent() { return new TextButton (String::empty); }
|
||||
const Rectangle<int> getDefaultSize() { return Rectangle<int> (0, 0, 150, 24); }
|
||||
void ComponentTypeHandler::updateComponent (Component* comp, const ValueTree& state)
|
||||
{
|
||||
comp->setBounds (stringToComponentBounds (state [compBoundsProperty]));
|
||||
comp->setName (state [compNameProperty]);
|
||||
}
|
||||
|
||||
void updateComponent (Component* comp, const ValueTree& state)
|
||||
{
|
||||
ComponentTypeHandler::updateComponent (comp, state);
|
||||
}
|
||||
const ValueTree ComponentTypeHandler::createNewItem (ComponentDocument& document)
|
||||
{
|
||||
ValueTree v (getXmlTag());
|
||||
v.setProperty (idProperty, createAlphaNumericUID(), 0);
|
||||
v.setProperty (compNameProperty, String::empty, 0);
|
||||
v.setProperty (memberNameProperty, document.getNonExistentMemberName (getMemberNameRoot()), 0);
|
||||
v.setProperty (compBoundsProperty,
|
||||
componentBoundsToString (getDefaultSize().withPosition (Point<int> (Random::getSystemRandom().nextInt (100) + 100,
|
||||
Random::getSystemRandom().nextInt (100) + 100))), 0);
|
||||
return v;
|
||||
}
|
||||
|
||||
const ValueTree createNewItem()
|
||||
{
|
||||
ValueTree v (ComponentTypeHandler::createNewItem());
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
class ComponentTypeManager : public DeletedAtShutdown
|
||||
|
|
@ -113,6 +89,7 @@ public:
|
|||
ComponentTypeManager()
|
||||
{
|
||||
handlers.add (new TextButtonHandler());
|
||||
handlers.add (new ToggleButtonHandler());
|
||||
}
|
||||
|
||||
~ComponentTypeManager()
|
||||
|
|
@ -137,7 +114,7 @@ public:
|
|||
ComponentTypeHandler* getHandlerFor (const String& type)
|
||||
{
|
||||
for (int i = handlers.size(); --i >= 0;)
|
||||
if (handlers.getUnchecked(i)->getTag() == type)
|
||||
if (handlers.getUnchecked(i)->getXmlTag() == type)
|
||||
return handlers.getUnchecked(i);
|
||||
|
||||
return 0;
|
||||
|
|
@ -164,13 +141,38 @@ juce_ImplementSingleton_SingleThreaded (ComponentTypeManager);
|
|||
|
||||
//==============================================================================
|
||||
ComponentDocument::ComponentDocument (Project* project_, const File& cppFile_)
|
||||
: project (project_), cppFile (cppFile_), root (componentDocumentTag)
|
||||
: project (project_), cppFile (cppFile_), root (componentDocumentTag),
|
||||
changedSinceSaved (false)
|
||||
{
|
||||
reload();
|
||||
checkRootObject();
|
||||
|
||||
root.addListener (this);
|
||||
}
|
||||
|
||||
ComponentDocument::~ComponentDocument()
|
||||
{
|
||||
root.removeListener (this);
|
||||
}
|
||||
|
||||
void ComponentDocument::beginNewTransaction()
|
||||
{
|
||||
undoManager.beginNewTransaction();
|
||||
}
|
||||
|
||||
void ComponentDocument::valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property)
|
||||
{
|
||||
changedSinceSaved = true;
|
||||
}
|
||||
|
||||
void ComponentDocument::valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged)
|
||||
{
|
||||
changedSinceSaved = true;
|
||||
}
|
||||
|
||||
void ComponentDocument::valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged)
|
||||
{
|
||||
changedSinceSaved = true;
|
||||
}
|
||||
|
||||
bool ComponentDocument::isComponentFile (const File& file)
|
||||
|
|
@ -178,39 +180,118 @@ bool ComponentDocument::isComponentFile (const File& file)
|
|||
if (! file.hasFileExtension (".cpp"))
|
||||
return false;
|
||||
|
||||
ScopedPointer <InputStream> in (file.createInputStream());
|
||||
InputStream* in = file.createInputStream();
|
||||
|
||||
if (in == 0)
|
||||
return false;
|
||||
if (in != 0)
|
||||
{
|
||||
BufferedInputStream buf (in, 8192, true);
|
||||
|
||||
const int amountToRead = 1024;
|
||||
HeapBlock <char> initialData;
|
||||
initialData.calloc (amountToRead + 4);
|
||||
in->read (initialData, amountToRead);
|
||||
while (! buf.isExhausted())
|
||||
if (buf.readNextLine().contains (metadataTagStart))
|
||||
return true;
|
||||
}
|
||||
|
||||
return String::createStringFromData (initialData, amountToRead)
|
||||
.contains ("JUCER_" "COMPONENT"); // written like this to avoid thinking this file is a component!
|
||||
return false;
|
||||
}
|
||||
|
||||
void ComponentDocument::writeCode (OutputStream& cpp, OutputStream& header)
|
||||
{
|
||||
cpp << "/** */"
|
||||
<< newLine << newLine;
|
||||
|
||||
header << "/** */"
|
||||
<< newLine << newLine;
|
||||
}
|
||||
|
||||
void ComponentDocument::writeMetadata (OutputStream& out)
|
||||
{
|
||||
out << "#if 0" << newLine
|
||||
<< "/** Jucer-generated metadata section - Edit this data at own risk!" << newLine
|
||||
<< metadataTagStart << newLine << newLine;
|
||||
|
||||
ScopedPointer<XmlElement> xml (root.createXml());
|
||||
jassert (xml != 0);
|
||||
|
||||
if (xml != 0)
|
||||
xml->writeToStream (out, String::empty, false, false);
|
||||
|
||||
out << newLine
|
||||
<< metadataTagEnd << " */" << newLine
|
||||
<< "#endif" << newLine;
|
||||
}
|
||||
|
||||
bool ComponentDocument::save()
|
||||
{
|
||||
MemoryOutputStream cpp, header;
|
||||
writeCode (cpp, header);
|
||||
writeMetadata (cpp);
|
||||
|
||||
//XXX
|
||||
return false;
|
||||
bool savedOk = overwriteFileWithNewDataIfDifferent (cppFile, cpp)
|
||||
&& overwriteFileWithNewDataIfDifferent (cppFile.withFileExtension (".h"), header);
|
||||
|
||||
if (savedOk)
|
||||
changedSinceSaved = false;
|
||||
|
||||
return savedOk;
|
||||
}
|
||||
|
||||
bool ComponentDocument::reload()
|
||||
{
|
||||
String xmlString;
|
||||
|
||||
//XXX
|
||||
return true;
|
||||
{
|
||||
InputStream* in = cppFile.createInputStream();
|
||||
|
||||
if (in == 0)
|
||||
return false;
|
||||
|
||||
BufferedInputStream buf (in, 8192, true);
|
||||
String::Concatenator xml (xmlString);
|
||||
|
||||
while (! buf.isExhausted())
|
||||
{
|
||||
String line (buf.readNextLine());
|
||||
|
||||
if (line.contains (metadataTagStart))
|
||||
{
|
||||
while (! buf.isExhausted())
|
||||
{
|
||||
line = buf.readNextLine();
|
||||
if (line.contains (metadataTagEnd))
|
||||
break;
|
||||
|
||||
xml.append (line);
|
||||
xml.append (newLine);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XmlDocument doc (xmlString);
|
||||
ScopedPointer<XmlElement> xml (doc.getDocumentElement());
|
||||
|
||||
if (xml != 0 && xml->hasTagName (componentDocumentTag))
|
||||
{
|
||||
ValueTree newTree (ValueTree::fromXml (*xml));
|
||||
|
||||
if (newTree.isValid())
|
||||
{
|
||||
root = newTree;
|
||||
checkRootObject();
|
||||
undoManager.clearUndoHistory();
|
||||
changedSinceSaved = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ComponentDocument::hasChangedSinceLastSave()
|
||||
{
|
||||
|
||||
//XXX
|
||||
return false;
|
||||
return changedSinceSaved;
|
||||
}
|
||||
|
||||
void ComponentDocument::checkRootObject()
|
||||
|
|
@ -219,6 +300,9 @@ void ComponentDocument::checkRootObject()
|
|||
|
||||
if (! getComponentGroup().isValid())
|
||||
root.addChild (ValueTree (componentGroupTag), -1, 0);
|
||||
|
||||
if (getClassName().toString().isEmpty())
|
||||
getClassName() = "NewComponent";
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -242,7 +326,7 @@ void ComponentDocument::performNewComponentMenuItem (int menuResultCode)
|
|||
jassert (handler != 0);
|
||||
|
||||
if (handler != 0)
|
||||
getComponentGroup().addChild (handler->createNewItem(), -1, getUndoManager());
|
||||
getComponentGroup().addChild (handler->createNewItem (*this), -1, getUndoManager());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -262,6 +346,20 @@ const ValueTree ComponentDocument::getComponent (int index) const
|
|||
return getComponentGroup().getChild (index);
|
||||
}
|
||||
|
||||
const ValueTree ComponentDocument::getComponentWithMemberName (const String& name) const
|
||||
{
|
||||
const ValueTree comps (getComponentGroup());
|
||||
|
||||
for (int i = comps.getNumChildren(); --i >= 0;)
|
||||
{
|
||||
const ValueTree v (comps.getChild(i));
|
||||
if (v [memberNameProperty] == name)
|
||||
return v;
|
||||
}
|
||||
|
||||
return ValueTree::invalid;
|
||||
}
|
||||
|
||||
Component* ComponentDocument::createComponent (int index) const
|
||||
{
|
||||
const ValueTree v (getComponentGroup().getChild (index));
|
||||
|
|
@ -322,6 +420,24 @@ bool ComponentDocument::isStateForComponent (const ValueTree& storedState, Compo
|
|||
return storedState [idProperty] == comp->getProperties() [idProperty];
|
||||
}
|
||||
|
||||
const String ComponentDocument::getNonExistentMemberName (String suggestedName)
|
||||
{
|
||||
suggestedName = makeValidCppIdentifier (suggestedName, false, true, false);
|
||||
const String original (suggestedName);
|
||||
int num = 1;
|
||||
|
||||
while (getComponentWithMemberName (suggestedName).isValid())
|
||||
{
|
||||
suggestedName = original;
|
||||
while (String ("0123456789").containsChar (suggestedName.getLastCharacter()))
|
||||
suggestedName = suggestedName.dropLastCharacters (1);
|
||||
|
||||
suggestedName << num++;
|
||||
}
|
||||
|
||||
return suggestedName;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class ComponentDocument::DragHandler
|
||||
{
|
||||
|
|
@ -340,14 +456,19 @@ public:
|
|||
draggedComponents.add (v);
|
||||
originalPositions.add (stringToComponentBounds (v [compBoundsProperty]));
|
||||
}
|
||||
|
||||
document.beginNewTransaction();
|
||||
}
|
||||
|
||||
~DragHandler()
|
||||
{
|
||||
document.beginNewTransaction();
|
||||
}
|
||||
|
||||
void drag (const MouseEvent& e)
|
||||
{
|
||||
document.getUndoManager()->undoCurrentTransactionOnly();
|
||||
|
||||
for (int i = 0; i < draggedComponents.size(); ++i)
|
||||
move (draggedComponents.getReference(i), e.getOffsetFromDragStart(), originalPositions.getReference(i));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
|
||||
//==============================================================================
|
||||
class ComponentDocument
|
||||
class ComponentDocument : public ValueTree::Listener
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
|
|
@ -46,9 +46,15 @@ public:
|
|||
|
||||
typedef SelectedItemSet<uint32> SelectedItems;
|
||||
|
||||
//==============================================================================
|
||||
Value getClassName() { return getRootValue ("className"); }
|
||||
Value getClassDescription() { return getRootValue ("classDesc"); }
|
||||
const String getNonExistentMemberName (String suggestedName);
|
||||
|
||||
//==============================================================================
|
||||
int getNumComponents() const;
|
||||
const ValueTree getComponent (int index) const;
|
||||
const ValueTree getComponentWithMemberName (const String& name) const;
|
||||
Component* createComponent (int index) const;
|
||||
void updateComponent (Component* comp) const;
|
||||
bool containsComponent (Component* comp) const;
|
||||
|
|
@ -59,14 +65,6 @@ public:
|
|||
void performNewComponentMenuItem (int menuResultCode);
|
||||
|
||||
//==============================================================================
|
||||
enum ResizeZones
|
||||
{
|
||||
zoneL = 1,
|
||||
zoneR = 2,
|
||||
zoneT = 4,
|
||||
zoneB = 8
|
||||
};
|
||||
|
||||
void beginDrag (const Array<Component*>& items, const MouseEvent& e,
|
||||
const ResizableBorderComponent::Zone& zone);
|
||||
void continueDrag (const MouseEvent& e);
|
||||
|
|
@ -75,18 +73,52 @@ public:
|
|||
//==============================================================================
|
||||
ValueTree& getRoot() { return root; }
|
||||
UndoManager* getUndoManager() throw() { return &undoManager; }
|
||||
void beginNewTransaction();
|
||||
|
||||
void valueTreePropertyChanged (ValueTree& treeWhosePropertyHasChanged, const var::identifier& property);
|
||||
void valueTreeChildrenChanged (ValueTree& treeWhoseChildHasChanged);
|
||||
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged);
|
||||
|
||||
private:
|
||||
Project* project;
|
||||
File cppFile;
|
||||
ValueTree root;
|
||||
UndoManager undoManager;
|
||||
bool changedSinceSaved;
|
||||
|
||||
class DragHandler;
|
||||
ScopedPointer <DragHandler> dragger;
|
||||
|
||||
void checkRootObject();
|
||||
ValueTree getComponentGroup() const;
|
||||
Value getRootValue (const var::identifier& name) { return root.getPropertyAsValue (name, getUndoManager()); }
|
||||
|
||||
void writeCode (OutputStream& cpp, OutputStream& header);
|
||||
void writeMetadata (OutputStream& out);
|
||||
};
|
||||
|
||||
|
||||
//==============================================================================
|
||||
class ComponentTypeHandler
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
ComponentTypeHandler (const String& name_, const String& xmlTag_, const String& memberNameRoot_);
|
||||
virtual ~ComponentTypeHandler();
|
||||
|
||||
const String& getName() const { return name; }
|
||||
const String& getXmlTag() const { return xmlTag; }
|
||||
const String& getMemberNameRoot() const { return memberNameRoot; }
|
||||
|
||||
virtual Component* createComponent() = 0;
|
||||
virtual const Rectangle<int> getDefaultSize() = 0;
|
||||
|
||||
virtual void updateComponent (Component* comp, const ValueTree& state);
|
||||
virtual const ValueTree createNewItem (ComponentDocument& document);
|
||||
|
||||
//==============================================================================
|
||||
protected:
|
||||
const String name, xmlTag, memberNameRoot;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -466,3 +466,57 @@ void ComponentEditor::resized()
|
|||
{
|
||||
viewport->setBounds (0, 0, getWidth(), getHeight());
|
||||
}
|
||||
|
||||
void ComponentEditor::getAllCommands (Array <CommandID>& commands)
|
||||
{
|
||||
DocumentEditorComponent::getAllCommands (commands);
|
||||
|
||||
const CommandID ids[] = { CommandIDs::undo,
|
||||
CommandIDs::redo };
|
||||
|
||||
commands.addArray (ids, numElementsInArray (ids));
|
||||
}
|
||||
|
||||
void ComponentEditor::getCommandInfo (CommandID commandID, ApplicationCommandInfo& result)
|
||||
{
|
||||
result.setActive (document != 0);
|
||||
|
||||
switch (commandID)
|
||||
{
|
||||
case CommandIDs::undo:
|
||||
result.setInfo ("Undo", "Undoes the last change",
|
||||
CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add (KeyPress ('z', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
case CommandIDs::redo:
|
||||
result.setInfo ("Redo", "Redoes the last change",
|
||||
CommandCategories::general, 0);
|
||||
result.defaultKeypresses.add (KeyPress ('z', ModifierKeys::shiftModifier | ModifierKeys::commandModifier, 0));
|
||||
result.defaultKeypresses.add (KeyPress ('y', ModifierKeys::commandModifier, 0));
|
||||
break;
|
||||
|
||||
default:
|
||||
DocumentEditorComponent::getCommandInfo (commandID, result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool ComponentEditor::perform (const InvocationInfo& info)
|
||||
{
|
||||
switch (info.commandID)
|
||||
{
|
||||
case CommandIDs::undo:
|
||||
jassertfalse //xxx
|
||||
return true;
|
||||
|
||||
case CommandIDs::redo:
|
||||
jassertfalse //xxx
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DocumentEditorComponent::perform (info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ public:
|
|||
~ComponentEditor();
|
||||
|
||||
//==============================================================================
|
||||
void getAllCommands (Array <CommandID>& commands);
|
||||
void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result);
|
||||
bool perform (const InvocationInfo& info);
|
||||
|
||||
void paint (Graphics& g);
|
||||
void resized();
|
||||
|
||||
|
|
|
|||
|
|
@ -60878,9 +60878,9 @@ ResizableBorderComponent::Zone& ResizableBorderComponent::Zone::operator= (const
|
|||
bool ResizableBorderComponent::Zone::operator== (const ResizableBorderComponent::Zone& other) const throw() { return zone == other.zone; }
|
||||
bool ResizableBorderComponent::Zone::operator!= (const ResizableBorderComponent::Zone& other) const throw() { return zone != other.zone; }
|
||||
|
||||
const ResizableBorderComponent::Zone::Zone ResizableBorderComponent::Zone::fromPositionOnBorder (const Rectangle<int>& totalSize,
|
||||
const BorderSize& border,
|
||||
const Point<int>& position)
|
||||
const ResizableBorderComponent::Zone ResizableBorderComponent::Zone::fromPositionOnBorder (const Rectangle<int>& totalSize,
|
||||
const BorderSize& border,
|
||||
const Point<int>& position)
|
||||
{
|
||||
int z = 0;
|
||||
|
||||
|
|
@ -70113,6 +70113,9 @@ private:
|
|||
mouseMovedSignificantlySincePressed = mouseMovedSignificantlySincePressed
|
||||
|| mouseDowns[0].position.getDistanceFrom (screenPos) >= 4;
|
||||
}
|
||||
|
||||
MouseInputSourceInternal (const MouseInputSourceInternal&);
|
||||
MouseInputSourceInternal& operator= (const MouseInputSourceInternal&);
|
||||
};
|
||||
|
||||
MouseInputSource::MouseInputSource (const int index, const bool isMouseDevice)
|
||||
|
|
|
|||
|
|
@ -45,9 +45,9 @@ ResizableBorderComponent::Zone& ResizableBorderComponent::Zone::operator= (const
|
|||
bool ResizableBorderComponent::Zone::operator== (const ResizableBorderComponent::Zone& other) const throw() { return zone == other.zone; }
|
||||
bool ResizableBorderComponent::Zone::operator!= (const ResizableBorderComponent::Zone& other) const throw() { return zone != other.zone; }
|
||||
|
||||
const ResizableBorderComponent::Zone::Zone ResizableBorderComponent::Zone::fromPositionOnBorder (const Rectangle<int>& totalSize,
|
||||
const BorderSize& border,
|
||||
const Point<int>& position)
|
||||
const ResizableBorderComponent::Zone ResizableBorderComponent::Zone::fromPositionOnBorder (const Rectangle<int>& totalSize,
|
||||
const BorderSize& border,
|
||||
const Point<int>& position)
|
||||
{
|
||||
int z = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -469,6 +469,9 @@ private:
|
|||
mouseMovedSignificantlySincePressed = mouseMovedSignificantlySincePressed
|
||||
|| mouseDowns[0].position.getDistanceFrom (screenPos) >= 4;
|
||||
}
|
||||
|
||||
MouseInputSourceInternal (const MouseInputSourceInternal&);
|
||||
MouseInputSourceInternal& operator= (const MouseInputSourceInternal&);
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue