classpublicPriority 3
ImageImportPage
com.hypixel.hytale.builtin.buildertools.imageimport.ImageImportPage
extends InteractiveCustomUIPage
1
Methods
1
Public Methods
11
Fields
1
Constructors
Constants
BuilderCodec<ImageImportPage.PageData>CODEC= BuilderCodec.builder(ImageImportPage.PageData.class, ImageImportPage.PageData::new)
.add...
intDEFAULT_MAX_SIZE= 128
PathIMPORTS_DIR= Paths.get("imports", "images")
StringKEY_BROWSE= "Browse"
StringKEY_BROWSER_CANCEL= "BrowserCancel"
StringKEY_BROWSER_SELECT= "BrowserSelect"
StringKEY_IMAGE_PATH= "@ImagePath"
StringKEY_IMPORT= "Import"
StringKEY_MAX_SIZE= "@MaxSize"
StringKEY_ORIENTATION= "@Orientation"
StringKEY_ORIGIN= "@Origin"
intMAX_SIZE= 512
intMIN_SIZE= 1
StringPASTE_TOOL_ID= "EditorTool_Paste"
Constructors
public
ImageImportPage(PlayerRef playerRef)Methods
Public Methods (1)
public
void handleDataEvent(Ref<EntityStore> ref, Store<EntityStore> store, ImageImportPage.PageData data)Fields
Private/Package Fields (11)
private
ServerFileBrowser browserprivate
String imagePathprivate
boolean isErrorprivate
boolean isProcessingprivate
int maxDimensionprivate
ImageImportPage.Orientation orientationprivate
String orientationStrprivate
ImageImportPage.Origin originprivate
String originStrprivate
boolean showBrowserprivate
String statusMessageInheritance
Parent
Current
Interface
Child
Use mouse wheel to zoom, drag to pan. Click nodes to navigate.
Related Classes
Used By
BlockColorIndexBuilderToolsPluginCodecKeyedCodecBuilderCodecStringUtilRefStoreHytaleLoggerVector3iCustomPageLifetimeCustomUIEventBindingTypePageSetActiveSlotMessagePlayerInteractiveCustomUIPageInventoryItemStackItemContainerSingleplayerModuleBlockSelectionDropdownEntryInfoLocalizableStringFileBrowserConfigServerFileBrowserEventDataUICommandBuilderUIEventBuilderPlayerRefEntityStore
Source Code
package com.hypixel.hytale.builtin.buildertools.imageimport;
import com.hypixel.hytale.builtin.buildertools.BlockColorIndex;
import com.hypixel.hytale.builtin.buildertools.BuilderToolsPlugin;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.common.util.StringUtil;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageLifetime;
import com.hypixel.hytale.protocol.packets.interface_.CustomUIEventBindingType;
import com.hypixel.hytale.protocol.packets.interface_.Page;
import com.hypixel.hytale.protocol.packets.inventory.SetActiveSlot;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.entity.entities.player.pages.InteractiveCustomUIPage;
import com.hypixel.hytale.server.core.inventory.Inventory;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
import com.hypixel.hytale.server.core.modules.singleplayer.SingleplayerModule;
import com.hypixel.hytale.server.core.prefab.selection.standard.BlockSelection;
import com.hypixel.hytale.server.core.ui.DropdownEntryInfo;
import com.hypixel.hytale.server.core.ui.LocalizableString;
import com.hypixel.hytale.server.core.ui.browser.FileBrowserConfig;
import com.hypixel.hytale.server.core.ui.browser.ServerFileBrowser;
import com.hypixel.hytale.server.core.ui.builder.EventData;
import com.hypixel.hytale.server.core.ui.builder.UICommandBuilder;
import com.hypixel.hytale.server.core.ui.builder.UIEventBuilder;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.imageio.ImageIO;
public class ImageImportPage extends InteractiveCustomUIPage<ImageImportPage.PageData> {
private static final int DEFAULT_MAX_SIZE = 128;
private static final int MIN_SIZE = 1;
private static final int MAX_SIZE = 512;
private static final String PASTE_TOOL_ID = "EditorTool_Paste";
private static final Path IMPORTS_DIR = Paths.get("imports", "images");
@Nonnull
private String imagePath = "";
private int maxDimension = 128;
@Nonnull
private String orientationStr = "wall_xy";
@Nonnull
private ImageImportPage.Orientation orientation = ImageImportPage.Orientation.VERTICAL_XY;
@Nonnull
private String originStr = "bottom_center";
@Nonnull
private ImageImportPage.Origin origin = ImageImportPage.Origin.BOTTOM_CENTER;
@Nullable
private String statusMessage = null;
private boolean isError = false;
private boolean isProcessing = false;
private boolean showBrowser = false;
@Nonnull
private final ServerFileBrowser browser;
public ImageImportPage(@Nonnull PlayerRef playerRef) {
super(playerRef, CustomPageLifetime.CanDismiss, ImageImportPage.PageData.CODEC);
FileBrowserConfig config = FileBrowserConfig.builder()
.listElementId("#BrowserPage #FileList")
.searchInputId("#BrowserPage #SearchInput")
.currentPathId("#BrowserPage #CurrentPath")
.roots(List.of(new FileBrowserConfig.RootEntry("Imports", IMPORTS_DIR)))
.allowedExtensions(".png", ".jpg", ".jpeg", ".gif", ".bmp")
.enableRootSelector(false)
.enableSearch(true)
.enableDirectoryNav(true)
.maxResults(50)
.build();
try {
Files.createDirectories(IMPORTS_DIR);
} catch (IOException var4) {
}
this.browser = new ServerFileBrowser(config);
}
@Override
public void build(
@Nonnull Ref<EntityStore> ref, @Nonnull UICommandBuilder commandBuilder, @Nonnull UIEventBuilder eventBuilder, @Nonnull Store<EntityStore> store
) {
commandBuilder.append("Pages/ImageImportPage.ui");
commandBuilder.set("#ImagePath #Input.Value", this.imagePath);
commandBuilder.set("#MaxSizeInput #Input.Value", this.maxDimension);
List<DropdownEntryInfo> orientationEntries = new ArrayList<>();
orientationEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.imageImport.orientation.wall_xy"), "wall_xy"));
orientationEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.imageImport.orientation.wall_xz"), "wall_xz"));
orientationEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.imageImport.orientation.floor"), "floor"));
commandBuilder.set("#OrientationInput #Input.Entries", orientationEntries);
commandBuilder.set("#OrientationInput #Input.Value", this.orientationStr);
List<DropdownEntryInfo> originEntries = new ArrayList<>();
originEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.origin.bottom_front_left"), "bottom_front_left"));
originEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.origin.bottom_center"), "bottom_center"));
originEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.origin.center"), "center"));
originEntries.add(new DropdownEntryInfo(LocalizableString.fromMessageId("server.customUI.origin.top_center"), "top_center"));
commandBuilder.set("#OriginInput #Input.Entries", originEntries);
commandBuilder.set("#OriginInput #Input.Value", this.originStr);
this.updateStatus(commandBuilder);
eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#ImagePath #Input", EventData.of("@ImagePath", "#ImagePath #Input.Value"), false);
eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#MaxSizeInput #Input", EventData.of("@MaxSize", "#MaxSizeInput #Input.Value"), false);
eventBuilder.addEventBinding(
CustomUIEventBindingType.ValueChanged, "#OrientationInput #Input", EventData.of("@Orientation", "#OrientationInput #Input.Value"), false
);
eventBuilder.addEventBinding(CustomUIEventBindingType.ValueChanged, "#OriginInput #Input", EventData.of("@Origin", "#OriginInput #Input.Value"), false);
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#ImportButton", EventData.of("Import", "true"));
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#ImagePath #BrowseButton", EventData.of("Browse", "true"));
commandBuilder.set("#FormContainer.Visible", !this.showBrowser);
commandBuilder.set("#BrowserPage.Visible", this.showBrowser);
if (this.showBrowser) {
this.buildBrowserPage(commandBuilder, eventBuilder);
}
}
private void buildBrowserPage(@Nonnull UICommandBuilder commandBuilder, @Nonnull UIEventBuilder eventBuilder) {
this.browser.buildSearchInput(commandBuilder, eventBuilder);
this.browser.buildCurrentPath(commandBuilder);
this.browser.buildFileList(commandBuilder, eventBuilder);
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#BrowserPage #SelectButton", EventData.of("BrowserSelect", "true"));
eventBuilder.addEventBinding(CustomUIEventBindingType.Activating, "#BrowserPage #CancelButton", EventData.of("BrowserCancel", "true"));
}
private void updateStatus(@Nonnull UICommandBuilder commandBuilder) {
if (this.statusMessage != null) {
commandBuilder.set("#StatusText.Text", this.statusMessage);
commandBuilder.set("#StatusText.Visible", true);
commandBuilder.set("#StatusText.Style.TextColor", this.isError ? "#e74c3c" : "#cfd8e3");
} else {
commandBuilder.set("#StatusText.Visible", false);
}
}
private void setError(@Nonnull String message) {
this.statusMessage = message;
this.isError = true;
this.isProcessing = false;
this.rebuild();
}
private void setStatus(@Nonnull String message) {
this.statusMessage = message;
this.isError = false;
this.rebuild();
}
public void handleDataEvent(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store, @Nonnull ImageImportPage.PageData data) {
boolean needsUpdate = false;
if (data.browse != null && data.browse) {
this.showBrowser = true;
this.rebuild();
} else if (data.browserCancel != null && data.browserCancel) {
this.showBrowser = false;
this.rebuild();
} else if (data.browserSelect != null && data.browserSelect) {
if (!this.browser.getSelectedItems().isEmpty()) {
String selectedPath = this.browser.getSelectedItems().iterator().next();
this.imagePath = this.browser.getRoot().resolve(selectedPath).toString();
}
this.showBrowser = false;
this.rebuild();
} else {
if (this.showBrowser && (data.file != null || data.searchQuery != null || data.searchResult != null)) {
boolean handled = false;
if (data.searchQuery != null) {
this.browser.setSearchQuery(data.searchQuery.trim().toLowerCase());
handled = true;
}
if (data.file != null) {
String fileName = data.file;
if ("..".equals(fileName)) {
this.browser.navigateUp();
handled = true;
} else {
Path targetPath = this.browser.resolveFromCurrent(fileName);
if (targetPath != null && Files.isDirectory(targetPath)) {
this.browser.navigateTo(Paths.get(fileName));
handled = true;
} else if (targetPath != null && Files.isRegularFile(targetPath)) {
this.imagePath = targetPath.toString();
this.showBrowser = false;
this.rebuild();
return;
}
}
}
if (data.searchResult != null) {
Path resolvedPath = this.browser.resolveSecure(data.searchResult);
if (resolvedPath != null && Files.isRegularFile(resolvedPath)) {
this.imagePath = resolvedPath.toString();
this.showBrowser = false;
this.rebuild();
return;
}
}
if (handled) {
UICommandBuilder commandBuilder = new UICommandBuilder();
UIEventBuilder eventBuilder = new UIEventBuilder();
this.browser.buildFileList(commandBuilder, eventBuilder);
this.browser.buildCurrentPath(commandBuilder);
this.sendUpdate(commandBuilder, eventBuilder, false);
return;
}
}
if (data.imagePath != null) {
this.imagePath = StringUtil.stripQuotes(data.imagePath.trim());
this.statusMessage = null;
needsUpdate = true;
}
if (data.maxSize != null) {
this.maxDimension = Math.max(1, Math.min(512, data.maxSize));
needsUpdate = true;
}
if (data.orientation != null) {
this.orientationStr = data.orientation.trim().toLowerCase();
String var8 = this.orientationStr;
this.orientation = switch (var8) {
case "wall_xz", "xz", "vertical_xz" -> ImageImportPage.Orientation.VERTICAL_XZ;
case "floor", "horizontal", "horizontal_xz" -> ImageImportPage.Orientation.HORIZONTAL_XZ;
default -> ImageImportPage.Orientation.VERTICAL_XY;
};
needsUpdate = true;
}
if (data.origin != null) {
this.originStr = data.origin.trim().toLowerCase();
String var9 = this.originStr;
this.origin = switch (var9) {
case "bottom_front_left" -> ImageImportPage.Origin.BOTTOM_FRONT_LEFT;
case "center" -> ImageImportPage.Origin.CENTER;
case "top_center" -> ImageImportPage.Origin.TOP_CENTER;
default -> ImageImportPage.Origin.BOTTOM_CENTER;
};
needsUpdate = true;
}
if (data.doImport != null && data.doImport && !this.isProcessing) {
this.performImport(ref, store);
} else {
if (needsUpdate) {
this.sendUpdate();
}
}
}
}
private void performImport(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store) {
if (this.imagePath.isEmpty()) {
this.setError("Please enter a path to an image file");
} else {
Path path = Paths.get(this.imagePath);
if (!SingleplayerModule.isOwner(this.playerRef)) {
Path normalizedPath = path.toAbsolutePath().normalize();
Path normalizedImports = IMPORTS_DIR.toAbsolutePath().normalize();
if (!normalizedPath.startsWith(normalizedImports)) {
this.setError("Files must be in the server's imports/images directory");
return;
}
}
if (!Files.exists(path)) {
this.setError("File not found: " + this.imagePath);
} else {
this.isProcessing = true;
this.setStatus("Processing...");
Player playerComponent = store.getComponent(ref, Player.getComponentType());
PlayerRef playerRefComponent = store.getComponent(ref, PlayerRef.getComponentType());
if (playerComponent != null && playerRefComponent != null) {
String finalPath = this.imagePath;
int finalMaxSize = this.maxDimension;
ImageImportPage.Orientation finalOrientation = this.orientation;
ImageImportPage.Origin finalOrigin = this.origin;
BuilderToolsPlugin.addToQueue(
playerComponent,
playerRefComponent,
(r, builderState, componentAccessor) -> {
try {
BufferedImage image = null;
try {
image = ImageIO.read(Paths.get(finalPath).toFile());
} catch (Exception var38) {
}
if (image == null) {
this.setError("Unable to read image file (unsupported format or corrupted). Try PNG format.");
return;
}
int width = image.getWidth();
int height = image.getHeight();
float scale = 1.0F;
if (width > finalMaxSize || height > finalMaxSize) {
scale = (float)finalMaxSize / (float)Math.max(width, height);
width = Math.round((float)width * scale);
height = Math.round((float)height * scale);
}
BlockColorIndex colorIndex = BuilderToolsPlugin.get().getBlockColorIndex();
if (colorIndex.isEmpty()) {
this.setError("Block color index not initialized");
return;
}
int sizeX;
int sizeY;
int sizeZ;
switch (finalOrientation) {
case VERTICAL_XY:
sizeX = width;
sizeY = height;
sizeZ = 1;
break;
case VERTICAL_XZ:
sizeX = width;
sizeY = 1;
sizeZ = height;
break;
case HORIZONTAL_XZ:
sizeX = width;
sizeY = 1;
sizeZ = height;
break;
default:
sizeX = width;
sizeY = height;
sizeZ = 1;
}
int offsetX = 0;
int offsetY = 0;
int offsetZ = 0;
switch (finalOrigin) {
case BOTTOM_FRONT_LEFT:
default:
break;
case BOTTOM_CENTER:
offsetX = -sizeX / 2;
offsetZ = -sizeZ / 2;
break;
case CENTER:
offsetX = -sizeX / 2;
offsetY = -sizeY / 2;
offsetZ = -sizeZ / 2;
break;
case TOP_CENTER:
offsetX = -sizeX / 2;
offsetY = -sizeY;
offsetZ = -sizeZ / 2;
}
BlockSelection selection = new BlockSelection(width * height, 0);
selection.setPosition(0, 0, 0);
int blockCount = 0;
float finalScale = scale;
for (int imgY = 0; imgY < height; imgY++) {
for (int imgX = 0; imgX < width; imgX++) {
int srcX = Math.min((int)((float)imgX / finalScale), image.getWidth() - 1);
int srcY = Math.min((int)((float)imgY / finalScale), image.getHeight() - 1);
int rgba = image.getRGB(srcX, srcY);
int alpha = rgba >> 24 & 0xFF;
if (alpha >= 128) {
int red = rgba >> 16 & 0xFF;
int green = rgba >> 8 & 0xFF;
int blue = rgba & 0xFF;
int blockId = colorIndex.findClosestBlock(red, green, blue);
if (blockId > 0) {
int blockX;
int blockY;
int blockZ;
switch (finalOrientation) {
case VERTICAL_XY:
blockX = imgX;
blockY = height - 1 - imgY;
blockZ = 0;
break;
case VERTICAL_XZ:
blockX = imgX;
blockY = 0;
blockZ = height - 1 - imgY;
break;
case HORIZONTAL_XZ:
blockX = imgX;
blockY = 0;
blockZ = imgY;
break;
default:
blockX = imgX;
blockY = height - 1 - imgY;
blockZ = 0;
}
selection.addBlockAtLocalPos(blockX + offsetX, blockY + offsetY, blockZ + offsetZ, blockId, 0, 0, 0);
blockCount++;
}
}
}
}
selection.setSelectionArea(
new Vector3i(offsetX, offsetY, offsetZ), new Vector3i(sizeX - 1 + offsetX, sizeY - 1 + offsetY, sizeZ - 1 + offsetZ)
);
builderState.setSelection(selection);
builderState.sendSelectionToClient();
this.statusMessage = String.format("Success! %d blocks copied to clipboard (%dx%dx%d)", blockCount, sizeX, sizeY, sizeZ);
this.isProcessing = false;
playerRefComponent.sendMessage(
Message.translation("server.builderTools.imageImport.success")
.param("count", blockCount)
.param("width", sizeX)
.param("height", sizeY)
.param("depth", sizeZ)
);
playerComponent.getPageManager().setPage(r, store, Page.None);
this.switchToPasteTool(playerComponent, playerRefComponent);
} catch (Exception var39) {
((HytaleLogger.Api)BuilderToolsPlugin.get().getLogger().at(Level.WARNING).withCause(var39)).log("Image import error");
this.setError("Error: " + var39.getMessage());
}
}
);
} else {
this.setError("Player not found");
}
}
}
}
private void switchToPasteTool(@Nonnull Player playerComponent, @Nonnull PlayerRef playerRef) {
Inventory inventory = playerComponent.getInventory();
ItemContainer hotbar = inventory.getHotbar();
ItemContainer storage = inventory.getStorage();
ItemContainer tools = inventory.getTools();
int hotbarSize = hotbar.getCapacity();
for (short slot = 0; slot < hotbarSize; slot++) {
ItemStack itemStack = hotbar.getItemStack(slot);
if (itemStack != null && !itemStack.isEmpty() && "EditorTool_Paste".equals(itemStack.getItemId())) {
inventory.setActiveHotbarSlot((byte)slot);
playerRef.getPacketHandler().writeNoCache(new SetActiveSlot(-1, (byte)slot));
return;
}
}
short emptySlot = -1;
for (short slotx = 0; slotx < hotbarSize; slotx++) {
ItemStack itemStack = hotbar.getItemStack(slotx);
if (itemStack == null || itemStack.isEmpty()) {
emptySlot = slotx;
break;
}
}
if (emptySlot != -1) {
for (short slotxx = 0; slotxx < storage.getCapacity(); slotxx++) {
ItemStack itemStack = storage.getItemStack(slotxx);
if (itemStack != null && !itemStack.isEmpty() && "EditorTool_Paste".equals(itemStack.getItemId())) {
storage.moveItemStackFromSlotToSlot(slotxx, 1, hotbar, emptySlot);
inventory.setActiveHotbarSlot((byte)emptySlot);
playerRef.getPacketHandler().writeNoCache(new SetActiveSlot(-1, (byte)emptySlot));
return;
}
}
ItemStack pasteToolStack = null;
for (short slotxxx = 0; slotxxx < tools.getCapacity(); slotxxx++) {
ItemStack itemStack = tools.getItemStack(slotxxx);
if (itemStack != null && !itemStack.isEmpty() && "EditorTool_Paste".equals(itemStack.getItemId())) {
pasteToolStack = itemStack;
break;
}
}
if (pasteToolStack != null) {
hotbar.setItemStackForSlot(emptySlot, new ItemStack(pasteToolStack.getItemId()));
inventory.setActiveHotbarSlot((byte)emptySlot);
playerRef.getPacketHandler().writeNoCache(new SetActiveSlot(-1, (byte)emptySlot));
}
}
}
public static enum Orientation {
VERTICAL_XY,
VERTICAL_XZ,
HORIZONTAL_XZ;
private Orientation() {
}
}
public static enum Origin {
BOTTOM_FRONT_LEFT,
BOTTOM_CENTER,
CENTER,
TOP_CENTER;
private Origin() {
}
}
public static class PageData {
static final String KEY_IMAGE_PATH = "@ImagePath";
static final String KEY_MAX_SIZE = "@MaxSize";
static final String KEY_ORIENTATION = "@Orientation";
static final String KEY_ORIGIN = "@Origin";
static final String KEY_IMPORT = "Import";
static final String KEY_BROWSE = "Browse";
static final String KEY_BROWSER_SELECT = "BrowserSelect";
static final String KEY_BROWSER_CANCEL = "BrowserCancel";
public static final BuilderCodec<ImageImportPage.PageData> CODEC = BuilderCodec.builder(ImageImportPage.PageData.class, ImageImportPage.PageData::new)
.addField(new KeyedCodec<>("@ImagePath", Codec.STRING), (entry, s) -> entry.imagePath = s, entry -> entry.imagePath)
.addField(new KeyedCodec<>("@MaxSize", Codec.INTEGER), (entry, i) -> entry.maxSize = i, entry -> entry.maxSize)
.addField(new KeyedCodec<>("@Orientation", Codec.STRING), (entry, s) -> entry.orientation = s, entry -> entry.orientation)
.addField(new KeyedCodec<>("@Origin", Codec.STRING), (entry, s) -> entry.origin = s, entry -> entry.origin)
.addField(
new KeyedCodec<>("Import", Codec.STRING),
(entry, s) -> entry.doImport = "true".equalsIgnoreCase(s),
entry -> entry.doImport != null && entry.doImport ? "true" : null
)
.addField(
new KeyedCodec<>("Browse", Codec.STRING),
(entry, s) -> entry.browse = "true".equalsIgnoreCase(s),
entry -> entry.browse != null && entry.browse ? "true" : null
)
.addField(
new KeyedCodec<>("BrowserSelect", Codec.STRING),
(entry, s) -> entry.browserSelect = "true".equalsIgnoreCase(s),
entry -> entry.browserSelect != null && entry.browserSelect ? "true" : null
)
.addField(
new KeyedCodec<>("BrowserCancel", Codec.STRING),
(entry, s) -> entry.browserCancel = "true".equalsIgnoreCase(s),
entry -> entry.browserCancel != null && entry.browserCancel ? "true" : null
)
.addField(new KeyedCodec<>("File", Codec.STRING), (entry, s) -> entry.file = s, entry -> entry.file)
.addField(new KeyedCodec<>("@SearchQuery", Codec.STRING), (entry, s) -> entry.searchQuery = s, entry -> entry.searchQuery)
.addField(new KeyedCodec<>("SearchResult", Codec.STRING), (entry, s) -> entry.searchResult = s, entry -> entry.searchResult)
.build();
@Nullable
private String imagePath;
@Nullable
private Integer maxSize;
@Nullable
private String orientation;
@Nullable
private String origin;
@Nullable
private Boolean doImport;
@Nullable
private Boolean browse;
@Nullable
private Boolean browserSelect;
@Nullable
private Boolean browserCancel;
@Nullable
private String file;
@Nullable
private String searchQuery;
@Nullable
private String searchResult;
public PageData() {
}
}
}