diff --git a/main.py b/main.py
index 2e1b0aa..e8377e0 100644
--- a/main.py
+++ b/main.py
@@ -39,11 +39,15 @@ async def get_settings(self):
async def save_rgb_per_game_profiles_enabled(self, enabled: bool):
return settings.set_setting('rgbPerGameProfilesEnabled', enabled)
- async def save_rgb_settings(self, rgbProfiles):
- return settings.set_all_rgb_profiles(rgbProfiles)
+ async def save_rgb_settings(self, rgbProfiles, currentGameId):
+ result = settings.set_all_rgb_profiles(rgbProfiles)
+ if currentGameId:
+ rgb.sync_rgb_settings(currentGameId)
+ return result
+ # sync state in settings.json to actual controller RGB hardware
async def sync_rgb_settings(self, currentGameId):
- decky_plugin.logger.info(f"sync rgb settings {currentGameId}")
+ # decky_plugin.logger.info(f"sync rgb settings {currentGameId}")
return rgb.sync_rgb_settings(currentGameId)
async def remap_button(self, button: str, action: str):
diff --git a/py_modules/controller_enums.py b/py_modules/controller_enums.py
index 1cf70bf..2407ff6 100644
--- a/py_modules/controller_enums.py
+++ b/py_modules/controller_enums.py
@@ -43,4 +43,9 @@ class RemapActions(Enum):
R_TRIGGER = 0x19
VIEW = 0x23
- MENU = 0x24
\ No newline at end of file
+ MENU = 0x24
+
+class RgbModes(Enum):
+ SOLID = 0x01
+ DYNAMIC = 0x03
+ BLINKING = 0x02
\ No newline at end of file
diff --git a/py_modules/rgb.py b/py_modules/rgb.py
index e1f83e7..5b1be26 100644
--- a/py_modules/rgb.py
+++ b/py_modules/rgb.py
@@ -10,6 +10,7 @@ def sync_rgb_settings(current_game_id):
rgb_profile = s.get('rgb').get(current_game_id)
for controller in ['LEFT', 'RIGHT']:
rgb_light = rgb_profile.get(controller)
+ rgb_mode = rgb_light.get('mode')
if rgb_light.get('enabled'):
rgb_on(current_game_id, controller)
@@ -17,6 +18,7 @@ def sync_rgb_settings(current_game_id):
rgb_color(
current_game_id,
controller,
+ rgb_mode,
rgb_light.get('red'),
rgb_light.get('blue'),
rgb_light.get('green'),
@@ -38,10 +40,12 @@ def rgb_off(current_game_id, controller: str):
legion_configurator.send_command(rgb_off_command)
-def rgb_color(current_game_id, controller: str, red, blue, green, brightness):
+def rgb_color(current_game_id, controller: str, mode: str, red, blue, green, brightness):
hex_brightness = int(brightness)
color = bytes([red, green, blue])
controller_code = controller_enums.Controller[controller].value
- rgb = legion_configurator.create_rgb_control_command(controller_code,0x01,color, hex_brightness, 0x01)
+ rgb_mode_code = controller_enums.RgbModes[mode].value or controller_enums.RgbModes['SOLID'].value
+
+ rgb = legion_configurator.create_rgb_control_command(controller_code, rgb_mode_code, color, hex_brightness, 0x01)
# decky_plugin.logger.info(list(rgb))
legion_configurator.send_command(rgb)
\ No newline at end of file
diff --git a/src/backend/constants.tsx b/src/backend/constants.tsx
index c0a2d98..00992ad 100644
--- a/src/backend/constants.tsx
+++ b/src/backend/constants.tsx
@@ -40,3 +40,9 @@ export enum RemapActions {
VIEW = 'VIEW',
MENU = 'MENU'
}
+
+export enum RgbModes {
+ SOLID = 'SOLID',
+ DYNAMIC = 'DYNAMIC',
+ BLINKING = 'BLINKING'
+}
diff --git a/src/components/ControllerLightingPanel.tsx b/src/components/ControllerLightingPanel.tsx
index d196a8f..0277d28 100644
--- a/src/components/ControllerLightingPanel.tsx
+++ b/src/components/ControllerLightingPanel.tsx
@@ -10,8 +10,11 @@ import { useState } from 'react';
import {
useRgb,
usePerGameRgbProfilesEnabled,
- useRgbProfileDisplayName
+ useRgbProfileDisplayName,
+ useRgbMode
} from '../hooks/rgb';
+import RgbModeDropdown from './RgbModeDropdown';
+import { RgbModes } from '../backend/constants';
const DEFAULT_STATE = {
isTouchpad: true
};
@@ -19,6 +22,9 @@ const DEFAULT_STATE = {
const ControllerLightingPanel: VFC<{ serverAPI: ServerAPI }> = ({
serverAPI
}) => {
+ const [leftMode] = useRgbMode('LEFT');
+ const [rightMode] = useRgbMode('RIGHT');
+
const [perGameProfilesEnabled, setPerGameProfilesEnabled] =
usePerGameRgbProfilesEnabled();
const displayName = useRgbProfileDisplayName();
@@ -89,6 +95,7 @@ const ControllerLightingPanel: VFC<{ serverAPI: ServerAPI }> = ({
)}
{showRightOptions && isRightRgbOn && (
<>
+
= ({
validValues="range"
onChange={(value) => setRightLedBrightness(value)}
>
- <>
- {
- setRightColor('red', value);
- }}
- />
- {
- setRightColor('green', value);
- }}
- />
- {
- setRightColor('blue', value);
- }}
- />
-
- >
+ {rightMode !== RgbModes.DYNAMIC && (
+ <>
+ {
+ setRightColor('red', value);
+ }}
+ />
+ {
+ setRightColor('green', value);
+ }}
+ />
+ {
+ setRightColor('blue', value);
+ }}
+ />
+
+ >
+ )}
>
)}
@@ -162,6 +171,7 @@ const ControllerLightingPanel: VFC<{ serverAPI: ServerAPI }> = ({
)}
{showLeftOptions && isLeftRgbOn && (
<>
+
= ({
validValues="range"
onChange={(value) => setLeftLedBrightness(value)}
>
- <>
- {
- setLeftColor('red', value);
- }}
- />
- {
- setLeftColor('green', value);
- }}
- />
- {
- setLeftColor('blue', value);
- }}
- />
-
- >
+ {leftMode !== RgbModes.DYNAMIC && (
+ <>
+ {
+ setLeftColor('red', value);
+ }}
+ />
+ {
+ setLeftColor('green', value);
+ }}
+ />
+ {
+ setLeftColor('blue', value);
+ }}
+ />
+
+ >
+ )}
>
)}
diff --git a/src/components/RgbModeDropdown.tsx b/src/components/RgbModeDropdown.tsx
new file mode 100644
index 0000000..7598c3f
--- /dev/null
+++ b/src/components/RgbModeDropdown.tsx
@@ -0,0 +1,46 @@
+import { FC } from 'react';
+import { DropdownItem } from 'decky-frontend-lib';
+import { ControllerType, RgbModes } from '../backend/constants';
+import { useRgbMode } from '../hooks/rgb';
+
+type PropType = {
+ controller: ControllerType;
+};
+
+const RgbModeDropdown: FC = ({ controller }) => {
+ const [mode, setMode] = useRgbMode(controller);
+
+ const dropdownOptions = Object.values(RgbModes).map((action) => {
+ return {
+ data: action,
+ label: `${action}`,
+ value: action
+ };
+ });
+
+ return (
+ <>
+ {
+ return {
+ data: o.data,
+ label: o.label,
+ value: o.value
+ };
+ })}
+ selectedOption={
+ dropdownOptions.find((o) => {
+ return o.data === mode;
+ })?.data
+ }
+ onChange={(value: any) => {
+ setMode(value.data);
+ }}
+ />
+ >
+ );
+};
+
+export default RgbModeDropdown;
diff --git a/src/hooks/rgb.tsx b/src/hooks/rgb.tsx
index bbd0ee2..36e9f51 100644
--- a/src/hooks/rgb.tsx
+++ b/src/hooks/rgb.tsx
@@ -1,11 +1,12 @@
import { useDispatch, useSelector } from 'react-redux';
import { useCallback } from 'react';
-import { ControllerType } from '../backend/constants';
+import { ControllerType, RgbModes } from '../backend/constants';
import {
rgbSlice,
selectRgbInfo,
selectRgbProfileDisplayName,
- selectPerGameProfilesEnabled
+ selectPerGameProfilesEnabled,
+ selectRgbMode
} from '../redux-modules/rgbSlice';
export enum Colors {
@@ -14,6 +15,20 @@ export enum Colors {
BLUE = 'blue'
}
+export const useRgbMode = (controller: ControllerType) => {
+ const mode = useSelector(selectRgbMode(controller));
+ const dispatch = useDispatch();
+
+ const setMode = useCallback(
+ (mode: RgbModes) => {
+ return dispatch(rgbSlice.actions.setRgbMode({ controller, mode }));
+ },
+ [controller]
+ );
+
+ return [mode, setMode] as any;
+};
+
export const usePerGameRgbProfilesEnabled = () => {
const isEnabled = useSelector(selectPerGameProfilesEnabled);
const dispatch = useDispatch();
diff --git a/src/redux-modules/rgbSlice.tsx b/src/redux-modules/rgbSlice.tsx
index 47fab80..8131a0e 100644
--- a/src/redux-modules/rgbSlice.tsx
+++ b/src/redux-modules/rgbSlice.tsx
@@ -4,11 +4,12 @@ import { get, merge } from 'lodash';
import type { RootState } from './store';
import { setCurrentGameId, setInitialState } from './extraActions';
import { extractCurrentGameId, getServerApi } from '../backend/utils';
-import { ControllerType } from '../backend/constants';
+import { ControllerType, RgbModes } from '../backend/constants';
import { Router } from 'decky-frontend-lib';
-const DEFAULT_RGB_LIGHT_VALUES = {
+const DEFAULT_RGB_LIGHT_VALUES: RgbLight = {
enabled: false,
+ mode: RgbModes.SOLID,
red: 255,
green: 255,
blue: 255,
@@ -23,6 +24,7 @@ enum Colors {
type RgbLight = {
enabled: boolean;
+ mode: RgbModes;
red: number;
green: number;
blue: number;
@@ -77,6 +79,18 @@ export const rgbSlice = createSlice({
bootstrapRgbProfile(state, extractCurrentGameId());
}
},
+ setRgbMode: (
+ state,
+ action: PayloadAction<{ controller: string; mode: RgbModes }>
+ ) => {
+ const { controller, mode } = action.payload;
+ if (state.perGameProfilesEnabled) {
+ const currentGameId = extractCurrentGameId();
+ state.rgbProfiles[currentGameId][controller]['mode'] = mode;
+ } else {
+ state.rgbProfiles['default'][controller]['mode'] = mode;
+ }
+ },
updateRgbProfiles: (state, action: PayloadAction) => {
merge(state.rgbProfiles, action.payload);
},
@@ -165,6 +179,19 @@ export const selectRgbInfo =
return rgbInfo;
};
+export const selectRgbMode =
+ (controller: ControllerType) => (state: RootState) => {
+ const currentGameId = extractCurrentGameId();
+ let rgbMode;
+ if (state.rgb.perGameProfilesEnabled) {
+ rgbMode = state.rgb.rgbProfiles[currentGameId][controller].mode;
+ } else {
+ rgbMode = state.rgb.rgbProfiles['default'][controller].mode;
+ }
+
+ return rgbMode;
+ };
+
export const selectPerGameProfilesEnabled = (state: RootState) => {
return state.rgb.perGameProfilesEnabled;
};
@@ -185,7 +212,8 @@ const mutatingActionTypes = [
rgbSlice.actions.updateRgbProfiles.type,
rgbSlice.actions.setColor.type,
rgbSlice.actions.setEnabled.type,
- rgbSlice.actions.setPerGameProfilesEnabled,
+ rgbSlice.actions.setPerGameProfilesEnabled.type,
+ rgbSlice.actions.setRgbMode.type,
rgbSlice.actions.setBrightness.type
];
@@ -199,25 +227,16 @@ export const saveRgbSettingsMiddleware =
if (mutatingActionTypes.includes(type)) {
// get latest state from store
const {
- rgb: { rgbProfiles }
+ rgb: { rgbProfiles, perGameProfilesEnabled }
} = store.getState();
+ const currentGameId = perGameProfilesEnabled
+ ? extractCurrentGameId()
+ : 'default';
- serverApi
- ?.callPluginMethod('save_rgb_settings', { rgbProfiles })
- .then((res) => {
- const {
- rgb: { perGameProfilesEnabled }
- } = store.getState();
-
- const currentGameId = perGameProfilesEnabled
- ? extractCurrentGameId()
- : 'default';
-
- if (res.success) {
- // since RGB settings changed, update state of RBG lights
- serverApi.callPluginMethod('sync_rgb_settings', { currentGameId });
- }
- });
+ serverApi?.callPluginMethod('save_rgb_settings', {
+ rgbProfiles,
+ currentGameId
+ });
}
if (type === setInitialState.type || type === setCurrentGameId.type) {
// tell backend to sync LEDs to current FE state