/* * This file is part of NucleusFramework for Bukkit, licensed under the MIT License (MIT). * * Copyright (c) JCThePants (www.jcwhatever.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.jcwhatever.nucleus.views.menu; import com.jcwhatever.nucleus.mixins.IPaginator; import com.jcwhatever.nucleus.mixins.IPaginator.PageStartIndex; import com.jcwhatever.nucleus.utils.MetaKey; import com.jcwhatever.nucleus.utils.PreCon; import com.jcwhatever.nucleus.utils.items.ItemStackMatcher; import com.jcwhatever.nucleus.views.View; import com.jcwhatever.nucleus.views.ViewCloseReason; import com.jcwhatever.nucleus.views.ViewOpenReason; import com.jcwhatever.nucleus.views.ViewSession; import org.bukkit.Material; import org.bukkit.plugin.Plugin; import java.util.ArrayList; import java.util.List; import javax.annotation.Nullable; /** * A basic paginator view. * * <p>The paginator view provides a selection interface for an * {@link com.jcwhatever.nucleus.mixins.IPaginator} instance. When a page * is selected the view is closed and the result can be retrieved using the * {@link #getSelectedPage} method.</p> */ public class PaginatorView extends MenuView { private static final MetaKey<Integer> SELECTED_PAGE = new MetaKey<>(Integer.class); /** * Show the paginator view if the specified paginator has more than 1 page. * Otherwise show the next view. * * <p>If the paginator view is shown, selecting a page will cause the next view * to open.</p> * * @param viewSession The view session. * @param nextView The next view to show. * @param paginator The paginator. * @param matcher The {@link ItemStackMatcher} to use. */ public static void paginateNext(ViewSession viewSession, View nextView, IPaginator paginator, @Nullable ItemStackMatcher matcher) { if (paginator.getTotalPages() > 1) { viewSession.next(new PaginatorView(nextView.getPlugin(), paginator, nextView, matcher)); } else { viewSession.next(nextView); } } private final IPaginator _paginator; private final View _nextView; private int _selectedPage = 1; /** * Constructor. * * @param plugin The owning plugin. * @param paginator The paginator of the view. * @param matcher The item stack matcher. */ public PaginatorView(Plugin plugin, IPaginator paginator, @Nullable ItemStackMatcher matcher) { this(plugin, paginator, null, matcher); } /** * Constructor. * * @param plugin The owning plugin. * @param nextView The nextView to open when a page is selected. * @param paginator The paginator of the view. * @param matcher The item stack matcher. */ public PaginatorView(Plugin plugin, IPaginator paginator, @Nullable View nextView, @Nullable ItemStackMatcher matcher) { super(plugin, matcher); PreCon.notNull(paginator); _paginator = paginator; _nextView = nextView; } /** * Get the page selected. */ public int getSelectedPage() { return _selectedPage; } @Override public String getTitle() { return "Select page"; } @Override protected void onClose(ViewCloseReason reason) { // do nothing } @Override protected void onShow(ViewOpenReason reason) { // do nothing } @Override protected List<MenuItem> createMenuItems() { int itemsPerPage = _paginator.getItemsPerPage(); if (itemsPerPage > MenuView.MAX_SLOTS) throw new RuntimeException("Items per page cannot be larger than " + MenuView.MAX_SLOTS); int totalPages = _paginator.getTotalPages(); if (totalPages > MenuView.MAX_SLOTS) throw new RuntimeException("Total pages cannot be larger than " + MenuView.MAX_SLOTS); List<MenuItem> menuItems = new ArrayList<>(totalPages); for (int i=0; i < totalPages; i++) { int page = i; if (_paginator.getPageStartIndex() == PageStartIndex.ONE) page++; menuItems.add(getPageItem(i, page)); } return menuItems; } @Override protected void onItemSelect(MenuItem menuItem) { Integer selectedPage = menuItem.getMeta().get(SELECTED_PAGE); if (selectedPage == null) throw new AssertionError(); _selectedPage = selectedPage; if (_nextView == null) { getViewSession().previous(); } else { getViewSession().next(_nextView); } } /** * Create a menu item for the slot and page. * * @param slot The slot the menu item will be in. * @param page The page the menu item represents. */ protected MenuItem getPageItem(int slot, int page) { return new MenuItemBuilder(Material.PAPER) .title("Page" + page) .description("Click to view page " + page + '.') .meta(SELECTED_PAGE, page) .build(slot); } }