package org.intellij.plugins.markdown.ui.split;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.ActionToolbar;
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl;
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
import com.intellij.util.ui.JBEmptyBorder;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.intellij.plugins.markdown.MarkdownBundle;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.ArrayList;
import java.util.List;
public class SplitEditorToolbar extends JPanel implements Disposable {
private static final String LEFT_TOOLBAR_GROUP_ID = "Markdown.Toolbar.Left";
private static final String RIGHT_TOOLBAR_GROUP_ID = "Markdown.Toolbar.Right";
private final MySpacingPanel mySpacingPanel;
private final ActionToolbar myRightToolbar;
private final List<EditorGutterComponentEx> myGutters = new ArrayList<>();
private final ComponentAdapter myAdjustToGutterListener = new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
adjustSpacing();
}
@Override
public void componentShown(ComponentEvent e) {
adjustSpacing();
}
@Override
public void componentHidden(ComponentEvent e) {
adjustSpacing();
}
};
public SplitEditorToolbar(@NotNull final JComponent targetComponentForActions) {
super(new GridBagLayout());
final ActionToolbar leftToolbar = createToolbarFromGroupId(LEFT_TOOLBAR_GROUP_ID);
leftToolbar.setTargetComponent(targetComponentForActions);
myRightToolbar = createToolbarFromGroupId(RIGHT_TOOLBAR_GROUP_ID);
myRightToolbar.setTargetComponent(targetComponentForActions);
mySpacingPanel = new MySpacingPanel((int)leftToolbar.getComponent().getPreferredSize().getHeight());
final JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.add(new JLabel(MarkdownBundle.message("markdown.toolbar.view.label"), SwingConstants.RIGHT), BorderLayout.EAST);
add(mySpacingPanel);
add(leftToolbar.getComponent());
add(centerPanel,
new GridBagConstraints(2, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, JBUI.emptyInsets(), 0, 0));
add(myRightToolbar.getComponent());
setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIUtil.CONTRAST_BORDER_COLOR));
addComponentListener(myAdjustToGutterListener);
}
public void addGutterToTrack(@NotNull EditorGutterComponentEx gutterComponentEx) {
myGutters.add(gutterComponentEx);
gutterComponentEx.addComponentListener(myAdjustToGutterListener);
}
public void refresh() {
adjustSpacing();
myRightToolbar.updateActionsImmediately();
}
private void adjustSpacing() {
EditorGutterComponentEx leftMostGutter = null;
for (EditorGutterComponentEx gutter : myGutters) {
if (!gutter.isShowing()) {
continue;
}
if (leftMostGutter == null || leftMostGutter.getX() > gutter.getX()) {
leftMostGutter = gutter;
}
}
final int spacing;
if (leftMostGutter == null) {
spacing = 0;
}
else {
spacing = leftMostGutter.getWhitespaceSeparatorOffset();
}
mySpacingPanel.setSpacing(spacing);
revalidate();
repaint();
}
@Override
public void dispose() {
removeComponentListener(myAdjustToGutterListener);
for (EditorGutterComponentEx gutter : myGutters) {
gutter.removeComponentListener(myAdjustToGutterListener);
}
}
@NotNull
private static ActionToolbar createToolbarFromGroupId(@NotNull String groupId) {
final ActionManager actionManager = ActionManager.getInstance();
if (!actionManager.isGroup(groupId)) {
throw new IllegalStateException(groupId + " should have been a group");
}
final ActionGroup group = ((ActionGroup)actionManager.getAction(groupId));
final ActionToolbarImpl editorToolbar =
((ActionToolbarImpl)actionManager.createActionToolbar(ActionPlaces.EDITOR_TOOLBAR, group, true));
editorToolbar.setOpaque(false);
editorToolbar.setBorder(new JBEmptyBorder(0, 2, 0, 2));
return editorToolbar;
}
private static class MySpacingPanel extends JPanel {
private final int myHeight;
private int mySpacing;
public MySpacingPanel(int height) {
myHeight = height;
mySpacing = 0;
setOpaque(false);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(mySpacing, myHeight);
}
public void setSpacing(int spacing) {
mySpacing = spacing;
}
}
}