Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.api.client.rendering.v1.advancement;

import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.Nullable;

import net.minecraft.advancements.Advancement;
import net.minecraft.advancements.AdvancementHolder;
import net.minecraft.advancements.AdvancementProgress;
import net.minecraft.advancements.DisplayInfo;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.navigation.ScreenRectangle;

@ApiStatus.NonExtendable
public sealed interface AdvancementRenderContext permits AdvancementRenderContext.Icon, AdvancementRenderContext.Frame, AdvancementRenderContext.Background {
/**
* The graphics instance used for rendering.
* @return {@link GuiGraphics} instance
*/
GuiGraphics graphics();

/**
* The holder for the advancement.
* @return {@link AdvancementHolder} instance
*/
AdvancementHolder holder();

/**
* @return The advancement's progress, or {@code null} if there is no progress.
*/
@Nullable
AdvancementProgress progress();

/**
* The advancement being rendered.
* @return {@link Advancement} instance
*/
default Advancement advancement() {
return holder().value();
}

/**
* The display info of the advancement.
* @return {@link DisplayInfo} instance
*/
default DisplayInfo display() {
return advancement().display().orElseThrow();
}

/**
* @return {@code true} if the advancement has been obtained.
*/
default boolean isObtained() {
AdvancementProgress progress = progress();
return progress != null && progress.getPercent() >= 1;
}

@ApiStatus.NonExtendable
non-sealed interface Icon extends AdvancementRenderContext {
/**
* @return The x coordinate of the icon's top-left corner.
*/
int x();

/**
* @return The y coordinate of the icon's top-left corner.
*/
int y();

/**
* @return {@code true} if the mouse is hovered over the icon.
*/
boolean isHovered();

/**
* @return {@code true} if the icon is rendered as a selected tab.
*/
boolean isSelected();
}

@ApiStatus.NonExtendable
non-sealed interface Frame extends AdvancementRenderContext {
/**
* @return The x coordinate of the frame's top-left corner.
*/
int x();

/**
* @return The y coordinate of the frame's top-left corner.
*/
int y();

/**
* @return {@code true} if the mouse is hovered over the frame.
*/
boolean isHovered();
}

@ApiStatus.NonExtendable
non-sealed interface Background extends AdvancementRenderContext {
/**
* @return the {@link ScreenRectangle} that the background is contained within.
* @apiNote use {@link ScreenRectangle#left()} and {@link ScreenRectangle#top()} for the starting coordinates of the background.
*/
ScreenRectangle bounds();

/**
* @return the background's x scroll offset.
*/
double scrollX();

/**
* @return the background's y scroll offset.
*/
double scrollY();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.api.client.rendering.v1.advancement;

import net.minecraft.resources.Identifier;

import net.fabricmc.fabric.impl.client.rendering.advancement.AdvancementRendererRegistryImpl;

/**
* Advancement renderers allow for custom advancement icons, frames, and backgrounds
* which render in the {@link net.minecraft.client.gui.screens.advancements.AdvancementsScreen advancements screen}
* and {@link net.minecraft.client.gui.components.toasts.AdvancementToast advancement toasts}.
*/
public final class AdvancementRenderer {
/**
* Registers an {@link IconRenderer} for advancement icons that show on advancement widgets, tabs, and toasts.
* @param iconRenderer the icon renderer
* @param advancementIds identifiers of the advancements
* @throws IllegalArgumentException if an advancement already has a registered icon renderer
* @throws NullPointerException if either an advancement id or the icon renderer is null
*/
public static void registerIcon(IconRenderer iconRenderer, Identifier... advancementIds) {
AdvancementRendererRegistryImpl.registerIcon(iconRenderer, advancementIds);
}

/**
* Registers a {@link FrameRenderer} for advancement frames that show on advancement widgets.
* @param frameRenderer the frame renderer
* @param advancementIds identifiers of the advancements
* @throws IllegalArgumentException if an advancement already has a registered frame renderer
* @throws NullPointerException if either an advancement id or the frame renderer is null
*/
public static void registerFrame(FrameRenderer frameRenderer, Identifier... advancementIds) {
AdvancementRendererRegistryImpl.registerFrame(frameRenderer, advancementIds);
}

/**
* Registers a {@link BackgroundRenderer} for the backgrounds of advancement tabs.
*
* <p>Only root advancements render their backgrounds.
* @param backgroundRenderer the frame renderer
* @param advancementIds identifiers of the advancements
* @throws IllegalArgumentException if an advancement already has a registered background renderer
* @throws NullPointerException if either an advancement id or the background renderer is null
*/
public static void registerBackground(BackgroundRenderer backgroundRenderer, Identifier... advancementIds) {
AdvancementRendererRegistryImpl.registerBackground(backgroundRenderer, advancementIds);
}

/**
* Called after the icon (display item) of an advancement renders.
*
* <p>By default, the original icon does not render.
* To have it render, override {@link #shouldRenderOriginalIcon()} and return {@code true}.
*/
@FunctionalInterface
public interface IconRenderer {
/**
* @param context the context of the icon rendering, which has
* {@link net.minecraft.client.gui.GuiGraphics gui graphics} for rendering,
* the {@link net.minecraft.advancements.Advancement advancement} instance, and the icon's coordinates.
*/
void renderAdvancementIcon(AdvancementRenderContext.Icon context);

/**
* @return {@code true} if the original advancement icon should render alongside this icon renderer.
*/
default boolean shouldRenderOriginalIcon() {
return false;
}
}

/**
* Called after the frame of an advancement renders.
*
* <p>By default, the original frame does not render.
* To have it render, override {@link #shouldRenderOriginalFrame()} and return {@code true}.
*
* <p>The tooltip which shows the advancement's name, description, and progress when hovered will render by default.
* To cancel its rendering, override {@link #shouldRenderTooltip()} and return {@code false}.
*/
@FunctionalInterface
public interface FrameRenderer {
/**
* @param context the context of the frame rendering, which has
* {@link net.minecraft.client.gui.GuiGraphics gui graphics} for rendering,
* the {@link net.minecraft.advancements.Advancement advancement} instance, and the frame's coordinates.
*/
void renderAdvancementFrame(AdvancementRenderContext.Frame context);

/**
* @return {@code true} if the original advancement frame should render alongside this frame renderer.
*/
default boolean shouldRenderOriginalFrame() {
return false;
}

/**
* @return {@code true} if the tooltip of a hovered advancement widget should render.
*/
default boolean shouldRenderTooltip() {
return true;
}
}

/**
* Called after the background of an advancement tab renders.
*
* <p>By default, the original background does not render.
* To have it render, override {@link #shouldRenderOriginalBackground()} and return {@code true}.
*/
@FunctionalInterface
public interface BackgroundRenderer {
/**
* @param context the context of the frame rendering, which has
* {@link net.minecraft.client.gui.GuiGraphics gui graphics} for rendering,
* the {@link net.minecraft.advancements.Advancement advancement} instance,
* and the background's {@link net.minecraft.client.gui.navigation.ScreenRectangle bounds}.
*/
void renderAdvancementBackground(AdvancementRenderContext.Background context);

/**
* @return {@code true} if the original advancement background should render alongside this background renderer.
*/
default boolean shouldRenderOriginalBackground() {
return false;
}
}

private AdvancementRenderer() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package net.fabricmc.fabric.impl.client.rendering.advancement;

import org.jspecify.annotations.Nullable;

import net.minecraft.advancements.AdvancementHolder;
import net.minecraft.advancements.AdvancementProgress;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.navigation.ScreenRectangle;

import net.fabricmc.fabric.api.client.rendering.v1.advancement.AdvancementRenderContext;

public final class AdvancementRenderContextImpl {
public static final class IconImpl implements AdvancementRenderContext.Icon {
private final GuiGraphics graphics;
private final AdvancementHolder holder;
@Nullable
private final AdvancementProgress progress;
private int x;
private int y;
private final boolean hovered;
private final boolean selected;

public IconImpl(GuiGraphics graphics, AdvancementHolder holder, @Nullable AdvancementProgress progress, int x, int y, boolean hovered, boolean selected) {
this.graphics = graphics;
this.holder = holder;
this.progress = progress;
this.x = x;
this.y = y;
this.hovered = hovered;
this.selected = selected;
}

public IconImpl(GuiGraphics graphics, AdvancementHolder holder, @Nullable AdvancementProgress progress, boolean hovered, boolean selected) {
this(graphics, holder, progress, 0, 0, hovered, selected);
}

@Override
public GuiGraphics graphics() {
return graphics;
}

@Override
public AdvancementHolder holder() {
return holder;
}

@Override
public @Nullable AdvancementProgress progress() {
return progress;
}

@Override
public int x() {
return x;
}

@Override
public int y() {
return y;
}

@Override
public boolean isHovered() {
return hovered;
}

@Override
public boolean isSelected() {
return selected;
}

public void setPos(int x, int y) {
this.x = x;
this.y = y;
}
}

public record FrameImpl(GuiGraphics graphics, AdvancementHolder holder, @Nullable AdvancementProgress progress, int x, int y, boolean isHovered) implements AdvancementRenderContext.Frame {
}

public record BackgroundImpl(GuiGraphics graphics, AdvancementHolder holder, @Nullable AdvancementProgress progress, ScreenRectangle bounds, double scrollX, double scrollY) implements AdvancementRenderContext.Background {
}

private AdvancementRenderContextImpl() {
}
}
Loading
Loading