Guide to TGUI

From Paradise Station Wiki
Revision as of 10:21, 19 May 2022 by Sirryan2002 (talk | contribs) (i'll finish the modal section later)
Jump to navigation Jump to search
This page/section is a stub You can help by expanding it


Installation

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