Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some more browser tweaks #1464

Merged
merged 1 commit into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 71 additions & 100 deletions src-ui/app/browser-ui/BrowserPane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,48 +209,16 @@ struct DriveArea : juce::Component, HasEditor
}
};

struct DriveFSListBoxModel : juce::ListBoxModel
{
BrowserPane *browserPane{nullptr};
DriveFSListBoxModel(BrowserPane *b) : browserPane(b) {}
int getNumRows() override;
void paintListBoxItem(int rowNumber, juce::Graphics &g, int width, int height,
bool rowIsSelected) override
{
}
juce::Component *refreshComponentForRow(int rowNumber, bool isRowSelected,
juce::Component *existingComponentToUpdate) override;

void selectedRowsChanged(int lastRowSelected) override {}
};

struct DriveFSArea : juce::Component, HasEditor
{
BrowserPane *browserPane{nullptr};
std::unique_ptr<DriveFSListBoxModel> model;
std::unique_ptr<juce::ListBox> lbox;
std::unique_ptr<jcmp::TextPushButton> dotDot;
std::unique_ptr<jcmp::ListView> listView;

DriveFSArea(BrowserPane *b, SCXTEditor *e) : browserPane(b), HasEditor(e)
{
model = std::make_unique<DriveFSListBoxModel>(browserPane);
lbox = std::make_unique<juce::ListBox>("Current Data", model.get());
lbox->setClickingTogglesRowSelection(true);
lbox->setMultipleSelectionEnabled(false);
lbox->setRowHeight(18);
lbox->setColour(juce::ListBox::ColourIds::backgroundColourId,
juce::Colour(0.f, 0.f, 0.f, 0.f));

addAndMakeVisible(*lbox);

dotDot = std::make_unique<jcmp::TextPushButton>();
dotDot->setLabel("up one dir");
dotDot->setOnCallback([w = juce::Component::SafePointer(this)]() {
if (w)
w->upOneLevel();
});
dotDot->setEnabled(false);
addAndMakeVisible(*dotDot);
listView = std::make_unique<jcmp::ListView>();
setupListView();
addAndMakeVisible(*listView);
}

void paint(juce::Graphics &g) override
Expand All @@ -266,14 +234,12 @@ struct DriveFSArea : juce::Component, HasEditor
{
rootPath = p;
currentPath = p;
dotDot->setEnabled(false);
recalcContents();
}

void setCurrentPath(const fs::path &p)
{
currentPath = p;
dotDot->setEnabled(currentPath > rootPath);
recalcContents();
}

Expand All @@ -290,6 +256,7 @@ struct DriveFSArea : juce::Component, HasEditor
{
// Make a copy for now. this sucks and we should be smarter
contents.clear();
auto lcontents = contents;
try
{
for (auto const &dir_entry : fs::directory_iterator{currentPath})
Expand All @@ -307,26 +274,31 @@ struct DriveFSArea : juce::Component, HasEditor

if (include)
{
contents.push_back(dir_entry);
lcontents.push_back(dir_entry);
}
}
}
catch (const fs::filesystem_error &e)
{
SCLOG(e.what());
}
std::sort(contents.begin(), contents.end(), [](auto &a, auto &b) {
std::sort(lcontents.begin(), lcontents.end(), [](auto &a, auto &b) {
return strnatcasecmp(a.path().u8string().c_str(), b.path().u8string().c_str()) < 0;
});
lbox->updateContent();
if (currentPath > rootPath)
contents.emplace_back("..");
for (auto &c : lcontents)
contents.emplace_back(c);
listView->refresh();
}

void resized() override
{
auto bd = getLocalBounds().reduced(1);
dotDot->setBounds(bd.withHeight(20));
lbox->setBounds(bd.withTrimmedTop(22));
listView->setBounds(bd);
}

void setupListView();
};

struct DevicesPane : HasEditor, juce::Component
Expand Down Expand Up @@ -376,22 +348,15 @@ void DriveArea::DriveAreaRow::mouseDown(const juce::MouseEvent &e)
}
}

int DriveFSListBoxModel::getNumRows()
{
if (!browserPane || !browserPane->devicesPane || !browserPane->devicesPane->driveFSArea)
return 0;

return browserPane->devicesPane->driveFSArea->contents.size();
}

struct DriveFSListBoxRow : public juce::Component
struct DriveFSRowComponent : public juce::Component
{
bool isSelected;
int rowNumber;
BrowserPane *browserPane{nullptr};
DriveFSListBoxModel *model{nullptr};
jcmp::ListView *listView{nullptr};

DriveFSRowComponent(BrowserPane *p, jcmp::ListView *v) : browserPane(p), listView(v) {}

juce::ListBox *enclosingBox() { return browserPane->devicesPane->driveFSArea->lbox.get(); }
bool isDragging{false};
bool isMouseDownWithoutDrag{false};
bool hasStartedPreview{false};
Expand All @@ -414,7 +379,7 @@ struct DriveFSListBoxRow : public juce::Component
}
}

enclosingBox()->selectRowsBasedOnModifierKeys(rowNumber, event.mods, false);
listView->rowSelected(rowNumber, true);

if (event.mods.isPopupMenu())
{
Expand Down Expand Up @@ -454,10 +419,18 @@ struct DriveFSListBoxRow : public juce::Component
{
isDragging = false;
}
else
{
enclosingBox()->selectRowsBasedOnModifierKeys(rowNumber, event.mods, true);
}
}

bool isHovered;
void mouseEnter(const juce::MouseEvent &) override
{
isHovered = true;
repaint();
}
void mouseExit(const juce::MouseEvent &) override
{
isHovered = false;
repaint();
}

void stopPreview()
Expand All @@ -480,7 +453,11 @@ struct DriveFSListBoxRow : public juce::Component
const auto &data = browserPane->devicesPane->driveFSArea->contents;
if (rowNumber >= 0 && rowNumber < data.size())
{
if (data[rowNumber].is_directory())
if (data[rowNumber] == fs::path(".."))
{
browserPane->devicesPane->driveFSArea->upOneLevel();
}
else if (data[rowNumber].is_directory())
{
browserPane->devicesPane->driveFSArea->setCurrentPath(data[rowNumber].path());
}
Expand Down Expand Up @@ -547,21 +524,22 @@ struct DriveFSListBoxRow : public juce::Component
fillColor = browserPane->editor->themeColor(theme::ColorMap::bg_3);
textColor = browserPane->editor->themeColor(theme::ColorMap::generic_content_high);
}
else if (isHovered)
{
fillColor = browserPane->editor->themeColor(theme::ColorMap::bg_3);
}
g.setColour(fillColor);
g.fillRect(0, 0, width, height);
// TODO: Replace with glyph painter fo course
auto r = juce::Rectangle<int>(1, (height - 10) / 2, 10, 10);
auto r = juce::Rectangle<int>(1, (height - 14) / 2, 14, 14);
if (entry.is_directory())
{
g.setColour(textColor.withAlpha(0.5f));
g.fillRect(r);
g.setColour(textColor.brighter(0.4f));
g.drawRect(r);
jcmp::GlyphPainter::paintGlyph(g, r, jcmp::GlyphPainter::FOLDER,
textColor.withAlpha(isSelected ? 1.f : 0.5f));
}
else
{
jcmp::GlyphPainter::paintGlyph(g, r, jcmp::GlyphPainter::TUNING,
textColor.withAlpha(0.5f));
jcmp::GlyphPainter::paintGlyph(g, r, jcmp::GlyphPainter::FILE_MUSIC,
textColor.withAlpha(isSelected ? 1.f : 0.5f));
}

if (hasStartedPreview)
Expand All @@ -571,47 +549,40 @@ struct DriveFSListBoxRow : public juce::Component
// textColor.withAlpha(0.5f));
}
g.setColour(textColor);
g.drawText(entry.path().filename().u8string(), 14, 1, width - 16, height - 2,
g.drawText(entry.path().filename().u8string(), 16, 1, width - 16, height - 2,
juce::Justification::centredLeft);
}
}
};

juce::Component *
DriveFSListBoxModel::refreshComponentForRow(int rowNumber, bool isRowSelected,
juce::Component *existingComponentToUpdate)
void DriveFSArea::setupListView()
{
if (!browserPane || !browserPane->devicesPane || !browserPane->devicesPane->driveFSArea)
return nullptr;
listView->getRowCount = [this]() -> uint32_t {
if (!browserPane || !browserPane->devicesPane || !browserPane->devicesPane->driveFSArea)
return 0;

const auto &data = browserPane->devicesPane->driveFSArea->contents;
if (rowNumber >= 0 && rowNumber < data.size())
{
auto rc = dynamic_cast<DriveFSListBoxRow *>(existingComponentToUpdate);

if (!rc)
return browserPane->devicesPane->driveFSArea->contents.size();
};
listView->getRowHeight = [this]() { return 18; };
listView->makeRowComponent = [this]() {
return std::make_unique<DriveFSRowComponent>(browserPane, listView.get());
};
listView->assignComponentToRow = [this](const auto &c, auto r) {
auto dfs = dynamic_cast<DriveFSRowComponent *>(c.get());
if (dfs)
{
// Should never happen but
if (existingComponentToUpdate)
{
delete existingComponentToUpdate;
existingComponentToUpdate = nullptr;
}

rc = new DriveFSListBoxRow();
dfs->rowNumber = r;
dfs->repaint();
}

rc->isSelected = isRowSelected;
rc->rowNumber = rowNumber;
rc->browserPane = browserPane;
rc->model = this;
rc->repaint();
return rc;
}

if (existingComponentToUpdate)
delete existingComponentToUpdate;
return nullptr;
};
listView->setRowSelection = [this](const auto &c, auto r) {
auto dfs = dynamic_cast<DriveFSRowComponent *>(c.get());
if (dfs)
{
dfs->isSelected = r;
dfs->repaint();
}
};
}

struct FavoritesPane : TempPane
Expand Down