From 663bc08d964cb3a7c50230f2902306d3513c345b Mon Sep 17 00:00:00 2001 From: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Date: Sun, 23 Mar 2025 18:43:11 -0400 Subject: [PATCH] Smartfridge/Vending machine layouts auto-update rather than be a setting (#90159) ## About The Pull Request Sorry for my incompetence with TGUI. This comes from a comment I made here https://github.com/tgstation/tgstation/pull/89137#issuecomment-2601185587 & https://github.com/tgstation/tgstation/pull/89160#pullrequestreview-2566047191 Instead of having to go to your game settings, find the option of layout style you want your vending/fridge machines to be, and change it without having a UI to show you the difference, now the preference is tied to the in-game UI; Clicking to swap to the other layout mode will automatically update your prefs and stay until you change it again. I also separated smartfridges and vending machines as 2 separate prefs so players can have grid on one and list on the other. I couldn't figure out a way to implement this without adding a new var on base ``/datum``, if you got other possible solutions I'd be happy to try. I thought of making 'layouts' limited to smartfridge/vending machines, taking it out of backend for all UIs, but thought I should avoid that if possible in case future UIs want to make use of it. If it's better than a var on datum I'm fine taking that path instead. https://github.com/user-attachments/assets/921586fa-1ec1-49c0-87ca-ec4bbb6aaa98 ## Why It's Good For The Game The settings list having these small options that you can't even see the effects of until you find the machine in-game is a little lame, now players don't even have to think about it, they simply set it to the mode they want as they use the machine and it'll update itself for the player. Currently using the button to swap to list/grid mode instantly reverts itself as soon as you close the UI, which is a little lame. ## Changelog :cl: qol: Smartfridges and Vending machines no longer have a setting to change the list/grid mode, it instead updates automatically as you swap the mode in-game. /:cl: --- code/__DEFINES/preferences.dm | 2 -- code/datums/datum.dm | 2 ++ code/modules/client/preferences/tgui.dm | 10 +++++-- .../food_and_drinks/machinery/smartfridge.dm | 6 +--- code/modules/tgui/external.dm | 4 +++ code/modules/tgui/tgui.dm | 2 +- .../features/game_preferences/tgui.tsx | 11 +------ tgui/packages/tgui/interfaces/SmartVend.tsx | 9 +----- .../tgui/interfaces/common/LayoutToggle.tsx | 30 +++++++++---------- 9 files changed, 31 insertions(+), 45 deletions(-) diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 2ee19ad2ed5..8d9e911e9ae 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -80,8 +80,6 @@ #define DEFAULT_CYBORG_NAME "Default Cyborg Name" // Choose grid or list TGUI layouts for UI's, when possible. -/// Default layout will be used. It can be either a grid or a list -#define TGUI_LAYOUT_DEFAULT "default" /// Force grid layout, even if default is a list. #define TGUI_LAYOUT_GRID "grid" /// Force list layout, even if default is a grid. diff --git a/code/datums/datum.dm b/code/datums/datum.dm index c3c800bd85c..0dc21ab494d 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -79,6 +79,8 @@ #ifdef DATUMVAR_DEBUGGING_MODE var/list/cached_vars #endif + ///The layout pref we take from the player looking at this datum's UI to know what layout to give. + var/datum/preference/choiced/layout_prefs_used = /datum/preference/choiced/tgui_layout /** * Called when a href for this datum is clicked diff --git a/code/modules/client/preferences/tgui.dm b/code/modules/client/preferences/tgui.dm index c09bba9740a..94cb68067f8 100644 --- a/code/modules/client/preferences/tgui.dm +++ b/code/modules/client/preferences/tgui.dm @@ -39,25 +39,29 @@ /// Changes layout in some UI's, like Vending, Smartfridge etc. Making it list or grid /datum/preference/choiced/tgui_layout - category = PREFERENCE_CATEGORY_GAME_PREFERENCES savefile_key = "tgui_layout" savefile_identifier = PREFERENCE_PLAYER /datum/preference/choiced/tgui_layout/init_possible_values() return list( - TGUI_LAYOUT_DEFAULT, TGUI_LAYOUT_GRID, TGUI_LAYOUT_LIST, ) /datum/preference/choiced/tgui_layout/create_default_value() - return TGUI_LAYOUT_DEFAULT + return TGUI_LAYOUT_LIST /datum/preference/choiced/tgui_layout/apply_to_client(client/client, value) for (var/datum/tgui/tgui as anything in client.mob?.tgui_open_uis) // Force it to reload either way tgui.update_static_data(client.mob) +/datum/preference/choiced/tgui_layout/smartfridge + savefile_key = "tgui_layout_smartfridge" + +/datum/preference/choiced/tgui_layout/create_default_value() + return TGUI_LAYOUT_GRID + /datum/preference/toggle/tgui_lock category = PREFERENCE_CATEGORY_GAME_PREFERENCES savefile_key = "tgui_lock" diff --git a/code/modules/food_and_drinks/machinery/smartfridge.dm b/code/modules/food_and_drinks/machinery/smartfridge.dm index 4653c744d89..315999f78c8 100644 --- a/code/modules/food_and_drinks/machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/machinery/smartfridge.dm @@ -32,8 +32,7 @@ var/welded_down = FALSE /// The sound of item retrieval var/vend_sound = 'sound/machines/machine_vend.ogg' - /// Whether the UI should be set to list view by default - var/default_list_view = FALSE + layout_prefs_used = /datum/preference/choiced/tgui_layout/smartfridge /obj/machinery/smartfridge/Initialize(mapload) . = ..() @@ -385,7 +384,6 @@ .["contents"] = sort_list(listofitems) .["name"] = name .["isdryer"] = FALSE - .["default_list_view"] = default_list_view /obj/machinery/smartfridge/Exited(atom/movable/gone, direction) // Update the UIs in case something inside is removed . = ..() @@ -729,7 +727,6 @@ desc = "A refrigerated storage unit for medicine storage." base_build_path = /obj/machinery/smartfridge/chemistry contents_overlay_icon = "chem" - default_list_view = TRUE /obj/machinery/smartfridge/chemistry/accept_check(obj/item/weapon) // not an item or reagent container @@ -780,7 +777,6 @@ desc = "A refrigerated storage unit for volatile sample storage." base_build_path = /obj/machinery/smartfridge/chemistry/virology contents_overlay_icon = "viro" - default_list_view = TRUE /obj/machinery/smartfridge/chemistry/virology/preloaded initial_contents = list( diff --git a/code/modules/tgui/external.dm b/code/modules/tgui/external.dm index f9e05f9e95a..5d93ee76541 100644 --- a/code/modules/tgui/external.dm +++ b/code/modules/tgui/external.dm @@ -90,6 +90,10 @@ // If UI is not interactive or usr calling Topic is not the UI user, bail. if(!ui || ui.status != UI_INTERACTIVE) return TRUE + if(action == "change_ui_state") + var/mob/living/user = ui.user + //write_preferences will make sure it's valid for href exploits. + user.client.prefs.write_preference(GLOB.preference_entries[layout_prefs_used], params["new_state"]) /** * public diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index 4a9463aca5c..a4e622c87ea 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -248,7 +248,7 @@ "status" = status, "interface" = list( "name" = interface, - "layout" = user.client.prefs.read_preference(/datum/preference/choiced/tgui_layout), + "layout" = user.client.prefs.read_preference(src_object.layout_prefs_used), ), "refreshing" = refreshing, "window" = list( diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/tgui.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/tgui.tsx index 9e63f7a038b..8b358cd1ed4 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/tgui.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/tgui.tsx @@ -1,5 +1,4 @@ -import { CheckboxInput, Feature, FeatureToggle } from '../base'; -import { FeatureDropdownInput } from '../dropdowns'; +import { CheckboxInput, FeatureToggle } from '../base'; export const tgui_fancy: FeatureToggle = { name: 'Enable fancy TGUI', @@ -29,14 +28,6 @@ export const tgui_input_swapped: FeatureToggle = { component: CheckboxInput, }; -export const tgui_layout: Feature = { - name: 'Default TGUI Layout', - category: 'UI', - description: - 'Applies the selected layout type to all interfaces where it possible. Like on Smartfridge.', - component: FeatureDropdownInput, -}; - export const tgui_lock: FeatureToggle = { name: 'Lock TGUI to main monitor', category: 'UI', diff --git a/tgui/packages/tgui/interfaces/SmartVend.tsx b/tgui/packages/tgui/interfaces/SmartVend.tsx index 4e2e2090bef..698686bb729 100644 --- a/tgui/packages/tgui/interfaces/SmartVend.tsx +++ b/tgui/packages/tgui/interfaces/SmartVend.tsx @@ -28,19 +28,12 @@ type Data = { name: string; isdryer: BooleanLike; drying: BooleanLike; - default_list_view: BooleanLike; }; export const SmartVend = (props) => { const { act, data } = useBackend(); const [searchText, setSearchText] = useState(''); - const [displayMode, setDisplayMode] = useState( - getLayoutState() === LAYOUT.Default - ? data.default_list_view - ? LAYOUT.List - : LAYOUT.Grid - : getLayoutState(), - ); + const [displayMode, setDisplayMode] = useState(getLayoutState()); const search = createSearch(searchText, (item: Item) => item.name); const contents = searchText.length > 0 diff --git a/tgui/packages/tgui/interfaces/common/LayoutToggle.tsx b/tgui/packages/tgui/interfaces/common/LayoutToggle.tsx index f98b56fe1ed..7c16f5d2f8d 100644 --- a/tgui/packages/tgui/interfaces/common/LayoutToggle.tsx +++ b/tgui/packages/tgui/interfaces/common/LayoutToggle.tsx @@ -10,16 +10,12 @@ type Props = { }; export enum LAYOUT { - Default = 'default', Grid = 'grid', List = 'list', } export function getLayoutState(defaultState?: LAYOUT) { const { config } = useBackend(); - if (config.interface.layout === LAYOUT.Default) { - return defaultState || LAYOUT.Default; - } return config.interface.layout; } @@ -29,22 +25,24 @@ export function getLayoutState(defaultState?: LAYOUT) { */ export function LayoutToggle(props: Props) { const { setState, state } = props; + const { act } = useBackend(); const handleClick = () => { const newState = state === LAYOUT.Grid ? LAYOUT.List : LAYOUT.Grid; setState(newState); + act('change_ui_state', { + new_state: newState, + }); }; - if (getLayoutState() === LAYOUT.Default) { - return ( - -