210 lines
7.7 KiB
Java
210 lines
7.7 KiB
Java
/*
|
|
* WorldEdit, a Minecraft world manipulation toolkit
|
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
|
* Copyright (C) WorldEdit team and contributors
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package com.sk89q.worldedit.util.formatting.component;
|
|
|
|
import com.fastasyncworldedit.core.configuration.Caption;
|
|
import com.google.common.base.Function;
|
|
import com.google.common.collect.Collections2;
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.sk89q.worldedit.util.formatting.text.Component;
|
|
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
|
import com.sk89q.worldedit.util.formatting.text.event.ClickEvent;
|
|
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
|
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
|
|
|
import javax.annotation.Nullable;
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import java.util.stream.Collectors;
|
|
|
|
public abstract class PaginationBox extends MessageBox {
|
|
|
|
private static final int IDEAL_ROWS_FOR_PLAYER = 8;
|
|
|
|
private String pageCommand;
|
|
private int componentsPerPage = IDEAL_ROWS_FOR_PLAYER;
|
|
private int currentPage = -1;
|
|
|
|
/**
|
|
* Creates a Paginated component
|
|
*
|
|
* @param title The title
|
|
*/
|
|
protected PaginationBox(String title) {
|
|
this(title, null);
|
|
}
|
|
|
|
public abstract Component getComponent(int number);
|
|
|
|
public abstract int getComponentsSize();
|
|
|
|
public void setComponentsPerPage(int componentsPerPage) {
|
|
this.componentsPerPage = componentsPerPage;
|
|
}
|
|
|
|
public void formatForConsole() {
|
|
this.pageCommand = null;
|
|
this.componentsPerPage = 20;
|
|
}
|
|
|
|
protected final int getCurrentPage() {
|
|
return currentPage;
|
|
}
|
|
|
|
/**
|
|
* Creates a Paginated component
|
|
*
|
|
* @param title The title
|
|
* @param pageCommand The command to run to switch page, with %page% representing page number
|
|
*/
|
|
protected PaginationBox(String title, @Nullable String pageCommand) {
|
|
super(title, new TextComponentProducer());
|
|
|
|
if (pageCommand != null && !pageCommand.contains("%page%")) {
|
|
if (pageCommand.contains("-p ")) {
|
|
pageCommand = pageCommand.replaceAll("-p [0-9]+", "-p %page%");
|
|
} else {
|
|
pageCommand = pageCommand + " -p %page%";
|
|
}
|
|
}
|
|
this.pageCommand = pageCommand;
|
|
}
|
|
|
|
public Component create(int page) throws InvalidComponentException {
|
|
if (page == 1 && getComponentsSize() == 0) {
|
|
return getContents().reset().append("No results found.").create();
|
|
}
|
|
int pageCount = (int) Math.ceil(getComponentsSize() / (double) componentsPerPage);
|
|
if (page < 1 || page > pageCount) {
|
|
throw new InvalidComponentException(Caption.of("worldedit.error.invalid-page"));
|
|
}
|
|
currentPage = page;
|
|
final int lastComp = Math.min(page * componentsPerPage, getComponentsSize());
|
|
for (int i = (page - 1) * componentsPerPage; i < lastComp; i++) {
|
|
getContents().append(getComponent(i));
|
|
if (i + 1 != lastComp) {
|
|
getContents().newline();
|
|
}
|
|
}
|
|
if (pageCount == 1) {
|
|
return super.create();
|
|
}
|
|
getContents().newline();
|
|
TextComponent pageNumberComponent = TextComponent.of("Page ", TextColor.YELLOW)
|
|
.append(TextComponent.of(String.valueOf(page), TextColor.GOLD))
|
|
.append(TextComponent.of(" of "))
|
|
.append(TextComponent.of(String.valueOf(pageCount), TextColor.GOLD));
|
|
if (pageCommand != null) {
|
|
TextComponentProducer navProducer = new TextComponentProducer();
|
|
if (page > 1) {
|
|
TextComponent prevComponent = TextComponent.of("<<< ", TextColor.GOLD)
|
|
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, pageCommand.replace("%page%", String.valueOf(page - 1))))
|
|
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to navigate")));
|
|
navProducer.append(prevComponent);
|
|
}
|
|
navProducer.append(pageNumberComponent);
|
|
if (page < pageCount) {
|
|
TextComponent nextComponent = TextComponent.of(" >>>", TextColor.GOLD)
|
|
.clickEvent(ClickEvent.of(ClickEvent.Action.RUN_COMMAND, pageCommand.replace("%page%", String.valueOf(page + 1))))
|
|
.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, TextComponent.of("Click to navigate")));
|
|
navProducer.append(nextComponent);
|
|
}
|
|
getContents().append(centerAndBorder(navProducer.create()));
|
|
} else {
|
|
getContents().append(centerAndBorder(pageNumberComponent));
|
|
}
|
|
return super.create();
|
|
}
|
|
|
|
@Override
|
|
public TextComponent create() {
|
|
throw new IllegalStateException("Pagination components must be created with a page");
|
|
}
|
|
|
|
public static <T> PaginationBox fromStrings(String header, @Nullable String pageCommand, Collection<T> lines, Function<T, Component> adapt) {
|
|
return fromComponents(header, pageCommand, Collections2.transform(lines, adapt));
|
|
}
|
|
|
|
public static PaginationBox fromStrings(String header, @Nullable String pageCommand, Collection<String> lines) {
|
|
return fromComponents(header, pageCommand, lines.stream()
|
|
.map(TextComponent::of)
|
|
.collect(Collectors.toList()));
|
|
}
|
|
|
|
public static PaginationBox fromComponents(String header, @Nullable String pageCommand, Collection<Component> lines) {
|
|
return new ListPaginationBox(header, pageCommand, lines);
|
|
}
|
|
|
|
private static class ListPaginationBox extends PaginationBox {
|
|
private final List<Component> lines;
|
|
|
|
ListPaginationBox(String header, String pageCommand, Collection<Component> lines) {
|
|
super(header, pageCommand);
|
|
this.lines = ImmutableList.copyOf(lines);
|
|
}
|
|
|
|
@Override
|
|
public Component getComponent(int number) {
|
|
return lines.get(number);
|
|
}
|
|
|
|
@Override
|
|
public int getComponentsSize() {
|
|
return lines.size();
|
|
}
|
|
}
|
|
|
|
public static class MergedPaginationBox extends PaginationBox {
|
|
private final PaginationBox[] values;
|
|
|
|
public MergedPaginationBox(String header, String pageCommand, PaginationBox... values) {
|
|
super(header, pageCommand);
|
|
this.values = values;
|
|
}
|
|
|
|
@Override
|
|
public Component getComponent(int number) {
|
|
for (PaginationBox box : values) {
|
|
if (box == null) {
|
|
continue;
|
|
}
|
|
int size = box.getComponentsSize();
|
|
if (size > number) {
|
|
return box.getComponent(number);
|
|
}
|
|
number -= size;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public int getComponentsSize() {
|
|
int size = 0;
|
|
for (PaginationBox box : values) {
|
|
if (box == null) {
|
|
continue;
|
|
}
|
|
size += box.getComponentsSize();
|
|
}
|
|
return size;
|
|
}
|
|
}
|
|
}
|