--- ../Rack/src/app/ModuleWidget.cpp	2022-09-21 19:49:12.198540676 +0100
+++ ModuleWidget.cpp	2022-12-02 19:11:45.780215974 +0000
@@ -1,3 +1,32 @@
+/*
+ * DISTRHO Cardinal Plugin
+ * Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 3 of
+ * the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * For a full copy of the GNU General Public License see the LICENSE file.
+ */
+
+/**
+ * This file is an edited version of VCVRack's ModuleWidget.cpp
+ * Copyright (C) 2016-2021 VCV.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ */
+
+#include "../../CardinalCommon.hpp"
+
 #include <thread>
 #include <regex>
 
@@ -375,7 +404,7 @@
 			if (e.action == GLFW_PRESS) {
 				// Open selection context menu on right-click
 				ui::Menu* menu = createMenu();
-				APP->scene->rack->appendSelectionContextMenu(menu);
+				patchUtils::appendSelectionContextMenu(menu);
 			}
 			e.consume(this);
 		}
@@ -627,6 +656,9 @@
 	std::string presetDir = model->getUserPresetDirectory();
 	system::createDirectories(presetDir);
 
+	WeakPtr<ModuleWidget> weakThis = this;
+	async_dialog_filebrowser(false, nullptr, presetDir.c_str(), "Load preset", [=](char* pathC) {
+
 	// Delete directories if empty
 	DEFER({
 		try {
@@ -638,10 +670,8 @@
 		}
 	});
 
-	osdialog_filters* filters = osdialog_filters_parse(PRESET_FILTERS);
-	DEFER({osdialog_filters_free(filters);});
-
-	char* pathC = osdialog_file(OSDIALOG_OPEN, presetDir.c_str(), NULL, filters);
+	if (!weakThis)
+		return;
 	if (!pathC) {
 		// No path selected
 		return;
@@ -649,11 +679,13 @@
 	DEFER({std::free(pathC);});
 
 	try {
-		loadAction(pathC);
+		weakThis->loadAction(pathC);
 	}
 	catch (Exception& e) {
-		osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, e.what());
+		async_dialog_message(e.what());
 	}
+
+	});
 }
 
 void ModuleWidget::save(std::string filename) {
@@ -715,6 +747,9 @@
 	std::string presetDir = model->getUserPresetDirectory();
 	system::createDirectories(presetDir);
 
+	WeakPtr<ModuleWidget> weakThis = this;
+	async_dialog_filebrowser(true, "preset.vcvm", presetDir.c_str(), "Save preset", [=](char* pathC) {
+
 	// Delete directories if empty
 	DEFER({
 		try {
@@ -726,10 +761,8 @@
 		}
 	});
 
-	osdialog_filters* filters = osdialog_filters_parse(PRESET_FILTERS);
-	DEFER({osdialog_filters_free(filters);});
-
-	char* pathC = osdialog_file(OSDIALOG_SAVE, presetDir.c_str(), "Untitled.vcvm", filters);
+	if (!weakThis)
+		return;
 	if (!pathC) {
 		// No path selected
 		return;
@@ -741,7 +774,8 @@
 	if (system::getExtension(path) != ".vcvm")
 		path += ".vcvm";
 
-	save(path);
+	weakThis->save(path);
+	});
 }
 
 void ModuleWidget::disconnect() {
@@ -944,16 +978,12 @@
 			std::regex r("^\\d+_");
 			name = std::regex_replace(name, r, "");
 
-			if (system::isDirectory(path)) {
-				hasPresets = true;
-
-				menu->addChild(createSubmenuItem(name, "", [=](ui::Menu* menu) {
-					if (!moduleWidget)
-						return;
-					appendPresetItems(menu, moduleWidget, path);
-				}));
+			if (false) {
 			}
 			else if (system::getExtension(path) == ".vcvm" && name != "template") {
+				if (!hasPresets)
+					menu->addChild(new ui::MenuSeparator);
+
 				hasPresets = true;
 
 				menu->addChild(createMenuItem(name, "", [=]() {
@@ -963,15 +993,12 @@
 						moduleWidget->loadAction(path);
 					}
 					catch (Exception& e) {
-						osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, e.what());
+						async_dialog_message(e.what());
 					}
 				}));
 			}
 		}
 	}
-	if (!hasPresets) {
-		menu->addChild(createMenuLabel("(None)"));
-	}
 };
 
 
@@ -1010,6 +1037,7 @@
 			weakThis->loadDialog();
 		}));
 
+		/* TODO requires setting up user dir
 		menu->addChild(createMenuItem("Save as", "", [=]() {
 			if (!weakThis)
 				return;
@@ -1032,10 +1060,13 @@
 		menu->addChild(new ui::MenuSeparator);
 		menu->addChild(createMenuLabel("User presets"));
 		appendPresetItems(menu, weakThis, weakThis->model->getUserPresetDirectory());
+		*/
 
 		// Scan `<plugin dir>/presets/<module slug>` for presets.
+		/* TODO enable only after setting up user dir
 		menu->addChild(new ui::MenuSeparator);
 		menu->addChild(createMenuLabel("Factory presets"));
+		*/
 		appendPresetItems(menu, weakThis, weakThis->model->getFactoryPresetDirectory());
 	}));
 
@@ -1127,4 +1158,4 @@
 
 
 } // namespace app
-} // namespace rack
\ No newline at end of file
+} // namespace rack
