Package org.terasology.rendering.nui.layers.mainMenu

Source Code of org.terasology.rendering.nui.layers.mainMenu.SelectModulesScreen$ModuleSelectionInfo

/*
* Copyright 2014 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.layers.mainMenu;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.terasology.config.Config;
import org.terasology.config.ModuleConfig;
import org.terasology.engine.SimpleUri;
import org.terasology.engine.module.ModuleManager;
import org.terasology.math.Vector2i;
import org.terasology.module.DependencyResolver;
import org.terasology.module.Module;
import org.terasology.module.ModuleMetadata;
import org.terasology.module.ResolutionResult;
import org.terasology.naming.Name;
import org.terasology.registry.In;
import org.terasology.rendering.nui.Canvas;
import org.terasology.rendering.nui.CoreScreenLayer;
import org.terasology.rendering.nui.UIWidget;
import org.terasology.rendering.nui.WidgetUtil;
import org.terasology.rendering.nui.databinding.Binding;
import org.terasology.rendering.nui.databinding.ReadOnlyBinding;
import org.terasology.rendering.nui.itemRendering.AbstractItemRenderer;
import org.terasology.rendering.nui.widgets.ActivateEventListener;
import org.terasology.rendering.nui.widgets.ItemActivateEventListener;
import org.terasology.rendering.nui.widgets.UIButton;
import org.terasology.rendering.nui.widgets.UILabel;
import org.terasology.rendering.nui.widgets.UIList;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
* @author Immortius
*/
public class SelectModulesScreen extends CoreScreenLayer {

    @In
    private ModuleManager moduleManager;

    @In
    private Config config;

    private Map<Name, ModuleSelectionInfo> modulesLookup;
    private List<ModuleSelectionInfo> sortedModules;
    private DependencyResolver resolver;

    @Override
    public void onOpened() {
        super.onOpened();

        for (ModuleSelectionInfo info : sortedModules) {
            info.setExplicitSelection(config.getDefaultModSelection().hasModule(info.getMetadata().getId()));
        }

        refreshSelection();
    }

    @Override
    public void initialise() {
        resolver = new DependencyResolver(moduleManager.getRegistry());
        modulesLookup = Maps.newHashMap();
        sortedModules = Lists.newArrayList();

        populateModuleInformation();

        Collections.sort(sortedModules, new Comparator<ModuleSelectionInfo>() {
            @Override
            public int compare(ModuleSelectionInfo o1, ModuleSelectionInfo o2) {
                return o1.getMetadata().getDisplayName().toString().compareTo(o2.getMetadata().getDisplayName().toString());
            }
        });

        final UIList<ModuleSelectionInfo> moduleList = find("moduleList", UIList.class);
        if (moduleList != null) {
            moduleList.setList(sortedModules);
            moduleList.setItemRenderer(new AbstractItemRenderer<ModuleSelectionInfo>() {

                public String getString(ModuleSelectionInfo value) {
                    return value.getMetadata().getDisplayName().toString();
                }

                @Override
                public void draw(ModuleSelectionInfo value, Canvas canvas) {
                    if (isSelectedGameplayModule(value)) {
                        canvas.setMode("gameplay");
                    } else if (value.isSelected() && value.isExplicitSelection()) {
                        canvas.setMode("enabled");
                    } else if (value.isSelected()) {
                        canvas.setMode("dependency");
                    } else if (value.isValidToSelect()) {
                        canvas.setMode("disabled");
                    } else {
                        canvas.setMode("invalid");
                    }
                    canvas.drawText(getString(value), canvas.getRegion());
                }

                @Override
                public Vector2i getPreferredSize(ModuleSelectionInfo value, Canvas canvas) {
                    String text = getString(value);
                    return new Vector2i(canvas.getCurrentStyle().getFont().getWidth(text), canvas.getCurrentStyle().getFont().getLineHeight());
                }
            });

            //ItemActivateEventListener is triggered by double clicking
            moduleList.subscribe(new ItemActivateEventListener<ModuleSelectionInfo>() {
                @Override
                public void onItemActivated(UIWidget widget, ModuleSelectionInfo item) {
                    if (item.isSelected() && moduleList.getSelection().isExplicitSelection()) {
                        deselect(item);
                    } else if (item.isValidToSelect()) {
                        select(item);
                    }
                }
            });

            final Binding<ModuleMetadata> moduleInfoBinding = new ReadOnlyBinding<ModuleMetadata>() {
                @Override
                public ModuleMetadata get() {
                    if (moduleList.getSelection() != null) {
                        return moduleList.getSelection().getMetadata();
                    }
                    return null;
                }
            };

            UILabel name = find("name", UILabel.class);
            if (name != null) {
                name.bindText(new ReadOnlyBinding<String>() {
                    @Override
                    public String get() {
                        if (moduleInfoBinding.get() != null) {
                            return moduleInfoBinding.get().getDisplayName().toString();
                        }
                        return "";
                    }
                });
            }

            UILabel version = find("version", UILabel.class);
            if (version != null) {
                version.bindText(new ReadOnlyBinding<String>() {
                    @Override
                    public String get() {
                        if (moduleInfoBinding.get() != null) {
                            return moduleInfoBinding.get().getVersion().toString();
                        }
                        return "";
                    }
                });
            }

            UILabel description = find("description", UILabel.class);
            if (description != null) {
                description.bindText(new ReadOnlyBinding<String>() {
                    @Override
                    public String get() {
                        if (moduleInfoBinding.get() != null) {
                            return moduleInfoBinding.get().getDescription().toString();
                        }
                        return "";
                    }
                });
            }

            UILabel error = find("errorMessage", UILabel.class);
            if (error != null) {
                error.bindText(new ReadOnlyBinding<String>() {
                    @Override
                    public String get() {
                        if (moduleList.getSelection() != null) {
                            if (!moduleList.getSelection().isValidToSelect()) {
                                return "Incompatible with existing selection, or dependencies cannot be resolved";
                            }
                        }
                        return "";
                    }
                });
            }

            UIButton toggle = find("toggleActivation", UIButton.class);
            if (toggle != null) {
                toggle.subscribe(new ActivateEventListener() {
                    @Override
                    public void onActivated(UIWidget button) {
                        if (moduleList.getSelection() != null) {

                            // Toggle
                            if (moduleList.getSelection().isSelected() && moduleList.getSelection().isExplicitSelection()) {
                                deselect(moduleList.getSelection());
                            } else if (moduleList.getSelection().isValidToSelect()) {
                                select(moduleList.getSelection());
                            }
                        }
                    }
                });
                toggle.bindVisible(new ReadOnlyBinding<Boolean>() {
                    @Override
                    public Boolean get() {
                        return moduleList.getSelection() != null
                                && (moduleList.getSelection().isSelected() || moduleList.getSelection().isValidToSelect());
                    }
                });
                toggle.bindText(new ReadOnlyBinding<String>() {
                    @Override
                    public String get() {
                        if (moduleList.getSelection() != null) {
                            if (moduleList.getSelection().isExplicitSelection()) {
                                return "Deactivate";
                            } else {
                                return "Activate";
                            }
                        }
                        return "";
                    }
                });
            }

            UIButton enableAll = find("enableAll", UIButton.class);
            if (enableAll != null) {
                enableAll.subscribe(new ActivateEventListener() {
                    @Override
                    public void onActivated(UIWidget button) {
                        for (ModuleSelectionInfo info : sortedModules) {
                            if (!info.isExplicitSelection() && info.isValidToSelect()) {
                                select(info);
                            }
                        }
                    }
                });
            }

            UIButton disableAll = find("disableAll", UIButton.class);
            if (disableAll != null) {
                disableAll.subscribe(new ActivateEventListener() {
                    @Override
                    public void onActivated(UIWidget button) {
                        for (ModuleSelectionInfo info : sortedModules) {
                            if (info.isSelected() && info.isExplicitSelection()) {
                                deselect(info);
                            }
                        }
                    }
                });
            }
        }


        WidgetUtil.trySubscribe(this, "close", new ActivateEventListener() {
            @Override
            public void onActivated(UIWidget button) {
                getManager().popScreen();
            }
        });
    }

    private void updateValidToSelect() {
        List<Name> selectedModules = Lists.newArrayList();
        for (SelectModulesScreen.ModuleSelectionInfo info : sortedModules) {
            if (info.isSelected()) {
                selectedModules.add(info.getMetadata().getId());
            }
        }
        Name[] selectedModulesArray = selectedModules.toArray(new Name[selectedModules.size()]);
        for (SelectModulesScreen.ModuleSelectionInfo info : sortedModules) {
            if (!info.isSelected()) {
                info.setValidToSelect(resolver.resolve(info.getMetadata().getId(), selectedModulesArray).isSuccess());
            }
        }
    }

    private void setSelectedVersions(ResolutionResult currentSelectionResults) {
        for (Module module : currentSelectionResults.getModules()) {
            SelectModulesScreen.ModuleSelectionInfo info = modulesLookup.get(module.getId());
            info.setSelectedVersion(module);
        }
    }

    private void populateModuleInformation() {
        for (Name moduleId : moduleManager.getRegistry().getModuleIds()) {
            Module latestVersion = moduleManager.getRegistry().getLatestModuleVersion(moduleId);
            if (!latestVersion.isOnClasspath()) {
                SelectModulesScreen.ModuleSelectionInfo info = new SelectModulesScreen.ModuleSelectionInfo(latestVersion);
                modulesLookup.put(info.getMetadata().getId(), info);
                sortedModules.add(info);
            }
        }
    }

    @Override
    public void onClosed() {
        ModuleConfig moduleConfig = config.getDefaultModSelection();
        moduleConfig.clear();
        for (ModuleSelectionInfo info : sortedModules) {
            if (info.isSelected() && info.isExplicitSelection()) {
                moduleConfig.addModule(info.getMetadata().getId());
            }
        }
        if (!moduleConfig.hasModule(config.getWorldGeneration().getDefaultGenerator().getModuleName())) {
            config.getWorldGeneration().setDefaultGenerator(new SimpleUri());
        }
        config.save();
    }

    @Override
    public boolean isLowerLayerVisible() {
        return false;
    }

    private void select(ModuleSelectionInfo target) {
        if (target.isValidToSelect() && !target.isExplicitSelection()) {
            boolean previouslySelected = target.isSelected();
            target.setExplicitSelection(true);
            if (!previouslySelected) {
                refreshSelection();
            }
        }
    }

    private List<Name> getExplicitlySelectedModules() {
        List<Name> selectedModules = Lists.newArrayList();
        for (SelectModulesScreen.ModuleSelectionInfo info : sortedModules) {
            if (info.isExplicitSelection()) {
                selectedModules.add(info.getMetadata().getId());
            }
        }
        return selectedModules;
    }

    private void deselect(ModuleSelectionInfo target) {
        // only deselect if it is already selected and if it is not the currently selected gameplay module
        if (target.isExplicitSelection()
                && !isSelectedGameplayModule(target)) {
            target.setExplicitSelection(false);
            refreshSelection();
        }
    }

    private boolean isSelectedGameplayModule(ModuleSelectionInfo target) {
        return target.getMetadata().getId().equals(new Name(config.getDefaultModSelection().getDefaultGameplayModuleName()));
    }

    private void refreshSelection() {
        List<Name> selectedModules = getExplicitlySelectedModules();
        for (ModuleSelectionInfo info : sortedModules) {
            info.setSelectedVersion(null);
        }
        setSelectedVersions(resolver.resolve(selectedModules));
        updateValidToSelect();
    }


    private static class ModuleSelectionInfo {
        private Module latestVersion;
        private Module selectedVersion;
        private boolean explicitSelection;
        private boolean validToSelect = true;

        public ModuleSelectionInfo(Module module) {
            this.latestVersion = module;
        }

        public ModuleMetadata getMetadata() {
            if (selectedVersion != null) {
                return selectedVersion.getMetadata();
            } else {
                return latestVersion.getMetadata();
            }
        }

        public boolean isSelected() {
            return selectedVersion != null;
        }

        public void setSelectedVersion(Module selectedVersion) {
            this.selectedVersion = selectedVersion;
        }

        public boolean isExplicitSelection() {
            return explicitSelection;
        }

        public void setExplicitSelection(boolean explicitSelection) {
            this.explicitSelection = explicitSelection;
        }

        public boolean isValidToSelect() {
            return validToSelect;
        }

        public void setValidToSelect(boolean validToSelect) {
            this.validToSelect = validToSelect;
        }
    }
}
TOP

Related Classes of org.terasology.rendering.nui.layers.mainMenu.SelectModulesScreen$ModuleSelectionInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.