Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/client/java/com/pixelreel/client/ClientNetworking.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.world.InteractionHand;

public final class ClientNetworking {
private static OnDemandProvider pendingBrowseProvider = OnDemandProvider.JELLYFIN;
Expand Down Expand Up @@ -275,6 +276,33 @@ public static void unequipPixelGlasses() {
}
}

public static void placeCustomScreen(
BlockPos pos, int width, int height, int audioDepth, int audioSide, InteractionHand hand
) {
if (ClientPlayNetworking.canSend(ModNetworkPayloads.PlaceCustomScreen.TYPE)) {
ClientPlayNetworking.send(new ModNetworkPayloads.PlaceCustomScreen(
pos, width, height, ModNetworkPayloads.PlaceCustomScreen.packAudioSettings(audioDepth, audioSide),
hand == InteractionHand.OFF_HAND
));
}
}

public static void configureScreenwriterLink(BlockPos pos, int auditorium, boolean unlink) {
if (ClientPlayNetworking.canSend(ModNetworkPayloads.ScreenwriterLink.TYPE)) {
ClientPlayNetworking.send(new ModNetworkPayloads.ScreenwriterLink(pos, auditorium, unlink));
}
}

public static void resetLocalPlaybackConnection(BlockPos pos) {
Minecraft minecraft = Minecraft.getInstance();
boolean reset = PlaybackManager.INSTANCE.resetConnection(pos);
if (minecraft.player != null) {
minecraft.player.displayClientMessage(Component.translatable(
reset ? "message.pixelreel.playback.connection_reset" : "message.pixelreel.playback.no_connection"
), true);
}
}

public static void sendControl(BlockPos pos, ScreenAction action, float value) {
if (ClientPlayNetworking.canSend(ModNetworkPayloads.ScreenControl.TYPE)) {
ClientPlayNetworking.send(new ModNetworkPayloads.ScreenControl(pos, action, value));
Expand Down
15 changes: 15 additions & 0 deletions src/client/java/com/pixelreel/client/PixelReelClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.pixelreel.ClientBridge;
import com.pixelreel.blockentities.DisplayBlockEntity;
import com.pixelreel.blocks.DisplayBlock;
import com.pixelreel.client.gui.CustomScreenPlacementScreen;
import com.pixelreel.client.gui.ScreenwriterLinkScreen;
import com.pixelreel.client.playback.PlaybackManager;
import com.pixelreel.client.playback.video.VlcRuntime;
import com.pixelreel.client.render.DisplayBlockEntityRenderer;
Expand All @@ -19,6 +21,7 @@
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;

Expand All @@ -42,6 +45,18 @@ public void openChannelMenu(BlockPos controllerPos) {
public void releasePlayback(BlockPos controllerPos) {
PlaybackManager.INSTANCE.release(controllerPos);
}

@Override
public void openCustomScreenPlacement(BlockPos controllerPos, InteractionHand hand, boolean curved) {
Minecraft minecraft = Minecraft.getInstance();
minecraft.execute(() -> minecraft.setScreen(new CustomScreenPlacementScreen(controllerPos, hand, curved)));
}

@Override
public void openScreenwriterLink(BlockPos controllerPos) {
Minecraft minecraft = Minecraft.getInstance();
minecraft.execute(() -> minecraft.setScreen(new ScreenwriterLinkScreen(controllerPos)));
}
});

ClientTickEvents.END_CLIENT_TICK.register(minecraft -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package com.pixelreel.client.gui;

import com.pixelreel.blockentities.DisplayBlockEntity;
import com.pixelreel.blocks.DisplayGeometry;
import com.pixelreel.client.ClientNetworking;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.world.InteractionHand;

/** Size/audio prompt shown when placing either custom cinema screen item. */
public class CustomScreenPlacementScreen extends Screen {
private final BlockPos controllerPos;
private final InteractionHand hand;
private final boolean curved;
private EditBox widthBox;
private EditBox heightBox;
private EditBox audioDepthBox;
private EditBox audioSideBox;
private Component validationMessage = Component.empty();

public CustomScreenPlacementScreen(BlockPos controllerPos, InteractionHand hand, boolean curved) {
super(Component.translatable(curved
? "gui.pixelreel.custom_curved_screen.title"
: "gui.pixelreel.custom_screen.title"));
this.controllerPos = controllerPos.immutable();
this.hand = hand;
this.curved = curved;
}

@Override
protected void init() {
int left = this.width / 2 - 90;
int top = this.height / 2 - 92;

this.widthBox = new EditBox(this.font, left, top, 180, 20, Component.translatable("gui.pixelreel.custom_screen.width"));
this.widthBox.setMaxLength(2);
this.widthBox.setFilter(CustomScreenPlacementScreen::digitsOnly);
this.widthBox.setValue("27");
this.addRenderableWidget(this.widthBox);

this.heightBox = new EditBox(this.font, left, top + 34, 180, 20, Component.translatable("gui.pixelreel.custom_screen.height"));
this.heightBox.setMaxLength(2);
this.heightBox.setFilter(CustomScreenPlacementScreen::digitsOnly);
this.heightBox.setValue("11");
this.addRenderableWidget(this.heightBox);

this.audioDepthBox = new EditBox(this.font, left, top + 68, 180, 20, Component.translatable("gui.pixelreel.custom_screen.audio_depth"));
this.audioDepthBox.setMaxLength(3);
this.audioDepthBox.setFilter(CustomScreenPlacementScreen::digitsOnly);
this.audioDepthBox.setValue(Integer.toString(DisplayBlockEntity.DEFAULT_CUSTOM_AUDIO_DEPTH));
this.addRenderableWidget(this.audioDepthBox);

this.audioSideBox = new EditBox(this.font, left, top + 102, 180, 20, Component.translatable("gui.pixelreel.custom_screen.audio_side"));
this.audioSideBox.setMaxLength(2);
this.audioSideBox.setFilter(CustomScreenPlacementScreen::digitsOnly);
this.audioSideBox.setValue(Integer.toString(DisplayBlockEntity.DEFAULT_CUSTOM_AUDIO_SIDE));
this.addRenderableWidget(this.audioSideBox);

this.addRenderableWidget(Button.builder(Component.translatable("gui.pixelreel.custom_screen.place"), button -> this.place())
.bounds(left, top + 140, 86, 20).build());
this.addRenderableWidget(Button.builder(Component.translatable("gui.pixelreel.custom_screen.cancel"), button -> this.onClose())
.bounds(left + 94, top + 140, 86, 20).build());
this.setInitialFocus(this.widthBox);
}

private static boolean digitsOnly(String value) {
if (value.isEmpty()) return true;
for (int i = 0; i < value.length(); i++) {
if (!Character.isDigit(value.charAt(i))) return false;
}
return true;
}

private void place() {
int width = parse(this.widthBox.getValue());
int height = parse(this.heightBox.getValue());
int audioDepth = parse(this.audioDepthBox.getValue());
int audioSide = parse(this.audioSideBox.getValue());
if (width < DisplayGeometry.MIN_WIDTH || width > DisplayGeometry.MAX_WIDTH
|| height < DisplayGeometry.MIN_HEIGHT || height > DisplayGeometry.MAX_HEIGHT) {
this.validationMessage = Component.translatable("gui.pixelreel.custom_screen.invalid",
DisplayGeometry.MIN_WIDTH, DisplayGeometry.MAX_WIDTH, DisplayGeometry.MIN_HEIGHT, DisplayGeometry.MAX_HEIGHT);
return;
}
if (audioDepth < DisplayBlockEntity.MIN_CUSTOM_AUDIO_DEPTH || audioDepth > DisplayBlockEntity.MAX_CUSTOM_AUDIO_DEPTH
|| audioSide < DisplayBlockEntity.MIN_CUSTOM_AUDIO_SIDE || audioSide > DisplayBlockEntity.MAX_CUSTOM_AUDIO_SIDE) {
this.validationMessage = Component.translatable("gui.pixelreel.custom_screen.audio_invalid",
DisplayBlockEntity.MIN_CUSTOM_AUDIO_DEPTH, DisplayBlockEntity.MAX_CUSTOM_AUDIO_DEPTH,
DisplayBlockEntity.MIN_CUSTOM_AUDIO_SIDE, DisplayBlockEntity.MAX_CUSTOM_AUDIO_SIDE);
return;
}
ClientNetworking.placeCustomScreen(this.controllerPos, width, height, audioDepth, audioSide, this.hand);
this.onClose();
}

private static int parse(String value) {
try { return Integer.parseInt(value); }
catch (NumberFormatException ignored) { return -1; }
}

@Override
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
super.render(graphics, mouseX, mouseY, partialTicks);
int left = this.width / 2 - 90;
int top = this.height / 2 - 92;
graphics.drawCenteredString(this.font, this.title, this.width / 2, top - 28, GuiColors.TEXT);
graphics.drawCenteredString(this.font, Component.translatable("gui.pixelreel.custom_screen.subtitle"), this.width / 2, top - 15, GuiColors.TEXT_DIM);
graphics.drawString(this.font, Component.translatable("gui.pixelreel.custom_screen.width"), left, top - 10, GuiColors.TEXT_DIM);
graphics.drawString(this.font, Component.translatable("gui.pixelreel.custom_screen.height"), left, top + 24, GuiColors.TEXT_DIM);
graphics.drawString(this.font, Component.translatable("gui.pixelreel.custom_screen.audio_depth"), left, top + 58, GuiColors.TEXT_DIM);
graphics.drawString(this.font, Component.translatable("gui.pixelreel.custom_screen.audio_side"), left, top + 92, GuiColors.TEXT_DIM);
graphics.drawCenteredString(this.font, Component.translatable("gui.pixelreel.custom_screen.audio_hint"), this.width / 2, top + 126, GuiColors.TEXT_DIM);
if (!this.validationMessage.getString().isEmpty()) {
graphics.drawCenteredString(this.font, this.validationMessage, this.width / 2, top + 166, GuiColors.ERROR);
}
}

@Override
public boolean isPauseScreen() { return false; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,18 @@ protected void init() {
y += smallH + gap;

if (showPlayback) {
int playbackHalf = (PANEL_WIDTH - gap) / 2;
this.addRenderableWidget(
Button.builder(Component.translatable("gui.pixelreel.playback.open"), button -> {
if (this.minecraft != null) {
this.minecraft.setScreen(new PlaybackControlScreen(this.display));
}
}).bounds(centreX - PANEL_WIDTH / 2, y, PANEL_WIDTH, smallH).build()
}).bounds(centreX - PANEL_WIDTH / 2, y, playbackHalf, smallH).build()
);
this.addRenderableWidget(
Button.builder(Component.translatable("gui.pixelreel.playback.reset_connection"), button ->
ClientNetworking.resetLocalPlaybackConnection(this.display.getBlockPos())
).bounds(centreX - PANEL_WIDTH / 2 + playbackHalf + gap, y, playbackHalf, smallH).build()
);
y += smallH + gap;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ protected void init() {
ClientNetworking.sendControl(this.display.getBlockPos(), ScreenAction.STOP, 0.0F)
).bounds(centre + 110, y, 50, 20).build()
);
this.addRenderableWidget(
Button.builder(Component.translatable("gui.pixelreel.playback.reset_connection"), button ->
ClientNetworking.resetLocalPlaybackConnection(this.display.getBlockPos())
).bounds(centre - 140, y - 56, 280, 20).build()
);
this.subtitleButton = this.addRenderableWidget(
Button.builder(this.subtitleLabel(), button -> {
if (this.minecraft != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.pixelreel.client.gui;

import com.pixelreel.client.ClientNetworking;
import com.pixelreel.server.ScreenwriterManager;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;

/** Auditorium-number prompt used when linking a custom screen to Screenwriter. */
public class ScreenwriterLinkScreen extends Screen {
private final BlockPos controllerPos;
private EditBox auditoriumBox;
private Component validationMessage = Component.empty();

public ScreenwriterLinkScreen(BlockPos controllerPos) {
super(Component.translatable("gui.pixelreel.screenwriter_link.title"));
this.controllerPos = controllerPos.immutable();
}

@Override
protected void init() {
int left = this.width / 2 - 90;
int top = this.height / 2 - 52;
this.auditoriumBox = new EditBox(this.font, left, top, 180, 20, Component.translatable("gui.pixelreel.screenwriter_link.auditorium"));
this.auditoriumBox.setMaxLength(2);
this.auditoriumBox.setFilter(ScreenwriterLinkScreen::digitsOnly);
this.addRenderableWidget(this.auditoriumBox);
this.addRenderableWidget(Button.builder(Component.translatable("gui.pixelreel.screenwriter_link.link"), button -> this.link())
.bounds(left, top + 38, 86, 20).build());
this.addRenderableWidget(Button.builder(Component.translatable("gui.pixelreel.screenwriter_link.unlink"), button -> this.unlink())
.bounds(left + 94, top + 38, 86, 20).build());
this.addRenderableWidget(Button.builder(Component.translatable("gui.pixelreel.screenwriter_link.cancel"), button -> this.onClose())
.bounds(left + 47, top + 66, 86, 20).build());
this.setInitialFocus(this.auditoriumBox);
}

private static boolean digitsOnly(String value) {
if (value.isEmpty()) return true;
for (int i = 0; i < value.length(); i++) if (!Character.isDigit(value.charAt(i))) return false;
return true;
}

private void link() {
int auditorium = parse(this.auditoriumBox.getValue());
if (auditorium < 1 || auditorium > ScreenwriterManager.MAX_SCREENS) {
this.validationMessage = Component.translatable("gui.pixelreel.screenwriter_link.invalid", 1, ScreenwriterManager.MAX_SCREENS);
return;
}
ClientNetworking.configureScreenwriterLink(this.controllerPos, auditorium, false);
this.onClose();
}

private void unlink() {
ClientNetworking.configureScreenwriterLink(this.controllerPos, 0, true);
this.onClose();
}

private static int parse(String value) {
try { return Integer.parseInt(value.trim()); }
catch (NumberFormatException ignored) { return -1; }
}

@Override
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) {
super.render(graphics, mouseX, mouseY, partialTicks);
int left = this.width / 2 - 90;
int top = this.height / 2 - 52;
graphics.drawCenteredString(this.font, this.title, this.width / 2, top - 32, GuiColors.TEXT);
graphics.drawCenteredString(this.font, Component.translatable("gui.pixelreel.screenwriter_link.subtitle", ScreenwriterManager.MAX_SCREENS), this.width / 2, top - 18, GuiColors.TEXT_DIM);
graphics.drawString(this.font, Component.translatable("gui.pixelreel.screenwriter_link.auditorium"), left, top - 10, GuiColors.TEXT_DIM);
if (!this.validationMessage.getString().isEmpty()) graphics.drawCenteredString(this.font, this.validationMessage, this.width / 2, top + 94, GuiColors.ERROR);
}

@Override
public boolean isPauseScreen() { return false; }
}
Loading