001/* 002 * This file is part of Baritone. 003 * 004 * Baritone is free software: you can redistribute it and/or modify 005 * it under the terms of the GNU Lesser General Public License as published by 006 * the Free Software Foundation, either version 3 of the License, or 007 * (at your option) any later version. 008 * 009 * Baritone is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public License 015 * along with Baritone. If not, see <https://www.gnu.org/licenses/>. 016 */ 017 018package baritone.api.command.helpers; 019 020import baritone.api.command.argument.IArgConsumer; 021import baritone.api.command.exception.CommandException; 022import baritone.api.command.exception.CommandInvalidTypeException; 023import baritone.api.utils.Helper; 024import net.minecraft.util.text.ITextComponent; 025import net.minecraft.util.text.TextComponentString; 026import net.minecraft.util.text.TextFormatting; 027import net.minecraft.util.text.event.ClickEvent; 028import net.minecraft.util.text.event.HoverEvent; 029 030import java.util.Arrays; 031import java.util.List; 032import java.util.function.Function; 033 034public class Paginator<E> implements Helper { 035 036 public final List<E> entries; 037 public int pageSize = 8; 038 public int page = 1; 039 040 public Paginator(List<E> entries) { 041 this.entries = entries; 042 } 043 044 public Paginator(E... entries) { 045 this.entries = Arrays.asList(entries); 046 } 047 048 public Paginator<E> setPageSize(int pageSize) { 049 this.pageSize = pageSize; 050 return this; 051 } 052 053 public int getMaxPage() { 054 return (entries.size() - 1) / pageSize + 1; 055 } 056 057 public boolean validPage(int page) { 058 return page > 0 && page <= getMaxPage(); 059 } 060 061 public Paginator<E> skipPages(int pages) { 062 page += pages; 063 return this; 064 } 065 066 public void display(Function<E, ITextComponent> transform, String commandPrefix) { 067 int offset = (page - 1) * pageSize; 068 for (int i = offset; i < offset + pageSize; i++) { 069 if (i < entries.size()) { 070 logDirect(transform.apply(entries.get(i))); 071 } else { 072 logDirect("--", TextFormatting.DARK_GRAY); 073 } 074 } 075 boolean hasPrevPage = commandPrefix != null && validPage(page - 1); 076 boolean hasNextPage = commandPrefix != null && validPage(page + 1); 077 ITextComponent prevPageComponent = new TextComponentString("<<"); 078 if (hasPrevPage) { 079 prevPageComponent.getStyle() 080 .setClickEvent(new ClickEvent( 081 ClickEvent.Action.RUN_COMMAND, 082 String.format("%s %d", commandPrefix, page - 1) 083 )) 084 .setHoverEvent(new HoverEvent( 085 HoverEvent.Action.SHOW_TEXT, 086 new TextComponentString("Click to view previous page") 087 )); 088 } else { 089 prevPageComponent.getStyle().setColor(TextFormatting.DARK_GRAY); 090 } 091 ITextComponent nextPageComponent = new TextComponentString(">>"); 092 if (hasNextPage) { 093 nextPageComponent.getStyle() 094 .setClickEvent(new ClickEvent( 095 ClickEvent.Action.RUN_COMMAND, 096 String.format("%s %d", commandPrefix, page + 1) 097 )) 098 .setHoverEvent(new HoverEvent( 099 HoverEvent.Action.SHOW_TEXT, 100 new TextComponentString("Click to view next page") 101 )); 102 } else { 103 nextPageComponent.getStyle().setColor(TextFormatting.DARK_GRAY); 104 } 105 ITextComponent pagerComponent = new TextComponentString(""); 106 pagerComponent.getStyle().setColor(TextFormatting.GRAY); 107 pagerComponent.appendSibling(prevPageComponent); 108 pagerComponent.appendText(" | "); 109 pagerComponent.appendSibling(nextPageComponent); 110 pagerComponent.appendText(String.format(" %d/%d", page, getMaxPage())); 111 logDirect(pagerComponent); 112 } 113 114 public void display(Function<E, ITextComponent> transform) { 115 display(transform, null); 116 } 117 118 public static <T> void paginate(IArgConsumer consumer, Paginator<T> pagi, Runnable pre, Function<T, ITextComponent> transform, String commandPrefix) throws CommandException { 119 int page = 1; 120 consumer.requireMax(1); 121 if (consumer.hasAny()) { 122 page = consumer.getAs(Integer.class); 123 if (!pagi.validPage(page)) { 124 throw new CommandInvalidTypeException( 125 consumer.consumed(), 126 String.format( 127 "a valid page (1-%d)", 128 pagi.getMaxPage() 129 ), 130 consumer.consumed().getValue() 131 ); 132 } 133 } 134 pagi.skipPages(page - pagi.page); 135 if (pre != null) { 136 pre.run(); 137 } 138 pagi.display(transform, commandPrefix); 139 } 140 141 public static <T> void paginate(IArgConsumer consumer, List<T> elems, Runnable pre, Function<T, ITextComponent> transform, String commandPrefix) throws CommandException { 142 paginate(consumer, new Paginator<>(elems), pre, transform, commandPrefix); 143 } 144 145 public static <T> void paginate(IArgConsumer consumer, T[] elems, Runnable pre, Function<T, ITextComponent> transform, String commandPrefix) throws CommandException { 146 paginate(consumer, Arrays.asList(elems), pre, transform, commandPrefix); 147 } 148 149 public static <T> void paginate(IArgConsumer consumer, Paginator<T> pagi, Function<T, ITextComponent> transform, String commandPrefix) throws CommandException { 150 paginate(consumer, pagi, null, transform, commandPrefix); 151 } 152 153 public static <T> void paginate(IArgConsumer consumer, List<T> elems, Function<T, ITextComponent> transform, String commandPrefix) throws CommandException { 154 paginate(consumer, new Paginator<>(elems), null, transform, commandPrefix); 155 } 156 157 public static <T> void paginate(IArgConsumer consumer, T[] elems, Function<T, ITextComponent> transform, String commandPrefix) throws CommandException { 158 paginate(consumer, Arrays.asList(elems), null, transform, commandPrefix); 159 } 160 161 public static <T> void paginate(IArgConsumer consumer, Paginator<T> pagi, Runnable pre, Function<T, ITextComponent> transform) throws CommandException { 162 paginate(consumer, pagi, pre, transform, null); 163 } 164 165 public static <T> void paginate(IArgConsumer consumer, List<T> elems, Runnable pre, Function<T, ITextComponent> transform) throws CommandException { 166 paginate(consumer, new Paginator<>(elems), pre, transform, null); 167 } 168 169 public static <T> void paginate(IArgConsumer consumer, T[] elems, Runnable pre, Function<T, ITextComponent> transform) throws CommandException { 170 paginate(consumer, Arrays.asList(elems), pre, transform, null); 171 } 172 173 public static <T> void paginate(IArgConsumer consumer, Paginator<T> pagi, Function<T, ITextComponent> transform) throws CommandException { 174 paginate(consumer, pagi, null, transform, null); 175 } 176 177 public static <T> void paginate(IArgConsumer consumer, List<T> elems, Function<T, ITextComponent> transform) throws CommandException { 178 paginate(consumer, new Paginator<>(elems), null, transform, null); 179 } 180 181 public static <T> void paginate(IArgConsumer consumer, T[] elems, Function<T, ITextComponent> transform) throws CommandException { 182 paginate(consumer, Arrays.asList(elems), null, transform, null); 183 } 184}