com.github.ykrasik.jaci.cli.libgdx.input.KeyCombinationProcessor.java Source code

Java tutorial

Introduction

Here is the source code for com.github.ykrasik.jaci.cli.libgdx.input.KeyCombinationProcessor.java

Source

/******************************************************************************
 * Copyright (c) 2016 Yevgeny Krasik.                                         *
 *                                                                            *
 * 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.github.ykrasik.jaci.cli.libgdx.input;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputAdapter;

/**
 * Performs a single action when a key combination (which may also just be a single key) is detected.
 * The action is performed on keyDown().
 *
 * @author Yevgeny Krasik
 */
public abstract class KeyCombinationProcessor extends InputAdapter {
    private int keycode;
    private boolean shift;
    private boolean ctrl;
    private boolean alt;

    private boolean fired;

    /**
     * The action is fired on keyDown(), however a keyTyped() call will also be generated,
     * which we must consume - this key was never intended to be typed.
     */
    private boolean consumeNextKeyTyped;

    /**
     * Create a key combination with the given keycode.
     * Meta keys can be enabled with {@link #shift()}, {@link #ctrl()}, {@link #alt()}.
     *
     * @param keycode Base keycode for this combination.
     * @see Keys
     */
    public KeyCombinationProcessor(int keycode) {
        this.keycode = keycode;
    }

    /**
     * @return Combination keycode.
     */
    public int getKeycode() {
        return keycode;
    }

    /**
     * @param keycode keycode for this key combination.
     */
    public void setKeycode(int keycode) {
        this.keycode = keycode;
    }

    /**
     * @return {@code true} if this key combination includes the {@code shift} key.
     */
    public boolean isShift() {
        return shift;
    }

    /**
     * @param shift Whether this key combination should include the {@code shift} key.
     * @return {@code this}, for chaining.
     */
    public KeyCombinationProcessor setShift(boolean shift) {
        this.shift = shift;
        return this;
    }

    /**
     * Shortcut for {@link #setShift(boolean)} that enables {@code shift} for this key combination.
     *
     * @return {@code this}, for chaining.
     */
    public KeyCombinationProcessor shift() {
        return setShift(true);
    }

    /**
     * @return {@code true} if this key combination includes the {@code ctrl} key.
     */
    public boolean isCtrl() {
        return ctrl;
    }

    /**
     * @param ctrl Whether this key combination should include the {@code ctrl} key.
     * @return {@code this}, for chaining.
     */
    public KeyCombinationProcessor setCtrl(boolean ctrl) {
        this.ctrl = ctrl;
        return this;
    }

    /**
     * Shortcut for {@link #setCtrl(boolean)} that enables {@code ctrl} for this key combination.
     *
     * @return {@code this}, for chaining.
     */
    public KeyCombinationProcessor ctrl() {
        return setCtrl(true);
    }

    /**
     * @return {@code true} if this key combination includes the {@code alt} key.
     */
    public boolean isAlt() {
        return alt;
    }

    /**
     * @param alt Whether this key combination should include the {@code alt} key.
     * @return {@code this}, for chaining.
     */
    public KeyCombinationProcessor setAlt(boolean alt) {
        this.alt = alt;
        return this;
    }

    /**
     * Shortcut for {@link #setAlt(boolean)} that enables {@code alt} for this key combination.
     *
     * @return {@code this}, for chaining.
     */
    public KeyCombinationProcessor alt() {
        return setAlt(true);
    }

    @Override
    public boolean keyDown(int keycode) {
        if (fired || keycode != this.keycode) {
            return false;
        }

        if (!checkMetaKey(shift, Keys.SHIFT_LEFT, Keys.SHIFT_RIGHT)) {
            return false;
        }
        if (!checkMetaKey(ctrl, Keys.CONTROL_LEFT, Keys.CONTROL_RIGHT)) {
            return false;
        }
        if (!checkMetaKey(alt, Keys.ALT_LEFT, Keys.ALT_RIGHT)) {
            return false;
        }

        consumeNextKeyTyped = true;

        fired = true;
        fire();
        return true;
    }

    private boolean checkMetaKey(boolean expected, int leftKeycode, int rightKeycode) {
        return !expected || isKeyPressed(leftKeycode) || isKeyPressed(rightKeycode);
    }

    private boolean isKeyPressed(int keycode) {
        return Gdx.input.isKeyPressed(keycode);
    }

    @Override
    public boolean keyUp(int keycode) {
        if (!fired) {
            return false;
        }

        if (keycode == this.keycode) {
            fired = false;
            return true;
        }
        return false;
    }

    @Override
    public boolean keyTyped(char character) {
        if (consumeNextKeyTyped) {
            // Consume this event to stop it from being propagated.
            consumeNextKeyTyped = false;
            return true;
        }
        return false;
    }

    /**
     * Action to be performed when this key combination is detected.
     */
    protected abstract void fire();
}