diff --git a/src/main/scala/ocelot/desktop/Keymap.scala b/src/main/scala/ocelot/desktop/Keymap.scala deleted file mode 100644 index 4ddf537..0000000 --- a/src/main/scala/ocelot/desktop/Keymap.scala +++ /dev/null @@ -1,8 +0,0 @@ -package ocelot.desktop - -import org.lwjgl.input.Keyboard - -/** The default Ocelot keymap (unless overridden by the setting). */ -object Keymap { - val Insert: Int = Keyboard.KEY_INSERT -} diff --git a/src/main/scala/ocelot/desktop/Settings.scala b/src/main/scala/ocelot/desktop/Settings.scala index e0bcf29..2a081db 100644 --- a/src/main/scala/ocelot/desktop/Settings.scala +++ b/src/main/scala/ocelot/desktop/Settings.scala @@ -42,7 +42,7 @@ class Settings(val config: Config) extends SettingsData { windowSize.y -= 16 } - keymapInsert = config.getIntOrElse("ocelot.keymap.insert", Keymap.Insert) + keymap.load(config.getConfig("ocelot.keymap")) recentWorkspace = config.getOptionalString("ocelot.workspace.recent") pinNewWindows = config.getBooleanOrElse("ocelot.workspace.pinNewWindows", default = true) @@ -168,7 +168,7 @@ object Settings extends Logging { .withValuePreserveOrigin("ocelot.window.fullscreen", settings.windowFullscreen) .withValuePreserveOrigin("ocelot.window.disableVsync", settings.disableVsync) .withValuePreserveOrigin("ocelot.window.debugLwjgl", settings.debugLwjgl) - .withValue("ocelot.keymap.insert", settings.keymapInsert) + .withValue("ocelot.keymap", settings.keymap.save()) .withValue("ocelot.workspace.recent", settings.recentWorkspace) .withValuePreserveOrigin("ocelot.workspace.pinNewWindows", settings.pinNewWindows) .withValuePreserveOrigin("ocelot.workspace.unfocusedWindowTransparency", settings.unfocusedWindowTransparency) diff --git a/src/main/scala/ocelot/desktop/util/Keybind.scala b/src/main/scala/ocelot/desktop/util/Keybind.scala new file mode 100644 index 0000000..39e5248 --- /dev/null +++ b/src/main/scala/ocelot/desktop/util/Keybind.scala @@ -0,0 +1,11 @@ +package ocelot.desktop.util + +/** + * Collection of keybind handles. + * Each represents some action you may want to execute in Ocelot by pressing a key (or key combination). + */ + +object Keybind extends Enumeration { + type Keybind = Value + val Insert: Keybind = Value +} diff --git a/src/main/scala/ocelot/desktop/util/Keymap.scala b/src/main/scala/ocelot/desktop/util/Keymap.scala new file mode 100644 index 0000000..8f08556 --- /dev/null +++ b/src/main/scala/ocelot/desktop/util/Keymap.scala @@ -0,0 +1,57 @@ +package ocelot.desktop.util + +import com.typesafe.config.{Config, ConfigValue, ConfigValueFactory} +import ocelot.desktop.util.Keybind.Keybind +import org.lwjgl.input.Keyboard + +import scala.collection.mutable +import scala.jdk.CollectionConverters._ + +class Keymap { + // default mappings + val map: mutable.Map[Keybind, Int] = mutable.Map( + Keybind.Insert -> Keyboard.KEY_INSERT + ) + + /** Retrieves the LWJGL keycode which is associated with the given keybind. + * Will return `Keyboard.KEY_NONE` if the binding is not found. + * + * @param keybind the keybind + * @return the actual LWJGL key associated with the given keybind, + * or `Keyboard.KEY_NONE` if none is. + */ + def apply(keybind: Keybind): Int = map.getOrElse(keybind, Keyboard.KEY_NONE) + + /** Adds a new keybind mapping and optionally returns previous value. + * If the map already contains a + * mapping for the keybind, it will be overridden by the new value. + * + * @param keybind the keybind to update + * @param key the new LWJGL key code + * @return an option value containing the LWJGL key code associated with the keybind + * before the `set` operation was executed, or `None` if this keybind + * was not defined in the keymap before. + */ + def set(keybind: Keybind, key: Int): Option[Int] = map.put(keybind, key) + + /** + * Attempts to read known keybindings from a config. + * Will ignore missing or unfamiliar values, retaining default values. + */ + def load(config: Config): Unit = { + Keybind.values.foreach(keybind => { + val path = keybind.toString.toLowerCase + if (config.hasPath(path)) { + set(keybind, config.getInt(path)) + } + }) + } + + /** + * Generates a ConfigValue with this keybindings map, + * (which can be embedded into any Config). + */ + def save(): ConfigValue = ConfigValueFactory.fromMap((map.view map { + case (key: Keybind, value: Int) => (key.toString.toLowerCase(), value) + }).toMap.asJava) +} diff --git a/src/main/scala/ocelot/desktop/util/SettingsData.scala b/src/main/scala/ocelot/desktop/util/SettingsData.scala index 1f37ab2..b2a1027 100644 --- a/src/main/scala/ocelot/desktop/util/SettingsData.scala +++ b/src/main/scala/ocelot/desktop/util/SettingsData.scala @@ -1,6 +1,5 @@ package ocelot.desktop.util -import ocelot.desktop.Keymap import ocelot.desktop.Settings.Int2D import ocelot.desktop.util.SettingsData.Fields @@ -34,7 +33,7 @@ class SettingsData { var disableVsync: Boolean = false var debugLwjgl: Boolean = false - var keymapInsert: Int = Keymap.Insert + var keymap: Keymap = new Keymap var recentWorkspace: Option[String] = None diff --git a/src/main/scala/ocelot/desktop/windows/ScreenWindow.scala b/src/main/scala/ocelot/desktop/windows/ScreenWindow.scala index e444af3..6c25db3 100644 --- a/src/main/scala/ocelot/desktop/windows/ScreenWindow.scala +++ b/src/main/scala/ocelot/desktop/windows/ScreenWindow.scala @@ -11,7 +11,7 @@ import ocelot.desktop.ui.UiHandler import ocelot.desktop.ui.event.sources.{KeyEvents, MouseEvents} import ocelot.desktop.ui.event.{DragEvent, KeyEvent, MouseEvent, ScrollEvent} import ocelot.desktop.ui.widget.window.BasicWindow -import ocelot.desktop.util.{DrawUtils, Logging} +import ocelot.desktop.util.{DrawUtils, Keybind, Logging} import ocelot.desktop.windows.ScreenWindow._ import ocelot.desktop.{ColorScheme, OcelotDesktop, Settings} import org.apache.commons.lang3.StringUtils @@ -58,7 +58,7 @@ class ScreenWindow(screenNode: ScreenNode) extends BasicWindow with Logging { screen.keyDown(event.char, event.code, OcelotDesktop.player) // note: in OpenComputers, key_down signal is fired __before__ clipboard signal - if (event.code == Settings.get.keymapInsert) + if (event.code == Settings.get.keymap(Keybind.Insert)) screen.clipboard(UiHandler.clipboard, OcelotDesktop.player) case KeyEvent.State.Release =>