Merge pull request #2509 from Owain94/upstream-1904

project: Merge upstream
This commit is contained in:
Owain van Brakel
2020-04-19 14:30:07 +02:00
committed by GitHub
32 changed files with 812 additions and 280 deletions
+2 -2
View File
@@ -25,9 +25,9 @@
object ProjectVersions {
const val launcherVersion = "2.2.0"
const val rlVersion = "1.6.10"
const val rlVersion = "1.6.11"
const val openosrsVersion = "3.2.1"
const val openosrsVersion = "3.2.2"
const val openosrsInjectorVersion = "1.0.3.1"
const val rsversion = 189
@@ -29,6 +29,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import net.runelite.http.api.RuneLiteAPI;
import okhttp3.Call;
import okhttp3.Callback;
@@ -77,8 +78,10 @@ public class ConfigClient
}
}
public void set(String key, String value)
public CompletableFuture<Void> set(String key, String value)
{
CompletableFuture<Void> future = new CompletableFuture<>();
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
.addPathSegment("config")
.addPathSegment(key)
@@ -98,6 +101,7 @@ public class ConfigClient
public void onFailure(Call call, IOException e)
{
logger.warn("Unable to synchronize configuration item", e);
future.completeExceptionally(e);
}
@Override
@@ -105,12 +109,17 @@ public class ConfigClient
{
response.close();
logger.debug("Synchronized configuration value '{}' to '{}'", key, value);
future.complete(null);
}
});
return future;
}
public void unset(String key)
public CompletableFuture<Void> unset(String key)
{
CompletableFuture<Void> future = new CompletableFuture<>();
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
.addPathSegment("config")
.addPathSegment(key)
@@ -130,6 +139,7 @@ public class ConfigClient
public void onFailure(Call call, IOException e)
{
logger.warn("Unable to unset configuration item", e);
future.completeExceptionally(e);
}
@Override
@@ -137,7 +147,10 @@ public class ConfigClient
{
response.close();
logger.debug("Unset configuration value '{}'", key);
future.complete(null);
}
});
return future;
}
}
@@ -33,6 +33,7 @@ import java.io.InputStreamReader;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.runelite.http.api.RuneLiteAPI;
@@ -52,8 +53,10 @@ public class LootTrackerClient
private final UUID uuid;
public void submit(Collection<LootRecord> lootRecords)
public CompletableFuture<Void> submit(Collection<LootRecord> lootRecords)
{
CompletableFuture<Void> future = new CompletableFuture<>();
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
.addPathSegment("loottracker")
.build();
@@ -71,6 +74,7 @@ public class LootTrackerClient
public void onFailure(Call call, IOException e)
{
log.warn("unable to submit loot", e);
future.completeExceptionally(e);
}
@Override
@@ -78,8 +82,11 @@ public class LootTrackerClient
{
log.debug("Submitted loot");
response.close();
future.complete(null);
}
});
return future;
}
public Collection<LootRecord> get() throws IOException
@@ -121,6 +121,10 @@ public final class AnimationID
public static final int FISHING_BAREHAND_CAUGHT_SWORDFISH_2 = 6708;
public static final int FISHING_BAREHAND_CAUGHT_TUNA_1 = 6710;
public static final int FISHING_BAREHAND_CAUGHT_TUNA_2 = 6711;
public static final int FISHING_PEARL_ROD = 8188;
public static final int FISHING_PEARL_FLY_ROD = 8189;
public static final int FISHING_PEARL_BARBARIAN_ROD = 8190;
public static final int FISHING_PEARL_OILY_ROD = 6932;
public static final int MINING_BRONZE_PICKAXE = 625;
public static final int MINING_IRON_PICKAXE = 626;
public static final int MINING_STEEL_PICKAXE = 627;
@@ -138,6 +138,13 @@ public interface Client extends GameShell
*/
void setGameState(GameState gameState);
/**
* Causes the client to shutdown. It is faster than
* {@link java.applet.Applet#stop()} because it doesn't wait for 4000ms.
* This will call {@link System#exit} when it is done
*/
void stopNow();
/**
* Gets the current logged in username.
*
@@ -11426,8 +11426,13 @@ public final class ItemID
public static final int CARROT = 24546;
public static final int BROKEN_GOAT_HORN = 24547;
public static final int CAKE_24549 = 24549;
public static final int BLADE_OF_SAELDOR_I = 24551;
public static final int BLADE_OF_SAELDOR_I_24553 = 24553;
public static final int BLADE_OF_SAELDOR_C = 24551;
public static final int BLADE_OF_SAELDOR_C_24553 = 24553;
public static final int PYROMANCER_SET = 24554;
public static final int TANGLEROOT_24555 = 24555;
public static final int TANGLEROOT_24557 = 24557;
public static final int TANGLEROOT_24559 = 24559;
public static final int TANGLEROOT_24561 = 24561;
public static final int TANGLEROOT_24563 = 24563;
/* This file is automatically generated. Do not edit. */
}
@@ -5993,7 +5993,6 @@ public final class NpcID
public static final int SISTER_SCAROPHIA = 6590;
public static final int LAVA_DRAGON = 6593;
public static final int ENT = 6594;
public static final int THE_DISAPPOINTING_GELT = 6595;
public static final int ZOMBIE_6596 = 6596;
public static final int ZOMBIE_6597 = 6597;
public static final int ZOMBIE_6598 = 6598;
@@ -8483,21 +8482,17 @@ public final class NpcID
public static final int SISTER_SENGA = 9471;
public static final int SISTER_SENGA_9472 = 9472;
public static final int ENT_TRUNK = 9474;
public static final int DUKE_RABBACIO = 9475;
public static final int PAWS = 9476;
public static final int RABBIT_CHEF = 9477;
public static final int GUARD_9478 = 9478;
public static final int MAGIC_EGG = 9479;
public static final int RABBIT_9480 = 9480;
public static final int RABBIT_9481 = 9481;
public static final int RABBIT_9482 = 9482;
public static final int RID = 9483;
public static final int FARMER_MAGGOT = 9484;
public static final int FATHER_BUCKEREK = 9485;
public static final int RESTLESS_GOAT = 9486;
public static final int SHOP_KEEPER_9487 = 9487;
public static final int BARTENDER_9488 = 9488;
public static final int COW_CALF_9489 = 9489;
public static final int CHICKEN_9490 = 9490;
public static final int TANGLEROOT_9492 = 9492;
public static final int TANGLEROOT_9493 = 9493;
public static final int TANGLEROOT_9494 = 9494;
public static final int TANGLEROOT_9495 = 9495;
public static final int TANGLEROOT_9496 = 9496;
public static final int TANGLEROOT_9497 = 9497;
public static final int TANGLEROOT_9498 = 9498;
public static final int TANGLEROOT_9499 = 9499;
public static final int TANGLEROOT_9500 = 9500;
public static final int TANGLEROOT_9501 = 9501;
public static final int IORWERTH_WARRIOR_9502 = 9502;
public static final int IORWERTH_WARRIOR_9503 = 9503;
/* This file is automatically generated. Do not edit. */
}
@@ -12917,5 +12917,10 @@ public final class NullItemID
public static final int NULL_24548 = 24548;
public static final int NULL_24550 = 24550;
public static final int NULL_24552 = 24552;
public static final int NULL_24556 = 24556;
public static final int NULL_24558 = 24558;
public static final int NULL_24560 = 24560;
public static final int NULL_24562 = 24562;
public static final int NULL_24564 = 24564;
/* This file is automatically generated. Do not edit. */
}
@@ -14123,10 +14123,6 @@ public final class NullObjectID
public static final int NULL_30144 = 30144;
public static final int NULL_30156 = 30156;
public static final int NULL_30159 = 30159;
public static final int NULL_30165 = 30165;
public static final int NULL_30166 = 30166;
public static final int NULL_30167 = 30167;
public static final int NULL_30168 = 30168;
public static final int NULL_30171 = 30171;
public static final int NULL_30181 = 30181;
public static final int NULL_30182 = 30182;
@@ -14981,7 +14977,6 @@ public final class NullObjectID
public static final int NULL_31895 = 31895;
public static final int NULL_31896 = 31896;
public static final int NULL_31897 = 31897;
public static final int NULL_31899 = 31899;
public static final int NULL_31937 = 31937;
public static final int NULL_31938 = 31938;
public static final int NULL_31945 = 31945;
@@ -16166,7 +16161,6 @@ public final class NullObjectID
public static final int NULL_34678 = 34678;
public static final int NULL_34679 = 34679;
public static final int NULL_34680 = 34680;
public static final int NULL_34688 = 34688;
public static final int NULL_34689 = 34689;
public static final int NULL_34690 = 34690;
public static final int NULL_34691 = 34691;
@@ -18168,7 +18162,6 @@ public final class NullObjectID
public static final int NULL_37722 = 37722;
public static final int NULL_37723 = 37723;
public static final int NULL_37724 = 37724;
public static final int NULL_37725 = 37725;
public static final int NULL_37732 = 37732;
public static final int NULL_37733 = 37733;
public static final int NULL_37734 = 37734;
@@ -18336,11 +18329,7 @@ public final class NullObjectID
public static final int NULL_37933 = 37933;
public static final int NULL_37934 = 37934;
public static final int NULL_37935 = 37935;
public static final int NULL_37940 = 37940;
public static final int NULL_37945 = 37945;
public static final int NULL_37947 = 37947;
public static final int NULL_37950 = 37950;
public static final int NULL_37956 = 37956;
public static final int NULL_37958 = 37958;
/* This file is automatically generated. Do not edit. */
}
@@ -15803,8 +15803,6 @@ public final class ObjectID
public static final int POOL_OF_NIGHTMARES = 29706;
public static final int POOL_OF_NIGHTMARES_29707 = 29707;
public static final int SCOREBOARD_29708 = 29708;
public static final int MAGIC_PORTAL_29711 = 29711;
public static final int PAINT_BUCKETS = 29712;
public static final int NOTICEBOARD_29718 = 29718;
public static final int BALLISTA_29719 = 29719;
public static final int STAIRCASE_29720 = 29720;
@@ -16025,11 +16023,6 @@ public final class ObjectID
public static final int PAINTING_30155 = 30155;
public static final int FURNACE_30157 = 30157;
public static final int FURNACE_30158 = 30158;
public static final int BROKEN_EGG = 30160;
public static final int CONCH_SHELL = 30161;
public static final int THE_MAGIC_EGG = 30162;
public static final int CAKE = 30163;
public static final int CARROT = 30164;
public static final int CRACK_30169 = 30169;
public static final int ROOT_30170 = 30170;
public static final int PORTAL_30172 = 30172;
@@ -19545,9 +19538,6 @@ public final class ObjectID
public static final int NIGHTMARE_TOPIARY = 37630;
public static final int SUPPLIES_37631 = 37631;
public static final int BANNER_37726 = 37726;
public static final int RABBIT = 37727;
public static final int RABBIT_37728 = 37728;
public static final int GRAVE_37729 = 37729;
public static final int ENERGY_BARRIER_37730 = 37730;
public static final int ENERGY_BARRIER_37731 = 37731;
public static final int SPORE = 37738;
@@ -19590,19 +19580,8 @@ public final class ObjectID
public static final int CRATE_37936 = 37936;
public static final int DOOR_37937 = 37937;
public static final int DOOR_37938 = 37938;
public static final int BROKEN_GOAT_HORN = 37939;
public static final int GATE_37941 = 37941;
public static final int GATE_37942 = 37942;
public static final int GATE_37943 = 37943;
public static final int GATE_37944 = 37944;
public static final int TREE_37946 = 37946;
public static final int DEAD_TREE_37948 = 37948;
public static final int SCOREBOARD_37949 = 37949;
public static final int COFFIN_37951 = 37951;
public static final int JUNGLE_TREE_37952 = 37952;
public static final int YEW_37953 = 37953;
public static final int TREE_STUMP_37954 = 37954;
public static final int FURNACE_37955 = 37955;
public static final int HANDY_PORTAL = 37957;
/* This file is automatically generated. Do not edit. */
}
@@ -308,4 +308,13 @@ public final class ScriptID
*/
@ScriptArguments(integer = 7)
public static final int IGNORE_UPDATE = 630;
/**
* Called in an onTimer, determines whether to layout the bank during a search
* <ul>
* <li> int (WidgetID) * 16, various widgets making up the bank interface </li>
* </ul>
*/
@ScriptArguments(integer = 16)
public static final int BANKMAIN_SEARCH_REFRESH = 283;
}
@@ -27,10 +27,12 @@ package net.runelite.client;
import io.reactivex.rxjava3.schedulers.Schedulers;
import java.time.temporal.ChronoUnit;
import java.util.UUID;
import java.util.concurrent.Future;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.events.ClientShutdown;
import net.runelite.client.task.Schedule;
@Singleton
@@ -38,15 +40,23 @@ import net.runelite.client.task.Schedule;
public class ClientSessionManager
{
private final SessionClient sessionClient;
private final ClientThread clientThread;
private UUID sessionId;
@Inject
ClientSessionManager(ClientThread clientThread)
ClientSessionManager(EventBus eventBus)
{
this.sessionClient = new SessionClient();
this.clientThread = clientThread;
eventBus.subscribe(ClientShutdown.class, this, (e) ->
{
Future<Void> f = shutdown();
if (f != null)
{
e.waitFor(f);
}
sessionId = null;
});
}
void start()
@@ -54,7 +64,8 @@ public class ClientSessionManager
sessionClient.openSession()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.single())
.subscribe(this::setUuid, this::error);
.doOnError(this::error)
.subscribe(this::setUuid);
}
@Schedule(period = 10, unit = ChronoUnit.MINUTES, asynchronous = true)
@@ -73,18 +84,15 @@ public class ClientSessionManager
.subscribe();
}
public void shutdown()
private Future<Void> shutdown()
{
if (sessionId != null)
{
sessionClient.delete(sessionId)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.single())
.doOnError(this::error)
.subscribe();
return sessionClient.delete(sessionId)
.toFuture();
sessionId = null;
}
return null;
}
private void setUuid(UUID uuid)
@@ -469,7 +469,7 @@ public class RuneLite
// Initialize UI
RuneLiteSplashScreen.stage(.80, "Initialize UI");
clientUI.init(this);
clientUI.init();
// Initialize Discord service
discordService.init();
@@ -599,13 +599,6 @@ public class RuneLite
}
}
public void shutdown()
{
clientSessionManager.shutdown();
discordService.close();
groups.close();
}
private static class ConfigFileConverter implements ValueConverter<File>
{
@Override
@@ -371,18 +371,6 @@ public interface RuneLiteConfig extends Config
return false;
}
@ConfigItem(
keyName = "infoBoxWrap",
name = "Infobox wrap count",
description = "Configures the amount of infoboxes shown before wrapping",
position = 29,
titleSection = "infoboxTitle"
)
default int infoBoxWrap()
{
return 4;
}
@ConfigItem(
keyName = "infoBoxSize",
name = "Infobox size",
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2020 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.events;
import java.time.Duration;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.events.Event;
@Value
@Slf4j
public class ClientShutdown implements Event
{
private Queue<Future<?>> tasks = new ConcurrentLinkedQueue<>();
public void waitFor(Future<?> future)
{
tasks.add(future);
}
public void waitForAllConsumers(Duration totalTimeout)
{
long deadline = System.nanoTime() + totalTimeout.toNanos();
for (Future<?> task; (task = tasks.poll()) != null; )
{
long timeout = deadline - System.nanoTime();
if (timeout < 0)
{
log.warn("Timed out waiting for task completion");
return;
}
try
{
task.get(timeout, TimeUnit.NANOSECONDS);
}
catch (ThreadDeath d)
{
throw d;
}
catch (Throwable t)
{
log.warn("Error during shutdown: ", t);
}
}
}
}
@@ -49,25 +49,52 @@ public class KeyManager
public void processKeyPressed(KeyEvent keyEvent)
{
if (keyEvent.isConsumed())
{
return;
}
for (KeyListener keyListener : keyListeners)
{
keyListener.keyPressed(keyEvent);
if (keyEvent.isConsumed())
{
break;
}
}
}
public void processKeyReleased(KeyEvent keyEvent)
{
if (keyEvent.isConsumed())
{
return;
}
for (KeyListener keyListener : keyListeners)
{
keyListener.keyReleased(keyEvent);
if (keyEvent.isConsumed())
{
break;
}
}
}
public void processKeyTyped(KeyEvent keyEvent)
{
if (keyEvent.isConsumed())
{
return;
}
for (KeyListener keyListener : keyListeners)
{
keyListener.keyTyped(keyEvent);
if (keyEvent.isConsumed())
{
break;
}
}
}
}
@@ -82,30 +82,57 @@ public class MouseManager
public MouseEvent processMousePressed(MouseEvent mouseEvent)
{
if (mouseEvent.isConsumed())
{
return mouseEvent;
}
checkExtraMouseButtons(mouseEvent);
for (MouseListener mouseListener : mouseListeners)
{
mouseEvent = mouseListener.mousePressed(mouseEvent);
if (mouseEvent.isConsumed())
{
break;
}
}
return mouseEvent;
}
public MouseEvent processMouseReleased(MouseEvent mouseEvent)
{
if (mouseEvent.isConsumed())
{
return mouseEvent;
}
checkExtraMouseButtons(mouseEvent);
for (MouseListener mouseListener : mouseListeners)
{
mouseEvent = mouseListener.mouseReleased(mouseEvent);
if (mouseEvent.isConsumed())
{
break;
}
}
return mouseEvent;
}
public MouseEvent processMouseClicked(MouseEvent mouseEvent)
{
if (mouseEvent.isConsumed())
{
return mouseEvent;
}
checkExtraMouseButtons(mouseEvent);
for (MouseListener mouseListener : mouseListeners)
{
mouseEvent = mouseListener.mouseClicked(mouseEvent);
if (mouseEvent.isConsumed())
{
break;
}
}
return mouseEvent;
}
@@ -123,45 +150,90 @@ public class MouseManager
public MouseEvent processMouseEntered(MouseEvent mouseEvent)
{
if (mouseEvent.isConsumed())
{
return mouseEvent;
}
for (MouseListener mouseListener : mouseListeners)
{
mouseEvent = mouseListener.mouseEntered(mouseEvent);
if (mouseEvent.isConsumed())
{
break;
}
}
return mouseEvent;
}
public MouseEvent processMouseExited(MouseEvent mouseEvent)
{
if (mouseEvent.isConsumed())
{
return mouseEvent;
}
for (MouseListener mouseListener : mouseListeners)
{
mouseEvent = mouseListener.mouseExited(mouseEvent);
if (mouseEvent.isConsumed())
{
break;
}
}
return mouseEvent;
}
public MouseEvent processMouseDragged(MouseEvent mouseEvent)
{
if (mouseEvent.isConsumed())
{
return mouseEvent;
}
for (MouseListener mouseListener : mouseListeners)
{
mouseEvent = mouseListener.mouseDragged(mouseEvent);
if (mouseEvent.isConsumed())
{
break;
}
}
return mouseEvent;
}
public MouseEvent processMouseMoved(MouseEvent mouseEvent)
{
if (mouseEvent.isConsumed())
{
return mouseEvent;
}
for (MouseListener mouseListener : mouseListeners)
{
mouseEvent = mouseListener.mouseMoved(mouseEvent);
if (mouseEvent.isConsumed())
{
break;
}
}
return mouseEvent;
}
public MouseWheelEvent processMouseWheelMoved(MouseWheelEvent mouseWheelEvent)
{
if (mouseWheelEvent.isConsumed())
{
return mouseWheelEvent;
}
for (MouseWheelListener mouseWheelListener : mouseWheelListeners)
{
mouseWheelEvent = mouseWheelListener.mouseWheelMoved(mouseWheelEvent);
if (mouseWheelEvent.isConsumed())
{
break;
}
}
return mouseWheelEvent;
}
@@ -44,10 +44,13 @@ import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.Window;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.Duration;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Provider;
@@ -72,7 +75,6 @@ import net.runelite.api.Point;
import net.runelite.api.events.GameStateChanged;
import net.runelite.api.widgets.Widget;
import net.runelite.api.widgets.WidgetInfo;
import net.runelite.client.RuneLite;
import net.runelite.client.RuneLiteProperties;
import net.runelite.client.callback.ClientThread;
import net.runelite.client.config.ConfigManager;
@@ -80,6 +82,7 @@ import net.runelite.client.config.ExpandResizeType;
import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.config.WarningOnExit;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.events.ClientShutdown;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.events.NavigationButtonAdded;
import net.runelite.client.events.NavigationButtonRemoved;
@@ -131,6 +134,7 @@ public class ClientUI
private final Applet client;
private final ConfigManager configManager;
private final Provider<ClientThread> clientThreadProvider;
private final EventBus eventBus;
private final CardLayout cardLayout = new CardLayout();
private final Rectangle sidebarButtonPosition = new Rectangle();
private boolean withTitleBar;
@@ -144,6 +148,7 @@ public class ClientUI
private NavigationButton sidebarNavigationButton;
private JButton sidebarNavigationJButton;
private Dimension lastClientSize;
private Cursor defaultCursor;
private Field opacityField;
private Field peerField;
private Method setOpacityMethod;
@@ -164,6 +169,7 @@ public class ClientUI
this.client = client;
this.configManager = configManager;
this.clientThreadProvider = clientThreadProvider;
this.eventBus = eventbus;
eventbus.subscribe(ConfigChanged.class, this, this::onConfigChanged);
eventbus.subscribe(NavigationButtonAdded.class, this, this::onNavigationButtonAdded);
@@ -313,11 +319,8 @@ public class ClientUI
/**
* Initialize UI.
*
* @param runelite runelite instance that will be shut down on exit
* @throws Exception exception that can occur during creation of the UI
*/
public void init(final RuneLite runelite) throws Exception
public void init() throws Exception
{
SwingUtilities.invokeAndWait(() ->
{
@@ -335,14 +338,36 @@ public class ClientUI
frame.setLocationRelativeTo(frame.getOwner());
frame.setResizable(true);
SwingUtil.addGracefulExitCallback(frame,
() ->
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent event)
{
saveClientBoundsConfig();
runelite.shutdown();
},
this::showWarningOnExit
);
int result = JOptionPane.OK_OPTION;
if (showWarningOnExit())
{
try
{
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)
{
shutdownClient();
}
}
});
container = new JPanel();
container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
@@ -550,7 +575,7 @@ public class ClientUI
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(frame,
"OpenOSRS has not yet been updated to work with the latest\n"
+ "game update, it will work with reduced functionality until then.",
"RuneLite is outdated", INFORMATION_MESSAGE));
"OpenOSRS is outdated", INFORMATION_MESSAGE));
}
}
@@ -569,6 +594,45 @@ public class ClientUI
return false;
}
private void shutdownClient()
{
saveClientBoundsConfig();
ClientShutdown csev = new ClientShutdown();
eventBus.post(ClientShutdown.class, csev);
new Thread(() ->
{
csev.waitForAllConsumers(Duration.ofSeconds(10));
if (client != null)
{
// The client can call System.exit when it's done shutting down
// if it doesn't though, we want to exit anyway, so race it
int clientShutdownWaitMS;
if (client instanceof Client)
{
((Client) client).stopNow();
clientShutdownWaitMS = 1000;
}
else
{
// it will continue rendering for about 4 seconds before attempting shutdown if its vanilla
client.stop();
frame.setVisible(false);
clientShutdownWaitMS = 6000;
}
try
{
Thread.sleep(clientShutdownWaitMS);
}
catch (InterruptedException ignored)
{
}
}
System.exit(0);
}, "OpenOSRS Shutdown").start();
}
/**
* Paint this component to target graphics
*
@@ -654,7 +718,27 @@ public class ClientUI
}
/**
* Changes cursor for client window. Requires ${@link ClientUI#init(RuneLite)} to be called first.
* Returns current cursor set on game container
*
* @return awt cursor
*/
public Cursor getCurrentCursor()
{
return container.getCursor();
}
/**
* Returns current custom cursor or default system cursor if cursor is not set
*
* @return awt cursor
*/
public Cursor getDefaultCursor()
{
return defaultCursor != null ? defaultCursor : Cursor.getDefaultCursor();
}
/**
* Changes cursor for client window. Requires ${@link ClientUI#init()} to be called first.
* FIXME: This is working properly only on Windows, Linux and Mac are displaying cursor incorrectly
*
* @param image cursor image
@@ -669,7 +753,18 @@ public class ClientUI
final java.awt.Point hotspot = new java.awt.Point(0, 0);
final Cursor cursorAwt = Toolkit.getDefaultToolkit().createCustomCursor(image, hotspot, name);
container.setCursor(cursorAwt);
defaultCursor = cursorAwt;
setCursor(cursorAwt);
}
/**
* Changes cursor for client window. Requires ${@link ClientUI#init()} to be called first.
*
* @param cursor awt cursor
*/
public void setCursor(final Cursor cursor)
{
container.setCursor(cursor);
}
/**
@@ -684,6 +779,7 @@ public class ClientUI
return;
}
defaultCursor = null;
container.setCursor(Cursor.getDefaultCursor());
}
@@ -128,6 +128,12 @@ public class FlatTextField extends JPanel
setBackground(color, true);
}
@Override
public boolean requestFocusInWindow()
{
return textField.requestFocusInWindow();
}
public void setBackground(Color color, boolean saveColor)
{
if (color == null)
@@ -49,6 +49,7 @@ public abstract class Overlay implements LayoutableRenderableEntity
private OverlayPriority priority = OverlayPriority.NONE;
private OverlayLayer layer = OverlayLayer.UNDER_WIDGETS;
private final List<OverlayMenuEntry> menuEntries = new ArrayList<>();
private boolean resizable;
protected Overlay()
{
@@ -261,7 +261,7 @@ public class OverlayManager
saveOverlay(overlay);
}
private synchronized void rebuildOverlayLayers()
synchronized void rebuildOverlayLayers()
{
for (OverlayLayer l : OverlayLayer.values())
{
@@ -0,0 +1,96 @@
/*
* 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.overlay;
import java.awt.Dimension;
import java.awt.Graphics2D;
import lombok.Getter;
import lombok.Setter;
import net.runelite.client.plugins.Plugin;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.overlay.components.ComponentConstants;
import net.runelite.client.ui.overlay.components.PanelComponent;
@Getter
@Setter
public abstract class OverlayPanel extends Overlay
{
protected final PanelComponent panelComponent = new PanelComponent();
/**
* Enables/disables automatic clearing of {@link this#getPanelComponent()} children after rendering (enabled by default)
*/
private boolean clearChildren = true;
/**
* Enables/disables automatic font size changes based on panel component size relative to default panel component size.
*/
private boolean dynamicFont = false;
protected OverlayPanel()
{
super();
setResizable(true);
}
protected OverlayPanel(Plugin plugin)
{
super(plugin);
setResizable(true);
}
@Override
public Dimension render(final Graphics2D graphics)
{
final Dimension oldSize = panelComponent.getPreferredSize();
if (getPreferredSize() != null)
{
panelComponent.setPreferredSize(getPreferredSize());
if (dynamicFont)
{
if (getPreferredSize().width >= ComponentConstants.STANDARD_WIDTH * 1.3)
{
graphics.setFont(FontManager.getRunescapeBoldFont());
}
else if (getPreferredSize().width <= ComponentConstants.STANDARD_WIDTH * 0.8)
{
graphics.setFont(FontManager.getRunescapeSmallFont());
}
}
}
final Dimension dimension = panelComponent.render(graphics);
if (clearChildren)
{
panelComponent.getChildren().clear();
}
panelComponent.setPreferredSize(oldSize);
return dimension;
}
}
@@ -25,8 +25,10 @@
package net.runelite.client.ui.overlay;
import com.google.common.base.MoreObjects;
import com.google.common.primitives.Ints;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Paint;
@@ -60,6 +62,7 @@ import net.runelite.client.input.KeyListener;
import net.runelite.client.input.KeyManager;
import net.runelite.client.input.MouseAdapter;
import net.runelite.client.input.MouseManager;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.JagexColors;
import net.runelite.client.util.ColorUtil;
import net.runelite.client.util.MiscUtils;
@@ -71,21 +74,29 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
private static final int BORDER = 5;
private static final int BORDER_TOP = BORDER + 15;
private static final int PADDING = 2;
private static final int MIN_OVERLAY_SIZE = 32;
private static final int OVERLAY_RESIZE_TOLERANCE = 5;
private static final Dimension SNAP_CORNER_SIZE = new Dimension(80, 80);
private static final Color SNAP_CORNER_COLOR = new Color(0, 255, 255, 50);
private static final Color SNAP_CORNER_ACTIVE_COLOR = new Color(0, 255, 0, 100);
private static final Color MOVING_OVERLAY_COLOR = new Color(255, 255, 0, 100);
private static final Color MOVING_OVERLAY_ACTIVE_COLOR = new Color(255, 255, 0, 200);
private static final Color MOVING_OVERLAY_RESIZING_COLOR = new Color(255, 0, 255, 200);
private final Client client;
private final OverlayManager overlayManager;
private final RuneLiteConfig runeLiteConfig;
private final ClientUI clientUI;
// Overlay movement variables
private final Point overlayOffset = new Point();
private final Point mousePosition = new Point();
private Overlay movedOverlay;
private Overlay currentManagedOverlay;
private Rectangle currentManagedBounds;
private boolean inOverlayManagingMode;
private boolean inOverlayResizingMode;
private boolean inOverlayDraggingMode;
private boolean inMenuEntryMode;
private boolean startedMovingOverlay;
private MenuEntry[] menuEntries;
// Overlay state validation
@@ -106,11 +117,13 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
final RuneLiteConfig runeLiteConfig,
final MouseManager mouseManager,
final KeyManager keyManager,
final EventBus eventbus)
final EventBus eventbus,
final ClientUI clientUI)
{
this.client = client;
this.overlayManager = overlayManager;
this.runeLiteConfig = runeLiteConfig;
this.clientUI = clientUI;
keyManager.registerKeyListener(this);
mouseManager.registerMouseListener(this);
@@ -123,7 +136,8 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
{
if (!event.isFocused())
{
inOverlayDraggingMode = false;
inOverlayManagingMode = false;
resetOverlayManagementMode();
inMenuEntryMode = false;
menuEntries = null;
}
@@ -202,7 +216,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
OverlayUtil.setGraphicProperties(graphics);
// Draw snap corners
if (layer == OverlayLayer.UNDER_WIDGETS && movedOverlay != null && movedOverlay.getPosition() != OverlayPosition.DETACHED)
if (inOverlayDraggingMode && layer == OverlayLayer.UNDER_WIDGETS && currentManagedOverlay != null && currentManagedOverlay.getPosition() != OverlayPosition.DETACHED)
{
final OverlayBounds translatedSnapCorners = snapCorners.translated(
-SNAP_CORNER_SIZE.width,
@@ -294,12 +308,19 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
if (!bounds.isEmpty())
{
if (inOverlayDraggingMode)
if (inOverlayManagingMode)
{
final Color previous = graphics.getColor();
graphics.setColor(movedOverlay == overlay ? MOVING_OVERLAY_ACTIVE_COLOR : MOVING_OVERLAY_COLOR);
if (inOverlayResizingMode && currentManagedOverlay == overlay)
{
graphics.setColor(MOVING_OVERLAY_RESIZING_COLOR);
}
else
{
graphics.setColor(inOverlayDraggingMode && currentManagedOverlay == overlay ? MOVING_OVERLAY_ACTIVE_COLOR : MOVING_OVERLAY_COLOR);
}
graphics.draw(bounds);
graphics.setColor(previous);
graphics.setPaint(paint);
}
if (!client.isMenuOpen() && !client.isSpellSelected() && bounds.contains(mouse))
@@ -319,7 +340,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
@Override
public MouseEvent mousePressed(MouseEvent mouseEvent)
{
if (!inOverlayDraggingMode)
if (!inOverlayManagingMode)
{
return mouseEvent;
}
@@ -327,71 +348,205 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
final Point mousePoint = mouseEvent.getPoint();
mousePosition.setLocation(mousePoint);
synchronized (overlayManager)
if (currentManagedOverlay == null)
{
for (Overlay overlay : overlayManager.getOverlays())
return mouseEvent;
}
if (SwingUtilities.isRightMouseButton(mouseEvent))
{
overlayManager.resetOverlay(currentManagedOverlay);
}
else if (SwingUtilities.isLeftMouseButton(mouseEvent))
{
final Point offset = new Point(mousePoint.x, mousePoint.y);
offset.translate(-currentManagedOverlay.getBounds().x, -currentManagedOverlay.getBounds().y);
overlayOffset.setLocation(offset);
inOverlayResizingMode = currentManagedOverlay != null && currentManagedOverlay.isResizable() && clientUI.getCurrentCursor() != clientUI.getDefaultCursor();
inOverlayDraggingMode = !inOverlayResizingMode;
startedMovingOverlay = true;
currentManagedBounds = new Rectangle(currentManagedOverlay.getBounds());
}
else
{
return mouseEvent;
}
mouseEvent.consume();
return mouseEvent;
}
@Override
public MouseEvent mouseMoved(MouseEvent mouseEvent)
{
if (!inOverlayManagingMode)
{
return mouseEvent;
}
final Point mousePoint = mouseEvent.getPoint();
mousePosition.setLocation(mousePoint);
if (!inOverlayResizingMode && !inOverlayDraggingMode)
{
currentManagedOverlay = null;
synchronized (overlayManager)
{
final OverlayPosition overlayPosition = getCorrectedOverlayPosition(overlay);
if (overlayPosition == OverlayPosition.DYNAMIC || overlayPosition == OverlayPosition.TOOLTIP)
for (Overlay overlay : overlayManager.getOverlays())
{
continue;
}
if (overlay.getBounds().contains(mousePoint))
{
if (SwingUtilities.isRightMouseButton(mouseEvent))
final Rectangle bounds = overlay.getBounds();
if (bounds.contains(mousePoint))
{
overlayManager.resetOverlay(overlay);
currentManagedOverlay = overlay;
break;
}
else
{
final Point offset = new Point(mousePoint.x, mousePoint.y);
offset.translate(-overlay.getBounds().x, -overlay.getBounds().y);
overlayOffset.setLocation(offset);
mousePoint.translate(-offset.x, -offset.y);
movedOverlay = overlay;
movedOverlay.setPreferredPosition(null);
movedOverlay.setPreferredLocation(mousePoint);
overlayManager.saveOverlay(movedOverlay);
}
mouseEvent.consume();
break;
}
}
}
if (currentManagedOverlay == null || !currentManagedOverlay.isResizable())
{
clientUI.setCursor(clientUI.getDefaultCursor());
return mouseEvent;
}
final Rectangle toleranceRect = new Rectangle(currentManagedOverlay.getBounds());
toleranceRect.grow(-OVERLAY_RESIZE_TOLERANCE, -OVERLAY_RESIZE_TOLERANCE);
final int outcode = toleranceRect.outcode(mouseEvent.getPoint());
switch (outcode)
{
case Rectangle.OUT_TOP:
clientUI.setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
break;
case Rectangle.OUT_TOP | Rectangle.OUT_LEFT:
clientUI.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
break;
case Rectangle.OUT_LEFT:
clientUI.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
break;
case Rectangle.OUT_LEFT | Rectangle.OUT_BOTTOM:
clientUI.setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
break;
case Rectangle.OUT_BOTTOM:
clientUI.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
break;
case Rectangle.OUT_BOTTOM | Rectangle.OUT_RIGHT:
clientUI.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
break;
case Rectangle.OUT_RIGHT:
clientUI.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
break;
case Rectangle.OUT_RIGHT | Rectangle.OUT_TOP:
clientUI.setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
break;
default:
// center
clientUI.setCursor(clientUI.getDefaultCursor());
}
return mouseEvent;
}
@Override
public MouseEvent mouseDragged(MouseEvent mouseEvent)
{
if (!inOverlayDraggingMode)
if (!inOverlayManagingMode)
{
return mouseEvent;
}
final Point p = mouseEvent.getPoint();
mousePosition.setLocation(p);
if (currentManagedOverlay == null)
{
return mouseEvent;
}
final Point mousePoint = mouseEvent.getPoint();
mousePosition.setLocation(mousePoint);
final Rectangle canvasRect = new Rectangle(client.getRealDimensions());
if (!canvasRect.contains(mousePoint))
if (!canvasRect.contains(p))
{
return mouseEvent;
}
if (movedOverlay != null)
if (inOverlayResizingMode)
{
final Rectangle r = currentManagedBounds;
final int dx = p.x - r.x;
final int dy = p.y - r.y;
switch (clientUI.getCurrentCursor().getType())
{
case Cursor.N_RESIZE_CURSOR:
int height = r.height - dy;
r.setRect(r.x, r.y + dy, r.width, height);
break;
case Cursor.NW_RESIZE_CURSOR:
int width = r.width - dx;
height = r.height - dy;
r.setRect(r.x + dx, r.y + dy, width, height);
break;
case Cursor.W_RESIZE_CURSOR:
width = r.width - dx;
r.setRect(r.x + dx, r.y, width, r.height);
break;
case Cursor.SW_RESIZE_CURSOR:
width = r.width - dx;
height = dy;
r.setRect(r.x + dx, r.y, width, height);
break;
case Cursor.S_RESIZE_CURSOR:
height = dy;
r.setRect(r.x, r.y, r.width, height);
break;
case Cursor.SE_RESIZE_CURSOR:
width = dx;
height = dy;
r.setRect(r.x, r.y, width, height);
break;
case Cursor.E_RESIZE_CURSOR:
width = dx;
r.setRect(r.x, r.y, width, r.height);
break;
case Cursor.NE_RESIZE_CURSOR:
width = dx;
height = r.height - dy;
r.setRect(r.x, r.y + dy, width, height);
break;
default:
// center
}
currentManagedOverlay.setPreferredSize(new Dimension(Math.max(MIN_OVERLAY_SIZE, currentManagedBounds.width), Math.max(MIN_OVERLAY_SIZE, currentManagedBounds.height)));
if (currentManagedOverlay.getPreferredLocation() != null)
{
currentManagedOverlay.setPreferredLocation(currentManagedBounds.getLocation());
}
}
else if (inOverlayDraggingMode)
{
final Dimension realDimension = client.getRealDimensions();
mousePoint.translate(-overlayOffset.x, -overlayOffset.y);
mousePoint.x = MiscUtils.clamp(mousePoint.x, 0, Math.max(0, realDimension.width - movedOverlay.getBounds().width));
mousePoint.y = MiscUtils.clamp(mousePoint.y, 0, Math.max(0, realDimension.height - movedOverlay.getBounds().height));
movedOverlay.setPreferredPosition(null);
movedOverlay.setPreferredLocation(mousePoint);
mouseEvent.consume();
p.translate(-overlayOffset.x, -overlayOffset.y);
p.x = Ints.constrainToRange(p.x, 0, Math.max(0, realDimension.width - currentManagedOverlay.getBounds().width));
p.y = Ints.constrainToRange(p.y, 0, Math.max(0, realDimension.height - currentManagedOverlay.getBounds().height));
currentManagedOverlay.setPreferredPosition(null);
currentManagedOverlay.setPreferredLocation(p);
}
else
{
return mouseEvent;
}
if (startedMovingOverlay)
{
// Move currently moved overlay to correct layer
overlayManager.rebuildOverlayLayers();
startedMovingOverlay = false;
}
return mouseEvent;
@@ -400,39 +555,40 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
@Override
public MouseEvent mouseReleased(MouseEvent mouseEvent)
{
if (movedOverlay != null)
if (!inOverlayManagingMode || currentManagedOverlay == null || (!inOverlayDraggingMode && !inOverlayResizingMode))
{
mousePosition.setLocation(-1, -1);
// do not snapcorner detached overlays
if (movedOverlay.getPosition() != OverlayPosition.DETACHED)
{
final OverlayBounds snapCorners = this.snapCorners.translated(-SNAP_CORNER_SIZE.width, -SNAP_CORNER_SIZE.height);
for (Rectangle snapCorner : snapCorners.getBounds())
{
if (snapCorner.contains(mouseEvent.getPoint()))
{
OverlayPosition position = snapCorners.fromBounds(snapCorner);
if (position == movedOverlay.getPosition())
{
// overlay moves back to default position
position = null;
}
movedOverlay.setPreferredPosition(position);
movedOverlay.setPreferredLocation(null); // from dragging
break;
}
}
}
overlayManager.saveOverlay(movedOverlay);
movedOverlay = null;
mouseEvent.consume();
return mouseEvent;
}
mousePosition.setLocation(-1, -1);
// do not snapcorner detached overlays
if (currentManagedOverlay.getPosition() != OverlayPosition.DETACHED && inOverlayDraggingMode)
{
final OverlayBounds snapCorners = this.snapCorners.translated(-SNAP_CORNER_SIZE.width, -SNAP_CORNER_SIZE.height);
for (Rectangle snapCorner : snapCorners.getBounds())
{
if (snapCorner.contains(mouseEvent.getPoint()))
{
OverlayPosition position = snapCorners.fromBounds(snapCorner);
if (position == currentManagedOverlay.getPosition())
{
// overlay moves back to default position
position = null;
}
currentManagedOverlay.setPreferredPosition(position);
currentManagedOverlay.setPreferredLocation(null); // from dragging
break;
}
}
}
overlayManager.saveOverlay(currentManagedOverlay);
resetOverlayManagementMode();
mouseEvent.consume();
return mouseEvent;
}
@@ -446,7 +602,7 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
{
if (e.isAltDown())
{
inOverlayDraggingMode = true;
inOverlayManagingMode = true;
}
if (e.isShiftDown() && runeLiteConfig.menuEntryShift())
@@ -460,7 +616,8 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
{
if (!e.isAltDown())
{
inOverlayDraggingMode = false;
inOverlayManagingMode = false;
resetOverlayManagementMode();
}
if (!e.isShiftDown())
@@ -546,6 +703,15 @@ public class OverlayRenderer extends MouseAdapter implements KeyListener
return overlayPosition;
}
private void resetOverlayManagementMode()
{
inOverlayResizingMode = false;
inOverlayDraggingMode = false;
currentManagedOverlay = null;
currentManagedBounds = null;
clientUI.setCursor(clientUI.getDefaultCursor());
}
private boolean shouldInvalidateBounds()
{
final Widget chatbox = client.getWidget(WidgetInfo.CHATBOX);
@@ -45,6 +45,7 @@ public class PanelComponent implements LayoutableRenderableEntity
private Point preferredLocation = new Point();
@Setter
@Getter
private Dimension preferredSize = new Dimension(ComponentConstants.STANDARD_WIDTH, 0);
@Setter
@@ -58,7 +59,7 @@ public class PanelComponent implements LayoutableRenderableEntity
private ComponentOrientation orientation = ComponentOrientation.VERTICAL;
@Setter
private int wrapping = -1;
private boolean wrap = false;
@Setter
private Rectangle border = new Rectangle(
@@ -114,12 +115,23 @@ public class PanelComponent implements LayoutableRenderableEntity
int totalWidth = 0;
// Render all children
for (int i = 0; i < children.size(); i++)
for (final LayoutableRenderableEntity child : children)
{
final LayoutableRenderableEntity child = children.get(i);
// Correctly propagate child dimensions based on orientation and wrapping
if (!wrap)
{
switch (orientation)
{
case VERTICAL:
child.setPreferredSize(new Dimension(childPreferredSize.width, 0));
break;
case HORIZONTAL:
child.setPreferredSize(new Dimension(0, childPreferredSize.height));
break;
}
}
child.setPreferredLocation(new Point(x, y));
child.setPreferredSize(childPreferredSize);
final Dimension childDimension = child.render(graphics);
switch (orientation)
@@ -140,28 +152,38 @@ public class PanelComponent implements LayoutableRenderableEntity
totalWidth = Math.max(totalWidth, width);
totalHeight = Math.max(totalHeight, height);
if (wrapping > 0 && i < children.size() - 1 && (i + 1) % wrapping == 0)
if (!wrap)
{
switch (orientation)
continue;
}
switch (orientation)
{
case VERTICAL:
{
case VERTICAL:
if (childPreferredSize.height > 0 && height >= childPreferredSize.height)
{
height = 0;
y = baseY;
int diff = childDimension.width + gap.x;
x += diff;
width += diff;
break;
}
case HORIZONTAL:
break;
}
case HORIZONTAL:
{
if (childPreferredSize.width > 0 && width >= childPreferredSize.width)
{
width = 0;
x = baseX;
int diff = childDimension.height + gap.y;
y += diff;
height += diff;
break;
}
break;
}
}
}
@@ -36,19 +36,20 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import net.runelite.api.Client;
import net.runelite.client.config.RuneLiteConfig;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayPanel;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.components.ComponentOrientation;
import net.runelite.client.ui.overlay.components.InfoBoxComponent;
import net.runelite.client.ui.overlay.components.LayoutableRenderableEntity;
import net.runelite.client.ui.overlay.components.PanelComponent;
import net.runelite.client.ui.overlay.tooltip.Tooltip;
import net.runelite.client.ui.overlay.tooltip.TooltipManager;
@Singleton
public class InfoBoxOverlay extends Overlay
public class InfoBoxOverlay extends OverlayPanel
{
private final PanelComponent panelComponent = new PanelComponent();
private static final int GAP = 1;
private static final int DEFAULT_WRAP_COUNT = 4;
private final InfoBoxManager infoboxManager;
private final TooltipManager tooltipManager;
private final Client client;
@@ -66,10 +67,12 @@ public class InfoBoxOverlay extends Overlay
this.client = client;
this.config = config;
setPosition(OverlayPosition.TOP_LEFT);
setClearChildren(false);
panelComponent.setWrap(true);
panelComponent.setBackgroundColor(null);
panelComponent.setBorder(new Rectangle());
panelComponent.setGap(new Point(1, 1));
panelComponent.setGap(new Point(GAP, GAP));
}
@Override
@@ -82,12 +85,12 @@ public class InfoBoxOverlay extends Overlay
return null;
}
panelComponent.getChildren().clear();
panelComponent.setWrapping(config.infoBoxWrap());
// Set preferred size to the size of DEFAULT_WRAP_COUNT infoboxes, including the padding - which is applied
// to the last infobox prior to wrapping too.
panelComponent.setPreferredSize(new Dimension(DEFAULT_WRAP_COUNT * (config.infoBoxSize() + GAP), DEFAULT_WRAP_COUNT * (config.infoBoxSize() + GAP)));
panelComponent.setOrientation(config.infoBoxVertical()
? ComponentOrientation.VERTICAL
: ComponentOrientation.HORIZONTAL);
panelComponent.setPreferredSize(new Dimension(config.infoBoxSize(), config.infoBoxSize()));
for (InfoBox box : infoBoxes)
{
@@ -107,10 +110,11 @@ public class InfoBoxOverlay extends Overlay
}
infoBoxComponent.setImage(box.getScaledImage());
infoBoxComponent.setTooltip(box.getTooltip());
infoBoxComponent.setPreferredSize(new Dimension(config.infoBoxSize(), config.infoBoxSize()));
panelComponent.getChildren().add(infoBoxComponent);
}
final Dimension dimension = panelComponent.render(graphics);
final Dimension dimension = super.render(graphics);
// Handle tooltips
final Point mouse = new Point(client.getMouseCanvasPosition().getX(), client.getMouseCanvasPosition().getY());
@@ -135,6 +139,7 @@ public class InfoBoxOverlay extends Overlay
}
}
panelComponent.getChildren().clear();
return dimension;
}
}
@@ -24,27 +24,14 @@
*/
package net.runelite.client.ui.overlay.tooltip;
import com.google.common.base.Strings;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.Getter;
import net.runelite.client.config.ConfigManager;
import net.runelite.client.eventbus.Subscribe;
import net.runelite.client.events.ConfigChanged;
@Singleton
public class TooltipManager
{
private final ConfigManager configManager;
@Inject
private TooltipManager(final ConfigManager configManager)
{
this.configManager = configManager;
}
@Getter
private final List<Tooltip> tooltips = new ArrayList<>();
@@ -62,17 +49,4 @@ public class TooltipManager
{
tooltips.clear();
}
@Subscribe
public void onConfigChanged(final ConfigChanged event)
{
// Temporary fix for resetting repositioned tooltip overlay
// TODO: Remove this eventually
if (event.getGroup().equals("runelite") &&
event.getKey().equals("TooltipOverlay_preferredLocation") &&
!Strings.isNullOrEmpty(event.getNewValue()))
{
configManager.unsetConfiguration(event.getGroup(), event.getKey());
}
}
}
@@ -5,6 +5,8 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.AccessLevel;
@@ -12,6 +14,8 @@ import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.runelite.client.RuneLite;
import net.runelite.client.config.OpenOSRSConfig;
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.events.ClientShutdown;
import net.runelite.client.events.ConfigChanged;
import net.runelite.client.ui.RuneLiteSplashScreen;
import org.jgroups.Address;
@@ -38,7 +42,7 @@ public class Groups extends ReceiverAdapter
private final PublishSubject<Message> messageObjectSubject = PublishSubject.create();
@Inject
public Groups(OpenOSRSConfig openOSRSConfig) throws Exception
public Groups(OpenOSRSConfig openOSRSConfig, EventBus eventBus) throws Exception
{
this.openOSRSConfig = openOSRSConfig;
@@ -47,6 +51,11 @@ public class Groups extends ReceiverAdapter
.setReceiver(this)
.setDiscardOwnMessages(true)
.connect("openosrs");
eventBus.subscribe(ClientShutdown.class, this, (e) -> {
Future<Void> f = close();
e.waitFor(f);
});
}
public void broadcastSring(String command)
@@ -134,10 +143,22 @@ public class Groups extends ReceiverAdapter
{
messageObjectSubject.onNext(message);
}
}
public void close()
private CompletableFuture<Void> close()
{
channel.close();
CompletableFuture<Void> future = new CompletableFuture<>();
try
{
channel.close();
future.complete(null);
}
catch (Exception ex)
{
future.completeExceptionally(ex);
}
return future;
}
}
@@ -41,22 +41,18 @@ import java.awt.Toolkit;
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.lang.reflect.InvocationTargetException;
import java.util.Enumeration;
import java.util.concurrent.Callable;
import java.util.function.BiConsumer;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.swing.ButtonModel;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
@@ -67,7 +63,6 @@ import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
@@ -214,48 +209,6 @@ public class SwingUtil
return trayIcon;
}
/**
* 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);
}
}
});
}
/**
* Create swing button from navigation button.
*
@@ -83,7 +83,7 @@ public class WeaponMap
StyleMap.put(ItemID.BLACK_SWORD, WeaponStyle.MELEE);
StyleMap.put(ItemID.BLACK_WARHAMMER, WeaponStyle.MELEE);
StyleMap.put(ItemID.BLADE_OF_SAELDOR, WeaponStyle.MELEE);
StyleMap.put(ItemID.BLADE_OF_SAELDOR_I, WeaponStyle.MELEE);
StyleMap.put(ItemID.BLADE_OF_SAELDOR_C, WeaponStyle.MELEE);
StyleMap.put(ItemID.BLADE_OF_SAELDOR_INACTIVE, WeaponStyle.MELEE);
StyleMap.put(ItemID.BLESSED_AXE, WeaponStyle.MELEE);
StyleMap.put(ItemID.BLUE_FLOWERS, WeaponStyle.MELEE);
@@ -8706,6 +8706,14 @@
20621,
20622
],
"tangleroot": [
20661,
24555,
24557,
24559,
24561,
24563
],
"rift guardian": [
20665,
20667,
@@ -1930,5 +1930,12 @@ public abstract class RSClientMixin implements RSClient
{
invertYaw = state;
}
@Inject
@Override
public void stopNow()
{
setStopTimeMs(1);
}
}
@@ -1245,4 +1245,7 @@ public interface RSClient extends RSGameShell, Client
@Import("showLoadingMessages")
void setShowLoadingMessages(boolean showLoadingMessages);
@Import("stopTimeMs")
void setStopTimeMs(long time);
}