Browse Source

[hide] Renamed ContextMenu2 -> ContextMenu

Clément Espeute 10 tháng trước cách đây
mục cha
commit
61cbc5995b

+ 597 - 7
hide/comp/ContextMenu.hx

@@ -1,12 +1,602 @@
 package hide.comp;
 
-typedef ContextMenuItem = hide.comp.ContextMenu2.MenuItem;
+typedef MenuItem = {
+    ?label: String,
+    ?isSeparator: Bool,
+    ?menu: Array<MenuItem>,
+    ?click: Void -> Void,
+    ?enabled: Bool,
+    ?stayOpen : Bool,
+    ?icon: String,
+    ?keys: String,
+    ?checked: Bool,
+    ?tooltip: String
+}
+
+// for retrocompat with the old menu system
+typedef ContextMenuItem = hide.comp.ContextMenu.MenuItem;
+
+
+enum SearchMode {
+    /**
+        No search bar or search functionality
+    **/
+    None;
+
+    /**
+        Search bar is hidden, is shown when the user starts typing anything
+    **/
+    Hidden;
+
+    /**
+        Search bar is always visible
+    **/
+    Visible;
+}
+
+typedef MenuOptions = {
+    ?search: SearchMode, // default to Hidden for top level context menus
+    ?widthOverride: Int, // if set, force the width of the first menu
+
+    /**
+        Used to automaticaly widthOverride based on context (see createDropdown)
+    **/
+    ?autoWidth: Bool,
+
+    /**
+        Set this to true if you have no icons/checkmarks in your menu and you want to hide the padding on the left of the entries names
+    **/
+    ?noIcons: Bool,
+
+    /**
+        If this set, it will be used to place the element if it goes offscreen like so
+
+               | - placementWidth - |
+        | --- your context menu --- |  <--
+    **/
+    ?placementWidth: Int,
+
+    ?placementHeight: Int,
+
+}
 
 class ContextMenu {
-	public function new( config : Array<ContextMenuItem> ) {
-		var ide = hide.Ide.inst;
-		#if js
-		ContextMenu2.createFromPoint(ide.mouseX, ide.mouseY, config);
-		#end
-	}
+    var rootElement : js.html.Element;
+    var menu : js.html.MenuElement;
+    var searchInput : js.html.InputElement;
+    var searchBar : js.html.DivElement;
+
+    var options: MenuOptions;
+
+    var items: Array<MenuItem> = [];
+
+    var currentSubmenu: ContextMenu = null;
+    var currentSubmenuItemId: Int = -1;
+    var parentMenu: ContextMenu = null;
+
+    var originalPos: {x: Float, y:Float};
+
+    var filter = "";
+    var filteredItems : Array<MenuItem>;
+    var flatItems : Array<{menuItem: MenuItem, elem: js.html.Element, index: Int}> = [];
+    var selected = 0;
+
+    var autoCleanupTimer: haxe.Timer;
+
+    var popupTimer: haxe.Timer;
+    final openDelayMs = 250;
+
+    /**
+        Create a context menu from a js event. If you have a jQuery event, just `cast` it
+    **/
+    public static function createFromEvent(e: js.html.MouseEvent, items: Array<MenuItem>, options: MenuOptions = null) {
+        return new ContextMenu(items, cast e.target, null, {x: e.clientX, y: e.clientY}, options ?? {});
+    }
+
+    /**
+        Create a context menu at the given x, y position in browser coordinates
+    **/
+    public static function createFromPoint(x: Float, y: Float, items: Array<MenuItem>, options: MenuOptions = null) {
+        return new ContextMenu(items, null, null, {x:x, y:y}, options ?? {});
+    }
+
+    /**
+        Create a context menu under the given element. Will make the dropdown menu have the width of the element if option.autoWidth is set
+    **/
+    public static function createDropdown(element: js.html.Element, items: Array<MenuItem>, options: MenuOptions = null) {
+        options = options ?? {};
+        var rect = element.getBoundingClientRect();
+        if (options.autoWidth) {
+            options.widthOverride = Std.int(rect.width);
+        }
+        options.placementWidth = options.placementWidth ?? Std.int(rect.width);
+        options.placementHeight = options.placementHeight ?? -Std.int(rect.height);
+        return new ContextMenu(items, element, null, {x: rect.left, y:rect.bottom}, options);
+    }
+
+
+    /**
+        The constructor is public for backward compatibility reasons. Prefer using the static "createXXX" functions to create a
+        context menu
+    **/
+    public function new(items: Array<MenuItem>, parentElement: js.html.Element = null, parentMenu: ContextMenu = null, absPos: {x: Float, y: Float} = null, options: MenuOptions = null) {
+        this.items = items;
+        this.parentMenu = parentMenu;
+        if (absPos == null) {
+            originalPos = {
+                x: Ide.inst.mouseX,
+                y: Ide.inst.mouseY,
+            }
+        } else {
+            originalPos = absPos;
+        }
+
+        // Default options values
+        options = options ?? {};
+        options.search = options.search ?? Hidden;
+
+        this.options = options;
+
+        var nearest : js.html.Element = if (parentMenu != null) {
+                parentElement;
+            } else if (parentElement != null) {
+                parentElement.closest("[popover]") ?? js.Browser.document.body;
+            } else {
+                js.Browser.document.body;
+            };
+
+        rootElement = js.Browser.document.createDivElement();
+        rootElement.setAttribute("tabindex", "0");
+        nearest.appendChild(rootElement);
+
+        rootElement.classList.add("context-menu2");
+        if (options.widthOverride != null)
+            rootElement.style.width = '${options.widthOverride}px';
+        untyped rootElement.popover = parentMenu != null ? "manual" : "auto";
+        rootElement.style.left = '${0}px';
+        rootElement.style.top = '${0}px';
+        untyped rootElement.showPopover();
+
+        menu = js.Browser.document.createMenuElement();
+        if (options.search != None) {
+            searchBar = js.Browser.document.createDivElement();
+            rootElement.appendChild(searchBar);
+            searchBar.classList.add("search-bar");
+
+            searchInput = js.Browser.document.createInputElement();
+            searchInput.type = "text";
+            searchInput.placeholder = "Search ...";
+            searchInput.onkeyup = (e:js.html.KeyboardEvent) -> {
+                if (filter != searchInput.value) {
+                    filter = searchInput.value;
+                    refreshMenu();
+                }
+            }
+
+            searchInput.onblur = (e) -> {
+                rootElement.focus();
+            }
+
+            searchBar.appendChild(searchInput);
+        }
+        rootElement.appendChild(menu);
+
+        rootElement.ontoggle = (e) -> {
+            if (e.newState == "closed") {
+                cleanup();
+            }
+        }
+
+        refreshMenu();
+        refreshPos();
+
+        if (parentMenu == null) {
+            rootElement.addEventListener("keydown", onGlobalKeyDown);
+            if (options.search == Visible) {
+                searchInput.focus();
+            }
+            else {
+                rootElement.focus();
+            }
+        }
+
+        if (parentMenu == null && parentElement != null) {
+            autoCleanupTimer = new haxe.Timer(10);
+            autoCleanupTimer.run = () -> {
+                if (parentElement.closest("body") == null) {
+                    close();
+                }
+            };
+        }
+    }
+
+    function onGlobalKeyDown(e:js.html.KeyboardEvent) {
+        if (!handleMovementKeys(e)) {
+            if (searchBar != null) {
+                searchBar.style.display = "block";
+                searchInput.focus();
+            }
+        }
+    }
+
+    function refreshPos() {
+        // Make sure the menu never goes out of bounds
+        var rect = rootElement.getBoundingClientRect();
+        var y = originalPos.y + Std.parseInt(js.Browser.window.getComputedStyle(rootElement).getPropertyValue("--offset-y"));
+        var x = originalPos.x + Std.parseInt(js.Browser.window.getComputedStyle(rootElement).getPropertyValue("--offset-x"));
+
+
+        if (y + rect.height > js.Browser.window.innerHeight) {
+            if (parentMenu != null) {
+                y = js.Browser.window.innerHeight - rect.height;
+            } else {
+                y = originalPos.y - rect.height;
+                if (options.placementHeight != null) {
+                    y += options.placementHeight;
+                }
+            }
+
+        }
+        if (y < 0) {
+            y = 0;
+        }
+
+        if (x + rect.width > js.Browser.window.innerWidth) {
+            if (parentMenu != null) {
+                x = parentMenu.rootElement.getBoundingClientRect().left - rect.width;
+            } else {
+                // put the menu to the left of the cursor if there is no parent menu
+                x = originalPos.x - rect.width;
+                if (options.placementWidth != null) {
+                    x += options.placementWidth;
+                }
+            }
+        }
+        if (x < 0) {
+            x = 0;
+        }
+
+        rootElement.style.left = '${x}px';
+        rootElement.style.top = '${y}px';
+    }
+
+    function handleMovementKeys(e: js.html.KeyboardEvent) : Bool {
+        if (currentSubmenu != null) {
+            trace("submenu");
+            return currentSubmenu.handleMovementKeys(e);
+        }
+        if (e.key == "Escape") {
+            close();
+            return true;
+        }
+        else if (e.key == "ArrowUp") {
+            e.preventDefault();
+            updateSelection(selected - 1);
+            return true;
+        }
+        else if (e.key == "ArrowDown") {
+            e.preventDefault();
+            updateSelection(selected + 1);
+            return true;
+        }
+        else if (e.key == "Enter") {
+            e.preventDefault();
+            if (selected >= 0 && flatItems != null) {
+                if (flatItems[selected].menuItem.menu != null) {
+                    currentSubmenuItemId = flatItems[selected].index;
+                    refreshSubmenu();
+                    currentSubmenu.updateSelection(0);
+                } else {
+                    flatItems[selected].elem.click();
+                }
+            }
+            return true;
+        }
+        else if (filter == "") {
+            if (e.key == "ArrowRight") {
+                if (selected >= 0 && flatItems[selected].menuItem.menu != null) {
+                    currentSubmenuItemId = flatItems[selected].index;
+                    refreshSubmenu();
+                    currentSubmenu.updateSelection(0);
+                }
+                return true;
+            }
+            if (e.key == "ArrowLeft" && parentMenu != null) {
+                close();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public dynamic function onClose() {
+
+    }
+
+    function refreshMenu() {
+        if (popupTimer != null) {
+            popupTimer.stop();
+            popupTimer = null;
+        }
+
+        menu.innerHTML = "";
+
+        if (filter == "") {
+            flatItems = [];
+            selected = -1;
+
+            if (searchBar != null && options.search == Hidden) {
+                searchBar.style.display = "none";
+            }
+
+            filteredItems = null;
+            for (id => item in items) {
+                if (item.isSeparator) {
+                    var hr = js.Browser.document.createHRElement();
+                    menu.appendChild(hr);
+                } else {
+                    //var li = js.Browser.document.createLIElement();
+                    var li = createItem(item, id);
+                    menu.appendChild(li);
+                    if (item.enabled ?? true) {
+                        flatItems.push({menuItem: item, elem:li, index: id});
+                    }
+                }
+            }
+        }
+        else {
+            filteredItems = [];
+            flatItems = [];
+
+            searchBar.style.display = "block";
+
+            closeSubmenu();
+
+            var filterLower = filter.toLowerCase();
+
+            function filterElements(items: Array<MenuItem>, parentMatch: Bool) : Array<MenuItem> {
+                var filteredItems : Array<MenuItem> = [];
+                for (id => item in items) {
+                    var match = parentMatch || (item.label != null && StringTools.contains(item.label.toLowerCase(), filterLower));
+                    if (item.menu != null) {
+                        var subItems = filterElements(item.menu, match);
+                        if (subItems.length > 0) {
+                            filteredItems.push({label: item.label, menu: subItems});
+                        }
+                    }
+                    else {
+                        if (match) {
+                            filteredItems.push(item);
+                        }
+                    }
+                }
+                return filteredItems;
+            }
+
+            filteredItems = filterElements(items, false);
+
+            var submenuStack : Array<Iterator<MenuItem>> = [];
+            submenuStack.push(filteredItems.iterator());
+
+            // avoid double separators in a row
+            var lastSeparator : js.html.Element = null;
+            while (submenuStack.length > 0) {
+                var top = submenuStack[submenuStack.length-1];
+                if (!top.hasNext()) {
+                    submenuStack.pop();
+
+                    if (submenuStack.length > 0 && lastSeparator == null) {
+                        var hr = js.Browser.document.createHRElement();
+                        menu.appendChild(hr);
+                        lastSeparator = hr;
+                    }
+
+                    continue;
+                }
+
+                var item = top.next();
+                if (item.menu != null) {
+                    var li = js.Browser.document.createLIElement();
+                    menu.appendChild(li);
+                    li.style.setProperty("--level", '${submenuStack.length-1}');
+                    li.innerText = item.label;
+                    li.classList.add("submenu-inline-header");
+                    lastSeparator = null;
+                    submenuStack.push(item.menu.iterator());
+                }
+                else {
+                    var li = createItem(item, flatItems.length);
+                    menu.appendChild(li);
+                    li.style.setProperty("--level", '${submenuStack.length-1}');
+                    if (item.enabled == null || item.enabled == true) {
+                        flatItems.push({menuItem: item, elem: li, index: flatItems.length});
+                    }
+                    lastSeparator = null;
+                }
+            }
+            selected = -1;
+            updateSelection(0);
+
+            if (lastSeparator != null) {
+                lastSeparator.remove();
+            }
+        }
+    }
+
+    function close() {
+        cleanup();
+    }
+
+    function closeAll() {
+        var menu = this;
+        while(menu.parentMenu != null) {
+            menu = menu.parentMenu;
+        }
+        menu.close();
+    }
+
+    function createItem(menuItem: MenuItem, id: Int) : js.html.Element {
+        var li = js.Browser.document.createLIElement();
+
+        var icon = null;
+        if (options.noIcons == null || options.noIcons == false) {
+            icon = js.Browser.document.createSpanElement();
+            li.appendChild(icon);
+            icon.classList.add("icon");
+            if (menuItem.icon != null) {
+                icon.classList.add("fa");
+                icon.classList.add('fa-${menuItem.icon}');
+            }
+        }
+
+        if (menuItem.tooltip != null) {
+            li.title = menuItem.tooltip;
+        }
+
+        function refreshCheck() {
+            if (icon != null && menuItem.checked != null) {
+                icon.classList.add("fa");
+                icon.classList.toggle("fa-check-square", menuItem.checked);
+                icon.classList.toggle("fa-square-o", !menuItem.checked);
+            }
+        }
+
+        refreshCheck();
+
+        var span = js.Browser.document.createSpanElement();
+        span.innerHTML = menuItem.label;
+        span.classList.add("label");
+        li.appendChild(span);
+
+        if (menuItem.keys != null) {
+            var span = js.Browser.document.createSpanElement();
+            span.innerHTML = menuItem.keys;
+            span.classList.add("shortcut");
+            li.appendChild(span);
+        }
+
+        if (menuItem.menu != null) {
+            var span = js.Browser.document.createSpanElement();
+            span.classList.add("arrow");
+            span.classList.add("fa");
+            span.classList.add("fa-caret-right");
+            li.appendChild(span);
+
+            if (menuItem.menu.length <= 0) {
+                menuItem.enabled = false;
+            }
+        }
+
+        if (menuItem.enabled ?? true) {
+            li.onmouseleave = (e: js.html.MouseEvent) -> {
+                if (popupTimer != null) {
+                    popupTimer.stop();
+                    popupTimer = null;
+                }
+            }
+
+            li.onmouseenter = (e: js.html.MouseEvent) -> {
+                if (popupTimer != null) {
+                    popupTimer.stop();
+                }
+                popupTimer = haxe.Timer.delay(() -> {
+                    closeSubmenu();
+                    currentSubmenuItemId = menuItem.menu != null ? id : -1;
+                    refreshSubmenu();
+                }, openDelayMs);
+            }
+
+            li.onclick = () -> {
+                if (menuItem.click != null) {
+                    menuItem.click();
+                }
+                if (menuItem.menu != null) {
+                    if (popupTimer != null) {
+                        popupTimer.stop();
+                    }
+                    closeSubmenu();
+                    currentSubmenuItemId = id;
+                    refreshSubmenu();
+                    return;
+                }
+                if (menuItem.checked != null) {
+                    menuItem.checked = !menuItem.checked;
+                    refreshCheck();
+                }
+                if (!menuItem.stayOpen) {
+                    closeAll();
+                }
+            }
+        } else {
+            li.classList.add("disabled");
+        }
+
+        return li;
+    }
+
+    function updateSelection(newIndex: Int) {
+        if (selected != -1) {
+            flatItems[selected].elem.classList.remove("highlight");
+        }
+        if (newIndex < 0) {
+            newIndex = flatItems.length-1;
+        }
+        else if (newIndex > flatItems.length - 1) {
+            newIndex = 0;
+        }
+        if (newIndex < 0 || newIndex >= flatItems.length) {
+            selected = -1;
+        }
+        else {
+            selected = newIndex;
+            flatItems[selected].elem.classList.add("highlight");
+            flatItems[selected].elem.scrollIntoView({block: cast "nearest"});
+        }
+    }
+
+    function cleanup() {
+        rootElement.remove();
+        if (currentSubmenu != null) {
+            currentSubmenu.close();
+        }
+        if (autoCleanupTimer != null) {
+            autoCleanupTimer.stop();
+            autoCleanupTimer = null;
+        }
+        if (parentMenu != null) {
+            if (parentMenu.currentSubmenu != this)
+                throw "parentMenu.currentSubmenu != this";
+            parentMenu.currentSubmenu = null;
+        }
+
+        if (parentMenu == null) {
+            rootElement.removeEventListener("keydown", onGlobalKeyDown);
+        }
+
+        onClose();
+    }
+
+    function closeSubmenu() {
+        if (currentSubmenu != null) {
+            var element = menu.children[currentSubmenuItemId];
+            if (element != null) {
+                element.classList.remove("open");
+            }
+            currentSubmenu.close();
+            currentSubmenu = null;
+            currentSubmenuItemId = -1;
+        }
+    }
+
+    function refreshSubmenu() {
+        if (currentSubmenu != null) {
+            return;
+        }
+        if (currentSubmenuItemId >= 0) {
+            var element = menu.children[currentSubmenuItemId];
+            element.classList.add("open");
+            var rect = element.getBoundingClientRect();
+            currentSubmenu = new ContextMenu(items[currentSubmenuItemId].menu, rootElement, this, {x: rect.right, y: rect.top}, {search: None, noIcons: options.noIcons});
+        }
+    }
 }

+ 0 - 585
hide/comp/ContextMenu2.hx

@@ -1,585 +0,0 @@
-package hide.comp;
-
-typedef MenuItem = {
-    ?label: String,
-    ?isSeparator: Bool,
-    ?menu: Array<MenuItem>,
-    ?click: Void -> Void,
-    ?enabled: Bool,
-    ?stayOpen : Bool,
-    ?icon: String,
-    ?keys: String,
-    ?checked: Bool,
-    ?tooltip: String
-}
-
-enum SearchMode {
-    /**
-        No search bar or search functionality
-    **/
-    None;
-
-    /**
-        Search bar is hidden, is shown when the user starts typing anything
-    **/
-    Hidden;
-
-    /**
-        Search bar is always visible
-    **/
-    Visible;
-}
-
-typedef MenuOptions = {
-    ?search: SearchMode, // default to Hidden for top level context menus
-    ?widthOverride: Int, // if set, force the width of the first menu
-
-    /**
-        Used to automaticaly widthOverride based on context (see createDropdown)
-    **/
-    ?autoWidth: Bool,
-
-    /**
-        Set this to true if you have no icons/checkmarks in your menu and you want to hide the padding on the left of the entries names
-    **/
-    ?noIcons: Bool,
-
-    /**
-        If this set, it will be used to place the element if it goes offscreen like so
-
-               | - placementWidth - |
-        | --- your context menu --- |  <--
-    **/
-    ?placementWidth: Int,
-
-    ?placementHeight: Int,
-
-}
-
-class ContextMenu2 {
-    var rootElement : js.html.Element;
-    var menu : js.html.MenuElement;
-    var searchInput : js.html.InputElement;
-    var searchBar : js.html.DivElement;
-
-    var options: MenuOptions;
-
-    var items: Array<MenuItem> = [];
-
-    var currentSubmenu: ContextMenu2 = null;
-    var currentSubmenuItemId: Int = -1;
-    var parentMenu: ContextMenu2 = null;
-
-    var originalPos: {x: Float, y:Float};
-
-    var filter = "";
-    var filteredItems : Array<MenuItem>;
-    var flatItems : Array<{menuItem: MenuItem, elem: js.html.Element, index: Int}> = [];
-    var selected = 0;
-
-    var autoCleanupTimer: haxe.Timer;
-
-    var popupTimer: haxe.Timer;
-    final openDelayMs = 250;
-
-    /**
-        Create a context menu from a js event. If you have a jQuery event, just `cast` it
-    **/
-    public static function createFromEvent(e: js.html.MouseEvent, items: Array<MenuItem>, options: MenuOptions = null) {
-        return new ContextMenu2(cast e.target, null, {x: e.clientX, y: e.clientY}, items, options ?? {});
-    }
-
-    /**
-        Create a context menu at the given x, y position in browser coordinates
-    **/
-    public static function createFromPoint(x: Float, y: Float , items: Array<MenuItem>, options: MenuOptions = null) {
-        return new ContextMenu2(null, null, {x:x, y:y}, items, options ?? {});
-    }
-
-    /**
-        Create a context menu under the given element. Will make the dropdown menu have the width of the element if option.autoWidth is set
-    **/
-    public static function createDropdown(element: js.html.Element, items: Array<MenuItem>, options: MenuOptions = null) {
-        options = options ?? {};
-        var rect = element.getBoundingClientRect();
-        if (options.autoWidth) {
-            options.widthOverride = Std.int(rect.width);
-        }
-        options.placementWidth = options.placementWidth ?? Std.int(rect.width);
-        options.placementHeight = options.placementHeight ?? -Std.int(rect.height);
-        return new ContextMenu2(element, null, {x: rect.left, y:rect.bottom}, items, options);
-    }
-
-    function new(parentElement: js.html.Element, parentMenu: ContextMenu2, absPos: {x: Float, y: Float}, items: Array<MenuItem>, options: MenuOptions) {
-        this.items = items;
-        this.parentMenu = parentMenu;
-        originalPos = absPos;
-
-        // Default options values
-        options.search = options.search ?? Hidden;
-
-        this.options = options;
-
-        var nearest : js.html.Element = if (parentMenu != null) {
-                parentElement;
-            } else if (parentElement != null) {
-                parentElement.closest("[popover]") ?? js.Browser.document.body;
-            } else {
-                js.Browser.document.body;
-            };
-
-        rootElement = js.Browser.document.createDivElement();
-        rootElement.setAttribute("tabindex", "0");
-        nearest.appendChild(rootElement);
-
-        rootElement.classList.add("context-menu2");
-        if (options.widthOverride != null)
-            rootElement.style.width = '${options.widthOverride}px';
-        untyped rootElement.popover = parentMenu != null ? "manual" : "auto";
-        rootElement.style.left = '${0}px';
-        rootElement.style.top = '${0}px';
-        untyped rootElement.showPopover();
-
-        menu = js.Browser.document.createMenuElement();
-        if (options.search != None) {
-            searchBar = js.Browser.document.createDivElement();
-            rootElement.appendChild(searchBar);
-            searchBar.classList.add("search-bar");
-
-            searchInput = js.Browser.document.createInputElement();
-            searchInput.type = "text";
-            searchInput.placeholder = "Search ...";
-            searchInput.onkeyup = (e:js.html.KeyboardEvent) -> {
-                if (filter != searchInput.value) {
-                    filter = searchInput.value;
-                    refreshMenu();
-                }
-            }
-
-            searchInput.onblur = (e) -> {
-                rootElement.focus();
-            }
-
-            searchBar.appendChild(searchInput);
-        }
-        rootElement.appendChild(menu);
-
-        rootElement.ontoggle = (e) -> {
-            if (e.newState == "closed") {
-                cleanup();
-            }
-        }
-
-        refreshMenu();
-        refreshPos();
-
-        if (parentMenu == null) {
-            rootElement.addEventListener("keydown", onGlobalKeyDown);
-            if (options.search == Visible) {
-                searchInput.focus();
-            }
-            else {
-                rootElement.focus();
-            }
-        }
-
-        if (parentMenu == null && parentElement != null) {
-            autoCleanupTimer = new haxe.Timer(10);
-            autoCleanupTimer.run = () -> {
-                if (parentElement.closest("body") == null) {
-                    close();
-                }
-            };
-        }
-    }
-
-    function onGlobalKeyDown(e:js.html.KeyboardEvent) {
-        if (!handleMovementKeys(e)) {
-            if (searchBar != null) {
-                searchBar.style.display = "block";
-                searchInput.focus();
-            }
-        }
-    }
-
-    function refreshPos() {
-        // Make sure the menu never goes out of bounds
-        var rect = rootElement.getBoundingClientRect();
-        var y = originalPos.y + Std.parseInt(js.Browser.window.getComputedStyle(rootElement).getPropertyValue("--offset-y"));
-        var x = originalPos.x + Std.parseInt(js.Browser.window.getComputedStyle(rootElement).getPropertyValue("--offset-x"));
-
-
-        if (y + rect.height > js.Browser.window.innerHeight) {
-            if (parentMenu != null) {
-                y = js.Browser.window.innerHeight - rect.height;
-            } else {
-                y = originalPos.y - rect.height;
-                if (options.placementHeight != null) {
-                    y += options.placementHeight;
-                }
-            }
-
-        }
-        if (y < 0) {
-            y = 0;
-        }
-
-        if (x + rect.width > js.Browser.window.innerWidth) {
-            if (parentMenu != null) {
-                x = parentMenu.rootElement.getBoundingClientRect().left - rect.width;
-            } else {
-                // put the menu to the left of the cursor if there is no parent menu
-                x = originalPos.x - rect.width;
-                if (options.placementWidth != null) {
-                    x += options.placementWidth;
-                }
-            }
-        }
-        if (x < 0) {
-            x = 0;
-        }
-
-        rootElement.style.left = '${x}px';
-        rootElement.style.top = '${y}px';
-    }
-
-    function handleMovementKeys(e: js.html.KeyboardEvent) : Bool {
-        if (currentSubmenu != null) {
-            trace("submenu");
-            return currentSubmenu.handleMovementKeys(e);
-        }
-        if (e.key == "Escape") {
-            close();
-            return true;
-        }
-        else if (e.key == "ArrowUp") {
-            e.preventDefault();
-            updateSelection(selected - 1);
-            return true;
-        }
-        else if (e.key == "ArrowDown") {
-            e.preventDefault();
-            updateSelection(selected + 1);
-            return true;
-        }
-        else if (e.key == "Enter") {
-            e.preventDefault();
-            if (selected >= 0 && flatItems != null) {
-                if (flatItems[selected].menuItem.menu != null) {
-                    currentSubmenuItemId = flatItems[selected].index;
-                    refreshSubmenu();
-                    currentSubmenu.updateSelection(0);
-                } else {
-                    flatItems[selected].elem.click();
-                }
-            }
-            return true;
-        }
-        else if (filter == "") {
-            if (e.key == "ArrowRight") {
-                if (selected >= 0 && flatItems[selected].menuItem.menu != null) {
-                    currentSubmenuItemId = flatItems[selected].index;
-                    refreshSubmenu();
-                    currentSubmenu.updateSelection(0);
-                }
-                return true;
-            }
-            if (e.key == "ArrowLeft" && parentMenu != null) {
-                close();
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public dynamic function onClose() {
-
-    }
-
-    function refreshMenu() {
-        if (popupTimer != null) {
-            popupTimer.stop();
-            popupTimer = null;
-        }
-
-        menu.innerHTML = "";
-
-        if (filter == "") {
-            flatItems = [];
-            selected = -1;
-
-            if (searchBar != null && options.search == Hidden) {
-                searchBar.style.display = "none";
-            }
-
-            filteredItems = null;
-            for (id => item in items) {
-                if (item.isSeparator) {
-                    var hr = js.Browser.document.createHRElement();
-                    menu.appendChild(hr);
-                } else {
-                    //var li = js.Browser.document.createLIElement();
-                    var li = createItem(item, id);
-                    menu.appendChild(li);
-                    if (item.enabled ?? true) {
-                        flatItems.push({menuItem: item, elem:li, index: id});
-                    }
-                }
-            }
-        }
-        else {
-            filteredItems = [];
-            flatItems = [];
-
-            searchBar.style.display = "block";
-
-            closeSubmenu();
-
-            var filterLower = filter.toLowerCase();
-
-            function filterElements(items: Array<MenuItem>, parentMatch: Bool) : Array<MenuItem> {
-                var filteredItems : Array<MenuItem> = [];
-                for (id => item in items) {
-                    var match = parentMatch || (item.label != null && StringTools.contains(item.label.toLowerCase(), filterLower));
-                    if (item.menu != null) {
-                        var subItems = filterElements(item.menu, match);
-                        if (subItems.length > 0) {
-                            filteredItems.push({label: item.label, menu: subItems});
-                        }
-                    }
-                    else {
-                        if (match) {
-                            filteredItems.push(item);
-                        }
-                    }
-                }
-                return filteredItems;
-            }
-
-            filteredItems = filterElements(items, false);
-
-            var submenuStack : Array<Iterator<MenuItem>> = [];
-            submenuStack.push(filteredItems.iterator());
-
-            // avoid double separators in a row
-            var lastSeparator : js.html.Element = null;
-            while (submenuStack.length > 0) {
-                var top = submenuStack[submenuStack.length-1];
-                if (!top.hasNext()) {
-                    submenuStack.pop();
-
-                    if (submenuStack.length > 0 && lastSeparator == null) {
-                        var hr = js.Browser.document.createHRElement();
-                        menu.appendChild(hr);
-                        lastSeparator = hr;
-                    }
-
-                    continue;
-                }
-
-                var item = top.next();
-                if (item.menu != null) {
-                    var li = js.Browser.document.createLIElement();
-                    menu.appendChild(li);
-                    li.style.setProperty("--level", '${submenuStack.length-1}');
-                    li.innerText = item.label;
-                    li.classList.add("submenu-inline-header");
-                    lastSeparator = null;
-                    submenuStack.push(item.menu.iterator());
-                }
-                else {
-                    var li = createItem(item, flatItems.length);
-                    menu.appendChild(li);
-                    li.style.setProperty("--level", '${submenuStack.length-1}');
-                    if (item.enabled == null || item.enabled == true) {
-                        flatItems.push({menuItem: item, elem: li, index: flatItems.length});
-                    }
-                    lastSeparator = null;
-                }
-            }
-            selected = -1;
-            updateSelection(0);
-
-            if (lastSeparator != null) {
-                lastSeparator.remove();
-            }
-        }
-    }
-
-    function close() {
-        cleanup();
-    }
-
-    function closeAll() {
-        var menu = this;
-        while(menu.parentMenu != null) {
-            menu = menu.parentMenu;
-        }
-        menu.close();
-    }
-
-    function createItem(menuItem: MenuItem, id: Int) : js.html.Element {
-        var li = js.Browser.document.createLIElement();
-
-        var icon = null;
-        if (options.noIcons == null || options.noIcons == false) {
-            icon = js.Browser.document.createSpanElement();
-            li.appendChild(icon);
-            icon.classList.add("icon");
-            if (menuItem.icon != null) {
-                icon.classList.add("fa");
-                icon.classList.add('fa-${menuItem.icon}');
-            }
-        }
-
-        if (menuItem.tooltip != null) {
-            li.title = menuItem.tooltip;
-        }
-
-        function refreshCheck() {
-            if (icon != null && menuItem.checked != null) {
-                icon.classList.add("fa");
-                icon.classList.toggle("fa-check-square", menuItem.checked);
-                icon.classList.toggle("fa-square-o", !menuItem.checked);
-            }
-        }
-
-        refreshCheck();
-
-        var span = js.Browser.document.createSpanElement();
-        span.innerHTML = menuItem.label;
-        span.classList.add("label");
-        li.appendChild(span);
-
-        if (menuItem.keys != null) {
-            var span = js.Browser.document.createSpanElement();
-            span.innerHTML = menuItem.keys;
-            span.classList.add("shortcut");
-            li.appendChild(span);
-        }
-
-        if (menuItem.menu != null) {
-            var span = js.Browser.document.createSpanElement();
-            span.classList.add("arrow");
-            span.classList.add("fa");
-            span.classList.add("fa-caret-right");
-            li.appendChild(span);
-
-            if (menuItem.menu.length <= 0) {
-                menuItem.enabled = false;
-            }
-        }
-
-        if (menuItem.enabled ?? true) {
-            li.onmouseleave = (e: js.html.MouseEvent) -> {
-                if (popupTimer != null) {
-                    popupTimer.stop();
-                    popupTimer = null;
-                }
-            }
-
-            li.onmouseenter = (e: js.html.MouseEvent) -> {
-                if (popupTimer != null) {
-                    popupTimer.stop();
-                }
-                popupTimer = haxe.Timer.delay(() -> {
-                    closeSubmenu();
-                    currentSubmenuItemId = menuItem.menu != null ? id : -1;
-                    refreshSubmenu();
-                }, openDelayMs);
-            }
-
-            li.onclick = () -> {
-                if (menuItem.click != null) {
-                    menuItem.click();
-                }
-                if (menuItem.menu != null) {
-                    if (popupTimer != null) {
-                        popupTimer.stop();
-                    }
-                    closeSubmenu();
-                    currentSubmenuItemId = id;
-                    refreshSubmenu();
-                    return;
-                }
-                if (menuItem.checked != null) {
-                    menuItem.checked = !menuItem.checked;
-                    refreshCheck();
-                }
-                if (!menuItem.stayOpen) {
-                    closeAll();
-                }
-            }
-        } else {
-            li.classList.add("disabled");
-        }
-
-        return li;
-    }
-
-    function updateSelection(newIndex: Int) {
-        if (selected != -1) {
-            flatItems[selected].elem.classList.remove("highlight");
-        }
-        if (newIndex < 0) {
-            newIndex = flatItems.length-1;
-        }
-        else if (newIndex > flatItems.length - 1) {
-            newIndex = 0;
-        }
-        if (newIndex < 0 || newIndex >= flatItems.length) {
-            selected = -1;
-        }
-        else {
-            selected = newIndex;
-            flatItems[selected].elem.classList.add("highlight");
-            flatItems[selected].elem.scrollIntoView({block: cast "nearest"});
-        }
-    }
-
-    function cleanup() {
-        rootElement.remove();
-        if (currentSubmenu != null) {
-            currentSubmenu.close();
-        }
-        if (autoCleanupTimer != null) {
-            autoCleanupTimer.stop();
-            autoCleanupTimer = null;
-        }
-        if (parentMenu != null) {
-            if (parentMenu.currentSubmenu != this)
-                throw "parentMenu.currentSubmenu != this";
-            parentMenu.currentSubmenu = null;
-        }
-
-        if (parentMenu == null) {
-            rootElement.removeEventListener("keydown", onGlobalKeyDown);
-        }
-
-        onClose();
-    }
-
-    function closeSubmenu() {
-        if (currentSubmenu != null) {
-            var element = menu.children[currentSubmenuItemId];
-            if (element != null) {
-                element.classList.remove("open");
-            }
-            currentSubmenu.close();
-            currentSubmenu = null;
-            currentSubmenuItemId = -1;
-        }
-    }
-
-    function refreshSubmenu() {
-        if (currentSubmenu != null) {
-            return;
-        }
-        if (currentSubmenuItemId >= 0) {
-            var element = menu.children[currentSubmenuItemId];
-            element.classList.add("open");
-            var rect = element.getBoundingClientRect();
-            currentSubmenu = new ContextMenu2(rootElement, this, {x: rect.right, y: rect.top}, items[currentSubmenuItemId].menu, {search: None, noIcons: options.noIcons});
-        }
-    }
-}

+ 1 - 1
hide/comp/CurveEditor.hx

@@ -76,7 +76,7 @@ class EventsEditor extends Component implements CurveEditorComponent
 				e.preventDefault();
 				e.stopPropagation();
 
-				hide.comp.ContextMenu2.createFromEvent(cast e,[
+				hide.comp.ContextMenu.createFromEvent(cast e,[
 					{
 						label: "Delete", click: function() {
 							events.remove(event);

+ 1 - 1
hide/comp/ExpRange.hx

@@ -27,7 +27,7 @@ class ExpRange extends Range {
 
 		element.contextmenu((e: js.jquery.Event) -> {
 			e.preventDefault();
-			ContextMenu2.createFromEvent(cast e, [
+			ContextMenu.createFromEvent(cast e, [
 				{ label : "Reset", click : reset },
 				{ label : "sep", isSeparator: true},
 				{ label : "Copy", click : copy},

+ 1 - 1
hide/comp/FileSelect.hx

@@ -25,7 +25,7 @@ class FileSelect extends Component {
 		function contextMenu(e) {
 			e.preventDefault();
 			var fpath = getFullPath();
-			ContextMenu2.createFromEvent(cast e, [				{ label : "View", enabled : fpath != null, click : function() onView() },
+			ContextMenu.createFromEvent(cast e, [				{ label : "View", enabled : fpath != null, click : function() onView() },
 				{ label : "Clear", enabled : path != null, click : function() { path = null; onChange(); } },
 				{ label : "Copy Path", enabled : path != null, click : function() ide.setClipboard(path) },
 				{ label : "Copy Absolute Path", enabled : fpath != null, click : function() { ide.setClipboard(fpath); } },

+ 1 - 1
hide/comp/GradientEditor.hx

@@ -71,7 +71,7 @@ class GradientBox extends Component {
 
         function contextMenu(e : js.jquery.Event) {
             e.preventDefault();
-            ContextMenu2.createFromEvent(cast e, [
+            ContextMenu.createFromEvent(cast e, [
                 {label: "Reset", click: function() {
                     value = Gradient.getDefaultGradientData();
                     onChange(false);

+ 1 - 1
hide/comp/MultiRange.hx

@@ -138,7 +138,7 @@ class MultiRange extends Component {
 
         linkButton.contextmenu(function(e) {
             e.preventDefault();
-            ContextMenu2.createFromEvent(cast e, [
+            ContextMenu.createFromEvent(cast e, [
 				{ label : "Reset All", click : reset },
 				{ label : "Round All", click : round },
 				{ label : "sep", isSeparator: true},

+ 1 - 1
hide/comp/Range.hx

@@ -46,7 +46,7 @@ class Range extends Component {
 
 		element.contextmenu((e) -> {
 			e.preventDefault();
-			ContextMenu2.createFromEvent(cast e, [
+			ContextMenu.createFromEvent(cast e, [
 				{ label : "Reset", click : reset },
 				{ label : "sep", isSeparator: true},
 				{ label : "Copy", click : copy},

+ 18 - 18
hide/comp/SceneEditor.hx

@@ -1424,7 +1424,7 @@ class SceneEditor {
 		});
 	}
 
-	function splitMenu(menu : Array<hide.comp.ContextMenu2.MenuItem>, name : String, entries : Array<hide.comp.ContextMenu2.MenuItem>, len : Int = 30) {
+	function splitMenu(menu : Array<hide.comp.ContextMenu.MenuItem>, name : String, entries : Array<hide.comp.ContextMenu.MenuItem>, len : Int = 30) {
 		entries.sort((a,b) -> Reflect.compare(a.label, b.label));
 
 		var pos = 0;
@@ -1450,7 +1450,7 @@ class SceneEditor {
 		}
 	}
 
-	function getTagMenu(prefabs: Array<PrefabElement>) : Array<hide.comp.ContextMenu2.MenuItem> {
+	function getTagMenu(prefabs: Array<PrefabElement>) : Array<hide.comp.ContextMenu.MenuItem> {
 		var tags = getAvailableTags();
 		if(tags == null) return null;
 		var ret = [];
@@ -1763,10 +1763,10 @@ class SceneEditor {
 			}
 
 			var newItems = getNewContextMenu(current);
-			var menuItems : Array<hide.comp.ContextMenu2.MenuItem> = [
+			var menuItems : Array<hide.comp.ContextMenu.MenuItem> = [
 				{ label : "New...", menu : newItems },
 			];
-			var actionItems : Array<hide.comp.ContextMenu2.MenuItem> = [
+			var actionItems : Array<hide.comp.ContextMenu.MenuItem> = [
 				{ label : "Rename", enabled : current != null, click : function() tree.editNode(current), keys : view.config.get("key.rename") },
 				{ label : "Delete", enabled : current != null, click : function() deleteElements(selectedPrefabs), keys : view.config.get("key.delete") },
 				{ label : "Duplicate", enabled : current != null, click : duplicate.bind(false), keys : view.config.get("key.duplicateInPlace") },
@@ -1791,7 +1791,7 @@ class SceneEditor {
 					{ label : "Select all", click : selectAll, keys : view.config.get("key.selectAll") },
 					{ label : "Select children", enabled : current != null, click : function() selectElements(current.flatten()) },
 				]);
-				var exportMenu = new Array<hide.comp.ContextMenu2.MenuItem>();
+				var exportMenu = new Array<hide.comp.ContextMenu.MenuItem>();
 				exportMenu.push({ label : "Export (default)", enabled : curEdit != null && canExportSelection(), click : function() exportSelection({forward:"0", forwardSign:"1", up:"2", upSign:"1"}), keys : null });
 				exportMenu.push({ label : "Export (-X Forward, Z Up)", enabled : curEdit != null && canExportSelection(), click : function() exportSelection({forward:"0", forwardSign:"-1", up:"2", upSign:"1"}), keys : null });
 
@@ -1809,7 +1809,7 @@ class SceneEditor {
 			}
 
 			menuItems.push({ isSeparator : true, label : "" });
-			hide.comp.ContextMenu2.createFromEvent(cast e, cast menuItems.concat(actionItems));
+			hide.comp.ContextMenu.createFromEvent(cast e, cast menuItems.concat(actionItems));
 		};
 
 		tree.element.parent().contextmenu(ctxMenu.bind(tree));
@@ -2319,7 +2319,7 @@ class SceneEditor {
 				newObj2d.y = pt.y;
 			}
 		});
-		var menuItems : Array<hide.comp.ContextMenu2.MenuItem> = [
+		var menuItems : Array<hide.comp.ContextMenu.MenuItem> = [
 			{ label : "New...", menu : newItems },
 			{ isSeparator : true, label : "" },
 			{
@@ -2329,7 +2329,7 @@ class SceneEditor {
 				keys : view.config.get("key.sceneeditor.gatherToMouse"),
 			},
 		];
-		hide.comp.ContextMenu2.createFromPoint(ide.mouseX, ide.mouseY, cast menuItems);
+		hide.comp.ContextMenu.createFromPoint(ide.mouseX, ide.mouseY, cast menuItems);
 	}
 
 	public function refreshInteractive(elt : PrefabElement) {
@@ -3203,7 +3203,7 @@ class SceneEditor {
 			var header = properties.element.find('.group[name="$groupName"]').find(".title");
 			header.contextmenu( function(e) {
 				e.preventDefault();
-				ContextMenu2.createFromEvent(cast e, [{label: "Copy", click: function() {
+				ContextMenu.createFromEvent(cast e, [{label: "Copy", click: function() {
 					copyFields(groupFields);
 				}},
 				{label: "Paste", click: function() {
@@ -4462,7 +4462,7 @@ class SceneEditor {
 	public dynamic function onUpdate(dt:Float) {
 	}
 
-	function getNewRecentContextMenu(current, ?onMake: PrefabElement->Void=null) : Array<hide.comp.ContextMenu2.MenuItem> {
+	function getNewRecentContextMenu(current, ?onMake: PrefabElement->Void=null) : Array<hide.comp.ContextMenu.MenuItem> {
 		var parent = current == null ? sceneData : current;
 		var grecent = [];
 		var recents : Array<String> = ide.currentConfig.get("sceneeditor.newrecents", []);
@@ -4475,8 +4475,8 @@ class SceneEditor {
 	}
 
 	// Override
-	function getNewContextMenu(current: PrefabElement, ?onMake: PrefabElement->Void=null, ?groupByType=true ) : Array<hide.comp.ContextMenu2.MenuItem> {
-		var newItems = new Array<hide.comp.ContextMenu2.MenuItem>();
+	function getNewContextMenu(current: PrefabElement, ?onMake: PrefabElement->Void=null, ?groupByType=true ) : Array<hide.comp.ContextMenu.MenuItem> {
+		var newItems = new Array<hide.comp.ContextMenu.MenuItem>();
 
 		@:privateAccess var allRegs = hrt.prefab.Prefab.registry.copy();
 		allRegs.remove("reference");
@@ -4519,7 +4519,7 @@ class SceneEditor {
 				if( !found ) gother.push(m);
 			}
 		}
-		function sortByLabel(arr:Array<hide.comp.ContextMenu2.MenuItem>) {
+		function sortByLabel(arr:Array<hide.comp.ContextMenu.MenuItem>) {
 			arr.sort(function(l1,l2) return Reflect.compare(l1.label,l2.label));
 		}
 		for( g in groups )
@@ -4545,7 +4545,7 @@ class SceneEditor {
 		?label: String,
 		?objectName: String,
 		?path: String
-	) : hide.comp.ContextMenu2.MenuItem {
+	) : hide.comp.ContextMenu.MenuItem {
 		var prefabInfo = hrt.prefab.Prefab.getPrefabInfoByName(ptype);
 		return {
 			label : label != null ? label : prefabInfo.inf.name,
@@ -4608,7 +4608,7 @@ class SceneEditor {
 		hrt.shader.TextureMult,
 	];
 
-	function getNewShaderMenu(parentElt: PrefabElement, ?onMake: PrefabElement->Void) : hide.comp.ContextMenu2.MenuItem {
+	function getNewShaderMenu(parentElt: PrefabElement, ?onMake: PrefabElement->Void) : hide.comp.ContextMenu.MenuItem {
 		function isClassShader(path: String) {
 			return Type.resolveClass(path) != null || StringTools.endsWith(path, ".hx") || StringTools.endsWith(path, ".shgraph");
 		}
@@ -4645,7 +4645,7 @@ class SceneEditor {
 			icon : shModel.inf.icon,
 		};
 
-		function classShaderItem(path) : hide.comp.ContextMenu2.MenuItem {
+		function classShaderItem(path) : hide.comp.ContextMenu.MenuItem {
 			var name = path;
 			if(StringTools.endsWith(name, ".hx")) {
 				name = new haxe.io.Path(path).file;
@@ -4656,12 +4656,12 @@ class SceneEditor {
 			return getNewTypeMenuItem("shader", parentElt, onMake, name, name, path);
 		}
 
-		function graphShaderItem(path) : hide.comp.ContextMenu2.MenuItem {
+		function graphShaderItem(path) : hide.comp.ContextMenu.MenuItem {
 			var name = new haxe.io.Path(path).file;
 			return getNewTypeMenuItem("shgraph", parentElt, onMake, name, name, path);
 		}
 
-		var menu : Array<hide.comp.ContextMenu2.MenuItem> = [];
+		var menu : Array<hide.comp.ContextMenu.MenuItem> = [];
 
 		var shaders : Array<String> = hide.Ide.inst.currentConfig.get("fx.shaders", []);
 		for (sh in globalShaders) {

+ 1 - 1
hide/comp/Select.hx

@@ -57,7 +57,7 @@ class Select extends Component {
 		if (isClearable) {
 			options.unshift({ label : "Clear", click : () -> change("")});
 		}
-		ContextMenu2.createFromEvent(cast e, options);
+		ContextMenu.createFromEvent(cast e, options);
 	}
 
 	function change(newId : String) {

+ 1 - 1
hide/comp/TextureChoice.hx

@@ -67,7 +67,7 @@ class TextureChoice extends Component {
         var btn = new Element("<div class='hide-button change-button' title='Actions ...'>").appendTo(element);
         new Element("<div class='icon ico ico-ellipsis-h'>").appendTo(btn);
         btn.click(function(e) {
-            ContextMenu2.createDropdown(btn.get(0), [
+            ContextMenu.createDropdown(btn.get(0), [
                 { label : "Change to Texturepath", click : function() changeTextureType(TextureType.path), enabled: Utils.getTextureType(innerValue) != TextureType.path},
                 { label : "Change to Gradient", click : function() changeTextureType(TextureType.gradient), enabled: Utils.getTextureType(innerValue) != TextureType.gradient},
             ]);

+ 4 - 4
hide/comp/Toolbar.hx

@@ -5,7 +5,7 @@ enum ToolType {
 	Toggle(toggle: Bool->Void);
 	Range(onChange: Float->Void);
 	Color(onChange: Int -> Void);
-	Menu(items: Array<hide.comp.ContextMenu2.MenuItem>);
+	Menu(items: Array<hide.comp.ContextMenu.MenuItem>);
 	Popup(click: hide.Element -> hide.comp.Popup);
 	Separator;
 }
@@ -37,7 +37,7 @@ typedef ToolSelect<T> = {
 
 typedef ToolMenu<T> = {
 	var element : Element;
-	function setContent( elements : Array<hide.comp.ContextMenu2.MenuItem> ) : Void;
+	function setContent( elements : Array<hide.comp.ContextMenu.MenuItem> ) : Void;
 	dynamic function onSelect( v : T ) : Void;
 }
 
@@ -179,7 +179,7 @@ class Toolbar extends Component {
         if (label != null && label.length > 0) {
             menu.append(new Element('<span class="label">${label==null ? "" : label}</span>'));
         }
-		var menuItems : Array<hide.comp.ContextMenu2.MenuItem> = [];
+		var menuItems : Array<hide.comp.ContextMenu.MenuItem> = [];
 		var tool : ToolMenu<T> = {
 			element : menu,
 			setContent : function(c) {
@@ -189,7 +189,7 @@ class Toolbar extends Component {
 		};
 		menu.get(0).onclick = function(ev : js.html.MouseEvent) : Void {
 			if( ev.button == 0 ){
-				hide.comp.ContextMenu2.createDropdown(menu.get(0), menuItems);
+				hide.comp.ContextMenu.createDropdown(menu.get(0), menuItems);
 			}
 		};
 		menu.appendTo(curGroup);

+ 3 - 3
hide/comp/cdb/Cell.hx

@@ -118,7 +118,7 @@ class Cell {
 	}
 
 	function showMenu() {
-		var menu : Array<hide.comp.ContextMenu2.MenuItem> = null;
+		var menu : Array<hide.comp.ContextMenu.MenuItem> = null;
 		switch( column.type ) {
 		case TId:
 			if( value != null && value != "" )
@@ -156,7 +156,7 @@ class Cell {
 				editor.endChanges();
 				refresh();
 			}
-			var forms : Array<hide.comp.ContextMenu2.MenuItem>;
+			var forms : Array<hide.comp.ContextMenu.MenuItem>;
 			var current = editor.formulas.get(this);
 			forms = [for( f in editor.formulas.getList(table.sheet) ) { label : f.name, click : () -> if( f == current ) setF(null) else setF(f), checked : f == current }];
 			#if !hl
@@ -169,7 +169,7 @@ class Cell {
 		}
 		if( menu != null ) {
 			focus();
-			ContextMenu2.createFromPoint(ide.mouseX, ide.mouseY, menu);
+			ContextMenu.createFromPoint(ide.mouseX, ide.mouseY, menu);
 		}
 	}
 

+ 8 - 8
hide/comp/cdb/Editor.hx

@@ -2030,7 +2030,7 @@ class Editor extends Component {
 			return;
 		var sheet = table.getRealSheet();
 		var indexColumn = sheet.columns.indexOf(col);
-		var menu : Array<hide.comp.ContextMenu2.MenuItem> = [
+		var menu : Array<hide.comp.ContextMenu.MenuItem> = [
 			{ label : "Edit", click : function () editColumn(sheet, col) },
 			{
 				label : "Add Column",
@@ -2132,7 +2132,7 @@ class Editor extends Component {
 				refresh();
 			}});
 		}
-		hide.comp.ContextMenu2.createFromPoint(ide.mouseX, ide.mouseY, menu);
+		hide.comp.ContextMenu.createFromPoint(ide.mouseX, ide.mouseY, menu);
 	}
 
 	function nextVisibleColumnIndex( table : Table, index : Int, dir : Direction){
@@ -2222,7 +2222,7 @@ class Editor extends Component {
 				break;
 			}
 
-		var moveSubmenu : Array<hide.comp.ContextMenu2.MenuItem> = [];
+		var moveSubmenu : Array<hide.comp.ContextMenu.MenuItem> = [];
 		for( sepIndex => sep in sheet.separators ) {
 			if( sep.title == null )
 				continue;
@@ -2275,7 +2275,7 @@ class Editor extends Component {
 		if( sheet.parent == null )
 			checkRec(sheet);
 
-		var menu : Array<hide.comp.ContextMenu2.MenuItem> = [
+		var menu : Array<hide.comp.ContextMenu.MenuItem> = [
 			{
 				label : "Move Up",
 				enabled:  (firstLine.index > 0 || sepIndex >= 0),
@@ -2340,7 +2340,7 @@ class Editor extends Component {
 				},
 			});
 		}
-		hide.comp.ContextMenu2.createFromPoint(ide.mouseX, ide.mouseY, menu);
+		hide.comp.ContextMenu.createFromPoint(ide.mouseX, ide.mouseY, menu);
 	}
 
 	function rename( sheet : cdb.Sheet, name : String ) {
@@ -2376,7 +2376,7 @@ class Editor extends Component {
 	}
 
 	function categoriesMenu(categories: Array<String>, setFunc : Array<String> -> Void) {
-		var menu : Array<ContextMenu2.MenuItem> = [{ label : "Set...", click : function() {
+		var menu : Array<ContextMenu.MenuItem> = [{ label : "Set...", click : function() {
 			var wstr = "";
 			if(categories != null)
 				wstr = categories.join(",");
@@ -2430,7 +2430,7 @@ class Editor extends Component {
 		if( onChange == null ) onChange = function() {}
 		var index = base.sheets.indexOf(sheet);
 
-		var content : Array<ContextMenu2.MenuItem> = [];
+		var content : Array<ContextMenu.MenuItem> = [];
 		if (withMacro) {
 			content = content.concat([
 				{ label : "Add Sheet", click : function() { beginChanges(); var db = createDBSheet(index+1); endChanges(); if( db != null ) onChange(); } },
@@ -2516,7 +2516,7 @@ class Editor extends Component {
 					refresh();
 				}
 			});
-		ContextMenu2.createFromPoint(ide.mouseX, ide.mouseY, content);
+		ContextMenu.createFromPoint(ide.mouseX, ide.mouseY, content);
 	}
 
 	public function close() {

+ 2 - 2
hide/comp/cdb/Table.hx

@@ -491,7 +491,7 @@ class Table extends Component {
 				showRec(makeSeparatorTree(sepInfo));
 			}
 
-			var opts : Array<hide.comp.ContextMenu2.MenuItem> = [
+			var opts : Array<hide.comp.ContextMenu.MenuItem> = [
 
 				{ label : "Expand", click : function() expand(true) },
 				{ label : "Collapse", click : function() expand(false) },
@@ -561,7 +561,7 @@ class Table extends Component {
 					},
 				});
 			#end
-			hide.comp.ContextMenu2.createFromPoint(ide.mouseX, ide.mouseY, opts);
+			hide.comp.ContextMenu.createFromPoint(ide.mouseX, ide.mouseY, opts);
 		});
 
 		sep.dblclick(function(e) {

+ 3 - 3
hide/prefab/terrain/TerrainEditor.hx

@@ -1031,13 +1031,13 @@ class TerrainEditor {
 			var surfaceElem = new Element('<div class=" surface"><span class="tooltiptext">$label</span></div>').prepend(img);
 			surfaceElem.contextmenu(function(e) {
 				e.preventDefault();
-				var cmi :Array< hide.comp.ContextMenu2.MenuItem> = [];
-				var delete : hide.comp.ContextMenu2.MenuItem = {label : "Delete"};
+				var cmi :Array< hide.comp.ContextMenu.MenuItem> = [];
+				var delete : hide.comp.ContextMenu.MenuItem = {label : "Delete"};
 				delete.click = function(){
 					removeSurface(i, function(){refreshSurfaces(props, ctx);});
 				};
 				cmi.push(delete);
-				hide.comp.ContextMenu2.createFromEvent(cast e, cmi);
+				hide.comp.ContextMenu.createFromEvent(cast e, cmi);
 			});
 			surfaceElem.click(function(e){
 				editContext.scene.setCurrent();

+ 2 - 2
hide/ui/View.hx

@@ -165,7 +165,7 @@ class View<T> extends hide.comp.Component {
 			container.tab.element.contextmenu(function(e: js.jquery.Event) {
 				var menu = buildTabMenu();
 				if( menu.length > 0 ) {
-					hide.comp.ContextMenu2.createFromEvent(cast e, menu);
+					hide.comp.ContextMenu.createFromEvent(cast e, menu);
 				}
 				e.preventDefault();
 			});
@@ -275,7 +275,7 @@ class View<T> extends hide.comp.Component {
 		containerView.__view = null;
 	}
 
-	function buildTabMenu() : Array<hide.comp.ContextMenu2.MenuItem> {
+	function buildTabMenu() : Array<hide.comp.ContextMenu.MenuItem> {
 		if( @:privateAccess ide.subView != null )
 			return [];
 		return [

+ 9 - 9
hide/view/FXEditor.hx

@@ -204,7 +204,7 @@ private class FXSceneEditor extends hide.comp.SceneEditor {
 
 	override function getNewContextMenu(current: PrefabElement, ?onMake: PrefabElement->Void=null, ?groupByType = true ) {
 		if(current != null && current.to(hrt.prefab.Shader) != null) {
-			var ret : Array<hide.comp.ContextMenu2.MenuItem> = [];
+			var ret : Array<hide.comp.ContextMenu.MenuItem> = [];
 			ret.push({
 				label: "Animation",
 				menu: parent.getNewTrackMenu(current)
@@ -218,7 +218,7 @@ private class FXSceneEditor extends hide.comp.SceneEditor {
 
 
 
-		var shaderItems : Array<hide.comp.ContextMenu2.MenuItem> = [];
+		var shaderItems : Array<hide.comp.ContextMenu.MenuItem> = [];
 
 		if (parent.is2D) {
 			for(name in ["Group 2D", "Bitmap", "Anim2D", "Atlas", "Particle2D", "Text", "Shader", "Shader Graph", "Placeholder"]) {
@@ -1070,7 +1070,7 @@ class FXEditor extends hide.view.FileView {
 						if (menuItems.length == 0) {
 							menuItems = [{label: "No animation available", enabled: false}];
 						}
-						hide.comp.ContextMenu2.createDropdown(addTrackEl.get(0), menuItems);
+						hide.comp.ContextMenu.createDropdown(addTrackEl.get(0), menuItems);
 					};
 				}
 			}
@@ -1398,7 +1398,7 @@ class FXEditor extends hide.view.FileView {
 		return added;
 	}
 
-	public function getNewTrackMenu(elt: PrefabElement) : Array<hide.comp.ContextMenu2.MenuItem> {
+	public function getNewTrackMenu(elt: PrefabElement) : Array<hide.comp.ContextMenu.MenuItem> {
 		var obj3dElt = Std.downcast(elt, hrt.prefab.Object3D);
 		var obj2dElt = Std.downcast(elt, hrt.prefab.Object2D);
 		var shaderElt = Std.downcast(elt, hrt.prefab.Shader);
@@ -1406,14 +1406,14 @@ class FXEditor extends hide.view.FileView {
 		var emitterElt = Std.downcast(elt, hrt.prefab.fx.Emitter);
 
 		var particle2dElt = Std.downcast(elt, hrt.prefab.l2d.Particle2D);
-		var menuItems : Array<hide.comp.ContextMenu2.MenuItem> = [];
+		var menuItems : Array<hide.comp.ContextMenu.MenuItem> = [];
 		var lightElt = Std.downcast(elt, Light);
 
 		inline function hasTrack(pname) {
 			return getTrack(elt, pname) != null;
 		}
 
-		function trackItem(name: String, props: Array<PropTrackDef>, ?prefix: String) : hide.comp.ContextMenu2.MenuItem {
+		function trackItem(name: String, props: Array<PropTrackDef>, ?prefix: String) : hide.comp.ContextMenu.MenuItem {
 			var hasAllTracks = true;
 			for(p in props) {
 				if(getTrack(elt, prefix + ":" + p.name) == null)
@@ -1427,7 +1427,7 @@ class FXEditor extends hide.view.FileView {
 				enabled: !hasAllTracks };
 		}
 
-		function groupedTracks(prefix: String, props: Array<PropTrackDef>) : Array<hide.comp.ContextMenu2.MenuItem> {
+		function groupedTracks(prefix: String, props: Array<PropTrackDef>) : Array<hide.comp.ContextMenu.MenuItem> {
 			var allLabel = [for(p in props) upperCase(p.name)].join("/");
 			var ret = [];
 			ret.push(trackItem(allLabel, props, prefix));
@@ -1502,7 +1502,7 @@ class FXEditor extends hide.view.FileView {
 			for(param in params) {
 				if (param.qualifiers?.contains(Ignore) ?? false)
 					continue;
-				var item : hide.comp.ContextMenu2.MenuItem = switch(param.type) {
+				var item : hide.comp.ContextMenu.MenuItem = switch(param.type) {
 					case TVec(n, VFloat):
 						var color = param.name.toLowerCase().indexOf("color") >= 0;
 						var label = upperCase(param.name);
@@ -1536,7 +1536,7 @@ class FXEditor extends hide.view.FileView {
 		}
 		function addParam(param : hrt.prefab.fx.Emitter.ParamDef, prefix: String) {
 			var label = prefix + (param.disp != null ? param.disp : upperCase(param.name));
-			var item : hide.comp.ContextMenu2.MenuItem = switch(param.t) {
+			var item : hide.comp.ContextMenu.MenuItem = switch(param.t) {
 				case PVec(n, _):
 					{
 						label: label,

+ 1 - 1
hide/view/FileTree.hx

@@ -123,7 +123,7 @@ class FileTree extends FileView {
 					click : createNew.bind(selection[0], { options : { createNew : "Directory" }, extensions : null, component : null }),
 					icon : "folder",
 				});
-			hide.comp.ContextMenu2.createFromEvent(cast e, [
+			hide.comp.ContextMenu.createFromEvent(cast e, [
 				{ label : "New...", menu:newMenu },
 				{ label : "Collapse", click : tree.collapseAll },
 				{ label : "", isSeparator: true },

+ 2 - 2
hide/view/FileView.hx

@@ -204,8 +204,8 @@ class FileView extends hide.ui.View<{ path : String }> {
 
 	override function buildTabMenu() {
 		var hasPath = state.path != null && state.path != "";
-		var reloadItem : hide.comp.ContextMenu2.MenuItem = { label : "Reload", click : function() rebuild() };
-		var arr : Array<hide.comp.ContextMenu2.MenuItem>;
+		var reloadItem : hide.comp.ContextMenu.MenuItem = { label : "Reload", click : function() rebuild() };
+		var arr : Array<hide.comp.ContextMenu.MenuItem>;
 		if( !hasPath && !canSave() ) {
 			arr = [
 				reloadItem,

+ 5 - 5
hide/view/GraphEditor.hx

@@ -98,7 +98,7 @@ class GraphEditor extends hide.comp.Component {
 
 	public var currentUndoBuffer : UndoBuffer = [];
 
-	var contextMenu : hide.comp.ContextMenu2 = null;
+	var contextMenu : hide.comp.ContextMenu = null;
 
 
 
@@ -573,9 +573,9 @@ class GraphEditor extends hide.comp.Component {
 			closeAddMenu();
 		}
 
-		var menu : Array<hide.comp.ContextMenu2.MenuItem> = [];
+		var menu : Array<hide.comp.ContextMenu.MenuItem> = [];
 		for (group => entries in groups) {
-			var submenu: Array<hide.comp.ContextMenu2.MenuItem> = [];
+			var submenu: Array<hide.comp.ContextMenu.MenuItem> = [];
 			for (entry in entries) {
 				submenu.push({label: entry.name, click: doAdd.bind(entry.onConstructNode), tooltip: entry.description});
 			}
@@ -585,7 +585,7 @@ class GraphEditor extends hide.comp.Component {
 			});
 		}
 
-		contextMenu = hide.comp.ContextMenu2.createFromPoint(ide.mouseX, ide.mouseY, menu, {search: Visible, noIcons: true});
+		contextMenu = hide.comp.ContextMenu.createFromPoint(ide.mouseX, ide.mouseY, menu, {search: Visible, noIcons: true});
 		contextMenu.onClose = () -> {
 			contextMenu = null;
 		};
@@ -1747,7 +1747,7 @@ class GraphEditor extends hide.comp.Component {
 			});
 
 			curveHitbox.get(0).oncontextmenu = function(e: js.html.MouseEvent) {
-				hide.comp.ContextMenu2.createFromEvent(e, [
+				hide.comp.ContextMenu.createFromEvent(e, [
 					{label: "Delete ?", click: function() {
 							var edge = edgeFromPack(packedOutput, packedInput);
 							opEdge(packedOutput, packedInput, false, currentUndoBuffer);

+ 3 - 3
hide/view/Model.hx

@@ -1040,7 +1040,7 @@ class Model extends FileView {
 
 	override function buildTabMenu() {
 		var menu = super.buildTabMenu();
-		var arr : Array<hide.comp.ContextMenu2.MenuItem> = [
+		var arr : Array<hide.comp.ContextMenu.MenuItem> = [
 			{ label : null, isSeparator : true },
 			{ label : "Export", click : function() {
 				ide.chooseFileSave(this.getPath().substr(0,-4)+"_dump.txt", function(file) {
@@ -1207,14 +1207,14 @@ class Model extends FileView {
 					}));
 				}
 				var frame = Math.round((e.relX / W) * obj.currentAnimation.frameCount);
-				var menuItems : Array<hide.comp.ContextMenu2.MenuItem> = [
+				var menuItems : Array<hide.comp.ContextMenu.MenuItem> = [
 					{ label : "New", click: function(){ addEvent("NewEvent", frame); }},
 				];
 				if(obj.currentAnimation.events != null && obj.currentAnimation.events[frame] != null){
 					for(e in obj.currentAnimation.events[frame])
 						menuItems.push({ label : "Delete " + e, click: function(){ deleteEvent(e, frame); }});
 				}
-				hide.comp.ContextMenu2.createFromPoint(ide.mouseX, ide.mouseY, menuItems);
+				hide.comp.ContextMenu.createFromPoint(ide.mouseX, ide.mouseY, menuItems);
 			}
 		}
 

+ 1 - 1
hide/view/Particles2D.hx

@@ -170,7 +170,7 @@ class Particles2D extends FileView {
 				if( history ) undo.change(Custom(function(undo) moveIndex(undo ? -d : d,false)));
 				initProperties();
 			}
-			hide.comp.ContextMenu2.createFromEvent(cast ev, [
+			hide.comp.ContextMenu.createFromEvent(cast ev, [
 				{ label : "Enable", checked : g.enable, click : function() {
 					g.enable = !g.enable;
 					e.find("[field=enable]").prop("checked", g.enable);

+ 1 - 1
hide/view/Particles3D.hx

@@ -127,7 +127,7 @@ class Particles3D extends FileView {
 				if( history ) undo.change(Custom(function(undo) moveIndex(undo ? -d : d,false)));
 				initProperties();
 			}
-			hide.comp.ContextMenu2.createFromEvent(cast ev, [
+			hide.comp.ContextMenu.createFromEvent(cast ev, [
 				{ label : "Enable", checked : g.enable, click : function() { g.enable = !g.enable; e.find("[field=enable]").prop("checked", g.enable); } },
 				{ label : "Copy", click : function() setClipboard(g.save()) },
 				{ label : "Paste", enabled : hasClipboard(), click : function() {

+ 4 - 4
hide/view/Prefab.hx

@@ -91,7 +91,7 @@ class PrefabSceneEditor extends hide.comp.SceneEditor {
 		}
 
 		function addNewInstances() {
-			var items = new Array<hide.comp.ContextMenu2.MenuItem>();
+			var items = new Array<hide.comp.ContextMenu.MenuItem>();
 			for(type in DataFiles.getAvailableTypes() ) {
 				var typeId = DataFiles.getTypeName(type);
 				var label = typeId.charAt(0).toUpperCase() + typeId.substr(1);
@@ -111,7 +111,7 @@ class PrefabSceneEditor extends hide.comp.SceneEditor {
 				}
 
 				if(idCol != null && refSheet.props.dataFiles == null ) {
-					var kindItems = new Array<hide.comp.ContextMenu2.MenuItem>();
+					var kindItems = new Array<hide.comp.ContextMenu.MenuItem>();
 					for(line in refSheet.lines) {
 						var kind : String = Reflect.getProperty(line, idCol.name);
 						kindItems.push({
@@ -795,8 +795,8 @@ class Prefab extends hide.view.FileView {
 		}
 	}
 
-	function filtersToMenuItem(filters : Map<String, Bool>, type : String) : Array<hide.comp.ContextMenu2.MenuItem> {
-		var content : Array<hide.comp.ContextMenu2.MenuItem> = [];
+	function filtersToMenuItem(filters : Map<String, Bool>, type : String) : Array<hide.comp.ContextMenu.MenuItem> {
+		var content : Array<hide.comp.ContextMenu.MenuItem> = [];
 		var initDone = false;
 		for(typeid in filters.keys()) {
 			if ( type == "View" ) {

+ 1 - 1
hide/view/Script.hx

@@ -13,7 +13,7 @@ class Script extends FileView {
 		return new hide.comp.ScriptEditor.ScriptChecker(config,"hx");
 	}
 
-	override function buildTabMenu():Array<hide.comp.ContextMenu2.MenuItem> {
+	override function buildTabMenu():Array<hide.comp.ContextMenu.MenuItem> {
 		var arr = super.buildTabMenu();
 		if( lang == "xml" ) {
 			arr.push({ label : "Count Words", click : function() {

+ 7 - 7
hide/view/shadereditor/ShaderEditor.hx

@@ -274,7 +274,7 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
 
 		rightPannel.appendTo(element);
 
-		var newParamCtxMenu : Array<hide.comp.ContextMenu2.MenuItem> = [
+		var newParamCtxMenu : Array<hide.comp.ContextMenu.MenuItem> = [
 			{ label : "Number", click : () -> createParameter(HxslType.TFloat) },
 			{ label : "Vec2", click : () -> createParameter(HxslType.TVec(2, VFloat)) },
 			{ label : "Vec3", click : () -> createParameter(HxslType.TVec(3, VFloat)) },
@@ -284,14 +284,14 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
 
 		var createParameter = rightPannel.find("#createParameter");
 		createParameter.on("click", function() {
-			hide.comp.ContextMenu2.createDropdown(createParameter.get(0), newParamCtxMenu);
+			hide.comp.ContextMenu.createDropdown(createParameter.get(0), newParamCtxMenu);
 		});
 
 		parametersList = rightPannel.find("#parametersList");
 		parametersList.on("contextmenu", function(e) {
 			e.preventDefault();
 			e.stopPropagation();
-			hide.comp.ContextMenu2.createFromEvent(cast e, [
+			hide.comp.ContextMenu.createFromEvent(cast e, [
 				{
 					label : "Add Parameter",
 					menu : newParamCtxMenu,
@@ -305,7 +305,7 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
 
 
 		rightPannel.find("#debugMenu").click((e) -> {
-			hide.comp.ContextMenu2.createDropdown(rightPannel.find("#debugMenu").get(0), [
+			hide.comp.ContextMenu.createDropdown(rightPannel.find("#debugMenu").get(0), [
 				{
 					label : "Print Preview Shader code to Console",
 					click: () -> trace(hxsl.Printer.shaderToString(shaderGraph.compile(currentGraph.domain).shader.data, true))
@@ -452,7 +452,7 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
 		elt.on("contextmenu", function(e) {
 			var elements = [];
 			e.stopPropagation();
-			var newCtxMenu : Array<hide.comp.ContextMenu2.MenuItem> = [
+			var newCtxMenu : Array<hide.comp.ContextMenu.MenuItem> = [
 				{ label : "Move up", click : () -> {
 					//beforeChange();
 					moveParameter(parameter, true);
@@ -464,7 +464,7 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
 					//afterChange();
 				}, enabled: shaderGraph.parametersKeys.indexOf(parameter.id) < shaderGraph.parametersKeys.length-1}
 			];
-			hide.comp.ContextMenu2.createFromEvent(cast e, newCtxMenu);
+			hide.comp.ContextMenu.createFromEvent(cast e, newCtxMenu);
 			e.preventDefault();
 
 		});
@@ -908,7 +908,7 @@ class ShaderEditor extends hide.view.FileView implements GraphInterface.IGraphEd
 		var menu = new Element('<div class="button2 transparent" title="More options"><div class="ico ico-navicon"></div></div>');
 		menu.appendTo(group);
 		menu.click((e) -> {
-			hide.comp.ContextMenu2.createDropdown(menu.get(0), [
+			hide.comp.ContextMenu.createDropdown(menu.get(0), [
 				{label: "Reset Camera", click: resetPreviewCamera},
 				{label: "", isSeparator: true},
 				{label: "Sphere", click: setMeshPreviewSphere},

+ 1 - 1
hide/view/textureeditor/TextureEditor.hx

@@ -137,7 +137,7 @@ class TextureEditor extends hide.view.FileView implements GraphInterface.IGraphE
 		var menu = new Element('<div class="button2 transparent" title="More options"><div class="ico ico-navicon"></div></div>');
 		menu.appendTo(group);
 		menu.click((e) -> {
-			hide.comp.ContextMenu2.createDropdown(menu.get(0), [
+			hide.comp.ContextMenu.createDropdown(menu.get(0), [
 				{ label: "Center preview", click: centerPreviewCamera }
 			]);
 		});

+ 2 - 2
hrt/prefab/fx/Emitter.hx

@@ -1981,7 +1981,7 @@ class Emitter extends Object3D {
 						hide.comp.PropsEditor.makePropEl(p, dd);
 						dt.contextmenu(function(e) {
 							e.preventDefault();
-							hide.comp.ContextMenu2.createFromEvent(cast e, [
+							hide.comp.ContextMenu.createFromEvent(cast e, [
 								{ label : "Reset", click : function() {
 									addUndo(p.name);
 									resetParam(p);
@@ -2020,7 +2020,7 @@ class Emitter extends Object3D {
 							def: randDef}, dd);
 						dt.contextmenu(function(e) {
 							e.preventDefault();
-							hide.comp.ContextMenu2.createFromEvent(cast e, [
+							hide.comp.ContextMenu.createFromEvent(cast e, [
 								{ label : "Reset", click : function() {
 									addUndo(randProp(p.name));
 									Reflect.setField(this.props, randProp(p.name), randDef);

+ 1 - 1
hrt/prefab/l3d/MeshSpray.hx

@@ -666,7 +666,7 @@ class MeshSpray extends Spray {
 			var elt = new hide.Element('<option value="$path">${extractItemName(path)}</option>');
 			elt.contextmenu(function(e) {
 				e.preventDefault();
-				hide.comp.ContextMenu2.createFromEvent(cast e,[
+				hide.comp.ContextMenu.createFromEvent(cast e,[
 					{ label : "Swap Model", click : function() hide.Ide.inst.chooseFile(["fbx", "l3d"] , function (newPath) {
 						removeSourcePath(elt.val());
 						addSourcePath(newPath);

+ 1 - 1
hrt/prefab/l3d/Particles3D.hx

@@ -138,7 +138,7 @@ class Particles3D extends Object3D {
 						if( history ) undo(function(undo) moveIndex(undo ? -d : d,false));
 						ectx.rebuildProperties();
 					}
-					hide.comp.ContextMenu2.createFromEvent(cast ev,[
+					hide.comp.ContextMenu.createFromEvent(cast ev,[
 						{ label : "Enable", checked : g.enable, click : function() { g.enable = !g.enable; e.find("[field=enable]").prop("checked", g.enable); } },
 						{ label : "Copy", click : function() ectx.ide.setClipboard(g.save()) },
 						{ label : "Paste", enabled : ectx.ide.getClipboard() != null, click : function() {

+ 1 - 1
hrt/prefab/l3d/PrefabSpray.hx

@@ -64,7 +64,7 @@ class PrefabSpray extends Spray {
 			var elt = new hide.Element('<option value="$path">${extractItemName(path)}</option>');
 			elt.contextmenu(function(e) {
 				e.preventDefault();
-				hide.comp.ContextMenu2.createFromEvent(cast e, [
+				hide.comp.ContextMenu.createFromEvent(cast e, [
 					{ label : "Swap Prefab", click : function() hide.Ide.inst.chooseFile(["prefab", "l3d"] , function (newPath) {
 						removeSourcePath(elt.val());
 						addSourcePath(newPath);

+ 1 - 1
hrt/prefab/rfx/Configurator.hx

@@ -295,7 +295,7 @@ class Configurator extends RendererFX {
 				values.set(v.name, ref.v);
 			});
 			def.find("dt").contextmenu(function(e) {
-				hide.comp.ContextMenu2.createFromEvent(cast e, [
+				hide.comp.ContextMenu.createFromEvent(cast e, [
 					{ label : "Set Default", click : () -> v.defValue = ref.v },
 					{ label : "Remove", click : () -> {
 						vars.remove(v);