Skip to content

Commit 6be5825

Browse files
authored
Some more browser tweaks (#1464)
movign towards the jucegui listview model instead
1 parent 19c319d commit 6be5825

File tree

2 files changed

+72
-101
lines changed

2 files changed

+72
-101
lines changed

src-ui/app/browser-ui/BrowserPane.cpp

Lines changed: 71 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -209,48 +209,16 @@ struct DriveArea : juce::Component, HasEditor
209209
}
210210
};
211211

212-
struct DriveFSListBoxModel : juce::ListBoxModel
213-
{
214-
BrowserPane *browserPane{nullptr};
215-
DriveFSListBoxModel(BrowserPane *b) : browserPane(b) {}
216-
int getNumRows() override;
217-
void paintListBoxItem(int rowNumber, juce::Graphics &g, int width, int height,
218-
bool rowIsSelected) override
219-
{
220-
}
221-
juce::Component *refreshComponentForRow(int rowNumber, bool isRowSelected,
222-
juce::Component *existingComponentToUpdate) override;
223-
224-
void selectedRowsChanged(int lastRowSelected) override {}
225-
};
226-
227212
struct DriveFSArea : juce::Component, HasEditor
228213
{
229214
BrowserPane *browserPane{nullptr};
230-
std::unique_ptr<DriveFSListBoxModel> model;
231-
std::unique_ptr<juce::ListBox> lbox;
232-
std::unique_ptr<jcmp::TextPushButton> dotDot;
215+
std::unique_ptr<jcmp::ListView> listView;
233216

234217
DriveFSArea(BrowserPane *b, SCXTEditor *e) : browserPane(b), HasEditor(e)
235218
{
236-
model = std::make_unique<DriveFSListBoxModel>(browserPane);
237-
lbox = std::make_unique<juce::ListBox>("Current Data", model.get());
238-
lbox->setClickingTogglesRowSelection(true);
239-
lbox->setMultipleSelectionEnabled(false);
240-
lbox->setRowHeight(18);
241-
lbox->setColour(juce::ListBox::ColourIds::backgroundColourId,
242-
juce::Colour(0.f, 0.f, 0.f, 0.f));
243-
244-
addAndMakeVisible(*lbox);
245-
246-
dotDot = std::make_unique<jcmp::TextPushButton>();
247-
dotDot->setLabel("up one dir");
248-
dotDot->setOnCallback([w = juce::Component::SafePointer(this)]() {
249-
if (w)
250-
w->upOneLevel();
251-
});
252-
dotDot->setEnabled(false);
253-
addAndMakeVisible(*dotDot);
219+
listView = std::make_unique<jcmp::ListView>();
220+
setupListView();
221+
addAndMakeVisible(*listView);
254222
}
255223

256224
void paint(juce::Graphics &g) override
@@ -266,14 +234,12 @@ struct DriveFSArea : juce::Component, HasEditor
266234
{
267235
rootPath = p;
268236
currentPath = p;
269-
dotDot->setEnabled(false);
270237
recalcContents();
271238
}
272239

273240
void setCurrentPath(const fs::path &p)
274241
{
275242
currentPath = p;
276-
dotDot->setEnabled(currentPath > rootPath);
277243
recalcContents();
278244
}
279245

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

308275
if (include)
309276
{
310-
contents.push_back(dir_entry);
277+
lcontents.push_back(dir_entry);
311278
}
312279
}
313280
}
314281
catch (const fs::filesystem_error &e)
315282
{
316283
SCLOG(e.what());
317284
}
318-
std::sort(contents.begin(), contents.end(), [](auto &a, auto &b) {
285+
std::sort(lcontents.begin(), lcontents.end(), [](auto &a, auto &b) {
319286
return strnatcasecmp(a.path().u8string().c_str(), b.path().u8string().c_str()) < 0;
320287
});
321-
lbox->updateContent();
288+
if (currentPath > rootPath)
289+
contents.emplace_back("..");
290+
for (auto &c : lcontents)
291+
contents.emplace_back(c);
292+
listView->refresh();
322293
}
323294

324295
void resized() override
325296
{
326297
auto bd = getLocalBounds().reduced(1);
327-
dotDot->setBounds(bd.withHeight(20));
328-
lbox->setBounds(bd.withTrimmedTop(22));
298+
listView->setBounds(bd);
329299
}
300+
301+
void setupListView();
330302
};
331303

332304
struct DevicesPane : HasEditor, juce::Component
@@ -376,22 +348,15 @@ void DriveArea::DriveAreaRow::mouseDown(const juce::MouseEvent &e)
376348
}
377349
}
378350

379-
int DriveFSListBoxModel::getNumRows()
380-
{
381-
if (!browserPane || !browserPane->devicesPane || !browserPane->devicesPane->driveFSArea)
382-
return 0;
383-
384-
return browserPane->devicesPane->driveFSArea->contents.size();
385-
}
386-
387-
struct DriveFSListBoxRow : public juce::Component
351+
struct DriveFSRowComponent : public juce::Component
388352
{
389353
bool isSelected;
390354
int rowNumber;
391355
BrowserPane *browserPane{nullptr};
392-
DriveFSListBoxModel *model{nullptr};
356+
jcmp::ListView *listView{nullptr};
357+
358+
DriveFSRowComponent(BrowserPane *p, jcmp::ListView *v) : browserPane(p), listView(v) {}
393359

394-
juce::ListBox *enclosingBox() { return browserPane->devicesPane->driveFSArea->lbox.get(); }
395360
bool isDragging{false};
396361
bool isMouseDownWithoutDrag{false};
397362
bool hasStartedPreview{false};
@@ -414,7 +379,7 @@ struct DriveFSListBoxRow : public juce::Component
414379
}
415380
}
416381

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

419384
if (event.mods.isPopupMenu())
420385
{
@@ -454,10 +419,18 @@ struct DriveFSListBoxRow : public juce::Component
454419
{
455420
isDragging = false;
456421
}
457-
else
458-
{
459-
enclosingBox()->selectRowsBasedOnModifierKeys(rowNumber, event.mods, true);
460-
}
422+
}
423+
424+
bool isHovered;
425+
void mouseEnter(const juce::MouseEvent &) override
426+
{
427+
isHovered = true;
428+
repaint();
429+
}
430+
void mouseExit(const juce::MouseEvent &) override
431+
{
432+
isHovered = false;
433+
repaint();
461434
}
462435

463436
void stopPreview()
@@ -480,7 +453,11 @@ struct DriveFSListBoxRow : public juce::Component
480453
const auto &data = browserPane->devicesPane->driveFSArea->contents;
481454
if (rowNumber >= 0 && rowNumber < data.size())
482455
{
483-
if (data[rowNumber].is_directory())
456+
if (data[rowNumber] == fs::path(".."))
457+
{
458+
browserPane->devicesPane->driveFSArea->upOneLevel();
459+
}
460+
else if (data[rowNumber].is_directory())
484461
{
485462
browserPane->devicesPane->driveFSArea->setCurrentPath(data[rowNumber].path());
486463
}
@@ -547,21 +524,22 @@ struct DriveFSListBoxRow : public juce::Component
547524
fillColor = browserPane->editor->themeColor(theme::ColorMap::bg_3);
548525
textColor = browserPane->editor->themeColor(theme::ColorMap::generic_content_high);
549526
}
527+
else if (isHovered)
528+
{
529+
fillColor = browserPane->editor->themeColor(theme::ColorMap::bg_3);
530+
}
550531
g.setColour(fillColor);
551532
g.fillRect(0, 0, width, height);
552-
// TODO: Replace with glyph painter fo course
553-
auto r = juce::Rectangle<int>(1, (height - 10) / 2, 10, 10);
533+
auto r = juce::Rectangle<int>(1, (height - 14) / 2, 14, 14);
554534
if (entry.is_directory())
555535
{
556-
g.setColour(textColor.withAlpha(0.5f));
557-
g.fillRect(r);
558-
g.setColour(textColor.brighter(0.4f));
559-
g.drawRect(r);
536+
jcmp::GlyphPainter::paintGlyph(g, r, jcmp::GlyphPainter::FOLDER,
537+
textColor.withAlpha(isSelected ? 1.f : 0.5f));
560538
}
561539
else
562540
{
563-
jcmp::GlyphPainter::paintGlyph(g, r, jcmp::GlyphPainter::TUNING,
564-
textColor.withAlpha(0.5f));
541+
jcmp::GlyphPainter::paintGlyph(g, r, jcmp::GlyphPainter::FILE_MUSIC,
542+
textColor.withAlpha(isSelected ? 1.f : 0.5f));
565543
}
566544

567545
if (hasStartedPreview)
@@ -571,47 +549,40 @@ struct DriveFSListBoxRow : public juce::Component
571549
// textColor.withAlpha(0.5f));
572550
}
573551
g.setColour(textColor);
574-
g.drawText(entry.path().filename().u8string(), 14, 1, width - 16, height - 2,
552+
g.drawText(entry.path().filename().u8string(), 16, 1, width - 16, height - 2,
575553
juce::Justification::centredLeft);
576554
}
577555
}
578556
};
579557

580-
juce::Component *
581-
DriveFSListBoxModel::refreshComponentForRow(int rowNumber, bool isRowSelected,
582-
juce::Component *existingComponentToUpdate)
558+
void DriveFSArea::setupListView()
583559
{
584-
if (!browserPane || !browserPane->devicesPane || !browserPane->devicesPane->driveFSArea)
585-
return nullptr;
560+
listView->getRowCount = [this]() -> uint32_t {
561+
if (!browserPane || !browserPane->devicesPane || !browserPane->devicesPane->driveFSArea)
562+
return 0;
586563

587-
const auto &data = browserPane->devicesPane->driveFSArea->contents;
588-
if (rowNumber >= 0 && rowNumber < data.size())
589-
{
590-
auto rc = dynamic_cast<DriveFSListBoxRow *>(existingComponentToUpdate);
591-
592-
if (!rc)
564+
return browserPane->devicesPane->driveFSArea->contents.size();
565+
};
566+
listView->getRowHeight = [this]() { return 18; };
567+
listView->makeRowComponent = [this]() {
568+
return std::make_unique<DriveFSRowComponent>(browserPane, listView.get());
569+
};
570+
listView->assignComponentToRow = [this](const auto &c, auto r) {
571+
auto dfs = dynamic_cast<DriveFSRowComponent *>(c.get());
572+
if (dfs)
593573
{
594-
// Should never happen but
595-
if (existingComponentToUpdate)
596-
{
597-
delete existingComponentToUpdate;
598-
existingComponentToUpdate = nullptr;
599-
}
600-
601-
rc = new DriveFSListBoxRow();
574+
dfs->rowNumber = r;
575+
dfs->repaint();
602576
}
603-
604-
rc->isSelected = isRowSelected;
605-
rc->rowNumber = rowNumber;
606-
rc->browserPane = browserPane;
607-
rc->model = this;
608-
rc->repaint();
609-
return rc;
610-
}
611-
612-
if (existingComponentToUpdate)
613-
delete existingComponentToUpdate;
614-
return nullptr;
577+
};
578+
listView->setRowSelection = [this](const auto &c, auto r) {
579+
auto dfs = dynamic_cast<DriveFSRowComponent *>(c.get());
580+
if (dfs)
581+
{
582+
dfs->isSelected = r;
583+
dfs->repaint();
584+
}
585+
};
615586
}
616587

617588
struct FavoritesPane : TempPane

0 commit comments

Comments
 (0)