Merge pull request #880 from deathbeam/cleanup-clientui
Cleanup ClientUI
This commit is contained in:
@@ -35,7 +35,6 @@ import java.applet.Applet;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import joptsimple.OptionParser;
|
import joptsimple.OptionParser;
|
||||||
import joptsimple.OptionSet;
|
import joptsimple.OptionSet;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -43,12 +42,11 @@ import net.runelite.api.Client;
|
|||||||
import net.runelite.client.account.SessionManager;
|
import net.runelite.client.account.SessionManager;
|
||||||
import net.runelite.client.chat.ChatMessageManager;
|
import net.runelite.client.chat.ChatMessageManager;
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.config.RuneLiteConfig;
|
|
||||||
import net.runelite.client.discord.DiscordService;
|
import net.runelite.client.discord.DiscordService;
|
||||||
import net.runelite.client.events.ClientUILoaded;
|
|
||||||
import net.runelite.client.menus.MenuManager;
|
import net.runelite.client.menus.MenuManager;
|
||||||
import net.runelite.client.plugins.PluginManager;
|
import net.runelite.client.plugins.PluginManager;
|
||||||
import net.runelite.client.ui.ClientUI;
|
import net.runelite.client.ui.ClientUI;
|
||||||
|
import net.runelite.client.ui.TitleToolbar;
|
||||||
import net.runelite.client.ui.overlay.OverlayRenderer;
|
import net.runelite.client.ui.overlay.OverlayRenderer;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.slf4j.MDC;
|
import org.slf4j.MDC;
|
||||||
@@ -66,9 +64,6 @@ public class RuneLite
|
|||||||
private static Injector injector;
|
private static Injector injector;
|
||||||
private static OptionSet options;
|
private static OptionSet options;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private RuneLiteProperties properties;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private PluginManager pluginManager;
|
private PluginManager pluginManager;
|
||||||
|
|
||||||
@@ -90,17 +85,19 @@ public class RuneLite
|
|||||||
@Inject
|
@Inject
|
||||||
private SessionManager sessionManager;
|
private SessionManager sessionManager;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private RuneLiteConfig runeliteConfig;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DiscordService discordService;
|
private DiscordService discordService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ClientSessionManager clientSessionManager;
|
private ClientSessionManager clientSessionManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ClientUI clientUI;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TitleToolbar titleToolbar;
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
ClientUI gui;
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception
|
public static void main(String[] args) throws Exception
|
||||||
{
|
{
|
||||||
@@ -147,8 +144,8 @@ public class RuneLite
|
|||||||
this.client = (Client) client;
|
this.client = (Client) client;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load swing UI
|
// Initialize UI
|
||||||
SwingUtilities.invokeAndWait(() -> setGui(ClientUI.create(this, properties, client)));
|
clientUI.init(client);
|
||||||
|
|
||||||
// Initialize Discord service
|
// Initialize Discord service
|
||||||
discordService.init();
|
discordService.init();
|
||||||
@@ -157,10 +154,10 @@ public class RuneLite
|
|||||||
configManager.load();
|
configManager.load();
|
||||||
|
|
||||||
// Register event listeners
|
// Register event listeners
|
||||||
|
eventBus.register(clientUI);
|
||||||
eventBus.register(overlayRenderer);
|
eventBus.register(overlayRenderer);
|
||||||
eventBus.register(menuManager);
|
eventBus.register(menuManager);
|
||||||
eventBus.register(chatMessageManager);
|
eventBus.register(chatMessageManager);
|
||||||
eventBus.register(gui);
|
|
||||||
eventBus.register(pluginManager);
|
eventBus.register(pluginManager);
|
||||||
|
|
||||||
// Tell the plugin manager if client is outdated or not
|
// Tell the plugin manager if client is outdated or not
|
||||||
@@ -183,28 +180,11 @@ public class RuneLite
|
|||||||
// Load the session, including saved configuration
|
// Load the session, including saved configuration
|
||||||
sessionManager.loadSession();
|
sessionManager.loadSession();
|
||||||
|
|
||||||
SwingUtilities.invokeAndWait(() ->
|
// Refresh title toolbar
|
||||||
{
|
titleToolbar.refresh();
|
||||||
if (client != null)
|
|
||||||
{
|
|
||||||
client.setSize(runeliteConfig.gameSize());
|
|
||||||
client.setPreferredSize(runeliteConfig.gameSize());
|
|
||||||
|
|
||||||
client.getParent().setPreferredSize(runeliteConfig.gameSize());
|
// Show UI after all plugins are loaded
|
||||||
client.getParent().setSize(runeliteConfig.gameSize());
|
clientUI.show();
|
||||||
}
|
|
||||||
|
|
||||||
gui.showWithChrome(runeliteConfig.enableCustomChrome());
|
|
||||||
|
|
||||||
if (gui.isAlwaysOnTopSupported())
|
|
||||||
{
|
|
||||||
gui.setAlwaysOnTop(runeliteConfig.gameAlwaysOnTop());
|
|
||||||
}
|
|
||||||
|
|
||||||
gui.setResizable(!runeliteConfig.lockWindowSize());
|
|
||||||
});
|
|
||||||
|
|
||||||
eventBus.post(new ClientUILoaded());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutdown()
|
public void shutdown()
|
||||||
@@ -213,11 +193,6 @@ public class RuneLite
|
|||||||
discordService.close();
|
discordService.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGui(ClientUI gui)
|
|
||||||
{
|
|
||||||
this.gui = gui;
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public void setClient(Client client)
|
public void setClient(Client client)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ import net.runelite.client.game.ItemManager;
|
|||||||
import net.runelite.client.menus.MenuManager;
|
import net.runelite.client.menus.MenuManager;
|
||||||
import net.runelite.client.plugins.PluginManager;
|
import net.runelite.client.plugins.PluginManager;
|
||||||
import net.runelite.client.task.Scheduler;
|
import net.runelite.client.task.Scheduler;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
import net.runelite.client.util.QueryRunner;
|
import net.runelite.client.util.QueryRunner;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -67,12 +66,6 @@ public class RuneLiteModule extends AbstractModule
|
|||||||
return runeLite.client;
|
return runeLite.client;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
|
||||||
ClientUI provideClientUi(RuneLite runelite)
|
|
||||||
{
|
|
||||||
return runelite.gui;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
RuneLiteConfig provideConfig(ConfigManager configManager)
|
RuneLiteConfig provideConfig(ConfigManager configManager)
|
||||||
|
|||||||
@@ -60,16 +60,14 @@ public class SessionManager
|
|||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private ConfigManager configManager;
|
private ConfigManager configManager;
|
||||||
private ScheduledExecutorService executor;
|
private ScheduledExecutorService executor;
|
||||||
private final LinkBrowser browser;
|
|
||||||
private final AccountClient loginClient = new AccountClient();
|
private final AccountClient loginClient = new AccountClient();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public SessionManager(ConfigManager configManager, EventBus eventBus, ScheduledExecutorService executor, LinkBrowser browser)
|
public SessionManager(ConfigManager configManager, EventBus eventBus, ScheduledExecutorService executor)
|
||||||
{
|
{
|
||||||
this.configManager = configManager;
|
this.configManager = configManager;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
this.browser = browser;
|
|
||||||
eventBus.register(this);
|
eventBus.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +211,7 @@ public class SessionManager
|
|||||||
openSession(new AccountSession(login.getUid(), Instant.now()));
|
openSession(new AccountSession(login.getUid(), Instant.now()));
|
||||||
|
|
||||||
// Navigate to login link
|
// Navigate to login link
|
||||||
browser.browse(login.getOauthUrl());
|
LinkBrowser.browse(login.getOauthUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.events;
|
||||||
|
|
||||||
|
import lombok.Value;
|
||||||
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
public class PluginToolbarButtonAdded
|
||||||
|
{
|
||||||
|
private NavigationButton button;
|
||||||
|
private int index;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.events;
|
||||||
|
|
||||||
|
import lombok.Value;
|
||||||
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
public class PluginToolbarButtonRemoved
|
||||||
|
{
|
||||||
|
private NavigationButton button;
|
||||||
|
private int index;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.events;
|
||||||
|
|
||||||
|
import lombok.Value;
|
||||||
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
public class TitleToolbarButtonAdded
|
||||||
|
{
|
||||||
|
private NavigationButton button;
|
||||||
|
private int index;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.events;
|
||||||
|
|
||||||
|
import lombok.Value;
|
||||||
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
public class TitleToolbarButtonRemoved
|
||||||
|
{
|
||||||
|
private NavigationButton button;
|
||||||
|
private int index;
|
||||||
|
}
|
||||||
@@ -25,22 +25,20 @@
|
|||||||
package net.runelite.client.plugins.account;
|
package net.runelite.client.plugins.account;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.events.SessionClose;
|
import net.runelite.api.events.SessionClose;
|
||||||
|
import net.runelite.api.events.SessionOpen;
|
||||||
import net.runelite.client.account.AccountSession;
|
import net.runelite.client.account.AccountSession;
|
||||||
import net.runelite.client.account.SessionManager;
|
import net.runelite.client.account.SessionManager;
|
||||||
import net.runelite.api.events.SessionOpen;
|
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.ui.ClientUI;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
import net.runelite.client.ui.TitleToolbar;
|
import net.runelite.client.ui.TitleToolbar;
|
||||||
import net.runelite.client.util.RunnableExceptionLogger;
|
import net.runelite.client.util.RunnableExceptionLogger;
|
||||||
|
|
||||||
@@ -55,13 +53,13 @@ public class AccountPlugin extends Plugin
|
|||||||
private SessionManager sessionManager;
|
private SessionManager sessionManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ClientUI ui;
|
private TitleToolbar titleToolbar;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ScheduledExecutorService executor;
|
private ScheduledExecutorService executor;
|
||||||
|
|
||||||
private JButton loginButton;
|
private NavigationButton loginButton;
|
||||||
private JButton logoutButton;
|
private NavigationButton logoutButton;
|
||||||
|
|
||||||
private static final BufferedImage LOGIN_IMAGE, LOGOUT_IMAGE;
|
private static final BufferedImage LOGIN_IMAGE, LOGOUT_IMAGE;
|
||||||
|
|
||||||
@@ -84,47 +82,45 @@ public class AccountPlugin extends Plugin
|
|||||||
@Override
|
@Override
|
||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
{
|
||||||
loginButton = new JButton();
|
loginButton = NavigationButton.builder()
|
||||||
loginButton.setToolTipText("Login");
|
.icon(LOGIN_IMAGE)
|
||||||
loginButton.addActionListener(this::loginClick);
|
.tooltip("Login")
|
||||||
|
.onClick(this::loginClick)
|
||||||
|
.build();
|
||||||
|
|
||||||
logoutButton = new JButton();
|
logoutButton = NavigationButton.builder()
|
||||||
logoutButton.setToolTipText("Logout");
|
.icon(LOGOUT_IMAGE)
|
||||||
logoutButton.addActionListener(this::logoutClick);
|
.tooltip("Logout")
|
||||||
|
.onClick(this::logoutClick)
|
||||||
|
.build();
|
||||||
|
|
||||||
addAndRemoveButtons();
|
addAndRemoveButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAndRemoveButtons()
|
private void addAndRemoveButtons()
|
||||||
{
|
{
|
||||||
TitleToolbar tb = ui.getTitleToolbar();
|
titleToolbar.removeNavigation(loginButton);
|
||||||
tb.remove(loginButton);
|
titleToolbar.removeNavigation(logoutButton);
|
||||||
tb.remove(logoutButton);
|
titleToolbar.addNavigation(sessionManager.getAccountSession() == null
|
||||||
if (sessionManager.getAccountSession() == null)
|
? loginButton
|
||||||
{
|
: logoutButton);
|
||||||
tb.addButton(loginButton, LOGIN_IMAGE, LOGIN_IMAGE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tb.addButton(logoutButton, LOGOUT_IMAGE, LOGOUT_IMAGE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutDown() throws Exception
|
protected void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
ui.getTitleToolbar().remove(loginButton);
|
titleToolbar.removeNavigation(loginButton);
|
||||||
ui.getTitleToolbar().remove(logoutButton);
|
titleToolbar.removeNavigation(logoutButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loginClick(ActionEvent ae)
|
private void loginClick()
|
||||||
{
|
{
|
||||||
executor.execute(RunnableExceptionLogger.wrap(sessionManager::login));
|
executor.execute(RunnableExceptionLogger.wrap(sessionManager::login));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logoutClick(ActionEvent ae)
|
private void logoutClick()
|
||||||
{
|
{
|
||||||
if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(ui,
|
if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(null,
|
||||||
"Are you sure you want to logout?", "Logout Confirmation",
|
"Are you sure you want to logout?", "Logout Confirmation",
|
||||||
JOptionPane.YES_NO_OPTION))
|
JOptionPane.YES_NO_OPTION))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ import net.runelite.client.events.PluginChanged;
|
|||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.plugins.PluginManager;
|
import net.runelite.client.plugins.PluginManager;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
import net.runelite.client.ui.PluginToolbar;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Configuration",
|
name = "Configuration",
|
||||||
@@ -47,7 +47,7 @@ import net.runelite.client.ui.NavigationButton;
|
|||||||
public class ConfigPlugin extends Plugin
|
public class ConfigPlugin extends Plugin
|
||||||
{
|
{
|
||||||
@Inject
|
@Inject
|
||||||
private ClientUI ui;
|
private PluginToolbar pluginToolbar;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ConfigManager configManager;
|
private ConfigManager configManager;
|
||||||
@@ -75,18 +75,19 @@ public class ConfigPlugin extends Plugin
|
|||||||
icon = ImageIO.read(getClass().getResourceAsStream("config_icon.png"));
|
icon = ImageIO.read(getClass().getResourceAsStream("config_icon.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
navButton = new NavigationButton(
|
navButton = NavigationButton.builder()
|
||||||
"Configuration",
|
.name("Configuration")
|
||||||
icon,
|
.icon(icon)
|
||||||
() -> configPanel);
|
.panel(configPanel)
|
||||||
|
.build();
|
||||||
|
|
||||||
ui.getPluginToolbar().addNavigation(navButton);
|
pluginToolbar.addNavigation(navButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutDown() throws Exception
|
protected void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
ui.getPluginToolbar().removeNavigation(navButton);
|
pluginToolbar.removeNavigation(navButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ import net.runelite.api.widgets.Widget;
|
|||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
import net.runelite.client.ui.FontManager;
|
import net.runelite.client.ui.FontManager;
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
import net.runelite.client.ui.PluginToolbar;
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
@@ -47,7 +47,7 @@ import net.runelite.client.ui.overlay.Overlay;
|
|||||||
public class DevToolsPlugin extends Plugin
|
public class DevToolsPlugin extends Plugin
|
||||||
{
|
{
|
||||||
@Inject
|
@Inject
|
||||||
private ClientUI ui;
|
private PluginToolbar pluginToolbar;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DevToolsOverlay overlay;
|
private DevToolsOverlay overlay;
|
||||||
@@ -89,12 +89,13 @@ public class DevToolsPlugin extends Plugin
|
|||||||
icon = ImageIO.read(getClass().getResourceAsStream("devtools_icon.png"));
|
icon = ImageIO.read(getClass().getResourceAsStream("devtools_icon.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
navButton = new NavigationButton(
|
navButton = NavigationButton.builder()
|
||||||
"Developer Tools",
|
.name("Developer Tools")
|
||||||
icon,
|
.icon(icon)
|
||||||
() -> panel);
|
.panel(panel)
|
||||||
|
.build();
|
||||||
|
|
||||||
ui.getPluginToolbar().addNavigation(navButton);
|
pluginToolbar.addNavigation(navButton);
|
||||||
|
|
||||||
font = FontManager.getRunescapeFont()
|
font = FontManager.getRunescapeFont()
|
||||||
.deriveFont(Font.BOLD, 16);
|
.deriveFont(Font.BOLD, 16);
|
||||||
@@ -103,7 +104,7 @@ public class DevToolsPlugin extends Plugin
|
|||||||
@Override
|
@Override
|
||||||
protected void shutDown() throws Exception
|
protected void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
ui.getPluginToolbar().removeNavigation(navButton);
|
pluginToolbar.removeNavigation(navButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -27,19 +27,25 @@ package net.runelite.client.plugins.discord;
|
|||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.api.GameState;
|
import net.runelite.api.GameState;
|
||||||
import net.runelite.api.Skill;
|
import net.runelite.api.Skill;
|
||||||
import net.runelite.api.events.ExperienceChanged;
|
import net.runelite.api.events.ExperienceChanged;
|
||||||
import net.runelite.api.events.GameStateChanged;
|
import net.runelite.api.events.GameStateChanged;
|
||||||
|
import net.runelite.client.RuneLiteProperties;
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.discord.DiscordService;
|
import net.runelite.client.discord.DiscordService;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.task.Schedule;
|
import net.runelite.client.task.Schedule;
|
||||||
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
import net.runelite.client.ui.TitleToolbar;
|
||||||
|
import net.runelite.client.util.LinkBrowser;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Discord"
|
name = "Discord"
|
||||||
@@ -55,9 +61,16 @@ public class DiscordPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private DiscordService discordService;
|
private DiscordService discordService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TitleToolbar titleToolbar;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RuneLiteProperties properties;
|
||||||
|
|
||||||
private final DiscordState discordState = new DiscordState();
|
private final DiscordState discordState = new DiscordState();
|
||||||
private Map<Skill, Integer> skillExp = new HashMap<>();
|
private Map<Skill, Integer> skillExp = new HashMap<>();
|
||||||
private boolean loggedIn = false;
|
private boolean loggedIn = false;
|
||||||
|
private NavigationButton discordButton;
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
private DiscordConfig provideConfig(ConfigManager configManager)
|
private DiscordConfig provideConfig(ConfigManager configManager)
|
||||||
@@ -68,12 +81,26 @@ public class DiscordPlugin extends Plugin
|
|||||||
@Override
|
@Override
|
||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
{
|
||||||
|
BufferedImage icon;
|
||||||
|
synchronized (ImageIO.class)
|
||||||
|
{
|
||||||
|
icon = ImageIO.read(getClass().getResourceAsStream("discord.png"));
|
||||||
|
}
|
||||||
|
|
||||||
|
discordButton = NavigationButton.builder()
|
||||||
|
.tooltip("Join Discord")
|
||||||
|
.icon(icon)
|
||||||
|
.onClick(() -> LinkBrowser.browse(properties.getDiscordInvite()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
titleToolbar.addNavigation(discordButton);
|
||||||
updateGameStatus(client.getGameState(), true);
|
updateGameStatus(client.getGameState(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutDown() throws Exception
|
protected void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
|
titleToolbar.removeNavigation(discordButton);
|
||||||
discordService.clearPresence();
|
discordService.clearPresence();
|
||||||
discordState.reset();
|
discordState.reset();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,13 +120,11 @@ class FeedPanel extends PluginPanel
|
|||||||
|
|
||||||
private final FeedConfig config;
|
private final FeedConfig config;
|
||||||
private final Supplier<FeedResult> feedSupplier;
|
private final Supplier<FeedResult> feedSupplier;
|
||||||
private final LinkBrowser linkBrowser;
|
|
||||||
|
|
||||||
FeedPanel(FeedConfig config, Supplier<FeedResult> feedSupplier, LinkBrowser linkBrowser)
|
FeedPanel(FeedConfig config, Supplier<FeedResult> feedSupplier)
|
||||||
{
|
{
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.feedSupplier = feedSupplier;
|
this.feedSupplier = feedSupplier;
|
||||||
this.linkBrowser = linkBrowser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rebuildFeed()
|
void rebuildFeed()
|
||||||
@@ -294,7 +292,7 @@ class FeedPanel extends PluginPanel
|
|||||||
public void mouseReleased(MouseEvent e)
|
public void mouseReleased(MouseEvent e)
|
||||||
{
|
{
|
||||||
avatarAndRight.setBackground(hoverColor);
|
avatarAndRight.setBackground(hoverColor);
|
||||||
linkBrowser.browse(item.getUrl());
|
LinkBrowser.browse(item.getUrl());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -41,9 +41,8 @@ import net.runelite.client.config.ConfigManager;
|
|||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.task.Schedule;
|
import net.runelite.client.task.Schedule;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
import net.runelite.client.util.LinkBrowser;
|
import net.runelite.client.ui.PluginToolbar;
|
||||||
import net.runelite.http.api.feed.FeedClient;
|
import net.runelite.http.api.feed.FeedClient;
|
||||||
import net.runelite.http.api.feed.FeedResult;
|
import net.runelite.http.api.feed.FeedResult;
|
||||||
|
|
||||||
@@ -55,7 +54,7 @@ import net.runelite.http.api.feed.FeedResult;
|
|||||||
public class FeedPlugin extends Plugin
|
public class FeedPlugin extends Plugin
|
||||||
{
|
{
|
||||||
@Inject
|
@Inject
|
||||||
private ClientUI ui;
|
private PluginToolbar pluginToolbar;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private FeedConfig config;
|
private FeedConfig config;
|
||||||
@@ -63,9 +62,6 @@ public class FeedPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private ScheduledExecutorService executorService;
|
private ScheduledExecutorService executorService;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private LinkBrowser linkBrowser;
|
|
||||||
|
|
||||||
private FeedPanel feedPanel;
|
private FeedPanel feedPanel;
|
||||||
private NavigationButton navButton;
|
private NavigationButton navButton;
|
||||||
|
|
||||||
@@ -86,7 +82,7 @@ public class FeedPlugin extends Plugin
|
|||||||
@Override
|
@Override
|
||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
{
|
||||||
feedPanel = new FeedPanel(config, feedSupplier, linkBrowser);
|
feedPanel = new FeedPanel(config, feedSupplier);
|
||||||
|
|
||||||
BufferedImage icon;
|
BufferedImage icon;
|
||||||
synchronized (ImageIO.class)
|
synchronized (ImageIO.class)
|
||||||
@@ -94,20 +90,20 @@ public class FeedPlugin extends Plugin
|
|||||||
icon = ImageIO.read(getClass().getResourceAsStream("icon.png"));
|
icon = ImageIO.read(getClass().getResourceAsStream("icon.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
navButton = new NavigationButton(
|
navButton = NavigationButton.builder()
|
||||||
"News Feed",
|
.name("News Feed")
|
||||||
icon,
|
.icon(icon)
|
||||||
() -> feedPanel);
|
.panel(feedPanel)
|
||||||
|
.build();
|
||||||
ui.getPluginToolbar().addNavigation(navButton);
|
|
||||||
|
|
||||||
|
pluginToolbar.addNavigation(navButton);
|
||||||
executorService.submit(this::updateFeed);
|
executorService.submit(this::updateFeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutDown() throws Exception
|
protected void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
ui.getPluginToolbar().removeNavigation(navButton);
|
pluginToolbar.removeNavigation(navButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFeed()
|
private void updateFeed()
|
||||||
|
|||||||
@@ -45,10 +45,9 @@ import net.runelite.client.util.LinkBrowser;
|
|||||||
class GrandExchangeItemPanel extends JPanel
|
class GrandExchangeItemPanel extends JPanel
|
||||||
{
|
{
|
||||||
private static final NumberFormat NUMBER_FORMATTER = NumberFormat.getInstance();
|
private static final NumberFormat NUMBER_FORMATTER = NumberFormat.getInstance();
|
||||||
|
|
||||||
private static final Dimension ICON_SIZE = new Dimension(32, 32);
|
private static final Dimension ICON_SIZE = new Dimension(32, 32);
|
||||||
|
|
||||||
GrandExchangeItemPanel(LinkBrowser linkBrowser, BufferedImage icon, String name, int itemID, int gePrice, Double
|
GrandExchangeItemPanel(BufferedImage icon, String name, int itemID, int gePrice, Double
|
||||||
haPrice)
|
haPrice)
|
||||||
{
|
{
|
||||||
BorderLayout layout = new BorderLayout();
|
BorderLayout layout = new BorderLayout();
|
||||||
@@ -75,7 +74,7 @@ class GrandExchangeItemPanel extends JPanel
|
|||||||
@Override
|
@Override
|
||||||
public void mouseReleased(MouseEvent e)
|
public void mouseReleased(MouseEvent e)
|
||||||
{
|
{
|
||||||
geLink(linkBrowser, name, itemID);
|
geLink(name, itemID);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -125,13 +124,13 @@ class GrandExchangeItemPanel extends JPanel
|
|||||||
add(rightPanel, BorderLayout.CENTER);
|
add(rightPanel, BorderLayout.CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void geLink(LinkBrowser linkBrowser, String name, int itemID)
|
private void geLink(String name, int itemID)
|
||||||
{
|
{
|
||||||
final String url = "http://services.runescape.com/m=itemdb_oldschool/"
|
final String url = "http://services.runescape.com/m=itemdb_oldschool/"
|
||||||
+ name.replaceAll(" ", "_")
|
+ name.replaceAll(" ", "_")
|
||||||
+ "/viewitem?obj="
|
+ "/viewitem?obj="
|
||||||
+ itemID;
|
+ itemID;
|
||||||
|
|
||||||
linkBrowser.browse(url);
|
LinkBrowser.browse(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import net.runelite.api.Client;
|
|||||||
import net.runelite.api.GrandExchangeOffer;
|
import net.runelite.api.GrandExchangeOffer;
|
||||||
import net.runelite.client.game.ItemManager;
|
import net.runelite.client.game.ItemManager;
|
||||||
import net.runelite.client.ui.PluginPanel;
|
import net.runelite.client.ui.PluginPanel;
|
||||||
import net.runelite.client.util.LinkBrowser;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
class GrandExchangePanel extends PluginPanel
|
class GrandExchangePanel extends PluginPanel
|
||||||
@@ -54,7 +53,7 @@ class GrandExchangePanel extends PluginPanel
|
|||||||
private JTabbedPane tabbedPane = new JTabbedPane();
|
private JTabbedPane tabbedPane = new JTabbedPane();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GrandExchangePanel(Client client, ItemManager itemManager, ScheduledExecutorService executor, LinkBrowser linkBrowser)
|
GrandExchangePanel(Client client, ItemManager itemManager, ScheduledExecutorService executor)
|
||||||
{
|
{
|
||||||
setLayout(new BorderLayout());
|
setLayout(new BorderLayout());
|
||||||
add(tabbedPane, BorderLayout.NORTH);
|
add(tabbedPane, BorderLayout.NORTH);
|
||||||
@@ -68,7 +67,7 @@ class GrandExchangePanel extends PluginPanel
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Search Panel
|
// Search Panel
|
||||||
searchPanel = new GrandExchangeSearchPanel(client, itemManager, executor, linkBrowser);
|
searchPanel = new GrandExchangeSearchPanel(client, itemManager, executor);
|
||||||
|
|
||||||
tabbedPane.addTab("Offers", offerPanel);
|
tabbedPane.addTab("Offers", offerPanel);
|
||||||
tabbedPane.addTab("Search", searchPanel);
|
tabbedPane.addTab("Search", searchPanel);
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ import net.runelite.client.input.MouseListener;
|
|||||||
import net.runelite.client.input.MouseManager;
|
import net.runelite.client.input.MouseManager;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
import net.runelite.client.ui.PluginToolbar;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Grand Exchange"
|
name = "Grand Exchange"
|
||||||
@@ -69,7 +69,7 @@ public class GrandExchangePlugin extends Plugin
|
|||||||
private Client client;
|
private Client client;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ClientUI ui;
|
private PluginToolbar pluginToolbar;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private GrandExchangeConfig config;
|
private GrandExchangeConfig config;
|
||||||
@@ -84,13 +84,20 @@ public class GrandExchangePlugin extends Plugin
|
|||||||
protected void startUp() throws IOException
|
protected void startUp() throws IOException
|
||||||
{
|
{
|
||||||
panel = injector.getInstance(GrandExchangePanel.class);
|
panel = injector.getInstance(GrandExchangePanel.class);
|
||||||
|
|
||||||
BufferedImage icon;
|
BufferedImage icon;
|
||||||
synchronized (ImageIO.class)
|
synchronized (ImageIO.class)
|
||||||
{
|
{
|
||||||
icon = ImageIO.read(getClass().getResourceAsStream("ge_icon.png"));
|
icon = ImageIO.read(getClass().getResourceAsStream("ge_icon.png"));
|
||||||
}
|
}
|
||||||
button = new NavigationButton("GE Offers", icon, () -> panel);
|
|
||||||
ui.getPluginToolbar().addNavigation(button);
|
button = NavigationButton.builder()
|
||||||
|
.name("GE Offers")
|
||||||
|
.icon(icon)
|
||||||
|
.panel(panel)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
pluginToolbar.addNavigation(button);
|
||||||
|
|
||||||
itemClick = new MouseListener()
|
itemClick = new MouseListener()
|
||||||
{
|
{
|
||||||
@@ -119,7 +126,8 @@ public class GrandExchangePlugin extends Plugin
|
|||||||
|
|
||||||
if (!button.isSelected())
|
if (!button.isSelected())
|
||||||
{
|
{
|
||||||
button.doClick();
|
button.setSelected(true);
|
||||||
|
button.getOnSelect().run();
|
||||||
}
|
}
|
||||||
|
|
||||||
panel.getSearchPanel().priceLookup(itemComp.getName());
|
panel.getSearchPanel().priceLookup(itemComp.getName());
|
||||||
@@ -145,8 +153,7 @@ public class GrandExchangePlugin extends Plugin
|
|||||||
@Override
|
@Override
|
||||||
protected void shutDown()
|
protected void shutDown()
|
||||||
{
|
{
|
||||||
ui.getPluginToolbar().removeNavigation(button);
|
pluginToolbar.removeNavigation(button);
|
||||||
|
|
||||||
mouseManager.unregisterMouseListener(itemClick);
|
mouseManager.unregisterMouseListener(itemClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,10 +179,6 @@ public class GrandExchangePlugin extends Plugin
|
|||||||
@Subscribe
|
@Subscribe
|
||||||
public void onGrandExchangeOfferChanged(GrandExchangeOfferChanged offerEvent)
|
public void onGrandExchangeOfferChanged(GrandExchangeOfferChanged offerEvent)
|
||||||
{
|
{
|
||||||
SwingUtilities.invokeLater(() ->
|
SwingUtilities.invokeLater(() -> panel.updateOffer(offerEvent.getOffer(), offerEvent.getSlot()));
|
||||||
{
|
|
||||||
panel.updateOffer(offerEvent.getOffer(), offerEvent.getSlot());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ import net.runelite.api.Client;
|
|||||||
import net.runelite.api.ItemComposition;
|
import net.runelite.api.ItemComposition;
|
||||||
import net.runelite.client.game.ItemManager;
|
import net.runelite.client.game.ItemManager;
|
||||||
import net.runelite.client.plugins.hiscore.IconTextField;
|
import net.runelite.client.plugins.hiscore.IconTextField;
|
||||||
import net.runelite.client.util.LinkBrowser;
|
|
||||||
import net.runelite.http.api.item.Item;
|
import net.runelite.http.api.item.Item;
|
||||||
import net.runelite.http.api.item.ItemClient;
|
import net.runelite.http.api.item.ItemClient;
|
||||||
import net.runelite.http.api.item.ItemPrice;
|
import net.runelite.http.api.item.ItemPrice;
|
||||||
@@ -60,7 +59,6 @@ class GrandExchangeSearchPanel extends JPanel
|
|||||||
private final Client client;
|
private final Client client;
|
||||||
private final ItemManager itemManager;
|
private final ItemManager itemManager;
|
||||||
private final ScheduledExecutorService executor;
|
private final ScheduledExecutorService executor;
|
||||||
private final LinkBrowser linkBrowser;
|
|
||||||
|
|
||||||
private ItemClient itemClient;
|
private ItemClient itemClient;
|
||||||
|
|
||||||
@@ -71,12 +69,11 @@ class GrandExchangeSearchPanel extends JPanel
|
|||||||
private JPanel searchItemsPanel = new JPanel();
|
private JPanel searchItemsPanel = new JPanel();
|
||||||
private JLabel searchingLabel = new JLabel();
|
private JLabel searchingLabel = new JLabel();
|
||||||
|
|
||||||
GrandExchangeSearchPanel(Client client, ItemManager itemManager, ScheduledExecutorService executor, LinkBrowser linkBrowser)
|
GrandExchangeSearchPanel(Client client, ItemManager itemManager, ScheduledExecutorService executor)
|
||||||
{
|
{
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.itemManager = itemManager;
|
this.itemManager = itemManager;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
this.linkBrowser = linkBrowser;
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +200,7 @@ class GrandExchangeSearchPanel extends JPanel
|
|||||||
{
|
{
|
||||||
for (GrandExchangeItems item : ITEMS_LIST)
|
for (GrandExchangeItems item : ITEMS_LIST)
|
||||||
{
|
{
|
||||||
GrandExchangeItemPanel panel = new GrandExchangeItemPanel(linkBrowser, item.getIcon(), item.getName(),
|
GrandExchangeItemPanel panel = new GrandExchangeItemPanel(item.getIcon(), item.getName(),
|
||||||
item.getItemId(), item.getGePrice(), item.getHaPrice());
|
item.getItemId(), item.getGePrice(), item.getHaPrice());
|
||||||
|
|
||||||
searchItemsPanel.add(panel);
|
searchItemsPanel.add(panel);
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ import net.runelite.client.config.ConfigManager;
|
|||||||
import net.runelite.client.menus.MenuManager;
|
import net.runelite.client.menus.MenuManager;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
import net.runelite.client.ui.PluginToolbar;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "HiScore",
|
name = "HiScore",
|
||||||
@@ -50,7 +50,7 @@ public class HiscorePlugin extends Plugin
|
|||||||
private static final String LOOKUP = "Lookup";
|
private static final String LOOKUP = "Lookup";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ClientUI ui;
|
private PluginToolbar pluginToolbar;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private MenuManager menuManager;
|
private MenuManager menuManager;
|
||||||
@@ -81,12 +81,13 @@ public class HiscorePlugin extends Plugin
|
|||||||
icon = ImageIO.read(getClass().getResourceAsStream("hiscore.gif"));
|
icon = ImageIO.read(getClass().getResourceAsStream("hiscore.gif"));
|
||||||
}
|
}
|
||||||
|
|
||||||
navButton = new NavigationButton(
|
navButton = NavigationButton.builder()
|
||||||
"Hiscore",
|
.name("Hiscore")
|
||||||
icon,
|
.icon(icon)
|
||||||
() -> hiscorePanel);
|
.panel(hiscorePanel)
|
||||||
|
.build();
|
||||||
|
|
||||||
ui.getPluginToolbar().addNavigation(navButton);
|
pluginToolbar.addNavigation(navButton);
|
||||||
|
|
||||||
if (config.playerOption())
|
if (config.playerOption())
|
||||||
{
|
{
|
||||||
@@ -97,8 +98,7 @@ public class HiscorePlugin extends Plugin
|
|||||||
@Override
|
@Override
|
||||||
protected void shutDown() throws Exception
|
protected void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
ui.getPluginToolbar().removeNavigation(navButton);
|
pluginToolbar.removeNavigation(navButton);
|
||||||
|
|
||||||
menuManager.removePlayerMenuItem(LOOKUP);
|
menuManager.removePlayerMenuItem(LOOKUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +129,8 @@ public class HiscorePlugin extends Plugin
|
|||||||
{
|
{
|
||||||
if (!navButton.isSelected())
|
if (!navButton.isSelected())
|
||||||
{
|
{
|
||||||
navButton.doClick();
|
navButton.setSelected(true);
|
||||||
|
navButton.getOnSelect().run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,15 +26,15 @@ package net.runelite.client.plugins.info;
|
|||||||
|
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.awt.Font;
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.awt.Font;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import javax.inject.Singleton;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.GroupLayout;
|
import javax.swing.GroupLayout;
|
||||||
|
import javax.swing.JButton;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.LayoutStyle;
|
import javax.swing.LayoutStyle;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.event.HyperlinkEvent;
|
import javax.swing.event.HyperlinkEvent;
|
||||||
@@ -46,23 +46,25 @@ import net.runelite.client.RuneLiteProperties;
|
|||||||
import net.runelite.client.account.SessionManager;
|
import net.runelite.client.account.SessionManager;
|
||||||
import net.runelite.client.config.RuneLiteConfig;
|
import net.runelite.client.config.RuneLiteConfig;
|
||||||
import net.runelite.client.events.ClientUILoaded;
|
import net.runelite.client.events.ClientUILoaded;
|
||||||
import net.runelite.client.ui.ClientUI;
|
import net.runelite.client.events.TitleToolbarButtonAdded;
|
||||||
|
import net.runelite.client.events.TitleToolbarButtonRemoved;
|
||||||
|
import net.runelite.client.ui.ClientTitleToolbar;
|
||||||
import net.runelite.client.ui.FontManager;
|
import net.runelite.client.ui.FontManager;
|
||||||
import net.runelite.client.ui.PluginPanel;
|
import net.runelite.client.ui.PluginPanel;
|
||||||
import net.runelite.client.util.RunnableExceptionLogger;
|
import net.runelite.client.util.RunnableExceptionLogger;
|
||||||
|
import net.runelite.client.util.SwingUtil;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Singleton
|
||||||
public class InfoPanel extends PluginPanel
|
public class InfoPanel extends PluginPanel
|
||||||
{
|
{
|
||||||
private final static String RUNELITE_LOGIN = "https://runelite_login/";
|
private static final int TITLEBAR_SIZE = 23;
|
||||||
|
private static final String RUNELITE_LOGIN = "https://runelite_login/";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@Nullable
|
@Nullable
|
||||||
private Client client;
|
private Client client;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ClientUI clientUI;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private RuneLiteConfig runeliteConfig;
|
private RuneLiteConfig runeliteConfig;
|
||||||
|
|
||||||
@@ -79,9 +81,7 @@ public class InfoPanel extends PluginPanel
|
|||||||
private ScheduledExecutorService executor;
|
private ScheduledExecutorService executor;
|
||||||
|
|
||||||
private final GroupLayout layout = new GroupLayout(this);
|
private final GroupLayout layout = new GroupLayout(this);
|
||||||
|
private final ClientTitleToolbar titleBar = new ClientTitleToolbar();
|
||||||
private final JPanel toolbarPanelPlaceholder = new JPanel();
|
|
||||||
|
|
||||||
private final JLabel usernameHeader = new JLabel();
|
private final JLabel usernameHeader = new JLabel();
|
||||||
private final JRichTextPane username = new JRichTextPane();
|
private final JRichTextPane username = new JRichTextPane();
|
||||||
|
|
||||||
@@ -90,8 +90,7 @@ public class InfoPanel extends PluginPanel
|
|||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
final Font smallFont = FontManager.getRunescapeSmallFont();
|
final Font smallFont = FontManager.getRunescapeSmallFont();
|
||||||
|
updateTitleBar();
|
||||||
toolbarPanelPlaceholder.setVisible(false);
|
|
||||||
|
|
||||||
final JLabel runeliteVersionHeader = new JLabel("RuneLite version");
|
final JLabel runeliteVersionHeader = new JLabel("RuneLite version");
|
||||||
runeliteVersionHeader.setFont(smallFont);
|
runeliteVersionHeader.setFont(smallFont);
|
||||||
@@ -119,7 +118,8 @@ public class InfoPanel extends PluginPanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setNotLoggedIn();
|
|
||||||
|
updateLoggedIn();
|
||||||
|
|
||||||
final JRichTextPane issueLink = new JRichTextPane("text/html",
|
final JRichTextPane issueLink = new JRichTextPane("text/html",
|
||||||
"RuneLite is open source!<br>"
|
"RuneLite is open source!<br>"
|
||||||
@@ -132,7 +132,7 @@ public class InfoPanel extends PluginPanel
|
|||||||
setBorder(BorderFactory.createEmptyBorder(2, 6, 6, 6));
|
setBorder(BorderFactory.createEmptyBorder(2, 6, 6, 6));
|
||||||
|
|
||||||
layout.setVerticalGroup(layout.createSequentialGroup()
|
layout.setVerticalGroup(layout.createSequentialGroup()
|
||||||
.addComponent(toolbarPanelPlaceholder)
|
.addComponent(titleBar)
|
||||||
.addGap(3)
|
.addGap(3)
|
||||||
.addGroup(layout.createParallelGroup()
|
.addGroup(layout.createParallelGroup()
|
||||||
.addComponent(runeliteVersionHeader)
|
.addComponent(runeliteVersionHeader)
|
||||||
@@ -152,16 +152,15 @@ public class InfoPanel extends PluginPanel
|
|||||||
layout.setHorizontalGroup(layout.createParallelGroup()
|
layout.setHorizontalGroup(layout.createParallelGroup()
|
||||||
.addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
|
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
|
||||||
.addComponent(toolbarPanelPlaceholder)
|
.addComponent(titleBar))
|
||||||
).addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(runeliteVersionHeader)
|
.addComponent(runeliteVersionHeader)
|
||||||
.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
|
.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
|
||||||
.addComponent(runescapeVersionHeader)
|
.addComponent(runescapeVersionHeader))
|
||||||
).addGroup(layout.createSequentialGroup()
|
.addGroup(layout.createSequentialGroup()
|
||||||
.addComponent(runeliteVersion)
|
.addComponent(runeliteVersion)
|
||||||
.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
|
.addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
|
||||||
.addComponent(runescapeVersion)
|
.addComponent(runescapeVersion))
|
||||||
)
|
|
||||||
.addComponent(usernameHeader)
|
.addComponent(usernameHeader)
|
||||||
.addComponent(username)
|
.addComponent(username)
|
||||||
.addComponent(issueLink)
|
.addComponent(issueLink)
|
||||||
@@ -170,50 +169,81 @@ public class InfoPanel extends PluginPanel
|
|||||||
eventBus.register(this);
|
eventBus.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setNotLoggedIn()
|
private void updateLoggedIn()
|
||||||
{
|
{
|
||||||
username.setContentType("text/html");
|
final String name = sessionManager.getAccountSession() != null
|
||||||
username.setText("<a href=\"" + RUNELITE_LOGIN + "\">Login</a> to sync settings to the cloud.");
|
? sessionManager.getAccountSession().getUsername()
|
||||||
usernameHeader.setText("Not logged in");
|
: null;
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
private void onClientUILoaded(ClientUILoaded e)
|
|
||||||
{
|
|
||||||
// Add the title toolbar to the infopanel if the custom chrome is disabled
|
|
||||||
if (!runeliteConfig.enableCustomChrome())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
SwingUtilities.invokeAndWait(() ->
|
|
||||||
{
|
|
||||||
JPanel toolbar = clientUI.getTitleToolbar();
|
|
||||||
layout.replace(toolbarPanelPlaceholder, toolbar);
|
|
||||||
toolbar.revalidate();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (InterruptedException | InvocationTargetException ex)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Subscribe
|
|
||||||
public void onSessionOpen(SessionOpen sessionOpen)
|
|
||||||
{
|
|
||||||
String name = sessionManager.getAccountSession().getUsername();
|
|
||||||
if (name != null)
|
if (name != null)
|
||||||
{
|
{
|
||||||
username.setContentType("text/plain");
|
username.setContentType("text/plain");
|
||||||
username.setText(name);
|
username.setText(name);
|
||||||
usernameHeader.setText("Logged in as");
|
usernameHeader.setText("Logged in as");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
username.setContentType("text/html");
|
||||||
|
username.setText("<a href=\"" + RUNELITE_LOGIN + "\">Login</a> to sync settings to the cloud.");
|
||||||
|
usernameHeader.setText("Not logged in");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTitleBar()
|
||||||
|
{
|
||||||
|
titleBar.setVisible(!runeliteConfig.enableCustomChrome());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void onSessionClose(SessionClose e)
|
public void onClientUILoaded(ClientUILoaded e)
|
||||||
{
|
{
|
||||||
setNotLoggedIn();
|
// Add the title toolbar to the infopanel if the custom chrome is disabled
|
||||||
|
updateTitleBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onSessionOpen(SessionOpen sessionOpen)
|
||||||
|
{
|
||||||
|
updateLoggedIn();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onSessionClose(SessionClose e)
|
||||||
|
{
|
||||||
|
updateLoggedIn();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onTitleToolbarButtonAdded(TitleToolbarButtonAdded event)
|
||||||
|
{
|
||||||
|
if (runeliteConfig.enableCustomChrome())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(() ->
|
||||||
|
{
|
||||||
|
final int iconSize = TITLEBAR_SIZE - 6;
|
||||||
|
final JButton button = SwingUtil.createSwingButton(event.getButton(), iconSize, null);
|
||||||
|
titleBar.addComponent(event.getButton(), button);
|
||||||
|
titleBar.revalidate();
|
||||||
|
titleBar.repaint();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onTitleToolbarButtonRemoved(TitleToolbarButtonRemoved event)
|
||||||
|
{
|
||||||
|
if (runeliteConfig.enableCustomChrome())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater(() ->
|
||||||
|
{
|
||||||
|
titleBar.removeComponent(event.getButton());
|
||||||
|
titleBar.revalidate();
|
||||||
|
titleBar.repaint();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,12 @@ package net.runelite.client.plugins.info;
|
|||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import net.runelite.client.config.RuneLiteConfig;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
import net.runelite.client.ui.PluginToolbar;
|
||||||
|
import net.runelite.client.ui.TitleToolbar;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Info Panel",
|
name = "Info Panel",
|
||||||
@@ -39,7 +41,13 @@ import net.runelite.client.ui.NavigationButton;
|
|||||||
public class InfoPlugin extends Plugin
|
public class InfoPlugin extends Plugin
|
||||||
{
|
{
|
||||||
@Inject
|
@Inject
|
||||||
private ClientUI ui;
|
private PluginToolbar pluginToolbar;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TitleToolbar titleToolbar;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RuneLiteConfig runeLiteConfig;
|
||||||
|
|
||||||
private NavigationButton navButton;
|
private NavigationButton navButton;
|
||||||
|
|
||||||
@@ -55,18 +63,23 @@ public class InfoPlugin extends Plugin
|
|||||||
icon = ImageIO.read(getClass().getResourceAsStream("info_icon.png"));
|
icon = ImageIO.read(getClass().getResourceAsStream("info_icon.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
navButton = new NavigationButton(
|
navButton = NavigationButton.builder()
|
||||||
"Info",
|
.name("Info")
|
||||||
icon,
|
.icon(icon)
|
||||||
() -> panel
|
.panel(panel)
|
||||||
);
|
.build();
|
||||||
|
|
||||||
ui.getPluginToolbar().addNavigation(navButton);
|
pluginToolbar.addNavigation(navButton);
|
||||||
|
|
||||||
|
if (!runeLiteConfig.enableCustomChrome())
|
||||||
|
{
|
||||||
|
titleToolbar.refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutDown()
|
protected void shutDown()
|
||||||
{
|
{
|
||||||
ui.getPluginToolbar().removeNavigation(navButton);
|
pluginToolbar.removeNavigation(navButton);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ import net.runelite.api.widgets.Widget;
|
|||||||
import net.runelite.api.widgets.WidgetInfo;
|
import net.runelite.api.widgets.WidgetInfo;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
import net.runelite.client.ui.PluginToolbar;
|
||||||
import net.runelite.client.ui.overlay.Overlay;
|
import net.runelite.client.ui.overlay.Overlay;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
@@ -57,7 +57,7 @@ public class KourendLibraryPlugin extends Plugin
|
|||||||
final static boolean debug = false;
|
final static boolean debug = false;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ClientUI ui;
|
private PluginToolbar pluginToolbar;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Client client;
|
private Client client;
|
||||||
@@ -86,19 +86,19 @@ public class KourendLibraryPlugin extends Plugin
|
|||||||
icon = ImageIO.read(Book.class.getResourceAsStream("panel_icon.png"));
|
icon = ImageIO.read(Book.class.getResourceAsStream("panel_icon.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
navButton = new NavigationButton(
|
navButton = NavigationButton.builder()
|
||||||
"Kourend Library",
|
.name("Kourend Library")
|
||||||
icon,
|
.icon(icon)
|
||||||
() -> panel
|
.panel(panel)
|
||||||
);
|
.build();
|
||||||
|
|
||||||
ui.getPluginToolbar().addNavigation(navButton);
|
pluginToolbar.addNavigation(navButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutDown()
|
protected void shutDown()
|
||||||
{
|
{
|
||||||
ui.getPluginToolbar().removeNavigation(navButton);
|
pluginToolbar.removeNavigation(navButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -24,19 +24,18 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.plugins.notes;
|
package net.runelite.client.plugins.notes;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
import com.google.inject.Provides;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import com.google.common.eventbus.Subscribe;
|
|
||||||
import com.google.inject.Provides;
|
|
||||||
import net.runelite.api.events.SessionOpen;
|
import net.runelite.api.events.SessionOpen;
|
||||||
import net.runelite.client.config.ConfigManager;
|
import net.runelite.client.config.ConfigManager;
|
||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import net.runelite.client.ui.PluginToolbar;
|
||||||
|
|
||||||
@PluginDescriptor(
|
@PluginDescriptor(
|
||||||
name = "Notes",
|
name = "Notes",
|
||||||
@@ -46,7 +45,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
public class NotesPlugin extends Plugin
|
public class NotesPlugin extends Plugin
|
||||||
{
|
{
|
||||||
@Inject
|
@Inject
|
||||||
private ClientUI ui;
|
private PluginToolbar pluginToolbar;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private NotesConfig config;
|
private NotesConfig config;
|
||||||
@@ -72,19 +71,19 @@ public class NotesPlugin extends Plugin
|
|||||||
icon = ImageIO.read(getClass().getResourceAsStream("notes_icon.png"));
|
icon = ImageIO.read(getClass().getResourceAsStream("notes_icon.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
navButton = new NavigationButton(
|
navButton = NavigationButton.builder()
|
||||||
"Notes",
|
.name("Notes")
|
||||||
icon,
|
.icon(icon)
|
||||||
() -> panel
|
.panel(panel)
|
||||||
);
|
.build();
|
||||||
|
|
||||||
ui.getPluginToolbar().addNavigation(navButton);
|
pluginToolbar.addNavigation(navButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutDown()
|
protected void shutDown()
|
||||||
{
|
{
|
||||||
ui.getPluginToolbar().removeNavigation(navButton);
|
pluginToolbar.removeNavigation(navButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|||||||
@@ -25,19 +25,17 @@
|
|||||||
package net.runelite.client.plugins.screenshot;
|
package net.runelite.client.plugins.screenshot;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Desktop;
|
import java.awt.Desktop;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Point;
|
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.TrayIcon;
|
import java.awt.TrayIcon;
|
||||||
import java.awt.datatransfer.Clipboard;
|
import java.awt.datatransfer.Clipboard;
|
||||||
import java.awt.datatransfer.StringSelection;
|
import java.awt.datatransfer.StringSelection;
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -52,10 +50,6 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JMenuItem;
|
|
||||||
import javax.swing.JPopupMenu;
|
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.ChatMessageType;
|
import net.runelite.api.ChatMessageType;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
@@ -80,6 +74,8 @@ import net.runelite.client.plugins.screenshot.imgur.ImageUploadRequest;
|
|||||||
import net.runelite.client.plugins.screenshot.imgur.ImageUploadResponse;
|
import net.runelite.client.plugins.screenshot.imgur.ImageUploadResponse;
|
||||||
import net.runelite.client.ui.ClientUI;
|
import net.runelite.client.ui.ClientUI;
|
||||||
import net.runelite.client.ui.FontManager;
|
import net.runelite.client.ui.FontManager;
|
||||||
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
import net.runelite.client.ui.TitleToolbar;
|
||||||
import net.runelite.client.ui.overlay.OverlayRenderer;
|
import net.runelite.client.ui.overlay.OverlayRenderer;
|
||||||
import net.runelite.client.util.Text;
|
import net.runelite.client.util.Text;
|
||||||
import net.runelite.http.api.RuneLiteAPI;
|
import net.runelite.http.api.RuneLiteAPI;
|
||||||
@@ -125,13 +121,16 @@ public class ScreenshotPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private ClientUI clientUi;
|
private ClientUI clientUi;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private TitleToolbar titleToolbar;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private OverlayRenderer overlayRenderer;
|
private OverlayRenderer overlayRenderer;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ScheduledExecutorService executor;
|
private ScheduledExecutorService executor;
|
||||||
|
|
||||||
private JButton titleBarButton;
|
private NavigationButton titleBarButton;
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
ScreenshotConfig getConfig(ConfigManager configManager)
|
ScreenshotConfig getConfig(ConfigManager configManager)
|
||||||
@@ -141,66 +140,39 @@ public class ScreenshotPlugin extends Plugin
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void startUp() throws Exception
|
protected void startUp() throws Exception
|
||||||
{
|
|
||||||
addButtonToTitleBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void shutDown() throws Exception
|
|
||||||
{
|
|
||||||
removeButtonFromTitlebar();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addButtonToTitleBar()
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
BufferedImage iconImage;
|
BufferedImage iconImage;
|
||||||
BufferedImage invertedIconImage;
|
|
||||||
synchronized (ImageIO.class)
|
synchronized (ImageIO.class)
|
||||||
{
|
{
|
||||||
iconImage = ImageIO.read(ScreenshotPlugin.class.getResourceAsStream("screenshot.png"));
|
iconImage = ImageIO.read(ScreenshotPlugin.class.getResourceAsStream("screenshot.png"));
|
||||||
invertedIconImage = ImageIO.read(ScreenshotPlugin.class.getResourceAsStream("screenshot_inverted.png"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() ->
|
titleBarButton = NavigationButton.builder()
|
||||||
{
|
.tooltip("Take screenshot")
|
||||||
titleBarButton = new JButton();
|
.icon(iconImage)
|
||||||
titleBarButton.setToolTipText("Take screenshot");
|
.onClick(() -> takeScreenshot(
|
||||||
titleBarButton.addMouseListener(new MouseAdapter()
|
TIME_FORMAT.format(new Date()),
|
||||||
{
|
client.getLocalPlayer() != null))
|
||||||
@Override
|
.popup(ImmutableMap
|
||||||
public void mouseClicked(MouseEvent e)
|
.<String, Runnable>builder()
|
||||||
|
.put("Open screenshot folder...", () ->
|
||||||
{
|
{
|
||||||
super.mouseClicked(e);
|
try
|
||||||
|
|
||||||
if (SwingUtilities.isLeftMouseButton(e))
|
|
||||||
{
|
{
|
||||||
takeScreenshot(TIME_FORMAT.format(new Date()), client.getLocalPlayer() != null);
|
Desktop.getDesktop().open(RuneLite.SCREENSHOT_DIR);
|
||||||
}
|
}
|
||||||
}
|
catch (IOException ex)
|
||||||
});
|
{
|
||||||
|
log.warn("Error opening screenshot dir", ex);
|
||||||
|
|
||||||
JPopupMenu popupMenu = new JPopupMenu();
|
}
|
||||||
|
})
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
JMenuItem folderItem = new JMenuItem("Open screenshot folder...");
|
titleToolbar.addNavigation(titleBarButton);
|
||||||
folderItem.addActionListener(e ->
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Desktop.getDesktop().open(RuneLite.SCREENSHOT_DIR);
|
|
||||||
}
|
|
||||||
catch (IOException ex)
|
|
||||||
{
|
|
||||||
log.warn("Error opening screenshot directory", ex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
popupMenu.add(folderItem);
|
|
||||||
|
|
||||||
titleBarButton.setComponentPopupMenu(popupMenu);
|
|
||||||
|
|
||||||
clientUi.getTitleToolbar().addButton(titleBarButton, iconImage, invertedIconImage);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
@@ -208,12 +180,10 @@ public class ScreenshotPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeButtonFromTitlebar()
|
@Override
|
||||||
|
protected void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
SwingUtilities.invokeLater(() ->
|
titleToolbar.removeNavigation(titleBarButton);
|
||||||
{
|
|
||||||
clientUi.getTitleToolbar().remove(titleBarButton);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
@@ -410,9 +380,8 @@ public class ScreenshotPlugin extends Plugin
|
|||||||
clientUi.paint(graphics);
|
clientUi.paint(graphics);
|
||||||
|
|
||||||
// Evaluate the position of the game inside the frame
|
// Evaluate the position of the game inside the frame
|
||||||
Point gamePoint = SwingUtilities.convertPoint(client.getCanvas(), 0, 0, clientUi);
|
gameOffsetX = 6;
|
||||||
gameOffsetX = gamePoint.x;
|
gameOffsetY = 0;
|
||||||
gameOffsetY = gamePoint.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the game onto the screenshot
|
// Draw the game onto the screenshot
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ import net.runelite.client.game.SkillIconManager;
|
|||||||
import net.runelite.client.plugins.Plugin;
|
import net.runelite.client.plugins.Plugin;
|
||||||
import net.runelite.client.plugins.PluginDescriptor;
|
import net.runelite.client.plugins.PluginDescriptor;
|
||||||
import static net.runelite.client.plugins.xptracker.XpWorldType.NORMAL;
|
import static net.runelite.client.plugins.xptracker.XpWorldType.NORMAL;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
import net.runelite.client.ui.NavigationButton;
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
import net.runelite.client.ui.PluginToolbar;
|
||||||
import net.runelite.http.api.worlds.World;
|
import net.runelite.http.api.worlds.World;
|
||||||
import net.runelite.http.api.worlds.WorldClient;
|
import net.runelite.http.api.worlds.WorldClient;
|
||||||
import net.runelite.http.api.worlds.WorldResult;
|
import net.runelite.http.api.worlds.WorldResult;
|
||||||
@@ -62,7 +62,7 @@ import net.runelite.http.api.xp.XpClient;
|
|||||||
public class XpTrackerPlugin extends Plugin
|
public class XpTrackerPlugin extends Plugin
|
||||||
{
|
{
|
||||||
@Inject
|
@Inject
|
||||||
private ClientUI ui;
|
private PluginToolbar pluginToolbar;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Client client;
|
private Client client;
|
||||||
@@ -104,25 +104,27 @@ public class XpTrackerPlugin extends Plugin
|
|||||||
log.warn("Error looking up worlds list", e);
|
log.warn("Error looking up worlds list", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xpPanel = new XpPanel(this, client, skillIconManager);
|
||||||
|
|
||||||
BufferedImage icon;
|
BufferedImage icon;
|
||||||
synchronized (ImageIO.class)
|
synchronized (ImageIO.class)
|
||||||
{
|
{
|
||||||
icon = ImageIO.read(getClass().getResourceAsStream("xp.png"));
|
icon = ImageIO.read(getClass().getResourceAsStream("xp.png"));
|
||||||
}
|
}
|
||||||
|
|
||||||
xpPanel = new XpPanel(this, client, skillIconManager);
|
navButton = NavigationButton.builder()
|
||||||
navButton = new NavigationButton(
|
.name("XP Tracker")
|
||||||
"XP Tracker",
|
.icon(icon)
|
||||||
icon,
|
.panel(xpPanel)
|
||||||
() -> xpPanel);
|
.build();
|
||||||
|
|
||||||
ui.getPluginToolbar().addNavigation(navButton);
|
pluginToolbar.addNavigation(navButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void shutDown() throws Exception
|
protected void shutDown() throws Exception
|
||||||
{
|
{
|
||||||
ui.getPluginToolbar().removeNavigation(navButton);
|
pluginToolbar.removeNavigation(navButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2017-2018, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.ui;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.swing.JToolBar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client plugin toolbar.
|
||||||
|
*/
|
||||||
|
public class ClientPluginToolbar extends JToolBar
|
||||||
|
{
|
||||||
|
private static final int TOOLBAR_WIDTH = 36, TOOLBAR_HEIGHT = 503;
|
||||||
|
private final Map<NavigationButton, Component> componentMap = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new Client plugin toolbar.
|
||||||
|
*/
|
||||||
|
ClientPluginToolbar()
|
||||||
|
{
|
||||||
|
super(JToolBar.VERTICAL);
|
||||||
|
setFloatable(false);
|
||||||
|
setSize(new Dimension(TOOLBAR_WIDTH, TOOLBAR_HEIGHT));
|
||||||
|
setMinimumSize(new Dimension(TOOLBAR_WIDTH, TOOLBAR_HEIGHT));
|
||||||
|
setPreferredSize(new Dimension(TOOLBAR_WIDTH, TOOLBAR_HEIGHT));
|
||||||
|
setMaximumSize(new Dimension(TOOLBAR_WIDTH, Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addComponent(final int index, final NavigationButton button, final Component component)
|
||||||
|
{
|
||||||
|
if (componentMap.put(button, component) == null)
|
||||||
|
{
|
||||||
|
add(component, index);
|
||||||
|
revalidate();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeComponent(final NavigationButton button)
|
||||||
|
{
|
||||||
|
final Component component = componentMap.remove(button);
|
||||||
|
|
||||||
|
if (component != null)
|
||||||
|
{
|
||||||
|
remove(component);
|
||||||
|
revalidate();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 Abex
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.ui;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Container;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.LayoutManager2;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client title toolbar component.
|
||||||
|
*/
|
||||||
|
public class ClientTitleToolbar extends JPanel
|
||||||
|
{
|
||||||
|
public static final int TITLEBAR_SIZE = 23;
|
||||||
|
private static final int ITEM_PADDING = 4;
|
||||||
|
|
||||||
|
private final Map<NavigationButton, Component> componentMap = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new Client title toolbar.
|
||||||
|
*/
|
||||||
|
public ClientTitleToolbar()
|
||||||
|
{
|
||||||
|
// The only other layout manager that would manage it's preferred size without padding
|
||||||
|
// was the GroupLayout manager, which doesn't work with dynamic layouts like this one.
|
||||||
|
// Primarily, it would not remove components unless it was immediately repainted.
|
||||||
|
setLayout(new LayoutManager2()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void addLayoutComponent(String name, Component comp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addLayoutComponent(Component comp, Object constraints)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeLayoutComponent(Component comp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension preferredLayoutSize(Container parent)
|
||||||
|
{
|
||||||
|
int width = parent.getComponentCount() * (TITLEBAR_SIZE + ITEM_PADDING);
|
||||||
|
return new Dimension(width, TITLEBAR_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension minimumLayoutSize(Container parent)
|
||||||
|
{
|
||||||
|
return preferredLayoutSize(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension maximumLayoutSize(Container parent)
|
||||||
|
{
|
||||||
|
return preferredLayoutSize(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLayoutAlignmentX(Container target)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getLayoutAlignmentY(Container target)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateLayout(Container target)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void layoutContainer(Container parent)
|
||||||
|
{
|
||||||
|
int x = 0;
|
||||||
|
for (Component c : parent.getComponents())
|
||||||
|
{
|
||||||
|
x += ITEM_PADDING;
|
||||||
|
int height = c.getPreferredSize().height;
|
||||||
|
if (height > TITLEBAR_SIZE)
|
||||||
|
{
|
||||||
|
height = TITLEBAR_SIZE;
|
||||||
|
}
|
||||||
|
c.setBounds(x, (TITLEBAR_SIZE - height) / 2, TITLEBAR_SIZE, height);
|
||||||
|
x += TITLEBAR_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addComponent(NavigationButton button, Component c)
|
||||||
|
{
|
||||||
|
if (componentMap.put(button, c) == null)
|
||||||
|
{
|
||||||
|
add(c);
|
||||||
|
revalidate();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeComponent(NavigationButton button)
|
||||||
|
{
|
||||||
|
final Component component = componentMap.remove(button);
|
||||||
|
if (component != null)
|
||||||
|
{
|
||||||
|
remove(component);
|
||||||
|
revalidate();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,40 +24,32 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.ui;
|
package net.runelite.client.ui;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import java.applet.Applet;
|
import java.applet.Applet;
|
||||||
import java.awt.AWTException;
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Canvas;
|
import java.awt.Canvas;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Frame;
|
import java.awt.Graphics;
|
||||||
import java.awt.LayoutManager;
|
import java.awt.LayoutManager;
|
||||||
import java.awt.SystemTray;
|
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.TrayIcon;
|
import java.awt.TrayIcon;
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.awt.event.WindowAdapter;
|
|
||||||
import java.awt.event.WindowEvent;
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Enumeration;
|
import javax.annotation.Nullable;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
import javax.swing.BoxLayout;
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JOptionPane;
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JPopupMenu;
|
|
||||||
import javax.swing.JRootPane;
|
import javax.swing.JRootPane;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.ToolTipManager;
|
|
||||||
import javax.swing.UIManager;
|
|
||||||
import javax.swing.UnsupportedLookAndFeelException;
|
|
||||||
import javax.swing.plaf.FontUIResource;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
@@ -65,31 +57,29 @@ import net.runelite.api.GameState;
|
|||||||
import net.runelite.api.events.ConfigChanged;
|
import net.runelite.api.events.ConfigChanged;
|
||||||
import net.runelite.client.RuneLite;
|
import net.runelite.client.RuneLite;
|
||||||
import net.runelite.client.RuneLiteProperties;
|
import net.runelite.client.RuneLiteProperties;
|
||||||
|
import net.runelite.client.config.RuneLiteConfig;
|
||||||
|
import net.runelite.client.events.ClientUILoaded;
|
||||||
|
import net.runelite.client.events.PluginToolbarButtonAdded;
|
||||||
|
import net.runelite.client.events.PluginToolbarButtonRemoved;
|
||||||
|
import net.runelite.client.events.TitleToolbarButtonAdded;
|
||||||
|
import net.runelite.client.events.TitleToolbarButtonRemoved;
|
||||||
import net.runelite.client.util.OSType;
|
import net.runelite.client.util.OSType;
|
||||||
import net.runelite.client.util.OSXUtil;
|
import net.runelite.client.util.OSXUtil;
|
||||||
|
import net.runelite.client.util.SwingUtil;
|
||||||
import org.pushingpixels.substance.api.skin.SubstanceGraphiteLookAndFeel;
|
import org.pushingpixels.substance.api.skin.SubstanceGraphiteLookAndFeel;
|
||||||
import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities;
|
import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities;
|
||||||
import org.pushingpixels.substance.internal.utils.SubstanceTitlePaneUtilities;
|
import org.pushingpixels.substance.internal.utils.SubstanceTitlePaneUtilities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client UI.
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ClientUI extends JFrame
|
@Singleton
|
||||||
|
public class ClientUI
|
||||||
{
|
{
|
||||||
private static final int PANEL_EXPANDED_WIDTH = PluginPanel.PANEL_WIDTH + PluginPanel.SCROLLBAR_WIDTH;
|
private static final int PANEL_EXPANDED_WIDTH = PluginPanel.PANEL_WIDTH + PluginPanel.SCROLLBAR_WIDTH;
|
||||||
public static final BufferedImage ICON;
|
public static final BufferedImage ICON;
|
||||||
|
|
||||||
@Getter
|
|
||||||
private TrayIcon trayIcon;
|
|
||||||
|
|
||||||
private final RuneLite runelite;
|
|
||||||
private final Applet client;
|
|
||||||
private final RuneLiteProperties properties;
|
|
||||||
private JPanel navContainer;
|
|
||||||
private PluginToolbar pluginToolbar;
|
|
||||||
private PluginPanel pluginPanel;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private TitleToolbar titleToolbar;
|
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
BufferedImage icon = null;
|
BufferedImage icon = null;
|
||||||
@@ -109,129 +99,39 @@ public class ClientUI extends JFrame
|
|||||||
ICON = icon;
|
ICON = icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClientUI create(RuneLite runelite, RuneLiteProperties properties, Applet client)
|
@Getter
|
||||||
{
|
private TrayIcon trayIcon;
|
||||||
// Force heavy-weight popups/tooltips.
|
|
||||||
// Prevents them from being obscured by the game applet.
|
|
||||||
ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);
|
|
||||||
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
|
|
||||||
|
|
||||||
// Do not render shadows under popups/tooltips.
|
private final RuneLite runelite;
|
||||||
// Fixes black boxes under popups that are above the game applet.
|
private final RuneLiteProperties properties;
|
||||||
System.setProperty("jgoodies.popupDropShadowEnabled", "false");
|
private final RuneLiteConfig config;
|
||||||
|
private final EventBus eventBus;
|
||||||
|
private Applet client;
|
||||||
|
private JFrame frame;
|
||||||
|
private JPanel navContainer;
|
||||||
|
private PluginPanel pluginPanel;
|
||||||
|
private ClientPluginToolbar pluginToolbar;
|
||||||
|
private ClientTitleToolbar titleToolbar;
|
||||||
|
private JButton currentButton;
|
||||||
|
|
||||||
// Do not fill in background on repaint. Reduces flickering when
|
@Inject
|
||||||
// the applet is resized.
|
private ClientUI(
|
||||||
System.setProperty("sun.awt.noerasebackground", "true");
|
RuneLite runelite,
|
||||||
|
RuneLiteProperties properties,
|
||||||
// Use substance look and feel
|
RuneLiteConfig config,
|
||||||
try
|
EventBus eventBus)
|
||||||
{
|
|
||||||
UIManager.setLookAndFeel(new SubstanceGraphiteLookAndFeel());
|
|
||||||
}
|
|
||||||
catch (UnsupportedLookAndFeelException ex)
|
|
||||||
{
|
|
||||||
log.warn("unable to set look and feel", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use custom UI font
|
|
||||||
setUIFont(new FontUIResource(FontManager.getRunescapeFont()));
|
|
||||||
|
|
||||||
ClientUI gui = new ClientUI(runelite, properties, client);
|
|
||||||
OSXUtil.tryEnableFullscreen(gui);
|
|
||||||
return gui;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClientUI(RuneLite runelite, RuneLiteProperties properties, Applet client)
|
|
||||||
{
|
{
|
||||||
this.runelite = runelite;
|
this.runelite = runelite;
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.client = client;
|
this.config = config;
|
||||||
this.trayIcon = setupTrayIcon();
|
this.eventBus = eventBus;
|
||||||
|
|
||||||
init();
|
|
||||||
setTitle(properties.getTitle());
|
|
||||||
setIconImage(ICON);
|
|
||||||
// Prevent substance from using a resize cursor for pointing
|
|
||||||
getLayeredPane().setCursor(Cursor.getDefaultCursor());
|
|
||||||
setLocationRelativeTo(getOwner());
|
|
||||||
setResizable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showWithChrome(boolean customChrome)
|
|
||||||
{
|
|
||||||
setUndecorated(customChrome);
|
|
||||||
|
|
||||||
if (customChrome)
|
|
||||||
{
|
|
||||||
getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
|
|
||||||
|
|
||||||
JComponent titleBar = SubstanceCoreUtilities.getTitlePaneComponent(this);
|
|
||||||
titleToolbar.putClientProperty(SubstanceTitlePaneUtilities.EXTRA_COMPONENT_KIND, SubstanceTitlePaneUtilities.ExtraComponentKind.TRAILING);
|
|
||||||
titleBar.add(titleToolbar);
|
|
||||||
|
|
||||||
// Substance's default layout manager for the title bar only lays out substance's components
|
|
||||||
// This wraps the default manager and lays out the TitleToolbar as well.
|
|
||||||
LayoutManager delegate = titleBar.getLayout();
|
|
||||||
titleBar.setLayout(new LayoutManager()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void addLayoutComponent(String name, Component comp)
|
|
||||||
{
|
|
||||||
delegate.addLayoutComponent(name, comp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeLayoutComponent(Component comp)
|
|
||||||
{
|
|
||||||
delegate.removeLayoutComponent(comp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension preferredLayoutSize(Container parent)
|
|
||||||
{
|
|
||||||
return delegate.preferredLayoutSize(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension minimumLayoutSize(Container parent)
|
|
||||||
{
|
|
||||||
return delegate.minimumLayoutSize(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void layoutContainer(Container parent)
|
|
||||||
{
|
|
||||||
delegate.layoutContainer(parent);
|
|
||||||
final int width = titleToolbar.getPreferredSize().width;
|
|
||||||
titleToolbar.setBounds(titleBar.getWidth() - 75 - width, 0, width, titleBar.getHeight());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pack();
|
|
||||||
revalidateMinimumSize();
|
|
||||||
setLocationRelativeTo(getOwner());
|
|
||||||
|
|
||||||
setVisible(true);
|
|
||||||
toFront();
|
|
||||||
requestFocus();
|
|
||||||
giveClientFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void giveClientFocus()
|
|
||||||
{
|
|
||||||
if (client instanceof Client)
|
|
||||||
{
|
|
||||||
final Canvas c = ((Client) client).getCanvas();
|
|
||||||
c.requestFocusInWindow();
|
|
||||||
}
|
|
||||||
else if (client != null)
|
|
||||||
{
|
|
||||||
client.requestFocusInWindow();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On config changed.
|
||||||
|
*
|
||||||
|
* @param event the event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onConfigChanged(ConfigChanged event)
|
public void onConfigChanged(ConfigChanged event)
|
||||||
{
|
{
|
||||||
@@ -240,147 +140,303 @@ public class ClientUI extends JFrame
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.getKey().equals("gameAlwaysOnTop"))
|
|
||||||
{
|
|
||||||
if (this.isAlwaysOnTopSupported())
|
|
||||||
{
|
|
||||||
this.setAlwaysOnTop(Boolean.valueOf(event.getNewValue()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.getKey().equals("lockWindowSize"))
|
|
||||||
{
|
|
||||||
SwingUtilities.invokeLater(() -> setResizable(!Boolean.valueOf(event.getNewValue())));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!event.getKey().equals("gameSize"))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] splitStr = event.getNewValue().split("x");
|
|
||||||
int width = Integer.parseInt(splitStr[0]);
|
|
||||||
int height = Integer.parseInt(splitStr[1]);
|
|
||||||
|
|
||||||
// The upper bounds are defined by the applet's max size
|
|
||||||
// The lower bounds are taken care of by ClientPanel's setMinimumSize
|
|
||||||
|
|
||||||
if (width > 7680)
|
|
||||||
{
|
|
||||||
width = 7680;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (height > 2160)
|
|
||||||
{
|
|
||||||
height = 2160;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dimension size = new Dimension(width, height);
|
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() ->
|
SwingUtilities.invokeLater(() ->
|
||||||
{
|
{
|
||||||
|
if (event.getKey().equals("gameAlwaysOnTop"))
|
||||||
|
{
|
||||||
|
if (frame.isAlwaysOnTopSupported())
|
||||||
|
{
|
||||||
|
frame.setAlwaysOnTop(config.gameAlwaysOnTop());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.getKey().equals("lockWindowSize"))
|
||||||
|
{
|
||||||
|
SwingUtilities.invokeLater(() -> frame.setResizable(!config.lockWindowSize()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!event.getKey().equals("gameSize"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = config.gameSize().width;
|
||||||
|
int height = config.gameSize().height;
|
||||||
|
|
||||||
|
// The upper bounds are defined by the applet's max size
|
||||||
|
// The lower bounds are taken care of by ClientPanel's setMinimumSize
|
||||||
|
|
||||||
|
if (width > 7680)
|
||||||
|
{
|
||||||
|
width = 7680;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height > 2160)
|
||||||
|
{
|
||||||
|
height = 2160;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Dimension size = new Dimension(width, height);
|
||||||
|
|
||||||
client.setSize(size);
|
client.setSize(size);
|
||||||
client.setPreferredSize(size);
|
client.setPreferredSize(size);
|
||||||
|
|
||||||
client.getParent().setPreferredSize(size);
|
client.getParent().setPreferredSize(size);
|
||||||
client.getParent().setSize(size);
|
client.getParent().setSize(size);
|
||||||
|
|
||||||
if (isVisible())
|
if (frame.isVisible())
|
||||||
{
|
{
|
||||||
pack();
|
frame.pack();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setUIFont(FontUIResource f)
|
@Subscribe
|
||||||
|
public void onPluginToolbarButtonAdded(final PluginToolbarButtonAdded event)
|
||||||
{
|
{
|
||||||
final Enumeration keys = UIManager.getDefaults().keys();
|
SwingUtilities.invokeLater(() ->
|
||||||
|
|
||||||
while (keys.hasMoreElements())
|
|
||||||
{
|
{
|
||||||
final Object key = keys.nextElement();
|
final JButton button = SwingUtil.createSwingButton(event.getButton(), 0, (jButton) ->
|
||||||
final Object value = UIManager.get(key);
|
|
||||||
|
|
||||||
if (value instanceof FontUIResource)
|
|
||||||
{
|
{
|
||||||
UIManager.put(key, f);
|
final PluginPanel panel = event.getButton().getPanel();
|
||||||
}
|
|
||||||
}
|
if (panel == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentButton != null)
|
||||||
|
{
|
||||||
|
currentButton.setSelected(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentButton == jButton)
|
||||||
|
{
|
||||||
|
contract();
|
||||||
|
currentButton = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentButton = jButton;
|
||||||
|
currentButton.setSelected(true);
|
||||||
|
expand(panel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pluginToolbar.addComponent(event.getIndex(), event.getButton(), button);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private TrayIcon setupTrayIcon()
|
@Subscribe
|
||||||
|
public void onPluginToolbarButtonRemoved(final PluginToolbarButtonRemoved event)
|
||||||
{
|
{
|
||||||
if (!SystemTray.isSupported())
|
SwingUtilities.invokeLater(() -> pluginToolbar.removeComponent(event.getButton()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onTitleToolbarButtonAdded(final TitleToolbarButtonAdded event)
|
||||||
|
{
|
||||||
|
if (!config.enableCustomChrome() && !SwingUtil.isCustomTitlePanePresent(frame))
|
||||||
{
|
{
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemTray systemTray = SystemTray.getSystemTray();
|
SwingUtilities.invokeLater(() ->
|
||||||
TrayIcon trayIcon = new TrayIcon(ICON, properties.getTitle());
|
{
|
||||||
trayIcon.setImageAutoSize(true);
|
final int iconSize = ClientTitleToolbar.TITLEBAR_SIZE - 6;
|
||||||
|
final JButton button = SwingUtil.createSwingButton(event.getButton(), iconSize, null);
|
||||||
|
titleToolbar.addComponent(event.getButton(), button);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
try
|
@Subscribe
|
||||||
|
public void onTitleToolbarButtonRemoved(final TitleToolbarButtonRemoved event)
|
||||||
|
{
|
||||||
|
if (!config.enableCustomChrome() && !SwingUtil.isCustomTitlePanePresent(frame))
|
||||||
{
|
{
|
||||||
systemTray.add(trayIcon);
|
return;
|
||||||
}
|
|
||||||
catch (AWTException ex)
|
|
||||||
{
|
|
||||||
log.debug("Unable to add system tray icon", ex);
|
|
||||||
return trayIcon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// bring to front when tray icon is clicked
|
SwingUtilities.invokeLater(() -> titleToolbar.removeComponent(event.getButton()));
|
||||||
trayIcon.addMouseListener(new MouseAdapter()
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize UI.
|
||||||
|
*
|
||||||
|
* @param client the client
|
||||||
|
* @throws Exception exception that can occur during creation of the UI
|
||||||
|
*/
|
||||||
|
public void init(@Nullable final Applet client) throws Exception
|
||||||
|
{
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
SwingUtilities.invokeAndWait(() ->
|
||||||
{
|
{
|
||||||
@Override
|
// Set some sensible swing defaults
|
||||||
public void mouseClicked(MouseEvent e)
|
SwingUtil.setupDefaults();
|
||||||
|
|
||||||
|
// Use substance look and feel
|
||||||
|
SwingUtil.setTheme(new SubstanceGraphiteLookAndFeel());
|
||||||
|
|
||||||
|
// Use custom UI font
|
||||||
|
SwingUtil.setFont(FontManager.getRunescapeFont());
|
||||||
|
|
||||||
|
// Create main window
|
||||||
|
frame = new JFrame();
|
||||||
|
|
||||||
|
// Try to enable fullscreen on OSX
|
||||||
|
OSXUtil.tryEnableFullscreen(frame);
|
||||||
|
|
||||||
|
trayIcon = SwingUtil.createTrayIcon(ICON, properties.getTitle(), frame);
|
||||||
|
|
||||||
|
frame.setTitle(properties.getTitle());
|
||||||
|
frame.setIconImage(ICON);
|
||||||
|
frame.getLayeredPane().setCursor(Cursor.getDefaultCursor()); // Prevent substance from using a resize cursor for pointing
|
||||||
|
frame.setLocationRelativeTo(frame.getOwner());
|
||||||
|
frame.setResizable(true);
|
||||||
|
|
||||||
|
SwingUtil.addGracefulExitCallback(frame, runelite::shutdown,
|
||||||
|
() -> client != null
|
||||||
|
&& client instanceof Client
|
||||||
|
&& ((Client) client).getGameState() != GameState.LOGIN_SCREEN);
|
||||||
|
|
||||||
|
final JPanel container = new JPanel();
|
||||||
|
container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
|
||||||
|
container.add(new ClientPanel(client));
|
||||||
|
|
||||||
|
navContainer = new JPanel();
|
||||||
|
navContainer.setLayout(new BorderLayout(0, 0));
|
||||||
|
navContainer.setMinimumSize(new Dimension(0, 0));
|
||||||
|
navContainer.setMaximumSize(new Dimension(0, Integer.MAX_VALUE));
|
||||||
|
container.add(navContainer);
|
||||||
|
|
||||||
|
pluginToolbar = new ClientPluginToolbar();
|
||||||
|
container.add(pluginToolbar);
|
||||||
|
|
||||||
|
titleToolbar = new ClientTitleToolbar();
|
||||||
|
frame.add(container);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show client UI after everything else is done.
|
||||||
|
*
|
||||||
|
* @throws Exception exception that can occur during modification of the UI
|
||||||
|
*/
|
||||||
|
public void show() throws Exception
|
||||||
|
{
|
||||||
|
final boolean withTitleBar = config.enableCustomChrome();
|
||||||
|
|
||||||
|
SwingUtilities.invokeAndWait(() ->
|
||||||
|
{
|
||||||
|
frame.setUndecorated(withTitleBar);
|
||||||
|
|
||||||
|
if (withTitleBar)
|
||||||
{
|
{
|
||||||
setVisible(true);
|
frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
|
||||||
setState(Frame.NORMAL); // unminimize
|
|
||||||
|
final JComponent titleBar = SubstanceCoreUtilities.getTitlePaneComponent(frame);
|
||||||
|
titleToolbar.putClientProperty(SubstanceTitlePaneUtilities.EXTRA_COMPONENT_KIND, SubstanceTitlePaneUtilities.ExtraComponentKind.TRAILING);
|
||||||
|
titleBar.add(titleToolbar);
|
||||||
|
|
||||||
|
// Substance's default layout manager for the title bar only lays out substance's components
|
||||||
|
// This wraps the default manager and lays out the TitleToolbar as well.
|
||||||
|
LayoutManager delegate = titleBar.getLayout();
|
||||||
|
titleBar.setLayout(new LayoutManager()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void addLayoutComponent(String name, Component comp)
|
||||||
|
{
|
||||||
|
delegate.addLayoutComponent(name, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeLayoutComponent(Component comp)
|
||||||
|
{
|
||||||
|
delegate.removeLayoutComponent(comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension preferredLayoutSize(Container parent)
|
||||||
|
{
|
||||||
|
return delegate.preferredLayoutSize(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension minimumLayoutSize(Container parent)
|
||||||
|
{
|
||||||
|
return delegate.minimumLayoutSize(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void layoutContainer(Container parent)
|
||||||
|
{
|
||||||
|
delegate.layoutContainer(parent);
|
||||||
|
final int width = titleToolbar.getPreferredSize().width;
|
||||||
|
titleToolbar.setBounds(titleBar.getWidth() - 75 - width, 0, width, titleBar.getHeight());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frame.pack();
|
||||||
|
SwingUtil.revalidateMinimumSize(frame);
|
||||||
|
frame.setLocationRelativeTo(frame.getOwner());
|
||||||
|
frame.setVisible(true);
|
||||||
|
frame.toFront();
|
||||||
|
requestFocus();
|
||||||
|
giveClientFocus();
|
||||||
});
|
});
|
||||||
|
|
||||||
return trayIcon;
|
eventBus.post(new ClientUILoaded());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init()
|
/**
|
||||||
|
* Paint this component to target graphics
|
||||||
|
*
|
||||||
|
* @param graphics the graphics
|
||||||
|
*/
|
||||||
|
public void paint(final Graphics graphics)
|
||||||
{
|
{
|
||||||
assert SwingUtilities.isEventDispatchThread();
|
frame.paint(graphics);
|
||||||
|
|
||||||
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
|
||||||
addWindowListener(new WindowAdapter()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void windowClosing(WindowEvent e)
|
|
||||||
{
|
|
||||||
checkExit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
final JPanel container = new JPanel();
|
|
||||||
container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
|
|
||||||
container.add(new ClientPanel(client));
|
|
||||||
|
|
||||||
navContainer = new JPanel();
|
|
||||||
navContainer.setLayout(new BorderLayout(0, 0));
|
|
||||||
navContainer.setMinimumSize(new Dimension(0, 0));
|
|
||||||
navContainer.setMaximumSize(new Dimension(0, Integer.MAX_VALUE));
|
|
||||||
container.add(navContainer);
|
|
||||||
|
|
||||||
pluginToolbar = new PluginToolbar(this);
|
|
||||||
container.add(pluginToolbar);
|
|
||||||
|
|
||||||
titleToolbar = new TitleToolbar(properties);
|
|
||||||
|
|
||||||
add(container);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
|
* Gets component width.
|
||||||
|
*
|
||||||
|
* @return the width
|
||||||
|
*/
|
||||||
|
public int getWidth()
|
||||||
|
{
|
||||||
|
return frame.getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets component height.
|
||||||
|
*
|
||||||
|
* @return the height
|
||||||
|
*/
|
||||||
|
public int getHeight()
|
||||||
|
{
|
||||||
|
return frame.getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this component has focus.
|
||||||
|
*
|
||||||
|
* @return true if component has focus
|
||||||
|
*/
|
||||||
|
public boolean isFocused()
|
||||||
|
{
|
||||||
|
return frame.isFocused();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request focus on this component and then on client component
|
||||||
|
*/
|
||||||
public void requestFocus()
|
public void requestFocus()
|
||||||
{
|
{
|
||||||
if (OSType.getOSType() == OSType.MacOS)
|
if (OSType.getOSType() == OSType.MacOS)
|
||||||
@@ -388,17 +444,11 @@ public class ClientUI extends JFrame
|
|||||||
OSXUtil.requestFocus();
|
OSXUtil.requestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
super.requestFocus();
|
frame.requestFocus();
|
||||||
giveClientFocus();
|
giveClientFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void revalidateMinimumSize()
|
private void expand(PluginPanel panel)
|
||||||
{
|
|
||||||
// The JFrame only respects minimumSize if it was set by setMinimumSize, for some reason. (atleast on windows/native)
|
|
||||||
this.setMinimumSize(this.getLayout().minimumLayoutSize(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
void expand(PluginPanel panel)
|
|
||||||
{
|
{
|
||||||
if (pluginPanel != null)
|
if (pluginPanel != null)
|
||||||
{
|
{
|
||||||
@@ -406,9 +456,11 @@ public class ClientUI extends JFrame
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (isInScreenBounds((int) getLocationOnScreen().getX() + getWidth() + PANEL_EXPANDED_WIDTH, (int) getLocationOnScreen().getY()))
|
if (SwingUtil.isInScreenBounds(
|
||||||
|
frame.getLocationOnScreen().y + frame.getWidth() + PANEL_EXPANDED_WIDTH,
|
||||||
|
frame.getLocationOnScreen().y))
|
||||||
{
|
{
|
||||||
this.setSize(getWidth() + PANEL_EXPANDED_WIDTH, getHeight());
|
frame.setSize(frame.getWidth() + PANEL_EXPANDED_WIDTH, frame.getHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -425,57 +477,42 @@ public class ClientUI extends JFrame
|
|||||||
panel.onActivate();
|
panel.onActivate();
|
||||||
|
|
||||||
wrappedPanel.repaint();
|
wrappedPanel.repaint();
|
||||||
revalidateMinimumSize();
|
SwingUtil.revalidateMinimumSize(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void contract()
|
private void contract()
|
||||||
{
|
{
|
||||||
boolean wasMinimumWidth = this.getWidth() == (int) this.getMinimumSize().getWidth();
|
boolean wasMinimumWidth = frame.getWidth() == frame.getMinimumSize().width;
|
||||||
pluginPanel.onDeactivate();
|
pluginPanel.onDeactivate();
|
||||||
navContainer.remove(0);
|
navContainer.remove(0);
|
||||||
navContainer.setMinimumSize(new Dimension(0, 0));
|
navContainer.setMinimumSize(new Dimension(0, 0));
|
||||||
navContainer.setMaximumSize(new Dimension(0, Integer.MAX_VALUE));
|
navContainer.setMaximumSize(new Dimension(0, 0));
|
||||||
navContainer.revalidate();
|
navContainer.revalidate();
|
||||||
giveClientFocus();
|
giveClientFocus();
|
||||||
revalidateMinimumSize();
|
SwingUtil.revalidateMinimumSize(frame);
|
||||||
|
|
||||||
if (wasMinimumWidth)
|
if (wasMinimumWidth)
|
||||||
{
|
{
|
||||||
this.setSize((int) this.getMinimumSize().getWidth(), getHeight());
|
frame.setSize(frame.getMinimumSize().width, frame.getHeight());
|
||||||
}
|
}
|
||||||
else if (getWidth() < Toolkit.getDefaultToolkit().getScreenSize().getWidth())
|
else if (frame.getWidth() < Toolkit.getDefaultToolkit().getScreenSize().getWidth())
|
||||||
{
|
{
|
||||||
this.setSize(getWidth() - PANEL_EXPANDED_WIDTH, getHeight());
|
frame.setSize(frame.getWidth() - PANEL_EXPANDED_WIDTH, frame.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginPanel = null;
|
pluginPanel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInScreenBounds(int x, int y)
|
private void giveClientFocus()
|
||||||
{
|
{
|
||||||
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
|
if (client instanceof Client)
|
||||||
return x >= 0 && x <= size.getWidth() && y >= 0 && y <= size.getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkExit()
|
|
||||||
{
|
|
||||||
int result = JOptionPane.OK_OPTION;
|
|
||||||
|
|
||||||
// only ask if not logged out
|
|
||||||
if (client != null && client instanceof Client && ((Client) client).getGameState() != GameState.LOGIN_SCREEN)
|
|
||||||
{
|
{
|
||||||
result = JOptionPane.showConfirmDialog(this, "Are you sure you want to exit?", "Exit", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
|
final Canvas c = ((Client) client).getCanvas();
|
||||||
|
c.requestFocusInWindow();
|
||||||
}
|
}
|
||||||
|
else if (client != null)
|
||||||
if (result == JOptionPane.OK_OPTION)
|
|
||||||
{
|
{
|
||||||
runelite.shutdown();
|
client.requestFocusInWindow();
|
||||||
System.exit(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginToolbar getPluginToolbar()
|
|
||||||
{
|
|
||||||
return pluginToolbar;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
* Copyright (c) 2017-2018, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.con>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -24,30 +25,57 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.ui;
|
package net.runelite.client.ui;
|
||||||
|
|
||||||
import java.awt.Image;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.function.Supplier;
|
import java.util.Map;
|
||||||
import javax.swing.ImageIcon;
|
import lombok.Builder;
|
||||||
import javax.swing.JButton;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Slf4j
|
/**
|
||||||
public class NavigationButton extends JButton
|
* UI navigation button.
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@EqualsAndHashCode(of = {"name", "tooltip"})
|
||||||
|
public class NavigationButton
|
||||||
{
|
{
|
||||||
@Getter
|
/**
|
||||||
private final Supplier<PluginPanel> panelSupplier;
|
* Button name.
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
public NavigationButton(String name, Image icon)
|
/**
|
||||||
{
|
* Icon of button.
|
||||||
this(name, icon, null);
|
*/
|
||||||
}
|
private final BufferedImage icon;
|
||||||
|
|
||||||
public NavigationButton(String name, Image icon, Supplier<PluginPanel> panelSupplier)
|
/**
|
||||||
{
|
* Tooltip to show when hovered.
|
||||||
super();
|
*/
|
||||||
setName(name);
|
private String tooltip;
|
||||||
setToolTipText(name);
|
|
||||||
setIcon(new ImageIcon(icon));
|
/**
|
||||||
this.panelSupplier = panelSupplier;
|
* Button selection state
|
||||||
}
|
*/
|
||||||
|
private boolean selected;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On select action of the button.
|
||||||
|
*/
|
||||||
|
private Runnable onSelect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On click action of the button.
|
||||||
|
*/
|
||||||
|
private Runnable onClick;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin panel, used when expanding and contracting sidebar.
|
||||||
|
*/
|
||||||
|
private PluginPanel panel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of key-value pairs for setting the popup menu
|
||||||
|
*/
|
||||||
|
private Map<String, Runnable> popup;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,87 +24,60 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.ui;
|
package net.runelite.client.ui;
|
||||||
|
|
||||||
import java.awt.Component;
|
import com.google.common.eventbus.EventBus;
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.function.Supplier;
|
import javax.inject.Inject;
|
||||||
import javax.swing.JToolBar;
|
import javax.inject.Singleton;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import net.runelite.client.events.PluginToolbarButtonAdded;
|
||||||
|
import net.runelite.client.events.PluginToolbarButtonRemoved;
|
||||||
|
|
||||||
@Slf4j
|
/**
|
||||||
public class PluginToolbar extends JToolBar
|
* Plugin toolbar buttons holder.
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class PluginToolbar
|
||||||
{
|
{
|
||||||
public static final int TOOLBAR_WIDTH = 36, TOOLBAR_HEIGHT = 503;
|
private final EventBus eventBus;
|
||||||
|
private final TreeSet<NavigationButton> buttons = new TreeSet<>(Comparator.comparing(NavigationButton::getName));
|
||||||
|
|
||||||
private final ClientUI ui;
|
@Inject
|
||||||
private final TreeSet<NavigationButton> buttons = new TreeSet<>(Comparator.comparing(Component::getName));
|
private PluginToolbar(final EventBus eventBus)
|
||||||
|
|
||||||
private NavigationButton current;
|
|
||||||
|
|
||||||
public PluginToolbar(ClientUI ui)
|
|
||||||
{
|
{
|
||||||
super(JToolBar.VERTICAL);
|
this.eventBus = eventBus;
|
||||||
this.ui = ui;
|
|
||||||
|
|
||||||
super.setFloatable(false);
|
|
||||||
super.setSize(new Dimension(TOOLBAR_WIDTH, TOOLBAR_HEIGHT));
|
|
||||||
super.setMinimumSize(new Dimension(TOOLBAR_WIDTH, TOOLBAR_HEIGHT));
|
|
||||||
super.setPreferredSize(new Dimension(TOOLBAR_WIDTH, TOOLBAR_HEIGHT));
|
|
||||||
super.setMaximumSize(new Dimension(TOOLBAR_WIDTH, Integer.MAX_VALUE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addNavigation(NavigationButton button)
|
/**
|
||||||
|
* Add navigation.
|
||||||
|
*
|
||||||
|
* @param button the button
|
||||||
|
*/
|
||||||
|
public void addNavigation(final NavigationButton button)
|
||||||
{
|
{
|
||||||
button.addActionListener((ae) -> onClick(button));
|
|
||||||
button.setToolTipText(button.getName());
|
|
||||||
|
|
||||||
if (buttons.contains(button))
|
if (buttons.contains(button))
|
||||||
{
|
{
|
||||||
log.warn("Button already in container '{}'", button.getName());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
buttons.add(button);
|
if (buttons.add(button))
|
||||||
|
{
|
||||||
|
int index = buttons.headSet(button).size();
|
||||||
|
eventBus.post(new PluginToolbarButtonAdded(button, index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove navigation.
|
||||||
|
*
|
||||||
|
* @param button the button
|
||||||
|
*/
|
||||||
|
public void removeNavigation(final NavigationButton button)
|
||||||
|
{
|
||||||
int index = buttons.headSet(button).size();
|
int index = buttons.headSet(button).size();
|
||||||
add(button, index);
|
|
||||||
revalidate();
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeNavigation(NavigationButton button)
|
if (buttons.remove(button))
|
||||||
{
|
|
||||||
buttons.remove(button);
|
|
||||||
remove(button);
|
|
||||||
revalidate();
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onClick(NavigationButton button)
|
|
||||||
{
|
|
||||||
Supplier<PluginPanel> panelSupplier = button.getPanelSupplier();
|
|
||||||
if (panelSupplier == null)
|
|
||||||
{
|
{
|
||||||
return;
|
eventBus.post(new PluginToolbarButtonRemoved(button, index));
|
||||||
}
|
|
||||||
|
|
||||||
if (current != null)
|
|
||||||
{
|
|
||||||
current.setSelected(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current == button)
|
|
||||||
{
|
|
||||||
ui.contract();
|
|
||||||
current = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
current = button;
|
|
||||||
current.setSelected(true);
|
|
||||||
|
|
||||||
PluginPanel pluginPanel = panelSupplier.get();
|
|
||||||
ui.expand(pluginPanel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 Abex
|
* Copyright (c) 2017-2018, Adam <Adam@sigterm.info>
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -24,174 +25,78 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.ui;
|
package net.runelite.client.ui;
|
||||||
|
|
||||||
import java.awt.Component;
|
import com.google.common.eventbus.EventBus;
|
||||||
import java.awt.Container;
|
import java.util.Comparator;
|
||||||
import java.awt.Desktop;
|
import java.util.Iterator;
|
||||||
import java.awt.Dimension;
|
import java.util.TreeSet;
|
||||||
import java.awt.Image;
|
import javax.inject.Inject;
|
||||||
import java.awt.LayoutManager2;
|
import javax.inject.Singleton;
|
||||||
import java.awt.event.MouseAdapter;
|
import net.runelite.client.events.TitleToolbarButtonAdded;
|
||||||
import java.awt.event.MouseEvent;
|
import net.runelite.client.events.TitleToolbarButtonRemoved;
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.URL;
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import javax.swing.ImageIcon;
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.runelite.client.RuneLiteProperties;
|
|
||||||
import org.pushingpixels.substance.internal.SubstanceSynapse;
|
|
||||||
|
|
||||||
@Slf4j
|
/**
|
||||||
public class TitleToolbar extends JPanel
|
* Title toolbar buttons holder.
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class TitleToolbar
|
||||||
{
|
{
|
||||||
private static final int TITLEBAR_SIZE = 23;
|
private final EventBus eventBus;
|
||||||
private static final int ITEM_PADDING = 4;
|
private final TreeSet<NavigationButton> buttons = new TreeSet<>(Comparator.comparing(NavigationButton::getTooltip));
|
||||||
|
|
||||||
public TitleToolbar(RuneLiteProperties properties)
|
@Inject
|
||||||
|
private TitleToolbar(final EventBus eventBus)
|
||||||
{
|
{
|
||||||
// The only other layout manager that would manage it's preferred size without padding
|
this.eventBus = eventBus;
|
||||||
// was the GroupLayout manager, which doesn't work with dynamic layouts like this one.
|
}
|
||||||
// Primarily, it would not remove components unless it was immediately repainted.
|
|
||||||
setLayout(new LayoutManager2()
|
/**
|
||||||
|
* Add navigation.
|
||||||
|
*
|
||||||
|
* @param button the button
|
||||||
|
*/
|
||||||
|
public void addNavigation(final NavigationButton button)
|
||||||
|
{
|
||||||
|
if (buttons.contains(button))
|
||||||
{
|
{
|
||||||
@Override
|
return;
|
||||||
public void addLayoutComponent(String name, Component comp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addLayoutComponent(Component comp, Object constraints)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeLayoutComponent(Component comp)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension preferredLayoutSize(Container parent)
|
|
||||||
{
|
|
||||||
int width = parent.getComponentCount() * (TITLEBAR_SIZE + ITEM_PADDING);
|
|
||||||
return new Dimension(width, TITLEBAR_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension minimumLayoutSize(Container parent)
|
|
||||||
{
|
|
||||||
return preferredLayoutSize(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Dimension maximumLayoutSize(Container parent)
|
|
||||||
{
|
|
||||||
return preferredLayoutSize(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getLayoutAlignmentX(Container target)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getLayoutAlignmentY(Container target)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateLayout(Container target)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void layoutContainer(Container parent)
|
|
||||||
{
|
|
||||||
int x = 0;
|
|
||||||
for (Component c : parent.getComponents())
|
|
||||||
{
|
|
||||||
x += ITEM_PADDING;
|
|
||||||
int height = c.getPreferredSize().height;
|
|
||||||
if (height > TITLEBAR_SIZE)
|
|
||||||
{
|
|
||||||
height = TITLEBAR_SIZE;
|
|
||||||
}
|
|
||||||
c.setBounds(x, (TITLEBAR_SIZE - height) / 2, TITLEBAR_SIZE, height);
|
|
||||||
x += TITLEBAR_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
BufferedImage discordIcon;
|
|
||||||
BufferedImage invertedIcon;
|
|
||||||
synchronized (ImageIO.class)
|
|
||||||
{
|
|
||||||
discordIcon = ImageIO.read(ClientUI.class.getResourceAsStream("discord.png"));
|
|
||||||
invertedIcon = ImageIO.read(ClientUI.class.getResourceAsStream("discord_inverted.png"));
|
|
||||||
}
|
|
||||||
|
|
||||||
JButton discordButton = new JButton();
|
|
||||||
discordButton.setToolTipText("Join Discord");
|
|
||||||
discordButton.addMouseListener(new MouseAdapter()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(MouseEvent e)
|
|
||||||
{
|
|
||||||
super.mouseClicked(e);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Desktop.getDesktop().browse(new URL(properties.getDiscordInvite()).toURI());
|
|
||||||
}
|
|
||||||
catch (IOException | URISyntaxException ex)
|
|
||||||
{
|
|
||||||
log.warn("error opening browser", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addButton(discordButton, discordIcon, invertedIcon);
|
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
|
||||||
|
if (buttons.add(button))
|
||||||
{
|
{
|
||||||
log.warn("unable to load discord button", ex);
|
int index = buttons.headSet(button).size();
|
||||||
|
eventBus.post(new TitleToolbarButtonAdded(button, index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addButton(JButton button, Image iconImage, Image invertedIconImage)
|
/**
|
||||||
|
* Remove navigation.
|
||||||
|
*
|
||||||
|
* @param button the button
|
||||||
|
*/
|
||||||
|
public void removeNavigation(final NavigationButton button)
|
||||||
{
|
{
|
||||||
final int iconSize = TITLEBAR_SIZE - 6;
|
int index = buttons.headSet(button).size();
|
||||||
ImageIcon icon = new ImageIcon(iconImage.getScaledInstance(iconSize, iconSize, Image.SCALE_SMOOTH));
|
|
||||||
ImageIcon invertedIcon;
|
|
||||||
if (invertedIconImage == null)
|
|
||||||
{
|
|
||||||
invertedIcon = icon;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
invertedIcon = new ImageIcon(invertedIconImage.getScaledInstance(iconSize, iconSize, Image.SCALE_SMOOTH));
|
|
||||||
}
|
|
||||||
|
|
||||||
button.setIcon(icon);
|
if (buttons.remove(button))
|
||||||
button.setRolloverIcon(invertedIcon);
|
{
|
||||||
button.putClientProperty(SubstanceSynapse.FLAT_LOOK, Boolean.TRUE);
|
eventBus.post(new TitleToolbarButtonRemoved(button, index));
|
||||||
button.setFocusable(false);
|
}
|
||||||
|
|
||||||
add(button);
|
|
||||||
revalidate();
|
|
||||||
repaint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void remove(Component c)
|
* Refresh all buttons
|
||||||
|
*/
|
||||||
|
public void refresh()
|
||||||
{
|
{
|
||||||
super.remove(c);
|
final Iterator<NavigationButton> iterator = buttons.iterator();
|
||||||
revalidate();
|
int index = 0;
|
||||||
repaint();
|
|
||||||
|
while (iterator.hasNext())
|
||||||
|
{
|
||||||
|
final NavigationButton button = iterator.next();
|
||||||
|
eventBus.post(new TitleToolbarButtonRemoved(button, index));
|
||||||
|
eventBus.post(new TitleToolbarButtonAdded(button, index));
|
||||||
|
index++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,10 @@ import java.awt.datatransfer.StringSelection;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Provider;
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class used for browser navigation
|
* Utility class used for browser navigation
|
||||||
@@ -45,21 +42,13 @@ import net.runelite.client.ui.ClientUI;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class LinkBrowser
|
public class LinkBrowser
|
||||||
{
|
{
|
||||||
private final Provider<ClientUI> clientUIProvider;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private LinkBrowser(final Provider<ClientUI> clientUIProvider)
|
|
||||||
{
|
|
||||||
this.clientUIProvider = clientUIProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to navigate to specified URL in browser. In case operation fails, displays message box with message
|
* Tries to navigate to specified URL in browser. In case operation fails, displays message box with message
|
||||||
* and copies link to clipboard to navigate to.
|
* and copies link to clipboard to navigate to.
|
||||||
* @param url url to open
|
* @param url url to open
|
||||||
* @return true if operation was successful
|
* @return true if operation was successful
|
||||||
*/
|
*/
|
||||||
public boolean browse(final String url)
|
public static boolean browse(final String url)
|
||||||
{
|
{
|
||||||
if (!Desktop.isDesktopSupported())
|
if (!Desktop.isDesktopSupported())
|
||||||
{
|
{
|
||||||
@@ -93,18 +82,11 @@ public class LinkBrowser
|
|||||||
* Open swing message box with specified message and copy data to clipboard
|
* Open swing message box with specified message and copy data to clipboard
|
||||||
* @param message message to show
|
* @param message message to show
|
||||||
*/
|
*/
|
||||||
private void showMessageBox(final String message, final String data)
|
private static void showMessageBox(final String message, final String data)
|
||||||
{
|
{
|
||||||
final ClientUI clientUI = clientUIProvider.get();
|
|
||||||
|
|
||||||
if (clientUI == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() ->
|
SwingUtilities.invokeLater(() ->
|
||||||
{
|
{
|
||||||
final int result = JOptionPane.showConfirmDialog(clientUI, message, "Message",
|
final int result = JOptionPane.showConfirmDialog(null, message, "Message",
|
||||||
JOptionPane.OK_CANCEL_OPTION);
|
JOptionPane.OK_CANCEL_OPTION);
|
||||||
|
|
||||||
if (result == JOptionPane.OK_OPTION)
|
if (result == JOptionPane.OK_OPTION)
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ package net.runelite.client.util;
|
|||||||
|
|
||||||
import com.apple.eawt.Application;
|
import com.apple.eawt.Application;
|
||||||
import com.apple.eawt.FullScreenUtilities;
|
import com.apple.eawt.FullScreenUtilities;
|
||||||
|
import javax.swing.JFrame;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class with OSX-specific functions to improve integration.
|
* A class with OSX-specific functions to improve integration.
|
||||||
@@ -40,7 +40,7 @@ public class OSXUtil
|
|||||||
*
|
*
|
||||||
* @param gui The gui to enable the fullscreen on.
|
* @param gui The gui to enable the fullscreen on.
|
||||||
*/
|
*/
|
||||||
public static void tryEnableFullscreen(ClientUI gui)
|
public static void tryEnableFullscreen(JFrame gui)
|
||||||
{
|
{
|
||||||
if (OSType.getOSType() == OSType.MacOS)
|
if (OSType.getOSType() == OSType.MacOS)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,318 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.util;
|
||||||
|
|
||||||
|
import java.awt.AWTException;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.Frame;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.SystemTray;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.TrayIcon;
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
|
import javax.swing.LookAndFeel;
|
||||||
|
import javax.swing.ToolTipManager;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.UnsupportedLookAndFeelException;
|
||||||
|
import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE;
|
||||||
|
import javax.swing.plaf.FontUIResource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.client.ui.NavigationButton;
|
||||||
|
import org.pushingpixels.substance.internal.SubstanceSynapse;
|
||||||
|
import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Various Swing utilities.
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class SwingUtil
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Sets some sensible defaults for swing.
|
||||||
|
* IMPORTANT! Needs to be called before main frame creation
|
||||||
|
*/
|
||||||
|
public static void setupDefaults()
|
||||||
|
{
|
||||||
|
// Force heavy-weight popups/tooltips.
|
||||||
|
// Prevents them from being obscured by the game applet.
|
||||||
|
ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);
|
||||||
|
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
|
||||||
|
|
||||||
|
// Do not render shadows under popups/tooltips.
|
||||||
|
// Fixes black boxes under popups that are above the game applet.
|
||||||
|
System.setProperty("jgoodies.popupDropShadowEnabled", "false");
|
||||||
|
|
||||||
|
// Do not fill in background on repaint. Reduces flickering when
|
||||||
|
// the applet is resized.
|
||||||
|
System.setProperty("sun.awt.noerasebackground", "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Safely sets Swing theme
|
||||||
|
*
|
||||||
|
* @param laf the swing look and feel
|
||||||
|
*/
|
||||||
|
public static void setTheme(@Nonnull final LookAndFeel laf)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UIManager.setLookAndFeel(laf);
|
||||||
|
}
|
||||||
|
catch (UnsupportedLookAndFeelException ex)
|
||||||
|
{
|
||||||
|
log.warn("Unable to set look and feel", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets default Swing font.
|
||||||
|
* IMPORTANT! Needs to be called before main frame creation
|
||||||
|
*
|
||||||
|
* @param font the new font to use
|
||||||
|
*/
|
||||||
|
public static void setFont(@Nonnull final Font font)
|
||||||
|
{
|
||||||
|
final FontUIResource f = new FontUIResource(font);
|
||||||
|
final Enumeration keys = UIManager.getDefaults().keys();
|
||||||
|
|
||||||
|
while (keys.hasMoreElements())
|
||||||
|
{
|
||||||
|
final Object key = keys.nextElement();
|
||||||
|
final Object value = UIManager.get(key);
|
||||||
|
|
||||||
|
if (value instanceof FontUIResource)
|
||||||
|
{
|
||||||
|
UIManager.put(key, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create tray icon.
|
||||||
|
*
|
||||||
|
* @param icon the icon
|
||||||
|
* @param title the title
|
||||||
|
* @param frame the frame
|
||||||
|
* @return the tray icon
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static TrayIcon createTrayIcon(@Nonnull final Image icon, @Nonnull final String title, @Nonnull final Frame frame)
|
||||||
|
{
|
||||||
|
if (!SystemTray.isSupported())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final SystemTray systemTray = SystemTray.getSystemTray();
|
||||||
|
final TrayIcon trayIcon = new TrayIcon(icon, title);
|
||||||
|
trayIcon.setImageAutoSize(true);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
systemTray.add(trayIcon);
|
||||||
|
}
|
||||||
|
catch (AWTException ex)
|
||||||
|
{
|
||||||
|
log.debug("Unable to add system tray icon", ex);
|
||||||
|
return trayIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bring to front when tray icon is clicked
|
||||||
|
trayIcon.addMouseListener(new MouseAdapter()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e)
|
||||||
|
{
|
||||||
|
frame.setVisible(true);
|
||||||
|
frame.setState(Frame.NORMAL); // Restore
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return trayIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if point is in screen bounds.
|
||||||
|
*
|
||||||
|
* @param x the x
|
||||||
|
* @param y the y
|
||||||
|
* @return the boolean
|
||||||
|
*/
|
||||||
|
public static boolean isInScreenBounds(final int x, final int y)
|
||||||
|
{
|
||||||
|
final Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
|
final Rectangle bounds = new Rectangle(size);
|
||||||
|
return bounds.contains(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add graceful exit callback.
|
||||||
|
*
|
||||||
|
* @param frame the frame
|
||||||
|
* @param callback the callback
|
||||||
|
* @param confirmRequired the confirm required
|
||||||
|
*/
|
||||||
|
public static void addGracefulExitCallback(@Nonnull final JFrame frame, @Nonnull final Runnable callback, @Nonnull final Callable<Boolean> confirmRequired)
|
||||||
|
{
|
||||||
|
frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
||||||
|
frame.addWindowListener(new WindowAdapter()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent event)
|
||||||
|
{
|
||||||
|
int result = JOptionPane.OK_OPTION;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (confirmRequired.call())
|
||||||
|
{
|
||||||
|
result = JOptionPane.showConfirmDialog(
|
||||||
|
frame,
|
||||||
|
"Are you sure you want to exit?", "Exit",
|
||||||
|
JOptionPane .OK_CANCEL_OPTION,
|
||||||
|
JOptionPane.QUESTION_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.warn("Unexpected exception occurred while check for confirm required", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == JOptionPane.OK_OPTION)
|
||||||
|
{
|
||||||
|
callback.run();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revalidate minimum frame size.
|
||||||
|
*
|
||||||
|
* @param frame the frame
|
||||||
|
*/
|
||||||
|
public static void revalidateMinimumSize(final JFrame frame)
|
||||||
|
{
|
||||||
|
// The JFrame only respects minimumSize if it was set by setMinimumSize, for some reason. (atleast on windows/native)
|
||||||
|
frame.setMinimumSize(frame.getLayout().minimumLayoutSize(frame));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static BufferedImage resizeImage(BufferedImage image, int newWidth, int newHeight)
|
||||||
|
{
|
||||||
|
final Image tmp = image.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH);
|
||||||
|
final BufferedImage dimg = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
|
||||||
|
final Graphics2D g2d = dimg.createGraphics();
|
||||||
|
g2d.drawImage(tmp, 0, 0, null);
|
||||||
|
g2d.dispose();
|
||||||
|
return dimg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create swing button from navigation button.
|
||||||
|
*
|
||||||
|
* @param navigationButton the navigation button
|
||||||
|
* @param iconSize the icon size (in case it is 0 default icon size will be used)
|
||||||
|
* @param specialCallback the special callback
|
||||||
|
* @return the swing button
|
||||||
|
*/
|
||||||
|
public static JButton createSwingButton(
|
||||||
|
@Nonnull final NavigationButton navigationButton,
|
||||||
|
int iconSize,
|
||||||
|
@Nullable final Consumer<JButton> specialCallback)
|
||||||
|
{
|
||||||
|
|
||||||
|
final BufferedImage scaledImage = iconSize > 0
|
||||||
|
? resizeImage(navigationButton.getIcon(), iconSize, iconSize)
|
||||||
|
: navigationButton.getIcon();
|
||||||
|
|
||||||
|
final JButton button = new JButton();
|
||||||
|
button.setName(navigationButton.getName());
|
||||||
|
button.setToolTipText(navigationButton.getTooltip());
|
||||||
|
button.setIcon(new ImageIcon(scaledImage));
|
||||||
|
button.putClientProperty(SubstanceSynapse.FLAT_LOOK, Boolean.TRUE);
|
||||||
|
button.setFocusable(false);
|
||||||
|
button.addActionListener(e ->
|
||||||
|
{
|
||||||
|
if (specialCallback != null)
|
||||||
|
{
|
||||||
|
specialCallback.accept(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navigationButton.getOnClick() != null)
|
||||||
|
{
|
||||||
|
navigationButton.getOnClick().run();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (navigationButton.getPopup() != null)
|
||||||
|
{
|
||||||
|
final JPopupMenu popupMenu = new JPopupMenu();
|
||||||
|
|
||||||
|
navigationButton.getPopup().forEach((name, callback) ->
|
||||||
|
{
|
||||||
|
final JMenuItem menuItem = new JMenuItem(name);
|
||||||
|
menuItem.addActionListener((e) -> callback.run());
|
||||||
|
popupMenu.add(menuItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
button.setComponentPopupMenu(popupMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
navigationButton.setOnSelect(() -> button.setSelected(navigationButton.isSelected()));
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if custom substance title pane is present.
|
||||||
|
*
|
||||||
|
* @param frame the parent frame
|
||||||
|
* @return true if title pane is present
|
||||||
|
*/
|
||||||
|
public static boolean isCustomTitlePanePresent(final Window frame)
|
||||||
|
{
|
||||||
|
return SubstanceCoreUtilities.getTitlePaneComponent(frame) != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 67 KiB |
@@ -45,7 +45,6 @@ import joptsimple.OptionSet;
|
|||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import net.runelite.client.RuneLite;
|
import net.runelite.client.RuneLite;
|
||||||
import net.runelite.client.RuneLiteModule;
|
import net.runelite.client.RuneLiteModule;
|
||||||
import net.runelite.client.ui.ClientUI;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
@@ -67,9 +66,6 @@ public class PluginManagerTest
|
|||||||
private RuneLite runelite;
|
private RuneLite runelite;
|
||||||
private Set<Class> pluginClasses;
|
private Set<Class> pluginClasses;
|
||||||
|
|
||||||
@Mock
|
|
||||||
ClientUI clientUi;
|
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
Client client;
|
Client client;
|
||||||
|
|
||||||
@@ -83,7 +79,6 @@ public class PluginManagerTest
|
|||||||
RuneLite.setInjector(injector);
|
RuneLite.setInjector(injector);
|
||||||
|
|
||||||
runelite = injector.getInstance(RuneLite.class);
|
runelite = injector.getInstance(RuneLite.class);
|
||||||
runelite.setGui(clientUi);
|
|
||||||
|
|
||||||
// Find plugins we expect to have
|
// Find plugins we expect to have
|
||||||
pluginClasses = new HashSet<>();
|
pluginClasses = new HashSet<>();
|
||||||
|
|||||||
Reference in New Issue
Block a user