5050import net .wurstclient .mixin .HandledScreenAccessor ;
5151import net .wurstclient .settings .CheckboxSetting ;
5252import net .wurstclient .settings .ColorSetting ;
53+ import net .wurstclient .settings .EnumSetting ;
5354import net .wurstclient .settings .SliderSetting ;
5455import net .wurstclient .settings .SliderSetting .ValueDisplay ;
5556import net .wurstclient .util .ItemUtils ;
@@ -123,6 +124,12 @@ public final class EnchantmentHandlerHack extends Hack
123124 new CheckboxSetting ("Include shulker contents" , true );
124125 private final CheckboxSetting showOnInventoryScreen =
125126 new CheckboxSetting ("Show on inventory screen" , true );
127+ private final EnumSetting <PanelAnchor > panelAnchor = new EnumSetting <>(
128+ "Panel anchor" ,
129+ "Pin the panel to the left, right, top, or bottom of the current inventory/container." ,
130+ PanelAnchor .values (), PanelAnchor .LEFT );
131+ private final SliderSetting panelAnchorGap = new SliderSetting (
132+ "Panel anchor gap" , 6 , 0 , 240 , 1 , ValueDisplay .INTEGER );
126133 private final CheckboxSetting slotHighlightEnabled =
127134 new CheckboxSetting ("Slot highlight" , true );
128135 private final ColorSetting slotHighlightColor =
@@ -191,6 +198,8 @@ public EnchantmentHandlerHack()
191198 addSetting (includePlayerInventory );
192199 addSetting (includeShulkerContents );
193200 addSetting (showOnInventoryScreen );
201+ addSetting (panelAnchor );
202+ addSetting (panelAnchorGap );
194203 addSetting (slotHighlightEnabled );
195204 addSetting (slotHighlightColor );
196205 addSetting (slotHighlightOpacity );
@@ -308,19 +317,14 @@ public void renderOnHandledScreen(AbstractContainerScreen<?> screen,
308317 Math .max (60 , windowHeight - 10 ));
309318
310319 renderingInventoryScreen = screen instanceof InventoryScreen ;
311- int defaultX = accessor .getX () - panelWidth - PANEL_PADDING ;
312- int defaultY = accessor .getY ();
313- if (renderingInventoryScreen )
314- {
315- defaultX = accessor .getX ();
316- defaultY = accessor .getY () + accessor .getBackgroundHeight ()
317- + PANEL_PADDING ;
318- }
319- if (renderingInventoryScreen && inventoryCustomPosition )
320+ int defaultX = getAnchoredPanelX (accessor );
321+ int defaultY = getAnchoredPanelY (accessor );
322+ boolean freePosition = usesFreePosition ();
323+ if (freePosition && renderingInventoryScreen && inventoryCustomPosition )
320324 {
321325 panelX = inventoryPanelX ;
322326 panelY = inventoryPanelY ;
323- }else if (!renderingInventoryScreen && customPosition )
327+ }else if (freePosition && !renderingInventoryScreen && customPosition )
324328 {
325329 panelX = containerPanelX ;
326330 panelY = containerPanelY ;
@@ -345,11 +349,11 @@ public void renderOnHandledScreen(AbstractContainerScreen<?> screen,
345349 panelX =
346350 Mth .clamp (panelX , 2 - panelWidth , windowWidth - panelWidth - 2 );
347351 panelY = Mth .clamp (panelY , 2 , windowHeight - panelHeight - 2 );
348- if (renderingInventoryScreen && inventoryCustomPosition )
352+ if (freePosition && renderingInventoryScreen && inventoryCustomPosition )
349353 {
350354 inventoryPanelX = panelX ;
351355 inventoryPanelY = panelY ;
352- }else if (!renderingInventoryScreen && customPosition )
356+ }else if (freePosition && !renderingInventoryScreen && customPosition )
353357 {
354358 containerPanelX = panelX ;
355359 containerPanelY = panelY ;
@@ -376,6 +380,8 @@ public boolean handleMouseClick(AbstractContainerScreen<?> screen,
376380
377381 if (button == 0 && isInsideDragBar (mouseX , mouseY ))
378382 {
383+ if (!usesFreePosition ())
384+ return true ;
379385 startPanelDrag (mouseX , mouseY );
380386 return true ;
381387 }
@@ -531,6 +537,8 @@ private double getScrollThumbHeight(double trackHeight)
531537
532538 private void startPanelDrag (double mouseX , double mouseY )
533539 {
540+ if (!usesFreePosition ())
541+ return ;
534542 panelDragging = true ;
535543 dragOffsetX = (int )Math .round (mouseX - panelX );
536544 dragOffsetY = (int )Math .round (mouseY - panelY );
@@ -542,6 +550,8 @@ private void startPanelDrag(double mouseX, double mouseY)
542550
543551 private void savePanelPosition ()
544552 {
553+ if (!usesFreePosition ())
554+ return ;
545555 if (renderingInventoryScreen )
546556 {
547557 savedInventoryPosition .setChecked (inventoryCustomPosition );
@@ -562,6 +572,48 @@ private void addHiddenPositionSetting(
562572 addSetting (setting );
563573 }
564574
575+ private boolean usesFreePosition ()
576+ {
577+ return panelAnchor .getSelected () == PanelAnchor .FREE ;
578+ }
579+
580+ private int getAnchoredPanelX (HandledScreenAccessor accessor )
581+ {
582+ int gap = panelAnchorGap .getValueI ();
583+ return switch (panelAnchor .getSelected ())
584+ {
585+ case LEFT -> accessor .getX () - panelWidth - gap ;
586+ case RIGHT -> accessor .getX () + accessor .getBackgroundWidth () + gap ;
587+ case TOP , BOTTOM -> accessor .getX ()
588+ + (accessor .getBackgroundWidth () - panelWidth ) / 2 ;
589+ case FREE ->
590+ {
591+ if (renderingInventoryScreen )
592+ yield accessor .getX ();
593+ yield accessor .getX () - panelWidth - PANEL_PADDING ;
594+ }
595+ };
596+ }
597+
598+ private int getAnchoredPanelY (HandledScreenAccessor accessor )
599+ {
600+ int gap = panelAnchorGap .getValueI ();
601+ return switch (panelAnchor .getSelected ())
602+ {
603+ case LEFT , RIGHT -> accessor .getY ();
604+ case TOP -> accessor .getY () - panelHeight - gap ;
605+ case BOTTOM -> accessor .getY () + accessor .getBackgroundHeight ()
606+ + gap ;
607+ case FREE ->
608+ {
609+ if (renderingInventoryScreen )
610+ yield accessor .getY () + accessor .getBackgroundHeight ()
611+ + PANEL_PADDING ;
612+ yield accessor .getY ();
613+ }
614+ };
615+ }
616+
565617 private void renderOverlay (GuiGraphicsExtractor context )
566618 {
567619 hitboxes .clear ();
@@ -2318,6 +2370,28 @@ private static enum CategoryKind
23182370 POTION ;
23192371 }
23202372
2373+ private static enum PanelAnchor
2374+ {
2375+ FREE ("Free" ),
2376+ LEFT ("Left" ),
2377+ RIGHT ("Right" ),
2378+ TOP ("Top" ),
2379+ BOTTOM ("Bottom" );
2380+
2381+ private final String displayName ;
2382+
2383+ PanelAnchor (String displayName )
2384+ {
2385+ this .displayName = displayName ;
2386+ }
2387+
2388+ @ Override
2389+ public String toString ()
2390+ {
2391+ return displayName ;
2392+ }
2393+ }
2394+
23212395 private static enum GearCategory
23222396 {
23232397 HELMET ("Armor (Helmet)" ),
0 commit comments