diff --git a/build.gradle b/build.gradle index f0cc49d..aa67876 100644 --- a/build.gradle +++ b/build.gradle @@ -24,9 +24,9 @@ dependencies { implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - implementation "curse.maven:modern-ui-352491:8206272" - implementation "icyllis.modernui:ModernUI-Fabric:26.1.2-3.13.0.4" - implementation "icyllis.arc3d:arc3d-core:2026.1.0" + implementation "dev.icyllis:modernui-core:${modernui_version}" + implementation "icyllis.modernui:ModernUI-Markflow:${modernui_version}" + implementation("icyllis.modernui:ModernUI-Fabric:${minecraft_version}-${modernui_version}.+") } processResources { diff --git a/gradle.properties b/gradle.properties index 217cde9..1927367 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,4 +11,5 @@ maven_group=de.winniepat archives_base_name=ParrotMod # Dependencies # check this on https://modmuss50.me/fabric.html -fabric_version=0.151.0+26.1.2 \ No newline at end of file +fabric_version=0.151.0+26.1.2 +modernui_version=3.13.0 \ No newline at end of file diff --git a/src/main/java/de/winniepat/parrotmod/mixin/TitleScreenMixin.java b/src/main/java/de/winniepat/parrotmod/mixin/TitleScreenMixin.java index 8653cb9..47ef8f6 100644 --- a/src/main/java/de/winniepat/parrotmod/mixin/TitleScreenMixin.java +++ b/src/main/java/de/winniepat/parrotmod/mixin/TitleScreenMixin.java @@ -1,30 +1,30 @@ package de.winniepat.parrotmod.mixin; -import de.winniepat.parrotmod.ui.SettingsScreen; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.components.Button; // Updated import +import de.winniepat.parrotmod.ui.SettingsFragment; +import icyllis.modernui.mc.MuiModApi; +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.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.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(TitleScreen.class) -public class TitleScreenMixin extends Screen { +public abstract class TitleScreenMixin extends Screen { protected TitleScreenMixin(Component title) { super(title); } - @Inject(at = @At("RETURN"), method = "init") - private void addCustomButton(CallbackInfo ci) { - int x = this.width / 2 - 100; - int y = this.height / 4 + 120; - - this.addRenderableWidget(Button.builder(Component.literal("Parrot Mod"), (button) -> { - Minecraft.getInstance().setScreen(new SettingsScreen(Component.literal("Settings"))); - }).bounds(x, y, 200, 20).build()); + @Inject(method = "init", at = @At("TAIL")) + private void onInit(CallbackInfo ci) { + WidgetSprites sprites = new WidgetSprites(Identifier.fromNamespaceAndPath("parrotmod", "icon"), Identifier.fromNamespaceAndPath("parrotmod", "icon")); + this.addRenderableWidget(new ImageButton(this.width / 2 + 104, this.height / 4 + 48, 20, 20, sprites, b -> { + MuiModApi.get().openScreen(new SettingsFragment()); + })); } } \ No newline at end of file diff --git a/src/main/java/de/winniepat/parrotmod/ui/GeneralTabFragment.java b/src/main/java/de/winniepat/parrotmod/ui/GeneralTabFragment.java new file mode 100644 index 0000000..7ebd746 --- /dev/null +++ b/src/main/java/de/winniepat/parrotmod/ui/GeneralTabFragment.java @@ -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); + } +} \ No newline at end of file diff --git a/src/main/java/de/winniepat/parrotmod/ui/SettingsFragment.java b/src/main/java/de/winniepat/parrotmod/ui/SettingsFragment.java new file mode 100644 index 0000000..8918079 --- /dev/null +++ b/src/main/java/de/winniepat/parrotmod/ui/SettingsFragment.java @@ -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; + } +} \ No newline at end of file diff --git a/src/main/java/de/winniepat/parrotmod/ui/SettingsScreen.java b/src/main/java/de/winniepat/parrotmod/ui/SettingsScreen.java deleted file mode 100644 index 81bc147..0000000 --- a/src/main/java/de/winniepat/parrotmod/ui/SettingsScreen.java +++ /dev/null @@ -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()); - } - } - -} diff --git a/src/main/resources/assets/parrotmod/icon.png b/src/main/resources/assets/parrotmod/icon.png deleted file mode 100644 index a4c15f3..0000000 Binary files a/src/main/resources/assets/parrotmod/icon.png and /dev/null differ diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index bff3c70..2bf6fb2 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -7,7 +7,7 @@ "authors": [], "contact": {}, "license": "All-Rights-Reserved", - "icon": "assets/parrotmod/icon.png", + "icon": "assets/parrotmod/textures/gui/sprites/icon.png", "environment": "*", "entrypoints": { "main": [