@@ -371,7 +371,8 @@ class PaletteSelector final : public TextButton {
371371 {
372372 if (e.mods .isRightButtonDown ()) {
373373 PopupMenu menu;
374- menu.addItem (" Delete palette" , rightClicked);
374+ menu.addItem (" Export palette" , exportClicked);
375+ menu.addItem (" Delete palette" , deleteClicked);
375376 menu.showMenuAsync (PopupMenu::Options ());
376377 }
377378
@@ -419,7 +420,8 @@ class PaletteSelector final : public TextButton {
419420 return palette;
420421 }
421422
422- std::function<void ()> rightClicked = [] { };
423+ std::function<void ()> exportClicked = [] { };
424+ std::function<void ()> deleteClicked = [] { };
423425
424426private:
425427 ValueTree palette;
@@ -472,6 +474,7 @@ class Palettes final : public Component
472474 addButton.onClick = [this ] {
473475 auto menu = new PopupMenu ();
474476 menu->addItem (1 , " New palette" );
477+ menu->addItem (2 , " Import palette" );
475478
476479 PopupMenu defaultPalettesMenu;
477480
@@ -502,10 +505,22 @@ class Palettes final : public Component
502505 auto * parent = ProjectInfo::canUseSemiTransparentWindows () ? editor->calloutArea .get () : nullptr ;
503506
504507 ArrowPopupMenu::showMenuAsync (menu, PopupMenu::Options ().withMinimumWidth (100 ).withMaximumNumColumns (1 ).withTargetComponent (&addButton).withParentComponent (parent), [this , menu](int const result) {
505- if (result > 0 ) {
508+ if (result == 1 ) {
506509 auto newUntitledPalette = ValueTree (" Palette" );
507510 newUntitledPalette.setProperty (" Name" , var (" Untitled palette" ), nullptr );
508511 newPalette (newUntitledPalette);
512+ } else if (result == 2 ) {
513+ Dialogs::showOpenDialog ([this ](URL const & url) {
514+ auto const result = url.getLocalFile ();
515+ if (!result.exists ())
516+ return ;
517+
518+ auto const paletteXml = result.loadFileAsString ();
519+ auto importedPalette = ValueTree::fromXml (paletteXml);
520+ importedPalette.setProperty (" Name" , var (result.getFileNameWithoutExtension ()), nullptr );
521+ newPalette (importedPalette);
522+ },
523+ true , false , " *.pdpalette" , " PaletteLocation" , getTopLevelComponent ());
509524 }
510525
511526 MessageManager::callAsync ([menu, this ] {
@@ -827,7 +842,19 @@ class Palettes final : public Component
827842 }
828843 };
829844
830- button->rightClicked = [this , newPaletteTree] {
845+ button->exportClicked = [this , newPaletteTree] {
846+ auto paletteContent = newPaletteTree.toXmlString ();
847+
848+ Dialogs::showSaveDialog ([paletteContent](URL const & url) {
849+ auto const result = url.getLocalFile ();
850+ if (result.getParentDirectory ().exists ()) {
851+ result.replaceWithText (paletteContent);
852+ }
853+ },
854+ " *.pdpalette" , " PaletteLocation" , getTopLevelComponent ());
855+ };
856+
857+ button->deleteClicked = [this , newPaletteTree] {
831858 for (int i = 0 ; i < paletteSelectors.size (); i++) {
832859 auto * paletteSelector = paletteSelectors[i];
833860 if (paletteSelector->getTree () == newPaletteTree) {
@@ -846,6 +873,7 @@ class Palettes final : public Component
846873 palettesTree.removeChild (newPaletteTree, nullptr );
847874 resized ();
848875 };
876+
849877 paletteBar.addAndMakeVisible (button);
850878
851879 if (!construct) {
0 commit comments