Difference between revisions of "Guide to TGUI"
Sirryan2002 (talk | contribs) (i'll finish the modal section later) |
Sirryan2002 (talk | contribs) (added info about TGUI installation) |
||
Line 1: | Line 1: | ||
'''TGUI''' is a user interface library that Paradise (and many other ss13) servers use to create modern, responsive user interfaces for players to interact with various in-game objects and mechanics. TGUI is JavaScript based and uses the InfernoJS and ReactJS frameworks. Unlike general code contributions, a contributor will need to go through extra steps to make TGUI changes such as installing package managers and performing extra compilations using yarn. TGUI can be hell to get working and compile the first time, however, it's worth it to keep trying until you can actually make a successful change, I promise! | |||
==Installation== | {{Note|Please read through the README.md file in the TGUI directory on your copy of the codebase, it will provide all necessary instructions to setup TGUI}} | ||
==Installation Process== | |||
Make sure to follow these steps chronologically and ensure you have proper dependencies installed | |||
===Prerequisites=== | |||
You will need to download and install the following dependencies: | |||
# [https://nodejs.org/en/download/ Node v12.13+] | |||
# [https://yarnpkg.com/en/docs/install Yarn v1.19+] | |||
===Final Installation=== | |||
If you are running MSys2, Git Bash, WSL, Linux or macOS please see the README.md for proper installation, for everyone else use this. | |||
You will need to open a terminal, command window, powershell window, etc in the TGUI directory. If you are in vscode and have a terminal open to your codebase directory, you can use '''<code>cd tgui</code>''' to set the directory to the TGUI folder of your codebase. Now if your directory is correctly set to the base TGUI folder, you can now run '''<code>yarn install</code>''' | |||
This should properly install everything, you can check if this worked by running '''<code>yarn run build</code>''' and it should spit out a console log that look something like this: | |||
[[File:TGUI Build Success Log.png]] | |||
If you are getting a bunch of errors, you should count your blessings and go ask somebody in #coding_chat to help you. | |||
==Basic Syntax== | ==Basic Syntax== | ||
Revision as of 15:56, 18 July 2022
TGUI is a user interface library that Paradise (and many other ss13) servers use to create modern, responsive user interfaces for players to interact with various in-game objects and mechanics. TGUI is JavaScript based and uses the InfernoJS and ReactJS frameworks. Unlike general code contributions, a contributor will need to go through extra steps to make TGUI changes such as installing package managers and performing extra compilations using yarn. TGUI can be hell to get working and compile the first time, however, it's worth it to keep trying until you can actually make a successful change, I promise!
Note: Please read through the README.md file in the TGUI directory on your copy of the codebase, it will provide all necessary instructions to setup TGUI.
Installation Process
Make sure to follow these steps chronologically and ensure you have proper dependencies installed
Prerequisites
You will need to download and install the following dependencies:
Final Installation
If you are running MSys2, Git Bash, WSL, Linux or macOS please see the README.md for proper installation, for everyone else use this.
You will need to open a terminal, command window, powershell window, etc in the TGUI directory. If you are in vscode and have a terminal open to your codebase directory, you can use cd tgui
to set the directory to the TGUI folder of your codebase. Now if your directory is correctly set to the base TGUI folder, you can now run yarn install
This should properly install everything, you can check if this worked by running yarn run build
and it should spit out a console log that look something like this:
If you are getting a bunch of errors, you should count your blessings and go ask somebody in #coding_chat to help you.
Basic Syntax
Advanced UI
Modals
Modals are temporary popup menus in a TGUI window that contributors generally use to enable the view to see additional information or provide an input. In order to use them in a JavaScript file one will first need to import two packages import { ComplexModal, modalOpen } from './common/ComplexModal';
Implementation
In the constant where you first define the actual window, you'll need to include the <ComplexModal />
element directly after the <Window>
declaration. This is mandatory in order for the modal to work. Here is an example usage of it:
export const ComputerUI = (props, context) => { const { act, data } = useBackend(context); const { var1, var2, } = data; return ( <Window resizable> <ComplexModal /> <Window.Content scrollable className="Layout__content--flexColumn"> <ComputerNavigation /> <ComputerPageContent /> </Window.Content> </Window> ); };
Once the complex modal element is added, then once can add further elements into the JS file in order to prompt the game to actually open the modal. This can be done through a button onClick event for example. One will need to call modalOpen(context, 'modal_action_name')
in the JS file, it will take context as the first paramater, and then this actions unique name which as been set as 'modal_action_name' here but it can be anything within reason. Here is an example where it is in a buttons onclick event.
<Button fluid textAlign="left" icon="pen" width="auto" content="Example Content" onClick={() => modalOpen(context, 'edit_title')} />
You can add these as many times as necessary! However, editing the JS file isn't enough to make these work or interact with the game.
DM Code Implementation
For this part, we'll operate under the assumption that you already have basic knowledge of /ui_act and /ui_data. Now we'll be introducing /ui_act_modal which is where we will do the bulk of our DM logic for modals. Go ahead and define that proc now /obj/machinery/computer/examplemachine/proc/ui_act_modal(action, list/params)
. Next we will add logic to our ui_act and ui_data procs.
For ui_act we will need to make sure to include all four of these parameters for our proc (action, list/params, datum/tgui/ui, datum/ui_state/state)
this is more than most machines will use however we're special (and I promise these are used later). In addition to the new parameters, you will need to add an if statement calling ui_act_modal after the parent function call and before the "action" switch statement is performed. This is demonstrated below:
/obj/machinery/computer/examplemachine/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) if(..()) return if(ui_act_modal(action, params)) return switch(action)
What we're doing here is we're checking for additional actions as part of the normal ui_act functionality. Opening a modal is the same thing as performing an action, we're just adding another proc to add ease of use and integrate special functionality already created in parent functions. We've now added a way for our DM code to actually know when the TGUI window wants to open a modal. This next part, I have no fucking idea what it does but it is critically important to making these pieces of shit work. We'll need to add one line to our ui_data proc:
data["modal"] = ui_modal_data(src)
Congratulations, we're now ready to add the final logic (and probably implement the code you've been wanting to add for the past few hours). This is where our ui_act_modal proc comes in. I'll do my best to break it down for a text/int input only (I'm sure more types of modals exist dont worry). First you will need to add some initial code, that is . = true
and then define your id and arguments vars. Essentially what we're doing here is making sure our proc knows what modal window we're working with (by knowing its id) and then getting all those lovely arguments we snatched in our ui_act proc. Once this is done
/obj/machinery/computer/library/proc/ui_act_modal(action, list/params) . = TRUE var/id = params["id"] // The modal's ID var/list/arguments = istext(params["arguments"]) ? json_decode(params["arguments"]) : params["arguments"] switch(ui_modal_act(src, action, params)) if(UI_MODAL_OPEN) switch(id) if("edit_title") ui_modal_input(src, id, "Please input the new title:", null, arguments, selected_book.title) if("edit_author") ui_modal_input(src, id, "Please input the new author:", null, arguments, selected_book.author) else return FALSE if(UI_MODAL_ANSWER) var/answer = params["answer"] switch(id) if("action_a") if(!length(answer) && length(answer) <= MAX_NAME_LEN) return selected_book.title = answer if("action_b") if(!length(answer)) return selected_book.author = answer else return FALSE else return FALSE