bw logo

Chapter 2. The Script and GUI Files

Creating a progress bar using BigWorld technology is a straightforward task. In this document, we will implement a progress bar using a GUI script in Python, which will in turn generate a GUI file in XML format.

2.1. Script for generating the GUI file

For this example, we will be using the FantasyDemo scripts.

Open the fantasydemo/res/scripts/client/PyGUI.py, and include the following lines:

"""
This class is a simple Progress Bar.
   """
   class ProgressBar( PyGUIBase ):
    
      factoryString="PyGUI.ProgressBar"
    
      def __init__( self, component ):        
         PyGUIBase.__init__( self, component )        
                    
      def setProgress( self, value ):
         pass

Progress bar script PyGUI.py

The example given in this document uses PyGUIBase, which is the base class for GUI components, and is described in file fantasydemo/res/scripts/client/helpers/PyGUI.py. The use of this class to implement the progress bar is optional.

The class attribute factoryString tells the GUI library which class to instantiate when we load our GUI from the XML file. The XML will contain a <script> entry with the value "PyGUI.ProgressBar"

The method setProgress() is called by the user to set the current progress level. Our script will respond by moving the bar to the appropriate place.

2.2. Generating the GUI file

It is easier to create a GUI at runtime if you use the in-game Python console. So, first launch the FantasyDemo executable, then press DEBUG+P to open the Python console. The code below defines the GUI for our progress bar:

import GUI
progress = GUI.Window( "maps/gui/gui_bar_back.dds" )
progress.bar = GUI.Simple( "maps/gui/gui_bar.dds" )
progress.bar.clipper = GUI.ClipShader()
progress.height = progress.bar.height = 0.1
progress.materialFX = progress.bar.materialFX = "BLEND"
progress.bar.colour = (128,128,255,255)
GUI.addRoot( progress )

Script for generating GUI file (Defining visual elements)

The file above defines a bitmapped border component for the bar, and a bitmapped bar component hooked up to a Clip GUI Shader.

Given that the specified border component is the image below:

Border component

And given that the bar component is the image below:

Bar component

Note that we have created the progress bar as a Window. This enables us to reposition the whole progress bar simply by moving the root component.

For example, to move the entire progress bar to the top middle of the screen, we would write:

progress.position = (0,0.8,1)

Script for generating GUI file — Positioning bar on top middle screen

The final attribute we need to set on the progress bar component is its script. We do this simply by instantiating the appropriate Python class, as illustrated below:

from Helpers import PyGUI
progress.script = PyGUI.ProgressBar(None)

Script for generating GUI file — Defining bar's script

To generate the progress bar GUI file, hook up the script to the GUI component and save it to disk, as illustrated below:

progress.save( "guis/progress_bar.gui" )

Script for generating GUI file (Generating the bar's GUI file)

2.3. The generated GUI file

The generated file guis/progress_bar.gui will look something like this:

<progress_bar.gui>

    <WindowGUIComponent>   301410224
        <position>         0.000000 0.000000 1.000000 </position>

        <widthInClip>      true                       </widthInClip>
        <width>            0.500000                   </width>
        <heightInClip>     true                       </heightInClip>
        <height>           0.100000                   </height>
        <colour>           255.0 255.0 255.0 255.0    </colour>
        <angle>            0                          </angle>
        <flip>             0                          </flip>
        <visible>          true                       </visible>
        <horizontalAnchor> 1                          </horizontalAnchor>
        <verticalAnchor>   1                          </verticalAnchor>
        <textureName>      maps/gui/gui_bar_back.dds  </textureName>
        <materialFX>       1                          </materialFX>
        <tiled>            false                      </tiled>
        <tileWidth>        16                         </tileWidth>
        <tileHeight>       16                         </tileHeight>
        <script>           "PyGUI.ProgressBar"        </script>
        <children>
            <bar>          301291568                  </bar>
        </children>
        <scroll>           0.000000 0.000000          </scroll>
        <minScroll>        0.000000 0.000000          </minScroll>
        <maxScroll>        0.000000 0.000000          </maxScroll>
    </WindowGUIComponent>
    
    <SimpleGUIComponent>   301291568

        <position>         0.000000 0.000000 1.000000 </position>
        <widthInClip>      true                       </widthInClip>
        <width>            0.500000                   </width>
        <heightInClip>     true                       </heightInClip>
        <height>           0.100000                   </height>
        <colour>           128.0 128.0 255.0 255.0    </colour>
        <angle>            0                          </angle>
        <flip>             0                          </flip>
        <visible>          true                       </visible>
        <horizontalAnchor> 1                          </horizontalAnchor>
        <verticalAnchor>   1                          </verticalAnchor>
        <textureName>      maps/gui/gui_bar.dds       </textureName>
        <materialFX>       1                          </materialFX>
        <tiled>            false                      </tiled>
        <tileWidth>        16                         </tileWidth>
        <tileHeight>       16                         </tileHeight>
        <shaders>
            <clipper>      301215592                  </clipper>
        </shaders>
    </SimpleGUIComponent>

    <ClipGUIShader>        301215592

        <mode>             0                          </mode>
        <value>            1.000000                   </value>
        <speed>            0.000000                   </speed>
        <delay>            0.000000                   </delay>
        <slant>            0.000000                   </slant>
    </ClipGUIShader>

</progress_bar.gui>

GUI file progress_bar.gui

Now that we know the names of the components, we can implement the GUI script. The script controls the progress bar via its method setProgress:

def setProgress( self, value ):
    clipper = self.frame.bar.clipper
    if value > clipper.value:
        self.frame.bar.clipper.value = value

Progress bar script file PyGUI.py (Controlling the progress)

This method simply maps the incoming progress value (between 0.0 and 1.0) to the clip value on the GUI Clip shader. The Clip shader will smoothly clip the component to the new value over a set amount of time.