Skip to content

Commit

Permalink
feat: context menu is rebuildable
Browse files Browse the repository at this point in the history
  • Loading branch information
teletha committed Feb 13, 2024
1 parent aceb266 commit afcf0f3
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 36 deletions.
39 changes: 21 additions & 18 deletions src/main/java/viewtify/ui/UITab.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,28 +88,31 @@ public UITab(View parent) {
tabPaneProperty().addListener(invalidaed -> styleable = null);

context(menus -> {
menus.menu().text(CloseThisTab).action(this::close);
menus.menu(CloseMultipleTabs, sub -> {
ObservableList<Tab> tabs = getTabPane().getTabs();
int index = tabs.indexOf(this);
ObservableList<Tab> tabs = getTabPane().getTabs();

if (index + 1 != tabs.size()) {
sub.menu(CloseRightTabs).action(() -> {
I.signal(tabs).skip(index + 1).buffer().flatIterable(x -> x).to(x -> tabs.remove(x));
menus.menu().text(CloseThisTab).action(this::close);
if (tabs.size() > 1) {
menus.menu(CloseMultipleTabs, sub -> {
int index = tabs.indexOf(this);

if (index + 1 != tabs.size()) {
sub.menu(CloseRightTabs).action(() -> {
I.signal(tabs).skip(index + 1).buffer().flatIterable(x -> x).to(x -> tabs.remove(x));
});
}
if (index != 0) {
sub.menu(CloseLeftTabs).action(() -> {
I.signal(tabs).take(index).buffer().flatIterable(x -> x).to(x -> tabs.remove(x));
});
}
if (tabs.size() > 1) sub.menu(CloseOtherTabs).action(() -> {
I.signal(tabs).skip(this).buffer().flatIterable(x -> x).to(x -> tabs.remove(x));
});
}
if (index != 0) {
sub.menu(CloseLeftTabs).action(() -> {
I.signal(tabs).take(index).buffer().flatIterable(x -> x).to(x -> tabs.remove(x));
sub.menu(CloseAllTabs).action(() -> {
tabs.clear();
});
}
if (tabs.size() > 1) sub.menu(CloseOtherTabs).action(() -> {
I.signal(tabs).skip(this).buffer().flatIterable(x -> x).to(x -> tabs.remove(x));
});
sub.menu(CloseAllTabs).action(() -> {
tabs.clear();
});
});
}
});
}

Expand Down
38 changes: 20 additions & 18 deletions src/main/java/viewtify/ui/helper/ContextMenuHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
import javafx.beans.property.Property;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventTarget;
import javafx.event.EventType;
import javafx.geometry.Side;
Expand Down Expand Up @@ -63,7 +61,7 @@ private EnhancedContextMenu context() {
* @return A chainable API for further configuration.
*/
default Self context(Consumer<UIContextMenu> builder) {
return context(true, this, builder);
return context(this, true, builder);
}

/**
Expand All @@ -77,32 +75,32 @@ default Self context(Consumer<UIContextMenu> builder) {
* @return A chainable API for further configuration.
*/
default Self context(Object id, Consumer<UIContextMenu> builder) {
return context(true, id, builder);
return context(id, true, builder);
}

/**
* Define the context menu with the option to specify whether it should be generated lazily.
* This method allows you to specify a context menu using a builder function.
*
* @param lazy If true, the context menu will be generated lazily.
* @param rebuildable If true, the context menu will be generated on every popup.
* @param builder A consumer that builds the UIContextMenu for the context menu.
* @return A chainable API for further configuration.
*/
default Self context(boolean lazy, Consumer<UIContextMenu> builder) {
default Self context(boolean rebuildable, Consumer<UIContextMenu> builder) {
return context(this, builder);
}

/**
* Define the context menu with the option to specify whether it should be generated lazily. If
* the specified ID already exists, the menu will be overwritten instead of added. This method
* allows you to specify a context menu using a builder function.
*
* @param lazy If true, the context menu will be generated lazily.
*
* @param id An identifier for the context menu.
* @param rebuildable If true, the context menu will be generated on every popup.
* @param builder A consumer that builds the UIContextMenu for the context menu.
* @return A chainable API for further configuration.
*/
default Self context(boolean lazy, Object id, Consumer<UIContextMenu> builder) {
default Self context(Object id, boolean rebuildable, Consumer<UIContextMenu> builder) {
EnhancedContextMenu menus = context();

// separate for each context assigners
Expand All @@ -119,26 +117,30 @@ default Self context(boolean lazy, Object id, Consumer<UIContextMenu> builder) {
}

// build context menus
if (!lazy) {
if (!rebuildable) {
// eager setup
builder.accept(new UIContextMenu(id, menus.getItems()));
} else {
// lazy setup
EventHandler<Event>[] setup = new EventHandler[1];
setup[0] = e -> {
menus.addEventFilter(Menu.ON_SHOWING, e -> {
int index = 0;
ObservableList<MenuItem> children = menus.getItems();

// remove old menus
for (int i = children.size() - 1; 0 <= i; i--) {
MenuItem child = children.get(i);
if (child.getProperties().containsKey(id)) {
children.remove(i);
List<MenuItem> container = new ArrayList();
builder.accept(new UIContextMenu(id, container));
children.addAll(i, container);
index = i;
}
}
menus.removeEventFilter(Menu.ON_SHOWING, setup[0]);
};
menus.addEventFilter(Menu.ON_SHOWING, setup[0]);

// add new menus
List<MenuItem> container = new ArrayList();
builder.accept(new UIContextMenu(id, container));
container.forEach(menu -> menu.getProperties().put(id, null));
children.addAll(index, container);
});

// create dummy context
MenuItem menu = new MenuItem("");
Expand Down

0 comments on commit afcf0f3

Please sign in to comment.