Package org.spoutcraft.client.controls

Source Code of org.spoutcraft.client.controls.SimpleKeyBindingManager

/*
* This file is part of Spoutcraft.
*
* Copyright (c) 2011 SpoutcraftDev <http://spoutcraft.org/>
* Spoutcraft is licensed under the GNU Lesser General Public License.
*
* Spoutcraft is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Spoutcraft is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.spoutcraft.client.controls;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.introspector.BeanAccess;

import org.lwjgl.input.Keyboard;

import net.minecraft.src.Block;
import net.minecraft.src.GuiChat;
import net.minecraft.src.GuiScreen;

import org.spoutcraft.api.Spoutcraft;
import org.spoutcraft.api.gui.ScreenType;
import org.spoutcraft.api.keyboard.AbstractBinding;
import org.spoutcraft.api.keyboard.KeyBinding;
import org.spoutcraft.api.keyboard.KeyBindingManager;
import org.spoutcraft.api.keyboard.KeyBindingPress;
import org.spoutcraft.client.SpoutClient;
import org.spoutcraft.client.gui.controls.GuiControls;
import org.spoutcraft.client.io.FileUtil;
import org.spoutcraft.client.packet.PacketKeyBinding;

public class SimpleKeyBindingManager implements KeyBindingManager {
  private ArrayList<KeyBinding> bindings;
  private ArrayList<Shortcut> shortcuts = new ArrayList<Shortcut>();
  private HashMap<Integer, ArrayList<AbstractBinding>> bindingsForKey = new HashMap<Integer, ArrayList<AbstractBinding>>();
  public static final int MOUSE_OFFSET = -100;

  public SimpleKeyBindingManager() {
  }

  public void registerControl(KeyBinding binding) {
    KeyBinding result = null;
    for (KeyBinding check:bindings) {
      if (check.getId().equals(binding.getId()) && check.getAddonName().equals(binding.getAddonName())) {
        result = check;
      }
    }
    if (result != null) {
      result.takeChanges(binding);
    } else {
      bindings.add(binding);
    }
    updateBindings();
    save();
  }

  public void registerShortcut(Shortcut shortcut) {
    shortcuts.add(shortcut);
    updateBindings();
    save();
  }

  public void unregisterShortcut(Shortcut shortcut) {
    if (shortcut == null) {
      return;
    }
    shortcuts.remove(shortcut);
    if (bindingsForKey.get(shortcut.getKey()) == null) {
      return;
    }
    bindingsForKey.get(shortcut.getKey()).remove(shortcut);
    save();
  }

  public void unregisterControl(KeyBinding binding) {
    if (binding == null) {
      return;
    }
    bindings.remove(binding);
    if (bindingsForKey.get(binding.getKey()) == null) {
      return;
    }
    bindingsForKey.get(binding.getKey()).remove(binding);
    save();
  }

  public void updateBindings() {
    if (bindings == null) {
      bindings = new ArrayList<KeyBinding>();
    }
    if (shortcuts == null) {
      shortcuts = new ArrayList<Shortcut>();
    }

    bindingsForKey.clear();
    for (KeyBinding binding:bindings) {
      ArrayList<AbstractBinding> bindings = bindingsForKey.get(binding.getKey());
      if (bindings == null) {
        bindings = new ArrayList<AbstractBinding>();
        bindingsForKey.put(binding.getKey(), bindings);
      }
      bindings.add(binding);
    }
    for (Shortcut binding:shortcuts) {
      ArrayList<AbstractBinding> bindings = bindingsForKey.get(binding.getKey());
      if (bindings == null) {
        bindings = new ArrayList<AbstractBinding>();
        bindingsForKey.put(binding.getKey(), bindings);
      }
      bindings.add(binding);
    }
  }

  public void save() {
    Yaml yaml = new Yaml();
    yaml.setBeanAccess(BeanAccess.FIELD); // To ignore transient fields
    try {
      // KeyBindings saving
      FileWriter writer = new FileWriter(getBindingsFile());
      ArrayList<Object> kbsave = new ArrayList<Object>();
      for (KeyBinding binding:bindings) {
        HashMap<String, Object> item = new HashMap<String, Object>();
        item.put("key", binding.getKey());
        item.put("id", binding.getId());
        item.put("description", binding.getDescription());
        item.put("addonName", binding.getAddonName());
        item.put("modifiers", binding.getModifiers());
        kbsave.add(item);
      }
      yaml.dump(kbsave, writer);

      // Shortcuts saving
      writer = new FileWriter(getShortcutsFile());
      ArrayList<Object> shsave = new ArrayList<Object>();
      for (Shortcut sh:shortcuts) {
        HashMap<String, Object> item = new HashMap<String, Object>();
        item.put("title", sh.getTitle());
        item.put("key", sh.getKey());
        item.put("modifiers", sh.getModifiers());
        item.put("commands", sh.getCommands());
        item.put("delay", sh.getDelay());
        shsave.add(item);
      }
      yaml.dump(shsave, writer);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  private File getBindingsFile() throws IOException {
    File file = new File(FileUtil.getConfigDir(), "bindings.yml");
    if (!file.exists()) {
      file.createNewFile();
    }
    return file;
  }

  private File getShortcutsFile() throws IOException {
    File file = new File(FileUtil.getConfigDir(), "shortcuts.yml");
    if (!file.exists()) {
      file.createNewFile();
    }
    return file;
  }

  @SuppressWarnings("unchecked")
  public void load() {
    Yaml yaml = new Yaml();
    try {
      bindings = new ArrayList<KeyBinding>();
      ArrayList<Object> kbsave = yaml.loadAs(new FileReader(getBindingsFile()), ArrayList.class);
      if (kbsave == null) {
        kbsave = new ArrayList<Object>();
      }
      for (Object obj:kbsave) {
        HashMap<String, Object> item = (HashMap<String, Object>) obj;
        int key = (Integer) item.get("key");
        String id, description, addonName;
        id = (String) item.get("id");
        description = (String) item.get("description");
        byte modifiers = 0;
        if (item.containsKey("modifiers")) {
          modifiers = (byte)(int)(Integer) item.get("modifiers");
        }
        if (item.containsKey("addonName")) {
          addonName = (String) item.get("addonName");
        } else if (item.containsKey("plugin")) {
          addonName = (String) item.get("plugin");
        } else {
          continue; // Invalid item
        }
        KeyBinding binding = new KeyBinding(key, addonName, id, description);
        binding.setRawModifiers(modifiers);
        bindings.add(binding);
      }
    } catch (Exception e) {
      e.printStackTrace();
      bindings = new ArrayList<KeyBinding>();
    }
    try {
      shortcuts.clear();
      ArrayList<Object> shsave = yaml.loadAs(new FileReader(getShortcutsFile()), ArrayList.class);
      if (shsave == null) {
        shsave = new ArrayList<Object>();
      }
      for (Object obj:shsave) {
        HashMap<String, Object> item = (HashMap<String, Object>) obj;
        Shortcut sh = new Shortcut();
        sh.setTitle((String)item.get("title"));
        sh.setKey((Integer)item.get("key"));
        sh.setCommands((ArrayList<String>)item.get("commands"));
        if (item.containsKey("modifiers")) {
          sh.setRawModifiers((byte)(int)(Integer)item.get("modifiers"));
        }
        if (item.containsKey("delay")) {
          sh.setDelay((Integer) item.get("delay"));
        }
        shortcuts.add(sh);
      }
    } catch (Exception e) {
      e.printStackTrace();
      shortcuts = new ArrayList<Shortcut>();
    }
    updateBindings();
  }

  public void pressKey(int key, boolean keyPressed, int screen) {
    if (SpoutClient.getHandle().currentScreen instanceof GuiAmbigousInput || SpoutClient.getHandle().currentScreen instanceof GuiControls) {
      return;
    }
    if (bindingsForKey.containsKey(key)) {
      ArrayList<AbstractBinding> bindings = bindingsForKey.get(key);
      ArrayList<AbstractBinding> effective = new ArrayList<AbstractBinding>();
      for (AbstractBinding b:bindings) {
        if (b.matches(key, getPressedModifiers())) {
          effective.add(b);
        }
      }
      if (effective.size() == 0) {
        return;
      } else if (effective.size() == 1) {
        effective.iterator().next().summon(key, !keyPressed, screen);
      } else if (screen == 0 || (getPressedModifiers() != 0 && getPressedModifiers() != AbstractBinding.MOD_SHIFT)) {
        GuiScreen parent = SpoutClient.getHandle().currentScreen;
        SpoutClient.getHandle().displayGuiScreen(new GuiAmbigousInput(effective, parent));
      } else {
        GuiScreen parent = SpoutClient.getHandle().currentScreen;
        if (!(parent instanceof GuiChat)) {
          Spoutcraft.getActivePlayer().showAchievement("Multiple Bindings ...", "are assigned to Key " + Keyboard.getKeyName(key), Block.workbench.blockID);
        }
      }
    }
  }

  public static boolean isModifierKey(int key) {
    if (key == Keyboard.KEY_LSHIFT
        || key == Keyboard.KEY_RSHIFT
        || key == Keyboard.KEY_LMENU
        || key == Keyboard.KEY_RMENU
        || key == Keyboard.KEY_LCONTROL
        || key == Keyboard.KEY_RCONTROL
        || key == Keyboard.KEY_LMETA
        || key == Keyboard.KEY_RMETA) {
      return true;
    }
    return false;
  }

  public List<KeyBinding> getAllBindings() {
    return Collections.unmodifiableList(bindings);
  }

  public List<Shortcut> getAllShortcuts() {
    return Collections.unmodifiableList(shortcuts);
  }

  public static void setModifiersToShortcut(Shortcut sh) {
    if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) {
      sh.setModifier(AbstractBinding.MOD_SHIFT, true);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)) {
      sh.setModifier(AbstractBinding.MOD_CTRL, true);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_LMENU) || Keyboard.isKeyDown(Keyboard.KEY_RMENU)) {
      sh.setModifier(AbstractBinding.MOD_ALT, true);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_LMETA) || Keyboard.isKeyDown(Keyboard.KEY_RMETA)) {
      sh.setModifier(AbstractBinding.MOD_SUPER, true);
    }
  }

  public static byte getPressedModifiers() {
    byte res = 0;
    if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) {
      res|=Shortcut.MOD_SHIFT;
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)) {
      res|=Shortcut.MOD_CTRL;
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_LMENU) || Keyboard.isKeyDown(Keyboard.KEY_RMENU)) {
      res|=Shortcut.MOD_ALT;
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_LMETA) || Keyboard.isKeyDown(Keyboard.KEY_RMETA)) {
      res|=Shortcut.MOD_SUPER;
    }
    return res;
  }

  public void summon(KeyBinding binding, int key, boolean keyReleased, int screen) {
    if (binding.getDelegate() == null &&  binding.getUniqueId() != null) { // Server-side
      SpoutClient.getInstance().getPacketManager().sendSpoutPacket(new PacketKeyBinding(binding, key, !keyReleased, screen));
    } else if (binding.getDelegate() != null) { // Client-side
      KeyBindingPress event = new KeyBindingPress(org.spoutcraft.api.gui.Keyboard.getKey(key), binding, ScreenType.getType(screen));
      if (!keyReleased) {
        binding.getDelegate().onKeyPress(event);
      } else {
        binding.getDelegate().onKeyRelease(event);
      }
    }
  }
}
TOP

Related Classes of org.spoutcraft.client.controls.SimpleKeyBindingManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.