Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
import net.runelite.client.ui.components.materialtabs.MaterialTab;
import net.runelite.client.ui.components.materialtabs.MaterialTabGroup;
import net.runelite.client.util.ImageUtil;
import net.runelite.client.ui.FontManager;

import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.image.BufferedImage;

@Singleton
public class MicrobotTopLevelConfigPanel extends PluginPanel {
Expand All @@ -28,6 +30,174 @@ public class MicrobotTopLevelConfigPanel extends PluginPanel {
private PluginPanel current;
private boolean removeOnTabChange;

// -- BEGIN: NEW badge ( to be removed once we migrate all plugins to Hub) --
private final MaterialTab hubTab;
private JPanel glassPane;
private JLabel newBadgeOverlay;
private Timer newBadgeTimer;
private Component previousGlassPane;

private void createNewBadgeOverlay() {
if (hubTab == null) return;

glassPane = new JPanel() {
@Override
public boolean contains(int x, int y) {
return false;
}
@Override
protected void paintChildren(Graphics g) {
super.paintChildren(g);
}
};
glassPane.setOpaque(false);
glassPane.setLayout(null);

newBadgeOverlay = new JLabel() {
private final BufferedImage newBadge = ImageUtil.loadImageResource(MicrobotTopLevelConfigPanel.class, "NEW.png");
private final long startTime = System.currentTimeMillis();

@Override
protected void paintComponent(Graphics g) {
if (newBadge == null) {
System.out.println("DEBUG: newBadge image is null, cannot paint");
SwingUtilities.invokeLater(MicrobotTopLevelConfigPanel.this::cleanupNewBadge);
return;
}

Graphics2D g2d = (Graphics2D) g.create();
try {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

double time = (System.currentTimeMillis() - startTime) % 3000;
double scale;

if (time < 300) {
double pulsePhase = (time / 300.0) * Math.PI;
double pulseAmount = Math.sin(pulsePhase) * 0.06;
scale = 0.7 + pulseAmount;
} else {
scale = 0.7;
}

double scaledWidth = newBadge.getWidth() * scale;
double scaledHeight = newBadge.getHeight() * scale;

double x = (getWidth() - scaledWidth) / 2.0;
double y = (getHeight() - scaledHeight) / 2.0;

g2d.rotate(Math.toRadians(20), getWidth() / 2.0, getHeight() / 2.0);
g2d.drawImage(newBadge, (int)x, (int)y, (int)(x + scaledWidth), (int)(y + scaledHeight),
0, 0, newBadge.getWidth(), newBadge.getHeight(), null);

} finally {
g2d.dispose();
}
}
};

newBadgeOverlay.setOpaque(false);
newBadgeOverlay.setSize(32, 32);
newBadgeOverlay.setVisible(false);
glassPane.add(newBadgeOverlay);

SwingUtilities.invokeLater(() -> {
JRootPane rootPane = SwingUtilities.getRootPane(this);
if (rootPane != null) {
if (previousGlassPane == null) {
previousGlassPane = rootPane.getGlassPane();
}
rootPane.setGlassPane(glassPane);
glassPane.setVisible(true);
updateBadgePosition();
}
});

newBadgeTimer = new Timer(50, e -> {
if (hubTab != null && hubTab.isShowing() && glassPane.isVisible()) {
updateBadgePosition();
newBadgeOverlay.setVisible(true);
newBadgeOverlay.repaint();
} else {
newBadgeOverlay.setVisible(false);
}
});
newBadgeTimer.start();
}

private void updateBadgePosition() {
if (newBadgeOverlay == null || hubTab == null || glassPane == null) return;

try {
Point topRight = SwingUtilities.convertPoint(hubTab, hubTab.getWidth(), 0, glassPane);
int x = topRight.x - 25;
int y = topRight.y - 12;
newBadgeOverlay.setLocation(x, y);
} catch (Exception ex) {
System.out.println("DEBUG: Exception in updateBadgePosition: " + ex);
}
}

private void cleanupNewBadge() {
if (newBadgeTimer != null) {
newBadgeTimer.stop();
newBadgeTimer = null;
}
if (glassPane != null) {
glassPane.setVisible(false);
JRootPane rootPane = SwingUtilities.getRootPane(this);
if (rootPane != null && previousGlassPane != null) {
rootPane.setGlassPane(previousGlassPane);
previousGlassPane = null;
}
glassPane = null;
}
newBadgeOverlay = null;
}
// -- END: NEW badge ( to be removed once we migrate all plugins to Hub) --

/**
* Creates a simple text-based icon for tabs.
* @param text {@link String} Text to display
* @param textColor {@link Color} Color of the text
* @param backgroundColor {@link Color} Background color (can be null for transparent)
* @param width Width of the icon
* @param height Height of the icon
* @return ImageIcon {@link ImageIcon} with rendered text
*/
private ImageIcon createTextIcon(String text, Color textColor, Color backgroundColor, int width, int height) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = image.createGraphics();

// Enable antialiasing for smoother text
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

// Set background (optional, can be transparent)
if (backgroundColor != null) {
g2d.setColor(backgroundColor);
g2d.fillRect(0, 0, width, height);
}

// Set font and text color
g2d.setFont(FontManager.getRunescapeBoldFont());
g2d.setColor(textColor);

// Calculate text position to center it
FontMetrics fm = g2d.getFontMetrics();
int textWidth = fm.stringWidth(text);
int textHeight = fm.getAscent();

int x = (width - textWidth) / 2;
int y = (height - textHeight) / 2 + textHeight;

g2d.drawString(text, x, y);
g2d.dispose();

return new ImageIcon(image);
}

@Inject
MicrobotTopLevelConfigPanel(
EventBus eventBus,
Expand All @@ -51,46 +221,48 @@ public class MicrobotTopLevelConfigPanel extends PluginPanel {
add(content, BorderLayout.CENTER);

this.pluginListPanel = pluginListPanel;
pluginListPanelTab = addTab(pluginListPanel.getMuxer(), "microbot_config_icon_lg.png", "Microbot Plugins");

addTab(microbotPluginHubPanelProvider, "plugin_hub_icon.png", "Microbot Hub");
// Create text-based icons instead of using image files for better clarity
ImageIcon installedIcon = createTextIcon("Installed", Color.YELLOW, null, 80, 32);
ImageIcon hubIcon = createTextIcon("Plugin Hub", Color.YELLOW, null, 80, 32);

pluginListPanelTab = addTab(pluginListPanel.getMuxer(), installedIcon, "Installed Microbot Plugins");
hubTab = addTab(microbotPluginHubPanelProvider, hubIcon, "Microbot Hub");


tabGroup.select(pluginListPanelTab);

// Create NEW badge overlay after UI is initialized (remove after migrating all plugins to hub)
SwingUtilities.invokeLater(this::createNewBadgeOverlay);
}

private MaterialTab addTab(PluginPanel panel, String image, String tooltip) {
MaterialTab mt = new MaterialTab(
new ImageIcon(ImageUtil.loadImageResource(MicrobotTopLevelConfigPanel.class, image)),
tabGroup, null);
private MaterialTab addTab(PluginPanel panel, ImageIcon icon, String tooltip) {
MaterialTab mt = new MaterialTab(icon, tabGroup, null);
mt.setToolTipText(tooltip);
tabGroup.addTab(mt);

content.add(image, panel.getWrappedPanel());
content.add(tooltip, panel.getWrappedPanel()); // Use tooltip as unique key instead of image name
eventBus.register(panel);

mt.setOnSelectEvent(() ->
{
switchTo(image, panel, false);
switchTo(tooltip, panel, false);
return true;
});
return mt;
}

private MaterialTab addTab(Provider<? extends PluginPanel> panelProvider, String image, String tooltip) {
MaterialTab mt = new MaterialTab(
new ImageIcon(ImageUtil.loadImageResource(MicrobotTopLevelConfigPanel.class, image)),
tabGroup, null);
private MaterialTab addTab(Provider<? extends PluginPanel> panelProvider, ImageIcon icon, String tooltip) {
MaterialTab mt = new MaterialTab(icon, tabGroup, null);
mt.setToolTipText(tooltip);
tabGroup.addTab(mt);

mt.setOnSelectEvent(() ->
{
PluginPanel panel = panelProvider.get();
content.add(image, panel.getWrappedPanel());
content.add(tooltip, panel.getWrappedPanel());
eventBus.register(panel);
switchTo(image, panel, true);
switchTo(tooltip, panel, true);
return true;
});
return mt;
Expand Down Expand Up @@ -121,12 +293,20 @@ private void switchTo(String cardName, PluginPanel panel, boolean removeOnTabCha
public void onActivate() {
active = true;
current.onActivate();
// BEGIN: NEW badge readd code (remove once we migrate all plugins to hub)
if (newBadgeTimer == null || glassPane == null) {
SwingUtilities.invokeLater(this::createNewBadgeOverlay);
}
// END: NEW badge readd code (remove once we migrate all plugins to hub)
}

@Override
public void onDeactivate() {
active = false;
current.onDeactivate();
// BEGIN: NEW badge clean up code (remove once we migrate all plugins to hub)
cleanupNewBadge();
// END: NEW badge clean up code (remove once we migrate all plugins to hub)
}

public void openConfigurationPanel(String name) {
Expand All @@ -143,4 +323,4 @@ public void openWithFilter(String filter) {
tabGroup.select(pluginListPanelTab);
pluginListPanel.openWithFilter(filter);
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.