Implement a serializable Keymap class

This commit is contained in:
UnicornFreedom 2025-07-29 20:21:37 +02:00
parent 73a63e75aa
commit 98d352a9e6
No known key found for this signature in database
GPG Key ID: B4ED0DB6B940024F
6 changed files with 73 additions and 14 deletions

View File

@ -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
}

View File

@ -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)

View File

@ -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
}

View File

@ -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)
}

View File

@ -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

View File

@ -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 =>