IDEA-163208: simplify BarContainer and create bars with linked components

need store swing components to obtain correct DataContext (the same as corresponding tool-panel)
This commit is contained in:
Artem Bochkarev
2018-04-26 15:00:13 +07:00
parent b562b727c8
commit 360c48ea27
12 changed files with 89 additions and 95 deletions
@@ -7,13 +7,13 @@ import java.util.HashMap;
import java.util.Map;
public class MultiBarContainer implements BarContainer {
private final @NotNull BarContainer myMain;
private final Map<Long, BarContainer> myKeyMask2Alt = new HashMap<>();
private BarContainer myCurrent;
private final @NotNull TouchBar myMain;
private final Map<Long, TouchBar> myKeyMask2Alt = new HashMap<>();
private TouchBar myCurrent;
MultiBarContainer(@NotNull BarContainer main) { myMain = main; }
MultiBarContainer(@NotNull TouchBar main) { myMain = main; }
void registerAltByKeyMask(long keyMask, @NotNull BarContainer altBar) { myKeyMask2Alt.put(keyMask, altBar); }
void registerAltByKeyMask(long keyMask, @NotNull TouchBar altBar) { myKeyMask2Alt.put(keyMask, altBar); }
void selectBarByKeyMask(long keyMask) {
if (keyMask == 0) {
@@ -21,8 +21,7 @@ public class MultiBarContainer implements BarContainer {
return;
}
// TODO: support composite masks
final BarContainer alt = myKeyMask2Alt.get(keyMask);
final TouchBar alt = myKeyMask2Alt.get(keyMask);
if (alt != null)
myCurrent = alt;
}
@@ -31,7 +30,7 @@ public class MultiBarContainer implements BarContainer {
public TouchBar get() {
if (myCurrent == null)
myCurrent = myMain;
return myCurrent.get();
return myCurrent;
}
@Override
@@ -5,7 +5,10 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.awt.event.InputEvent;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@@ -17,43 +20,40 @@ public class ProjectBarsStorage {
private static final Map<Project, ProjectBarsStorage> ourInstances = new HashMap<>();
private final @NotNull Project myProject;
private final Map<String, BarContainer> myBars = new HashMap<>();
private final List<BarContainer> myBars = new ArrayList<>();
ProjectBarsStorage(@NotNull Project project) { myProject = project; }
BarContainer getBarContainer(@NotNull String type) {
ApplicationManager.getApplication().assertIsDispatchThread();
BarContainer createBarContainer(@NotNull String type, Component component) {
ApplicationManager.getApplication().assertIsDispatchThread ();
BarContainer result = myBars.get(type);
if (result == null) {
if (type.equals(GENERAL)) {
result = new SingleBarContainer(() -> new TouchBarGeneral(myProject));
} else if (type.equals(DEBUGGER)) {
final BarContainer mainDebug = new SingleBarContainer(()->new TouchBarDebugger(myProject));
final BarContainer altDebug = new SingleBarContainer(()->new TouchBarDebuggerAlt(myProject));
MultiBarContainer container = new MultiBarContainer(mainDebug);
final long mask = InputEvent.ALT_DOWN_MASK;
container.registerAltByKeyMask(mask, altDebug);
result = container;
} else if (type.equals(EDITOR)) {
final BarContainer mainEditor = getBarContainer(GENERAL);
MultiBarContainer container = new MultiBarContainer(mainEditor);
container.registerAltByKeyMask(InputEvent.ALT_DOWN_MASK, new SingleBarContainer(()->new TouchBarEditorAlt(myProject)));
container.registerAltByKeyMask(InputEvent.META_DOWN_MASK, new SingleBarContainer(()->new TouchBarEditorCmd(myProject)));
container.registerAltByKeyMask(InputEvent.ALT_DOWN_MASK | InputEvent.META_DOWN_MASK, new SingleBarContainer(()->new TouchBarEditorCmdAlt(myProject)));
container.registerAltByKeyMask(InputEvent.SHIFT_DOWN_MASK, new SingleBarContainer(()->new TouchBarEditorShift(myProject)));
result = container;
} else
throw new RuntimeException("unknown context of project-touchbar: " + type);
BarContainer result;
if (type.equals(GENERAL)) {
result = new SingleBarContainer(new TouchBarGeneral(myProject, component, "GLOBAL"));
} else if (type.equals(DEBUGGER)) {
MultiBarContainer container = new MultiBarContainer(new TouchBarDebugger(myProject, component));
final long mask = InputEvent.ALT_DOWN_MASK;
container.registerAltByKeyMask(mask, new TouchBarDebuggerAlt(myProject, component));
result = container;
} else if (type.equals(EDITOR)) {
MultiBarContainer container = new MultiBarContainer(new TouchBarGeneral(myProject, component, "EDITOR"));
container.registerAltByKeyMask(InputEvent.ALT_DOWN_MASK, new TouchBarEditorAlt(myProject, component));
container.registerAltByKeyMask(InputEvent.META_DOWN_MASK, new TouchBarEditorCmd(myProject, component));
container.registerAltByKeyMask(InputEvent.ALT_DOWN_MASK | InputEvent.META_DOWN_MASK, new TouchBarEditorCmdAlt(myProject, component));
container.registerAltByKeyMask(InputEvent.SHIFT_DOWN_MASK, new TouchBarEditorShift(myProject, component));
result = container;
} else
throw new RuntimeException("unknown context of project-touchbar: " + type);
myBars.add(result);
myBars.put(type, result);
}
return result;
}
void releaseAll() {
ApplicationManager.getApplication().assertIsDispatchThread();
myBars.forEach((str, bc)->bc.release());
myBars.forEach((bc)->bc.release());
myBars.clear();
}
@@ -1,31 +1,13 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ui.mac.touchbar;
interface BarCreator {
TouchBar create();
}
public class SingleBarContainer implements BarContainer {
private final BarCreator myCreator;
private TouchBar myTouchBar = null;
private final TouchBar myTouchBar;
public SingleBarContainer(BarCreator creator) { myCreator = creator; }
public SingleBarContainer(TouchBar touchBar) { myTouchBar = touchBar; }
@Override
public TouchBar get() {
if (myTouchBar == null) {
try (NSAutoreleaseLock lock = new NSAutoreleaseLock()) {
myTouchBar = myCreator.create();
}
}
return myTouchBar;
}
public TouchBar get() { return myTouchBar; }
@Override
public void release() {
if (myTouchBar != null) {
myTouchBar.release();
myTouchBar = null;
}
}
public void release() { myTouchBar.release(); }
}
@@ -26,10 +26,12 @@ public class TouchBarActionBase extends TouchBarProjectBase implements Execution
private final PresentationFactory myPresentationFactory = new PresentationFactory();
private final TimerListener myTimerListener;
private final Component myComponent;
public TouchBarActionBase(@NotNull String touchbarName, @NotNull Project project) {
public TouchBarActionBase(@NotNull String touchbarName, @NotNull Project project, Component component) {
super(touchbarName, project);
myComponent = component;
myTimerListener = new TimerListener() {
@Override
public ModalityState getModalityState() { return ModalityState.current(); }
@@ -55,7 +57,7 @@ public class TouchBarActionBase extends TouchBarProjectBase implements Execution
}
TBItemAnActionButton addAnActionButton(String actId) {
return addAnActionButton(ActionManager.getInstance().getAction(actId), true, TBItemAnActionButton.SHOWMODE_IMAGE_ONLY, null, null);
return addAnActionButton(ActionManager.getInstance().getAction(actId), true, TBItemAnActionButton.SHOWMODE_IMAGE_ONLY, myComponent, null);
}
TBItemAnActionButton addAnActionButton(String actId, boolean hiddenWhenDisabled) {
@@ -64,11 +66,11 @@ public class TouchBarActionBase extends TouchBarProjectBase implements Execution
LOG.error("can't find action by id: " + actId);
return null;
}
return addAnActionButton(act, hiddenWhenDisabled, TBItemAnActionButton.SHOWMODE_IMAGE_ONLY, null, null);
return addAnActionButton(act, hiddenWhenDisabled, TBItemAnActionButton.SHOWMODE_IMAGE_ONLY, myComponent, null);
}
TBItemAnActionButton addAnActionButton(AnAction act, boolean hiddenWhenDisabled, int showMode) {
return addAnActionButton(act, hiddenWhenDisabled, showMode, null, null);
return addAnActionButton(act, hiddenWhenDisabled, showMode, myComponent, null);
}
TBItemAnActionButton addAnActionButton(AnAction act, boolean hiddenWhenDisabled, int showMode, Component component, ModalityState modality) {
@@ -77,7 +79,7 @@ public class TouchBarActionBase extends TouchBarProjectBase implements Execution
return null;
}
final String uid = String.format("%s.anActionButton.%d", myName, myCounter++);
final String uid = String.format("%s.anActionButton.%d.%s", myName, myCounter++, ActionManager.getInstance().getId(act));
final TBItemAnActionButton butt = new TBItemAnActionButton(uid, act, hiddenWhenDisabled, showMode, component, modality);
myItems.add(butt);
return butt;
@@ -6,9 +6,11 @@ import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
public class TouchBarDebugger extends TouchBarActionBase {
TouchBarDebugger(@NotNull Project project) {
super("debugger", project);
TouchBarDebugger(@NotNull Project project, Component component) {
super("debugger", project, component);
addButton(AllIcons.Actions.Restart, null, new PlatformAction(IdeActions.ACTION_RERUN));
addAnActionButton("Pause");
@@ -4,9 +4,11 @@ package com.intellij.ui.mac.touchbar;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
public class TouchBarDebuggerAlt extends TouchBarActionBase {
public TouchBarDebuggerAlt(@NotNull Project project) {
super("debugger_alt", project);
public TouchBarDebuggerAlt(@NotNull Project project, Component component) {
super("debugger_alt", project, component);
addAnActionButton("ViewBreakpoints", false);
addFlexibleSpacing();
@@ -5,9 +5,11 @@ import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
public class TouchBarEditorAlt extends TouchBarActionBase {
TouchBarEditorAlt(@NotNull Project project) {
super("editor_alt", project);
TouchBarEditorAlt(@NotNull Project project, Component component) {
super("editor_alt", project, component);
addFlexibleSpacing();
addAnActionButton(ActionManager.getInstance().getAction("Terminal.OpenInTerminal"), false, TBItemAnActionButton.SHOWMODE_IMAGE_TEXT);
@@ -5,9 +5,11 @@ import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
public class TouchBarEditorCmd extends TouchBarActionBase {
TouchBarEditorCmd(@NotNull Project project) {
super("editor_cmd", project);
TouchBarEditorCmd(@NotNull Project project, Component component) {
super("editor_cmd", project, component);
// Use Cmd modifier key to show Navigation buttons, Bookmark and Breakpoint toggles and to Show Usages
// Cmd key is used, because it’s used in most of the action shortcuts: Back/Forward, Breakpoint and Find Usages.
@@ -5,9 +5,11 @@ import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
public class TouchBarEditorCmdAlt extends TouchBarActionBase {
TouchBarEditorCmdAlt(@NotNull Project project) {
super("editor_cmd_alt", project);
TouchBarEditorCmdAlt(@NotNull Project project, Component component) {
super("editor_cmd_alt", project, component);
addFlexibleSpacing();
addAnActionButton(ActionManager.getInstance().getAction("SwitchCoverage"), false, TBItemAnActionButton.SHOWMODE_TEXT_ONLY);
@@ -5,9 +5,11 @@ import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
public class TouchBarEditorShift extends TouchBarActionBase {
TouchBarEditorShift(@NotNull Project project) {
super("editor_shift", project);
TouchBarEditorShift(@NotNull Project project, Component component) {
super("editor_shift", project, component);
// Use Shift to show Refactor actions
addAnActionButton(ActionManager.getInstance().getAction("RenameElement"), false, TBItemAnActionButton.SHOWMODE_TEXT_ONLY);
@@ -12,6 +12,7 @@ import com.intellij.util.messages.MessageBus;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
@@ -27,8 +28,8 @@ public class TouchBarGeneral extends TouchBarActionBase {
private TBItemAnActionButton myButtonDebug;
private TBItemAnActionButton myButtonStop;
TouchBarGeneral(@NotNull Project project) {
super("general", project);
TouchBarGeneral(@NotNull Project project, Component component, String desc) {
super("general_"+desc, project, component);
addAnActionButton("CompileDirty", false); // NOTE: IdeActions.ACTION_COMPILE doesn't work
@@ -82,8 +83,6 @@ public class TouchBarGeneral extends TouchBarActionBase {
});
}
public TouchBar getPopoverRunConfExpandTB() { return myPopoverRunConfExpandTB; }
@Override
public void processStarted(@NotNull String executorId, @NotNull ExecutionEnvironment env, @NotNull ProcessHandler handler) {
super.processStarted(executorId, env, handler);
@@ -50,7 +50,8 @@ public class TouchBarsManager {
return;
editor.addFocusListener(new FocusChangeListener() {
private BarContainer myEditorBar = ProjectBarsStorage.instance(proj).getBarContainer(ProjectBarsStorage.EDITOR);
private BarContainer myEditorBar = ProjectBarsStorage.instance(proj).createBarContainer(ProjectBarsStorage.EDITOR, editor.getContentComponent());
@Override
public void focusGained(Editor editor) {
if (!hasTemporary())
@@ -97,23 +98,28 @@ public class TouchBarsManager {
Foundation.invoke(app, "setAutomaticCustomizeTouchBarMenuItemEnabled:", true);
ApplicationManager.getApplication().getMessageBus().connect().subscribe(ProjectManager.TOPIC, new ProjectManagerListener() {
private BarContainer myGeneralBar;
@Override
public void projectOpened(Project project) {
trace("opened project %s, set general touchbar", project);
showTouchBar(ProjectBarsStorage.instance(project).getBarContainer(ProjectBarsStorage.GENERAL));
myGeneralBar = ProjectBarsStorage.instance(project).createBarContainer(ProjectBarsStorage.GENERAL, null);
showTouchBar(myGeneralBar);
final ToolWindowManagerEx twm = ToolWindowManagerEx.getInstanceEx(project);
twm.addToolWindowManagerListener(new ToolWindowManagerListener() {
private BarContainer myDebuggerBar = ProjectBarsStorage.instance(project).getBarContainer(ProjectBarsStorage.DEBUGGER);
private BarContainer myDebuggerBar;
@Override
public void toolWindowRegistered(@NotNull String id) {}
@Override
public void stateChanged() {
final String activeId = twm.getActiveToolWindowId();
if (activeId != null && activeId.equals("Debug"))
if (activeId != null && activeId.equals("Debug")) {
if (myDebuggerBar == null) {
myDebuggerBar = ProjectBarsStorage.instance(project).createBarContainer(ProjectBarsStorage.DEBUGGER, twm.getToolWindow(activeId).getComponent());
}
showTouchBar(myDebuggerBar);
else
} else
closeTouchBar(myDebuggerBar);
}
});
@@ -121,7 +127,7 @@ public class TouchBarsManager {
@Override
public void projectClosed(Project project) {
trace("closed project %s, hide touchbar", project);
closeTouchBar(ProjectBarsStorage.instance(project).getBarContainer(ProjectBarsStorage.GENERAL));
closeTouchBar(myGeneralBar);
ProjectBarsStorage.instance(project).releaseAll();
}
});
@@ -180,8 +186,8 @@ public class TouchBarsManager {
ourTouchBarChanger.updateTouchBar(bar.get());
}
synchronized public static void closeTouchBar(@NotNull BarContainer tb) {
if (ourTouchBarStack.isEmpty())
synchronized public static void closeTouchBar(BarContainer tb) {
if (tb == null || ourTouchBarStack.isEmpty())
return;
BarContainer top = ourTouchBarStack.peek();
@@ -241,7 +247,7 @@ public class TouchBarsManager {
private static TouchBar _createButtonsBar(List<JButton> jbuttons, Project project) {
try (NSAutoreleaseLock lock = new NSAutoreleaseLock()) {
TouchBarActionBase result = new TouchBarActionBase("dialog_buttons", project);
TouchBarActionBase result = new TouchBarActionBase("dialog_buttons", project, null);
final ModalityState ms = LaterInvocator.getCurrentModalityState();
for (JButton jb : jbuttons) {
if (jb instanceof JBOptionButton) {
@@ -317,14 +323,8 @@ public class TouchBarsManager {
}
}
private static class TempBarContainer implements BarContainer {
private @NotNull TouchBar myTouchBar;
TempBarContainer(@NotNull TouchBar tb) { myTouchBar = tb; }
@Override
public TouchBar get() { return myTouchBar; }
@Override
public void release() { myTouchBar.release(); }
private static class TempBarContainer extends SingleBarContainer {
TempBarContainer(@NotNull TouchBar tb) { super(tb); }
@Override
public boolean isTemporary() { return true; }
}