mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
action system: transparent actions + debugger actions made transparent
This commit is contained in:
@@ -159,6 +159,10 @@ public abstract class ActionManager implements ApplicationComponent {
|
||||
|
||||
public abstract void removeTimerListener(TimerListener listener);
|
||||
|
||||
public abstract void addTransparrentTimerListener(int delay, TimerListener listener);
|
||||
|
||||
public abstract void removeTransparrentTimerListener(TimerListener listener);
|
||||
|
||||
public abstract ActionCallback tryToExecute(@NotNull AnAction action, @NotNull InputEvent inputEvent, @Nullable Component contextComponent,
|
||||
@Nullable String place, boolean now);
|
||||
|
||||
|
||||
@@ -70,7 +70,9 @@ public abstract class AnAction {
|
||||
private static final ShortcutSet ourEmptyShortcutSet = new CustomShortcutSet(new Shortcut[0]);
|
||||
private boolean myIsDefaultIcon = true;
|
||||
private boolean myWorksInInjected;
|
||||
|
||||
|
||||
|
||||
private boolean myTransparentUpdate = false;
|
||||
/**
|
||||
* Creates a new action with its text, description and icon set to <code>null</code>.
|
||||
*/
|
||||
@@ -288,4 +290,12 @@ public abstract class AnAction {
|
||||
public boolean isInInjectedContext() {
|
||||
return myWorksInInjected;
|
||||
}
|
||||
|
||||
public boolean isTransparentUpdate() {
|
||||
return myTransparentUpdate;
|
||||
}
|
||||
|
||||
public void setTransparentUpdate(boolean transparentUpdate) {
|
||||
myTransparentUpdate = transparentUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,5 +144,6 @@ public abstract class ActionManagerEx extends ActionManager{
|
||||
|
||||
public abstract boolean isActionPopupStackEmpty();
|
||||
|
||||
public abstract boolean isTransparrentOnlyActionsUpdateNow();
|
||||
}
|
||||
|
||||
|
||||
+65
-13
@@ -120,6 +120,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
private final Map<AnAction, AnActionEvent> myQueuedNotificationsEvents = new LinkedHashMap<AnAction, AnActionEvent>();
|
||||
|
||||
private Runnable myPreloadActionsRunnable;
|
||||
private boolean myTransparrentOnlyUpdate;
|
||||
|
||||
ActionManagerImpl(KeymapManager keymapManager, DataManager dataManager) {
|
||||
myId2Action = new THashMap<String, Object>();
|
||||
@@ -145,20 +146,39 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
}
|
||||
|
||||
public void addTimerListener(int delay, final TimerListener listener) {
|
||||
_addTimerListener(delay, listener, false);
|
||||
}
|
||||
|
||||
public void removeTimerListener(TimerListener listener) {
|
||||
_removeTimerListener(listener, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTransparrentTimerListener(int delay, TimerListener listener) {
|
||||
_addTimerListener(delay, listener, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTransparrentTimerListener(TimerListener listener) {
|
||||
_removeTimerListener(listener, true);
|
||||
}
|
||||
|
||||
|
||||
private void _addTimerListener(int delay, final TimerListener listener, boolean transparrent) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) return;
|
||||
if (myTimer == null) {
|
||||
myTimer = new MyTimer();
|
||||
myTimer.start();
|
||||
}
|
||||
|
||||
myTimer.addTimerListener(listener);
|
||||
myTimer.addTimerListener(listener, transparrent);
|
||||
}
|
||||
|
||||
public void removeTimerListener(TimerListener listener) {
|
||||
private void _removeTimerListener(TimerListener listener, boolean transparrent) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) return;
|
||||
LOG.assertTrue(myTimer != null);
|
||||
|
||||
myTimer.removeTimerListener(listener);
|
||||
myTimer.removeTimerListener(listener, transparrent);
|
||||
}
|
||||
|
||||
public ActionPopupMenu createActionPopupMenu(String place, @NotNull ActionGroup group, @Nullable PresentationFactory presentationFactory) {
|
||||
@@ -975,6 +995,11 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
return myPopups.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTransparrentOnlyActionsUpdateNow() {
|
||||
return myTransparrentOnlyUpdate;
|
||||
}
|
||||
|
||||
private void flushActionPerformed() {
|
||||
final Set<AnAction> actions = myQueuedNotifications.keySet();
|
||||
for (final AnAction eachAction : actions) {
|
||||
@@ -1147,6 +1172,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
|
||||
private class MyTimer extends Timer implements ActionListener {
|
||||
private final List<TimerListener> myTimerListeners = Collections.synchronizedList(new ArrayList<TimerListener>());
|
||||
private final List<TimerListener> myTransparrentTimerListeners = Collections.synchronizedList(new ArrayList<TimerListener>());
|
||||
private int myLastTimePerformed;
|
||||
|
||||
MyTimer() {
|
||||
@@ -1155,12 +1181,20 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
setRepeats(true);
|
||||
}
|
||||
|
||||
public void addTimerListener(TimerListener listener){
|
||||
myTimerListeners.add(listener);
|
||||
public void addTimerListener(TimerListener listener, boolean transparent){
|
||||
if (transparent) {
|
||||
myTransparrentTimerListeners.add(listener);
|
||||
} else {
|
||||
myTimerListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeTimerListener(TimerListener listener){
|
||||
myTimerListeners.remove(listener);
|
||||
public void removeTimerListener(TimerListener listener, boolean transparent){
|
||||
if (transparent) {
|
||||
myTransparrentTimerListeners.remove(listener);
|
||||
} else {
|
||||
myTimerListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@@ -1171,16 +1205,34 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
final int lastEventCount = myLastTimePerformed;
|
||||
myLastTimePerformed = ActivityTracker.getInstance().getCount();
|
||||
|
||||
if (myLastTimePerformed == lastEventCount) {
|
||||
return;
|
||||
}
|
||||
boolean transparentOnly = myLastTimePerformed == lastEventCount;
|
||||
|
||||
final TimerListener[] listeners = myTimerListeners.toArray(new TimerListener[myTimerListeners.size()]);
|
||||
try {
|
||||
HashSet<TimerListener> notified = new HashSet<TimerListener>();
|
||||
myTransparrentOnlyUpdate = transparentOnly;
|
||||
notifyListeners(myTransparrentTimerListeners, notified);
|
||||
|
||||
if (transparentOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
notifyListeners(myTimerListeners, notified);
|
||||
}
|
||||
finally {
|
||||
myTransparrentOnlyUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListeners(final List<TimerListener> timerListeners, final Set<TimerListener> notified) {
|
||||
final TimerListener[] listeners = timerListeners.toArray(new TimerListener[timerListeners.size()]);
|
||||
IdeFocusManager.getInstance(null).doWhenFocusSettlesDown(new Runnable() {
|
||||
public void run() {
|
||||
for (TimerListener listener : listeners) {
|
||||
if (myTimerListeners.contains(listener)) {
|
||||
runListenerAction(listener);
|
||||
if (timerListeners.contains(listener)) {
|
||||
if (!notified.contains(listener)) {
|
||||
notified.add(listener);
|
||||
runListenerAction(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+27
-11
@@ -73,7 +73,6 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
|
||||
private final ActionGroup myActionGroup;
|
||||
private final String myPlace;
|
||||
@SuppressWarnings({"FieldCanBeLocal"}) private final MyKeymapManagerListener myKeymapManagerListener;
|
||||
@SuppressWarnings({"FieldCanBeLocal"}) private final MyTimerListener myTimerListener;
|
||||
private ArrayList<AnAction> myNewVisibleActions;
|
||||
protected ArrayList<AnAction> myVisibleActions;
|
||||
private final PresentationFactory myPresentationFactory;
|
||||
@@ -100,6 +99,8 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
|
||||
private JComponent myTargetComponent;
|
||||
|
||||
private boolean myReservePlaceAutoPopupIcon = true;
|
||||
private WeakTimerListener myWeakTimerListener;
|
||||
private ActionToolbarImpl.MyTimerListener myTimerListener;
|
||||
|
||||
public ActionToolbarImpl(final String place,
|
||||
final ActionGroup actionGroup,
|
||||
@@ -127,7 +128,6 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
|
||||
myActionGroup = actionGroup;
|
||||
myPresentationFactory = new PresentationFactory();
|
||||
myKeymapManagerListener = new MyKeymapManagerListener();
|
||||
myTimerListener = new MyTimerListener();
|
||||
myVisibleActions = new ArrayList<AnAction>();
|
||||
myNewVisibleActions = new ArrayList<AnAction>();
|
||||
myDataManager = dataManager;
|
||||
@@ -138,15 +138,30 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
|
||||
mySecondaryActions.getTemplatePresentation().setIcon(mySecondaryGroupIcon);
|
||||
mySecondaryActions.setPopup(true);
|
||||
|
||||
updateActions(updateActionsNow);
|
||||
updateActions(updateActionsNow, false);
|
||||
|
||||
//
|
||||
keymapManager.addKeymapManagerListener(new WeakKeymapManagerListener(keymapManager, myKeymapManagerListener));
|
||||
actionManager.addTimerListener(500, new WeakTimerListener(actionManager, myTimerListener));
|
||||
myTimerListener = new MyTimerListener();
|
||||
myWeakTimerListener = new WeakTimerListener(actionManager, myTimerListener);
|
||||
// If the panel doesn't handle mouse event then it will be passed to its parent.
|
||||
// It means that if the panel is in slidindg mode then the focus goes to the editor
|
||||
// and panel will be automatically hidden.
|
||||
enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
|
||||
enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.COMPONENT_EVENT_MASK | AWTEvent.CONTAINER_EVENT_MASK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
super.addNotify();
|
||||
myActionManager.addTimerListener(500, myWeakTimerListener);
|
||||
myActionManager.addTransparrentTimerListener(500, myWeakTimerListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNotify() {
|
||||
super.removeNotify();
|
||||
myActionManager.removeTimerListener(myWeakTimerListener);
|
||||
myActionManager.removeTransparrentTimerListener(myWeakTimerListener);
|
||||
}
|
||||
|
||||
public JComponent getComponent() {
|
||||
@@ -656,6 +671,7 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
|
||||
}
|
||||
|
||||
private final class MyTimerListener implements TimerListener {
|
||||
|
||||
public ModalityState getModalityState() {
|
||||
return ModalityState.stateForComponent(ActionToolbarImpl.this);
|
||||
}
|
||||
@@ -682,7 +698,7 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
|
||||
}
|
||||
}
|
||||
|
||||
updateActions(false);
|
||||
updateActions(false, myActionManager.isTransparrentOnlyActionsUpdateNow());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -715,16 +731,16 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
|
||||
|
||||
public void updateActionsImmediately() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
updateActions(true);
|
||||
updateActions(true, false);
|
||||
}
|
||||
|
||||
private void updateActions(boolean now) {
|
||||
private void updateActions(boolean now, final boolean transparrentOnly) {
|
||||
final Runnable updateRunnable = new Runnable() {
|
||||
public void run() {
|
||||
myNewVisibleActions.clear();
|
||||
final DataContext dataContext = getDataContext();
|
||||
|
||||
Utils.expandActionGroup(myActionGroup, myNewVisibleActions, myPresentationFactory, dataContext, myPlace, myActionManager);
|
||||
Utils.expandActionGroup(myActionGroup, myNewVisibleActions, myPresentationFactory, dataContext, myPlace, myActionManager, transparrentOnly);
|
||||
|
||||
if (!myNewVisibleActions.equals(myVisibleActions)) {
|
||||
// should rebuild UI
|
||||
@@ -781,7 +797,7 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
|
||||
if (myTargetComponent != null && myTargetComponent.isVisible()) {
|
||||
ApplicationManager.getApplication().invokeLater(new DumbAwareRunnable() {
|
||||
public void run() {
|
||||
updateActions(false);
|
||||
updateActions(false, false);
|
||||
}
|
||||
}, ModalityState.stateForComponent(myTargetComponent));
|
||||
}
|
||||
@@ -927,7 +943,7 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar {
|
||||
Disposer.dispose(myPopup);
|
||||
myPopup = null;
|
||||
|
||||
updateActions(false);
|
||||
updateActions(false, false);
|
||||
}
|
||||
|
||||
abstract static class PopupToolbar extends ActionToolbarImpl implements AnActionListener, Disposable {
|
||||
|
||||
@@ -80,6 +80,17 @@ public class Utils{
|
||||
PresentationFactory presentationFactory,
|
||||
DataContext context,
|
||||
String place, ActionManager actionManager){
|
||||
expandActionGroup(group, list, presentationFactory, context, place, actionManager, false);
|
||||
}
|
||||
/**
|
||||
* @param actionManager manager
|
||||
* @param list this list contains expanded actions.
|
||||
*/
|
||||
public static void expandActionGroup(@NotNull ActionGroup group,
|
||||
ArrayList<AnAction> list,
|
||||
PresentationFactory presentationFactory,
|
||||
DataContext context,
|
||||
String place, ActionManager actionManager, boolean transparrentOnly){
|
||||
Presentation presentation = presentationFactory.getPresentation(group);
|
||||
AnActionEvent e = new AnActionEvent(
|
||||
null,
|
||||
@@ -106,7 +117,11 @@ public class Utils{
|
||||
presentation = presentationFactory.getPresentation(child);
|
||||
AnActionEvent e1 = new AnActionEvent(null, context, place, presentation, actionManager, 0);
|
||||
e1.setInjectedContext(child.isInInjectedContext());
|
||||
if (!doUpdate(child, e1, presentation)) continue;
|
||||
|
||||
if ((transparrentOnly && child.isTransparentUpdate()) || !transparrentOnly) {
|
||||
if (!doUpdate(child, e1, presentation)) continue;
|
||||
}
|
||||
|
||||
if (!presentation.isVisible()) { // don't create invisible items in the menu
|
||||
continue;
|
||||
}
|
||||
|
||||
+1
@@ -29,6 +29,7 @@ public abstract class XDebuggerActionBase extends AnAction {
|
||||
|
||||
protected XDebuggerActionBase() {
|
||||
this(false);
|
||||
setTransparentUpdate(true);
|
||||
}
|
||||
|
||||
protected XDebuggerActionBase(final boolean hideDisabledInPopup) {
|
||||
|
||||
Reference in New Issue
Block a user