276 lines
7.8 KiB
C++
276 lines
7.8 KiB
C++
/*
|
|
==============================================================================
|
|
|
|
This file is part of the JUCE library.
|
|
Copyright (c) 2017 - ROLI Ltd.
|
|
|
|
JUCE is an open source library subject to commercial or open-source
|
|
licensing.
|
|
|
|
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
|
|
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
|
|
27th April 2017).
|
|
|
|
End User License Agreement: www.juce.com/juce-5-licence
|
|
Privacy Policy: www.juce.com/juce-5-privacy-policy
|
|
|
|
Or: You may also use this code under the terms of the GPL v3 (see
|
|
www.gnu.org/licenses).
|
|
|
|
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
|
|
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
|
|
DISCLAIMED.
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
namespace juce
|
|
{
|
|
|
|
FileSearchPathListComponent::FileSearchPathListComponent()
|
|
: addButton ("+"),
|
|
removeButton ("-"),
|
|
changeButton (TRANS ("change...")),
|
|
upButton ({}, DrawableButton::ImageOnButtonBackground),
|
|
downButton ({}, DrawableButton::ImageOnButtonBackground)
|
|
{
|
|
listBox.setModel (this);
|
|
addAndMakeVisible (listBox);
|
|
listBox.setColour (ListBox::backgroundColourId, Colours::black.withAlpha (0.02f));
|
|
listBox.setColour (ListBox::outlineColourId, Colours::black.withAlpha (0.1f));
|
|
listBox.setOutlineThickness (1);
|
|
|
|
addAndMakeVisible (addButton);
|
|
addButton.onClick = [this] { addPath(); };
|
|
addButton.setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight | Button::ConnectedOnBottom | Button::ConnectedOnTop);
|
|
|
|
addAndMakeVisible (removeButton);
|
|
removeButton.onClick = [this] { deleteSelected(); };
|
|
removeButton.setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight | Button::ConnectedOnBottom | Button::ConnectedOnTop);
|
|
|
|
addAndMakeVisible (changeButton);
|
|
changeButton.onClick = [this] { editSelected(); };
|
|
|
|
addAndMakeVisible (upButton);
|
|
upButton.onClick = [this] { moveSelection (-1); };
|
|
|
|
auto arrowColour = findColour (ListBox::textColourId);
|
|
|
|
{
|
|
Path arrowPath;
|
|
arrowPath.addArrow ({ 50.0f, 100.0f, 50.0f, 0.0f }, 40.0f, 100.0f, 50.0f);
|
|
DrawablePath arrowImage;
|
|
arrowImage.setFill (arrowColour);
|
|
arrowImage.setPath (arrowPath);
|
|
|
|
upButton.setImages (&arrowImage);
|
|
}
|
|
|
|
addAndMakeVisible (downButton);
|
|
downButton.onClick = [this] { moveSelection (1); };
|
|
|
|
{
|
|
Path arrowPath;
|
|
arrowPath.addArrow ({ 50.0f, 0.0f, 50.0f, 100.0f }, 40.0f, 100.0f, 50.0f);
|
|
DrawablePath arrowImage;
|
|
arrowImage.setFill (arrowColour);
|
|
arrowImage.setPath (arrowPath);
|
|
|
|
downButton.setImages (&arrowImage);
|
|
}
|
|
|
|
updateButtons();
|
|
}
|
|
|
|
FileSearchPathListComponent::~FileSearchPathListComponent()
|
|
{
|
|
}
|
|
|
|
void FileSearchPathListComponent::updateButtons()
|
|
{
|
|
const bool anythingSelected = listBox.getNumSelectedRows() > 0;
|
|
|
|
removeButton.setEnabled (anythingSelected);
|
|
changeButton.setEnabled (anythingSelected);
|
|
upButton.setEnabled (anythingSelected);
|
|
downButton.setEnabled (anythingSelected);
|
|
}
|
|
|
|
void FileSearchPathListComponent::changed()
|
|
{
|
|
listBox.updateContent();
|
|
listBox.repaint();
|
|
updateButtons();
|
|
}
|
|
|
|
//==============================================================================
|
|
void FileSearchPathListComponent::setPath (const FileSearchPath& newPath)
|
|
{
|
|
if (newPath.toString() != path.toString())
|
|
{
|
|
path = newPath;
|
|
changed();
|
|
}
|
|
}
|
|
|
|
void FileSearchPathListComponent::setDefaultBrowseTarget (const File& newDefaultDirectory)
|
|
{
|
|
defaultBrowseTarget = newDefaultDirectory;
|
|
}
|
|
|
|
//==============================================================================
|
|
int FileSearchPathListComponent::getNumRows()
|
|
{
|
|
return path.getNumPaths();
|
|
}
|
|
|
|
void FileSearchPathListComponent::paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected)
|
|
{
|
|
if (rowIsSelected)
|
|
g.fillAll (findColour (TextEditor::highlightColourId));
|
|
|
|
g.setColour (findColour (ListBox::textColourId));
|
|
Font f (height * 0.7f);
|
|
f.setHorizontalScale (0.9f);
|
|
g.setFont (f);
|
|
|
|
g.drawText (path[rowNumber].getFullPathName(),
|
|
4, 0, width - 6, height,
|
|
Justification::centredLeft, true);
|
|
}
|
|
|
|
void FileSearchPathListComponent::deleteKeyPressed (int row)
|
|
{
|
|
if (isPositiveAndBelow (row, path.getNumPaths()))
|
|
{
|
|
path.remove (row);
|
|
changed();
|
|
}
|
|
}
|
|
|
|
void FileSearchPathListComponent::returnKeyPressed (int row)
|
|
{
|
|
#if JUCE_MODAL_LOOPS_PERMITTED
|
|
FileChooser chooser (TRANS("Change folder..."), path[row], "*");
|
|
|
|
if (chooser.browseForDirectory())
|
|
{
|
|
path.remove (row);
|
|
path.add (chooser.getResult(), row);
|
|
changed();
|
|
}
|
|
#else
|
|
ignoreUnused (row);
|
|
#endif
|
|
}
|
|
|
|
void FileSearchPathListComponent::listBoxItemDoubleClicked (int row, const MouseEvent&)
|
|
{
|
|
returnKeyPressed (row);
|
|
}
|
|
|
|
void FileSearchPathListComponent::selectedRowsChanged (int)
|
|
{
|
|
updateButtons();
|
|
}
|
|
|
|
void FileSearchPathListComponent::paint (Graphics& g)
|
|
{
|
|
g.fillAll (findColour (backgroundColourId));
|
|
}
|
|
|
|
void FileSearchPathListComponent::resized()
|
|
{
|
|
const int buttonH = 22;
|
|
const int buttonY = getHeight() - buttonH - 4;
|
|
listBox.setBounds (2, 2, getWidth() - 4, buttonY - 5);
|
|
|
|
addButton.setBounds (2, buttonY, buttonH, buttonH);
|
|
removeButton.setBounds (addButton.getRight(), buttonY, buttonH, buttonH);
|
|
|
|
changeButton.changeWidthToFitText (buttonH);
|
|
downButton.setSize (buttonH * 2, buttonH);
|
|
upButton.setSize (buttonH * 2, buttonH);
|
|
|
|
downButton.setTopRightPosition (getWidth() - 2, buttonY);
|
|
upButton.setTopRightPosition (downButton.getX() - 4, buttonY);
|
|
changeButton.setTopRightPosition (upButton.getX() - 8, buttonY);
|
|
}
|
|
|
|
bool FileSearchPathListComponent::isInterestedInFileDrag (const StringArray&)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void FileSearchPathListComponent::filesDropped (const StringArray& filenames, int, int mouseY)
|
|
{
|
|
for (int i = filenames.size(); --i >= 0;)
|
|
{
|
|
const File f (filenames[i]);
|
|
|
|
if (f.isDirectory())
|
|
{
|
|
auto row = listBox.getRowContainingPosition (0, mouseY - listBox.getY());
|
|
path.add (f, row);
|
|
changed();
|
|
}
|
|
}
|
|
}
|
|
|
|
void FileSearchPathListComponent::addPath()
|
|
{
|
|
auto start = defaultBrowseTarget;
|
|
|
|
if (start == File())
|
|
start = path[0];
|
|
|
|
if (start == File())
|
|
start = File::getCurrentWorkingDirectory();
|
|
|
|
#if JUCE_MODAL_LOOPS_PERMITTED
|
|
FileChooser chooser (TRANS("Add a folder..."), start, "*");
|
|
|
|
if (chooser.browseForDirectory())
|
|
path.add (chooser.getResult(), listBox.getSelectedRow());
|
|
|
|
changed();
|
|
#else
|
|
jassertfalse; // needs rewriting to deal with non-modal environments
|
|
#endif
|
|
}
|
|
|
|
void FileSearchPathListComponent::deleteSelected()
|
|
{
|
|
deleteKeyPressed (listBox.getSelectedRow());
|
|
changed();
|
|
}
|
|
|
|
void FileSearchPathListComponent::editSelected()
|
|
{
|
|
returnKeyPressed (listBox.getSelectedRow());
|
|
changed();
|
|
}
|
|
|
|
void FileSearchPathListComponent::moveSelection (int delta)
|
|
{
|
|
jassert (delta == -1 || delta == 1);
|
|
auto currentRow = listBox.getSelectedRow();
|
|
|
|
if (isPositiveAndBelow (currentRow, path.getNumPaths()))
|
|
{
|
|
auto newRow = jlimit (0, path.getNumPaths() - 1, currentRow + delta);
|
|
|
|
if (currentRow != newRow)
|
|
{
|
|
auto f = path[currentRow];
|
|
path.remove (currentRow);
|
|
path.add (f, newRow);
|
|
listBox.selectRow (newRow);
|
|
changed();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
} // namespace juce
|