/*
* Copyright 2016 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.rendering.nui.contextMenu;
import com.google.common.collect.Lists;
import org.terasology.math.geom.Vector2i;
import org.terasology.rendering.nui.NUIManager;
import org.terasology.rendering.nui.databinding.Binding;
import org.terasology.rendering.nui.databinding.ReadOnlyBinding;
import org.terasology.rendering.nui.widgets.UIList;
import java.util.List;
/**
* A utility class to initialize and display {@link ContextMenuScreen} instances.
* <p>
* Should be used in favor of manually creating the screen.
*/
public final class ContextMenuUtils {
private ContextMenuUtils() {
}
/**
* Initialize and display a {@link ContextMenuScreen} based on a given menu tree.
*
* @param manager The {@link NUIManager} to be used to display the screen.
* @param position The position of the initial menu tree.
* @param tree The menu tree the context menu is based on.
*/
public static void showContextMenu(NUIManager manager, Vector2i position, MenuTree tree) {
if (!manager.isOpen(ContextMenuScreen.ASSET_URI)) {
manager.pushScreen(ContextMenuScreen.ASSET_URI, ContextMenuScreen.class);
}
ContextMenuScreen contextMenuScreen = (ContextMenuScreen) manager.getScreen(ContextMenuScreen.ASSET_URI);
contextMenuScreen.setMenuWidgets(getMenuLevelList(manager, new VisibleTree(tree, true)));
contextMenuScreen.setPosition(position);
}
private static List<UIList<AbstractContextMenuItem>> getMenuLevelList(NUIManager manager, VisibleTree tree) {
List<UIList<AbstractContextMenuItem>> menuLevels = Lists.newArrayList();
menuLevels.add(getList(manager, tree));
for (AbstractContextMenuItem item : tree.getOptions()) {
if (item instanceof VisibleTree) {
menuLevels.addAll(getMenuLevelList(manager, (VisibleTree) item));
}
}
return menuLevels;
}
private static UIList<AbstractContextMenuItem> getList(NUIManager manager, VisibleTree tree) {
UIList<AbstractContextMenuItem> list = new UIList<>();
list.setList(tree.getOptions());
list.setCanBeFocus(false);
list.bindSelection(new Binding<AbstractContextMenuItem>() {
@Override
public AbstractContextMenuItem get() {
return null;
}
@Override
public void set(AbstractContextMenuItem value) {
if (tree.select(value)) {
manager.closeScreen(ContextMenuScreen.ASSET_URI);
}
}
});
list.bindVisible(new ReadOnlyBinding<Boolean>() {
@Override
public Boolean get() {
return tree.visible;
}
});
return list;
}
private static class VisibleTree implements AbstractContextMenuItem {
private String name;
private List<AbstractContextMenuItem> options = Lists.newArrayList();
private boolean visible;
VisibleTree(MenuTree tree, boolean visible) {
this.name = tree.getName();
for (AbstractContextMenuItem option : tree.getOptions()) {
if (option instanceof MenuTree) {
this.options.add(new VisibleTree((MenuTree) option, false));
} else {
this.options.add(option);
}
}
this.visible = visible;
}
/**
* @param option The option to be selected.
* @return Whether the context menu should be closed after the option is selected
*/
public boolean select(AbstractContextMenuItem option) {
if (options.contains(option)) {
if (option instanceof ContextMenuOption) {
((ContextMenuOption) option).select();
return ((ContextMenuOption) option).isFinalized();
} else if (option instanceof VisibleTree) {
((VisibleTree) option).visible = !((VisibleTree) option).visible;
return false;
} else {
return false;
}
}
return false;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
public List<AbstractContextMenuItem> getOptions() {
return options;
}
@Override
public String toString() {
return name;
}
}
}