Standardize and improve status display UI's (#68976)

* Standardized and improves status display app, making it share the same UI as the Communication Console's version of it, and moves shared status display screens into global lists instead of vars.

Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
This commit is contained in:
Tastyfish
2022-08-29 22:58:23 -04:00
committed by GitHub
co-authored by John Willard
parent d0c73f8406
commit 7eef1a5547
7 changed files with 191 additions and 160 deletions
+16
View File
@@ -359,3 +359,19 @@ GLOBAL_LIST_INIT(admiral_messages, list(
))
GLOBAL_LIST_INIT(junkmail_messages, world.file2list("strings/junkmail.txt"))
// All valid inputs to status display post_status
GLOBAL_LIST_INIT(status_display_approved_pictures, list(
"blank",
"shuttle",
"default",
"biohazard",
"lockdown",
"redalert",
))
// Members of status_display_approved_pictures that are actually states and not alert values
GLOBAL_LIST_INIT(status_display_state_pictures, list(
"blank",
"shuttle",
))
+8 -11
View File
@@ -140,8 +140,6 @@
/obj/machinery/computer/communications/ui_act(action, list/params)
var/static/list/approved_states = list(STATE_BUYING_SHUTTLE, STATE_CHANGING_STATUS, STATE_MAIN, STATE_MESSAGES)
var/static/list/approved_status_pictures = list("biohazard", "blank", "default", "lockdown", "redalert", "shuttle")
var/static/list/state_status_pictures = list("blank", "shuttle")
. = ..()
if (.)
@@ -355,9 +353,8 @@
if ("setStatusMessage")
if (!authenticated(usr))
return
var/line_one = reject_bad_text(params["lineOne"] || "", MAX_STATUS_LINE_LENGTH)
var/line_two = reject_bad_text(params["lineTwo"] || "", MAX_STATUS_LINE_LENGTH)
post_status("alert", "blank")
var/line_one = reject_bad_text(params["upperText"] || "", MAX_STATUS_LINE_LENGTH)
var/line_two = reject_bad_text(params["lowerText"] || "", MAX_STATUS_LINE_LENGTH)
post_status("message", line_one, line_two)
last_status_display = list(line_one, line_two)
playsound(src, SFX_TERMINAL_TYPE, 50, FALSE)
@@ -365,9 +362,9 @@
if (!authenticated(usr))
return
var/picture = params["picture"]
if (!(picture in approved_status_pictures))
if (!(picture in GLOB.status_display_approved_pictures))
return
if(picture in state_status_pictures)
if(picture in GLOB.status_display_state_pictures)
post_status(picture)
else
post_status("alert", picture)
@@ -596,8 +593,8 @@
data["budget"] = bank_account.account_balance
data["shuttles"] = shuttles
if (STATE_CHANGING_STATUS)
data["lineOne"] = last_status_display ? last_status_display[1] : ""
data["lineTwo"] = last_status_display ? last_status_display[2] : ""
data["upperText"] = last_status_display ? last_status_display[1] : ""
data["lowerText"] = last_status_display ? last_status_display[2] : ""
return data
@@ -744,8 +741,8 @@
var/datum/signal/status_signal = new(list("command" = command))
switch(command)
if("message")
status_signal.data["msg1"] = data1
status_signal.data["msg2"] = data2
status_signal.data["top_text"] = data1
status_signal.data["bottom_text"] = data2
if("alert")
status_signal.data["picture_state"] = data1
+3 -3
View File
@@ -380,7 +380,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/evac, 32)
set_messages("", "")
if("message")
current_mode = SD_MESSAGE
set_messages(signal.data["msg1"] || "", signal.data["msg2"] || "")
set_messages(signal.data["top_text"] || "", signal.data["bottom_text"] || "")
if("alert")
current_mode = SD_PICTURE
last_picture = signal.data["picture_state"]
@@ -584,8 +584,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/ai, 32)
var/datum/signal/status_signal = new(list("command" = command_value))
switch(command_value)
if("message")
status_signal.data["msg1"] = message1.value
status_signal.data["msg2"] = message2.value
status_signal.data["top_text"] = message1.value
status_signal.data["bottom_text"] = message2.value
if("alert")
status_signal.data["picture_state"] = picture_map[picture.value]
@@ -12,28 +12,52 @@
usage_flags = PROGRAM_ALL
available_on_ntnet = FALSE
var/upper_text
var/lower_text
var/upper_text = ""
var/lower_text = ""
/datum/computer_file/program/status/proc/SendSignal()
/**
* Post status display radio packet.
* Arguments:
* * command - the status display command
* * data1 - the data1 value, as defined by status displays
* * data2 - the data2 value, as defined by status displays
*/
/datum/computer_file/program/status/proc/post_status(command, data1, data2)
var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS)
if(!frequency)
return
var/datum/signal/status_signal = new(list("command" = "message"))
var/datum/signal/status_signal = new(list("command" = command))
switch(command)
if("message")
status_signal.data["top_text"] = data1
status_signal.data["bottom_text"] = data2
if("alert")
status_signal.data["picture_state"] = data1
status_signal.data["msg1"] = reject_bad_text(upper_text || "", MAX_STATUS_LINE_LENGTH)
status_signal.data["msg2"] = reject_bad_text(lower_text || "", MAX_STATUS_LINE_LENGTH)
frequency.post_signal(src, status_signal)
frequency.post_signal(computer, status_signal)
/**
* Post a message to status displays
* Arguments:
* * upper - Top text
* * lower - Bottom text
*/
/datum/computer_file/program/status/proc/post_message(upper, lower)
post_status("message", upper, lower)
/datum/computer_file/program/status/proc/SetText(position, text)
switch(position)
if("upper")
upper_text = text
if("lower")
lower_text = text
/**
* Post a picture to status displays
* Arguments:
* * picture - The picture name
*/
/datum/computer_file/program/status/proc/post_picture(picture)
if (!(picture in GLOB.status_display_approved_pictures))
return
if(picture in GLOB.status_display_state_pictures)
post_status(picture)
else
post_status("alert", picture)
/datum/computer_file/program/status/ui_act(action, list/params, datum/tgui/ui)
. = ..()
@@ -41,15 +65,24 @@
return
switch(action)
if("stat_send")
SendSignal()
if("stat_update")
SetText(params["position"], params["text"]) // i hate the player i hate the player
if("setStatusMessage")
upper_text = reject_bad_text(params["upperText"] || "", MAX_STATUS_LINE_LENGTH)
lower_text = reject_bad_text(params["lowerText"] || "", MAX_STATUS_LINE_LENGTH)
post_message(upper_text, lower_text)
if("setStatusPicture")
post_picture(params["picture"])
/datum/computer_file/program/status/ui_static_data(mob/user)
var/list/data = list()
data["maxStatusLineLength"] = MAX_STATUS_LINE_LENGTH
return data
/datum/computer_file/program/status/ui_data(mob/user)
var/list/data = get_header_data()
data["upper"] = upper_text
data["lower"] = lower_text
data["upperText"] = upper_text
data["lowerText"] = lower_text
return data
@@ -1,7 +1,8 @@
import { sortBy } from 'common/collections';
import { capitalize } from 'common/string';
import { useBackend, useLocalState } from '../backend';
import { Blink, Box, Button, Dimmer, Flex, Icon, Input, Modal, Section, TextArea } from '../components';
import { Blink, Box, Button, Dimmer, Flex, Icon, Modal, Section, TextArea } from '../components';
import { StatusDisplayControls } from './common/StatusDisplayControls';
import { Window } from '../layouts';
import { sanitizeText } from '../sanitize';
@@ -202,11 +203,7 @@ const PageBuyingShuttle = (props, context) => {
};
const PageChangingStatus = (props, context) => {
const { act, data } = useBackend(context);
const { maxStatusLineLength } = data;
const [lineOne, setLineOne] = useLocalState(context, 'lineOne', data.lineOne);
const [lineTwo, setLineTwo] = useLocalState(context, 'lineTwo', data.lineTwo);
const { act } = useBackend(context);
return (
<Box>
@@ -218,85 +215,7 @@ const PageChangingStatus = (props, context) => {
/>
</Section>
<Section>
<Flex direction="column">
<Flex.Item>
<Button
icon="times"
content="Clear Alert"
color="bad"
onClick={() => act('setStatusPicture', { picture: 'blank' })}
/>
</Flex.Item>
<Flex.Item mt={1}>
<Button
icon="check-square-o"
content="Default"
onClick={() => act('setStatusPicture', { picture: 'default' })}
/>
<Button
icon="bell-o"
content="Red Alert"
onClick={() => act('setStatusPicture', { picture: 'redalert' })}
/>
<Button
icon="exclamation-triangle"
content="Lockdown"
onClick={() => act('setStatusPicture', { picture: 'lockdown' })}
/>
<Button
icon="exclamation-circle"
content="Biohazard"
onClick={() => act('setStatusPicture', { picture: 'biohazard' })}
/>
<Button
icon="space-shuttle"
content="Shuttle ETA"
onClick={() => act('setStatusPicture', { picture: 'shuttle' })}
/>
</Flex.Item>
</Flex>
</Section>
<Section title="Message">
<Flex direction="column">
<Flex.Item mb={1}>
<Input
maxLength={maxStatusLineLength}
value={lineOne}
width="200px"
onChange={(_, value) => setLineOne(value)}
/>
</Flex.Item>
<Flex.Item mb={1}>
<Input
maxLength={maxStatusLineLength}
value={lineTwo}
width="200px"
onChange={(_, value) => setLineTwo(value)}
/>
</Flex.Item>
<Flex.Item>
<Button
icon="comment-o"
content="Message"
onClick={() =>
act('setStatusMessage', {
lineOne,
lineTwo,
})
}
/>
</Flex.Item>
</Flex>
</Section>
<StatusDisplayControls />
</Box>
);
};
+4 -41
View File
@@ -1,48 +1,11 @@
import { useBackend } from '../backend';
import { NtosWindow } from '../layouts';
import { Input, Section, Button } from '../components';
type Data = {
upper: string;
lower: string;
};
export const NtosStatus = (props, context) => {
const { act, data } = useBackend<Data>(context);
const { upper, lower } = data;
import { StatusDisplayControls } from './common/StatusDisplayControls';
export const NtosStatus = () => {
return (
<NtosWindow width={310} height={200}>
<NtosWindow width={400} height={350}>
<NtosWindow.Content>
<Section>
<Input
fluid
value={upper}
onChange={(_, value) =>
act('stat_update', {
position: 'upper',
text: value,
})
}
/>
<br />
<Input
fluid
value={lower}
onChange={(_, value) =>
act('stat_update', {
position: 'lower',
text: value,
})
}
/>
<br />
<Button
fluid
onClick={() => act('stat_send')}
content="Update Status Displays"
/>
</Section>
<StatusDisplayControls />
</NtosWindow.Content>
</NtosWindow>
);
@@ -0,0 +1,103 @@
import { useBackend, useSharedState } from '../../backend';
import { Flex, Input, Section, Button } from '../../components';
type Data = {
upperText: string;
lowerText: string;
maxStatusLineLength: number;
};
export const StatusDisplayControls = (props, context) => {
const { act, data } = useBackend<Data>(context);
const {
upperText: initialUpper,
lowerText: initialLower,
maxStatusLineLength,
} = data;
const [upperText, setUpperText] = useSharedState(
context,
'statusUpperText',
initialUpper
);
const [lowerText, setLowerText] = useSharedState(
context,
'statusLowerText',
initialLower
);
return (
<>
<Section>
<Button
icon="toggle-off"
content="Off"
color="bad"
onClick={() => act('setStatusPicture', { picture: 'blank' })}
/>
<Button
icon="space-shuttle"
content="Shuttle ETA / Off"
color=""
onClick={() => act('setStatusPicture', { picture: 'shuttle' })}
/>
</Section>
<Section title="Graphics">
<Button
icon="flag"
content="Logo"
onClick={() => act('setStatusPicture', { picture: 'default' })}
/>
<Button
icon="bell-o"
content="Red Alert"
onClick={() => act('setStatusPicture', { picture: 'redalert' })}
/>
<Button
icon="exclamation-triangle"
content="Lockdown"
onClick={() => act('setStatusPicture', { picture: 'lockdown' })}
/>
<Button
icon="biohazard"
content="Biohazard"
onClick={() => act('setStatusPicture', { picture: 'biohazard' })}
/>
</Section>
<Section title="Message">
<Flex direction="column" align="stretch">
<Flex.Item mb={1}>
<Input
fluid
maxLength={maxStatusLineLength}
value={upperText}
onChange={(_, value) => setUpperText(value)}
/>
</Flex.Item>
<Flex.Item mb={1}>
<Input
fluid
maxLength={maxStatusLineLength}
value={lowerText}
onChange={(_, value) => setLowerText(value)}
/>
</Flex.Item>
<Flex.Item>
<Button
icon="comment-o"
onClick={() => act('setStatusMessage', { upperText, lowerText })}
content="Send"
/>
</Flex.Item>
</Flex>
</Section>
</>
);
};