fix(gui): various tabs related fixes (PR #2595)

* 1. Fix tab rendering when preview state changed

* 2. Fix selected tab after closing currently active tab

* 3. Fix tab selection when pinning currently active tab

* 4. Make current preview tab permanent on double click

* 5. Fix preview tab font not reloading on settings change
This commit is contained in:
Andrei Kudryavtsev
2025-08-04 22:09:22 +05:00
committed by GitHub
parent bdbeaff8f0
commit da3ac6bff0
5 changed files with 76 additions and 21 deletions
@@ -63,4 +63,6 @@ public interface ITabStatesListener {
default void onTabSave(TabBlueprint blueprint, EditorViewState viewState) {
}
default void onTabPreviewChange(TabBlueprint blueprint) {
}
}
@@ -79,4 +79,9 @@ public class LogTabStates implements ITabStatesListener {
public void onTabVisibilityChange(TabBlueprint blueprint) {
LOG.debug("onTabVisibilityChange: blueprint={}", blueprint);
}
@Override
public void onTabPreviewChange(TabBlueprint blueprint) {
LOG.debug("onTabPreviewChange: blueprint={}", blueprint);
}
}
@@ -64,7 +64,13 @@ public class TabComponent extends JPanel {
}
private Font getLabelFont() {
return tabsController.getMainWindow().getSettings().getFont().deriveFont(Font.BOLD);
Font font = tabsController.getMainWindow().getSettings().getFont();
int style = font.getStyle();
style |= Font.BOLD;
if (getBlueprint().isPreviewTab()) {
style ^= Font.ITALIC; // flip italic bit to distinguish preview
}
return font.deriveFont(style);
}
private void init() {
@@ -75,14 +81,12 @@ public class TabComponent extends JPanel {
icon = new OverlayIcon(node.getIcon());
label = new NodeLabel(buildTabTitle(node), node.disableHtml());
makeLabelFont();
String toolTip = contentPanel.getTabTooltip();
if (toolTip != null) {
setToolTipText(toolTip);
}
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));
label.setIcon(icon);
updateBookmarkIcon();
if (node instanceof JEditableNode) {
((JEditableNode) node).addChangeListener(c -> label.setText(buildTabTitle(node)));
}
@@ -122,6 +126,9 @@ public class TabComponent extends JPanel {
menu.show(e.getComponent(), e.getX(), e.getY());
} else if (SwingUtilities.isLeftMouseButton(e)) {
tabsController.selectTab(node);
if (e.getClickCount() == 2) {
tabsController.setTabPreview(node, false);
}
}
}
};
@@ -129,11 +136,18 @@ public class TabComponent extends JPanel {
addListenerForDnd();
add(label);
updateCloseOrPinButton();
setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
update();
}
public void updateCloseOrPinButton() {
public void update() {
updateCloseOrPinButton();
updateBookmarkIcon();
updateFont();
}
private void updateCloseOrPinButton() {
if (getBlueprint().isPinned()) {
if (closeBtn.isShowing()) {
remove(closeBtn);
@@ -151,7 +165,7 @@ public class TabComponent extends JPanel {
}
}
public void updateBookmarkIcon() {
private void updateBookmarkIcon() {
icon.clear();
if (getBlueprint().isBookmarked()) {
@@ -174,14 +188,8 @@ public class TabComponent extends JPanel {
tabsController.setTabBookmarked(getNode(), bookmarked);
}
private void makeLabelFont() {
boolean previewTab = getBlueprint().isPreviewTab();
if (previewTab) {
Font newLabelFont = new Font(label.getFont().getName(), Font.ITALIC, label.getFont().getSize());
label.setFont(newLabelFont);
} else {
label.setFont(getLabelFont());
}
private void updateFont() {
label.setFont(getLabelFont());
}
private void addListenerForDnd() {
@@ -442,13 +442,28 @@ public class TabbedPane extends JTabbedPane implements ITabStatesListener {
@Override
public void onTabClose(TabBlueprint blueprint) {
ContentPanel contentPanel = getTabByNode(blueprint.getNode());
if (contentPanel == null) {
ContentPanel contentPanelToClose = getTabByNode(blueprint.getNode());
if (contentPanelToClose == null) {
return;
}
tabsMap.remove(contentPanel.getNode());
remove(contentPanel);
contentPanel.dispose();
ContentPanel currentContentPanel = getSelectedContentPanel();
if (currentContentPanel == contentPanelToClose) {
if (lastTab != null && lastTab.getNode() != null) {
selectTab(lastTab);
} else if (getTabCount() > 1) {
int removalIdx = indexOfComponent(contentPanelToClose);
if (removalIdx > 0) { // select left tab
setSelectedIndex(removalIdx - 1);
} else if (removalIdx == 0) { // select right tab
setSelectedIndex(removalIdx + 1);
}
}
}
tabsMap.remove(contentPanelToClose.getNode());
remove(contentPanelToClose);
contentPanelToClose.dispose();
}
@Override
@@ -465,9 +480,13 @@ public class TabbedPane extends JTabbedPane implements ITabStatesListener {
if (tabComponent == null) {
return;
}
boolean restoreSelection = contentPanel == getSelectedContentPanel();
remove(contentPanel);
add(contentPanel, position);
setTabComponentAt(position, tabComponent);
if (restoreSelection) {
setSelectedIndex(position);
}
}
@Override
@@ -476,7 +495,7 @@ public class TabbedPane extends JTabbedPane implements ITabStatesListener {
if (tabComponent == null) {
return;
}
tabComponent.updateCloseOrPinButton();
tabComponent.update();
}
@Override
@@ -485,7 +504,7 @@ public class TabbedPane extends JTabbedPane implements ITabStatesListener {
if (tabComponent == null) {
return;
}
tabComponent.updateBookmarkIcon();
tabComponent.update();
}
@Override
@@ -498,6 +517,15 @@ public class TabbedPane extends JTabbedPane implements ITabStatesListener {
}
}
@Override
public void onTabPreviewChange(TabBlueprint blueprint) {
TabComponent tabComponent = getTabComponentByNode(blueprint.getNode());
if (tabComponent == null) {
return;
}
tabComponent.update();
}
@Override
public void onTabRestore(TabBlueprint blueprint, EditorViewState viewState) {
ContentPanel contentPanel = getTabByNode(blueprint.getNode());
@@ -281,6 +281,18 @@ public class TabsController {
}
}
public void setTabPreview(JNode node, boolean isPreview) {
TabBlueprint blueprint = getTabByNode(node);
setTabPreviewInternal(blueprint, isPreview);
}
private void setTabPreviewInternal(TabBlueprint blueprint, boolean isPreview) {
if (blueprint != null && blueprint.isPreviewTab() != isPreview) {
blueprint.setPreviewTab(isPreview);
listeners.forEach(l -> l.onTabPreviewChange(blueprint));
}
}
private void removeTabIfNotReferenced(TabBlueprint blueprint) {
if (blueprint.isHidden() && !blueprint.isReferenced()) {
tabsMap.remove(blueprint.getNode());