Add ChatboxPanelManager to allow for more advanced chatbox inputs
This commit is contained in:
@@ -53,6 +53,7 @@ import net.runelite.client.discord.DiscordService;
|
||||
import net.runelite.client.game.ClanManager;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.game.LootManager;
|
||||
import net.runelite.client.game.chatbox.ChatboxPanelManager;
|
||||
import net.runelite.client.menus.MenuManager;
|
||||
import net.runelite.client.plugins.PluginManager;
|
||||
import net.runelite.client.rs.ClientUpdateCheckMode;
|
||||
@@ -141,6 +142,9 @@ public class RuneLite
|
||||
@Inject
|
||||
private Provider<LootManager> lootManager;
|
||||
|
||||
@Inject
|
||||
private Provider<ChatboxPanelManager> chatboxPanelManager;
|
||||
|
||||
@Inject
|
||||
@Nullable
|
||||
private Client client;
|
||||
@@ -278,6 +282,7 @@ public class RuneLite
|
||||
eventBus.register(chatMessageManager.get());
|
||||
eventBus.register(commandManager.get());
|
||||
eventBus.register(lootManager.get());
|
||||
eventBus.register(chatboxPanelManager.get());
|
||||
|
||||
// Add core overlays
|
||||
WidgetOverlay.createOverlays(client).forEach(overlayManager::add);
|
||||
|
||||
@@ -98,7 +98,7 @@ public class ChatboxInputManager
|
||||
}
|
||||
this.open = false;
|
||||
clientThread.invoke(() -> client.runScript(
|
||||
ScriptID.CLOSE_CHATBOX_INPUT,
|
||||
ScriptID.RESET_CHATBOX_INPUT,
|
||||
1,
|
||||
1
|
||||
));
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.game.chatbox;
|
||||
|
||||
/**
|
||||
* A modal input that lives in the chatbox panel.
|
||||
*/
|
||||
public abstract class ChatboxInput
|
||||
{
|
||||
protected void open()
|
||||
{
|
||||
}
|
||||
|
||||
protected void close()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* 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.game.chatbox;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.ScriptID;
|
||||
import net.runelite.api.VarClientInt;
|
||||
import net.runelite.api.events.ScriptCallbackEvent;
|
||||
import net.runelite.api.vars.InputType;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.input.MouseListener;
|
||||
import net.runelite.client.input.MouseManager;
|
||||
import net.runelite.client.input.MouseWheelListener;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class ChatboxPanelManager
|
||||
{
|
||||
private final Client client;
|
||||
private final ClientThread clientThread;
|
||||
private final EventBus eventBus;
|
||||
|
||||
private final KeyManager keyManager;
|
||||
private final MouseManager mouseManager;
|
||||
|
||||
private final Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider;
|
||||
private final Provider<ChatboxTextInput> chatboxTextInputProvider;
|
||||
|
||||
@Getter
|
||||
private ChatboxInput currentInput = null;
|
||||
|
||||
@Inject
|
||||
private ChatboxPanelManager(EventBus eventBus, Client client, ClientThread clientThread,
|
||||
KeyManager keyManager, MouseManager mouseManager,
|
||||
Provider<ChatboxTextMenuInput> chatboxTextMenuInputProvider, Provider<ChatboxTextInput> chatboxTextInputProvider)
|
||||
{
|
||||
this.client = client;
|
||||
this.clientThread = clientThread;
|
||||
this.eventBus = eventBus;
|
||||
|
||||
this.keyManager = keyManager;
|
||||
this.mouseManager = mouseManager;
|
||||
|
||||
this.chatboxTextMenuInputProvider = chatboxTextMenuInputProvider;
|
||||
this.chatboxTextInputProvider = chatboxTextInputProvider;
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
clientThread.invokeLater(this::unsafeCloseInput);
|
||||
}
|
||||
|
||||
private void unsafeCloseInput()
|
||||
{
|
||||
client.runScript(
|
||||
ScriptID.RESET_CHATBOX_INPUT,
|
||||
0,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
private void unsafeOpenInput(ChatboxInput input)
|
||||
{
|
||||
client.runScript(ScriptID.CLEAR_CHATBOX_PANEL);
|
||||
|
||||
eventBus.register(input);
|
||||
if (input instanceof KeyListener)
|
||||
{
|
||||
keyManager.registerKeyListener((KeyListener) input);
|
||||
}
|
||||
if (input instanceof MouseListener)
|
||||
{
|
||||
mouseManager.registerMouseListener((MouseListener) input);
|
||||
}
|
||||
if (input instanceof MouseWheelListener)
|
||||
{
|
||||
mouseManager.registerMouseWheelListener((MouseWheelListener) input);
|
||||
}
|
||||
|
||||
currentInput = input;
|
||||
client.setVar(VarClientInt.INPUT_TYPE, InputType.RUNELITE_CHATBOX_PANEL.getType());
|
||||
client.getWidget(WidgetInfo.CHATBOX_TITLE).setHidden(true);
|
||||
client.getWidget(WidgetInfo.CHATBOX_FULL_INPUT).setHidden(true);
|
||||
|
||||
Widget c = getContainerWidget();
|
||||
c.deleteAllChildren();
|
||||
c.setOnDialogAbortListener((JavaScriptCallback) ev -> this.unsafeCloseInput());
|
||||
input.open();
|
||||
}
|
||||
|
||||
public void openInput(ChatboxInput input)
|
||||
{
|
||||
clientThread.invokeLater(() -> unsafeOpenInput(input));
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput openTextMenuInput(String title)
|
||||
{
|
||||
return chatboxTextMenuInputProvider.get()
|
||||
.title(title);
|
||||
}
|
||||
|
||||
public ChatboxTextInput openTextInput(String prompt)
|
||||
{
|
||||
return chatboxTextInputProvider.get()
|
||||
.prompt(prompt);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onScriptCallbackEvent(ScriptCallbackEvent ev)
|
||||
{
|
||||
if (currentInput != null && "resetChatboxInput".equals(ev.getEventName()))
|
||||
{
|
||||
try
|
||||
{
|
||||
currentInput.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.warn("Exception closing {}", currentInput.getClass(), e);
|
||||
}
|
||||
|
||||
eventBus.unregister(currentInput);
|
||||
if (currentInput instanceof KeyListener)
|
||||
{
|
||||
keyManager.unregisterKeyListener((KeyListener) currentInput);
|
||||
}
|
||||
if (currentInput instanceof MouseListener)
|
||||
{
|
||||
mouseManager.unregisterMouseListener((MouseListener) currentInput);
|
||||
}
|
||||
if (currentInput instanceof MouseWheelListener)
|
||||
{
|
||||
mouseManager.unregisterMouseWheelListener((MouseWheelListener) currentInput);
|
||||
}
|
||||
currentInput = null;
|
||||
}
|
||||
}
|
||||
|
||||
public Widget getContainerWidget()
|
||||
{
|
||||
return client.getWidget(WidgetInfo.CHATBOX_CONTAINER);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,666 @@
|
||||
/*
|
||||
* 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.game.chatbox;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.IOException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.ToIntFunction;
|
||||
import javax.swing.SwingUtilities;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.FontTypeFace;
|
||||
import net.runelite.api.FontID;
|
||||
import net.runelite.api.WidgetType;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetPositionMode;
|
||||
import net.runelite.api.widgets.WidgetSizeMode;
|
||||
import net.runelite.api.widgets.WidgetTextAlignment;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.MouseListener;
|
||||
|
||||
@Slf4j
|
||||
public class ChatboxTextInput extends ChatboxInput implements KeyListener, MouseListener
|
||||
{
|
||||
private static final int CURSOR_FLASH_RATE_MILLIS = 1000;
|
||||
|
||||
private final ChatboxPanelManager chatboxPanelManager;
|
||||
private final ClientThread clientThread;
|
||||
|
||||
private static IntPredicate getDefaultCharValidator()
|
||||
{
|
||||
return i -> i >= 32 && i < 127;
|
||||
}
|
||||
|
||||
@Getter
|
||||
private String prompt;
|
||||
|
||||
private StringBuffer value = new StringBuffer();
|
||||
|
||||
@Getter
|
||||
private int cursor = 0;
|
||||
|
||||
@Getter
|
||||
private int cursorEnd = 0;
|
||||
|
||||
private int selectionStart = -1;
|
||||
private int selectionEnd = -1;
|
||||
|
||||
@Getter
|
||||
private IntPredicate charValidator = getDefaultCharValidator();
|
||||
|
||||
@Getter
|
||||
private Runnable onClose = null;
|
||||
|
||||
@Getter
|
||||
private Consumer<String> onDone = null;
|
||||
|
||||
@Getter
|
||||
private Consumer<String> onChanged = null;
|
||||
|
||||
@Getter
|
||||
private int fontID = FontID.QUILL_8;
|
||||
|
||||
// This is a lambda so I can have atomic updates for it's captures
|
||||
private ToIntFunction<MouseEvent> getCharOffset = null;
|
||||
private Predicate<MouseEvent> isInBounds = null;
|
||||
|
||||
private boolean built = false;
|
||||
|
||||
@Inject
|
||||
protected ChatboxTextInput(ChatboxPanelManager chatboxPanelManager, ClientThread clientThread)
|
||||
{
|
||||
this.chatboxPanelManager = chatboxPanelManager;
|
||||
this.clientThread = clientThread;
|
||||
}
|
||||
|
||||
public ChatboxTextInput prompt(String prompt)
|
||||
{
|
||||
this.prompt = prompt;
|
||||
if (built)
|
||||
{
|
||||
clientThread.invoke(this::update);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextInput value(String value)
|
||||
{
|
||||
this.value = new StringBuffer(value);
|
||||
if (built)
|
||||
{
|
||||
clientThread.invoke(this::update);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextInput cursorAt(int index)
|
||||
{
|
||||
return cursorAt(index, index);
|
||||
}
|
||||
|
||||
public ChatboxTextInput cursorAt(int indexA, int indexB)
|
||||
{
|
||||
if (indexA < 0)
|
||||
{
|
||||
indexA = 0;
|
||||
}
|
||||
if (indexB < 0)
|
||||
{
|
||||
indexB = 0;
|
||||
}
|
||||
if (indexA > value.length())
|
||||
{
|
||||
indexA = value.length();
|
||||
}
|
||||
if (indexB > value.length())
|
||||
{
|
||||
indexB = value.length();
|
||||
}
|
||||
int start = indexA;
|
||||
int end = indexB;
|
||||
if (start > end)
|
||||
{
|
||||
int v = start;
|
||||
start = end;
|
||||
end = v;
|
||||
}
|
||||
|
||||
this.cursor = start;
|
||||
this.cursorEnd = end;
|
||||
|
||||
if (built)
|
||||
{
|
||||
clientThread.invoke(this::update);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
public ChatboxTextInput charValidator(IntPredicate val)
|
||||
{
|
||||
if (val == null)
|
||||
{
|
||||
val = getDefaultCharValidator();
|
||||
}
|
||||
this.charValidator = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextInput onClose(Runnable onClose)
|
||||
{
|
||||
this.onClose = onClose;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextInput onDone(Consumer<String> onDone)
|
||||
{
|
||||
this.onDone = onDone;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextInput onChanged(Consumer<String> onChanged)
|
||||
{
|
||||
this.onChanged = onChanged;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextInput fontID(int fontID)
|
||||
{
|
||||
this.fontID = fontID;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void update()
|
||||
{
|
||||
this.built = true;
|
||||
Widget container = chatboxPanelManager.getContainerWidget();
|
||||
container.deleteAllChildren();
|
||||
|
||||
Widget promptWidget = container.createChild(-1, WidgetType.TEXT);
|
||||
promptWidget.setText(this.prompt);
|
||||
promptWidget.setTextColor(0x800000);
|
||||
promptWidget.setFontId(fontID);
|
||||
promptWidget.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
|
||||
promptWidget.setOriginalX(0);
|
||||
promptWidget.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
|
||||
promptWidget.setOriginalY(8);
|
||||
promptWidget.setOriginalHeight(24);
|
||||
promptWidget.setXTextAlignment(WidgetTextAlignment.CENTER);
|
||||
promptWidget.setYTextAlignment(WidgetTextAlignment.CENTER);
|
||||
promptWidget.setWidthMode(WidgetSizeMode.MINUS);
|
||||
promptWidget.revalidate();
|
||||
|
||||
buildEdit(0, 50, container.getWidth(), 0);
|
||||
}
|
||||
|
||||
protected void buildEdit(int x, int y, int w, int h)
|
||||
{
|
||||
Widget container = chatboxPanelManager.getContainerWidget();
|
||||
|
||||
String lt = value.substring(0, this.cursor);
|
||||
String mt = value.substring(this.cursor, this.cursorEnd);
|
||||
String rt = value.substring(this.cursorEnd);
|
||||
|
||||
Widget leftText = container.createChild(-1, WidgetType.TEXT);
|
||||
Widget cursor = container.createChild(-1, WidgetType.RECTANGLE);
|
||||
Widget middleText = container.createChild(-1, WidgetType.TEXT);
|
||||
Widget rightText = container.createChild(-1, WidgetType.TEXT);
|
||||
|
||||
leftText.setFontId(fontID);
|
||||
FontTypeFace font = leftText.getFont();
|
||||
|
||||
if (h <= 0)
|
||||
{
|
||||
h = font.getBaseline();
|
||||
}
|
||||
|
||||
int ltw = font.getTextWidth(lt);
|
||||
int mtw = font.getTextWidth(mt);
|
||||
int rtw = font.getTextWidth(rt);
|
||||
|
||||
int fullWidth = ltw + mtw + rtw;
|
||||
|
||||
int ox = x;
|
||||
if (w > 0)
|
||||
{
|
||||
x += (w - fullWidth) / 2;
|
||||
}
|
||||
|
||||
int ltx = x;
|
||||
int mtx = ltx + ltw;
|
||||
int rtx = mtx + mtw;
|
||||
|
||||
leftText.setText(lt);
|
||||
leftText.setOriginalX(ltx);
|
||||
leftText.setOriginalY(y);
|
||||
leftText.setOriginalWidth(ltw);
|
||||
leftText.setOriginalHeight(h);
|
||||
leftText.revalidate();
|
||||
|
||||
if (mt.length() > 0)
|
||||
{
|
||||
cursor.setTextColor(0x113399);
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor.setTextColor(0xFFFFFF);
|
||||
cursor.setOnTimerListener((JavaScriptCallback) ev ->
|
||||
{
|
||||
boolean on = System.currentTimeMillis() % CURSOR_FLASH_RATE_MILLIS > (CURSOR_FLASH_RATE_MILLIS / 2);
|
||||
cursor.setOpacity(on ? 255 : 0);
|
||||
});
|
||||
}
|
||||
cursor.setFilled(true);
|
||||
cursor.setOriginalX(mtx - 1);
|
||||
cursor.setOriginalY(y);
|
||||
cursor.setOriginalWidth(2 + mtw);
|
||||
cursor.setOriginalHeight(h);
|
||||
cursor.revalidate();
|
||||
|
||||
middleText.setText(mt);
|
||||
middleText.setFontId(fontID);
|
||||
middleText.setOriginalX(mtx);
|
||||
middleText.setOriginalY(y);
|
||||
middleText.setOriginalWidth(mtw);
|
||||
middleText.setOriginalHeight(h);
|
||||
middleText.setTextColor(0xFFFFFF);
|
||||
middleText.revalidate();
|
||||
|
||||
rightText.setText(rt);
|
||||
rightText.setFontId(fontID);
|
||||
rightText.setOriginalX(rtx);
|
||||
rightText.setOriginalY(y);
|
||||
rightText.setOriginalWidth(rtw);
|
||||
rightText.setOriginalHeight(h);
|
||||
rightText.revalidate();
|
||||
|
||||
net.runelite.api.Point ccl = container.getCanvasLocation();
|
||||
int canvasX = ltx + ccl.getX();
|
||||
Rectangle bounds = new Rectangle(ccl.getX() + ox, ccl.getY() + y, w > 0 ? w : fullWidth, h);
|
||||
|
||||
String tsValue = value.toString();
|
||||
isInBounds = ev -> bounds.contains(ev.getPoint());
|
||||
getCharOffset = ev ->
|
||||
{
|
||||
int cx = ev.getX() - canvasX;
|
||||
|
||||
int charIndex = (tsValue.length() * cx) / fullWidth;
|
||||
|
||||
// `i` is used to track max execution time incase there is a font with ligature width data that causes this to fail
|
||||
for (int i = tsValue.length(); i >= 0 && charIndex >= 0 && charIndex <= tsValue.length(); i--)
|
||||
{
|
||||
int lcx = charIndex > 0 ? font.getTextWidth(tsValue.substring(0, charIndex - 1)) : 0;
|
||||
int mcx = font.getTextWidth(tsValue.substring(0, charIndex));
|
||||
int rcx = charIndex + 1 <= tsValue.length() ? font.getTextWidth(tsValue.substring(0, charIndex + 1)) : mcx;
|
||||
|
||||
int leftBound = (lcx + mcx) / 2;
|
||||
int rightBound = (mcx + rcx) / 2;
|
||||
|
||||
if (cx < leftBound)
|
||||
{
|
||||
charIndex--;
|
||||
continue;
|
||||
}
|
||||
if (cx > rightBound)
|
||||
{
|
||||
charIndex++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (charIndex < 0)
|
||||
{
|
||||
charIndex = 0;
|
||||
}
|
||||
if (charIndex > tsValue.length())
|
||||
{
|
||||
charIndex = tsValue.length();
|
||||
}
|
||||
|
||||
return charIndex;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void open()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void close()
|
||||
{
|
||||
if (this.onClose != null)
|
||||
{
|
||||
this.onClose.run();
|
||||
}
|
||||
}
|
||||
|
||||
public ChatboxTextInput build()
|
||||
{
|
||||
if (prompt == null)
|
||||
{
|
||||
throw new IllegalStateException("prompt must be non-null");
|
||||
}
|
||||
chatboxPanelManager.openInput(this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
char c = e.getKeyChar();
|
||||
if (charValidator.test(c))
|
||||
{
|
||||
if (cursor != cursorEnd)
|
||||
{
|
||||
value.delete(cursor, cursorEnd);
|
||||
}
|
||||
value.insert(cursor, c);
|
||||
cursorAt(cursor + 1);
|
||||
if (onChanged != null)
|
||||
{
|
||||
onChanged.accept(getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent ev)
|
||||
{
|
||||
int code = ev.getKeyCode();
|
||||
if (ev.isControlDown())
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case KeyEvent.VK_X:
|
||||
case KeyEvent.VK_C:
|
||||
if (cursor != cursorEnd)
|
||||
{
|
||||
String s = value.substring(cursor, cursorEnd);
|
||||
if (code == KeyEvent.VK_X)
|
||||
{
|
||||
value.delete(cursor, cursorEnd);
|
||||
cursorAt(cursor);
|
||||
}
|
||||
Toolkit.getDefaultToolkit()
|
||||
.getSystemClipboard()
|
||||
.setContents(new StringSelection(s), null);
|
||||
}
|
||||
return;
|
||||
case KeyEvent.VK_V:
|
||||
try
|
||||
{
|
||||
String s = Toolkit.getDefaultToolkit()
|
||||
.getSystemClipboard()
|
||||
.getData(DataFlavor.stringFlavor)
|
||||
.toString();
|
||||
if (cursor != cursorEnd)
|
||||
{
|
||||
value.delete(cursor, cursorEnd);
|
||||
}
|
||||
for (int i = 0; i < s.length(); i++)
|
||||
{
|
||||
char ch = s.charAt(i);
|
||||
if (charValidator.test(ch))
|
||||
{
|
||||
value.insert(cursor, ch);
|
||||
cursor++;
|
||||
}
|
||||
}
|
||||
cursorAt(cursor);
|
||||
if (onChanged != null)
|
||||
{
|
||||
onChanged.accept(getValue());
|
||||
}
|
||||
}
|
||||
catch (IOException | UnsupportedFlavorException ex)
|
||||
{
|
||||
log.warn("Unable to get clipboard", ex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
int newPos = cursor;
|
||||
if (ev.isShiftDown())
|
||||
{
|
||||
if (selectionEnd == -1 || selectionStart == -1)
|
||||
{
|
||||
selectionStart = cursor;
|
||||
selectionEnd = cursor;
|
||||
}
|
||||
newPos = selectionEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectionStart = -1;
|
||||
selectionEnd = -1;
|
||||
}
|
||||
switch (code)
|
||||
{
|
||||
case KeyEvent.VK_DELETE:
|
||||
if (cursor != cursorEnd)
|
||||
{
|
||||
value.delete(cursor, cursorEnd);
|
||||
cursorAt(cursor);
|
||||
if (onChanged != null)
|
||||
{
|
||||
onChanged.accept(getValue());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (cursor < value.length())
|
||||
{
|
||||
value.deleteCharAt(cursor);
|
||||
cursorAt(cursor);
|
||||
if (onChanged != null)
|
||||
{
|
||||
onChanged.accept(getValue());
|
||||
}
|
||||
}
|
||||
return;
|
||||
case KeyEvent.VK_BACK_SPACE:
|
||||
if (cursor != cursorEnd)
|
||||
{
|
||||
value.delete(cursor, cursorEnd);
|
||||
cursorAt(cursor);
|
||||
if (onChanged != null)
|
||||
{
|
||||
onChanged.accept(getValue());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (cursor > 0)
|
||||
{
|
||||
value.deleteCharAt(cursor - 1);
|
||||
cursorAt(cursor - 1);
|
||||
if (onChanged != null)
|
||||
{
|
||||
onChanged.accept(getValue());
|
||||
}
|
||||
}
|
||||
return;
|
||||
case KeyEvent.VK_LEFT:
|
||||
ev.consume();
|
||||
newPos--;
|
||||
break;
|
||||
case KeyEvent.VK_RIGHT:
|
||||
ev.consume();
|
||||
newPos++;
|
||||
break;
|
||||
case KeyEvent.VK_HOME:
|
||||
ev.consume();
|
||||
newPos = 0;
|
||||
break;
|
||||
case KeyEvent.VK_END:
|
||||
ev.consume();
|
||||
newPos = value.length();
|
||||
break;
|
||||
case KeyEvent.VK_ENTER:
|
||||
ev.consume();
|
||||
if (onDone != null)
|
||||
{
|
||||
onDone.accept(getValue());
|
||||
}
|
||||
chatboxPanelManager.close();
|
||||
return;
|
||||
case KeyEvent.VK_ESCAPE:
|
||||
ev.consume();
|
||||
if (cursor != cursorEnd)
|
||||
{
|
||||
cursorAt(cursor);
|
||||
return;
|
||||
}
|
||||
chatboxPanelManager.close();
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if (newPos > value.length())
|
||||
{
|
||||
newPos = value.length();
|
||||
}
|
||||
if (newPos < 0)
|
||||
{
|
||||
newPos = 0;
|
||||
}
|
||||
if (ev.isShiftDown())
|
||||
{
|
||||
selectionEnd = newPos;
|
||||
cursorAt(selectionStart, newPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
cursorAt(newPos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseClicked(MouseEvent mouseEvent)
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mousePressed(MouseEvent mouseEvent)
|
||||
{
|
||||
if (mouseEvent.getButton() != MouseEvent.BUTTON1)
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
if (isInBounds == null || !isInBounds.test(mouseEvent))
|
||||
{
|
||||
if (cursor != cursorEnd)
|
||||
{
|
||||
selectionStart = -1;
|
||||
selectionEnd = -1;
|
||||
cursorAt(getCharOffset.applyAsInt(mouseEvent));
|
||||
}
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
int nco = getCharOffset.applyAsInt(mouseEvent);
|
||||
|
||||
if (mouseEvent.isShiftDown() && selectionEnd != -1)
|
||||
{
|
||||
selectionEnd = nco;
|
||||
cursorAt(selectionStart, selectionEnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
selectionStart = nco;
|
||||
cursorAt(nco);
|
||||
}
|
||||
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseReleased(MouseEvent mouseEvent)
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseEntered(MouseEvent mouseEvent)
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseExited(MouseEvent mouseEvent)
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseDragged(MouseEvent mouseEvent)
|
||||
{
|
||||
if (!SwingUtilities.isLeftMouseButton(mouseEvent))
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
int nco = getCharOffset.applyAsInt(mouseEvent);
|
||||
if (selectionStart != -1)
|
||||
{
|
||||
selectionEnd = nco;
|
||||
cursorAt(selectionStart, selectionEnd);
|
||||
}
|
||||
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseMoved(MouseEvent mouseEvent)
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* 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.game.chatbox;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.FontID;
|
||||
import net.runelite.api.WidgetType;
|
||||
import net.runelite.api.widgets.JavaScriptCallback;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import net.runelite.api.widgets.WidgetPositionMode;
|
||||
import net.runelite.api.widgets.WidgetSizeMode;
|
||||
import net.runelite.api.widgets.WidgetTextAlignment;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
|
||||
@Slf4j
|
||||
public class ChatboxTextMenuInput extends ChatboxInput implements KeyListener
|
||||
{
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
private static final class Entry
|
||||
{
|
||||
private String text;
|
||||
private Runnable callback;
|
||||
}
|
||||
|
||||
private final ChatboxPanelManager chatboxPanelManager;
|
||||
|
||||
@Getter
|
||||
private String title;
|
||||
|
||||
@Getter
|
||||
private List<Entry> options = new ArrayList<>();
|
||||
|
||||
@Getter
|
||||
private Runnable onClose;
|
||||
|
||||
@Inject
|
||||
protected ChatboxTextMenuInput(ChatboxPanelManager chatboxPanelManager)
|
||||
{
|
||||
this.chatboxPanelManager = chatboxPanelManager;
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput title(String title)
|
||||
{
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput option(String text, Runnable callback)
|
||||
{
|
||||
options.add(new Entry(text, callback));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ChatboxTextMenuInput onClose(Runnable onClose)
|
||||
{
|
||||
this.onClose = onClose;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void build()
|
||||
{
|
||||
if (title == null)
|
||||
{
|
||||
throw new IllegalStateException("Title must be set");
|
||||
}
|
||||
|
||||
if (options.size() < 1)
|
||||
{
|
||||
throw new IllegalStateException("You must have atleast 1 option");
|
||||
}
|
||||
|
||||
chatboxPanelManager.openInput(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void open()
|
||||
{
|
||||
Widget container = chatboxPanelManager.getContainerWidget();
|
||||
|
||||
Widget prompt = container.createChild(-1, WidgetType.TEXT);
|
||||
prompt.setText(title);
|
||||
prompt.setTextColor(0x800000);
|
||||
prompt.setFontId(FontID.QUILL_8);
|
||||
prompt.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
|
||||
prompt.setOriginalX(0);
|
||||
prompt.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
|
||||
prompt.setOriginalY(8);
|
||||
prompt.setOriginalHeight(24);
|
||||
prompt.setXTextAlignment(WidgetTextAlignment.CENTER);
|
||||
prompt.setYTextAlignment(WidgetTextAlignment.CENTER);
|
||||
prompt.setWidthMode(WidgetSizeMode.MINUS);
|
||||
prompt.revalidate();
|
||||
|
||||
int y = prompt.getRelativeX() + prompt.getHeight() + 6;
|
||||
int height = container.getHeight() - y - 8;
|
||||
int step = height / options.size();
|
||||
int maxStep = options.size() >= 3 ? 25 : 30;
|
||||
if (step > maxStep)
|
||||
{
|
||||
int ds = step - maxStep;
|
||||
step = maxStep;
|
||||
y += (ds * options.size()) / 2;
|
||||
}
|
||||
|
||||
for (Entry option : options)
|
||||
{
|
||||
Widget optWidget = container.createChild(-1, WidgetType.TEXT);
|
||||
optWidget.setText(option.text);
|
||||
optWidget.setFontId(FontID.QUILL_8);
|
||||
optWidget.setXPositionMode(WidgetPositionMode.ABSOLUTE_CENTER);
|
||||
optWidget.setOriginalX(0);
|
||||
optWidget.setYPositionMode(WidgetPositionMode.ABSOLUTE_TOP);
|
||||
optWidget.setOriginalY(y);
|
||||
optWidget.setOriginalHeight(24);
|
||||
optWidget.setXTextAlignment(WidgetTextAlignment.CENTER);
|
||||
optWidget.setYTextAlignment(WidgetTextAlignment.CENTER);
|
||||
optWidget.setWidthMode(WidgetSizeMode.MINUS);
|
||||
optWidget.setAction(0, "Continue");
|
||||
optWidget.setOnOpListener((JavaScriptCallback) ev -> callback(option));
|
||||
optWidget.setOnMouseOverListener((JavaScriptCallback) ev -> optWidget.setTextColor(0xFFFFFF));
|
||||
optWidget.setOnMouseLeaveListener((JavaScriptCallback) ev -> optWidget.setTextColor(0));
|
||||
optWidget.setHasListener(true);
|
||||
optWidget.revalidate();
|
||||
|
||||
y += step;
|
||||
}
|
||||
}
|
||||
|
||||
private void callback(Entry entry)
|
||||
{
|
||||
Widget container = chatboxPanelManager.getContainerWidget();
|
||||
container.setOnKeyListener((Object[]) null);
|
||||
|
||||
chatboxPanelManager.close();
|
||||
|
||||
entry.callback.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void close()
|
||||
{
|
||||
if (onClose != null)
|
||||
{
|
||||
onClose.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
char c = e.getKeyChar();
|
||||
|
||||
if (c == '\033')
|
||||
{
|
||||
chatboxPanelManager.close();
|
||||
e.consume();
|
||||
return;
|
||||
}
|
||||
|
||||
int n = c - '1';
|
||||
if (n >= 0 && n < options.size())
|
||||
{
|
||||
callback(options.get(n));
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
|
||||
{
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -501,7 +501,7 @@ public class TabInterface
|
||||
{
|
||||
resetSearch();
|
||||
|
||||
clientThread.invokeLater(() -> client.runScript(ScriptID.CLOSE_CHATBOX_INPUT));
|
||||
clientThread.invokeLater(() -> client.runScript(ScriptID.RESET_CHATBOX_INPUT));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -934,7 +934,7 @@ public class TabInterface
|
||||
{
|
||||
// This ensures that any chatbox input (e.g from search) will not remain visible when
|
||||
// selecting/changing tab
|
||||
client.runScript(ScriptID.CLOSE_CHATBOX_INPUT);
|
||||
client.runScript(ScriptID.RESET_CHATBOX_INPUT);
|
||||
|
||||
client.setVar(VarClientInt.INPUT_TYPE, inputType.getType());
|
||||
client.setVar(VarClientStr.INPUT_TEXT, search);
|
||||
|
||||
@@ -148,6 +148,7 @@ public class WidgetInfoTableModel extends AbstractTableModel
|
||||
(w, str) -> w.setTextColor(Integer.parseInt(str, 16)),
|
||||
String.class
|
||||
));
|
||||
out.add(new WidgetField<>("Opacity", Widget::getOpacity, Widget::setOpacity, Integer.class));
|
||||
out.add(new WidgetField<>("FontId", Widget::getFontId, Widget::setFontId, Integer.class));
|
||||
out.add(new WidgetField<>("TextShadowed", Widget::getTextShadowed, Widget::setTextShadowed, Boolean.class));
|
||||
out.add(new WidgetField<>("Name", w -> w.getName().trim(), Widget::setName, String.class));
|
||||
@@ -156,23 +157,32 @@ public class WidgetInfoTableModel extends AbstractTableModel
|
||||
out.add(new WidgetField<>("ItemQuantityMode", Widget::getItemQuantityMode, Widget::setItemQuantityMode, Integer.class));
|
||||
out.add(new WidgetField<>("ModelId", Widget::getModelId));
|
||||
out.add(new WidgetField<>("SpriteId", Widget::getSpriteId, Widget::setSpriteId, Integer.class));
|
||||
out.add(new WidgetField<>("Width", Widget::getWidth, Widget::setWidth, Integer.class));
|
||||
out.add(new WidgetField<>("Height", Widget::getHeight, Widget::setHeight, Integer.class));
|
||||
out.add(new WidgetField<>("BorderType", Widget::getBorderType, Widget::setBorderType, Integer.class));
|
||||
out.add(new WidgetField<>("IsIf3", Widget::isIf3));
|
||||
out.add(new WidgetField<>("HasListener", Widget::hasListener, Widget::setHasListener, Boolean.class));
|
||||
out.add(new WidgetField<>("Filled", Widget::isFilled, Widget::setFilled, Boolean.class));
|
||||
out.add(new WidgetField<>("OriginalX", Widget::getOriginalX, Widget::setOriginalX, Integer.class));
|
||||
out.add(new WidgetField<>("OriginalY", Widget::getOriginalY, Widget::setOriginalY, Integer.class));
|
||||
out.add(new WidgetField<>("OriginalWidth", Widget::getOriginalWidth, Widget::setOriginalWidth, Integer.class));
|
||||
out.add(new WidgetField<>("OriginalHeight", Widget::getOriginalHeight, Widget::setOriginalHeight, Integer.class));
|
||||
out.add(new WidgetField<>("XPositionMode", Widget::getXPositionMode, Widget::setXPositionMode, Integer.class));
|
||||
out.add(new WidgetField<>("YPositionMode", Widget::getYPositionMode, Widget::setYPositionMode, Integer.class));
|
||||
out.add(new WidgetField<>("WidthMode", Widget::getWidthMode, Widget::setWidthMode, Integer.class));
|
||||
out.add(new WidgetField<>("HeightMode", Widget::getHeightMode, Widget::setHeightMode, Integer.class));
|
||||
out.add(new WidgetField<>("XTextAlignment", Widget::getXTextAlignment, Widget::setXTextAlignment, Integer.class));
|
||||
out.add(new WidgetField<>("YTextAlignment", Widget::getYTextAlignment, Widget::setYTextAlignment, Integer.class));
|
||||
out.add(new WidgetField<>("RelativeX", Widget::getRelativeX, Widget::setRelativeX, Integer.class));
|
||||
out.add(new WidgetField<>("RelativeY", Widget::getRelativeY, Widget::setRelativeY, Integer.class));
|
||||
out.add(new WidgetField<>("Width", Widget::getWidth, Widget::setWidth, Integer.class));
|
||||
out.add(new WidgetField<>("Height", Widget::getHeight, Widget::setHeight, Integer.class));
|
||||
out.add(new WidgetField<>("CanvasLocation", Widget::getCanvasLocation));
|
||||
out.add(new WidgetField<>("Bounds", Widget::getBounds));
|
||||
out.add(new WidgetField<>("ScrollX", Widget::getScrollX, Widget::setScrollX, Integer.class));
|
||||
out.add(new WidgetField<>("ScrollY", Widget::getScrollY, Widget::setScrollY, Integer.class));
|
||||
out.add(new WidgetField<>("ScrollWidth", Widget::getScrollWidth, Widget::setScrollWidth, Integer.class));
|
||||
out.add(new WidgetField<>("ScrollHeight", Widget::getScrollHeight, Widget::setScrollHeight, Integer.class));
|
||||
out.add(new WidgetField<>("OriginalX", Widget::getOriginalX));
|
||||
out.add(new WidgetField<>("OriginalY", Widget::getOriginalY));
|
||||
out.add(new WidgetField<>("BorderType", Widget::getBorderType, Widget::setBorderType, Integer.class));
|
||||
out.add(new WidgetField<>("DragDeadZone", Widget::getDragDeadZone, Widget::setDragDeadZone, Integer.class));
|
||||
out.add(new WidgetField<>("DragDeadTime", Widget::getDragDeadTime, Widget::setDragDeadTime, Integer.class));
|
||||
out.add(new WidgetField<>("IsIf3", Widget::isIf3));
|
||||
out.add(new WidgetField<>("HasListener", Widget::hasListener, Widget::setHasListener, Boolean.class));
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -142,6 +142,17 @@ class WidgetInspector extends JFrame
|
||||
onConfigChanged(null);
|
||||
bottomPanel.add(alwaysOnTop);
|
||||
|
||||
final JButton revalidateWidget = new JButton("Revalidate");
|
||||
revalidateWidget.addActionListener(ev -> clientThread.invokeLater(() ->
|
||||
{
|
||||
if (plugin.currentWidget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.currentWidget.revalidate();
|
||||
}));
|
||||
bottomPanel.add(revalidateWidget);
|
||||
|
||||
final JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, treeScrollPane, infoScrollPane);
|
||||
add(split, BorderLayout.CENTER);
|
||||
|
||||
Reference in New Issue
Block a user