-
Notifications
You must be signed in to change notification settings - Fork 11
Home
Contents:
-
BaseRenderer
- in-house rendering utilities, exposed publicly. -
BaseScreen
- extension of Vanilla screen, implements methods used by Spinnery, and overrides default behaviour.extend
this if you need extra functionality. -
BaseContainer
- extension of Vanilla container, implements methods used by Spinnery, and overrides default behaviour.extend
this if you need extra functionality. -
WWidget
- base class that any and all widgets build/should build upon.extend
this if you need extra functionality; though Spinnery, by default, provides some extensions:-
WPanel
- all widgets must be linked to a panel, but not necessarily be located on top of it. -
WButton
- implements a simple self-resetting button. Optionally, provides a label. -
WToggle
- implements a simple non-self-resetting toggle. Optionally, provides a label. -
WDropdown
- implements a simple drop-down panel. Optionally, provides a label. Internally, widgets are stored in a two-dimensional array, implemented through aList
ofList
s. -
WList
- implements a simple list, with smooth scrolling. Optionally, provides a label. Internally, widgets are stored in a two-dimensional array, implemented through aList
ofList
s. -
WDynamicText
- implements a complete textbox, with support forCtrl + C
,Ctrl + V
,Ctrl + A
,Ctrl + D
,Shift + Left (A)
,Shift + Right (D)
,Delete
,Left (A)
,Right (D)
andBackspace
, alongside text culling allowing for longer-than-textbox texts. Optionally, provides a label/default text. -
WStaticText
- implements a simple static text object, with no default text wrapping by default. -
WSlot
- reimplementsSlot
class to be decent.Shift + RMB + Drag
will place1
item in slots the cursor is dragged on top of.Shift + LMB + Drag
will evenly distribute items through the same slots. -
WStaticImage
- implements a static image object that displays the selected image. -
WDynamicImage
- implements a dynamic image object that displays a sequence of images. Work in progress.
-
-
Theme
- handles theme loading, parsing, building, and management. Themes are JSONs located under./minecraft/resources/spinnery
. A default one is provided. Themes have anID
, which is aString
. ATheme
can be retrieved from theResourceRegistry
withResourceRegistry.get(theme)
. A sub-theme (for a specific widget) can be obtained with.get(theme).getXTheme()
.WColor
is a class that holdsAlpha
,Red
,Green
andBlue
members used for drawing. Strings in the JSON are parsed toWColor
s, which are stored inside the sub-theme. AWColor
element can be obtained with.get(theme).getXTheme().getXPart()
. RawRGB
integer values can be obtained with.RGB
. Any themes located in./minecraft/resources/spinnery
will automatically be loaded on resource load/reload (supportingF3 + T
).
Example:
Create a class that extends
BaseContainer
:
package spinnery.container.common;
import net.minecraft.entity.player.PlayerInventory;
import spinnery.container.common.widget.WPanel;
public class TestContainer extends BaseContainer {
public TestContainer(int synchronizationID, PlayerInventory newLinkedPlayerInventory) {
super(synchronizationID, newLinkedPlayerInventory);
}
}
Then, add a main panel to the container:
setLinkedPanel(new WPanel(x, y, z, sizeX, sizeY, this));
Afterwards, register the container on the server:
ContainerProviderRegistry.INSTANCE.registerFactory(ID, (syncId, id, player, buffer) -> new TestContainer(syncId, player.inventory))
As you may have realized, buffer
is a PacketByteBuf
which can be used to pass customized data to the container constructor. Once your TestContainer
is registered, you can open it with:
ContainerProviderRegistry.INSTANCE.openContainer(ID, player, (buffer) -> {});
You may pass data to buffer
with the lambda expression which we left empty in (buffer) -> {}
. Before moving on, we must register our TestContainer
to a screen so we can actually play with it. That's done in the client, with:
ScreenProviderRegistry.INSTANCE.registerFactory(ID, (syncId, identifier, player, buffer) -> new BaseScreen(ID, new TestContainer(syncId, player.inventory), player));
Given we don't need anything fancier than a BaseScreen
, we register one to TestContainer
.
Once that's done, congratulations, you have a working container and screen that can be summoned at any time!
Here's some example code so you have something to base yourself on:
public class TestContainer extends BaseContainer {
public TestContainer(int synchronizationID, BlockPos newLinkedInventoryPosition, PlayerInventory newLinkedPlayerInventory) {
super(synchronizationID, newLinkedPlayerInventory);
setLinkedInventory(((TestBlock) newLinkedPlayerInventory.player.world.getBlockState(newLinkedInventoryPosition).getBlock()).getInventory());
setLinkedPanel(new WPanel(30, 0, - 10, 170, 210, this));
linkedPanel.center();
WSlot.addPlayerInventory(0, 18, 18, linkedPlayerInventory, linkedPanel);
WDropdown dropdownA = new WDropdown(WAnchor.MC_ORIGIN, - 70, 0, 0, 66, 18, 66, 170, linkedPanel);
WStaticText staticTextA = new WStaticText(WAnchor.MC_ORIGIN, 0, 0, 20, "? ?? ???", linkedPanel);
dropdownA.add(staticTextA);
WList listA = new WList(WAnchor.MC_ORIGIN, 174, 0, 0, 66, 170, linkedPanel);
for (int i = 0; i < 54; ++ i) {
WSlot slotA = new WSlot(WAnchor.MC_ORIGIN, 0, 0, 3, 18, 18, ++ i, linkedInventory, linkedPanel);
WSlot slotB = new WSlot(WAnchor.MC_ORIGIN, 0, 0, 3, 18, 18, ++ i, linkedInventory, linkedPanel);
WSlot slotC = new WSlot(WAnchor.MC_ORIGIN, 0, 0, 3, 18, 18, ++ i, linkedInventory, linkedPanel);
listA.add(slotA, slotB, slotC);
}
WHorizontalSlider sliderA = new WHorizontalSlider(WAnchor.MC_ORIGIN, 30, 25, 0, 18, 9, 9, linkedPanel);
WToggle toggleA = new WToggle(WAnchor.MC_ORIGIN, 30, 50, 0, 18, 9, linkedPanel);
WToggle toggleB = new WToggle(WAnchor.MC_ORIGIN, 30, 70, 0, 18, 9, linkedPanel);
WToggle toggleC = new WToggle(WAnchor.MC_ORIGIN, 30, 90, 0, 18, 9, linkedPanel);
WButton buttonA = new WButton(WAnchor.MC_ORIGIN, 55, 50, 20, 9, 9, linkedPanel);
WButton buttonB = new WButton(WAnchor.MC_ORIGIN, 55, 70, 20, 9, 9, linkedPanel);
WButton buttonC = new WButton(WAnchor.MC_ORIGIN, 55, 90, 20, 9, 9, linkedPanel);
buttonA.setLabel("Yeet");
buttonB.setLabel("Yoot");
buttonC.setLabel("Yuut");
WDynamicText dynamicTextA = new WDynamicText(WAnchor.MC_ORIGIN, 30, 110, 0, 100, 18, linkedPanel);
dynamicTextA.setLabel("Type here...");
listA.setLabel("Slots!");
linkedPanel.setLabel("Hello, world!");
dropdownA.setLabel("OwO");
getLinkedPanel().add(listA, sliderA, dropdownA, toggleA, toggleB, buttonA, buttonB, buttonC, toggleC, dynamicTextA);
}
}
Notice that the TestContainer
constructor was altered to take a BlockPos
, meaning the registries were changed, and the call to open the container writes the BlockPos
to buffer
.
The end result?
Spinnery is licensed under the LGPL-3.0 license.