@@ -139,6 +139,11 @@ bool MainWindow::closeProject (Project* project) | |||||
if (! OpenDocumentManager::getInstance()->closeAllDocumentsUsingProject (*project, true)) | if (! OpenDocumentManager::getInstance()->closeAllDocumentsUsingProject (*project, true)) | ||||
return false; | return false; | ||||
ProjectContentComponent* const pcc = getProjectContentComponent(); | |||||
if (pcc != nullptr) | |||||
pcc->saveTreeViewState(); | |||||
FileBasedDocument::SaveResult r = project->saveIfNeededAndUserAgrees(); | FileBasedDocument::SaveResult r = project->saveIfNeededAndUserAgrees(); | ||||
if (r == FileBasedDocument::savedOk) | if (r == FileBasedDocument::savedOk) | ||||
@@ -59,6 +59,8 @@ void ProjectContentComponent::setProject (Project* newProject) | |||||
{ | { | ||||
if (project != newProject) | if (project != newProject) | ||||
{ | { | ||||
PropertiesFile& settings = StoredSettings::getInstance()->getProps(); | |||||
if (project != nullptr) | if (project != nullptr) | ||||
project->removeChangeListener (this); | project->removeChangeListener (this); | ||||
@@ -67,7 +69,7 @@ void ProjectContentComponent::setProject (Project* newProject) | |||||
if (projectTree != nullptr) | if (projectTree != nullptr) | ||||
{ | { | ||||
StoredSettings::getInstance()->getProps().setValue ("projectTreeviewWidth", projectTree->getWidth()); | |||||
settings.setValue ("projectTreeviewWidth", projectTree->getWidth()); | |||||
projectTree->deleteRootItem(); | projectTree->deleteRootItem(); | ||||
projectTree = nullptr; | projectTree = nullptr; | ||||
} | } | ||||
@@ -86,7 +88,7 @@ void ProjectContentComponent::setProject (Project* newProject) | |||||
projectTree->setRootItem (new GroupTreeViewItem (project->getMainGroup())); | projectTree->setRootItem (new GroupTreeViewItem (project->getMainGroup())); | ||||
projectTree->getRootItem()->setOpen (true); | projectTree->getRootItem()->setOpen (true); | ||||
String lastTreeWidth (StoredSettings::getInstance()->getProps().getValue ("projectTreeviewWidth")); | |||||
String lastTreeWidth (settings.getValue ("projectTreeviewWidth")); | |||||
if (lastTreeWidth.getIntValue() < 150) | if (lastTreeWidth.getIntValue() < 150) | ||||
lastTreeWidth = "250"; | lastTreeWidth = "250"; | ||||
@@ -103,10 +105,27 @@ void ProjectContentComponent::setProject (Project* newProject) | |||||
invokeDirectly (CommandIDs::showProjectSettings, true); | invokeDirectly (CommandIDs::showProjectSettings, true); | ||||
updateMissingFileStatuses(); | updateMissingFileStatuses(); | ||||
const ScopedPointer<XmlElement> treeOpenness (settings.getXmlValue ("treeViewState_" + project->getProjectUID())); | |||||
if (treeOpenness != nullptr) | |||||
projectTree->restoreOpennessState (*treeOpenness, true); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
void ProjectContentComponent::saveTreeViewState() | |||||
{ | |||||
if (projectTree != nullptr) | |||||
{ | |||||
const ScopedPointer<XmlElement> opennessState (projectTree->getOpennessState (true)); | |||||
if (opennessState != nullptr) | |||||
StoredSettings::getInstance()->getProps() | |||||
.setValue ("treeViewState_" + project->getProjectUID(), opennessState); | |||||
} | |||||
} | |||||
void ProjectContentComponent::changeListenerCallback (ChangeBroadcaster*) | void ProjectContentComponent::changeListenerCallback (ChangeBroadcaster*) | ||||
{ | { | ||||
updateMissingFileStatuses(); | updateMissingFileStatuses(); | ||||
@@ -45,6 +45,7 @@ public: | |||||
void paint (Graphics& g); | void paint (Graphics& g); | ||||
void setProject (Project* project); | void setProject (Project* project); | ||||
void saveTreeViewState(); | |||||
bool showEditorForFile (const File& f); | bool showEditorForFile (const File& f); | ||||
bool showDocument (OpenDocumentManager::Document* doc); | bool showDocument (OpenDocumentManager::Document* doc); | ||||
@@ -39,7 +39,6 @@ public: | |||||
bool acceptsFileDrop (const StringArray& files) const { return false; } | bool acceptsFileDrop (const StringArray& files) const { return false; } | ||||
bool acceptsDragItems (const OwnedArray <Project::Item>& selectedNodes) { return false; } | bool acceptsDragItems (const OwnedArray <Project::Item>& selectedNodes) { return false; } | ||||
ProjectTreeViewBase* createSubItem (const Project::Item& child); | ProjectTreeViewBase* createSubItem (const Project::Item& child); | ||||
void createLeftEdgeComponents (OwnedArray<Component>& components) {} | |||||
void showDocument(); | void showDocument(); | ||||
void showPopupMenu(); | void showPopupMenu(); | ||||
void handlePopupMenuResult (int resultCode); | void handlePopupMenuResult (int resultCode); | ||||
@@ -60,7 +59,6 @@ public: | |||||
void checkFileStatus(); | void checkFileStatus(); | ||||
void moveSelectedItemsTo (OwnedArray <Project::Item>& selectedNodes, int insertIndex); | void moveSelectedItemsTo (OwnedArray <Project::Item>& selectedNodes, int insertIndex); | ||||
ProjectTreeViewBase* createSubItem (const Project::Item& child); | ProjectTreeViewBase* createSubItem (const Project::Item& child); | ||||
void createLeftEdgeComponents (OwnedArray<Component>& components) {} | |||||
void showDocument(); | void showDocument(); | ||||
void showPopupMenu(); | void showPopupMenu(); | ||||
void handlePopupMenuResult (int resultCode); | void handlePopupMenuResult (int resultCode); | ||||
@@ -28,7 +28,7 @@ | |||||
//============================================================================== | //============================================================================== | ||||
JucerTreeViewBase::JucerTreeViewBase() | JucerTreeViewBase::JucerTreeViewBase() | ||||
: numLeftHandComps (0) | |||||
: textX (0) | |||||
{ | { | ||||
setLinesDrawnForSubItems (false); | setLinesDrawnForSubItems (false); | ||||
} | } | ||||
@@ -38,26 +38,10 @@ Font JucerTreeViewBase::getFont() const | |||||
return Font (getItemHeight() * 0.6f); | return Font (getItemHeight() * 0.6f); | ||||
} | } | ||||
int JucerTreeViewBase::getTextX() const | |||||
{ | |||||
return (numLeftHandComps + 1) * getItemHeight() + 8; | |||||
} | |||||
void JucerTreeViewBase::paintItem (Graphics& g, int width, int height) | void JucerTreeViewBase::paintItem (Graphics& g, int width, int height) | ||||
{ | { | ||||
if (isSelected()) | if (isSelected()) | ||||
g.fillAll (Colour (0x401111ee)); | g.fillAll (Colour (0x401111ee)); | ||||
const int x = getTextX(); | |||||
g.setColour (Colours::black); | |||||
getIcon()->drawWithin (g, Rectangle<float> (0.0f, 2.0f, height + 6.0f, height - 4.0f), | |||||
RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, 1.0f); | |||||
g.setFont (getFont()); | |||||
g.setColour (isMissing() ? Colours::red : Colours::black); | |||||
g.drawFittedText (getDisplayName(), x, 0, width - x, height, Justification::centredLeft, 1, 0.8f); | |||||
} | } | ||||
void JucerTreeViewBase::paintOpenCloseButton (Graphics& g, int width, int height, bool isMouseOver) | void JucerTreeViewBase::paintOpenCloseButton (Graphics& g, int width, int height, bool isMouseOver) | ||||
@@ -74,38 +58,63 @@ void JucerTreeViewBase::paintOpenCloseButton (Graphics& g, int width, int height | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
class TreeLeftHandButtonHolderComponent : public Component | |||||
class TreeItemComponent : public Component | |||||
{ | { | ||||
public: | public: | ||||
TreeLeftHandButtonHolderComponent (OwnedArray<Component>& comps) | |||||
TreeItemComponent (JucerTreeViewBase& item_) | |||||
: item (item_) | |||||
{ | { | ||||
components.swapWithArray (comps); | |||||
setInterceptsMouseClicks (false, true); | setInterceptsMouseClicks (false, true); | ||||
for (int i = 0; i < components.size(); ++i) | |||||
addAndMakeVisible (components.getUnchecked(i)); | |||||
item.createLeftEdgeComponents (leftComps); | |||||
for (int i = 0; i < leftComps.size(); ++i) | |||||
addAndMakeVisible (leftComps.getUnchecked(i)); | |||||
addAndMakeVisible (rightHandComponent = item.createRightEdgeComponent()); | |||||
} | |||||
void paint (Graphics& g) | |||||
{ | |||||
g.setColour (Colours::black); | |||||
const int height = getHeight(); | |||||
item.getIcon()->drawWithin (g, Rectangle<float> (0.0f, 2.0f, height + 6.0f, height - 4.0f), | |||||
RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, 1.0f); | |||||
g.setFont (item.getFont()); | |||||
g.setColour (item.isMissing() ? Colours::red : Colours::black); | |||||
const int right = rightHandComponent != nullptr ? rightHandComponent->getX() - 2 | |||||
: getWidth(); | |||||
g.drawFittedText (item.getDisplayName(), | |||||
item.textX, 0, right - item.textX, height, Justification::centredLeft, 1, 0.8f); | |||||
} | } | ||||
void resized() | void resized() | ||||
{ | { | ||||
const int edge = 1; | const int edge = 1; | ||||
const int itemSize = getHeight() - edge * 2; | const int itemSize = getHeight() - edge * 2; | ||||
item.textX = (leftComps.size() + 1) * getHeight() + 8; | |||||
for (int i = 0; i < leftComps.size(); ++i) | |||||
leftComps.getUnchecked(i)->setBounds (5 + (i + 1) * getHeight(), edge, itemSize, itemSize); | |||||
for (int i = 0; i < components.size(); ++i) | |||||
components.getUnchecked(i)->setBounds (5 + (i + 1) * getHeight(), edge, itemSize, itemSize); | |||||
if (rightHandComponent != nullptr) | |||||
rightHandComponent->setBounds (getWidth() - itemSize - edge, edge, itemSize, itemSize); | |||||
} | } | ||||
private: | private: | ||||
OwnedArray<Component> components; | |||||
JucerTreeViewBase& item; | |||||
OwnedArray<Component> leftComps; | |||||
ScopedPointer<Component> rightHandComponent; | |||||
}; | }; | ||||
Component* JucerTreeViewBase::createItemComponent() | Component* JucerTreeViewBase::createItemComponent() | ||||
{ | { | ||||
OwnedArray<Component> components; | |||||
createLeftEdgeComponents (components); | |||||
numLeftHandComps = components.size(); | |||||
return numLeftHandComps == 0 ? nullptr : new TreeLeftHandButtonHolderComponent (components); | |||||
return new TreeItemComponent (*this); | |||||
} | } | ||||
//============================================================================== | //============================================================================== | ||||
@@ -149,7 +158,7 @@ private: | |||||
void JucerTreeViewBase::showRenameBox() | void JucerTreeViewBase::showRenameBox() | ||||
{ | { | ||||
Rectangle<int> r (getItemPosition (true)); | Rectangle<int> r (getItemPosition (true)); | ||||
r.setLeft (r.getX() + getTextX()); | |||||
r.setLeft (r.getX() + textX); | |||||
r.setHeight (getItemHeight()); | r.setHeight (getItemHeight()); | ||||
new RenameTreeItemCallback (*this, *getOwnerView(), r); | new RenameTreeItemCallback (*this, *getOwnerView(), r); | ||||
@@ -33,6 +33,8 @@ | |||||
class JucerTreeViewBase : public TreeViewItem | class JucerTreeViewBase : public TreeViewItem | ||||
{ | { | ||||
public: | public: | ||||
JucerTreeViewBase(); | |||||
int getItemWidth() const { return -1; } | int getItemWidth() const { return -1; } | ||||
int getItemHeight() const { return 20; } | int getItemHeight() const { return 20; } | ||||
@@ -48,7 +50,8 @@ public: | |||||
virtual void setName (const String& newName) = 0; | virtual void setName (const String& newName) = 0; | ||||
virtual bool isMissing() = 0; | virtual bool isMissing() = 0; | ||||
virtual const Drawable* getIcon() const = 0; | virtual const Drawable* getIcon() const = 0; | ||||
virtual void createLeftEdgeComponents (OwnedArray<Component>& components) = 0; | |||||
virtual void createLeftEdgeComponents (OwnedArray<Component>&) {} | |||||
virtual Component* createRightEdgeComponent() { return nullptr; } | |||||
virtual void showPopupMenu(); | virtual void showPopupMenu(); | ||||
virtual void showMultiSelectionPopupMenu(); | virtual void showMultiSelectionPopupMenu(); | ||||
@@ -72,12 +75,7 @@ public: | |||||
} | } | ||||
}; | }; | ||||
protected: | |||||
JucerTreeViewBase(); | |||||
private: | |||||
int numLeftHandComps; | |||||
int getTextX() const; | |||||
int textX; | |||||
}; | }; | ||||