From cd58ea631faf729976319be783d05236d9d9c3ab Mon Sep 17 00:00:00 2001 From: Patrick <147879351+WinniePatGG@users.noreply.github.com> Date: Sun, 21 Jun 2026 01:03:03 +0200 Subject: [PATCH] I dont want to do this anymore --- .../de/winniepat/parrotmod/config/Config.java | 2 + .../parrotmod/ui/BaseTabFragment.java | 148 ++++++--------- .../parrotmod/ui/DiscordTabFragment.java | 109 ++++++------ .../parrotmod/ui/GeneralTabFragment.java | 52 +++--- .../parrotmod/ui/InfoTabFragment.java | 88 ++++++--- .../parrotmod/ui/SettingsFragment.java | 168 ++++++------------ .../parrotmod/ui/util/ParrotTheme.java | 40 +++++ 7 files changed, 297 insertions(+), 310 deletions(-) create mode 100644 src/main/java/de/winniepat/parrotmod/ui/util/ParrotTheme.java diff --git a/src/main/java/de/winniepat/parrotmod/config/Config.java b/src/main/java/de/winniepat/parrotmod/config/Config.java index b53f9ac..aec9ee4 100644 --- a/src/main/java/de/winniepat/parrotmod/config/Config.java +++ b/src/main/java/de/winniepat/parrotmod/config/Config.java @@ -5,4 +5,6 @@ public class Config { public boolean showBiomeInRPC = true; public boolean showHeldItemInRPC = true; public boolean showHealthInRPC = true; + public boolean enableSmoothUI = true; + public boolean enableCompactMode = false; } diff --git a/src/main/java/de/winniepat/parrotmod/ui/BaseTabFragment.java b/src/main/java/de/winniepat/parrotmod/ui/BaseTabFragment.java index af89160..2b6d966 100644 --- a/src/main/java/de/winniepat/parrotmod/ui/BaseTabFragment.java +++ b/src/main/java/de/winniepat/parrotmod/ui/BaseTabFragment.java @@ -1,130 +1,98 @@ package de.winniepat.parrotmod.ui; +import de.winniepat.parrotmod.ui.util.ParrotTheme; import icyllis.modernui.animation.ObjectAnimator; import icyllis.modernui.fragment.Fragment; -import icyllis.modernui.graphics.drawable.ShapeDrawable; import icyllis.modernui.view.Gravity; import icyllis.modernui.view.View; import icyllis.modernui.view.ViewGroup; import icyllis.modernui.widget.LinearLayout; +import icyllis.modernui.widget.Switch; import icyllis.modernui.widget.TextView; public abstract class BaseTabFragment extends Fragment { - protected static final int COLOR_CARD = 0xFF23232D; - protected static final int COLOR_ACCENT = 0xFF5CF392; - protected static final int COLOR_ACCENT_DIM = 0xFF3E8E5A; - protected static final int COLOR_TEXT_MAIN = 0xFFF0F0F0; - protected static final int COLOR_TEXT_SEC = 0xFF9EA3AF; - protected static final int COLOR_CARD_BORDER = 0x265CF392; + protected void animateChildren(ViewGroup group) { + for (int i = 0; i < group.getChildCount(); i++) { + View child = group.getChildAt(i); + child.setAlpha(0); + child.setTranslationX(ParrotTheme.dp(20)); - protected int dp(float dp) { - return (int) (dp * getContext().getResources().getDisplayMetrics().density); + ObjectAnimator alpha = ObjectAnimator.ofFloat(child, View.ALPHA, 0, 1); + alpha.setDuration(400); + alpha.setStartDelay(i * 40L); + alpha.start(); + + ObjectAnimator slide = ObjectAnimator.ofFloat(child, View.TRANSLATION_X, ParrotTheme.dp(20), 0); + slide.setDuration(500); + slide.setStartDelay(i * 40L); + slide.start(); + } } - protected TextView makeLabel(String text) { - TextView tv = new TextView(getContext()); - tv.setText(text); - tv.setTextSize(14); - tv.setTextColor(COLOR_TEXT_MAIN); - var p = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - p.topMargin = dp(12); - p.bottomMargin = dp(4); - tv.setLayoutParams(p); - return tv; + protected void addPageHeader(LinearLayout parent, String title, String subtitle) { + LinearLayout headerBox = new LinearLayout(getContext()); + headerBox.setOrientation(LinearLayout.VERTICAL); + headerBox.setPadding(0, 0, 0, ParrotTheme.dp(24)); + + TextView titleView = new TextView(getContext()); + titleView.setText(title); + titleView.setTextSize(28); + titleView.setTextColor(ParrotTheme.TEXT_TITLE); + headerBox.addView(titleView); + + TextView subView = new TextView(getContext()); + subView.setText(subtitle); + subView.setTextSize(14); + subView.setTextColor(ParrotTheme.NEON_ACCENT); + headerBox.addView(subView); + + parent.addView(headerBox); } - protected void addSectionHeader(LinearLayout parent, String title) { + protected void addSectionLabel(LinearLayout parent, String title) { TextView tv = new TextView(getContext()); tv.setText(title.toUpperCase()); - tv.setTextSize(11); - tv.setTextColor(COLOR_ACCENT); + tv.setTextSize(12); + tv.setTextColor(ParrotTheme.TEXT_SUBTITLE); var p = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - p.topMargin = dp(24); - p.bottomMargin = dp(10); - p.leftMargin = dp(4); + p.topMargin = ParrotTheme.dp(16); + p.bottomMargin = ParrotTheme.dp(12); parent.addView(tv, p); } - protected void addTabHeader(LinearLayout parent, String title, String description) { - TextView titleView = new TextView(getContext()); - titleView.setText(title); - titleView.setTextSize(24); - titleView.setTextColor(0xFFFFFFFF); - titleView.setPadding(0, 0, 0, dp(2)); - parent.addView(titleView); - - if (description != null) { - TextView descView = new TextView(getContext()); - descView.setText(description); - descView.setTextSize(13); - descView.setTextColor(COLOR_TEXT_SEC); - descView.setPadding(0, 0, 0, dp(16)); - parent.addView(descView); - } - - View divider = new View(getContext()); - var divParams = new LinearLayout.LayoutParams(dp(40), dp(3)); - divParams.bottomMargin = dp(16); - divider.setLayoutParams(divParams); - divider.setBackground(makeRoundedBg(COLOR_ACCENT, 2)); - parent.addView(divider); - } - - protected LinearLayout createSettingCard(String title, String description) { + protected LinearLayout createToggleCard(String title, String desc, boolean isChecked, Switch.OnCheckedChangeListener listener) { LinearLayout card = new LinearLayout(getContext()); card.setOrientation(LinearLayout.HORIZONTAL); card.setGravity(Gravity.CENTER_VERTICAL); - card.setPadding(dp(18), dp(14), dp(18), dp(14)); - card.setBackground(makeBorderedBg(COLOR_CARD, COLOR_CARD_BORDER, 10, 1)); + card.setPadding(ParrotTheme.dp(20), ParrotTheme.dp(16), ParrotTheme.dp(20), ParrotTheme.dp(16)); + card.setBackground(ParrotTheme.createCard(12)); var cardParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - cardParams.bottomMargin = dp(10); + cardParams.bottomMargin = ParrotTheme.dp(12); card.setLayoutParams(cardParams); LinearLayout textLayout = new LinearLayout(getContext()); textLayout.setOrientation(LinearLayout.VERTICAL); - var textParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f); - card.addView(textLayout, textParams); + card.addView(textLayout, new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)); TextView titleView = new TextView(getContext()); titleView.setText(title); - titleView.setTextSize(15.5f); - titleView.setTextColor(COLOR_TEXT_MAIN); + titleView.setTextSize(16); + titleView.setTextColor(ParrotTheme.TEXT_TITLE); textLayout.addView(titleView); - if (description != null) { - TextView descView = new TextView(getContext()); - descView.setText(description); - descView.setTextSize(12.5f); - descView.setTextColor(COLOR_TEXT_SEC); - textLayout.addView(descView); - } + TextView descView = new TextView(getContext()); + descView.setText(desc); + descView.setTextSize(13); + descView.setTextColor(ParrotTheme.TEXT_SUBTITLE); + textLayout.addView(descView); + + Switch toggle = new Switch(getContext()); + toggle.setChecked(isChecked); + toggle.setOnCheckedChangeListener(listener); + card.addView(toggle); return card; } - - protected ShapeDrawable makeRoundedBg(int color, float radius) { - ShapeDrawable d = new ShapeDrawable(); - d.setCornerRadius(dp(radius)); - d.setColor(color); - return d; - } - - protected ShapeDrawable makeBorderedBg(int color, int strokeColor, float radius, float strokeWidth) { - ShapeDrawable d = new ShapeDrawable(); - d.setCornerRadius(dp(radius)); - d.setColor(color); - d.setStroke(dp(strokeWidth), strokeColor); - return d; - } - - @Override - public void onViewCreated(View view, icyllis.modernui.util.DataSet savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - view.setAlpha(0); - view.setTranslationY(dp(10)); - ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(400).start(); - ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, dp(10), 0).setDuration(400).start(); - } -} +} \ No newline at end of file diff --git a/src/main/java/de/winniepat/parrotmod/ui/DiscordTabFragment.java b/src/main/java/de/winniepat/parrotmod/ui/DiscordTabFragment.java index 19a6fc6..cc7cf41 100644 --- a/src/main/java/de/winniepat/parrotmod/ui/DiscordTabFragment.java +++ b/src/main/java/de/winniepat/parrotmod/ui/DiscordTabFragment.java @@ -1,92 +1,91 @@ package de.winniepat.parrotmod.ui; + import de.winniepat.parrotmod.config.ConfigManager; +import de.winniepat.parrotmod.ui.util.ParrotTheme; +import icyllis.modernui.animation.ObjectAnimator; import icyllis.modernui.util.DataSet; import icyllis.modernui.view.LayoutInflater; import icyllis.modernui.view.View; import icyllis.modernui.view.ViewGroup; import icyllis.modernui.widget.LinearLayout; -import icyllis.modernui.widget.Switch; import icyllis.modernui.widget.ScrollView; -import java.util.ArrayList; -import java.util.List; public class DiscordTabFragment extends BaseTabFragment { - private final List rpcDetailViews = new ArrayList<>(); + private LinearLayout contentLayout; + private LinearLayout subSettingsGroup; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, DataSet savedInstanceData) { - ScrollView scrollView = new ScrollView(getContext()); - scrollView.setFillViewport(true); + ScrollView scroll = new ScrollView(getContext()); - LinearLayout layout = new LinearLayout(getContext()); - layout.setOrientation(LinearLayout.VERTICAL); - layout.setPadding(dp(28), dp(24), dp(28), dp(24)); - scrollView.addView(layout); + contentLayout = new LinearLayout(getContext()); + contentLayout.setOrientation(LinearLayout.VERTICAL); + contentLayout.setPadding(ParrotTheme.dp(40), ParrotTheme.dp(40), ParrotTheme.dp(40), ParrotTheme.dp(40)); + scroll.addView(contentLayout); - addTabHeader(layout, "Discord Rich Presence", "Connect your Minecraft activity to your Discord profile."); + addPageHeader(contentLayout, "Discord Rich Presence", "Broadcast your Minecraft activity."); - addSectionHeader(layout, "Core Integration"); + addSectionLabel(contentLayout, "Core Integration"); - addSwitchRow(layout, "Status Integration", "Toggle Discord Rich Presence globally.", + contentLayout.addView(createToggleCard("Enable Rich Presence", "Connect Parrot to your Discord client.", ConfigManager.getInstance().enableDiscordRPC, (v, checked) -> { - ConfigManager.getInstance().enableDiscordRPC = checked; - ConfigManager.save(); - updateRPCDetailsEnabled(checked); - }); + ConfigManager.getInstance().enableDiscordRPC = checked; + ConfigManager.save(); + animateSubSettingsState(checked); + })); - addSectionHeader(layout, "Status Customization"); + addSectionLabel(contentLayout, "Activity Customization"); - rpcDetailViews.add(addSwitchRow(layout, "Location Tracking", "Broadcast your current biome.", + subSettingsGroup = new LinearLayout(getContext()); + subSettingsGroup.setOrientation(LinearLayout.VERTICAL); + contentLayout.addView(subSettingsGroup); + + subSettingsGroup.addView(createToggleCard("Location Tracking", "Broadcast your current biome and dimension.", ConfigManager.getInstance().showBiomeInRPC, (v, checked) -> { - ConfigManager.getInstance().showBiomeInRPC = checked; - ConfigManager.save(); - })); + ConfigManager.getInstance().showBiomeInRPC = checked; + ConfigManager.save(); + })); - rpcDetailViews.add(addSwitchRow(layout, "Equipment Status", "Show your currently held items.", + subSettingsGroup.addView(createToggleCard("Equipment Status", "Show your currently held items and armor.", ConfigManager.getInstance().showHeldItemInRPC, (v, checked) -> { - ConfigManager.getInstance().showHeldItemInRPC = checked; - ConfigManager.save(); - })); + ConfigManager.getInstance().showHeldItemInRPC = checked; + ConfigManager.save(); + })); - rpcDetailViews.add(addSwitchRow(layout, "Vitality Info", "Display your current health status.", + subSettingsGroup.addView(createToggleCard("Vitality Info", "Display your exact health and hunger.", ConfigManager.getInstance().showHealthInRPC, (v, checked) -> { - ConfigManager.getInstance().showHealthInRPC = checked; - ConfigManager.save(); - })); + ConfigManager.getInstance().showHealthInRPC = checked; + ConfigManager.save(); + })); - updateRPCDetailsEnabled(ConfigManager.getInstance().enableDiscordRPC); + applySubSettingsState(ConfigManager.getInstance().enableDiscordRPC); - return scrollView; + return scroll; } - private void updateRPCDetailsEnabled(boolean enabled) { - for (View v : rpcDetailViews) { - v.setEnabled(enabled); - v.setAlpha(enabled ? 1.0f : 0.5f); - if (v instanceof ViewGroup) { - setChildrenEnabled((ViewGroup) v, enabled); - } - } + private void animateSubSettingsState(boolean enabled) { + float targetAlpha = enabled ? 1.0f : 0.4f; + ObjectAnimator.ofFloat(subSettingsGroup, View.ALPHA, subSettingsGroup.getAlpha(), targetAlpha).setDuration(250).start(); + setChildrenEnabled(subSettingsGroup, enabled); } - private void setChildrenEnabled(ViewGroup vg, boolean enabled) { - for (int i = 0; i < vg.getChildCount(); i++) { - View child = vg.getChildAt(i); + private void applySubSettingsState(boolean enabled) { + subSettingsGroup.setAlpha(enabled ? 1.0f : 0.4f); + setChildrenEnabled(subSettingsGroup, enabled); + } + + private void setChildrenEnabled(ViewGroup group, boolean enabled) { + for (int i = 0; i < group.getChildCount(); i++) { + View child = group.getChildAt(i); child.setEnabled(enabled); - if (child instanceof ViewGroup) { - setChildrenEnabled((ViewGroup) child, enabled); - } + if (child instanceof ViewGroup vg) setChildrenEnabled(vg, enabled); } } - private View addSwitchRow(LinearLayout parent, String title, String desc, boolean checked, Switch.OnCheckedChangeListener listener) { - LinearLayout card = createSettingCard(title, desc); - Switch s = new Switch(getContext()); - s.setChecked(checked); - s.setOnCheckedChangeListener(listener); - card.addView(s); - parent.addView(card); - return card; + @Override + public void onViewCreated(View view, DataSet savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + animateChildren(contentLayout); } -} +} \ 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 index d4bca3a..74b4916 100644 --- a/src/main/java/de/winniepat/parrotmod/ui/GeneralTabFragment.java +++ b/src/main/java/de/winniepat/parrotmod/ui/GeneralTabFragment.java @@ -1,45 +1,49 @@ package de.winniepat.parrotmod.ui; import de.winniepat.parrotmod.config.ConfigManager; +import de.winniepat.parrotmod.ui.util.ParrotTheme; import icyllis.modernui.util.DataSet; import icyllis.modernui.view.LayoutInflater; import icyllis.modernui.view.View; import icyllis.modernui.view.ViewGroup; -import icyllis.modernui.widget.Button; import icyllis.modernui.widget.LinearLayout; -import net.minecraft.client.Minecraft; +import icyllis.modernui.widget.ScrollView; public class GeneralTabFragment extends BaseTabFragment { + private LinearLayout contentLayout; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, DataSet savedInstanceData) { - LinearLayout layout = new LinearLayout(getContext()); - layout.setOrientation(LinearLayout.VERTICAL); - layout.setPadding(dp(28), dp(24), dp(28), dp(24)); + ScrollView scroll = new ScrollView(getContext()); - addTabHeader(layout, "Client Settings", "Configure your client-side experience and mod data."); + contentLayout = new LinearLayout(getContext()); + contentLayout.setOrientation(LinearLayout.VERTICAL); + contentLayout.setPadding(ParrotTheme.dp(40), ParrotTheme.dp(40), ParrotTheme.dp(40), ParrotTheme.dp(40)); + scroll.addView(contentLayout); - addSectionHeader(layout, "Information"); - layout.addView(createSettingCard("Version", "Running on Minecraft " + Minecraft.getInstance().getLaunchedVersion())); + addPageHeader(contentLayout, "Client Settings", "Customize your gameplay experience."); - addSectionHeader(layout, "Data Management"); + addSectionLabel(contentLayout, "Interface"); - LinearLayout reloadCard = createSettingCard("Reload configuration", "Discard unsaved changes and reload from disk."); - Button reloadBtn = new Button(getContext()); - reloadBtn.setText("Reload"); - reloadBtn.setPadding(dp(16), 0, dp(16), 0); - reloadBtn.setOnClickListener(v -> ConfigManager.load()); - reloadCard.addView(reloadBtn); - layout.addView(reloadCard); + contentLayout.addView(createToggleCard("Smooth Animations", "Enable fluid transitions across the mod GUI.", + ConfigManager.getInstance().enableSmoothUI, (v, checked) -> { + ConfigManager.getInstance().enableSmoothUI = checked; + ConfigManager.save(); + })); - LinearLayout saveCard = createSettingCard("Commit changes", "Save all current settings to the configuration file."); - Button saveBtn = new Button(getContext()); - saveBtn.setText("Save"); - saveBtn.setPadding(dp(16), 0, dp(16), 0); - saveBtn.setOnClickListener(v -> ConfigManager.save()); - saveCard.addView(saveBtn); - layout.addView(saveCard); + contentLayout.addView(createToggleCard("Compact Mode", "Reduce padding to show more information at once.", + ConfigManager.getInstance().enableCompactMode, (v, checked) -> { + ConfigManager.getInstance().enableCompactMode = checked; + ConfigManager.save(); + })); - return layout; + return scroll; + } + + @Override + public void onViewCreated(View view, DataSet savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + animateChildren(contentLayout); } } \ No newline at end of file diff --git a/src/main/java/de/winniepat/parrotmod/ui/InfoTabFragment.java b/src/main/java/de/winniepat/parrotmod/ui/InfoTabFragment.java index 31e987f..54266fb 100644 --- a/src/main/java/de/winniepat/parrotmod/ui/InfoTabFragment.java +++ b/src/main/java/de/winniepat/parrotmod/ui/InfoTabFragment.java @@ -1,48 +1,88 @@ package de.winniepat.parrotmod.ui; +import de.winniepat.parrotmod.ui.util.ParrotTheme; import icyllis.modernui.util.DataSet; import icyllis.modernui.view.LayoutInflater; import icyllis.modernui.view.View; import icyllis.modernui.view.ViewGroup; import icyllis.modernui.widget.LinearLayout; import icyllis.modernui.widget.ScrollView; +import icyllis.modernui.widget.TextView; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.Minecraft; public class InfoTabFragment extends BaseTabFragment { + private LinearLayout contentLayout; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, DataSet savedInstanceData) { - ScrollView scrollView = new ScrollView(getContext()); - scrollView.setFillViewport(true); + ScrollView scroll = new ScrollView(getContext()); + scroll.setFillViewport(true); - LinearLayout layout = new LinearLayout(getContext()); - layout.setOrientation(LinearLayout.VERTICAL); - layout.setPadding(dp(28), dp(24), dp(28), dp(24)); - scrollView.addView(layout); + contentLayout = new LinearLayout(getContext()); + contentLayout.setOrientation(LinearLayout.VERTICAL); + contentLayout.setPadding(ParrotTheme.dp(40), ParrotTheme.dp(40), ParrotTheme.dp(40), ParrotTheme.dp(40)); + scroll.addView(contentLayout); - addTabHeader(layout, "System Overview", "Detailed information about your environment and mod versions."); + addPageHeader(contentLayout, "System Dashboard", "Real-time environment analytics"); - addSectionHeader(layout, "Software Manifest"); - String parrotVersion = FabricLoader.getInstance().getModContainer("parrotmod").orElseThrow().getMetadata().getVersion().getFriendlyString(); - layout.addView(createSettingCard("ParrotMod", "Stable Build v" + parrotVersion)); + addSectionLabel(contentLayout, "Software Manifest"); - String mcVersion = FabricLoader.getInstance().getModContainer("minecraft").orElseThrow().getMetadata().getVersion().getFriendlyString(); - layout.addView(createSettingCard("Minecraft Engine", Minecraft.getInstance().getLaunchedVersion() + " (" + mcVersion + ")")); + LinearLayout row1 = new LinearLayout(getContext()); + row1.setOrientation(LinearLayout.HORIZONTAL); + row1.addView(createStatGrid("Parrot Engine", "v" + FabricLoader.getInstance().getModContainer("parrotmod").orElseThrow().getMetadata().getVersion().getFriendlyString()), new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)); - String loaderVersion = FabricLoader.getInstance().getModContainer("fabricloader").orElseThrow().getMetadata().getVersion().getFriendlyString(); - layout.addView(createSettingCard("Fabric Loader", "Build " + loaderVersion)); + View spacer1 = new View(getContext()); + row1.addView(spacer1, new LinearLayout.LayoutParams(ParrotTheme.dp(16), 1)); - addSectionHeader(layout, "Runtime Environment"); - layout.addView(createSettingCard("Java Runtime", System.getProperty("java.version") + " [" + System.getProperty("os.arch") + "]")); - layout.addView(createSettingCard("Operating System", System.getProperty("os.name") + " [" + System.getProperty("os.version") + "]")); + row1.addView(createStatGrid("Minecraft", Minecraft.getInstance().getLaunchedVersion()), new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)); + contentLayout.addView(row1); - long maxMemory = Runtime.getRuntime().maxMemory(); - long totalMemory = Runtime.getRuntime().totalMemory(); - long freeMemory = Runtime.getRuntime().freeMemory(); - long usedMemory = totalMemory - freeMemory; - layout.addView(createSettingCard("Memory Allocation", String.format("%d MiB / %d MiB in use", usedMemory / 1024 / 1024, maxMemory / 1024 / 1024))); + addSectionLabel(contentLayout, "Hardware Status"); - return scrollView; + LinearLayout row2 = new LinearLayout(getContext()); + row2.setOrientation(LinearLayout.HORIZONTAL); + + long maxMem = Runtime.getRuntime().maxMemory() / 1024 / 1024; + long usedMem = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024 / 1024; + + row2.addView(createStatGrid("Memory Usage", usedMem + " / " + maxMem + " MB"), new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)); + + View spacer2 = new View(getContext()); + row2.addView(spacer2, new LinearLayout.LayoutParams(ParrotTheme.dp(16), 1)); + + row2.addView(createStatGrid("Architecture", System.getProperty("os.arch").toUpperCase()), new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)); + contentLayout.addView(row2); + + return scroll; } -} + + private LinearLayout createStatGrid(String label, String value) { + LinearLayout box = new LinearLayout(getContext()); + box.setOrientation(LinearLayout.VERTICAL); + box.setPadding(ParrotTheme.dp(20), ParrotTheme.dp(20), ParrotTheme.dp(20), ParrotTheme.dp(20)); + box.setBackground(ParrotTheme.createCard(12)); + + TextView valTxt = new TextView(getContext()); + valTxt.setText(value); + valTxt.setTextSize(20); + valTxt.setTextColor(ParrotTheme.NEON_ACCENT); + box.addView(valTxt); + + TextView lblTxt = new TextView(getContext()); + lblTxt.setText(label.toUpperCase()); + lblTxt.setTextSize(11); + lblTxt.setTextColor(ParrotTheme.TEXT_MUTED); + lblTxt.setPadding(0, ParrotTheme.dp(4), 0, 0); + box.addView(lblTxt); + + return box; + } + + @Override + public void onViewCreated(View view, DataSet savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + animateChildren(contentLayout); + } +} \ 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 index 5c796f5..24816c9 100644 --- a/src/main/java/de/winniepat/parrotmod/ui/SettingsFragment.java +++ b/src/main/java/de/winniepat/parrotmod/ui/SettingsFragment.java @@ -1,180 +1,114 @@ package de.winniepat.parrotmod.ui; +import de.winniepat.parrotmod.ui.util.ParrotTheme; import icyllis.modernui.R; import icyllis.modernui.animation.ObjectAnimator; 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.*; -import net.fabricmc.loader.api.FabricLoader; public class SettingsFragment extends Fragment { - private static final int COLOR_BACKGROUND = 0xFF18181F; - private static final int COLOR_SIDEBAR = 0xFF121217; - private static final int COLOR_ACCENT = 0xFF5CF392; - private static final int COLOR_TEXT_DIM = 0xFF9EA3AF; - private static final int COLOR_TAB_SELECTED = 0x125CF392; - private static final int COLOR_BORDER = 0x1AFFFFFF; - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, DataSet savedInstanceState) { FrameLayout root = new FrameLayout(getContext()); - root.setLayoutParams(new FrameLayout.LayoutParams(dp(760), dp(520), Gravity.CENTER)); + root.setLayoutParams(new FrameLayout.LayoutParams(ParrotTheme.dp(840), ParrotTheme.dp(580), Gravity.CENTER)); View bg = new View(getContext()); - bg.setBackground(makeBorderedBg(COLOR_BACKGROUND, COLOR_BORDER, 14, 1.2f)); + bg.setBackground(ParrotTheme.createGlassPanel(16, 1.5f)); root.addView(bg); LinearLayout layout = new LinearLayout(getContext()); layout.setOrientation(LinearLayout.HORIZONTAL); root.addView(layout); - FrameLayout sidebarContainer = new FrameLayout(getContext()); - var sidebarParams = new LinearLayout.LayoutParams(dp(190), ViewGroup.LayoutParams.MATCH_PARENT); - layout.addView(sidebarContainer, sidebarParams); - - View sidebarBg = new View(getContext()); - sidebarBg.setBackground(makeRoundedBg(COLOR_SIDEBAR, 14)); - sidebarContainer.addView(sidebarBg); - - LinearLayout sidebarContent = new LinearLayout(getContext()); - sidebarContent.setOrientation(LinearLayout.VERTICAL); - sidebarContent.setPadding(0, dp(28), 0, dp(16)); - sidebarContainer.addView(sidebarContent, new FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); - - View separator = new View(getContext()); - var sepParams = new LinearLayout.LayoutParams(dp(1), ViewGroup.LayoutParams.MATCH_PARENT); - separator.setOutlineAmbientShadowColor(COLOR_BORDER); - layout.addView(separator, sepParams); - - LinearLayout titleLayout = new LinearLayout(getContext()); - titleLayout.setOrientation(LinearLayout.VERTICAL); - titleLayout.setGravity(Gravity.CENTER); - titleLayout.setPadding(0, 0, 0, dp(32)); + LinearLayout sidebar = new LinearLayout(getContext()); + sidebar.setOrientation(LinearLayout.VERTICAL); + sidebar.setPadding(ParrotTheme.dp(20), ParrotTheme.dp(32), ParrotTheme.dp(20), ParrotTheme.dp(24)); + layout.addView(sidebar, new LinearLayout.LayoutParams(ParrotTheme.dp(220), ViewGroup.LayoutParams.MATCH_PARENT)); TextView title = new TextView(getContext()); title.setText("PARROT"); - title.setTextSize(22); - title.setGravity(Gravity.CENTER); - title.setTextColor(COLOR_ACCENT); - titleLayout.addView(title); + title.setTextSize(26); + title.setTextColor(ParrotTheme.NEON_ACCENT); + title.setGravity(Gravity.CENTER_HORIZONTAL); + sidebar.addView(title); - sidebarContent.addView(titleLayout); - - FrameLayout tabsContainer = new FrameLayout(getContext()); - sidebarContent.addView(tabsContainer, new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f)); + TextView subtitle = new TextView(getContext()); + subtitle.setText("CONTROL CENTER"); + subtitle.setTextSize(10); + subtitle.setTextColor(ParrotTheme.TEXT_MUTED); + subtitle.setGravity(Gravity.CENTER_HORIZONTAL); + subtitle.setPadding(0, 0, 0, ParrotTheme.dp(40)); + sidebar.addView(subtitle); LinearLayout tabsLayout = new LinearLayout(getContext()); tabsLayout.setOrientation(LinearLayout.VERTICAL); - tabsLayout.setPadding(dp(12), 0, dp(12), 0); - tabsContainer.addView(tabsLayout, new FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.TOP)); - + sidebar.addView(tabsLayout, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f)); FrameLayout contentArea = new FrameLayout(getContext()); contentArea.setId(R.id.content); - var contentParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 1f); - layout.addView(contentArea, contentParams); + layout.addView(contentArea, new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 1f)); - String[] tabNames = {"Info", "General", "Discord"}; - Fragment[] tabFragments = { - new InfoTabFragment(), - new GeneralTabFragment(), - new DiscordTabFragment() - }; + String[] tabNames = {"Dashboard", "Client Settings", "Discord RPC"}; + Fragment[] tabFragments = { new InfoTabFragment(), new GeneralTabFragment(), new DiscordTabFragment() }; - View[] tabContainers = new View[tabNames.length]; View[] indicators = new View[tabNames.length]; TextView[] textViews = new TextView[tabNames.length]; + View[] tabButtons = new View[tabNames.length]; for (int i = 0; i < tabNames.length; i++) { final int index = i; - - FrameLayout tabContainer = new FrameLayout(getContext()); - + FrameLayout tabBtn = new FrameLayout(getContext()); + tabButtons[i] = tabBtn; + View indicator = new View(getContext()); - indicator.setBackground(makeRoundedBg(COLOR_ACCENT, 2)); - indicator.setVisibility(View.INVISIBLE); - var indParams = new FrameLayout.LayoutParams(dp(3), dp(18), Gravity.START | Gravity.CENTER_VERTICAL); - tabContainer.addView(indicator, indParams); + icyllis.modernui.graphics.drawable.ShapeDrawable indBg = new icyllis.modernui.graphics.drawable.ShapeDrawable(); + indBg.setCornerRadius(ParrotTheme.dp(4)); + indBg.setColor(ParrotTheme.NEON_ACCENT); + indicator.setBackground(indBg); + indicator.setAlpha(0f); + + tabBtn.addView(indicator, new FrameLayout.LayoutParams(ParrotTheme.dp(4), ParrotTheme.dp(24), Gravity.START | Gravity.CENTER_VERTICAL)); TextView tabText = new TextView(getContext()); tabText.setText(tabNames[index]); - tabText.setTextSize(14); - tabText.setPadding(dp(24), 0, dp(16), 0); - tabText.setTextColor(COLOR_TEXT_DIM); - tabText.setGravity(Gravity.START | Gravity.CENTER_VERTICAL); - tabContainer.addView(tabText, new FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, dp(40))); + tabText.setTextSize(15); + tabText.setTextColor(ParrotTheme.TEXT_SUBTITLE); + tabText.setPadding(ParrotTheme.dp(20), ParrotTheme.dp(12), 0, ParrotTheme.dp(12)); + tabBtn.addView(tabText); - tabContainer.setOnClickListener(v -> { + tabBtn.setOnClickListener(v -> { getChildFragmentManager().beginTransaction() .setReorderingAllowed(true) .replace(contentArea.getId(), tabFragments[index]) .commit(); for (int j = 0; j < tabNames.length; j++) { - boolean selected = (j == index); - textViews[j].setTextColor(selected ? 0xFFFFFFFF : COLOR_TEXT_DIM); - tabContainers[j].setBackground(selected ? makeRoundedBg(COLOR_TAB_SELECTED, 8) : null); - indicators[j].setVisibility(selected ? View.VISIBLE : View.INVISIBLE); + boolean active = (j == index); + textViews[j].setTextColor(active ? ParrotTheme.TEXT_TITLE : ParrotTheme.TEXT_SUBTITLE); + ObjectAnimator.ofFloat(indicators[j], View.ALPHA, indicators[j].getAlpha(), active ? 1f : 0f).setDuration(200).start(); } }); - var tabParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp(40)); - tabParams.bottomMargin = dp(6); - tabsLayout.addView(tabContainer, tabParams); - - tabContainers[index] = tabContainer; + var btnParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + btnParams.bottomMargin = ParrotTheme.dp(8); + tabsLayout.addView(tabBtn, btnParams); + indicators[index] = indicator; textViews[index] = tabText; } - TextView footer = new TextView(getContext()); - String version = FabricLoader.getInstance().getModContainer("parrotmod") - .map(m -> m.getMetadata().getVersion().getFriendlyString()).orElse("?.?.?"); - footer.setText("v" + version); - footer.setTextSize(10); - footer.setTextColor(0x33FFFFFF); - footer.setGravity(Gravity.CENTER); - footer.setPadding(dp(16), dp(12), dp(16), dp(12)); - sidebarContent.addView(footer); - root.setAlpha(0); - root.setScaleX(0.98f); - root.setScaleY(0.98f); - ObjectAnimator.ofFloat(root, View.ALPHA, 0, 1).setDuration(350).start(); - ObjectAnimator.ofFloat(root, View.SCALE_X, 0.98f, 1).setDuration(350).start(); - ObjectAnimator.ofFloat(root, View.SCALE_Y, 0.98f, 1).setDuration(350).start(); + root.setScaleX(0.95f); + root.setScaleY(0.95f); + ObjectAnimator.ofFloat(root, View.ALPHA, 0, 1).setDuration(400).start(); + ObjectAnimator.ofFloat(root, View.SCALE_X, 0.95f, 1).setDuration(500).start(); + ObjectAnimator.ofFloat(root, View.SCALE_Y, 0.95f, 1).setDuration(500).start(); - root.post(() -> { - tabContainers[0].callOnClick(); - }); + root.post(() -> tabButtons[0].callOnClick()); return root; } - - private int dp(float dp) { - return (int) (dp * getContext().getResources().getDisplayMetrics().density); - } - - private ShapeDrawable makeRoundedBg(int color, float radius) { - ShapeDrawable d = new ShapeDrawable(); - d.setCornerRadius(dp(radius)); - d.setColor(color); - return d; - } - - private ShapeDrawable makeBorderedBg(int color, int strokeColor, float radius, float strokeWidth) { - ShapeDrawable d = new ShapeDrawable(); - d.setCornerRadius(dp(radius)); - d.setColor(color); - d.setStroke(dp(strokeWidth), strokeColor); - return d; - } } \ No newline at end of file diff --git a/src/main/java/de/winniepat/parrotmod/ui/util/ParrotTheme.java b/src/main/java/de/winniepat/parrotmod/ui/util/ParrotTheme.java new file mode 100644 index 0000000..b403326 --- /dev/null +++ b/src/main/java/de/winniepat/parrotmod/ui/util/ParrotTheme.java @@ -0,0 +1,40 @@ +package de.winniepat.parrotmod.ui.util; + +import icyllis.modernui.graphics.drawable.ShapeDrawable; +import icyllis.modernui.util.DisplayMetrics; +import icyllis.modernui.ModernUI; + +public class ParrotTheme { + public static final int BG_WINDOW = 0xCC09090E; + public static final int BG_CARD = 0x601A1A24; + + public static final int NEON_ACCENT = 0xFF00FF87; + + public static final int TEXT_TITLE = 0xFFFFFFFF; + public static final int TEXT_SUBTITLE = 0xFFA0A5B5; + public static final int TEXT_MUTED = 0xFF6B7280; + + public static final int BORDER_GLASS = 0x20FFFFFF; + public static final int BORDER_CARD = 0x15FFFFFF; + + public static int dp(float dp) { + DisplayMetrics metrics = ModernUI.getInstance().getResources().getDisplayMetrics(); + return (int) (dp * metrics.density); + } + + public static ShapeDrawable createGlassPanel(float radius, float strokeWidth) { + ShapeDrawable d = new ShapeDrawable(); + d.setCornerRadius(dp(radius)); + d.setColor(BG_WINDOW); + if (strokeWidth > 0) d.setStroke(dp(strokeWidth), BORDER_GLASS); + return d; + } + + public static ShapeDrawable createCard(float radius) { + ShapeDrawable d = new ShapeDrawable(); + d.setCornerRadius(dp(radius)); + d.setColor(BG_CARD); + d.setStroke(dp(1), BORDER_CARD); + return d; + } +} \ No newline at end of file