yeehaw it's done

This commit is contained in:
Seris02
2020-02-05 16:54:57 +08:00
633 changed files with 38003 additions and 6217 deletions
+6 -9
View File
@@ -24,16 +24,13 @@
extra = ` tooltip-${this.get('tooltip-side')}`
if (this.get('grid'))
extra += ' gridable'
if (this.get('enabled')) {
const state = this.get('state')
const style = this.get('style')
if (!state) {
return `active normal ${style} ${extra}`
} else {
return `inactive ${state} ${extra}`
}
const state = this.get('state')
const style = this.get('style')
const active_class = this.get('enabled') ? 'active' : 'inactive'
if (!state) {
return `${active_class} normal ${style} ${extra}`
} else {
return `inactive disabled ${extra}`
return `${active_class} ${state} ${extra}`
}
}
},
+15 -5
View File
@@ -4,11 +4,21 @@ buttoncolor(selector, color)
&.{selector}
transition: background-color 0.5s
background-color: color
&.{selector}.active:hover,
&.{selector}.active:focus
transition: background-color 0.25s
background-color: lighten(color, button-lighten-hover)
outline: 0
&.active:hover,
&.active:focus
transition: background-color 0.25s
background-color: lighten(color, button-lighten-hover)
outline: 0
if selector is not 'disabled'
&:not(.active)
background-image: repeating-linear-gradient(
-45deg,
color,
color 1px,
button-color-disabled 1px,
button-color-disabled 2px
)
span.button
@extend {context} $fontReset
+15 -15
View File
@@ -4,22 +4,22 @@ import { resize } from 'util/dragresize'
component.exports = {
oninit () {
const onresize = resize.bind(this)
const onrelease = () => this.set({ resize: false, x: null, y: null })
const onresize = resize.bind(this);
const onrelease = () => {
this.set({
resize: false,
x: null,
y: null,
});
document.removeEventListener('mousemove', onresize);
document.removeEventListener('mouseup', onrelease);
};
this.observe('config.fancy', (newkey, oldkey, keypath) => {
winset(this.get('config.window'), 'can-resize', !newkey)
if (newkey) {
document.addEventListener('mousemove', onresize)
document.addEventListener('mouseup', onrelease)
} else {
document.removeEventListener('mousemove', onresize)
document.removeEventListener('mouseup', onrelease)
}
})
this.on('resize', () => this.toggle('resize'))
this.on('resize', () => {
this.toggle('resize');
document.addEventListener('mousemove', onresize);
document.addEventListener('mouseup', onrelease);
});
}
}
</script>
+1 -6
View File
@@ -32,12 +32,6 @@ section
@extend $cell
width: 100%
.compressedcell
@extend $cell
&:not(:first-child)
text-align: center
padding-top: 0px
.cell
@extend $cell
&:not(:first-child)
@@ -47,3 +41,4 @@ section
width: 75px
&:not(:last-child)
padding-right: 4px
+35 -15
View File
@@ -1,7 +1,7 @@
<script>
import { UI_INTERACTIVE, UI_UPDATE, UI_DISABLED } from 'util/constants'
import { href, winset } from 'util/byond'
import { drag } from 'util/dragresize'
import { href, winget, winset, runCommand } from 'util/byond'
import { drag, lock } from 'util/dragresize'
component.exports = {
computed: {
@@ -15,12 +15,31 @@ component.exports = {
}
},
oninit () {
// Calculate offset between the "browser's screen space" and
// "BYOND screen space".
// This is necessary, because Windows 10 taskbar decreases the effective
// height by about 40px. If taskbar is located at the top and you try
// to drag a TGUI window, it rapidly propels itself to the bottom of
// the screen and gets stuck.
// See: https://github.com/tgstation/tgstation/issues/44038
this.set('screenOffsetX', 0);
this.set('screenOffsetY', 0);
winget(this.get('config.window'), 'pos')
.then(pos => {
this.set('screenOffsetX', pos.x - window.screenX);
this.set('screenOffsetY', pos.y - window.screenY);
// If the window starts off screen, pull it back.
let {x, y} = lock(window.screenLeft, window.screenTop)
if (x !== window.screenLeft || y !== window.screenTop) {
winset(this.get('config.window'), 'pos', `${x},${y}`);
}
});
const ondrag = drag.bind(this)
const onrelease = (event) => this.set({ drag: false, x: null, y: null })
this.observe('config.fancy', (newkey, oldkey, keypath) => {
winset(this.get('config.window'), 'titlebar', !newkey && this.get('config.titlebar'))
if (newkey) {
document.addEventListener('mousemove', ondrag)
document.addEventListener('mouseup', onrelease)
@@ -36,7 +55,7 @@ component.exports = {
},
close () {
winset(this.get('config.window'), 'is-visible', false)
window.location.href = href({command: `uiclose ${this.get('config.ref')}`}, 'winset')
runCommand(`uiclose ${this.get('config.ref')}`)
},
minimize () {
winset(this.get('config.window'), 'is-minimized', true)
@@ -46,13 +65,14 @@ component.exports = {
}
</script>
{{#if config.titlebar}}
<header class='titlebar' on-mousedown='drag'>
<i class='statusicon fa fa-eye fa-2x {{visualStatus}}'></i>
<span class='title'>{{yield}}</span>
{{#if config.fancy}}
<i class='minimize fa fa-minus fa-2x' on-click='minimize'></i>
<i class='close fa fa-close fa-2x' on-click='close'></i>
{{/if}}
</header>
{{/if}}
<header class='titlebar' on-mousedown='drag'>
<i class='statusicon fa fa-eye fa-2x {{visualStatus}}'></i>
<span class='title'>{{yield}}</span>
{{#if config.fancy}}
<i class='minimize fa fa-minus fa-2x' on-click='minimize'></i>
<i class='close fa fa-close fa-2x' on-click='close'></i>
{{else}}
<i class='minimize no-icons' on-click='minimize'></i>
<i class='close no-icons' on-click='close'></i>
{{/if}}
</header>
+4 -4
View File
@@ -49,17 +49,17 @@ header.titlebar
top: 4px
right: 12px
/.no-icons header.titlebar
.statusicon
header.titlebar
.statusicon.no-icons
font-size: 20px
&::after
content: "O"
.minimize
.minimize.no-icons
top: -2px
font-size: 20px
&::after
content: ""
.close
.close.no-icons
font-size: 20px
&::after
content: "X"
+2 -2
View File
@@ -31,9 +31,9 @@
<span>Otherwise, click 'No Frills' below to disable potentially incompatible features (and this message).</span>
<hr/>
<ui-button icon='close' action='tgui:nofrills'>No Frills</ui-button>
<ui-button icon='internet-explorer' action='tgui:link' params='{"url": "http://windows.microsoft.com/en-us/internet-explorer/download-ie"}'>
<ui-button action='tgui:link' params='{"url": "http://windows.microsoft.com/en-us/internet-explorer/download-ie"}'>
Upgrade IE</ui-button>
<ui-button icon='edge' action='tgui:link' params='{"url": "https://dev.windows.com/en-us/microsoft-edge/tools/vms"}'>
<ui-button action='tgui:link' params='{"url": "https://dev.windows.com/en-us/microsoft-edge/tools/vms"}'>
IE VMs</ui-button>
<ui-button icon='info' action='tgui:link' params='{"url": "https://support.microsoft.com/en-us/lifecycle#gp/Microsoft-Internet-Explorer"}'>
EOL Info</ui-button>
@@ -0,0 +1,10 @@
&.airlock_electronics
table
width: 100%
border-spacing: 2px
th
text-align: left
td
vertical-align: top
.button
margin-top: 4px
+1
View File
@@ -45,3 +45,4 @@ body.clockwork
background-color-end 100%)
@import "util/*"
@import "components/*"
@import "interfaces/*"
+2
View File
@@ -3,5 +3,7 @@ body.nanotrasen
linear-gradient(to bottom,
background-color-start 0%,
background-color-end 100%)
@import "util/*"
@import "components/*"
@import "interfaces/*"
+1
View File
@@ -28,3 +28,4 @@ body.syndicate
background-color-end 100%)
@import "util/*"
@import "components/*"
@import "interfaces/*"
+44 -27
View File
@@ -13,22 +13,35 @@ Object.assign(Math, require('util/math'))
// Set up the initialize function. This is either called below if JSON is provided
// inline, or called by the server if it was not.
import TGUI from 'tgui.ract'
window.initialize = (dataString) => {
// Don't run twice.
window.tgui = window.tgui || new TGUI({
el: '#container',
data () {
const initial = JSON.parse(dataString)
return {
constants: require('util/constants'),
text: require('util/text'),
config: initial.config,
data: initial.data,
adata: initial.data
}
// This thing was a part of an old index.html
window.update = window.initialize = dataString => {
const data = JSON.parse(dataString);
// Initialize
if (!window.tgui) {
window.tgui = new TGUI({
el: '#container',
data () {
const initial = data;
return {
constants: require('util/constants'),
text: require('util/text'),
config: initial.config,
data: initial.data,
adata: initial.data,
};
},
});
}
// Update
if (window.tgui) {
window.tgui.set('config', data.config);
if (typeof data.data !== 'undefined') {
window.tgui.set('data', data.data);
window.tgui.animate('adata', data.data);
}
})
}
}
};
// Try to find data in the page. If the JSON was inlined, load it.
const holder = document.getElementById('data')
@@ -38,16 +51,20 @@ if (data !== '{}') {
window.initialize(data)
holder.remove()
}
// Let the server know we're set up. This also sends data if it was not inlined.
import { act } from 'util/byond'
act(ref, 'tgui:initialize')
// Load fonts.
import { loadCSS } from 'fg-loadcss'
loadCSS('font-awesome.min.css')
// Handle font loads.
import FontFaceObserver from 'fontfaceobserver'
const fontawesome = new FontFaceObserver('FontAwesome')
fontawesome.check('\uf240')
.then(() => document.body.classList.add('icons'))
.catch(() => document.body.classList.add('no-icons'))
// Let the server know we're set up.
// This also sends data if it was not inlined.
// NOTE: This is currently handled by tgui-next. Only initialize if
// we were loaded by tgui-fallback.html.
import { act } from 'util/byond';
import { loadCSS } from 'fg-loadcss';
if (window.tguiFallback) {
act(ref, 'tgui:initialize');
// Load fonts.
loadCSS('v4shim.css')
loadCSS('font-awesome.css')
}
else {
act(ref, 'tgui:update');
}
+2 -8
View File
@@ -4,7 +4,6 @@
<script>
import { winset } from 'util/byond'
import { lock } from 'util/dragresize'
component.exports = {
components: {
@@ -30,6 +29,7 @@ component.exports = {
const interfaces = require('interfaces/**/*.ract', { mode: 'hash' })
if (requested in interfaces) {
this.components.interface = interfaces[requested] // Use the interface specified in the config...
document.body.classList.add(requested) //Name of the interface class for interface-level css
} else {
this.components.interface = interfaces.error // ...unless it does not exist.
}
@@ -41,12 +41,6 @@ component.exports = {
})
},
oncomplete () {
// If the window starts off screen, pull it back.
if (this.get('config.locked')) {
let {x, y} = lock(window.screenLeft, window.screenTop)
winset(this.get('config.window'), 'pos', `${x},${y}`)
}
// Give focus back to the map.
winset('mapwindow.map', 'focus', true)
}
@@ -58,6 +52,6 @@ component.exports = {
<warnings/>
<interface/>
</main>
{{#if config.titlebar}}
{{#if config.fancy}}
<resize/>
{{/if}}
+8 -8
View File
@@ -71,14 +71,14 @@ bar-color-border = royal-blue
bar-color-background = dark-gray
// Buttons
button-color-normal = royal-blue
button-color-disabled = light-gray
button-color-selected = green
button-color-caution = yellow
button-color-danger = dark-red
button-color-border = dark-gray
button-lighten-hover = 15%
button-alpha-disabled = .75
button-color-normal = royal-blue
button-color-disabled = light-gray
button-color-selected = green
button-color-caution = yellow
button-color-danger = dark-red
button-color-border = dark-gray
button-lighten-hover = 15%
button-desaturate-inactive = 50%
// Input
input-color-text = black
+65 -11
View File
@@ -1,16 +1,70 @@
const encode = encodeURIComponent
// Helper to generate a BYOND href given 'params' as an object (with an optional 'url' for eg winset).
export function href (params = {}, url = '') {
return `byond://${url}?` + Object.keys(params).map(key => `${encode(key)}=${encode(params[key])}`).join('&')
}
// Helper to generate a BYOND href given 'params' as an object
// (with an optional 'url' for eg winset).
export const href = (url, params = {}) => {
return `byond://${url || ''}?`
+ Object.keys(params)
.map(key => `${encode(key)}=${encode(params[key])}`)
.join('&');
};
// Helper to make a BYOND ui_act() call on the UI 'src' given an 'action' and optional 'params'.
export function act (src, action, params = {}) {
window.location.href = href(Object.assign({ src, action }, params))
}
// Helper to make a BYOND ui_act() call on the UI 'src' given an 'action'
// and optional 'params'.
export const act = (src, action, params = {}) => {
window.location.href = href('', Object.assign({ src, action }, params))
};
/**
* A high-level abstraction of BYJAX. Makes a call to BYOND and returns
* a promise, which (if endpoint has a callback parameter) resolves
* with the return value of that call.
*/
export const callByond = (url, params = {}) => {
// Create a callback array if it doesn't exist yet
window.byondCallbacks = window.byondCallbacks || [];
// Create a Promise and push its resolve function into callback array
const callbackIndex = window.byondCallbacks.length;
const promise = new Promise(resolve => {
// TODO: Fix a potential memory leak
window.byondCallbacks.push(resolve);
});
// Call BYOND client
window.location.href = href(url || '', Object.assign({}, params, {
callback: `byondCallbacks[${callbackIndex}]`,
}));
// Return promise (awaitable)
return promise;
};
export const runCommand = command => callByond('winset', { command });
/**
* A simple debug print.
*
* TODO: Find a better way to debug print.
* Right now we just print into the game chat.
*/
export const debugPrint = (...args) => {
const str = args
.map(arg => {
if (typeof arg === 'string') {
return arg
}
return JSON.stringify(arg);
})
.join(' ');
return runCommand('Me [debugPrint] ' + str);
};
export const winget = (win, key) => {
return callByond('winget', { id: win, property: key })
.then(obj => obj[key]);
};
// Helper to make a BYOND winset() call on 'window', setting 'key' to 'value'
export function winset (win, key, value) {
window.location.href = href({[`${win}.${key}`]: value}, 'winset')
}
export const winset = (win, key, value) => {
window.location.href = href('winset', {
[`${win}.${key}`]: value,
});
};
+18 -10
View File
@@ -17,17 +17,25 @@ export function lock (x, y) {
}
export function drag (event) {
event.preventDefault()
if (!this.get('drag')) return
if (this.get('x')) {
let x = (event.screenX - this.get('x')) + window.screenLeft
let y = (event.screenY - this.get('y')) + window.screenTop
if (this.get('config.locked')) ({x, y} = lock(x, y)) // Lock to primary monitor.
winset(this.get('config.window'), 'pos', `${x},${y}`)
event.preventDefault();
if (!this.get('drag')) {
return;
}
if (this.get('x')) {
let x = event.screenX
+ this.get('x')
+ this.get('screenOffsetX');
let y = event.screenY
+ this.get('y')
+ this.get('screenOffsetY');
winset(this.get('config.window'), 'pos', `${x},${y}`);
}
else {
this.set({
x: window.screenLeft - event.screenX,
y: window.screenTop - event.screenY,
});
}
this.set({ x: event.screenX, y: event.screenY })
}
export function sane (x, y) {
+1 -1
View File
@@ -9,7 +9,7 @@ div[data-tooltip], span[data-tooltip]
padding: 10px
transform: translateX(-50%)
pointer-events: none
visibility: hidden
opacity: 0