GUI Scripting: Popup Message Example

From The DarkMod Wiki
Revision as of 18:18, 4 July 2022 by Geep (talk | contribs)
Jump to navigationJump to search

This page is part of a series. See GUI Scripting Language for overview.

Introduction

This example considers TDM’s stock popup message box, to point out:

  • How an entity, script object, and gui can interact
  • Use of gui:: parameters, i.e., with the "gui::" prefix, for data passing.
  • onNamedEvent handling.

It is interesting to compare this with the similar GUI Scripting: Mission Start Example, that is invoked by the C++ code instead of using a script object.

Setup

The mapper prepares a popup message by creating an atdm:gui_message entity, whose entityDef defines and gives defaults for these spawnargs (among others):

lines			1
show			6		Number of seconds to show text before fade out.
text			This is a popup message.

The mapper overrides the default values. And arranges for the entity to be triggered at the appropriate time. (There are other options, which we’ll ignore here.)

Implementation

Entity

Additional spawnargs on the atdm:gui_message entity include:

scriptobject		tdm_gui_message
gui			guis/tdm_message.gui
call			showMessage

The defaults shown are only overridden if the mapper is customizing the gui or script object.

Default Script Object

Script object tdm_gui_message is defined within tdm_base01\script\tdm_message.script. In its "init()", there’s a call to:

AddTarget(self);

This causes any triggers to the entity to be rerouted to the scriptobject function specified in the "call" spawnarg, in this case, showMessage(). Showing just selected highlights of that function body, annotated:

void tdm_gui_message::showMessage()
{
  string gui_name = getKey("gui");                             Create and start a new GUI overlay,
  gui = $player1.createOverlay(gui_name, 10);                  and store its handle number in a scriptobject float.
  $player1.setGuiInt(gui, "msg_lines", getIntKey("lines"));    Pass the number of lines to gui::msg_lines.
  $player1.setGuiStringFromKey(gui, "msg_text", self, "text"); Likewise text, using a special method supporting > 127 characters:
  float wait_time = getFloatKey("show");
  sys.wait( wait_time );                                       Wait the specified time.
  $player1.callGui(gui, "doFadeOut");                          Ask the GUI to fade out the message box, then (not shown) sys.wait here for fade to finish
  $player1.destroyOverlay(gui);                                Destroy the GUI. Done.
}

Passing of Data and Control

To reprise, the foregoing code (due originally to Flanders) fetches the string from the "gui" spawnarg, to create a gui overlay and start it. Then, it transfers values from the "lines" and "text" spawnargs to gui:: parameters "msg_lines" and "msg_text" respectively. As shown below, the gui in turns picks those up, "immediately" (in 1 millisecond) adjusts the Y-origin of the message box based on the number of lines, and shows the message, fading the box and text in during 1 second (1000 milliseconds).

Note that it's the scriptobject’s timer (not an onTime event handler in the GUI) that decides when the message should start to be faded out. After showMessage calls the gui’s "doFadeOut", inside "onNamedEvent doFadeOut", the message box disappears in 1 second.

Default GUI Script

Here’s tdm_message.gui (slightly reformatted to be more concise):

windowDef parchment
{
    rect      		0,-10,206,160
    nocursor 		1
    background		"guis/assets/mainmenu/oldparchment_backdrop3"
    matcolor		0,0,0,0
	
    windowDef message {
       rect		10,66,185,1000
       visible		1
       text		""
       forecolor	0,0,0,0
       textscale	0.22
       textalign	1		// 0 = left, 1 = center
       font		"fonts/carleton"
       nocursor 	1
    }
		
    windowDef open {

       onTime 0 {
          if ( "gui::msg_lines" == 2 ) {
             transition "message::rect" "10, 30, 185, 1000" "10, 59, 185, 1000" "1" 
          }
          if ( "gui::msg_lines" == 3 ) {
             transition "message::rect" "10, 30, 185, 1000" "10, 52, 185, 1000" "1"
          }
          Not shown: similar code for lines 4 – 6
          if ( "gui::msg_lines" == 7 ) {
             transition "message::rect" "10, 30, 185, 1000" "10, 24, 185, 1000" "1" 	
          }
          set "message::text" "gui::msg_text"; 
          transition "parchment::matcolor" "0 0 0 0" "1 1 1 1"  "1000";
          transition "message::forecolor" "0 0 0 0" "0 0 0 1"  "1000";
      }
   }

   // called when the time is over 
   onNamedEvent doFadeOut {
      transition "parchment::matcolor" "1 1 1 1" "1 1 1 0" "1000";
      transition "message::forecolor" "0 0 0 1" "0 0 0 0" "1000";
   }
}