@@ -209,48 +209,16 @@ struct DriveArea : juce::Component, HasEditor
209
209
}
210
210
};
211
211
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
-
227
212
struct DriveFSArea : juce::Component, HasEditor
228
213
{
229
214
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;
233
216
234
217
DriveFSArea (BrowserPane *b, SCXTEditor *e) : browserPane(b), HasEditor(e)
235
218
{
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);
254
222
}
255
223
256
224
void paint (juce::Graphics &g) override
@@ -266,14 +234,12 @@ struct DriveFSArea : juce::Component, HasEditor
266
234
{
267
235
rootPath = p;
268
236
currentPath = p;
269
- dotDot->setEnabled (false );
270
237
recalcContents ();
271
238
}
272
239
273
240
void setCurrentPath (const fs::path &p)
274
241
{
275
242
currentPath = p;
276
- dotDot->setEnabled (currentPath > rootPath);
277
243
recalcContents ();
278
244
}
279
245
@@ -290,6 +256,7 @@ struct DriveFSArea : juce::Component, HasEditor
290
256
{
291
257
// Make a copy for now. this sucks and we should be smarter
292
258
contents.clear ();
259
+ auto lcontents = contents;
293
260
try
294
261
{
295
262
for (auto const &dir_entry : fs::directory_iterator{currentPath})
@@ -307,26 +274,31 @@ struct DriveFSArea : juce::Component, HasEditor
307
274
308
275
if (include)
309
276
{
310
- contents .push_back (dir_entry);
277
+ lcontents .push_back (dir_entry);
311
278
}
312
279
}
313
280
}
314
281
catch (const fs::filesystem_error &e)
315
282
{
316
283
SCLOG (e.what ());
317
284
}
318
- std::sort (contents .begin (), contents .end (), [](auto &a, auto &b) {
285
+ std::sort (lcontents .begin (), lcontents .end (), [](auto &a, auto &b) {
319
286
return strnatcasecmp (a.path ().u8string ().c_str (), b.path ().u8string ().c_str ()) < 0 ;
320
287
});
321
- lbox->updateContent ();
288
+ if (currentPath > rootPath)
289
+ contents.emplace_back (" .." );
290
+ for (auto &c : lcontents)
291
+ contents.emplace_back (c);
292
+ listView->refresh ();
322
293
}
323
294
324
295
void resized () override
325
296
{
326
297
auto bd = getLocalBounds ().reduced (1 );
327
- dotDot->setBounds (bd.withHeight (20 ));
328
- lbox->setBounds (bd.withTrimmedTop (22 ));
298
+ listView->setBounds (bd);
329
299
}
300
+
301
+ void setupListView ();
330
302
};
331
303
332
304
struct DevicesPane : HasEditor, juce::Component
@@ -376,22 +348,15 @@ void DriveArea::DriveAreaRow::mouseDown(const juce::MouseEvent &e)
376
348
}
377
349
}
378
350
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
388
352
{
389
353
bool isSelected;
390
354
int rowNumber;
391
355
BrowserPane *browserPane{nullptr };
392
- DriveFSListBoxModel *model{nullptr };
356
+ jcmp::ListView *listView{nullptr };
357
+
358
+ DriveFSRowComponent (BrowserPane *p, jcmp::ListView *v) : browserPane(p), listView(v) {}
393
359
394
- juce::ListBox *enclosingBox () { return browserPane->devicesPane ->driveFSArea ->lbox .get (); }
395
360
bool isDragging{false };
396
361
bool isMouseDownWithoutDrag{false };
397
362
bool hasStartedPreview{false };
@@ -414,7 +379,7 @@ struct DriveFSListBoxRow : public juce::Component
414
379
}
415
380
}
416
381
417
- enclosingBox ()-> selectRowsBasedOnModifierKeys (rowNumber, event. mods , false );
382
+ listView-> rowSelected (rowNumber, true );
418
383
419
384
if (event.mods .isPopupMenu ())
420
385
{
@@ -454,10 +419,18 @@ struct DriveFSListBoxRow : public juce::Component
454
419
{
455
420
isDragging = false ;
456
421
}
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 ();
461
434
}
462
435
463
436
void stopPreview ()
@@ -480,7 +453,11 @@ struct DriveFSListBoxRow : public juce::Component
480
453
const auto &data = browserPane->devicesPane ->driveFSArea ->contents ;
481
454
if (rowNumber >= 0 && rowNumber < data.size ())
482
455
{
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 ())
484
461
{
485
462
browserPane->devicesPane ->driveFSArea ->setCurrentPath (data[rowNumber].path ());
486
463
}
@@ -547,21 +524,22 @@ struct DriveFSListBoxRow : public juce::Component
547
524
fillColor = browserPane->editor ->themeColor (theme::ColorMap::bg_3);
548
525
textColor = browserPane->editor ->themeColor (theme::ColorMap::generic_content_high);
549
526
}
527
+ else if (isHovered)
528
+ {
529
+ fillColor = browserPane->editor ->themeColor (theme::ColorMap::bg_3);
530
+ }
550
531
g.setColour (fillColor);
551
532
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 );
554
534
if (entry.is_directory ())
555
535
{
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 ));
560
538
}
561
539
else
562
540
{
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 ));
565
543
}
566
544
567
545
if (hasStartedPreview)
@@ -571,47 +549,40 @@ struct DriveFSListBoxRow : public juce::Component
571
549
// textColor.withAlpha(0.5f));
572
550
}
573
551
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 ,
575
553
juce::Justification::centredLeft);
576
554
}
577
555
}
578
556
};
579
557
580
- juce::Component *
581
- DriveFSListBoxModel::refreshComponentForRow (int rowNumber, bool isRowSelected,
582
- juce::Component *existingComponentToUpdate)
558
+ void DriveFSArea::setupListView ()
583
559
{
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 ;
586
563
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)
593
573
{
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 ();
602
576
}
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
+ };
615
586
}
616
587
617
588
struct FavoritesPane : TempPane
0 commit comments