Plugin: MarkingMenus adds support for building and showing radial menus for boxes and for the canvas itself to Field. Menus are built up from coalescing MenuSpecifications from the "menuSpecs" property (signature: Function , MenuSpecification>). That puts labels an
| 33 | * memory. |
| 34 | */ |
| 35 | public class MarkingMenus extends Box { |
| 36 | |
| 37 | static public Dict.Prop<MarkingMenus> markingMenus = new Dict.Prop<>("markingMenus"); |
| 38 | |
| 39 | // sophisticated interface |
| 40 | static public Dict.Prop<Function<Window.Event<Window.MouseState>, MenuSpecification>> menuSpecs = new Dict.Prop<>("menuSpecs"); // TODO: comment |
| 41 | |
| 42 | // easy interface |
| 43 | static public Dict.Prop<IdempotencyMap<FunctionOfBox>> menu = new Dict.Prop<>("menu").toCanon() |
| 44 | .autoConstructs(() -> new IdempotencyMap<>(FunctionOfBox.class)).doc("Adds a menu item to a box at a particular direction. For example `_.menu.show_something_n = function(_) { ... }` will place a menu item 'show something' at the 'N(orth)' position. Note this position can get 'bumped' by other items."); |
| 45 | |
| 46 | |
| 47 | // easy interface |
| 48 | static public Dict.Prop<IdempotencyMap<FunctionOfBox>> spaceMenu = new Dict.Prop<>("spaceMenu").toCanon() |
| 49 | .autoConstructs(() -> new IdempotencyMap<>(FunctionOfBox.class)).doc("Adds a menu item to a box at a particular direction. For example `_.spaceMenu.show_something_n = function(_) { ... }` will place a menu item 'show something' at the 'N(orth)' position. Note this position can get 'bumped' by other items."); |
| 50 | |
| 51 | |
| 52 | static public Dict.Prop<IdempotencyMap<FunctionOfBox>> nothingCallback = new Dict.Prop<>("nothingCallback").toCanon() |
| 53 | .autoConstructs(() -> new IdempotencyMap<>(FunctionOfBox.class)).doc("Callback that's called should nothing be selected in a right-click menu. Allows you to bind a right-click to a box."); |
| 54 | |
| 55 | |
| 56 | public MarkingMenus(Box root) { |
| 57 | |
| 58 | this.properties.put(markingMenus, this); |
| 59 | this.properties.put(FLineDrawing.layer, "glass2"); |
| 60 | this.properties.put(Planes.plane, "__always__"); |
| 61 | |
| 62 | this.properties.putToMap(Mouse.onMouseDown, "__markingmenus__", (event, button) -> { |
| 63 | if (button != 1) return null; |
| 64 | |
| 65 | if (event.properties.isTrue(Window.consumed, false)) return null; |
| 66 | |
| 67 | Box startAt = Intersects.startAt(event.after, root); |
| 68 | |
| 69 | |
| 70 | if (startAt!=null && !startAt.properties.isTrue(Mouse.isSelected, false)) |
| 71 | { |
| 72 | FrameManipulation.setSelectionTo(root, Collections.singleton(startAt)); |
| 73 | } |
| 74 | |
| 75 | |
| 76 | FieldBoxWindow window = find(Boxes.window, both()).findFirst().get(); |
| 77 | Drawing drawing = find(Drawing.drawing, both()).findFirst().get(); |
| 78 | |
| 79 | Rect bounds= window.getBounds(); |
| 80 | Rect viewBounds = drawing.getCurrentViewBounds(this); |
| 81 | double[] originalMouseX = {0}; |
| 82 | double[] originalMouseY = {0}; |
| 83 | |
| 84 | GLFW.glfwGetCursorPos(window.getGLFWWindowReference(), originalMouseX, originalMouseY); |
| 85 | GLFW.glfwSetCursorPos(window.getGLFWWindowReference(), bounds.w/2, bounds.h/2); |
| 86 | |
| 87 | event.after.mx = viewBounds.x+viewBounds.w/2; |
| 88 | event.after.my = viewBounds.y+viewBounds.h/2; |
| 89 | |
| 90 | MenuSpecification m = startAt.find(menuSpecs, upwardsOrDownwards()) |
| 91 | .filter(x -> x != null) |
| 92 | .map(x -> x.apply(event)) |
nothing calls this directly
no test coverage detected