This UI framework is mostly composed of four main parts:
- Main JS file and supporting HTML code
- UI DM datum, responsible for linking opened ui window with code
- Object specific code, that generates data for uis, and handles actions.
- Sub System responsible for keeping track of all uis and making sure they tick.
First we have to create a way to open ui, for example, a proc that's called when we want to open ui:
/datum/mydatum/proc/open_ui()
var/datum/vueuiui/ui = SSvueui.get_open_ui(usr, src)
if (!ui)
ui = new(usr, src, "uiname", 300, 300, "Title of ui")
ui.open()
On first line we check if we already have open ui for this user, if we already have, then we just open it on last line, but if we don't have existing ui, we then create a new one.
But how we pass data to it? There is two ways to do it, first one is to pass initial data in constructor: new(usr, src, "uiname", 300, 300, "Title of ui", data)
. But it's recommended to use vueui_data_change
proc for data feed to ui.
/datum/mydatum/vueui_data_change(var/list/newdata, var/mob/user, var/datum/vueuiui/ui)
if(!newdata)
// generate new data
return list("counter" = 0)
// Here we can add checks for difference of state and alter it
// or do actions depending on it's change
if(newdata["counter"] >= 10)
return list("counter" = 0)
return
Every time server receives of frontend state change it calls this proc to make sure that frontend state didn't go too far from actual data it should represent. If everything is alright with newstate
and no push to frontend of data is needed then it should return 0
or null
, else return data that should be pushed.
Simply use Topic
proc to get ui action calls from ui.
/datum/mydatum/Topic(href, href_list)
if(href_list["action"] == "test")
world << "Got Test Action! [href_list["data"]]"
return
It is recommended to enable debugging for this step to make things easier.
To create ui itself, you need to create .vue
file inside \vueui\components\ui
and register it inside \vueui\components\ui\index.js
. Example vueui file:
<template>
<div>
<p>{{ counter }}</p>
<vui-button :params="{ action: 'test', data: 'This is from ui.' }">Call topic</vui-button>
<vui-button @click="counter++">Increment counter</vui-button>
</div>
</template>
<script>
export default {
name: 'view-uiname',
data() {
return this.$root.$data.state; // Make data more easily accessible
}
};
</script>
<style lang="scss" scoped>
p {
font-size: 3em;
}
</style>
This ui framework requires whole ui to be compiled for changes to be available. Compilation requires Node.js runtime, what is obtainable in various ways, most common is install from official site. To do initial dependency setup run npm install
to gather all dependencies needed for ui. Single compilation can be done with npm run compile
, but if you constantly do changes, then npm run run
is more convenient, as it compiles everything as soon as change is detected.
Asks all ui's to call object
's vueui_data_change
proc to make all uis up tp date. Should be used when bigger change was done or action done change that would affect global data.
Gets a list of all open uis for specified object. This allows to interact with individual uis.
Determines currently active view component for this ui datum. Should be combines with check_for_change()
or push_change()
.
Determines header component that is used with this ui. Should be set before ui.open()
.
Tries to open this ui, and sends all necessary assets for proper ui rendering. If ui has no data, then calls object.vueui_data_change(null ...)
to obtain initial ui data.
Sends singular asset to client for use in ui, after this call you might need to update client-side asset index. To do so call push_change(null)
.
Adds asset for ui use, but does not send it to client. It will be sent in during next ui.open()
call or if it's done manually with ui.send_asset(name)
combined with push_change(null)
.
Removes asset from future use in ui. But client-side asset index isn't updated immediately to reflect removal of asset.
Pushes data change to client. This also pushes changes to metadata, what includes: title, world time, ui status, active ui component, client-side asset index.
Checks with object.vueui_data_change
if data has changed, if so, then change is pushed. If forcedPush is resolving to true, then it pushes change anyways.
This call should be used if external change was detected. It checks if user still can use this ui, and what's it usability level.
To enable debug mode and make figuring out things easier do following steps:
- Enable development mode inside webpack file by changing out commented out line
\vueui\webpack.config.js: line 7
mode: 'production', // And comment this one out
//mode: 'development', // Uncomment this line to set mode to development
- Enable debugging inside ui datum. (This will always push new JS file each time open() is called and show data in JSON format at the end of ui)
\code\modules\vueui\ui.dm: line 5
#define UIDEBUG 0 // Change 0 to 1
- Use
\vueui\template.html
in Internet explorer to use inspector to analyze ui behaviour. Also don't forget to copy paste data from actual ui to this debug ui inside templates code.
You should look at official Vuejs guide. As it's more detailed and more accurate than any explanation that could have been written here.
Button programmed to send provided data to ui object. Comes with icon support.
Example:
<vui-button :params="{ action: 'delete' }" icon="close">Delete</vui-button>
Parameters:
$slot
- Contents of button.params
- key value pairs to send toTopic
of object.icon
- icon that should be used in that button. For available icons look at\vueui\styles\icons.scss
Simple progress bar for representing progress of a process or indicate status.
Example:
<vui-progress :value="50"></vui-progress>
Parameters:
value
- numerical value to display. Should be used with binding.max
- maximum value of provided value's range. Should be used with binding.min
- minimum value of provided value's range. Should be used with binding.
Wrapper for showing images added with ui proc ui.add_asset(name, image)
. Please note: images are sent to client when open()
is called, if it's added after, then send_asset(name)
should be used, also image index is sent with next data change, if immediate image change is needed then check_for_change(1)
or push_change(null)
should be used to send index.
Example:
<vui-img name="my-image-name"></vui-img>
Parameters:
name
- name of asset to show that was sent to client. Please note that regular<img>
parameters apply here.