blob: 72b56080d0abea6274cf4e6a29ea58e79c983278 [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.keymap.impl.keyGestures;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.keymap.impl.ActionProcessor;
import com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher;
import com.intellij.openapi.keymap.impl.KeyState;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
public class KeyboardGestureProcessor {
IdeKeyEventDispatcher myDispatcher;
StateContext myContext = new StateContext();
final KeyGestureState myWaitForStart = new KeyGestureState.WaitForStart(this);
final KeyGestureState myModifierPressed = new KeyGestureState.ModifierPressed(this);
final KeyGestureState myWaitForDblClick = new KeyGestureState.WaitForDblClick(this);
final KeyGestureState myWaitForAction = new KeyGestureState.WaitForAction(this);
final KeyGestureState myWaitForActionEnd = new KeyGestureState.WaitForActionEnd(this);
final KeyGestureState myFinish = new KeyGestureState.ProcessFinish(this);
KeyGestureState myState = myWaitForStart;
final Timer myHoldTimer = UIUtil.createNamedTimer("Keyboard hold",1200, new ActionListener() {
public void actionPerformed(final ActionEvent e) {
}
});
final Timer myDblClickTimer = UIUtil.createNamedTimer("Double click",Registry.intValue("actionSystem.keyGestureDblClickTime"), new ActionListener() {
public void actionPerformed(final ActionEvent e) {
myState.processDblClickTimer();
}
});
private final ActionProcessor myActionProcessor = new MyActionProcessor();
public KeyboardGestureProcessor(final IdeKeyEventDispatcher dispatcher) {
myDispatcher = dispatcher;
}
public boolean process() {
boolean wasNotInWaitState = myState != myWaitForStart;
if (Registry.is("ide.debugMode") && wasNotInWaitState) {
System.out.println("-- key gesture context: before process, state=" + myState);
System.out.println(myContext);
}
myContext.keyToProcess = myDispatcher.getContext().getInputEvent();
myContext.isModal = myDispatcher.getContext().isModalContext();
myContext.dataContext = myDispatcher.getContext().getDataContext();
boolean result = myState.process();
if (Registry.is("ide.debugMode") && (wasNotInWaitState || myState != myWaitForStart)) {
System.out.println("-- key gesture context: after process, state=" + myState);
System.out.println(myContext);
}
return result;
}
public boolean processInitState() {
if (!Registry.is("actionSystem.keyGestures.enabled")) return false;
myContext.focusOwner = myDispatcher.getContext().getFocusOwner();
return process();
}
void executeAction() {
myDispatcher.updateCurrentContext(myContext.focusOwner, getCurrentShortcut(), myContext.isModal);
myDispatcher.processAction(myContext.keyToProcess, myActionProcessor);
}
private Shortcut getCurrentShortcut() {
return KeyboardModifierGestureShortcut.newInstance(myContext.modifierType, myContext.actionShortcut);
}
void setState(KeyGestureState state) {
final boolean isGestureProcessingState = myDispatcher.getState() == KeyState.STATE_KEY_GESTURE_PROCESSOR;
if (state == myWaitForStart) {
myContext.actionKey = null;
if (isGestureProcessingState) {
myDispatcher.setState(KeyState.STATE_INIT);
}
} else if (state == myWaitForAction) {
myDispatcher.setState(KeyState.STATE_KEY_GESTURE_PROCESSOR);
}
myState = state;
}
private class MyActionProcessor implements ActionProcessor {
@NotNull
public AnActionEvent createEvent(final InputEvent inputEvent, @NotNull final DataContext context, @NotNull final String place, @NotNull final Presentation presentation,
final ActionManager manager) {
myContext.actionPresentation = presentation;
myContext.actionPlace = place;
return myState.createActionEvent();
}
public void onUpdatePassed(final InputEvent inputEvent, @NotNull final AnAction action, @NotNull final AnActionEvent actionEvent) {
}
public void performAction(final InputEvent e, @NotNull final AnAction action, @NotNull final AnActionEvent actionEvent) {
final boolean isGestureAction = action instanceof KeyboardGestureAction;
actionEvent.accept(new AnActionEventVisitor() {
@Override
public void visitGestureInitEvent(final AnActionEvent anActionEvent) {
if (isGestureAction) {
execute(anActionEvent, action, e);
}
}
@Override
public void visitGesturePerformedEvent(final AnActionEvent anActionEvent) {
execute(anActionEvent, action, e);
}
@Override
public void visitGestureFinishEvent(final AnActionEvent anActionEvent) {
if (isGestureAction) {
execute(anActionEvent, action, e);
}
}
});
}
private void execute(final AnActionEvent anActionEvent, final AnAction action, final InputEvent e) {
action.actionPerformed(anActionEvent);
e.consume();
}
}
}