feat(gui): dragging tab appearance settings (#2120)(PR #2118)

This commit is contained in:
Andrei Kudryavtsev
2024-03-09 01:11:58 +05:00
committed by GitHub
parent 2fdd496518
commit 3599b248a4
15 changed files with 53 additions and 12 deletions
@@ -41,6 +41,7 @@ import jadx.gui.settings.data.ShortcutsWrapper;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.action.ActionModel;
import jadx.gui.ui.codearea.EditorTheme;
import jadx.gui.ui.tab.dnd.TabDndGhostType;
import jadx.gui.utils.FontUtils;
import jadx.gui.utils.LafManager;
import jadx.gui.utils.LangLocale;
@@ -52,7 +53,7 @@ public class JadxSettings extends JadxCLIArgs {
private static final Path USER_HOME = Paths.get(System.getProperty("user.home"));
private static final int RECENT_PROJECTS_COUNT = 30;
private static final int CURRENT_SETTINGS_VERSION = 19;
private static final int CURRENT_SETTINGS_VERSION = 20;
private static final Font DEFAULT_FONT = new RSyntaxTextArea().getFont();
@@ -134,6 +135,8 @@ public class JadxSettings extends JadxCLIArgs {
private boolean dockLogViewer = true;
private TabDndGhostType tabDndGhostType = TabDndGhostType.OUTLINE;
private int settingsVersion = CURRENT_SETTINGS_VERSION;
@JadxSettingsAdapter.GsonExclude
@@ -749,6 +752,14 @@ public class JadxSettings extends JadxCLIArgs {
this.xposedCodegenLanguage = language;
}
public void setTabDndGhostType(TabDndGhostType tabDndGhostType) {
this.tabDndGhostType = tabDndGhostType;
}
public TabDndGhostType getTabDndGhostType() {
return this.tabDndGhostType;
}
private void upgradeSettings(int fromVersion) {
LOG.debug("upgrade settings from version: {} to {}", fromVersion, CURRENT_SETTINGS_VERSION);
if (fromVersion <= 10) {
@@ -790,6 +801,10 @@ public class JadxSettings extends JadxCLIArgs {
xposedCodegenLanguage = XposedCodegenLanguage.JAVA;
fromVersion++;
}
if (fromVersion == 19) {
tabDndGhostType = TabDndGhostType.OUTLINE;
fromVersion++;
}
if (fromVersion != CURRENT_SETTINGS_VERSION) {
LOG.warn("Incorrect settings upgrade. Expected version: {}, got: {}", CURRENT_SETTINGS_VERSION, fromVersion);
}
@@ -65,6 +65,7 @@ import jadx.gui.settings.ui.plugins.PluginSettings;
import jadx.gui.settings.ui.shortcut.ShortcutsSettingsGroup;
import jadx.gui.ui.MainWindow;
import jadx.gui.ui.codearea.EditorTheme;
import jadx.gui.ui.tab.dnd.TabDndGhostType;
import jadx.gui.utils.FontUtils;
import jadx.gui.utils.LafManager;
import jadx.gui.utils.LangLocale;
@@ -396,6 +397,15 @@ public class JadxSettingsWindow extends JDialog {
}
}
});
JComboBox<TabDndGhostType> tabDndGhostTypeCbx = new JComboBox<>(TabDndGhostType.values());
tabDndGhostTypeCbx.setSelectedItem(settings.getTabDndGhostType());
tabDndGhostTypeCbx.addActionListener(e -> {
settings.setTabDndGhostType((TabDndGhostType) tabDndGhostTypeCbx.getSelectedItem());
mainWindow.loadSettings();
});
group.addRow(NLS.str("preferences.tab_dnd_appearance"), tabDndGhostTypeCbx);
return group;
}
@@ -1306,7 +1306,7 @@ public class MainWindow extends JFrame {
tabbedPane = new TabbedPane(this);
tabbedPane.setMinimumSize(new Dimension(150, 150));
new TabDndController(tabbedPane);
new TabDndController(tabbedPane, settings);
rightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
rightSplitPane.setTopComponent(tabbedPane);
@@ -41,6 +41,7 @@ import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.plaf.metal.MetalTabbedPaneUI;
import jadx.gui.settings.JadxSettings;
import jadx.gui.ui.tab.TabbedPane;
public class TabDndController {
@@ -63,11 +64,11 @@ public class TabDndController {
protected Rectangle rectForward = new Rectangle();
private boolean isDragging = false;
public TabDndController(TabbedPane pane) {
public TabDndController(TabbedPane pane, JadxSettings settings) {
pane.setDnd(this);
this.pane = pane;
tabDndGhostPane = new TabDndGhostPane(this);
tabDndGhostPane = new TabDndGhostPane(this, settings);
new DropTarget(tabDndGhostPane, DnDConstants.ACTION_COPY_OR_MOVE, new TabDndTargetListener(this), true);
DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(pane,
@@ -244,11 +245,11 @@ public class TabDndController {
pane.setTabComponentAt(dragTabIndex, c);
break;
}
case COLORFUL_RECT: {
case OUTLINE: {
tabDndGhostPane.setGhostSize(d);
break;
}
case NONE:
case TARGET_MARK:
break;
}
}
@@ -34,20 +34,24 @@ import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.UIManager;
import jadx.gui.settings.JadxSettings;
public class TabDndGhostPane extends JComponent {
private final TabDndController dnd;
private final Rectangle lineRect = new Rectangle();
private final Point location = new Point();
private transient BufferedImage ghostImage;
private TabDndGhostType tabDndGhostType = TabDndGhostType.COLORFUL_RECT;
private JadxSettings settings;
private TabDndGhostType tabDndGhostType = TabDndGhostType.OUTLINE;
private Dimension ghostSize;
private Color ghostColor;
private Insets insets;
protected TabDndGhostPane(TabDndController dnd) {
protected TabDndGhostPane(TabDndController dnd, JadxSettings settings) {
super();
this.dnd = dnd;
this.settings = settings;
loadSettings();
}
@@ -58,6 +62,8 @@ public class TabDndGhostPane extends JComponent {
Insets ins = UIManager.getInsets("TabbedPane.tabInsets");
insets = ins != null ? ins : new Insets(0, 0, 0, 0);
tabDndGhostType = settings.getTabDndGhostType();
}
public void setTargetRect(int x, int y, int width, int height) {
@@ -129,7 +135,7 @@ public class TabDndGhostPane extends JComponent {
g.drawImage(ghostImage, (int) x, (int) y, this);
break;
}
case COLORFUL_RECT: {
case OUTLINE: {
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .2f));
if (ghostSize == null) {
return;
@@ -140,7 +146,7 @@ public class TabDndGhostPane extends JComponent {
g.fillRect((int) x, (int) y, ghostSize.width, ghostSize.height);
break;
}
case NONE:
case TARGET_MARK:
break;
}
}
@@ -10,10 +10,10 @@ public enum TabDndGhostType {
/**
* Colored rect of tabs size is dragged along with cursor.
*/
COLORFUL_RECT,
OUTLINE,
/**
* Only insert mark is rendered.
*/
NONE,
TARGET_MARK,
}
@@ -236,6 +236,7 @@ preferences.search_group_title=Ressourcen durchsuchen
#preferences.search_results_per_page=Results per page (0 - no limit)
preferences.res_file_ext=Dateierweiterungen (z.B. .xml|.html), * bedeutet alle
preferences.res_skip_file=Dateien überspringen (MB)
preferences.tab_dnd_appearance=Dragging tab appearance
#preferences.plugins.install=Install plugin
#preferences.plugins.install_btn=Install
@@ -236,6 +236,7 @@ preferences.search_group_title=Search
preferences.search_results_per_page=Results per page (0 - no limit)
preferences.res_file_ext=Resource files extensions ('xml|html', * for all)
preferences.res_skip_file=Skip resources files if larger (MB) (0 - disable)
preferences.tab_dnd_appearance=Dragging tab appearance
preferences.plugins.install=Install plugin
preferences.plugins.install_btn=Install
@@ -236,6 +236,7 @@ preferences.reset_title=Reestablecer preferencias
#preferences.search_results_per_page=Results per page (0 - no limit)
#preferences.res_file_ext=Resource files extensions ('xml|html', * for all)
#preferences.res_skip_file=Skip resources files if larger (MB)
#preferences.tab_dnd_appearance=Dragging tab appearance
#preferences.plugins.install=Install plugin
#preferences.plugins.install_btn=Install
@@ -236,6 +236,7 @@ preferences.search_group_title=Pencarian
preferences.search_results_per_page=Hasil per halaman (0 - tanpa batas)
preferences.res_file_ext=Ekstensi berkas sumber daya ('xml|html', * untuk semua)
preferences.res_skip_file=Lewati berkas sumber daya jika lebih besar (MB) (0 - nonaktifkan)
preferences.tab_dnd_appearance=Dragging tab appearance
preferences.plugins.install=Instal plugin
preferences.plugins.install_btn=Instal
@@ -236,6 +236,7 @@ preferences.search_group_title=리소스 검색
#preferences.search_results_per_page=Results per page (0 - no limit)
preferences.res_file_ext=파일 확장자 (예: .xml|.html) (* 은 전체를 의미)
preferences.res_skip_file=이 옵션보다 큰 파일 건너 뛰기 (MB)
preferences.tab_dnd_appearance=Dragging tab appearance
#preferences.plugins.install=Install plugin
#preferences.plugins.install_btn=Install
@@ -236,6 +236,7 @@ preferences.search_group_title=Buscar recursos
#preferences.search_results_per_page=Results per page (0 - no limit)
preferences.res_file_ext=Extensões de arquivos (ex: .xml|.html), * significa todas
preferences.res_skip_file=Pular arquivos excedidos
preferences.tab_dnd_appearance=Dragging tab appearance
#preferences.plugins.install=Install plugin
#preferences.plugins.install_btn=Install
@@ -236,6 +236,7 @@ preferences.search_group_title=Поиск
preferences.search_results_per_page=Результатов на страницу (0 - без лимита)
preferences.res_file_ext=Расширения файлов ресурсов ('xml|html', * для всех)
preferences.res_skip_file=Пропускать ресурсы больше чем (в МБ)
preferences.tab_dnd_appearance=Dragging tab appearance
#preferences.plugins.install=Install plugin
#preferences.plugins.install_btn=Install
@@ -236,6 +236,7 @@ preferences.search_group_title=搜索资源
preferences.search_results_per_page=每页结果数(0 - 无限制)
preferences.res_file_ext=文件扩展名(e.g. .xml|.html),* 表示所有
preferences.res_skip_file=跳过文件大小(MB
preferences.tab_dnd_appearance=Dragging tab appearance
preferences.plugins.install=安装插件
preferences.plugins.install_btn=安装
@@ -236,6 +236,7 @@ preferences.search_group_title=搜尋資源
preferences.search_results_per_page=每頁的搜尋結果數 (0 - 無限制)
preferences.res_file_ext=副檔名 (e.g. .xml|.html), * 表示全部
preferences.res_skip_file=略過大於此值的檔案 (MB)
preferences.tab_dnd_appearance=Dragging tab appearance
preferences.plugins.install=安裝外掛程式
preferences.plugins.install_btn=安裝