Skip to content

Commit

Permalink
advanced state management
Browse files Browse the repository at this point in the history
  • Loading branch information
Windmill-City committed Jan 16, 2024
1 parent 65f3707 commit 20cdab1
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 48 deletions.
47 changes: 39 additions & 8 deletions 1.7.10/src/main/java/city/windmill/ingameime/ClientProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;

import javax.annotation.Nonnull;

import static city.windmill.ingameime.IngameIME_Forge.LOG;
import static org.lwjgl.input.Keyboard.KEY_HOME;

public class ClientProxy extends CommonProxy {
public class ClientProxy extends CommonProxy implements IMEventHandler {
public static ClientProxy INSTANCE = null;
public static OverlayScreen Screen = new OverlayScreen();
public static KeyBinding KeyBind = new KeyBinding("ingameime.key.desc", KEY_HOME, "IngameIME");
public static boolean IsToggledManually = false;
public static city.windmill.ingameime.IMEventHandler IMEventHandler = IMStates.Disabled;
private static boolean IsKeyDown = false;

@SubscribeEvent
Expand All @@ -27,23 +30,51 @@ public void onRenderScreen(GuiScreenEvent.DrawScreenEvent.Post event) {
IsKeyDown = true;
} else if (IsKeyDown) {
IsKeyDown = false;
ClientProxy.IsToggledManually = true;
Internal.toggleInputMethod();
LOG.info("Toggled by keybinding");
onToggleKey();
}

if (Config.TurnOffOnMouseMove.getBoolean())
if (ClientProxy.IsToggledManually && (Mouse.getDX() > 0 || Mouse.getDY() > 0)) {
Internal.setActivated(false);
LOG.info("Turned off by mouse move");
if (IMEventHandler == IMStates.OpenedManual && (Mouse.getDX() > 0 || Mouse.getDY() > 0)) {
onMouseMove();
}
}

public void preInit(FMLPreInitializationEvent event) {
INSTANCE = this;
Config.synchronizeConfiguration(event.getSuggestedConfigurationFile());
ClientRegistry.registerKeyBinding(KeyBind);
Internal.loadLibrary();
Internal.createInputCtx();
MinecraftForge.EVENT_BUS.register(this);
}

@Override
public IMStates onScreenClose() {
IMEventHandler = IMEventHandler.onScreenClose();
return null;
}

@Override
public IMStates onControlFocus(@Nonnull Object control, boolean focused) {
IMEventHandler = IMEventHandler.onControlFocus(control, focused);
return null;
}

@Override
public IMStates onScreenOpen(Object screen) {
IMEventHandler = IMEventHandler.onScreenOpen(screen);
return null;
}

@Override
public IMStates onToggleKey() {
IMEventHandler = IMEventHandler.onToggleKey();
return null;
}

@Override
public IMStates onMouseMove() {
IMEventHandler = IMEventHandler.onMouseMove();
return null;
}
}
16 changes: 16 additions & 0 deletions 1.7.10/src/main/java/city/windmill/ingameime/IMEventHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package city.windmill.ingameime;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public interface IMEventHandler {
IMStates onScreenClose();

IMStates onControlFocus(@Nonnull Object control, boolean focused);

IMStates onScreenOpen(@Nullable Object screen);

IMStates onToggleKey();

IMStates onMouseMove();
}
98 changes: 98 additions & 0 deletions 1.7.10/src/main/java/city/windmill/ingameime/IMStates.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package city.windmill.ingameime;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public enum IMStates implements IMEventHandler {
Disabled {
@Override
public IMStates onControlFocus(@Nonnull Object control, boolean focused) {
if (focused) {
ActiveControl = control;
IngameIME_Forge.LOG.info("Opened by control focus: {}", ActiveControl.getClass());
Internal.setActivated(true);
return OpenedAuto;
} else {
return this;
}
}

@Override
public IMStates onToggleKey() {
IngameIME_Forge.LOG.info("Turned on by toggle key");
Internal.setActivated(true);
return OpenedManual;
}

},
OpenedManual {
@Override
public IMStates onControlFocus(@Nonnull Object control, boolean focused) {
// Ignore all focus event
return this;
}

@Override
public IMStates onMouseMove() {
if (!Config.TurnOffOnMouseMove.getBoolean()) return this;
IngameIME_Forge.LOG.info("Turned off by mouse move");
Internal.setActivated(false);
return Disabled;
}
},
OpenedAuto {
@Override
public IMStates onControlFocus(@Nonnull Object control, boolean focused) {
// Ignore not active focus one
if (!focused && control != ActiveControl) return this;

if (!focused) {
IngameIME_Forge.LOG.info("Turned off by losing control focus: {}", ActiveControl.getClass());
Internal.setActivated(false);
return Disabled;
}

// Update active focused control
if (ActiveControl != control) {
ActiveControl = control;
IngameIME_Forge.LOG.info("Opened by control focus: {}", ActiveControl.getClass());
Internal.setActivated(true);
ClientProxy.Screen.WInputMode.setActive(true);
}
return this;
}
};

@Nullable
public static Object ActiveScreen = null;
@Nullable
public static Object ActiveControl = null;

@Override
public IMStates onScreenClose() {
if (ActiveScreen != null) IngameIME_Forge.LOG.info("Screen closed: {}", ActiveScreen.getClass());
Internal.setActivated(false);
ActiveScreen = null;
return Disabled;
}

@Override
public IMStates onScreenOpen(Object screen) {
if (ActiveScreen == screen) return this;
ActiveScreen = screen;
if (ActiveScreen != null) IngameIME_Forge.LOG.info("Screen Opened: {}", ActiveScreen.getClass());
return this;
}

@Override
public IMStates onMouseMove() {
return this;
}

@Override
public IMStates onToggleKey() {
IngameIME_Forge.LOG.info("Turned off by toggle key");
Internal.setActivated(false);
return Disabled;
}
}
58 changes: 21 additions & 37 deletions 1.7.10/src/main/java/city/windmill/ingameime/Internal.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,18 @@ public class Internal {
static InputModeCallback inputModeCallback = null;

private static void tryLoadLibrary(String libName) {
if (!LIBRARY_LOADED)
try {
InputStream lib = IngameIME.class.getClassLoader().getResourceAsStream(libName);
if (lib == null) throw new RuntimeException("Required library resource not exist!");
Path path = Files.createTempFile("IngameIME-Native", null);
Files.copy(lib, path, StandardCopyOption.REPLACE_EXISTING);
System.load(path.toString());
LIBRARY_LOADED = true;
LOG.info("Library [{}] has loaded!", libName);
} catch (Throwable e) {
LOG.warn("Try to load library [{}] but failed: {}", libName, e.getClass().getSimpleName());
}
else
LOG.info("Library has loaded, skip loading of [{}]", libName);
if (!LIBRARY_LOADED) try {
InputStream lib = IngameIME.class.getClassLoader().getResourceAsStream(libName);
if (lib == null) throw new RuntimeException("Required library resource not exist!");
Path path = Files.createTempFile("IngameIME-Native", null);
Files.copy(lib, path, StandardCopyOption.REPLACE_EXISTING);
System.load(path.toString());
LIBRARY_LOADED = true;
LOG.info("Library [{}] has loaded!", libName);
} catch (Throwable e) {
LOG.warn("Try to load library [{}] but failed: {}", libName, e.getClass().getSimpleName());
}
else LOG.info("Library has loaded, skip loading of [{}]", libName);
}

private static long getWindowHandle_LWJGL3() {
Expand Down Expand Up @@ -89,13 +87,10 @@ public static void createInputCtx() {

LOG.info("Using IngameIME-Native: {}", InputContext.getVersion());

long hWnd = Loader.isModLoaded("lwjgl3ify") ?
getWindowHandle_LWJGL3() :
getWindowHandle_LWJGL2();
long hWnd = Loader.isModLoaded("lwjgl3ify") ? getWindowHandle_LWJGL3() : getWindowHandle_LWJGL2();
if (hWnd != 0) {
// Once switched to the full screen, we can't back to not UiLess mode, unless restart the game
if (Minecraft.getMinecraft().isFullScreen())
Config.UiLess_Windows.set(true);
if (Minecraft.getMinecraft().isFullScreen()) Config.UiLess_Windows.set(true);
API api = Config.API_Windows.getString().equals("TextServiceFramework") ? API.TextServiceFramework : API.Imm32;
LOG.info("Using API: {}, UiLess: {}", api, Config.UiLess_Windows.getBoolean());
InputCtx = IngameIME.CreateInputContextWin32(hWnd, api, Config.UiLess_Windows.getBoolean());
Expand All @@ -112,13 +107,10 @@ protected void call(CompositionState arg0, PreEditContext arg1) {
LOG.info("PreEdit State: {}", arg0);

//Hide Indicator when PreEdit start
if (arg0 == CompositionState.Begin)
ClientProxy.Screen.WInputMode.setActive(false);
if (arg0 == CompositionState.Begin) ClientProxy.Screen.WInputMode.setActive(false);

if (arg1 != null)
ClientProxy.Screen.PreEdit.setContent(arg1.getContent(), arg1.getSelStart());
else
ClientProxy.Screen.PreEdit.setContent(null, -1);
if (arg1 != null) ClientProxy.Screen.PreEdit.setContent(arg1.getContent(), arg1.getSelStart());
else ClientProxy.Screen.PreEdit.setContent(null, -1);
} catch (Throwable e) {
LOG.error("Exception thrown during callback handling", e);
}
Expand Down Expand Up @@ -156,8 +148,7 @@ protected void call(CandidateListState arg0, CandidateListContext arg1) {
try {
if (arg1 != null)
ClientProxy.Screen.CandidateList.setContent(new ArrayList<>(arg1.getCandidates()), arg1.getSelection());
else
ClientProxy.Screen.CandidateList.setContent(null, -1);
else ClientProxy.Screen.CandidateList.setContent(null, -1);
} catch (Throwable e) {
LOG.error("Exception thrown during callback handling", e);
}
Expand Down Expand Up @@ -203,21 +194,14 @@ static void loadLibrary() {
}

public static boolean getActivated() {
if (InputCtx != null) {
return InputCtx.getActivated();
}
return false;
if (InputCtx != null) return InputCtx.getActivated();
else return false;
}

public static void setActivated(boolean activated) {
if (InputCtx != null && getActivated() != activated) {
InputCtx.setActivated(activated);
if (!activated) ClientProxy.IsToggledManually = false;
LOG.info("InputMethod activated: {}", activated);
LOG.info("IM active state: {}", activated);
}
}

public static void toggleInputMethod() {
setActivated(!getActivated());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ void onDrawCaret(CallbackInfo ci, int var1, int var2, int var3, String var4, int

@Inject(method = "setFocused", at = @At(value = "HEAD"))
void onSetFocus(boolean focused, CallbackInfo ci) {
Internal.setActivated(focused);
ClientProxy.INSTANCE.onControlFocus(this, focused);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ void postDisplayScreen(GuiScreen guiScreenIn, CallbackInfo ci) {
// Reset pos when screen changes
ClientProxy.Screen.setCaretPos(0, 0);
// Disable input method when not screen
if (Minecraft.getMinecraft().currentScreen == null)
Internal.setActivated(false);
GuiScreen currentScreen = Minecraft.getMinecraft().currentScreen;
if (currentScreen == null)
ClientProxy.INSTANCE.onScreenClose();
else
ClientProxy.INSTANCE.onScreenOpen(currentScreen);
}
}
2 changes: 2 additions & 0 deletions IngameIME-Native/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ plugins {

tasks.compileJava {
options.encoding = "UTF-8"
sourceCompatibility = "1.8"
}

tasks.compileTestJava {
options.encoding = "UTF-8"
sourceCompatibility = "1.8"
}

configurations.all {
Expand Down

0 comments on commit 20cdab1

Please sign in to comment.