Enabled tabs to be rearranged. Did not add functionality for a tab to be dropped out. We could possibly add it at a later time, also add a setting to toggle it on/off? Recommend to gather feedback to see if that is something wanted.

This commit is contained in:
Cody 2023-01-23 23:13:36 -08:00
parent 218de052e0
commit ae6911658c
5 changed files with 45 additions and 172 deletions

View file

@ -129,8 +129,6 @@ import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
public class BytecodeViewer public class BytecodeViewer
{ {
//TODO fix this for tab dragging & better tab controls
public static boolean EXPERIMENTAL_TAB_CODE = true;
//the launch args called on BCV //the launch args called on BCV
public static String[] launchArgs; public static String[] launchArgs;

View file

@ -2,14 +2,23 @@ package the.bytecode.club.bytecodeviewer.gui.resourceviewer;
import com.android.tools.r8.internal.Cl; import com.android.tools.r8.internal.Cl;
import com.github.weisj.darklaf.components.CloseButton; import com.github.weisj.darklaf.components.CloseButton;
import com.github.weisj.darklaf.listener.MouseClickListener;
import the.bytecode.club.bytecodeviewer.gui.components.listeners.MouseClickedListener;
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class CloseButtonComponent extends JPanel { public class CloseButtonComponent extends JPanel {
private final JTabbedPane pane; private final JTabbedPane pane;
String title = "";
public CloseButtonComponent(final JTabbedPane pane) { public CloseButtonComponent(final JTabbedPane pane) {
super(new FlowLayout(FlowLayout.LEFT, 0, 0)); super(new FlowLayout(FlowLayout.LEFT, 0, 0));
if (pane == null) { if (pane == null) {
@ -33,6 +42,40 @@ public class CloseButtonComponent extends JPanel {
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
JButton button = new CloseButton(); JButton button = new CloseButton();
add(button); add(button);
JPopupMenu rightClickMenu = new JPopupMenu();
JMenuItem closeAllTabs = new JMenuItem(String.valueOf(TranslatedStrings.CLOSE_ALL_BUT_THIS));
JMenuItem closeTab = new JMenuItem(String.valueOf(TranslatedStrings.CLOSE_TAB));
rightClickMenu.add(closeAllTabs);
rightClickMenu.add(closeTab);
button.setComponentPopupMenu(rightClickMenu);
button.addMouseListener(new MouseClickedListener(e ->
{
if (pane.indexOfTabComponent(CloseButtonComponent.this) != -1)
pane.remove(pane.indexOfTabComponent(CloseButtonComponent.this));
}));
closeTab.addActionListener(e ->
{
if (pane.indexOfTabComponent(CloseButtonComponent.this) != -1)
pane.remove(pane.indexOfTabComponent(CloseButtonComponent.this));
});
closeAllTabs.addActionListener(e ->
{
while (true) {
if (pane.getTabCount() <= 1)
return;
if (pane.indexOfTabComponent(CloseButtonComponent.this) != 0)
pane.remove(0);
else
pane.remove(1);
}
});
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
} }

View file

@ -1,6 +1,5 @@
package the.bytecode.club.bytecodeviewer.gui.resourceviewer; package the.bytecode.club.bytecodeviewer.gui.resourceviewer;
import com.github.weisj.darklaf.components.CloseButton;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import javax.swing.*; import javax.swing.*;
@ -8,10 +7,6 @@ import java.awt.*;
import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable; import java.awt.datatransfer.Transferable;
import java.awt.dnd.*; import java.awt.dnd.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;

View file

@ -76,166 +76,8 @@ public class TabbedPane extends JPanel {
this.add(label); this.add(label);
// add more space between the label and the button // add more space between the label and the button
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
// tab button
JButton exitButton = new CloseButton();
// add more space to the top of the component // add more space to the top of the component
setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
//define the right click pop-up menu
JPopupMenu rightClickMenu = new JPopupMenu();
this.putClientProperty("index", this.getTabIndex());
JMenuItem closeAllTabs = new JMenuItem(TranslatedStrings.CLOSE_ALL_BUT_THIS + ": " + name);
JMenuItem closeTab = new JMenuItem(TranslatedStrings.CLOSE_TAB + ": " + name);
rightClickMenu.add(closeAllTabs);
rightClickMenu.add(closeTab);
//setComponentPopupMenu(rightClickMenu);
exitButton.setComponentPopupMenu(rightClickMenu);
exitButton.addMouseListener(new MouseClickedListener(e ->
{
if (this.getTabIndex() != -1)
existingTabs.remove(this.getTabIndex());
}));
closeTab.addActionListener(e ->
{
if (this.getTabIndex() != -1)
existingTabs.remove(this.getTabIndex());
});
closeAllTabs.addActionListener(e ->
{
while (true) {
if (existingTabs.getTabCount() <= 1)
return;
if (this.getTabIndex() != 0)
existingTabs.remove(0);
else
existingTabs.remove(1);
}
});
//tab dragging
if (BytecodeViewer.EXPERIMENTAL_TAB_CODE) {
/*label.addMouseListener(new MouseListener() {
@Override public void mouseClicked(MouseEvent e) {}
@Override public void mouseEntered(MouseEvent arg0) {
}
@Override public void mouseExited(MouseEvent arg0) {
}
@Override public void mousePressed(MouseEvent e) {
onMousePressed(e);
}
@Override public void mouseReleased(MouseEvent e) {
stopDragging(e.getX(), e.getY());
}
});*/
this.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent e) {
onMousePressed(e);
}
@Override
public void mouseReleased(MouseEvent e) {
}
});
}
//middle click close
if (BytecodeViewer.EXPERIMENTAL_TAB_CODE) {
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON2)
return;
final int i = existingTabs.indexOfTabComponent(TabbedPane.this);
if (i != -1)
existingTabs.remove(i);
}
});
}
}
private void stopDragging(int mouseX, int mouseY) {
if (System.currentTimeMillis() - startedDragging >= 210) {
if (mouseX < 0) {
mouseX = 0;
}
Rectangle bounds = new Rectangle(1, 1, mouseX, mouseY);
System.out.println("debug-5: " + mouseX + ", " + mouseY);
int totalTabs = BytecodeViewer.viewer.workPane.tabs.getTabCount();
int curIndex = getTabIndex();
int toIndex = -1;
//Set up the indexes of our tabs.
for (int i = 0; i < totalTabs; i++) {
Component c = BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(i);
System.err.println("Our bounds: " + bounds + " component: " + c.getBounds() + " intersects: " + bounds.intersects(c.getBounds()));
if (bounds.intersects(c.getBounds()) && c != this) {
toIndex = i;
}
}
System.err.println(totalTabs + " " + curIndex + " " + toIndex);
if (toIndex == totalTabs) {
System.err.println("here");
} else if (curIndex > toIndex) {
if (toIndex == -1) {
toIndex = 0;
}
// [tab0=index0][tab1=index1]
// ---> == remove(tab0)
// [tab1=index0]
// add(tab0)
// [tab1=index0][tab0=index1]
Component c = BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(toIndex + 1);
System.err.println("here1");
// BytecodeViewer.viewer.workPane.tabs.remove(curIndex - 1); // 0
// BytecodeViewer.viewer.workPane.tabs.add(BytecodeViewer.viewer.workPane.op);
// BytecodeViewer.viewer.workPane.tabs.setTabComponentAt(curIndex, BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(curIndex - 1));
} else {
BytecodeViewer.viewer.workPane.tabs.remove(curIndex); // 0
BytecodeViewer.viewer.workPane.tabs.add(resource);
BytecodeViewer.viewer.workPane.tabs.setTabComponentAt(toIndex, this);
}
if (toIndex == -1) {
for (int i = 0; i < totalTabs; i++) {
Component c = BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(i);
//do some check to see if it's past the X or Y
if (c != null) {
System.out.println("debug-6: " + c.getBounds());
}
}
}
}
SwingUtilities.invokeLater(() ->
{
label.setBackground(BLANK_COLOR);
label.updateUI();
});
} }
public void onMousePressed(MouseEvent e) public void onMousePressed(MouseEvent e)
@ -260,15 +102,11 @@ public class TabbedPane extends JPanel {
BytecodeViewer.viewer.workPane.tabs.setSelectedIndex(i); BytecodeViewer.viewer.workPane.tabs.setSelectedIndex(i);
} }
} }
else
{
stopDragging(e.getX(), e.getY());
}
} }
private static final long serialVersionUID = -4774885688297538774L; private static final long serialVersionUID = -4774885688297538774L;
public int getTabIndex() { /*public int getTabIndex() {
return tabs.indexOfTabComponent(this); return tabs.indexOfTabComponent(this);
} }*/
} }

View file

@ -230,7 +230,6 @@ public class Workspace extends TranslatedVisibleComponent
resourceView.resource.workingName = workingName; resourceView.resource.workingName = workingName;
//set the tabs index //set the tabs index
// tabs.setTabComponentAt(tabIndex, tabbedPane);
tabs.setTabComponentAt(tabIndex, new CloseButtonComponent(tabs)); tabs.setTabComponentAt(tabIndex, new CloseButtonComponent(tabs));
//open the tab that was just added //open the tab that was just added