Merge remote-tracking branch 'runelite/master'

This commit is contained in:
Owain van Brakel
2021-08-30 07:21:12 +02:00
12 changed files with 466 additions and 424 deletions

View File

@@ -188,7 +188,7 @@ public class SessionManager
} }
catch (IOException ex) catch (IOException ex)
{ {
log.warn("Unable to logout of session", ex); log.warn("Unable to sign out of session", ex);
} }
accountSession = null; // No more account accountSession = null; // No more account
@@ -227,7 +227,7 @@ public class SessionManager
@Subscribe @Subscribe
public void onLoginResponse(LoginResponse loginResponse) public void onLoginResponse(LoginResponse loginResponse)
{ {
log.debug("Now logged in as {}", loginResponse.getUsername()); log.debug("Now signed in as {}", loginResponse.getUsername());
AccountSession session = getAccountSession(); AccountSession session = getAccountSession();
session.setUsername(loginResponse.getUsername()); session.setUsername(loginResponse.getUsername());

View File

@@ -75,14 +75,14 @@ public class AccountPlugin extends Plugin
loginButton = NavigationButton.builder() loginButton = NavigationButton.builder()
.tab(false) .tab(false)
.icon(LOGIN_IMAGE) .icon(LOGIN_IMAGE)
.tooltip("Log in to RuneLite") .tooltip("Sign in to RuneLite")
.onClick(this::loginClick) .onClick(this::loginClick)
.build(); .build();
logoutButton = NavigationButton.builder() logoutButton = NavigationButton.builder()
.tab(false) .tab(false)
.icon(LOGOUT_IMAGE) .icon(LOGOUT_IMAGE)
.tooltip("Log out of RuneLite") .tooltip("Sign out of RuneLite")
.onClick(this::logoutClick) .onClick(this::logoutClick)
.build(); .build();
@@ -113,7 +113,7 @@ public class AccountPlugin extends Plugin
private void logoutClick() private void logoutClick()
{ {
if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(null, if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(null,
"Are you sure you want to log out from RuneLite?", "Logout Confirmation", "Are you sure you want to sign out of RuneLite?", "Sign Out Confirmation",
JOptionPane.YES_NO_OPTION)) JOptionPane.YES_NO_OPTION))
{ {
executor.execute(sessionManager::logout); executor.execute(sessionManager::logout);

View File

@@ -189,7 +189,7 @@ public class InfoPanel extends PluginPanel
syncPanel = buildLinkPanel(IMPORT_ICON, "Import signed-out", "settings", () -> syncPanel = buildLinkPanel(IMPORT_ICON, "Import signed-out", "settings", () ->
{ {
final int result = JOptionPane.showOptionDialog(syncPanel, final int result = JOptionPane.showOptionDialog(syncPanel,
"<html>This will overwrite your settings with settings from your local profile, which<br/>is the profile used when not logged into RuneLite with a RuneLite account.</html>", "<html>This will overwrite your settings with settings from your local profile, which<br/>is the profile used when not signed into RuneLite with a RuneLite account.</html>",
"Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, "Are you sure?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
null, new String[]{"Yes", "No"}, "No"); null, new String[]{"Yes", "No"}, "No");
@@ -303,14 +303,14 @@ public class InfoPanel extends PluginPanel
{ {
emailLabel.setContentType("text/plain"); emailLabel.setContentType("text/plain");
emailLabel.setText(name); emailLabel.setText(name);
loggedLabel.setText("Logged in as"); loggedLabel.setText("Signed in as");
actionsContainer.add(syncPanel, 0); actionsContainer.add(syncPanel, 0);
} }
else else
{ {
emailLabel.setContentType("text/html"); emailLabel.setContentType("text/html");
emailLabel.setText("<a href=\"" + RUNELITE_LOGIN + "\">Login</a> to sync settings to the cloud."); emailLabel.setText("<a href=\"" + RUNELITE_LOGIN + "\">Sign in</a> to sync settings to the cloud.");
loggedLabel.setText("Not logged in"); loggedLabel.setText("Not signed in");
actionsContainer.remove(syncPanel); actionsContainer.remove(syncPanel);
} }
} }

View File

@@ -92,7 +92,7 @@ public interface LootTrackerConfig extends Config
@ConfigItem( @ConfigItem(
keyName = "syncPanel", keyName = "syncPanel",
name = "Synchronize panel contents", name = "Synchronize panel contents",
description = "Synchronize your local loot tracker with your server data (requires being logged in).<br/>" + description = "Synchronize your local loot tracker with your server data (requires being signed in).<br/>" +
" This means the panel is filled with portions of your remote data on startup<br/>" + " This means the panel is filled with portions of your remote data on startup<br/>" +
" and deleting data in the panel also deletes it on the server." " and deleting data in the panel also deletes it on the server."
) )

View File

@@ -46,6 +46,9 @@ import net.runelite.client.util.SwingUtil;
@Getter @Getter
public class TimeablePanel<T> extends JPanel public class TimeablePanel<T> extends JPanel
{ {
private static final ImageIcon NOTIFY_ICON = new ImageIcon(ImageUtil.loadImageResource(TimeTrackingPlugin.class, "notify_icon.png"));
private static final ImageIcon NOTIFY_SELECTED_ICON = new ImageIcon(ImageUtil.loadImageResource(TimeTrackingPlugin.class, "notify_selected_icon.png"));
private final T timeable; private final T timeable;
private final JLabel icon = new JLabel(); private final JLabel icon = new JLabel();
private final JLabel farmingContractIcon = new JLabel(); private final JLabel farmingContractIcon = new JLabel();
@@ -84,13 +87,10 @@ public class TimeablePanel<T> extends JPanel
infoPanel.add(text); infoPanel.add(text);
infoPanel.add(estimate); infoPanel.add(estimate);
ImageIcon notifyIcon = new ImageIcon(ImageUtil.loadImageResource(TimeTrackingPlugin.class, "notify_icon.png"));
ImageIcon notifySelectedIcon = new ImageIcon(ImageUtil.loadImageResource(TimeTrackingPlugin.class, "notify_selected_icon.png"));
notifyButton.setPreferredSize(new Dimension(30, 16)); notifyButton.setPreferredSize(new Dimension(30, 16));
notifyButton.setBorder(new EmptyBorder(0, 0, 0, 10)); notifyButton.setBorder(new EmptyBorder(0, 0, 0, 10));
notifyButton.setIcon(notifyIcon); notifyButton.setIcon(NOTIFY_ICON);
notifyButton.setSelectedIcon(notifySelectedIcon); notifyButton.setSelectedIcon(NOTIFY_SELECTED_ICON);
SwingUtil.removeButtonDecorations(notifyButton); SwingUtil.removeButtonDecorations(notifyButton);
SwingUtil.addModalTooltip(notifyButton, "Disable notifications", "Enable notifications"); SwingUtil.addModalTooltip(notifyButton, "Disable notifications", "Enable notifications");

View File

@@ -1,364 +1,402 @@
/* /*
* Copyright (c) 2018, Psikoi <https://github.com/Psikoi> * Copyright (c) 2018, Psikoi <https://github.com/Psikoi>
* 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
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this * 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. * list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, * 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * 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 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 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 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
package net.runelite.client.plugins.worldhopper; package net.runelite.client.plugins.worldhopper;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import net.runelite.client.ui.FontManager; import net.runelite.client.ui.FontManager;
import net.runelite.client.util.ImageUtil; import net.runelite.client.util.ImageUtil;
import net.runelite.http.api.worlds.World; import net.runelite.http.api.worlds.World;
import net.runelite.http.api.worlds.WorldRegion; import net.runelite.http.api.worlds.WorldRegion;
import net.runelite.http.api.worlds.WorldType; import net.runelite.http.api.worlds.WorldType;
class WorldTableRow extends JPanel class WorldTableRow extends JPanel
{ {
private static final ImageIcon FLAG_AUS; private static final ImageIcon FLAG_AUS;
private static final ImageIcon FLAG_UK; private static final ImageIcon FLAG_UK;
private static final ImageIcon FLAG_US; private static final ImageIcon FLAG_US;
private static final ImageIcon FLAG_GER; private static final ImageIcon FLAG_GER;
private static final int WORLD_COLUMN_WIDTH = 60; private static final int WORLD_COLUMN_WIDTH = 60;
private static final int PLAYERS_COLUMN_WIDTH = 40; private static final int PLAYERS_COLUMN_WIDTH = 40;
private static final int PING_COLUMN_WIDTH = 35; private static final int PING_COLUMN_WIDTH = 35;
private static final Color CURRENT_WORLD = new Color(66, 227, 17); private static final Color CURRENT_WORLD = new Color(66, 227, 17);
private static final Color DANGEROUS_WORLD = new Color(251, 62, 62); private static final Color DANGEROUS_WORLD = new Color(251, 62, 62);
private static final Color TOURNAMENT_WORLD = new Color(79, 145, 255); private static final Color TOURNAMENT_WORLD = new Color(79, 145, 255);
private static final Color MEMBERS_WORLD = new Color(210, 193, 53); private static final Color MEMBERS_WORLD = new Color(210, 193, 53);
private static final Color FREE_WORLD = new Color(200, 200, 200); private static final Color FREE_WORLD = new Color(200, 200, 200);
private static final Color SEASONAL_WORLD = new Color(133, 177, 178); private static final Color SEASONAL_WORLD = new Color(133, 177, 178);
static static
{ {
FLAG_AUS = new ImageIcon(ImageUtil.loadImageResource(WorldHopperPlugin.class, "flag_aus.png")); FLAG_AUS = new ImageIcon(ImageUtil.loadImageResource(WorldHopperPlugin.class, "flag_aus.png"));
FLAG_UK = new ImageIcon(ImageUtil.loadImageResource(WorldHopperPlugin.class, "flag_uk.png")); FLAG_UK = new ImageIcon(ImageUtil.loadImageResource(WorldHopperPlugin.class, "flag_uk.png"));
FLAG_US = new ImageIcon(ImageUtil.loadImageResource(WorldHopperPlugin.class, "flag_us.png")); FLAG_US = new ImageIcon(ImageUtil.loadImageResource(WorldHopperPlugin.class, "flag_us.png"));
FLAG_GER = new ImageIcon(ImageUtil.loadImageResource(WorldHopperPlugin.class, "flag_ger.png")); FLAG_GER = new ImageIcon(ImageUtil.loadImageResource(WorldHopperPlugin.class, "flag_ger.png"));
} }
private final JMenuItem favoriteMenuOption = new JMenuItem(); private final JMenuItem favoriteMenuOption = new JMenuItem();
private JLabel worldField; private JLabel worldField;
private JLabel playerCountField; private JLabel playerCountField;
private JLabel activityField; private JLabel activityField;
private JLabel pingField; private JLabel pingField;
private final BiConsumer<World, Boolean> onFavorite; private final BiConsumer<World, Boolean> onFavorite;
@Getter @Getter
private final World world; private final World world;
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
private int updatedPlayerCount; private int updatedPlayerCount;
private int ping; private int ping;
private Color lastBackground; private Color lastBackground;
WorldTableRow(World world, boolean current, boolean favorite, Integer ping, Consumer<World> onSelect, BiConsumer<World, Boolean> onFavorite) WorldTableRow(World world, boolean current, boolean favorite, Integer ping, Consumer<World> onSelect, BiConsumer<World, Boolean> onFavorite)
{ {
this.world = world; this.world = world;
this.onFavorite = onFavorite; this.onFavorite = onFavorite;
this.updatedPlayerCount = world.getPlayers(); this.updatedPlayerCount = world.getPlayers();
setLayout(new BorderLayout()); setLayout(new BorderLayout());
setBorder(new EmptyBorder(2, 0, 2, 0)); setBorder(new EmptyBorder(2, 0, 2, 0));
addMouseListener(new MouseAdapter() addMouseListener(new MouseAdapter()
{ {
@Override @Override
public void mouseClicked(MouseEvent mouseEvent) public void mouseClicked(MouseEvent mouseEvent)
{ {
if (mouseEvent.getClickCount() == 2) if (mouseEvent.getClickCount() == 2)
{ {
if (onSelect != null) if (onSelect != null)
{ {
onSelect.accept(world); onSelect.accept(world);
} }
} }
} }
@Override @Override
public void mousePressed(MouseEvent mouseEvent) public void mousePressed(MouseEvent mouseEvent)
{ {
if (mouseEvent.getClickCount() == 2) if (mouseEvent.getClickCount() == 2)
{ {
setBackground(getBackground().brighter()); setBackground(getBackground().brighter());
} }
} }
@Override @Override
public void mouseReleased(MouseEvent mouseEvent) public void mouseReleased(MouseEvent mouseEvent)
{ {
if (mouseEvent.getClickCount() == 2) if (mouseEvent.getClickCount() == 2)
{ {
setBackground(getBackground().darker()); setBackground(getBackground().darker());
} }
} }
@Override @Override
public void mouseEntered(MouseEvent mouseEvent) public void mouseEntered(MouseEvent mouseEvent)
{ {
WorldTableRow.this.lastBackground = getBackground(); WorldTableRow.this.lastBackground = getBackground();
setBackground(getBackground().brighter()); setBackground(getBackground().brighter());
} }
@Override @Override
public void mouseExited(MouseEvent mouseEvent) public void mouseExited(MouseEvent mouseEvent)
{ {
setBackground(lastBackground); setBackground(lastBackground);
} }
}); });
setFavoriteMenu(favorite); setFavoriteMenu(favorite);
final JPopupMenu popupMenu = new JPopupMenu(); final JPopupMenu popupMenu = new JPopupMenu();
popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5)); popupMenu.setBorder(new EmptyBorder(5, 5, 5, 5));
popupMenu.add(favoriteMenuOption); popupMenu.add(favoriteMenuOption);
setComponentPopupMenu(popupMenu); setComponentPopupMenu(popupMenu);
JPanel leftSide = new JPanel(new BorderLayout()); JPanel leftSide = new JPanel(new BorderLayout());
JPanel rightSide = new JPanel(new BorderLayout()); JPanel rightSide = new JPanel(new BorderLayout());
leftSide.setOpaque(false); leftSide.setOpaque(false);
rightSide.setOpaque(false); rightSide.setOpaque(false);
JPanel worldField = buildWorldField(); JPanel worldField = buildWorldField();
worldField.setPreferredSize(new Dimension(WORLD_COLUMN_WIDTH, 0)); worldField.setPreferredSize(new Dimension(WORLD_COLUMN_WIDTH, 0));
worldField.setOpaque(false); worldField.setOpaque(false);
JPanel pingField = buildPingField(ping); JPanel pingField = buildPingField(ping);
pingField.setPreferredSize(new Dimension(PING_COLUMN_WIDTH, 0)); pingField.setPreferredSize(new Dimension(PING_COLUMN_WIDTH, 0));
pingField.setOpaque(false); pingField.setOpaque(false);
JPanel playersField = buildPlayersField(); JPanel playersField = buildPlayersField();
playersField.setPreferredSize(new Dimension(PLAYERS_COLUMN_WIDTH, 0)); playersField.setPreferredSize(new Dimension(PLAYERS_COLUMN_WIDTH, 0));
playersField.setOpaque(false); playersField.setOpaque(false);
JPanel activityField = buildActivityField(); JPanel activityField = buildActivityField();
activityField.setBorder(new EmptyBorder(5, 5, 5, 5)); activityField.setBorder(new EmptyBorder(5, 5, 5, 5));
activityField.setOpaque(false); activityField.setOpaque(false);
recolour(current); recolour(current);
leftSide.add(worldField, BorderLayout.WEST); leftSide.add(worldField, BorderLayout.WEST);
leftSide.add(playersField, BorderLayout.CENTER); leftSide.add(playersField, BorderLayout.CENTER);
rightSide.add(activityField, BorderLayout.CENTER); rightSide.add(activityField, BorderLayout.CENTER);
rightSide.add(pingField, BorderLayout.EAST); rightSide.add(pingField, BorderLayout.EAST);
add(leftSide, BorderLayout.WEST); add(leftSide, BorderLayout.WEST);
add(rightSide, BorderLayout.CENTER); add(rightSide, BorderLayout.CENTER);
} }
void setFavoriteMenu(boolean favorite) void setFavoriteMenu(boolean favorite)
{ {
String favoriteAction = favorite ? String favoriteAction = favorite ?
"Remove " + world.getId() + " from favorites" : "Remove " + world.getId() + " from favorites" :
"Add " + world.getId() + " to favorites"; "Add " + world.getId() + " to favorites";
favoriteMenuOption.setText(favoriteAction); favoriteMenuOption.setText(favoriteAction);
for (ActionListener listener : favoriteMenuOption.getActionListeners()) for (ActionListener listener : favoriteMenuOption.getActionListeners())
{ {
favoriteMenuOption.removeActionListener(listener); favoriteMenuOption.removeActionListener(listener);
} }
favoriteMenuOption.addActionListener(e -> favoriteMenuOption.addActionListener(e ->
{ {
onFavorite.accept(world, !favorite); onFavorite.accept(world, !favorite);
}); });
} }
void updatePlayerCount(int playerCount) void updatePlayerCount(int playerCount)
{ {
this.updatedPlayerCount = playerCount; this.updatedPlayerCount = playerCount;
playerCountField.setText(playerCountString(playerCount)); playerCountField.setText(playerCountString(playerCount));
} }
private static String playerCountString(int playerCount) private static String playerCountString(int playerCount)
{ {
return playerCount < 0 ? "OFF" : Integer.toString(playerCount); return playerCount < 0 ? "OFF" : Integer.toString(playerCount);
} }
void setPing(int ping) void setPing(int ping)
{ {
this.ping = ping; this.ping = ping;
pingField.setText(ping <= 0 ? "-" : Integer.toString(ping)); pingField.setText(ping <= 0 ? "-" : Integer.toString(ping));
} }
void hidePing() void hidePing()
{ {
pingField.setText("-"); pingField.setText("-");
} }
void showPing() void showPing()
{ {
setPing(ping); // to update pingField setPing(ping); // to update pingField
} }
int getPing() int getPing()
{ {
return ping; return ping;
} }
public void recolour(boolean current) public void recolour(boolean current)
{ {
playerCountField.setForeground(current ? CURRENT_WORLD : Color.WHITE); playerCountField.setForeground(current ? CURRENT_WORLD : Color.WHITE);
pingField.setForeground(current ? CURRENT_WORLD : Color.WHITE); pingField.setForeground(current ? CURRENT_WORLD : Color.WHITE);
if (current) if (current)
{ {
activityField.setForeground(CURRENT_WORLD); activityField.setForeground(CURRENT_WORLD);
worldField.setForeground(CURRENT_WORLD); worldField.setForeground(CURRENT_WORLD);
return; return;
} }
else if (world.getTypes().contains(WorldType.PVP) else if (world.getTypes().contains(WorldType.PVP)
|| world.getTypes().contains(WorldType.HIGH_RISK) || world.getTypes().contains(WorldType.HIGH_RISK)
|| world.getTypes().contains(WorldType.DEADMAN)) || world.getTypes().contains(WorldType.DEADMAN))
{ {
activityField.setForeground(DANGEROUS_WORLD); activityField.setForeground(DANGEROUS_WORLD);
} }
else if (world.getTypes().contains(WorldType.SEASONAL)) else if (world.getTypes().contains(WorldType.SEASONAL))
{ {
activityField.setForeground(SEASONAL_WORLD); activityField.setForeground(SEASONAL_WORLD);
} }
else if (world.getTypes().contains(WorldType.NOSAVE_MODE)) else if (world.getTypes().contains(WorldType.NOSAVE_MODE))
{ {
activityField.setForeground(TOURNAMENT_WORLD); activityField.setForeground(TOURNAMENT_WORLD);
} }
else else
{ {
activityField.setForeground(Color.WHITE); activityField.setForeground(Color.WHITE);
} }
worldField.setForeground(world.getTypes().contains(WorldType.MEMBERS) ? MEMBERS_WORLD : FREE_WORLD); worldField.setForeground(world.getTypes().contains(WorldType.MEMBERS) ? MEMBERS_WORLD : FREE_WORLD);
} }
/** /**
* Builds the players list field (containing the amount of players logged in that world). * Builds the players list field (containing the amount of players logged in that world).
*/ */
private JPanel buildPlayersField() private JPanel buildPlayersField()
{ {
JPanel column = new JPanel(new BorderLayout()); JPanel column = new JPanel(new BorderLayout());
column.setBorder(new EmptyBorder(0, 5, 0, 5)); column.setBorder(new EmptyBorder(0, 5, 0, 5));
playerCountField = new JLabel(playerCountString(world.getPlayers())); playerCountField = new JLabel(playerCountString(world.getPlayers()));
playerCountField.setFont(FontManager.getRunescapeSmallFont()); playerCountField.setFont(FontManager.getRunescapeSmallFont());
column.add(playerCountField, BorderLayout.WEST); column.add(playerCountField, BorderLayout.WEST);
return column; return column;
} }
private JPanel buildPingField(Integer ping) private JPanel buildPingField(Integer ping)
{ {
JPanel column = new JPanel(new BorderLayout()); JPanel column = new JPanel(new BorderLayout());
column.setBorder(new EmptyBorder(0, 5, 0, 5)); column.setBorder(new EmptyBorder(0, 5, 0, 5));
pingField = new JLabel("-"); pingField = new JLabel("-");
pingField.setFont(FontManager.getRunescapeSmallFont()); pingField.setFont(FontManager.getRunescapeSmallFont());
column.add(pingField, BorderLayout.EAST); column.add(pingField, BorderLayout.EAST);
if (ping != null) if (ping != null)
{ {
setPing(ping); setPing(ping);
} }
return column; return column;
} }
/** /**
* Builds the activity list field (containing that world's activity/theme). * Builds the activity list field (containing that world's activity/theme).
*/ */
private JPanel buildActivityField() private JPanel buildActivityField()
{ {
JPanel column = new JPanel(new BorderLayout()); JPanel column = new JPanel(new BorderLayout());
column.setBorder(new EmptyBorder(0, 5, 0, 5)); column.setBorder(new EmptyBorder(0, 5, 0, 5));
activityField = new JLabel(world.getActivity()); String activity = world.getActivity();
activityField.setFont(FontManager.getRunescapeSmallFont()); activityField = new JLabel(activity);
activityField.setFont(FontManager.getRunescapeSmallFont());
column.add(activityField, BorderLayout.WEST); if (activity != null && activity.length() > 16)
{
return column; activityField.setToolTipText(activity);
} // Pass up events - https://stackoverflow.com/a/14932443
activityField.addMouseListener(new MouseAdapter()
/** {
* Builds the world list field (containing the country's flag and the world index). @Override
*/ public void mouseClicked(MouseEvent e)
private JPanel buildWorldField() {
{ dispatchEvent(e);
JPanel column = new JPanel(new BorderLayout(7, 0)); }
column.setBorder(new EmptyBorder(0, 5, 0, 5));
@Override
worldField = new JLabel(world.getId() + ""); public void mousePressed(MouseEvent e)
{
ImageIcon flagIcon = getFlag(world.getRegion()); dispatchEvent(e);
if (flagIcon != null) }
{
JLabel flag = new JLabel(flagIcon); @Override
column.add(flag, BorderLayout.WEST); public void mouseReleased(MouseEvent e)
} {
column.add(worldField, BorderLayout.CENTER); dispatchEvent(e);
}
return column;
} @Override
public void mouseEntered(MouseEvent e)
private static ImageIcon getFlag(WorldRegion region) {
{ dispatchEvent(e);
if (region == null) }
{
return null; @Override
} public void mouseExited(MouseEvent e)
{
switch (region) dispatchEvent(e);
{ }
case UNITED_STATES_OF_AMERICA: });
return FLAG_US; }
case UNITED_KINGDOM:
return FLAG_UK; column.add(activityField, BorderLayout.WEST);
case AUSTRALIA:
return FLAG_AUS; return column;
case GERMANY: }
return FLAG_GER;
default: /**
return null; * Builds the world list field (containing the country's flag and the world index).
} */
} private JPanel buildWorldField()
} {
JPanel column = new JPanel(new BorderLayout(7, 0));
column.setBorder(new EmptyBorder(0, 5, 0, 5));
worldField = new JLabel(world.getId() + "");
ImageIcon flagIcon = getFlag(world.getRegion());
if (flagIcon != null)
{
JLabel flag = new JLabel(flagIcon);
column.add(flag, BorderLayout.WEST);
}
column.add(worldField, BorderLayout.CENTER);
return column;
}
private static ImageIcon getFlag(WorldRegion region)
{
if (region == null)
{
return null;
}
switch (region)
{
case UNITED_STATES_OF_AMERICA:
return FLAG_US;
case UNITED_KINGDOM:
return FLAG_UK;
case AUSTRALIA:
return FLAG_AUS;
case GERMANY:
return FLAG_GER;
default:
return null;
}
}
}

View File

@@ -129,10 +129,7 @@ public abstract class Overlay implements LayoutableRenderableEntity
return null; return null;
} }
public void reset() public void revalidate()
{ {
setPreferredPosition(null);
setPreferredSize(null);
setPreferredLocation(null);
} }
} }

View File

@@ -289,8 +289,11 @@ public class OverlayManager
*/ */
public synchronized void resetOverlay(final Overlay overlay) public synchronized void resetOverlay(final Overlay overlay)
{ {
overlay.reset(); overlay.setPreferredPosition(null);
overlay.setPreferredSize(null);
overlay.setPreferredLocation(null);
saveOverlay(overlay); saveOverlay(overlay);
overlay.revalidate();
} }
synchronized void rebuildOverlayLayers() synchronized void rebuildOverlayLayers()

View File

@@ -289,25 +289,18 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
final Dimension dimension = bounds.getSize(); final Dimension dimension = bounds.getSize();
final Point preferredLocation = overlay.getPreferredLocation(); final Point preferredLocation = overlay.getPreferredLocation();
Point location; Point location;
Rectangle snapCorner = null;
// If the final position is not modified, layout it // If the final position is not modified, layout it
if (overlayPosition != OverlayPosition.DETACHED && (preferredLocation == null || overlay.getPreferredPosition() != null)) if (overlayPosition != OverlayPosition.DETACHED && (preferredLocation == null || overlay.getPreferredPosition() != null))
{ {
final Rectangle snapCorner = snapCorners.forPosition(overlayPosition); snapCorner = snapCorners.forPosition(overlayPosition);
final Point translation = OverlayUtil.transformPosition(overlayPosition, dimension); // offset from corner final Point translation = OverlayUtil.transformPosition(overlayPosition, dimension); // offset from corner
// Target x/y to draw the overlay // Target x/y to draw the overlay
int destX = (int) snapCorner.getX() + translation.x; int destX = snapCorner.x + translation.x;
int destY = (int) snapCorner.getY() + translation.y; int destY = snapCorner.y + translation.y;
// Clamp the target position to ensure it is on screen or within parent bounds // Clamp the target position to ensure it is on screen or within parent bounds
location = clampOverlayLocation(destX, destY, dimension.width, dimension.height, overlay); location = clampOverlayLocation(destX, destY, dimension.width, dimension.height, overlay);
// Diff final position to target position in order to add it to the snap corner padding. The
// overlay effectively takes up the difference of (clamped location - target location) in
// addition to its normal dimensions.
int dX = location.x - destX;
int dY = location.y - destY;
final Point padding = OverlayUtil.padPosition(overlayPosition, dimension, PADDING); // overlay size + fixed padding
// translate corner for padding and any difference due to the position clamping
snapCorner.translate(padding.x + dX, padding.y + dY);
} }
else else
{ {
@@ -324,6 +317,12 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
safeRender(client, overlay, layer, graphics, location); safeRender(client, overlay, layer, graphics, location);
// Adjust snap corner based on where the overlay was drawn
if (snapCorner != null && bounds.width + bounds.height > 0)
{
OverlayUtil.shiftSnapCorner(overlayPosition, snapCorner, bounds, PADDING);
}
// Restore graphics2d properties prior to drawing bounds // Restore graphics2d properties prior to drawing bounds
graphics.setTransform(transform); graphics.setTransform(transform);
graphics.setStroke(stroke); graphics.setStroke(stroke);
@@ -703,7 +702,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
{ {
OverlayPosition position = snapCorners.fromBounds(snapCorner); OverlayPosition position = snapCorners.fromBounds(snapCorner);
if (position == currentManagedOverlay.getPosition()) if (position == getCorrectedOverlayPosition(currentManagedOverlay))
{ {
// overlay moves back to default position // overlay moves back to default position
position = null; position = null;
@@ -711,6 +710,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
currentManagedOverlay.setPreferredPosition(position); currentManagedOverlay.setPreferredPosition(position);
currentManagedOverlay.setPreferredLocation(null); // from dragging currentManagedOverlay.setPreferredLocation(null); // from dragging
currentManagedOverlay.revalidate();
break; break;
} }
} }

View File

@@ -30,6 +30,7 @@ import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Polygon; import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import java.awt.Shape; import java.awt.Shape;
import java.awt.Stroke; import java.awt.Stroke;
@@ -201,33 +202,32 @@ public class OverlayUtil
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
} }
public static java.awt.Point padPosition(OverlayPosition position, Dimension dimension, final int padding) static void shiftSnapCorner(OverlayPosition overlayPosition, Rectangle snapCorner, Rectangle bounds, int padding)
{ {
final java.awt.Point result = new java.awt.Point(); // translate corner for padding and also based on where the overlay bounds are now
int sX = snapCorner.x, sY = snapCorner.y;
switch (position) switch (overlayPosition)
{ {
case DYNAMIC:
case TOOLTIP:
break;
case BOTTOM_LEFT: case BOTTOM_LEFT:
result.x += dimension.width + (dimension.width == 0 ? 0 : padding); sX = bounds.x + bounds.width + padding;
break; break;
case BOTTOM_RIGHT: case BOTTOM_RIGHT:
result.x -= dimension.width + (dimension.width == 0 ? 0 : padding); sX = bounds.x - padding;
break; break;
case TOP_LEFT: case TOP_LEFT:
case TOP_CENTER: case TOP_CENTER:
case CANVAS_TOP_RIGHT: case CANVAS_TOP_RIGHT:
case TOP_RIGHT: case TOP_RIGHT:
result.y += dimension.height + (dimension.height == 0 ? 0 : padding); sY = bounds.y + bounds.height + padding;
break; break;
case ABOVE_CHATBOX_RIGHT: case ABOVE_CHATBOX_RIGHT:
result.y -= dimension.height + (dimension.height == 0 ? 0 : padding); sY = bounds.y - padding;
break; break;
default:
throw new IllegalArgumentException();
} }
snapCorner.x = sX;
return result; snapCorner.y = sY;
} }
public static java.awt.Point transformPosition(OverlayPosition position, Dimension dimension) public static java.awt.Point transformPosition(OverlayPosition position, Dimension dimension)

View File

@@ -121,9 +121,9 @@ public class WidgetOverlay extends Overlay
assert widget != null; assert widget != null;
final Rectangle bounds = getBounds(); final Rectangle bounds = getBounds();
// OverlayRenderer sets the overlay bounds to the preferred location if one is set prior to calling render() // OverlayRenderer sets the overlay bounds to where it would like the overlay to render at prior to calling
// for detached overlays. // render(). If the overlay has a preferred location or position set we update the widget position to that.
if (getPosition() != OverlayPosition.DETACHED || getPreferredLocation() != null) if (getPreferredLocation() != null || getPreferredPosition() != null)
{ {
// The widget relative pos is relative to the parent // The widget relative pos is relative to the parent
widget.setRelativeX(bounds.x - parent.x); widget.setRelativeX(bounds.x - parent.x);
@@ -188,9 +188,8 @@ public class WidgetOverlay extends Overlay
} }
@Override @Override
public void reset() public void revalidate()
{ {
super.reset();
// Revalidate must be called on the client thread, so defer til next frame // Revalidate must be called on the client thread, so defer til next frame
revalidate = true; revalidate = true;
} }

View File

@@ -11,6 +11,10 @@
{ {
"name": "Chaos Altar (700%)", "name": "Chaos Altar (700%)",
"value": 6 "value": 6
},
{
"name": "Morytania Diary 3 Shades(150%)",
"value": 0.5
} }
], ],
"actions": [ "actions": [
@@ -219,8 +223,7 @@
"level": 1, "level": 1,
"icon": 3396, "icon": 3396,
"name": "Loar Remains", "name": "Loar Remains",
"xp": 33, "xp": 33
"ignoreBonus": true
}, },
{ {
"level": 1, "level": 1,
@@ -274,8 +277,7 @@
"level": 1, "level": 1,
"icon": 3398, "icon": 3398,
"name": "Phrin Remains", "name": "Phrin Remains",
"xp": 46.5, "xp": 46.5
"ignoreBonus": true
}, },
{ {
"level": 1, "level": 1,
@@ -287,8 +289,7 @@
"level": 1, "level": 1,
"icon": 3400, "icon": 3400,
"name": "Riyl Remains", "name": "Riyl Remains",
"xp": 59.5, "xp": 59.5
"ignoreBonus": true
}, },
{ {
"level": 1, "level": 1,
@@ -312,8 +313,7 @@
"level": 1, "level": 1,
"icon": 3402, "icon": 3402,
"name": "Asyn Remains", "name": "Asyn Remains",
"xp": 82.5, "xp": 82.5
"ignoreBonus": true
}, },
{ {
"level": 1, "level": 1,
@@ -325,8 +325,7 @@
"level": 1, "level": 1,
"icon": 3404, "icon": 3404,
"name": "Fiyr Remains", "name": "Fiyr Remains",
"xp": 84, "xp": 84
"ignoreBonus": true
}, },
{ {
"level": 1, "level": 1,
@@ -363,6 +362,12 @@
"icon": 22124, "icon": 22124,
"name": "Superior Dragon Bones", "name": "Superior Dragon Bones",
"xp": 150 "xp": 150
},
{
"level": 1,
"icon": 25419,
"name": "Urium Remains",
"xp": 120
} }
] ]
} }