10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bwRavencl/ControllerBuddy/91a12d4ee6541c4cc39ecb8d9ddfd623fc05da39/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
95 |
--------------------------------------------------------------------------------
/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bwRavencl/ControllerBuddy/91a12d4ee6541c4cc39ecb8d9ddfd623fc05da39/icon.ico
--------------------------------------------------------------------------------
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bwRavencl/ControllerBuddy/91a12d4ee6541c4cc39ecb8d9ddfd623fc05da39/icon.png
--------------------------------------------------------------------------------
/screenshot_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bwRavencl/ControllerBuddy/91a12d4ee6541c4cc39ecb8d9ddfd623fc05da39/screenshot_1.png
--------------------------------------------------------------------------------
/screenshot_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bwRavencl/ControllerBuddy/91a12d4ee6541c4cc39ecb8d9ddfd623fc05da39/screenshot_2.png
--------------------------------------------------------------------------------
/screenshot_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bwRavencl/ControllerBuddy/91a12d4ee6541c4cc39ecb8d9ddfd623fc05da39/screenshot_3.png
--------------------------------------------------------------------------------
/screenshot_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bwRavencl/ControllerBuddy/91a12d4ee6541c4cc39ecb8d9ddfd623fc05da39/screenshot_4.png
--------------------------------------------------------------------------------
/screenshot_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bwRavencl/ControllerBuddy/91a12d4ee6541c4cc39ecb8d9ddfd623fc05da39/screenshot_5.png
--------------------------------------------------------------------------------
/screenshot_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bwRavencl/ControllerBuddy/91a12d4ee6541c4cc39ecb8d9ddfd623fc05da39/screenshot_6.png
--------------------------------------------------------------------------------
/screenshot_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bwRavencl/ControllerBuddy/91a12d4ee6541c4cc39ecb8d9ddfd623fc05da39/screenshot_7.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0'
3 | }
4 |
--------------------------------------------------------------------------------
/spotless.importorder:
--------------------------------------------------------------------------------
1 | 0=
2 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/ffi/Kernel32.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2025 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.ffi;
18 |
19 | import java.lang.foreign.Arena;
20 | import java.lang.foreign.FunctionDescriptor;
21 | import java.lang.foreign.Linker;
22 | import java.lang.foreign.SymbolLookup;
23 | import java.lang.foreign.ValueLayout;
24 | import java.lang.invoke.MethodHandle;
25 |
26 | @SuppressWarnings({ "exports", "restricted" })
27 | public final class Kernel32 {
28 |
29 | private static final Linker LINKER = Linker.nativeLinker();
30 |
31 | private static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.libraryLookup(System.mapLibraryName("Kernel32"),
32 | Arena.global());
33 |
34 | private static final MethodHandle GET_LAST_ERROR_METHOD_HANDLE = LINKER
35 | .downcallHandle(SYMBOL_LOOKUP.findOrThrow("GetLastError"), FunctionDescriptor.of(ValueLayout.JAVA_INT));
36 |
37 | private Kernel32() {
38 | }
39 |
40 | public static int GetLastError() {
41 | try {
42 | return (int) GET_LAST_ERROR_METHOD_HANDLE.invoke();
43 | } catch (final Throwable t) {
44 | throw new RuntimeException(t);
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/KeyStroke.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import java.io.IOException;
21 | import java.io.ObjectInputStream;
22 | import java.io.ObjectOutputStream;
23 | import java.io.Serial;
24 | import java.io.Serializable;
25 | import java.util.ArrayList;
26 | import java.util.Arrays;
27 | import java.util.Objects;
28 | import java.util.Set;
29 | import java.util.stream.Collectors;
30 |
31 | public final class KeyStroke implements Cloneable, Serializable {
32 |
33 | @Serial
34 | private static final long serialVersionUID = 3572153768203547877L;
35 |
36 | @SuppressWarnings({ "serial", "RedundantSuppression" })
37 | private ScanCode[] keyCodes;
38 |
39 | @SuppressWarnings({ "serial", "RedundantSuppression" })
40 | private ScanCode[] modifierCodes;
41 |
42 | public KeyStroke() {
43 | this(new ScanCode[0], new ScanCode[0]);
44 | }
45 |
46 | public KeyStroke(final ScanCode[] keyCodes, final ScanCode[] modifierCodes) {
47 | this.keyCodes = keyCodes;
48 | this.modifierCodes = modifierCodes;
49 | }
50 |
51 | @Override
52 | public Object clone() throws CloneNotSupportedException {
53 | final var keyStroke = (KeyStroke) super.clone();
54 |
55 | final var clonedKeyCodes = new ScanCode[keyCodes.length];
56 | System.arraycopy(keyCodes, 0, clonedKeyCodes, 0, keyCodes.length);
57 | keyStroke.keyCodes = clonedKeyCodes;
58 |
59 | final var clonedModifierCodes = new ScanCode[modifierCodes.length];
60 | System.arraycopy(modifierCodes, 0, clonedModifierCodes, 0, modifierCodes.length);
61 | keyStroke.modifierCodes = clonedModifierCodes;
62 |
63 | return keyStroke;
64 | }
65 |
66 | @Override
67 | public boolean equals(final Object obj) {
68 | return obj instanceof final KeyStroke keyStroke && Arrays.equals(keyCodes, keyStroke.keyCodes)
69 | && Arrays.equals(modifierCodes, keyStroke.modifierCodes);
70 | }
71 |
72 | public ScanCode[] getKeyCodes() {
73 | return keyCodes;
74 | }
75 |
76 | public ScanCode[] getModifierCodes() {
77 | return modifierCodes;
78 | }
79 |
80 | @Override
81 | public int hashCode() {
82 | return Objects.hash(Arrays.hashCode(keyCodes), Arrays.hashCode(modifierCodes));
83 | }
84 |
85 | @Serial
86 | private void readObject(final ObjectInputStream stream) throws ClassNotFoundException, IOException {
87 | @SuppressWarnings("unchecked")
88 | final var modifierCodesKeyCodes = (Set) stream.readObject();
89 | modifierCodes = modifierCodesKeyCodes.stream().map(ScanCode.KEY_CODE_TO_SCAN_CODE_MAP::get)
90 | .toArray(ScanCode[]::new);
91 |
92 | @SuppressWarnings("unchecked")
93 | final var keyCodesKeyCodes = (Set) stream.readObject();
94 | keyCodes = keyCodesKeyCodes.stream().map(ScanCode.KEY_CODE_TO_SCAN_CODE_MAP::get).toArray(ScanCode[]::new);
95 | }
96 |
97 | public void setKeyCodes(final ScanCode[] keyCodes) {
98 | this.keyCodes = keyCodes;
99 | }
100 |
101 | public void setModifierCodes(final ScanCode[] modifierCodes) {
102 | this.modifierCodes = modifierCodes;
103 | }
104 |
105 | @Override
106 | public String toString() {
107 | final var collectedKeyCodes = new ArrayList<>(Arrays.asList(modifierCodes));
108 | collectedKeyCodes.addAll(Arrays.asList(keyCodes));
109 | if (collectedKeyCodes.isEmpty()) {
110 | return Main.STRINGS.getString("NOTHING");
111 | }
112 |
113 | return collectedKeyCodes.stream().map(ScanCode::name).collect(Collectors.joining(" + "));
114 | }
115 |
116 | @Serial
117 | private void writeObject(final ObjectOutputStream stream) throws IOException {
118 | stream.writeObject(Arrays.stream(modifierCodes).map(ScanCode::keyCode).collect(Collectors.toSet()));
119 | stream.writeObject(Arrays.stream(keyCodes).map(ScanCode::keyCode).collect(Collectors.toSet()));
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/LockKey.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2016 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input;
18 |
19 | import de.bwravencl.controllerbuddy.runmode.UinputDevice.Event;
20 | import java.awt.event.KeyEvent;
21 | import java.util.Collections;
22 | import java.util.HashMap;
23 | import java.util.List;
24 | import java.util.Map;
25 |
26 | public record LockKey(String name, int virtualKeyCode, Event event, String sysfsLedName) {
27 |
28 | public static final String LOCK_SUFFIX = " Lock";
29 |
30 | public static final String CAPS_LOCK = "Caps" + LOCK_SUFFIX;
31 |
32 | public static final LockKey CAPS_LOCK_LOCK_KEY = new LockKey(CAPS_LOCK, KeyEvent.VK_CAPS_LOCK, Event.KEY_CAPSLOCK,
33 | "capslock");
34 |
35 | public static final Map NAME_TO_LOCK_KEY_MAP;
36 |
37 | public static final String NUM_LOCK = "Num" + LOCK_SUFFIX;
38 |
39 | public static final LockKey NUM_LOCK_LOCK_KEY = new LockKey(NUM_LOCK, KeyEvent.VK_NUM_LOCK, Event.KEY_NUMLOCK,
40 | "numlock");
41 |
42 | public static final Map VIRTUAL_KEY_CODE_TO_LOCK_KEY_MAP;
43 |
44 | private static final String SCROLL_LOCK = "Scroll" + LOCK_SUFFIX;
45 |
46 | public static final LockKey SCROLL_LOCK_LOCK_KEY = new LockKey(SCROLL_LOCK, KeyEvent.VK_SCROLL_LOCK,
47 | Event.KEY_SCROLLLOCK, "scrolllock");
48 |
49 | public static final List LOCK_KEYS = List.of(CAPS_LOCK_LOCK_KEY, NUM_LOCK_LOCK_KEY, SCROLL_LOCK_LOCK_KEY);
50 |
51 | static {
52 | final var modifiableNameToLockKeyMap = new HashMap();
53 | final var modifiableVirtualKeyCodeToLockKeyMap = new HashMap();
54 |
55 | for (final var lockKey : LOCK_KEYS) {
56 | modifiableNameToLockKeyMap.put(lockKey.name, lockKey);
57 | modifiableVirtualKeyCodeToLockKeyMap.put(lockKey.virtualKeyCode, lockKey);
58 | }
59 |
60 | NAME_TO_LOCK_KEY_MAP = Collections.unmodifiableMap(modifiableNameToLockKeyMap);
61 | VIRTUAL_KEY_CODE_TO_LOCK_KEY_MAP = Collections.unmodifiableMap(modifiableVirtualKeyCodeToLockKeyMap);
62 | }
63 |
64 | @Override
65 | public String toString() {
66 | return name;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/Mode.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Mode.Component.ComponentType;
21 | import de.bwravencl.controllerbuddy.input.action.IAction;
22 | import java.lang.constant.Constable;
23 | import java.util.ArrayList;
24 | import java.util.HashMap;
25 | import java.util.List;
26 | import java.util.Map;
27 | import java.util.Objects;
28 | import java.util.Set;
29 | import java.util.UUID;
30 | import java.util.stream.Collectors;
31 | import java.util.stream.Stream;
32 | import org.lwjgl.sdl.SDLGamepad;
33 |
34 | public final class Mode implements Cloneable {
35 |
36 | private final UUID uuid;
37 |
38 | private Map>> axisToActionsMap = new HashMap<>();
39 |
40 | private Map>> buttonToActionsMap = new HashMap<>();
41 |
42 | private String description;
43 |
44 | public Mode() {
45 | uuid = UUID.randomUUID();
46 | description = Main.STRINGS.getString("NEW_MODE_DESCRIPTION");
47 | }
48 |
49 | public Mode(final UUID uuid) {
50 | this.uuid = uuid;
51 | }
52 |
53 | @SuppressWarnings("unchecked")
54 | private static Map>> cloneActionMap(
55 | final Map>> actionMap) throws CloneNotSupportedException {
56 | final var clonedActionMap = new HashMap>>();
57 | for (final var entry : actionMap.entrySet()) {
58 | for (final var action : entry.getValue()) {
59 | final var key = entry.getKey();
60 |
61 | final var clonedActions = clonedActionMap.computeIfAbsent(key, _ -> new ArrayList<>());
62 | clonedActions.add((IAction) action.clone());
63 | }
64 | }
65 |
66 | return clonedActionMap;
67 | }
68 |
69 | @Override
70 | public Object clone() throws CloneNotSupportedException {
71 | final var mode = (Mode) super.clone();
72 |
73 | mode.axisToActionsMap = cloneActionMap(axisToActionsMap);
74 | mode.buttonToActionsMap = cloneActionMap(buttonToActionsMap);
75 |
76 | return mode;
77 | }
78 |
79 | @Override
80 | public boolean equals(final Object obj) {
81 | return obj instanceof final Mode mode && Objects.equals(uuid, mode.uuid);
82 | }
83 |
84 | public Set> getAllActions() {
85 | return Stream.concat(axisToActionsMap.values().stream(), buttonToActionsMap.values().stream())
86 | .flatMap(List::stream).collect(Collectors.toUnmodifiableSet());
87 | }
88 |
89 | public Map>> getAxisToActionsMap() {
90 | return axisToActionsMap;
91 | }
92 |
93 | public Map>> getButtonToActionsMap() {
94 | return buttonToActionsMap;
95 | }
96 |
97 | public Map getComponentToActionsMap(final ComponentType type) {
98 | if (type == ComponentType.AXIS) {
99 | return axisToActionsMap;
100 | }
101 | return buttonToActionsMap;
102 | }
103 |
104 | public String getDescription() {
105 | return description;
106 | }
107 |
108 | public UUID getUuid() {
109 | return uuid;
110 | }
111 |
112 | @Override
113 | public int hashCode() {
114 | return Objects.hash(uuid);
115 | }
116 |
117 | public void setButtonToActionsMap(final Map>> buttonToActionsMap) {
118 | this.buttonToActionsMap = buttonToActionsMap;
119 | }
120 |
121 | public void setDescription(final String description) {
122 | this.description = description;
123 | }
124 |
125 | @Override
126 | public String toString() {
127 | return description;
128 | }
129 |
130 | public static final class Component {
131 |
132 | private final int index;
133 |
134 | private final Main main;
135 |
136 | private final ComponentType type;
137 |
138 | public Component(final Main main, final ComponentType type, final int index) {
139 | this.main = main;
140 | this.type = type;
141 | this.index = index;
142 | }
143 |
144 | public int getIndex() {
145 | if (main.isSwapLeftAndRightSticks()) {
146 | return switch (type) {
147 | case AXIS -> switch (index) {
148 | case SDLGamepad.SDL_GAMEPAD_AXIS_LEFTX -> SDLGamepad.SDL_GAMEPAD_AXIS_RIGHTX;
149 | case SDLGamepad.SDL_GAMEPAD_AXIS_LEFTY -> SDLGamepad.SDL_GAMEPAD_AXIS_RIGHTY;
150 | case SDLGamepad.SDL_GAMEPAD_AXIS_RIGHTX -> SDLGamepad.SDL_GAMEPAD_AXIS_LEFTX;
151 | case SDLGamepad.SDL_GAMEPAD_AXIS_RIGHTY -> SDLGamepad.SDL_GAMEPAD_AXIS_LEFTY;
152 | default -> index;
153 | };
154 | case BUTTON -> switch (index) {
155 | case SDLGamepad.SDL_GAMEPAD_BUTTON_LEFT_STICK -> SDLGamepad.SDL_GAMEPAD_BUTTON_RIGHT_STICK;
156 | case SDLGamepad.SDL_GAMEPAD_BUTTON_RIGHT_STICK -> SDLGamepad.SDL_GAMEPAD_BUTTON_LEFT_STICK;
157 | default -> index;
158 | };
159 | };
160 | }
161 |
162 | return index;
163 | }
164 |
165 | public ComponentType getType() {
166 | return type;
167 | }
168 |
169 | public enum ComponentType {
170 | AXIS, BUTTON
171 | }
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/OverlayAxis.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input;
18 |
19 | import java.awt.Color;
20 |
21 | public final class OverlayAxis implements Cloneable {
22 |
23 | public Color color;
24 |
25 | public boolean inverted;
26 |
27 | public OverlayAxis() {
28 | this(Color.BLACK, false);
29 | }
30 |
31 | private OverlayAxis(final Color color, final boolean inverted) {
32 | this.color = color;
33 | this.inverted = inverted;
34 | }
35 |
36 | @SuppressWarnings("MethodDoesntCallSuperMethod")
37 | @Override
38 | public Object clone() {
39 | return new OverlayAxis(new Color(color.getRGB(), true), inverted);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ActivationIntervalAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2024 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
21 | import de.bwravencl.controllerbuddy.input.action.gui.ActivationIntervalEditorBuilder;
22 | import java.lang.constant.Constable;
23 |
24 | abstract class ActivationIntervalAction extends DescribableAction
25 | implements IInitializationAction {
26 |
27 | @ActionProperty(label = "MAX_ACTIVATION_INTERVAL", editorBuilder = ActivationIntervalEditorBuilder.class, order = 501)
28 | private int maxActivationInterval;
29 |
30 | private transient long maxActivationTime = Integer.MAX_VALUE;
31 |
32 | @ActionProperty(label = "MIN_ACTIVATION_INTERVAL", editorBuilder = ActivationIntervalEditorBuilder.class, order = 500)
33 | private int minActivationInterval;
34 |
35 | private transient long minActivationTime;
36 |
37 | private transient boolean wasUp = true;
38 |
39 | public int getMaxActivationInterval() {
40 | return maxActivationInterval;
41 | }
42 |
43 | public int getMinActivationInterval() {
44 | return minActivationInterval;
45 | }
46 |
47 | boolean handleActivationInterval(final boolean hot) {
48 | final var hasMinActivationInterval = minActivationInterval > 0L;
49 | final var hasMaxActivationInterval = maxActivationInterval > 0L;
50 |
51 | if (hasMinActivationInterval || hasMaxActivationInterval) {
52 | final var currentTime = System.currentTimeMillis();
53 |
54 | if (hot) {
55 | if (hasMaxActivationInterval && currentTime > maxActivationTime) {
56 | return false;
57 | }
58 |
59 | if (wasUp) {
60 | wasUp = false;
61 | if (hasMinActivationInterval) {
62 | minActivationTime = currentTime + minActivationInterval;
63 | }
64 | if (hasMaxActivationInterval) {
65 | maxActivationTime = currentTime + maxActivationInterval;
66 | }
67 | }
68 | } else {
69 | wasUp = true;
70 |
71 | if (hasMinActivationInterval && currentTime <= minActivationTime) {
72 | return true;
73 | }
74 |
75 | minActivationTime = 0L;
76 | maxActivationTime = Long.MAX_VALUE;
77 | }
78 | }
79 |
80 | return hot;
81 | }
82 |
83 | @Override
84 | public void init(final Input input) {
85 | wasUp = true;
86 | minActivationTime = 0;
87 | maxActivationTime = Long.MAX_VALUE;
88 | }
89 |
90 | public void setMaxActivationInterval(final int maxActivationInterval) {
91 | this.maxActivationInterval = maxActivationInterval;
92 | }
93 |
94 | public void setMinActivationInterval(final int minActivationInterval) {
95 | this.minActivationInterval = minActivationInterval;
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/AxisToAxisAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
23 | import de.bwravencl.controllerbuddy.input.action.gui.AxisValueEditorBuilder;
24 | import de.bwravencl.controllerbuddy.input.action.gui.DeadZoneEditorBuilder;
25 | import de.bwravencl.controllerbuddy.input.action.gui.ExponentEditorBuilder;
26 | import de.bwravencl.controllerbuddy.input.action.gui.MaxAxisValueEditorBuilder;
27 | import de.bwravencl.controllerbuddy.input.action.gui.MinAxisValueEditorBuilder;
28 |
29 | @Action(label = "TO_AXIS_ACTION", category = ActionCategory.AXIS, order = 10)
30 | public class AxisToAxisAction extends ToAxisAction implements IAxisToAction, IInitializationAction {
31 |
32 | private static final float DEFAULT_DEAD_ZONE = 0f;
33 |
34 | private static final float DEFAULT_EXPONENT = 1f;
35 |
36 | private static final float DEFAULT_INITIAL_VALUE = 0f;
37 |
38 | private static final float DEFAULT_MAX_VALUE = 1f;
39 |
40 | private static final float DEFAULT_MIN_VALUE = -1f;
41 |
42 | @ActionProperty(label = "DEAD_ZONE", editorBuilder = DeadZoneEditorBuilder.class, order = 100)
43 | float deadZone = DEFAULT_DEAD_ZONE;
44 |
45 | @ActionProperty(label = "EXPONENT", editorBuilder = ExponentEditorBuilder.class, order = 103)
46 | float exponent = DEFAULT_EXPONENT;
47 |
48 | @ActionProperty(label = "INITIAL_VALUE", editorBuilder = AxisValueEditorBuilder.class, order = 202)
49 | float initialValue = DEFAULT_INITIAL_VALUE;
50 |
51 | @ActionProperty(label = "MAX_AXIS_VALUE", editorBuilder = MaxAxisValueEditorBuilder.class, order = 102)
52 | float maxValue = DEFAULT_MAX_VALUE;
53 |
54 | @ActionProperty(label = "MIN_AXIS_VALUE", editorBuilder = MinAxisValueEditorBuilder.class, order = 101)
55 | float minValue = DEFAULT_MIN_VALUE;
56 |
57 | @Override
58 | public void doAction(final Input input, final int component, Float value) {
59 | if (input.isAxisSuspended(component)) {
60 | return;
61 | }
62 |
63 | final var absValue = Math.abs(value);
64 |
65 | if (absValue <= deadZone) {
66 | value = 0f;
67 | } else {
68 | final float inMax;
69 | if (exponent != 0f) {
70 | inMax = (float) Math.pow((1f - deadZone) * 100f, exponent);
71 |
72 | value = Math.signum(value) * (float) Math.pow((absValue - deadZone) * 100f, exponent);
73 | } else {
74 | inMax = 1f;
75 | }
76 |
77 | if (value >= 0f) {
78 | value = Input.normalize(value, deadZone, inMax, 0f, maxValue);
79 | } else {
80 | value = Input.normalize(value, -inMax, -deadZone, minValue, 0f);
81 | }
82 | }
83 |
84 | input.setAxis(virtualAxis, invert ? -value : value, false, null);
85 | }
86 |
87 | public float getDeadZone() {
88 | return deadZone;
89 | }
90 |
91 | public float getExponent() {
92 | return exponent;
93 | }
94 |
95 | public float getInitialValue() {
96 | return initialValue;
97 | }
98 |
99 | public float getMaxValue() {
100 | return maxValue;
101 | }
102 |
103 | public float getMinValue() {
104 | return minValue;
105 | }
106 |
107 | @Override
108 | public void init(final Input input) {
109 | if (!input.isSkipAxisInitialization()) {
110 | input.setAxis(virtualAxis, invert ? -initialValue : initialValue, false, null);
111 | }
112 | }
113 |
114 | public void setDeadZone(final float deadZone) {
115 | this.deadZone = deadZone;
116 | }
117 |
118 | public void setExponent(final float exponent) {
119 | this.exponent = exponent;
120 | }
121 |
122 | public void setInitialValue(final float initialValue) {
123 | this.initialValue = initialValue;
124 | }
125 |
126 | public void setMaxValue(final float maxValue) {
127 | this.maxValue = maxValue;
128 | }
129 |
130 | public void setMinValue(final float minValue) {
131 | this.minValue = minValue;
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/AxisToButtonAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
23 | import de.bwravencl.controllerbuddy.input.action.gui.AxisValueEditorBuilder;
24 | import de.bwravencl.controllerbuddy.input.action.gui.LongPressEditorBuilder;
25 |
26 | @Action(label = "TO_BUTTON_ACTION", category = ActionCategory.AXIS, order = 20)
27 | public final class AxisToButtonAction extends ToButtonAction implements IAxisToLongPressAction {
28 |
29 | private static final float DEFAULT_MAX_AXIS_VALUE = 1f;
30 |
31 | private static final float DEFAULT_MIN_AXIS_VALUE = 0.5f;
32 |
33 | @ActionProperty(label = "LONG_PRESS", editorBuilder = LongPressEditorBuilder.class, order = 400)
34 | private boolean longPress = DEFAULT_LONG_PRESS;
35 |
36 | @ActionProperty(label = "MAX_AXIS_VALUE", editorBuilder = AxisValueEditorBuilder.class, order = 101)
37 | private float maxAxisValue = DEFAULT_MAX_AXIS_VALUE;
38 |
39 | @ActionProperty(label = "MIN_AXIS_VALUE", editorBuilder = AxisValueEditorBuilder.class, order = 100)
40 | private float minAxisValue = DEFAULT_MIN_AXIS_VALUE;
41 |
42 | @Override
43 | public void doAction(final Input input, final int component, Float value) {
44 | value = handleLongPress(input, component, value);
45 |
46 | var hot = !input.isAxisSuspended(component) && value >= minAxisValue && value <= maxAxisValue;
47 | hot = handleActivationInterval(hot);
48 |
49 | if (hot && isAlreadyPressed(input)) {
50 | return;
51 | }
52 |
53 | input.setButton(buttonId, hot);
54 | }
55 |
56 | @Override
57 | public float getMaxAxisValue() {
58 | return maxAxisValue;
59 | }
60 |
61 | @Override
62 | public float getMinAxisValue() {
63 | return minAxisValue;
64 | }
65 |
66 | @Override
67 | public boolean isLongPress() {
68 | return longPress;
69 | }
70 |
71 | @Override
72 | public void setLongPress(final boolean longPress) {
73 | this.longPress = longPress;
74 | }
75 |
76 | @Override
77 | public void setMaxAxisValue(final float maxAxisValue) {
78 | this.maxAxisValue = maxAxisValue;
79 | }
80 |
81 | @Override
82 | public void setMinAxisValue(final float minAxisValue) {
83 | this.minAxisValue = minAxisValue;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/AxisToCursorAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
23 | import de.bwravencl.controllerbuddy.input.action.gui.DeadZoneEditorBuilder;
24 | import de.bwravencl.controllerbuddy.input.action.gui.ExponentEditorBuilder;
25 |
26 | @Action(label = "TO_CURSOR_ACTION", category = ActionCategory.AXIS, order = 25)
27 | public final class AxisToCursorAction extends ToCursorAction implements IAxisToAction {
28 |
29 | private static final float DEFAULT_DEAD_ZONE = 0.1f;
30 |
31 | private static final float DEFAULT_EXPONENT = 2f;
32 |
33 | @ActionProperty(label = "DEAD_ZONE", editorBuilder = DeadZoneEditorBuilder.class, order = 13)
34 | private float deadZone = DEFAULT_DEAD_ZONE;
35 |
36 | @ActionProperty(label = "EXPONENT", editorBuilder = ExponentEditorBuilder.class, order = 12)
37 | private float exponent = DEFAULT_EXPONENT;
38 |
39 | @Override
40 | public void doAction(final Input input, final int component, final Float value) {
41 | final var absValue = Math.abs(value);
42 |
43 | if (!input.isAxisSuspended(component) && absValue > deadZone) {
44 | final var inMax = (float) Math.pow((1f - deadZone) * 100f, exponent);
45 |
46 | final var d = Input.normalize(Math.signum(value) * (float) Math.pow((absValue - deadZone) * 100f, exponent),
47 | -inMax, inMax, -cursorSensitivity, cursorSensitivity) * input.getRateMultiplier();
48 | moveCursor(input, d);
49 | } else {
50 | remainingD = 0f;
51 | }
52 | }
53 |
54 | public float getDeadZone() {
55 | return deadZone;
56 | }
57 |
58 | public float getExponent() {
59 | return exponent;
60 | }
61 |
62 | public void setDeadZone(final float deadZone) {
63 | this.deadZone = deadZone;
64 | }
65 |
66 | public void setExponent(final float exponent) {
67 | this.exponent = exponent;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/AxisToKeyAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
23 | import de.bwravencl.controllerbuddy.input.action.gui.AxisValueEditorBuilder;
24 |
25 | @Action(label = "TO_KEY_ACTION", category = ActionCategory.AXIS, order = 40)
26 | public final class AxisToKeyAction extends ToKeyAction implements IAxisToLongPressAction {
27 |
28 | private static final float DEFAULT_MAX_AXIS_VALUE = 1f;
29 |
30 | private static final float DEFAULT_MIN_AXIS_VALUE = 0.5f;
31 |
32 | @ActionProperty(label = "MAX_AXIS_VALUE", editorBuilder = AxisValueEditorBuilder.class, order = 101)
33 | private float maxAxisValue = DEFAULT_MAX_AXIS_VALUE;
34 |
35 | @ActionProperty(label = "MIN_AXIS_VALUE", editorBuilder = AxisValueEditorBuilder.class, order = 100)
36 | private float minAxisValue = DEFAULT_MIN_AXIS_VALUE;
37 |
38 | @Override
39 | public void doAction(final Input input, final int component, Float value) {
40 | value = handleLongPress(input, component, value);
41 |
42 | final var inZone = !input.isAxisSuspended(component) && value >= minAxisValue && value <= maxAxisValue;
43 | handleAction(inZone, input);
44 | }
45 |
46 | @Override
47 | public float getMaxAxisValue() {
48 | return maxAxisValue;
49 | }
50 |
51 | @Override
52 | public float getMinAxisValue() {
53 | return minAxisValue;
54 | }
55 |
56 | @Override
57 | public void setMaxAxisValue(final float maxAxisValue) {
58 | this.maxAxisValue = maxAxisValue;
59 | }
60 |
61 | @Override
62 | public void setMinAxisValue(final float minAxisValue) {
63 | this.minAxisValue = minAxisValue;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/AxisToMouseButtonAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
23 | import de.bwravencl.controllerbuddy.input.action.gui.AxisValueEditorBuilder;
24 |
25 | @Action(label = "TO_MOUSE_BUTTON_ACTION", category = ActionCategory.AXIS, order = 30)
26 | public final class AxisToMouseButtonAction extends ToMouseButtonAction implements IAxisToLongPressAction {
27 |
28 | private static final float DEFAULT_MAX_AXIS_VALUE = 1f;
29 |
30 | private static final float DEFAULT_MIN_AXIS_VALUE = 0.5f;
31 |
32 | @ActionProperty(label = "MAX_AXIS_VALUE", editorBuilder = AxisValueEditorBuilder.class, order = 101)
33 | private float maxAxisValue = DEFAULT_MAX_AXIS_VALUE;
34 |
35 | @ActionProperty(label = "MIN_AXIS_VALUE", editorBuilder = AxisValueEditorBuilder.class, order = 100)
36 | private float minAxisValue = DEFAULT_MIN_AXIS_VALUE;
37 |
38 | @Override
39 | public void doAction(final Input input, final int component, Float value) {
40 | value = handleLongPress(input, component, value);
41 |
42 | final var inZone = !input.isAxisSuspended(component) && value >= minAxisValue && value <= maxAxisValue;
43 | handleAction(inZone, input);
44 | }
45 |
46 | @Override
47 | public float getMaxAxisValue() {
48 | return maxAxisValue;
49 | }
50 |
51 | @Override
52 | public float getMinAxisValue() {
53 | return minAxisValue;
54 | }
55 |
56 | @Override
57 | public void setMaxAxisValue(final float maxAxisValue) {
58 | this.maxAxisValue = maxAxisValue;
59 | }
60 |
61 | @Override
62 | public void setMinAxisValue(final float minAxisValue) {
63 | this.minAxisValue = minAxisValue;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/AxisToRelativeAxisAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
23 | import de.bwravencl.controllerbuddy.input.action.gui.BooleanEditorBuilder;
24 | import de.bwravencl.controllerbuddy.input.action.gui.DetentValueEditorBuilder;
25 | import de.bwravencl.controllerbuddy.input.action.gui.MaxRelativeSpeedEditorBuilder;
26 |
27 | @Action(label = "AXIS_TO_RELATIVE_AXIS_ACTION", category = ActionCategory.AXIS, order = 15)
28 | public final class AxisToRelativeAxisAction extends AxisToAxisAction {
29 |
30 | private static final boolean DEFAULT_HAPTIC_FEEDBACK = false;
31 |
32 | private static final float DEFAULT_MAX_RELATIVE_SPEED = 4f;
33 |
34 | transient float remainingD;
35 |
36 | @ActionProperty(label = "DETENT_VALUE", editorBuilder = DetentValueEditorBuilder.class, order = 203)
37 | private Float detentValue = null;
38 |
39 | @ActionProperty(label = "HAPTIC_FEEDBACK", editorBuilder = BooleanEditorBuilder.class, order = 204)
40 | private boolean hapticFeedback = DEFAULT_HAPTIC_FEEDBACK;
41 |
42 | @ActionProperty(label = "MAX_RELATIVE_SPEED", editorBuilder = MaxRelativeSpeedEditorBuilder.class, order = 201)
43 | private float maxRelativeSpeed = DEFAULT_MAX_RELATIVE_SPEED;
44 |
45 | @Override
46 | public void doAction(final Input input, final int component, final Float value) {
47 | final var absValue = Math.abs(value);
48 |
49 | if (input.isAxisSuspended(component) || absValue <= deadZone) {
50 | return;
51 | }
52 |
53 | final var inMax = (float) Math.pow((1f - deadZone) * 100f, exponent);
54 |
55 | var d = Input.normalize(Math.signum(value) * (float) Math.pow((absValue - deadZone) * 100f, exponent), -inMax,
56 | inMax, -maxRelativeSpeed, maxRelativeSpeed) * input.getRateMultiplier();
57 | d += remainingD;
58 |
59 | if (Math.abs(d) < input.getPlanckLength()) {
60 | remainingD = d;
61 | return;
62 | }
63 |
64 | final var runMode = input.getRunMode();
65 | final var oldValue = Input.normalize(input.getAxes().get(virtualAxis), runMode.getMinAxisValue(),
66 | runMode.getMaxAxisValue(), -1f, 1f);
67 |
68 | final var newValue = Math.min(Math.max(oldValue + (invert ? -d : d), minValue), maxValue);
69 | input.setAxis(virtualAxis, newValue, hapticFeedback, detentValue);
70 |
71 | remainingD = 0f;
72 | }
73 |
74 | public Float getDetentValue() {
75 | return detentValue;
76 | }
77 |
78 | public float getMaxRelativeSpeed() {
79 | return maxRelativeSpeed;
80 | }
81 |
82 | public boolean isHapticFeedback() {
83 | return hapticFeedback;
84 | }
85 |
86 | public void setDetentValue(final Float detentValue) {
87 | this.detentValue = detentValue;
88 | }
89 |
90 | public void setHapticFeedback(final boolean hapticFeedback) {
91 | this.hapticFeedback = hapticFeedback;
92 | }
93 |
94 | public void setMaxRelativeSpeed(final float maxRelativeSpeed) {
95 | this.maxRelativeSpeed = maxRelativeSpeed;
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/AxisToScrollAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
23 | import de.bwravencl.controllerbuddy.input.action.gui.DeadZoneEditorBuilder;
24 | import de.bwravencl.controllerbuddy.input.action.gui.ExponentEditorBuilder;
25 |
26 | @Action(label = "TO_SCROLL_ACTION", category = ActionCategory.AXIS, order = 35)
27 | public final class AxisToScrollAction extends ToScrollAction implements IAxisToAction {
28 |
29 | private static final float DEFAULT_DEAD_ZONE = 0.1f;
30 |
31 | private static final float DEFAULT_EXPONENT = 1f;
32 |
33 | @ActionProperty(label = "DEAD_ZONE", editorBuilder = DeadZoneEditorBuilder.class, order = 100)
34 | private float deadZone = DEFAULT_DEAD_ZONE;
35 |
36 | @ActionProperty(label = "EXPONENT", editorBuilder = ExponentEditorBuilder.class, order = 101)
37 | private float exponent = DEFAULT_EXPONENT;
38 |
39 | @Override
40 | public void doAction(final Input input, final int component, final Float value) {
41 | if (!input.isAxisSuspended(component) && Math.abs(value) > deadZone) {
42 | final var rateMultiplier = input.getRateMultiplier();
43 |
44 | final var d = -Input.normalize(
45 | Math.signum(value) * (float) Math.pow(Math.abs(value) * 100f, exponent) * rateMultiplier,
46 | (float) -Math.pow(99.9f, exponent) * rateMultiplier,
47 | (float) Math.pow(99.9f, exponent) * rateMultiplier, -clicks, clicks);
48 |
49 | scroll(input, d);
50 | } else {
51 | remainingD = 0f;
52 | }
53 | }
54 |
55 | public float getDeadZone() {
56 | return deadZone;
57 | }
58 |
59 | public float getExponent() {
60 | return exponent;
61 | }
62 |
63 | public void setDeadZone(final float deadZone) {
64 | this.deadZone = deadZone;
65 | }
66 |
67 | public void setExponent(final float exponent) {
68 | this.exponent = exponent;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ButtonToAxisResetAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2015 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.Input.VirtualAxis;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
23 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
24 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
25 | import de.bwravencl.controllerbuddy.input.action.gui.ActivationEditorBuilder;
26 | import de.bwravencl.controllerbuddy.input.action.gui.AxisValueEditorBuilder;
27 | import de.bwravencl.controllerbuddy.input.action.gui.BooleanEditorBuilder;
28 | import de.bwravencl.controllerbuddy.input.action.gui.LongPressEditorBuilder;
29 | import de.bwravencl.controllerbuddy.input.action.gui.VirtualAxisEditorBuilder;
30 | import java.text.MessageFormat;
31 |
32 | @Action(label = "BUTTON_TO_AXIS_RESET_ACTION", category = ActionCategory.BUTTON_AND_CYCLES, order = 135)
33 | public final class ButtonToAxisResetAction extends DescribableAction
34 | implements IButtonToAction, IActivatableAction {
35 |
36 | private static final boolean DEFAULT_FLUID = false;
37 |
38 | private static final float DEFAULT_RESET_VALUE = 0f;
39 |
40 | private transient Activatable activatable;
41 |
42 | @ActionProperty(label = "ACTIVATION", editorBuilder = ActivationEditorBuilder.class, order = 40)
43 | private Activation activation = Activation.SINGLE_IMMEDIATELY;
44 |
45 | @ActionProperty(label = "FLUID", editorBuilder = BooleanEditorBuilder.class, order = 30)
46 | private boolean fluid = DEFAULT_FLUID;
47 |
48 | @ActionProperty(label = "LONG_PRESS", editorBuilder = LongPressEditorBuilder.class, order = 50)
49 | private boolean longPress = DEFAULT_LONG_PRESS;
50 |
51 | @ActionProperty(label = "RESET_VALUE", editorBuilder = AxisValueEditorBuilder.class, order = 20)
52 | private float resetValue = DEFAULT_RESET_VALUE;
53 |
54 | @ActionProperty(label = "VIRTUAL_AXIS", editorBuilder = VirtualAxisEditorBuilder.class, order = 10)
55 | private VirtualAxis virtualAxis = VirtualAxis.X;
56 |
57 | @Override
58 | public void doAction(final Input input, final int component, Boolean value) {
59 | value = handleLongPress(input, component, value);
60 |
61 | switch (activation) {
62 | case REPEAT -> {
63 | if (value) {
64 | resetAxis(input);
65 | }
66 | }
67 | case SINGLE_IMMEDIATELY -> {
68 | if (!value) {
69 | activatable = Activatable.YES;
70 | } else if (activatable == Activatable.YES) {
71 | activatable = Activatable.NO;
72 | resetAxis(input);
73 | }
74 | }
75 | case SINGLE_ON_RELEASE -> {
76 | if (value) {
77 | if (activatable == Activatable.NO) {
78 | activatable = Activatable.YES;
79 | } else if (activatable == Activatable.DENIED_BY_OTHER_ACTION) {
80 | activatable = Activatable.NO;
81 | }
82 | } else if (activatable == Activatable.YES) {
83 | activatable = Activatable.NO;
84 | resetAxis(input);
85 | }
86 | }
87 | }
88 | }
89 |
90 | @Override
91 | public Activatable getActivatable() {
92 | return activatable;
93 | }
94 |
95 | @Override
96 | public Activation getActivation() {
97 | return activation;
98 | }
99 |
100 | @Override
101 | public String getDescription(final Input input) {
102 | if (!isDescriptionEmpty()) {
103 | return super.getDescription(input);
104 | }
105 |
106 | return MessageFormat.format(Main.STRINGS.getString("RESET_JOYSTICK_AXIS_NAME"), virtualAxis);
107 | }
108 |
109 | public float getResetValue() {
110 | return resetValue;
111 | }
112 |
113 | public VirtualAxis getVirtualAxis() {
114 | return virtualAxis;
115 | }
116 |
117 | public boolean isFluid() {
118 | return fluid;
119 | }
120 |
121 | @Override
122 | public boolean isLongPress() {
123 | return longPress;
124 | }
125 |
126 | private void resetAxis(final Input input) {
127 | if (fluid) {
128 | input.moveAxis(virtualAxis, resetValue);
129 | } else {
130 | input.setAxis(virtualAxis, resetValue, false, null);
131 | }
132 | }
133 |
134 | @Override
135 | public void setActivatable(final Activatable activatable) {
136 | this.activatable = activatable;
137 | }
138 |
139 | @Override
140 | public void setActivation(final Activation activation) {
141 | this.activation = activation;
142 | }
143 |
144 | public void setFluid(final boolean fluid) {
145 | this.fluid = fluid;
146 | }
147 |
148 | @Override
149 | public void setLongPress(final boolean longPress) {
150 | this.longPress = longPress;
151 | }
152 |
153 | public void setResetValue(final float resetValue) {
154 | this.resetValue = resetValue;
155 | }
156 |
157 | public void setVirtualAxis(final VirtualAxis virtualAxis) {
158 | this.virtualAxis = virtualAxis;
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ButtonToButtonAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
23 | import de.bwravencl.controllerbuddy.input.action.gui.LongPressEditorBuilder;
24 |
25 | @Action(label = "TO_BUTTON_ACTION", category = ActionCategory.BUTTON_AND_CYCLES, order = 110)
26 | public final class ButtonToButtonAction extends ToButtonAction implements IButtonToAction {
27 |
28 | @ActionProperty(label = "LONG_PRESS", editorBuilder = LongPressEditorBuilder.class, order = 400)
29 | private boolean longPress = DEFAULT_LONG_PRESS;
30 |
31 | @Override
32 | public void doAction(final Input input, final int component, Boolean value) {
33 | value = handleLongPress(input, component, value);
34 | value = handleActivationInterval(value);
35 |
36 | if (value && isAlreadyPressed(input)) {
37 | return;
38 | }
39 |
40 | input.setButton(buttonId, value);
41 | }
42 |
43 | @Override
44 | public boolean isLongPress() {
45 | return longPress;
46 | }
47 |
48 | @Override
49 | public void setLongPress(final boolean longPress) {
50 | this.longPress = longPress;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ButtonToCursorAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2020 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
23 | import de.bwravencl.controllerbuddy.input.action.gui.LongPressEditorBuilder;
24 |
25 | @Action(label = "TO_CURSOR_ACTION", category = ActionCategory.BUTTON, order = 125)
26 | public final class ButtonToCursorAction extends ToCursorAction implements IButtonToAction {
27 |
28 | @ActionProperty(label = "LONG_PRESS", editorBuilder = LongPressEditorBuilder.class, order = 400)
29 | private boolean longPress = DEFAULT_LONG_PRESS;
30 |
31 | @Override
32 | public void doAction(final Input input, final int component, Boolean value) {
33 | value = handleLongPress(input, component, value);
34 |
35 | if (!value) {
36 | remainingD = 0f;
37 |
38 | return;
39 | }
40 |
41 | final var d = cursorSensitivity * input.getRateMultiplier();
42 | moveCursor(input, d);
43 | }
44 |
45 | @Override
46 | public boolean isLongPress() {
47 | return longPress;
48 | }
49 |
50 | @Override
51 | public void setLongPress(final boolean longPress) {
52 | this.longPress = longPress;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ButtonToKeyAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 |
23 | @Action(label = "TO_KEY_ACTION", category = ActionCategory.BUTTON_AND_CYCLES, order = 115)
24 | public final class ButtonToKeyAction extends ToKeyAction implements IButtonToAction {
25 |
26 | @Override
27 | public void doAction(final Input input, final int component, Boolean value) {
28 | value = handleLongPress(input, component, value);
29 | handleAction(value, input);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ButtonToLockKeyAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2016 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.LockKey;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
23 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
24 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
25 | import de.bwravencl.controllerbuddy.input.action.gui.BooleanEditorBuilder;
26 | import de.bwravencl.controllerbuddy.input.action.gui.LockKeyEditorBuilder;
27 | import java.text.MessageFormat;
28 |
29 | @Action(label = "BUTTON_TO_LOCK_KEY_ACTION", category = ActionCategory.BUTTON_AND_CYCLES, order = 116)
30 | public final class ButtonToLockKeyAction extends DescribableAction
31 | implements IButtonToAction, IInitializationAction {
32 |
33 | private boolean longPress = DEFAULT_LONG_PRESS;
34 |
35 | @ActionProperty(label = "ON", editorBuilder = BooleanEditorBuilder.class, order = 11)
36 | private boolean on = true;
37 |
38 | @ActionProperty(label = "KEY", editorBuilder = LockKeyEditorBuilder.class, overrideFieldName = "lockKey", overrideFieldType = LockKey.class, order = 10)
39 | private LockKey virtualKeyCode = LockKey.CAPS_LOCK_LOCK_KEY;
40 |
41 | private transient boolean wasUp = true;
42 |
43 | @Override
44 | public void doAction(final Input input, final int component, Boolean value) {
45 | value = handleLongPress(input, component, value);
46 |
47 | if (value) {
48 | if (wasUp) {
49 | wasUp = false;
50 | if (on) {
51 | input.getOnLockKeys().add(virtualKeyCode);
52 | } else {
53 | input.getOffLockKeys().add(virtualKeyCode);
54 | }
55 | }
56 | } else {
57 | wasUp = true;
58 | }
59 | }
60 |
61 | @Override
62 | public String getDescription(final Input input) {
63 | if (!isDescriptionEmpty()) {
64 | return super.getDescription(input);
65 | }
66 |
67 | return MessageFormat.format(Main.STRINGS.getString(on ? "LOCK_KEY_ON" : "LOCK_KEY_OFF"), getLockKey());
68 | }
69 |
70 | public LockKey getLockKey() {
71 | return virtualKeyCode;
72 | }
73 |
74 | @Override
75 | public void init(final Input input) {
76 | resetWasUp();
77 | }
78 |
79 | @Override
80 | public boolean isLongPress() {
81 | return longPress;
82 | }
83 |
84 | public boolean isOn() {
85 | return on;
86 | }
87 |
88 | void resetWasUp() {
89 | wasUp = true;
90 | }
91 |
92 | public void setLockKey(final LockKey lockKey) {
93 | virtualKeyCode = lockKey;
94 | }
95 |
96 | @Override
97 | public void setLongPress(final boolean longPress) {
98 | this.longPress = longPress;
99 | }
100 |
101 | public void setOn(final boolean on) {
102 | this.on = on;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ButtonToMouseButtonAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 |
23 | @Action(label = "TO_MOUSE_BUTTON_ACTION", category = ActionCategory.BUTTON_AND_CYCLES, order = 120)
24 | public final class ButtonToMouseButtonAction extends ToMouseButtonAction implements IButtonToAction {
25 |
26 | @Override
27 | public void doAction(final Input input, final int component, Boolean value) {
28 | value = handleLongPress(input, component, value);
29 | handleAction(value, input);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ButtonToPressOnScreenKeyboardKeyAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2018 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
23 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
24 | import de.bwravencl.controllerbuddy.input.action.gui.BooleanEditorBuilder;
25 | import de.bwravencl.controllerbuddy.input.action.gui.LongPressEditorBuilder;
26 |
27 | @Action(label = "BUTTON_TO_PRESS_ON_SCREEN_KEYBOARD_KEY_ACTION", category = ActionCategory.ON_SCREEN_KEYBOARD_MODE, order = 520)
28 | public final class ButtonToPressOnScreenKeyboardKeyAction implements IButtonToAction, IInitializationAction {
29 |
30 | @ActionProperty(label = "LOCK_KEY", editorBuilder = BooleanEditorBuilder.class, order = 10)
31 | private boolean lockKey;
32 |
33 | @ActionProperty(label = "LONG_PRESS", editorBuilder = LongPressEditorBuilder.class, order = 400)
34 | private boolean longPress = DEFAULT_LONG_PRESS;
35 |
36 | private transient boolean wasDown;
37 |
38 | private transient boolean wasUp = true;
39 |
40 | @Override
41 | public Object clone() throws CloneNotSupportedException {
42 | return super.clone();
43 | }
44 |
45 | @Override
46 | public void doAction(final Input input, final int component, Boolean value) {
47 | value = handleLongPress(input, component, value);
48 |
49 | final var onScreenKeyboard = input.getMain().getOnScreenKeyboard();
50 |
51 | if (!value) {
52 | if (lockKey) {
53 | wasUp = true;
54 | } else {
55 | if (wasDown) {
56 | onScreenKeyboard.releaseSelectedButton();
57 | }
58 | wasDown = false;
59 | }
60 | } else if (lockKey) {
61 | if (wasUp) {
62 | onScreenKeyboard.toggleLock();
63 | wasUp = false;
64 | }
65 | } else {
66 | onScreenKeyboard.pressSelectedButton();
67 | wasDown = true;
68 | }
69 | }
70 |
71 | @Override
72 | public String getDescription(final Input input) {
73 | return Main.STRINGS
74 | .getString(lockKey ? "LOCK_SELECTED_ON_SCREEN_KEYBOARD_KEY" : "PRESS_SELECTED_ON_SCREEN_KEYBOARD_KEY");
75 | }
76 |
77 | @Override
78 | public void init(final Input input) {
79 | wasUp = true;
80 | wasDown = false;
81 | }
82 |
83 | public boolean isLockKey() {
84 | return lockKey;
85 | }
86 |
87 | @Override
88 | public boolean isLongPress() {
89 | return longPress;
90 | }
91 |
92 | public void setLockKey(final boolean lockKey) {
93 | this.lockKey = lockKey;
94 | }
95 |
96 | @Override
97 | public void setLongPress(final boolean longPress) {
98 | this.longPress = longPress;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ButtonToReleaseAllOnScreenKeyboardKeysAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2022 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
23 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
24 | import de.bwravencl.controllerbuddy.input.action.gui.LongPressEditorBuilder;
25 |
26 | @Action(label = "BUTTON_TO_RELEASE_ALL_ON_SCREEN_KEYBOARD_KEYS_ACTION", category = ActionCategory.ON_SCREEN_KEYBOARD_MODE, order = 530)
27 | public final class ButtonToReleaseAllOnScreenKeyboardKeysAction implements IButtonToAction {
28 |
29 | @ActionProperty(label = "LONG_PRESS", editorBuilder = LongPressEditorBuilder.class, order = 400)
30 | private boolean longPress = DEFAULT_LONG_PRESS;
31 |
32 | @Override
33 | public Object clone() throws CloneNotSupportedException {
34 | return super.clone();
35 | }
36 |
37 | @Override
38 | public void doAction(final Input input, final int component, Boolean value) {
39 | value = handleLongPress(input, component, value);
40 |
41 | if (value) {
42 | input.getMain().getOnScreenKeyboard().releaseAllButtons();
43 | }
44 | }
45 |
46 | @Override
47 | public String getDescription(final Input input) {
48 | return Main.STRINGS.getString("BUTTON_TO_RELEASE_ALL_ON_SCREEN_KEYBOARD_KEYS_ACTION");
49 | }
50 |
51 | @Override
52 | public boolean isLongPress() {
53 | return longPress;
54 | }
55 |
56 | @Override
57 | public void setLongPress(final boolean longPress) {
58 | this.longPress = longPress;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ButtonToScrollAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
23 | import de.bwravencl.controllerbuddy.input.action.gui.LongPressEditorBuilder;
24 |
25 | @Action(label = "TO_SCROLL_ACTION", category = ActionCategory.BUTTON_AND_CYCLES, order = 130)
26 | public final class ButtonToScrollAction extends ToScrollAction implements IButtonToAction {
27 |
28 | @ActionProperty(label = "LONG_PRESS", editorBuilder = LongPressEditorBuilder.class, order = 400)
29 | private boolean longPress = DEFAULT_LONG_PRESS;
30 |
31 | @Override
32 | public void doAction(final Input input, final int component, Boolean value) {
33 | value = handleLongPress(input, component, value);
34 |
35 | if (!value) {
36 | remainingD = 0f;
37 |
38 | return;
39 | }
40 |
41 | final var d = clicks * input.getRateMultiplier();
42 | scroll(input, d);
43 | }
44 |
45 | @Override
46 | public boolean isLongPress() {
47 | return longPress;
48 | }
49 |
50 | @Override
51 | public void setLongPress(final boolean longPress) {
52 | this.longPress = longPress;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ButtonToSelectOnScreenKeyboardKeyAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2018 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.gui.OnScreenKeyboard.Direction;
21 | import de.bwravencl.controllerbuddy.input.Input;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
23 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
24 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
25 | import de.bwravencl.controllerbuddy.input.action.gui.DirectionEditorBuilder;
26 | import de.bwravencl.controllerbuddy.input.action.gui.LongPressEditorBuilder;
27 | import java.text.MessageFormat;
28 | import java.util.Locale;
29 |
30 | @Action(label = "BUTTON_TO_SELECT_ON_SCREEN_KEYBOARD_KEY_ACTION", category = ActionCategory.ON_SCREEN_KEYBOARD_MODE, order = 510)
31 | public final class ButtonToSelectOnScreenKeyboardKeyAction implements IButtonToAction, IResetableAction {
32 |
33 | private static final long ACCELERATION_TIME = 300L;
34 |
35 | private static final long INITIAL_MIN_ELAPSE_TIME = 250L;
36 |
37 | private static final long PEAK_MIN_ELAPSE_TIME = 90L;
38 |
39 | private static final float PEAK_ELAPSE_TIME_REDUCTION = (INITIAL_MIN_ELAPSE_TIME - PEAK_MIN_ELAPSE_TIME)
40 | / (float) ACCELERATION_TIME;
41 |
42 | @ActionProperty(label = "DIRECTION", editorBuilder = DirectionEditorBuilder.class, order = 10)
43 | private Direction direction = Direction.UP;
44 |
45 | private transient long initialPressTime;
46 |
47 | private transient long lastPressTime;
48 |
49 | @ActionProperty(label = "LONG_PRESS", editorBuilder = LongPressEditorBuilder.class, order = 400)
50 | private boolean longPress = DEFAULT_LONG_PRESS;
51 |
52 | @Override
53 | public Object clone() throws CloneNotSupportedException {
54 | return super.clone();
55 | }
56 |
57 | @Override
58 | public void doAction(final Input input, final int component, Boolean value) {
59 | value = handleLongPress(input, component, value);
60 |
61 | if (value) {
62 | final var currentTime = System.currentTimeMillis();
63 | if (initialPressTime == 0) {
64 | initialPressTime = currentTime;
65 | }
66 |
67 | final var accelerationFactor = Math.min(currentTime - initialPressTime, ACCELERATION_TIME);
68 | final var minElapseTime = INITIAL_MIN_ELAPSE_TIME
69 | - (long) (accelerationFactor * PEAK_ELAPSE_TIME_REDUCTION);
70 |
71 | if (currentTime - lastPressTime >= minElapseTime) {
72 | input.getMain().getOnScreenKeyboard().moveSelector(direction);
73 | lastPressTime = currentTime;
74 | }
75 | } else {
76 | initialPressTime = 0;
77 | }
78 | }
79 |
80 | @Override
81 | public String getDescription(final Input input) {
82 | return MessageFormat.format(Main.STRINGS.getString("ON_SCREEN_KEYBOARD_KEY_SELECTOR"),
83 | direction.toString().toLowerCase(Locale.ROOT));
84 | }
85 |
86 | public Direction getDirection() {
87 | return direction;
88 | }
89 |
90 | @Override
91 | public boolean isLongPress() {
92 | return longPress;
93 | }
94 |
95 | @Override
96 | public void reset(final Input input) {
97 | initialPressTime = 0L;
98 | lastPressTime = 0L;
99 | }
100 |
101 | public void setDirection(final Direction direction) {
102 | this.direction = direction;
103 | }
104 |
105 | @Override
106 | public void setLongPress(final boolean longPress) {
107 | this.longPress = longPress;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/DescribableAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2020 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
21 | import de.bwravencl.controllerbuddy.input.action.gui.StringEditorBuilder;
22 | import java.lang.constant.Constable;
23 |
24 | public abstract class DescribableAction implements IAction {
25 |
26 | @ActionProperty(label = "DESCRIPTION", editorBuilder = StringEditorBuilder.class, order = 0)
27 | private String description;
28 |
29 | @Override
30 | public Object clone() throws CloneNotSupportedException {
31 | return super.clone();
32 | }
33 |
34 | public String getDescription() {
35 | return description;
36 | }
37 |
38 | @Override
39 | public String getDescription(final Input input) {
40 | if (!isDescriptionEmpty()) {
41 | return description;
42 | }
43 |
44 | return IAction.getDefaultDescription(this);
45 | }
46 |
47 | boolean isDescriptionEmpty() {
48 | return description == null || description.isEmpty();
49 | }
50 |
51 | public void setDescription(final String description) {
52 | this.description = description;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/IAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
22 | import java.lang.constant.Constable;
23 |
24 | public interface IAction extends Cloneable {
25 |
26 | static String getDefaultDescription(final IAction> action) {
27 | return getLabel(action.getClass());
28 | }
29 |
30 | static String getLabel(final Class> actionClass) {
31 | final var annotation = actionClass.getAnnotation(Action.class);
32 | if (annotation == null) {
33 | throw new RuntimeException(
34 | actionClass.getName() + ": missing " + Action.class.getSimpleName() + " annotation");
35 | }
36 |
37 | return Main.STRINGS.getString(annotation.label());
38 | }
39 |
40 | Object clone() throws CloneNotSupportedException;
41 |
42 | void doAction(final Input input, int component, V value);
43 |
44 | String getDescription(final Input input);
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/IActivatableAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2020 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import java.lang.constant.Constable;
22 |
23 | public interface IActivatableAction extends IInitializationAction {
24 |
25 | Activatable getActivatable();
26 |
27 | Activation getActivation();
28 |
29 | @Override
30 | default void init(final Input input) {
31 | setActivatable(getActivation() == Activation.SINGLE_ON_RELEASE ? Activatable.NO : Activatable.YES);
32 | }
33 |
34 | void setActivatable(final Activatable activatable);
35 |
36 | void setActivation(final Activation activation);
37 |
38 | enum Activatable {
39 | YES, NO, DENIED_BY_OTHER_ACTION, ALWAYS
40 | }
41 |
42 | enum Activation {
43 |
44 | REPEAT("ACTIVATION_REPEAT"), SINGLE_IMMEDIATELY("ACTIVATION_SINGLE_IMMEDIATELY"),
45 | SINGLE_ON_RELEASE("ACTIVATION_SINGLE_ON_RELEASE");
46 |
47 | private final String label;
48 |
49 | Activation(final String labelKey) {
50 | label = Main.STRINGS.getString(labelKey);
51 | }
52 |
53 | @Override
54 | public String toString() {
55 | return label;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/IAxisToAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2017 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | public interface IAxisToAction extends IAction {
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/IAxisToLongPressAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2021 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.Mode;
21 | import de.bwravencl.controllerbuddy.input.action.IActivatableAction.Activatable;
22 | import de.bwravencl.controllerbuddy.input.action.IActivatableAction.Activation;
23 | import java.util.HashMap;
24 | import java.util.Map;
25 |
26 | public interface IAxisToLongPressAction extends IAxisToAction, ILongPressAction {
27 |
28 | Map actionToDownSinceMap = new HashMap<>();
29 |
30 | Map, Boolean> actionToMustDenyActivationMap = new HashMap<>();
31 |
32 | private static boolean isOnReleaseAction(final IActivatableAction> action) {
33 | return action.getActivation() == Activation.SINGLE_ON_RELEASE;
34 | }
35 |
36 | static void onModeActivated(final Mode activeMode, final Mode newMode) {
37 | actionToDownSinceMap.keySet().removeIf(action -> {
38 | if (activeMode.getAllActions().contains(action)) {
39 | final var optionalAxisId = activeMode.getAxisToActionsMap().entrySet().stream()
40 | .filter(entry -> entry.getValue().contains(action)).map(Map.Entry::getKey).findFirst();
41 | return optionalAxisId.isPresent() && newMode.getButtonToActionsMap().containsKey(optionalAxisId.get());
42 | }
43 |
44 | return false;
45 | });
46 | }
47 |
48 | static void onModeDeactivated(final Mode activeMode) {
49 | actionToDownSinceMap.keySet().removeIf(action -> activeMode.getAllActions().contains(action));
50 | }
51 |
52 | static void reset() {
53 | actionToDownSinceMap.clear();
54 | actionToMustDenyActivationMap.clear();
55 | }
56 |
57 | float getMaxAxisValue();
58 |
59 | float getMinAxisValue();
60 |
61 | default Float handleLongPress(final Input input, final int component, final Float value) {
62 | if (!isLongPress()) {
63 | return value;
64 | }
65 |
66 | final var currentTime = System.currentTimeMillis();
67 |
68 | if (value >= getMinAxisValue() && value <= getMaxAxisValue()) {
69 | if (!actionToDownSinceMap.containsKey(this)) {
70 | actionToDownSinceMap.put(this, currentTime);
71 | } else if (currentTime - actionToDownSinceMap.get(this) >= MIN_LONG_PRESS_TIME) {
72 | for (final var mode : input.getProfile().getModes()) {
73 | final var actions = mode.getAxisToActionsMap().get(component);
74 |
75 | if (actions != null && actions.contains(this)) {
76 | for (final IAction> action : actions) {
77 | if (action == this) {
78 | continue;
79 | }
80 |
81 | var isUndelayedOnReleaseAction = actionToMustDenyActivationMap.get(action);
82 |
83 | if (isUndelayedOnReleaseAction == null) {
84 | isUndelayedOnReleaseAction = false;
85 |
86 | if (action instanceof final AxisToKeyAction axisToKeyAction) {
87 | if (!axisToKeyAction.isLongPress()) {
88 | isUndelayedOnReleaseAction = isOnReleaseAction(axisToKeyAction);
89 | }
90 | } else if (action instanceof final AxisToMouseButtonAction axisToMouseButtonAction) {
91 | if (!axisToMouseButtonAction.isLongPress()) {
92 | isUndelayedOnReleaseAction = isOnReleaseAction(axisToMouseButtonAction);
93 | }
94 | }
95 |
96 | actionToMustDenyActivationMap.put(action, isUndelayedOnReleaseAction);
97 | }
98 |
99 | if (isUndelayedOnReleaseAction) {
100 | ((IActivatableAction>) action).setActivatable(Activatable.DENIED_BY_OTHER_ACTION);
101 | }
102 | }
103 |
104 | break;
105 | }
106 | }
107 |
108 | return value;
109 | }
110 | } else {
111 | actionToDownSinceMap.remove(this);
112 | }
113 |
114 | return Float.MIN_VALUE;
115 | }
116 |
117 | void setMaxAxisValue(final float maxAxisValue);
118 |
119 | void setMinAxisValue(final float minAxisValue);
120 | }
121 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/IButtonToAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2015 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.Mode;
21 | import de.bwravencl.controllerbuddy.input.action.IActivatableAction.Activatable;
22 | import de.bwravencl.controllerbuddy.input.action.IActivatableAction.Activation;
23 | import java.util.HashMap;
24 | import java.util.Map;
25 |
26 | public interface IButtonToAction extends ILongPressAction {
27 |
28 | Map actionToDownSinceMap = new HashMap<>();
29 |
30 | Map, Boolean> actionToMustDenyActivationMap = new HashMap<>();
31 |
32 | private static boolean isOnReleaseAction(final IActivatableAction> action) {
33 | return action.getActivation() == Activation.SINGLE_ON_RELEASE;
34 | }
35 |
36 | static void onModeActivated(final Mode activeMode, final Mode newMode) {
37 | actionToDownSinceMap.keySet().removeIf(action -> {
38 | if (activeMode.getAllActions().contains(action)) {
39 | final var optionalButtonId = activeMode.getButtonToActionsMap().entrySet().stream()
40 | .filter(entry -> entry.getValue().contains(action)).map(Map.Entry::getKey).findFirst();
41 | return optionalButtonId.isPresent()
42 | && newMode.getButtonToActionsMap().containsKey(optionalButtonId.get());
43 | }
44 |
45 | return false;
46 | });
47 | }
48 |
49 | static void onModeDeactivated(final Mode activeMode) {
50 | actionToDownSinceMap.keySet().removeIf(action -> activeMode.getAllActions().contains(action));
51 | }
52 |
53 | static void reset() {
54 | actionToDownSinceMap.clear();
55 | actionToMustDenyActivationMap.clear();
56 | }
57 |
58 | default boolean handleLongPress(final Input input, final int component, final boolean value) {
59 | if (!isLongPress()) {
60 | return value;
61 | }
62 |
63 | final var currentTime = System.currentTimeMillis();
64 |
65 | if (value) {
66 | if (!actionToDownSinceMap.containsKey(this)) {
67 | actionToDownSinceMap.put(this, currentTime);
68 | } else if (currentTime - actionToDownSinceMap.get(this) >= MIN_LONG_PRESS_TIME) {
69 | for (final var mode : input.getProfile().getModes()) {
70 | final var actions = mode.getButtonToActionsMap().get(component);
71 |
72 | if (actions != null && actions.contains(this)) {
73 | for (final IAction> action : actions) {
74 | if (action == this) {
75 | continue;
76 | }
77 |
78 | var isUndelayedOnReleaseAction = actionToMustDenyActivationMap.get(action);
79 |
80 | if (isUndelayedOnReleaseAction == null) {
81 | isUndelayedOnReleaseAction = false;
82 |
83 | if (action instanceof final ButtonToKeyAction buttonToKeyAction) {
84 | if (!buttonToKeyAction.isLongPress()) {
85 | isUndelayedOnReleaseAction = isOnReleaseAction(buttonToKeyAction);
86 | }
87 | } else if (action instanceof final ButtonToMouseButtonAction buttonToMouseButtonAction) {
88 | if (!buttonToMouseButtonAction.isLongPress()) {
89 | isUndelayedOnReleaseAction = isOnReleaseAction(buttonToMouseButtonAction);
90 | }
91 | } else if (action instanceof final ButtonToCycleAction buttonToCycleAction) {
92 | if (!buttonToCycleAction.isLongPress()) {
93 | isUndelayedOnReleaseAction = true;
94 | }
95 | }
96 |
97 | actionToMustDenyActivationMap.put(action, isUndelayedOnReleaseAction);
98 | }
99 |
100 | if (isUndelayedOnReleaseAction) {
101 | ((IActivatableAction>) action).setActivatable(Activatable.DENIED_BY_OTHER_ACTION);
102 | }
103 | }
104 |
105 | break;
106 | }
107 | }
108 |
109 | return true;
110 | }
111 | } else {
112 | actionToDownSinceMap.remove(this);
113 | }
114 |
115 | return false;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/IInitializationAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2017 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import java.lang.constant.Constable;
21 |
22 | public interface IInitializationAction extends IAction {
23 |
24 | void init(final Input input);
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ILongPressAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2017 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import java.lang.constant.Constable;
20 |
21 | public interface ILongPressAction extends IAction {
22 |
23 | boolean DEFAULT_LONG_PRESS = false;
24 |
25 | long MIN_LONG_PRESS_TIME = 1000L;
26 |
27 | boolean isLongPress();
28 |
29 | void setLongPress(final boolean longPress);
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/IResetableAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2017 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import java.lang.constant.Constable;
21 |
22 | public interface IResetableAction extends IAction {
23 |
24 | void reset(final Input input);
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/InvertableAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
20 | import de.bwravencl.controllerbuddy.input.action.gui.BooleanEditorBuilder;
21 | import java.lang.constant.Constable;
22 |
23 | abstract class InvertableAction extends DescribableAction {
24 |
25 | @ActionProperty(label = "INVERT", editorBuilder = BooleanEditorBuilder.class, order = 500)
26 | boolean invert;
27 |
28 | public boolean isInvert() {
29 | return invert;
30 | }
31 |
32 | public void setInvert(final boolean invert) {
33 | this.invert = invert;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/NullAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.input.Input;
20 | import de.bwravencl.controllerbuddy.input.action.annotation.Action;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.Action.ActionCategory;
22 | import java.lang.constant.Constable;
23 |
24 | @Action(label = "NULL_ACTION", category = ActionCategory.ALL, order = 999)
25 | public final class NullAction implements IAction {
26 |
27 | @Override
28 | public Object clone() throws CloneNotSupportedException {
29 | return super.clone();
30 | }
31 |
32 | @Override
33 | public void doAction(final Input input, final int component, final Constable value) {
34 | }
35 |
36 | @Override
37 | public String getDescription(final Input input) {
38 | return IAction.getDefaultDescription(this);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ToAxisAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.Input.VirtualAxis;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
23 | import de.bwravencl.controllerbuddy.input.action.gui.VirtualAxisEditorBuilder;
24 | import java.lang.constant.Constable;
25 | import java.text.MessageFormat;
26 |
27 | abstract class ToAxisAction extends InvertableAction {
28 |
29 | @ActionProperty(label = "VIRTUAL_AXIS", editorBuilder = VirtualAxisEditorBuilder.class, order = 10)
30 | VirtualAxis virtualAxis = VirtualAxis.X;
31 |
32 | @Override
33 | public String getDescription(final Input input) {
34 | if (!isDescriptionEmpty()) {
35 | return super.getDescription(input);
36 | }
37 |
38 | return MessageFormat.format(Main.STRINGS.getString("JOYSTICK_AXIS_NAME"), virtualAxis);
39 | }
40 |
41 | public VirtualAxis getVirtualAxis() {
42 | return virtualAxis;
43 | }
44 |
45 | public void setVirtualAxis(final VirtualAxis virtualAxis) {
46 | this.virtualAxis = virtualAxis;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ToButtonAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
22 | import de.bwravencl.controllerbuddy.input.action.gui.ButtonEditorBuilder;
23 | import java.lang.constant.Constable;
24 | import java.text.MessageFormat;
25 |
26 | public abstract class ToButtonAction extends ActivationIntervalAction {
27 |
28 | @ActionProperty(label = "BUTTON_ID", editorBuilder = ButtonEditorBuilder.class, order = 10)
29 | int buttonId;
30 |
31 | public int getButtonId() {
32 | return buttonId;
33 | }
34 |
35 | @Override
36 | public String getDescription(final Input input) {
37 | if (!isDescriptionEmpty()) {
38 | return super.getDescription(input);
39 | }
40 |
41 | return MessageFormat.format(Main.STRINGS.getString("JOYSTICK_BUTTON_NO"), buttonId + 1);
42 | }
43 |
44 | final boolean isAlreadyPressed(final Input input) {
45 | final var buttons = input.getButtons();
46 | return buttonId < buttons.length && buttons[buttonId];
47 | }
48 |
49 | public void setButtonId(final int buttonId) {
50 | this.buttonId = buttonId;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ToCursorAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2020 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
22 | import de.bwravencl.controllerbuddy.input.action.gui.CursorSensitivityEditorBuilder;
23 | import de.bwravencl.controllerbuddy.input.action.gui.MouseAxisEditorBuilder;
24 | import java.lang.constant.Constable;
25 | import java.text.MessageFormat;
26 |
27 | public abstract class ToCursorAction extends InvertableAction {
28 |
29 | private static final int DEFAULT_CURSOR_SENSITIVITY = 2000;
30 |
31 | @ActionProperty(label = "CURSOR_SENSITIVITY", editorBuilder = CursorSensitivityEditorBuilder.class, order = 11)
32 | int cursorSensitivity = DEFAULT_CURSOR_SENSITIVITY;
33 |
34 | transient float remainingD;
35 |
36 | @ActionProperty(label = "MOUSE_AXIS", editorBuilder = MouseAxisEditorBuilder.class, order = 10)
37 | private MouseAxis axis = MouseAxis.X;
38 |
39 | public MouseAxis getAxis() {
40 | return axis;
41 | }
42 |
43 | public int getCursorSensitivity() {
44 | return cursorSensitivity;
45 | }
46 |
47 | @Override
48 | public String getDescription(final Input input) {
49 | if (!isDescriptionEmpty()) {
50 | return super.getDescription(input);
51 | }
52 |
53 | return MessageFormat.format(Main.STRINGS.getString("MOUSE_AXIS_DIR"), axis.toString());
54 | }
55 |
56 | void moveCursor(final Input input, float d) {
57 | d = invert ? -d : d;
58 | d += remainingD;
59 |
60 | final var roundedD = Math.round(d);
61 | if (roundedD == 0) {
62 | remainingD = d;
63 | return;
64 | }
65 |
66 | if (axis == MouseAxis.X) {
67 | input.setCursorDeltaX(input.getCursorDeltaX() + roundedD);
68 | } else {
69 | input.setCursorDeltaY(input.getCursorDeltaY() + roundedD);
70 | }
71 |
72 | remainingD = d - roundedD;
73 | }
74 |
75 | public void setAxis(final MouseAxis axis) {
76 | this.axis = axis;
77 | }
78 |
79 | public void setCursorSensitivity(final int cursorSensitivity) {
80 | this.cursorSensitivity = cursorSensitivity;
81 | }
82 |
83 | public enum MouseAxis {
84 |
85 | X("MOUSE_AXIS_X"), Y("MOUSE_AXIS_Y");
86 |
87 | private final String label;
88 |
89 | MouseAxis(final String labelKey) {
90 | label = Main.STRINGS.getString(labelKey);
91 | }
92 |
93 | @Override
94 | public String toString() {
95 | return label;
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ToKeyAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.KeyStroke;
22 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
23 | import de.bwravencl.controllerbuddy.input.action.gui.ActivationEditorBuilder;
24 | import de.bwravencl.controllerbuddy.input.action.gui.KeystrokeEditorBuilder;
25 | import de.bwravencl.controllerbuddy.input.action.gui.LongPressEditorBuilder;
26 | import java.lang.constant.Constable;
27 | import java.text.MessageFormat;
28 |
29 | abstract class ToKeyAction extends ActivationIntervalAction
30 | implements IActivatableAction, ILongPressAction, IResetableAction {
31 |
32 | private transient Activatable activatable;
33 |
34 | @ActionProperty(label = "ACTIVATION", editorBuilder = ActivationEditorBuilder.class, order = 11)
35 | private Activation activation = Activation.REPEAT;
36 |
37 | @ActionProperty(label = "KEYSTROKE", editorBuilder = KeystrokeEditorBuilder.class, order = 10)
38 | private KeyStroke keystroke = new KeyStroke();
39 |
40 | @ActionProperty(label = "LONG_PRESS", editorBuilder = LongPressEditorBuilder.class, order = 400)
41 | private boolean longPress = DEFAULT_LONG_PRESS;
42 |
43 | private transient boolean wasDown;
44 |
45 | @Override
46 | public Object clone() throws CloneNotSupportedException {
47 | final var toKeyAction = (ToKeyAction>) super.clone();
48 | toKeyAction.setKeystroke((KeyStroke) keystroke.clone());
49 |
50 | return toKeyAction;
51 | }
52 |
53 | @Override
54 | public Activatable getActivatable() {
55 | return activatable;
56 | }
57 |
58 | @Override
59 | public Activation getActivation() {
60 | return activation;
61 | }
62 |
63 | @Override
64 | public String getDescription(final Input input) {
65 | if (!isDescriptionEmpty()) {
66 | return super.getDescription(input);
67 | }
68 |
69 | return MessageFormat.format(Main.STRINGS.getString("PRESS"), keystroke);
70 | }
71 |
72 | public KeyStroke getKeystroke() {
73 | return keystroke;
74 | }
75 |
76 | void handleAction(boolean hot, final Input input) {
77 | hot = handleActivationInterval(hot);
78 |
79 | if (activatable == Activatable.ALWAYS) {
80 | input.getDownUpKeyStrokes().add(keystroke);
81 | return;
82 | }
83 |
84 | switch (activation) {
85 | case REPEAT -> {
86 | final var downKeyStrokes = input.getDownKeyStrokes();
87 | if (!hot) {
88 | if (wasDown) {
89 | downKeyStrokes.remove(keystroke);
90 | wasDown = false;
91 | }
92 | } else {
93 | downKeyStrokes.add(keystroke);
94 | wasDown = true;
95 | }
96 | }
97 | case SINGLE_IMMEDIATELY -> {
98 | if (!hot) {
99 | activatable = Activatable.YES;
100 | } else if (activatable == Activatable.YES) {
101 | activatable = Activatable.NO;
102 | input.getDownUpKeyStrokes().add(keystroke);
103 | }
104 | }
105 | case SINGLE_ON_RELEASE -> {
106 | if (hot) {
107 | if (activatable == Activatable.NO) {
108 | activatable = Activatable.YES;
109 | } else if (activatable == Activatable.DENIED_BY_OTHER_ACTION) {
110 | activatable = Activatable.NO;
111 | }
112 | } else if (activatable == Activatable.YES) {
113 | activatable = Activatable.NO;
114 | input.getDownUpKeyStrokes().add(keystroke);
115 | }
116 | }
117 | }
118 | }
119 |
120 | @Override
121 | public void init(final Input input) {
122 | super.init(input);
123 | IActivatableAction.super.init(input);
124 | }
125 |
126 | @Override
127 | public boolean isLongPress() {
128 | return longPress;
129 | }
130 |
131 | @Override
132 | public void reset(final Input input) {
133 | wasDown = false;
134 | }
135 |
136 | @Override
137 | public void setActivatable(final Activatable activatable) {
138 | this.activatable = activatable;
139 | }
140 |
141 | @Override
142 | public void setActivation(final Activation activation) {
143 | this.activation = activation;
144 | }
145 |
146 | public void setKeystroke(final KeyStroke keystroke) {
147 | this.keystroke = keystroke;
148 | }
149 |
150 | @Override
151 | public void setLongPress(final boolean longPress) {
152 | this.longPress = longPress;
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ToMouseButtonAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2015 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
22 | import de.bwravencl.controllerbuddy.input.action.gui.ActivationEditorBuilder;
23 | import de.bwravencl.controllerbuddy.input.action.gui.LongPressEditorBuilder;
24 | import de.bwravencl.controllerbuddy.input.action.gui.MouseButtonEditorBuilder;
25 | import java.lang.constant.Constable;
26 | import java.text.MessageFormat;
27 |
28 | abstract class ToMouseButtonAction extends ActivationIntervalAction
29 | implements IActivatableAction, ILongPressAction {
30 |
31 | private static final int DEFAULT_MOUSE_BUTTON = 1;
32 |
33 | private transient Activatable activatable;
34 |
35 | @ActionProperty(label = "ACTIVATION", editorBuilder = ActivationEditorBuilder.class, order = 11)
36 | private Activation activation = Activation.REPEAT;
37 |
38 | private transient boolean initiator;
39 |
40 | @ActionProperty(label = "LONG_PRESS", editorBuilder = LongPressEditorBuilder.class, order = 400)
41 | private boolean longPress = DEFAULT_LONG_PRESS;
42 |
43 | @ActionProperty(label = "MOUSE_BUTTON", editorBuilder = MouseButtonEditorBuilder.class, order = 10)
44 | private int mouseButton = DEFAULT_MOUSE_BUTTON;
45 |
46 | @Override
47 | public Activatable getActivatable() {
48 | return activatable;
49 | }
50 |
51 | @Override
52 | public Activation getActivation() {
53 | return activation;
54 | }
55 |
56 | @Override
57 | public String getDescription(final Input input) {
58 | if (!isDescriptionEmpty()) {
59 | return super.getDescription(input);
60 | }
61 |
62 | return MessageFormat.format(Main.STRINGS.getString("MOUSE_BUTTON_NO"), mouseButton);
63 | }
64 |
65 | public int getMouseButton() {
66 | return mouseButton;
67 | }
68 |
69 | void handleAction(boolean hot, final Input input) {
70 | hot = handleActivationInterval(hot);
71 |
72 | if (activatable == Activatable.ALWAYS) {
73 | input.getDownUpMouseButtons().add(mouseButton);
74 | return;
75 | }
76 |
77 | switch (activation) {
78 | case REPEAT -> {
79 | final var downMouseButtons = input.getDownMouseButtons();
80 | if (!hot) {
81 | if (initiator) {
82 | initiator = false;
83 | downMouseButtons.remove(mouseButton);
84 | }
85 | } else {
86 | initiator = true;
87 | downMouseButtons.add(mouseButton);
88 | }
89 | }
90 | case SINGLE_IMMEDIATELY -> {
91 | if (!hot) {
92 | activatable = Activatable.YES;
93 | } else if (activatable == Activatable.YES) {
94 | activatable = Activatable.NO;
95 | input.getDownUpMouseButtons().add(mouseButton);
96 | }
97 | }
98 | case SINGLE_ON_RELEASE -> {
99 | if (hot) {
100 | if (activatable == Activatable.NO) {
101 | activatable = Activatable.YES;
102 | } else if (activatable == Activatable.DENIED_BY_OTHER_ACTION) {
103 | activatable = Activatable.NO;
104 | }
105 | } else if (activatable == Activatable.YES) {
106 | activatable = Activatable.NO;
107 | input.getDownUpMouseButtons().add(mouseButton);
108 | }
109 | }
110 | }
111 | }
112 |
113 | @Override
114 | public void init(final Input input) {
115 | super.init(input);
116 | IActivatableAction.super.init(input);
117 | }
118 |
119 | @Override
120 | public boolean isLongPress() {
121 | return longPress;
122 | }
123 |
124 | @Override
125 | public void setActivatable(final Activatable activatable) {
126 | this.activatable = activatable;
127 | }
128 |
129 | @Override
130 | public void setActivation(final Activation activation) {
131 | this.activation = activation;
132 | }
133 |
134 | @Override
135 | public void setLongPress(final boolean longPress) {
136 | this.longPress = longPress;
137 | }
138 |
139 | public void setMouseButton(final int mouseButton) {
140 | this.mouseButton = mouseButton;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/ToScrollAction.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2014 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action;
18 |
19 | import de.bwravencl.controllerbuddy.gui.Main;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.action.annotation.ActionProperty;
22 | import de.bwravencl.controllerbuddy.input.action.gui.ClicksEditorBuilder;
23 | import java.lang.constant.Constable;
24 | import java.text.MessageFormat;
25 | import java.util.Locale;
26 |
27 | abstract class ToScrollAction extends InvertableAction {
28 |
29 | private static final int DEFAULT_CLICKS = 10;
30 |
31 | @ActionProperty(label = "CLICKS", editorBuilder = ClicksEditorBuilder.class, order = 10)
32 | int clicks = DEFAULT_CLICKS;
33 |
34 | transient float remainingD = 0f;
35 |
36 | public int getClicks() {
37 | return clicks;
38 | }
39 |
40 | @Override
41 | public String getDescription(final Input input) {
42 | if (!isDescriptionEmpty()) {
43 | return super.getDescription(input);
44 | }
45 |
46 | return MessageFormat.format(Main.STRINGS.getString("SCROLL_DIRECTION"),
47 | Main.STRINGS.getString(invert ? "DIRECTION_DOWN" : "DIRECTION_UP").toLowerCase(Locale.ROOT));
48 | }
49 |
50 | void scroll(final Input input, float d) {
51 | d = invert ? -d : d;
52 | d += remainingD;
53 |
54 | final var roundedD = Math.round(d);
55 | if (roundedD == 0) {
56 | remainingD = d;
57 | return;
58 | }
59 |
60 | input.setScrollClicks(roundedD);
61 | remainingD = d - roundedD;
62 | }
63 |
64 | public void setClicks(final int clicks) {
65 | this.clicks = clicks;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/annotation/Action.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.annotation;
18 |
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | @Retention(RetentionPolicy.RUNTIME)
25 | @Target(ElementType.TYPE)
26 | public @interface Action {
27 |
28 | ActionCategory category();
29 |
30 | String label();
31 |
32 | int order();
33 |
34 | enum ActionCategory {
35 | ALL, AXIS, BUTTON, BUTTON_AND_CYCLES, ON_SCREEN_KEYBOARD_MODE
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/annotation/ActionProperty.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.annotation;
18 |
19 | import de.bwravencl.controllerbuddy.input.action.gui.EditorBuilder;
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.RetentionPolicy;
23 | import java.lang.annotation.Target;
24 |
25 | @Retention(RetentionPolicy.RUNTIME)
26 | @Target(ElementType.FIELD)
27 | public @interface ActionProperty {
28 |
29 | Class extends EditorBuilder> editorBuilder();
30 |
31 | String label();
32 |
33 | int order();
34 |
35 | String overrideFieldName() default "";
36 |
37 | Class> overrideFieldType() default Void.class;
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/ActionsEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.gui.Main;
21 | import de.bwravencl.controllerbuddy.input.action.ButtonToCycleAction;
22 | import de.bwravencl.controllerbuddy.input.action.IAction;
23 | import java.awt.event.ActionEvent;
24 | import java.io.Serial;
25 | import java.lang.reflect.InvocationTargetException;
26 | import java.text.MessageFormat;
27 | import javax.swing.AbstractAction;
28 | import javax.swing.JButton;
29 | import javax.swing.JPanel;
30 |
31 | public final class ActionsEditorBuilder extends EditorBuilder {
32 |
33 | public ActionsEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action,
34 | final String fieldName, final Class> fieldType) throws SecurityException, NoSuchMethodException,
35 | IllegalAccessException, IllegalArgumentException, InvocationTargetException {
36 | super(editActionsDialog, action, fieldName, fieldType);
37 | }
38 |
39 | @Override
40 | public void buildEditor(final JPanel parentPanel) {
41 | final var editActionsButton = new JButton(new EditActionsAction());
42 | editActionsButton.setPreferredSize(Main.BUTTON_DIMENSION);
43 | parentPanel.add(editActionsButton);
44 | }
45 |
46 | private final class EditActionsAction extends AbstractAction {
47 |
48 | @Serial
49 | private static final long serialVersionUID = -6538021954760621595L;
50 |
51 | private EditActionsAction() {
52 | putValue(NAME, Main.STRINGS.getString("EDIT_ACTIONS_ACTION_NAME"));
53 | putValue(SHORT_DESCRIPTION, MessageFormat.format(Main.STRINGS.getString("EDIT_ACTIONS_ACTION_DESCRIPTION"),
54 | IAction.getLabel(action.getClass())));
55 | }
56 |
57 | @Override
58 | public void actionPerformed(final ActionEvent e) {
59 | final var editComponentDialog = new EditActionsDialog(editActionsDialog, (ButtonToCycleAction) action);
60 | editComponentDialog.setVisible(true);
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/ActivationEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.input.action.ButtonToCycleAction;
21 | import de.bwravencl.controllerbuddy.input.action.IAction;
22 | import de.bwravencl.controllerbuddy.input.action.IActivatableAction.Activation;
23 | import java.lang.reflect.InvocationTargetException;
24 | import javax.swing.JPanel;
25 |
26 | public final class ActivationEditorBuilder extends ArrayEditorBuilder {
27 |
28 | public ActivationEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action,
29 | final String fieldName, final Class> fieldType) throws SecurityException, NoSuchMethodException,
30 | IllegalAccessException, IllegalArgumentException, InvocationTargetException {
31 | super(editActionsDialog, action, fieldName, fieldType);
32 | }
33 |
34 | @Override
35 | public void buildEditor(final JPanel parentPanel) {
36 | final var cycleEditor = editActionsDialog.isCycleEditor();
37 |
38 | if (cycleEditor) {
39 | initialValue = Activation.SINGLE_IMMEDIATELY;
40 | }
41 |
42 | super.buildEditor(parentPanel);
43 |
44 | if (cycleEditor) {
45 | comboBox.setEnabled(false);
46 | }
47 | }
48 |
49 | @Override
50 | Activation[] getValues() {
51 | if (action instanceof ButtonToCycleAction) {
52 | return new Activation[] { Activation.SINGLE_IMMEDIATELY, Activation.SINGLE_ON_RELEASE };
53 | }
54 |
55 | return Activation.values();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/ActivationIntervalEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2023 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.gui.Main;
21 | import de.bwravencl.controllerbuddy.input.action.IAction;
22 | import java.lang.reflect.InvocationTargetException;
23 | import javax.swing.JPanel;
24 | import javax.swing.JSpinner;
25 | import javax.swing.text.DefaultFormatter;
26 |
27 | public final class ActivationIntervalEditorBuilder extends NumberEditorBuilder {
28 |
29 | public ActivationIntervalEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action,
30 | final String fieldName, final Class> fieldType) throws SecurityException, NoSuchMethodException,
31 | IllegalAccessException, IllegalArgumentException, InvocationTargetException {
32 | super(editActionsDialog, action, fieldName, fieldType);
33 | }
34 |
35 | @Override
36 | public void buildEditor(final JPanel parentPanel) {
37 | super.buildEditor(parentPanel);
38 |
39 | final var editor = new JSpinner.NumberEditor(spinner, "# " + Main.STRINGS.getString("MILLISECOND_SYMBOL"));
40 | spinner.setEditor(editor);
41 | textField = editor.getTextField();
42 | textField.setColumns(6);
43 |
44 | final var formatter = (DefaultFormatter) textField.getFormatter();
45 | formatter.setCommitsOnValidEdit(true);
46 | }
47 |
48 | @Override
49 | Comparable getMaximum() {
50 | return 10_000;
51 | }
52 |
53 | @Override
54 | Comparable getMinimum() {
55 | return 0;
56 | }
57 |
58 | @Override
59 | Number getStepSize() {
60 | return 10;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/ArrayEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.input.action.IAction;
21 | import java.awt.event.ActionEvent;
22 | import java.io.Serial;
23 | import java.lang.reflect.InvocationTargetException;
24 | import java.lang.reflect.Method;
25 | import java.util.Arrays;
26 | import java.util.logging.Level;
27 | import java.util.logging.Logger;
28 | import javax.swing.JComboBox;
29 | import javax.swing.JPanel;
30 |
31 | abstract class ArrayEditorBuilder extends EditorBuilder {
32 |
33 | private static final Logger LOGGER = Logger.getLogger(ArrayEditorBuilder.class.getName());
34 |
35 | JComboBox comboBox;
36 |
37 | ArrayEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action, final String fieldName,
38 | final Class> fieldType) throws SecurityException, NoSuchMethodException, IllegalAccessException,
39 | IllegalArgumentException, InvocationTargetException {
40 | super(editActionsDialog, action, fieldName, fieldType);
41 | }
42 |
43 | @Override
44 | public void buildEditor(final JPanel parentPanel) {
45 | final var values = getValues();
46 |
47 | comboBox = new JComboBox<>(values);
48 | comboBox.setAction(new JComboBoxSetPropertyAction(action, setterMethod));
49 | if (initialValue != null && Arrays.stream(values).noneMatch(initialValue::equals)) {
50 | comboBox.setSelectedItem(null);
51 | } else {
52 | comboBox.setSelectedItem(initialValue);
53 | }
54 |
55 | parentPanel.add(comboBox);
56 | }
57 |
58 | abstract T[] getValues();
59 |
60 | private static final class JComboBoxSetPropertyAction extends PropertySetterAction {
61 |
62 | @Serial
63 | private static final long serialVersionUID = 1938012378184518954L;
64 |
65 | JComboBoxSetPropertyAction(final IAction> action, final Method setterMethod) {
66 | super(action, setterMethod);
67 | }
68 |
69 | @Override
70 | public void actionPerformed(final ActionEvent e) {
71 | try {
72 | setterMethod.invoke(action, ((JComboBox>) e.getSource()).getSelectedItem());
73 | } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
74 | LOGGER.log(Level.SEVERE, e1.getMessage(), e1);
75 | }
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/AxisValueEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.input.action.IAction;
21 | import java.lang.reflect.InvocationTargetException;
22 |
23 | public class AxisValueEditorBuilder extends NumberEditorBuilder {
24 |
25 | public AxisValueEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action,
26 | final String fieldName, final Class> fieldType) throws SecurityException, NoSuchMethodException,
27 | IllegalAccessException, IllegalArgumentException, InvocationTargetException {
28 | super(editActionsDialog, action, fieldName, fieldType);
29 | }
30 |
31 | @Override
32 | Comparable getMaximum() {
33 | return 1f;
34 | }
35 |
36 | @Override
37 | Comparable getMinimum() {
38 | return -1f;
39 | }
40 |
41 | @Override
42 | Number getStepSize() {
43 | return 0.01f;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/BooleanEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.input.action.IAction;
21 | import java.awt.event.ActionEvent;
22 | import java.io.Serial;
23 | import java.lang.reflect.InvocationTargetException;
24 | import java.lang.reflect.Method;
25 | import java.util.logging.Level;
26 | import java.util.logging.Logger;
27 | import javax.swing.JCheckBox;
28 | import javax.swing.JPanel;
29 |
30 | public class BooleanEditorBuilder extends EditorBuilder {
31 |
32 | private static final Logger LOGGER = Logger.getLogger(BooleanEditorBuilder.class.getName());
33 |
34 | JCheckBox checkBox;
35 |
36 | public BooleanEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action,
37 | final String fieldName, final Class> fieldType) throws SecurityException, NoSuchMethodException,
38 | IllegalAccessException, IllegalArgumentException, InvocationTargetException {
39 | super(editActionsDialog, action, fieldName, fieldType);
40 | }
41 |
42 | @Override
43 | public void buildEditor(final JPanel parentPanel) {
44 | checkBox = new JCheckBox(new JCheckBoxSetPropertyAction(action, setterMethod));
45 | checkBox.setSelected((boolean) initialValue);
46 | parentPanel.add(checkBox);
47 | }
48 |
49 | private static final class JCheckBoxSetPropertyAction extends PropertySetterAction {
50 |
51 | @Serial
52 | private static final long serialVersionUID = -33052386834598414L;
53 |
54 | private JCheckBoxSetPropertyAction(final IAction> action, final Method setterMethod) {
55 | super(action, setterMethod);
56 | }
57 |
58 | @Override
59 | public void actionPerformed(final ActionEvent e) {
60 | try {
61 | final var selected = ((JCheckBox) e.getSource()).isSelected();
62 | setterMethod.invoke(action, selected);
63 | } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
64 | LOGGER.log(Level.SEVERE, e1.getMessage(), e1);
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/ButtonEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.action.IAction;
22 | import java.io.Serial;
23 | import java.lang.reflect.InvocationTargetException;
24 | import javax.swing.JFormattedTextField;
25 | import javax.swing.JFormattedTextField.AbstractFormatter;
26 | import javax.swing.JPanel;
27 | import javax.swing.text.DefaultFormatter;
28 | import javax.swing.text.DefaultFormatterFactory;
29 |
30 | public final class ButtonEditorBuilder extends NumberEditorBuilder {
31 |
32 | public ButtonEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action,
33 | final String fieldName, final Class> fieldType) throws SecurityException, NoSuchMethodException,
34 | IllegalAccessException, IllegalArgumentException, InvocationTargetException {
35 | super(editActionsDialog, action, fieldName, fieldType);
36 | }
37 |
38 | @Override
39 | public void buildEditor(final JPanel parentPanel) {
40 | super.buildEditor(parentPanel);
41 |
42 | final var formatterFactory = new ZeroBasedFormatterFactory();
43 | textField.setFormatterFactory(formatterFactory);
44 |
45 | final var formatter = (DefaultFormatter) textField.getFormatter();
46 | formatter.setCommitsOnValidEdit(true);
47 | }
48 |
49 | @Override
50 | Comparable getMaximum() {
51 | return Input.MAX_N_BUTTONS - 1;
52 | }
53 |
54 | @Override
55 | Comparable getMinimum() {
56 | return 0;
57 | }
58 |
59 | @Override
60 | Number getStepSize() {
61 | return 1;
62 | }
63 |
64 | private static final class ZeroBasedFormatter extends DefaultFormatter {
65 |
66 | @Serial
67 | private static final long serialVersionUID = -7229427356426148291L;
68 |
69 | @Override
70 | public Object stringToValue(final String text) {
71 | if (text == null || text.isBlank()) {
72 | return null;
73 | }
74 |
75 | return Integer.parseInt(text) - 1;
76 | }
77 |
78 | @Override
79 | public String valueToString(final Object value) {
80 | return Integer.toString((int) value + 1);
81 | }
82 | }
83 |
84 | private static final class ZeroBasedFormatterFactory extends DefaultFormatterFactory {
85 |
86 | @Serial
87 | private static final long serialVersionUID = -7273246342105584827L;
88 |
89 | @Override
90 | public AbstractFormatter getFormatter(final JFormattedTextField tf) {
91 | return new ZeroBasedFormatter();
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/ClicksEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.input.action.IAction;
21 | import java.lang.reflect.InvocationTargetException;
22 |
23 | public final class ClicksEditorBuilder extends NumberEditorBuilder {
24 |
25 | public ClicksEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action,
26 | final String fieldName, final Class> fieldType) throws SecurityException, NoSuchMethodException,
27 | IllegalAccessException, IllegalArgumentException, InvocationTargetException {
28 | super(editActionsDialog, action, fieldName, fieldType);
29 | }
30 |
31 | @Override
32 | Comparable getMaximum() {
33 | return 1000;
34 | }
35 |
36 | @Override
37 | Comparable getMinimum() {
38 | return 1;
39 | }
40 |
41 | @Override
42 | Number getStepSize() {
43 | return 1;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/CursorSensitivityEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.input.action.IAction;
21 | import java.lang.reflect.InvocationTargetException;
22 |
23 | public final class CursorSensitivityEditorBuilder extends NumberEditorBuilder {
24 |
25 | public CursorSensitivityEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action,
26 | final String fieldName, final Class> fieldType) throws SecurityException, NoSuchMethodException,
27 | IllegalAccessException, IllegalArgumentException, InvocationTargetException {
28 | super(editActionsDialog, action, fieldName, fieldType);
29 | }
30 |
31 | @Override
32 | Comparable getMaximum() {
33 | return 100_000;
34 | }
35 |
36 | @Override
37 | Comparable getMinimum() {
38 | return 1;
39 | }
40 |
41 | @Override
42 | Number getStepSize() {
43 | return 1;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/DeadZoneEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.input.action.IAction;
21 | import java.lang.reflect.InvocationTargetException;
22 |
23 | public final class DeadZoneEditorBuilder extends NumberEditorBuilder {
24 |
25 | public DeadZoneEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action,
26 | final String fieldName, final Class> fieldType) throws SecurityException, NoSuchMethodException,
27 | IllegalAccessException, IllegalArgumentException, InvocationTargetException {
28 | super(editActionsDialog, action, fieldName, fieldType);
29 | }
30 |
31 | @Override
32 | Comparable getMaximum() {
33 | return 1f;
34 | }
35 |
36 | @Override
37 | Comparable getMinimum() {
38 | return 0f;
39 | }
40 |
41 | @Override
42 | Number getStepSize() {
43 | return 0.01f;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/DetentValueEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.input.action.IAction;
21 | import java.awt.event.ActionEvent;
22 | import java.io.Serial;
23 | import java.lang.reflect.InvocationTargetException;
24 | import java.util.logging.Level;
25 | import java.util.logging.Logger;
26 | import javax.swing.AbstractAction;
27 | import javax.swing.JCheckBox;
28 | import javax.swing.JPanel;
29 |
30 | public final class DetentValueEditorBuilder extends NumberEditorBuilder {
31 |
32 | private static final Logger LOGGER = Logger.getLogger(DetentValueEditorBuilder.class.getName());
33 |
34 | public DetentValueEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action,
35 | final String fieldName, final Class> fieldType) throws SecurityException, NoSuchMethodException,
36 | IllegalAccessException, IllegalArgumentException, InvocationTargetException {
37 | super(editActionsDialog, action, fieldName, fieldType);
38 | }
39 |
40 | @Override
41 | public void buildEditor(final JPanel parentPanel) {
42 | final boolean enabled;
43 | if (initialValue == null) {
44 | enabled = false;
45 | initialValue = 0f;
46 | } else {
47 | enabled = true;
48 | }
49 |
50 | super.buildEditor(parentPanel);
51 | spinner.setEnabled(enabled);
52 |
53 | final var checkBox = new JCheckBox(new AbstractAction() {
54 |
55 | @Serial
56 | private static final long serialVersionUID = 3326369393786088402L;
57 |
58 | @Override
59 | public void actionPerformed(final ActionEvent e) {
60 | final var selected = ((JCheckBox) e.getSource()).isSelected();
61 |
62 | spinner.setEnabled(selected);
63 |
64 | final Float value;
65 | if (selected) {
66 | value = roundFloat((Float) spinner.getValue());
67 | } else {
68 | value = null;
69 | }
70 |
71 | try {
72 | setterMethod.invoke(action, value);
73 | } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
74 | LOGGER.log(Level.SEVERE, e1.getMessage(), e1);
75 | }
76 |
77 | spinner.setEnabled(selected);
78 | }
79 | });
80 | checkBox.setSelected(enabled);
81 | parentPanel.add(checkBox, 1);
82 | }
83 |
84 | @Override
85 | Comparable getMaximum() {
86 | return 1f;
87 | }
88 |
89 | @Override
90 | Comparable getMinimum() {
91 | return -1f;
92 | }
93 |
94 | @Override
95 | Number getStepSize() {
96 | return 0.05f;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/DirectionEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.gui.OnScreenKeyboard.Direction;
21 | import de.bwravencl.controllerbuddy.input.action.IAction;
22 | import java.lang.reflect.InvocationTargetException;
23 |
24 | public final class DirectionEditorBuilder extends ArrayEditorBuilder {
25 |
26 | public DirectionEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action,
27 | final String fieldName, final Class> fieldType) throws SecurityException, NoSuchMethodException,
28 | IllegalAccessException, IllegalArgumentException, InvocationTargetException {
29 | super(editActionsDialog, action, fieldName, fieldType);
30 | }
31 |
32 | @Override
33 | Direction[] getValues() {
34 | return Direction.values();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/EditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
20 | import de.bwravencl.controllerbuddy.input.Input;
21 | import de.bwravencl.controllerbuddy.input.Mode;
22 | import de.bwravencl.controllerbuddy.input.action.IAction;
23 | import java.io.NotSerializableException;
24 | import java.io.ObjectInputStream;
25 | import java.io.ObjectOutputStream;
26 | import java.io.Serial;
27 | import java.lang.reflect.InvocationTargetException;
28 | import java.lang.reflect.Method;
29 | import javax.swing.AbstractAction;
30 | import javax.swing.JPanel;
31 |
32 | public abstract class EditorBuilder {
33 |
34 | protected final IAction> action;
35 |
36 | protected final EditActionsDialog editActionsDialog;
37 |
38 | protected final Method setterMethod;
39 |
40 | protected Object initialValue;
41 |
42 | EditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action, final String fieldName,
43 | final Class> fieldType) throws SecurityException, NoSuchMethodException, IllegalAccessException,
44 | IllegalArgumentException, InvocationTargetException {
45 | this.editActionsDialog = editActionsDialog;
46 | this.action = action;
47 |
48 | final var clazz = action.getClass();
49 |
50 | final var fieldNameChars = fieldName.toCharArray();
51 | fieldNameChars[0] = Character.toUpperCase(fieldNameChars[0]);
52 | final var capitalizedFieldName = String.valueOf(fieldNameChars);
53 |
54 | setterMethod = clazz.getMethod("set" + capitalizedFieldName, fieldType);
55 |
56 | final var getterMethodPrefix = fieldType == boolean.class || fieldType == Boolean.class ? "is" : "get";
57 | final var modeProperty = fieldType == Mode.class;
58 |
59 | final var getterParams = modeProperty ? new Class>[] { Input.class } : null;
60 | final var getterMethod = clazz.getMethod(getterMethodPrefix + capitalizedFieldName, getterParams);
61 |
62 | final var getterArgs = modeProperty ? new Object[] { editActionsDialog.getInput() } : null;
63 | initialValue = getterMethod.invoke(action, getterArgs);
64 | }
65 |
66 | public abstract void buildEditor(final JPanel parentPanel);
67 |
68 | abstract static class PropertySetter {
69 |
70 | final IAction> action;
71 |
72 | final Method setterMethod;
73 |
74 | PropertySetter(final IAction> action, final Method setterMethod) {
75 | this.action = action;
76 | this.setterMethod = setterMethod;
77 | }
78 | }
79 |
80 | abstract static class PropertySetterAction extends AbstractAction {
81 |
82 | @Serial
83 | private static final long serialVersionUID = 4141747329971720525L;
84 |
85 | @SuppressWarnings({ "serial", "RedundantSuppression" })
86 | final IAction> action;
87 |
88 | @SuppressWarnings({ "serial", "RedundantSuppression" })
89 | final Method setterMethod;
90 |
91 | PropertySetterAction(final IAction> action, final Method setterMethod) {
92 | this.action = action;
93 | this.setterMethod = setterMethod;
94 | }
95 |
96 | @Serial
97 | private void readObject(final ObjectInputStream ignoredStream) throws NotSerializableException {
98 | throw new NotSerializableException(PropertySetterAction.class.getName());
99 | }
100 |
101 | @Serial
102 | private void writeObject(final ObjectOutputStream ignoredStream) throws NotSerializableException {
103 | throw new NotSerializableException(PropertySetterAction.class.getName());
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/java/de/bwravencl/controllerbuddy/input/action/gui/ExponentEditorBuilder.java:
--------------------------------------------------------------------------------
1 | /* Copyright (C) 2019 Matteo Hausner
2 | *
3 | * This program is free software: you can redistribute it and/or modify
4 | * it under the terms of the GNU General Public License as published by
5 | * the Free Software Foundation, either version 3 of the License, or
6 | * (at your option) any later version.
7 | *
8 | * This program is distributed in the hope that it will be useful,
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | * GNU General Public License for more details.
12 | *
13 | * You should have received a copy of the GNU General Public License
14 | * along with this program. If not, see .
15 | */
16 |
17 | package de.bwravencl.controllerbuddy.input.action.gui;
18 |
19 | import com.formdev.flatlaf.ui.FlatRoundBorder;
20 | import de.bwravencl.controllerbuddy.gui.EditActionsDialog;
21 | import de.bwravencl.controllerbuddy.gui.Main;
22 | import de.bwravencl.controllerbuddy.input.action.IAction;
23 | import java.awt.Color;
24 | import java.awt.Dimension;
25 | import java.awt.Graphics;
26 | import java.io.Serial;
27 | import java.lang.reflect.InvocationTargetException;
28 | import java.util.Arrays;
29 | import java.util.function.Consumer;
30 | import javax.swing.Box;
31 | import javax.swing.JComponent;
32 | import javax.swing.JPanel;
33 | import javax.swing.UIManager;
34 |
35 | public final class ExponentEditorBuilder extends NumberEditorBuilder {
36 |
37 | public ExponentEditorBuilder(final EditActionsDialog editActionsDialog, final IAction> action,
38 | final String fieldName, final Class> fieldType) throws SecurityException, NoSuchMethodException,
39 | IllegalAccessException, IllegalArgumentException, InvocationTargetException {
40 | super(editActionsDialog, action, fieldName, fieldType);
41 | }
42 |
43 | @Override
44 | public void buildEditor(final JPanel parentPanel) {
45 | super.buildEditor(parentPanel);
46 |
47 | parentPanel.add(Box.createHorizontalStrut(Main.DEFAULT_HGAP));
48 |
49 | final var powerFunctionPlotter = new PowerFunctionPlotter((float) initialValue);
50 | parentPanel.add(powerFunctionPlotter);
51 |
52 | Arrays.stream(spinner.getChangeListeners())
53 | .filter(changeListener -> changeListener instanceof JSpinnerSetPropertyChangeListener).findFirst()
54 | .ifPresent(changeListener -> ((JSpinnerSetPropertyChangeListener) changeListener)
55 | .setValueConsumer(powerFunctionPlotter));
56 | }
57 |
58 | @Override
59 | Comparable getMaximum() {
60 | return 10f;
61 | }
62 |
63 | @Override
64 | Comparable getMinimum() {
65 | return 0.1f;
66 | }
67 |
68 | @Override
69 | Number getStepSize() {
70 | return 0.1f;
71 | }
72 |
73 | private static final class PowerFunctionPlotter extends JComponent implements Consumer