Test Settings Menu
This commit is contained in:
+3
-3
@@ -24,9 +24,9 @@ dependencies {
|
|||||||
|
|
||||||
implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||||
|
|
||||||
implementation "curse.maven:modern-ui-352491:8206272"
|
implementation "dev.icyllis:modernui-core:${modernui_version}"
|
||||||
implementation "icyllis.modernui:ModernUI-Fabric:26.1.2-3.13.0.4"
|
implementation "icyllis.modernui:ModernUI-Markflow:${modernui_version}"
|
||||||
implementation "icyllis.arc3d:arc3d-core:2026.1.0"
|
implementation("icyllis.modernui:ModernUI-Fabric:${minecraft_version}-${modernui_version}.+")
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
|||||||
@@ -12,3 +12,4 @@ archives_base_name=ParrotMod
|
|||||||
# Dependencies
|
# Dependencies
|
||||||
# check this on https://modmuss50.me/fabric.html
|
# check this on https://modmuss50.me/fabric.html
|
||||||
fabric_version=0.151.0+26.1.2
|
fabric_version=0.151.0+26.1.2
|
||||||
|
modernui_version=3.13.0
|
||||||
@@ -1,30 +1,30 @@
|
|||||||
package de.winniepat.parrotmod.mixin;
|
package de.winniepat.parrotmod.mixin;
|
||||||
|
|
||||||
import de.winniepat.parrotmod.ui.SettingsScreen;
|
import de.winniepat.parrotmod.ui.SettingsFragment;
|
||||||
import net.minecraft.client.Minecraft;
|
import icyllis.modernui.mc.MuiModApi;
|
||||||
import net.minecraft.client.gui.components.Button; // Updated import
|
import net.minecraft.client.gui.components.ImageButton;
|
||||||
|
import net.minecraft.client.gui.components.WidgetSprites;
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
import net.minecraft.client.gui.screens.TitleScreen;
|
import net.minecraft.client.gui.screens.TitleScreen;
|
||||||
import net.minecraft.network.chat.Component; // Replaces Text
|
import net.minecraft.network.chat.Component;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
@Mixin(TitleScreen.class)
|
@Mixin(TitleScreen.class)
|
||||||
public class TitleScreenMixin extends Screen {
|
public abstract class TitleScreenMixin extends Screen {
|
||||||
|
|
||||||
protected TitleScreenMixin(Component title) {
|
protected TitleScreenMixin(Component title) {
|
||||||
super(title);
|
super(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(at = @At("RETURN"), method = "init")
|
@Inject(method = "init", at = @At("TAIL"))
|
||||||
private void addCustomButton(CallbackInfo ci) {
|
private void onInit(CallbackInfo ci) {
|
||||||
int x = this.width / 2 - 100;
|
WidgetSprites sprites = new WidgetSprites(Identifier.fromNamespaceAndPath("parrotmod", "icon"), Identifier.fromNamespaceAndPath("parrotmod", "icon"));
|
||||||
int y = this.height / 4 + 120;
|
this.addRenderableWidget(new ImageButton(this.width / 2 + 104, this.height / 4 + 48, 20, 20, sprites, b -> {
|
||||||
|
MuiModApi.get().openScreen(new SettingsFragment());
|
||||||
this.addRenderableWidget(Button.builder(Component.literal("Parrot Mod"), (button) -> {
|
}));
|
||||||
Minecraft.getInstance().setScreen(new SettingsScreen(Component.literal("Settings")));
|
|
||||||
}).bounds(x, y, 200, 20).build());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package de.winniepat.parrotmod.ui;
|
||||||
|
|
||||||
|
import icyllis.modernui.fragment.Fragment;
|
||||||
|
import icyllis.modernui.util.DataSet;
|
||||||
|
import icyllis.modernui.view.*;
|
||||||
|
import icyllis.modernui.widget.*;
|
||||||
|
|
||||||
|
public class GeneralTabFragment extends Fragment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, DataSet savedInstanceState) {
|
||||||
|
LinearLayout layout = new LinearLayout(getContext());
|
||||||
|
layout.setOrientation(LinearLayout.VERTICAL);
|
||||||
|
layout.setPadding(dp(12), dp(12), dp(12), dp(12));
|
||||||
|
|
||||||
|
// --- A toggle/switch setting ---
|
||||||
|
layout.addView(makeLabel("Enable feature X"));
|
||||||
|
Switch toggleX = new Switch(getContext());
|
||||||
|
toggleX.setChecked(true); // load from your config
|
||||||
|
toggleX.setOnCheckedChangeListener((v, checked) -> {
|
||||||
|
// save to config
|
||||||
|
MyConfig.enableFeatureX = checked;
|
||||||
|
});
|
||||||
|
layout.addView(toggleX, rowParams());
|
||||||
|
|
||||||
|
// --- Another toggle ---
|
||||||
|
layout.addView(makeLabel("Show HUD overlay"));
|
||||||
|
Switch toggleHUD = new Switch(getContext());
|
||||||
|
toggleHUD.setChecked(MyConfig.showHud);
|
||||||
|
toggleHUD.setOnCheckedChangeListener((v, checked) -> MyConfig.showHud = checked);
|
||||||
|
layout.addView(toggleHUD, rowParams());
|
||||||
|
|
||||||
|
// --- A slider ---
|
||||||
|
layout.addView(makeLabel("Opacity"));
|
||||||
|
SeekBar slider = new SeekBar(getContext());
|
||||||
|
slider.setMax(100);
|
||||||
|
slider.setProgress((int)(MyConfig.opacity * 100));
|
||||||
|
slider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||||
|
public void onProgressChanged(SeekBar bar, int progress, boolean fromUser) {
|
||||||
|
if (fromUser) MyConfig.opacity = progress / 100f;
|
||||||
|
}
|
||||||
|
public void onStartTrackingTouch(SeekBar bar) {}
|
||||||
|
public void onStopTrackingTouch(SeekBar bar) {}
|
||||||
|
});
|
||||||
|
layout.addView(slider, rowParams());
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextView makeLabel(String text) {
|
||||||
|
TextView tv = new TextView(getContext());
|
||||||
|
tv.setText(text);
|
||||||
|
tv.setTextSize(12);
|
||||||
|
tv.setTextColor(0xFFCCCCCC);
|
||||||
|
var p = new LinearLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
p.topMargin = dp(8);
|
||||||
|
p.bottomMargin = dp(2);
|
||||||
|
tv.setLayoutParams(p);
|
||||||
|
return tv;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LinearLayout.LayoutParams rowParams() {
|
||||||
|
return new LinearLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT, dp(28));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int dp(float dp) {
|
||||||
|
return (int) (dp * getContext().getResources().getDisplayMetrics().density);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
package de.winniepat.parrotmod.ui;
|
||||||
|
|
||||||
|
import icyllis.modernui.R;
|
||||||
|
import icyllis.modernui.fragment.Fragment;
|
||||||
|
import icyllis.modernui.util.DataSet;
|
||||||
|
import icyllis.modernui.view.*;
|
||||||
|
import icyllis.modernui.widget.*;
|
||||||
|
import icyllis.modernui.graphics.drawable.ShapeDrawable;
|
||||||
|
import icyllis.modernui.graphics.*;
|
||||||
|
|
||||||
|
public class SettingsFragment extends Fragment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, DataSet savedInstanceState) {
|
||||||
|
LinearLayout root = new LinearLayout(getContext());
|
||||||
|
root.setOrientation(LinearLayout.HORIZONTAL);
|
||||||
|
root.setLayoutParams(new FrameLayout.LayoutParams(
|
||||||
|
dp(520), dp(320), Gravity.CENTER));
|
||||||
|
|
||||||
|
// --- LEFT PANEL: tab buttons stacked vertically ---
|
||||||
|
LinearLayout sidebar = new LinearLayout(getContext());
|
||||||
|
sidebar.setOrientation(LinearLayout.VERTICAL);
|
||||||
|
sidebar.setPadding(dp(8), dp(8), dp(8), dp(8));
|
||||||
|
// Semi-transparent dark background
|
||||||
|
sidebar.setBackground(makeRoundedBg(0xCC1A1A2E));
|
||||||
|
|
||||||
|
var sidebarParams = new LinearLayout.LayoutParams(dp(110), ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
root.addView(sidebar, sidebarParams);
|
||||||
|
|
||||||
|
// --- RIGHT PANEL: fragment host ---
|
||||||
|
FrameLayout contentArea = new FrameLayout(getContext());
|
||||||
|
contentArea.setId(R.id.content); // or any stable int ID, e.g. 0x10001
|
||||||
|
contentArea.setBackground(makeRoundedBg(0xCC101018));
|
||||||
|
|
||||||
|
var contentParams = new LinearLayout.LayoutParams(
|
||||||
|
0, ViewGroup.LayoutParams.MATCH_PARENT, 1f); // weight=1, fills remaining space
|
||||||
|
contentParams.leftMargin = dp(6);
|
||||||
|
root.addView(contentArea, contentParams);
|
||||||
|
|
||||||
|
String[] tabNames = {"General", "Graphics", "Audio", "Keybinds"};
|
||||||
|
Fragment[] tabFragments = {
|
||||||
|
new GeneralTabFragment()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Show the first tab immediately
|
||||||
|
getChildFragmentManager().beginTransaction()
|
||||||
|
.replace(contentArea.getId(), tabFragments[0])
|
||||||
|
.commitNow();
|
||||||
|
|
||||||
|
Button[] tabs = new Button[tabNames.length];
|
||||||
|
for (int i = 0; i < tabNames.length; i++) {
|
||||||
|
final int index = i;
|
||||||
|
Button tab = new Button(getContext());
|
||||||
|
tab.setText(tabNames[i]);
|
||||||
|
tab.setTextSize(13);
|
||||||
|
tab.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
|
||||||
|
tab.setPadding(dp(10), dp(6), dp(10), dp(6));
|
||||||
|
tab.setBackground(null); // we'll tint active tab manually
|
||||||
|
|
||||||
|
tab.setOnClickListener(v -> {
|
||||||
|
// Swap content fragment
|
||||||
|
getChildFragmentManager().beginTransaction()
|
||||||
|
.setReorderingAllowed(true)
|
||||||
|
.replace(contentArea.getId(), tabFragments[index])
|
||||||
|
.commit();
|
||||||
|
// Highlight active tab
|
||||||
|
for (Button b : tabs) b.setTextColor(0xFFAAAAAA);
|
||||||
|
tab.setTextColor(0xFFFFFFFF);
|
||||||
|
});
|
||||||
|
|
||||||
|
var tabParams = new LinearLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT, dp(32));
|
||||||
|
tabParams.bottomMargin = dp(4);
|
||||||
|
sidebar.addView(tab, tabParams);
|
||||||
|
tabs[i] = tab;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default: highlight first tab
|
||||||
|
tabs[0].setTextColor(0xFFFFFFFF);
|
||||||
|
for (int i = 1; i < tabs.length; i++) tabs[i].setTextColor(0xFFAAAAAA);
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper: dp → px
|
||||||
|
private int dp(float dp) {
|
||||||
|
return (int) (dp * getContext().getResources().getDisplayMetrics().density);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper: semi-transparent rounded rectangle background
|
||||||
|
private ShapeDrawable makeRoundedBg(int color) {
|
||||||
|
ShapeDrawable d = new ShapeDrawable();
|
||||||
|
d.setCornerRadius(dp(6));
|
||||||
|
d.setColor(color);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package de.winniepat.parrotmod.ui;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.components.Button;
|
|
||||||
import net.minecraft.client.gui.components.Renderable;
|
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
|
|
||||||
public class SettingsScreen extends Screen {
|
|
||||||
private int tabWidth = 100;
|
|
||||||
private int currentTab = 0;
|
|
||||||
|
|
||||||
public SettingsScreen(Component title) {
|
|
||||||
super(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void init() {
|
|
||||||
this.addRenderableWidget(Button.builder(Component.literal("General"), (b) -> {
|
|
||||||
this.currentTab = 0;
|
|
||||||
this.rebuildWidgets();;
|
|
||||||
}).bounds(10, 65, tabWidth, 20).build());
|
|
||||||
|
|
||||||
this.addRenderableWidget(Button.builder(Component.literal("Graphics"), (b) -> {
|
|
||||||
this.currentTab = 1;
|
|
||||||
this.rebuildWidgets();
|
|
||||||
}).bounds(10, 65, tabWidth, 20).build());
|
|
||||||
|
|
||||||
if (currentTab == 0) {
|
|
||||||
this.addRenderableWidget(Button.builder(Component.literal("Enable Mod"), (b) -> {
|
|
||||||
System.out.println("Enable Mod clicked");
|
|
||||||
}).bounds(tabWidth + 30, 40, 150, 20).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.9 KiB |
@@ -7,7 +7,7 @@
|
|||||||
"authors": [],
|
"authors": [],
|
||||||
"contact": {},
|
"contact": {},
|
||||||
"license": "All-Rights-Reserved",
|
"license": "All-Rights-Reserved",
|
||||||
"icon": "assets/parrotmod/icon.png",
|
"icon": "assets/parrotmod/textures/gui/sprites/icon.png",
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"main": [
|
"main": [
|
||||||
|
|||||||
Reference in New Issue
Block a user