This commit is contained in:
Archie
2021-05-04 06:11:29 -03:00
parent bc4b16f5e3
commit c444126dae
8 changed files with 11797 additions and 2 deletions
+11449
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -744,7 +744,7 @@ The reactor CHEWS through moderator. It does not do this slowly. Be very careful
transfer_access = ACCESS_CONSTRUCTION
network_destination = "rbmk monitoring system"
size = 2
tgui_id = "NtosRbmkStats"
tgui_id = "ntosrbmkstats"
ui_x = 350
ui_y = 550
var/active = TRUE //Easy process throttle
+1 -1
View File
@@ -3087,6 +3087,7 @@
#include "hyperstation\code\modules\integrated_electronics\input.dm"
#include "hyperstation\code\modules\mob\mob_helpers.dm"
#include "hyperstation\code\modules\patreon\patreon.dm"
#include "hyperstation\code\modules\power\rbmk.dm"
#include "hyperstation\code\modules\reagents\chemistry\reagents\food_reagents.dm"
#include "hyperstation\code\modules\reagents\chemistry\reagents\hydroponics_reactions.dm"
#include "hyperstation\code\modules\resize\resize_action.dm"
@@ -3094,7 +3095,6 @@
#include "hyperstation\code\modules\resize\sizechems.dm"
#include "hyperstation\code\modules\resize\sizegun.dm"
#include "hyperstation\code\modules\surgery\organs\augments_arms.dm"
#include "hyperstation\code\modules\power\rbmk.dm"
#include "hyperstation\code\obj\ashtray.dm"
#include "hyperstation\code\obj\bluespace sewing kit.dm"
#include "hyperstation\code\obj\condom.dm"
+58
View File
@@ -0,0 +1,58 @@
import { classes } from 'common/react';
import { IS_IE8 } from '../byond';
/**
* Brings Layout__content DOM element back to focus.
*
* Commonly used to keep the content scrollable in IE.
*/
export const refocusLayout = () => {
// IE8: Focus method is seemingly fucked.
if (IS_IE8) {
return;
}
const element = document.getElementById('Layout__content');
if (element) {
element.focus();
}
};
export const Layout = props => {
const {
className,
theme = 'nanotrasen',
children,
} = props;
return (
<div className={'theme-' + theme}>
<div
className={classes([
'Layout',
className,
])}>
{children}
</div>
</div>
);
};
const LayoutContent = props => {
const {
className,
scrollable,
children,
} = props;
return (
<div
id="Layout__content"
className={classes([
'Layout__content',
scrollable && 'Layout__content--scrollable',
className,
])}>
{children}
</div>
);
};
Layout.Content = LayoutContent;
@@ -0,0 +1,126 @@
import { useBackend } from '../backend';
import { Box, Button } from '../components';
import { refocusLayout } from './Layout';
import { Window } from './Window';
export const NtosWindow = (props, context) => {
const {
resizable,
theme = 'ntos',
children,
} = props;
const { act, data } = useBackend(context);
const {
PC_batteryicon,
PC_showbatteryicon,
PC_batterypercent,
PC_ntneticon,
PC_apclinkicon,
PC_stationtime,
PC_programheaders = [],
PC_showexitprogram,
} = data;
return (
<Window
theme={theme}
resizable={resizable}>
<div className="NtosWindow">
<div
className="NtosWindow__header NtosHeader"
onMouseDown={() => {
refocusLayout();
}}>
<div className="NtosHeader__left">
<Box inline bold mr={2}>
{PC_stationtime}
</Box>
<Box inline italic mr={2} opacity={0.33}>
NtOS
</Box>
</div>
<div className="NtosHeader__right">
{PC_programheaders.map(header => (
<Box key={header.icon} inline mr={1}>
<img
className="NtosHeader__icon"
src={header.icon} />
</Box>
))}
<Box inline>
{PC_ntneticon && (
<img
className="NtosHeader__icon"
src={PC_ntneticon} />
)}
</Box>
{!!PC_showbatteryicon && PC_batteryicon && (
<Box inline mr={1}>
{PC_batteryicon && (
<img
className="NtosHeader__icon"
src={PC_batteryicon} />
)}
{PC_batterypercent && (
PC_batterypercent
)}
</Box>
)}
{PC_apclinkicon && (
<Box inline mr={1}>
<img
className="NtosHeader__icon"
src={PC_apclinkicon} />
</Box>
)}
{!!PC_showexitprogram && (
<Button
width="26px"
lineHeight="22px"
textAlign="center"
color="transparent"
icon="window-minimize-o"
tooltip="Minimize"
tooltipPosition="bottom"
onClick={() => act('PC_minimize')} />
)}
{!!PC_showexitprogram && (
<Button
mr="-3px"
width="26px"
lineHeight="22px"
textAlign="center"
color="transparent"
icon="window-close-o"
tooltip="Close"
tooltipPosition="bottom-left"
onClick={() => act('PC_exit')} />
)}
{!PC_showexitprogram && (
<Button
mr="-3px"
width="26px"
lineHeight="22px"
textAlign="center"
color="transparent"
icon="power-off"
tooltip="Power off"
tooltipPosition="bottom-left"
onClick={() => act('PC_shutdown')} />
)}
</div>
</div>
{children}
</div>
</Window>
);
};
const NtosWindowContent = props => {
return (
<div className="NtosWindow__content">
<Window.Content {...props} />
</div>
);
};
NtosWindow.Content = NtosWindowContent;
+142
View File
@@ -0,0 +1,142 @@
import { classes } from 'common/react';
import { decodeHtmlEntities, toTitleCase } from 'common/string';
import { Component, Fragment } from 'inferno';
import { useBackend } from '../backend';
import { IS_IE8, runCommand, winset } from '../byond';
import { Box, Icon } from '../components';
import { UI_DISABLED, UI_INTERACTIVE, UI_UPDATE } from '../constants';
import { dragStartHandler, resizeStartHandler } from '../drag';
import { releaseHeldKeys } from '../hotkeys';
import { createLogger } from '../logging';
import { Layout, refocusLayout } from './Layout';
const logger = createLogger('Window');
export class Window extends Component {
componentDidMount() {
refocusLayout();
}
render() {
const {
resizable,
theme,
children,
} = this.props;
const {
config,
debugLayout,
} = useBackend(this.context);
// Determine when to show dimmer
const showDimmer = config.observer
? config.status < UI_DISABLED
: config.status < UI_INTERACTIVE;
return (
<Layout
className="Window"
theme={theme}>
<TitleBar
className="Window__titleBar"
title={decodeHtmlEntities(config.title)}
status={config.status}
fancy={config.fancy}
onDragStart={dragStartHandler}
onClose={() => {
logger.log('pressed close');
releaseHeldKeys();
winset(config.window, 'is-visible', false);
runCommand(`uiclose ${config.ref}`);
}} />
<div
className={classes([
'Window__rest',
debugLayout && 'debug-layout',
])}>
{children}
{showDimmer && (
<div className="Window__dimmer" />
)}
</div>
{config.fancy && resizable && (
<Fragment>
<div className="Window__resizeHandle__e"
onMousedown={resizeStartHandler(1, 0)} />
<div className="Window__resizeHandle__s"
onMousedown={resizeStartHandler(0, 1)} />
<div className="Window__resizeHandle__se"
onMousedown={resizeStartHandler(1, 1)} />
</Fragment>
)}
</Layout>
);
}
}
const WindowContent = props => {
const { scrollable, children } = props;
// A bit lazy to actually write styles for it,
// so we simply include a Box with margins.
return (
<Layout.Content
scrollable={scrollable}>
<Box m={1}>
{children}
</Box>
</Layout.Content>
);
};
Window.Content = WindowContent;
const statusToColor = status => {
switch (status) {
case UI_INTERACTIVE:
return 'good';
case UI_UPDATE:
return 'average';
case UI_DISABLED:
default:
return 'bad';
}
};
const TitleBar = props => {
const {
className,
title,
status,
fancy,
onDragStart,
onClose,
} = props;
return (
<div
className={classes([
'TitleBar',
className,
])}>
<Icon
className="TitleBar__statusIcon"
color={statusToColor(status)}
name="eye" />
<div className="TitleBar__title">
{title === title.toLowerCase()
? toTitleCase(title)
: title}
</div>
<div
className="TitleBar__dragZone"
onMousedown={e => fancy && onDragStart(e)} />
{!!fancy && (
<div
className="TitleBar__close TitleBar__clickable"
// IE8: Synthetic onClick event doesn't work on IE8.
// IE8: Use a plain character instead of a unicode symbol.
// eslint-disable-next-line react/no-unknown-property
onclick={onClose}>
{IS_IE8 ? 'x' : '×'}
</div>
)}
</div>
);
};
+3
View File
@@ -0,0 +1,3 @@
export { Layout, refocusLayout } from './Layout';
export { NtosWindow } from './NtosWindow';
export { Window } from './Window';
+17
View File
@@ -60,6 +60,9 @@ import { NtosNetChat } from './interfaces/NtosNetChat';
import { NtosNetDownloader } from './interfaces/NtosNetDownloader';
import { NtosSupermatterMonitor } from './interfaces/NtosSupermatterMonitor';
import { NtosWrapper } from './interfaces/NtosWrapper';
import { NtosRbmkStats } from './interfaces/NtosRbmkStats';
import { RbmkControlRods } from './interfaces/RbmkControlRods';
import { RbmkStats } from './interfaces/RbmkStats';
import { NuclearBomb } from './interfaces/NuclearBomb';
import { OperatingComputer } from './interfaces/OperatingComputer';
import { OreBox } from './interfaces/OreBox';
@@ -370,6 +373,20 @@ const ROUTES = {
scrollable: true,
theme: 'ntos',
},
ntosrbmkstats: {
component: () => NtosRbmkStats,
wrapper: () => NtosWrapper,
scrollable: true,
theme: 'ntos',
},
rbmkcontrolrods: {
component: () => RbmkControlRods,
scrollable: true,
},
rbmkstats: {
component: () => RbmkStats,
scrollable: true,
},
nuclear_bomb: {
component: () => NuclearBomb,
scrollable: false,