Add browser-style drag-to-reorder for chat and server tabs
Dragging a tab shows animated snapshots on the glass pane and swaps with whichever neighbour it reaches the midpoint of; the real tab model is only touched once, on release, so an in-flight mouse grab never gets pulled out from under a rebuilt tab component. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -67,6 +67,8 @@ public final class ChatPanel extends JPanel {
|
||||
/** Static-content tabs (e.g. a moved-out description), keyed by caller-chosen id. */
|
||||
private final Map<String, Tab> noteTabs = new LinkedHashMap<>();
|
||||
|
||||
private final TabDragReorder dragReorder = new TabDragReorder(tabs, this::moveTab);
|
||||
|
||||
private SendHandler sendHandler;
|
||||
private LinkHandler linkHandler;
|
||||
|
||||
@@ -83,6 +85,7 @@ public final class ChatPanel extends JPanel {
|
||||
if (t != null) t.setUnread(false);
|
||||
});
|
||||
tabs.addMouseWheelListener(this::onWheel);
|
||||
dragReorder.attach(tabs);
|
||||
add(tabs, BorderLayout.CENTER);
|
||||
|
||||
JPanel bottom = new JPanel(new BorderLayout(4, 0));
|
||||
@@ -235,6 +238,21 @@ public final class ChatPanel extends JPanel {
|
||||
tabs.remove(tab.scroll);
|
||||
}
|
||||
|
||||
/** Drags a tab from one position to another, keeping the current selection on screen. */
|
||||
private void moveTab(int from, int to) {
|
||||
if (from < 0 || to < 0 || from >= tabs.getTabCount() || to >= tabs.getTabCount() || from == to) return;
|
||||
Component content = tabs.getComponentAt(from);
|
||||
String title = tabs.getTitleAt(from);
|
||||
Icon icon = tabs.getIconAt(from);
|
||||
String tip = tabs.getToolTipTextAt(from);
|
||||
Component header = tabs.getTabComponentAt(from);
|
||||
boolean wasSelected = tabs.getSelectedIndex() == from;
|
||||
tabs.removeTabAt(from);
|
||||
tabs.insertTab(title, icon, content, tip, to);
|
||||
tabs.setTabComponentAt(to, header);
|
||||
if (wasSelected) tabs.setSelectedIndex(to);
|
||||
}
|
||||
|
||||
private void onWheel(MouseWheelEvent e) {
|
||||
Component content = tabs.getSelectedComponent();
|
||||
if (content != null && content.getBounds().contains(e.getPoint())) return;
|
||||
@@ -339,6 +357,8 @@ public final class ChatPanel extends JPanel {
|
||||
titleLabel = new JLabel(title, icon, JLabel.LEADING);
|
||||
titleLabel.setFont(Theme.UI_FONT);
|
||||
p.add(titleLabel);
|
||||
dragReorder.attach(p);
|
||||
dragReorder.attach(titleLabel);
|
||||
if (closable) {
|
||||
JLabel close = new JLabel("×");
|
||||
close.setFont(Theme.UI_BOLD);
|
||||
|
||||
Reference in New Issue
Block a user