Facebook Twitter YouTube Frictional Games | Forum | Privacy Policy | Dev Blog | Dev Wiki | Support | Gametee


Thread Rating:
  • 3 Vote(s) - 3.67 Average
  • 1
  • 2
  • 3
  • 4
  • 5
GUI Tutorial Series
Abion47 Offline
Senior Member

Posts: 369
Threads: 22
Joined: Oct 2015
Reputation: 46
#3
RE: GUI Tutorial Series

Your Friendly Infomercial

Labels are good and all, but in terms of displaying text, they can be a bit limited. Also, what if we wanted to do something other than just simple text? This tutorial will introduce you to two new widgets - the TextFrame and the Image.

Table of Contents
The Basics
Getting More Advanced
Using SOMA's Built-In GUI Styles
  • StationGui (WIP)
  • UrbanGui (WIP)
  • Playing Audio (WIP)

Going Beyond Terminals
  • Setting Up a User Module (WIP)
  • Basic Heads-Up Display (WIP)
  • Target Info Module (WIP)
  • Player HUD Menu System (WIP)

Tutorial Requirements

For this tutorial, you will need the following:
  • A map with a prepared terminal, plus all the necessities.
  • A script file with a prepared OnGui terminal callback function.

Tutorial Source Files

Initial File
Completed File

The Tutorial Itself

We are tasked with making a professional-looking promotional display showing off the latest and greatest in technology. For some reason, someone higher up thought to give us the job, but hey, at the end of the day, a pay check is a pay check, right?

Let's start with a nice big header that will pop out and grab any passing pedestrian's eye. To do this, a Label would be just perfect, so let's set one of those up real quick.

cImGuiLabelData labelData;
labelData.mFont.mvSize = cVector2f(100, 100);

ImGui_DoLabelExt("Obligatory Omnitool", labelData, cVector3f(150, 90, 0));

As you can see, this is pretty similar to what we've already done in the last tutorial, with the only difference being a tweak to the position.

[Image: bmq6Uo9.jpg]

Next, we're going to need an image to show potential customers what it is they've actually been missing with their lives. To do this, we're going to need to introduce a new widget, appropriately named the Image.

Now unlike text, an image requires a bit of extra work to get done. When you pass ImGui an image file, it prefers that the file has already been pre-loaded into memory. The best place to do this is when the map first runs. Scroll up to the OnEnter function of your map script and stick in this code:

void OnEnter()
{
    ImGui_PreloadImage("inv_omnitool.tga");
}

What the ImGui_PreloadImage function does is it takes an image file and pre-loads it into the game. That way, when you give your image to ImGui, it doesn't need to bother with loading the image on the fly - it can just go and pull it from memory.

Now that we have that out of the way, it's time to actually draw your image. Head back to the OnGui function and put this code in after our Label code.

ImGui_DoImage(cImGuiGfx("inv_omnitool.tga"), cVector3f(530, 280, 0), cVector2f(500, 475));

As you may have noticed by now, the way the ImGui functions that deal with drawing widgets to the terminal follow a particular naming scheme. This function, ImGui_DoImage, takes a new form of widget data called cImGuiGfx as its first parameter. Like cImGuiLabelData, this type handles the customizable properties of a graphics asset, which in this case is an image file.

The second parameter should look familiar, as it's the same as what happens ImGui_DoLabel - you pass in a cVector3f to tell ImGui where the image needs to go. But it also has something new in the form of the cVector2f in the final parameter. This tells ImGui what size the image should be. If you don't specify this, it will default to the image file's physical size, which in this case would make the image quite small.

When you get that code put into place, it should look something like this:

[Image: 38Hgwhs.jpg]

Alright, we've got the eye-catching image and the attention-demanding title, but now we need some informational text to give the reader some more information about what it is they are looking at. We could use Labels again, but Labels only deal with one line of text at a time, which is fine for a brief snippet, but doesn't really work for a paragraph. What we need is a widget that will automatically wrap text around into multiple lines, and a TextFrame is just the widget for the job.

Underneath your Image code, put in the following. (It's a bit of a mouthful, so if you copy-paste this one I'd understand.)

cImGuiTextFrameData textFrameData;
textFrameData.mFont.mvSize = cVector2f(35, 35);
textFrameData.mColorBase = cColor(0, 0, 0, 0);

ImGui_DoTextFrameExt(
    "This is an Omnitool. Look at it's majesty. I bet you wish you had one. Well, unless you also want to live in a future world where robots and mutants comprise the only remaining lifeforms and the entire planet burns with the fire of a thousand evils, then I don't think you want one after all.",
    0,
    10,
    0,
    textFrameData,
    cVector3f(140, 340, 0),
    cVector2f(480, 360));

That's quite a lot of code! But don't worry, we can break it down into digestible chunks.

First up, we've got our widget data in the form of cImGuiTextFrameData, which holds the properties of a TextFrame. Like the Label, we set our font size so that we can actually read our text from further than two inches away. Unlike the Label, however, TextFrames come with a background color, which defaults to white. Incidentally, the TextFrame's text color also defaults to white, which is a bit of a problem. To compensate, we change the background to a nice fully transparent black.

Then we have the ImGui's draw function for TextFrames, the ImGui_DoTextFrameExt. The first parameter is the text that will actually go into the TextFrame, so that's self explanatory.

The second parameter is the amount of space the TextFrame will reserve around it's edges that it will not draw text into. (This is also called the "padding", for you web developers out there.) Because we aren't doing anything too fancy with the TextFrame, we can leave it at zero.

The third parameter is the amount of space between individual lines. Leaving this one at zero leads to potentially difficult to read text, so we'll throw in some breathing room.

The fourth parameter is the amount of extra space given to the first line of text. This is useful for if you're going for a sort of an essay feel and want to give your paragraphs a leading indentation. It's not really necessary for our purposes, though, so we'll leave it at zero as well.

The remaining parameters are what you've already seen so far - the widget data, the position vector, and the size vector. You should pay particular attention to the height of your TextFrame, as it will effectively clamp the number of lines in your text. If your text is too long, then any text after the cut will become lost.

Right, now that we've worked out what this code does, let's give it a go.

[Image: h3hwDk7.jpg]

That looks like a beautifully crafted advertisement if I've ever seen one. People would be absolutely mad to not want an Omnitool after seeing this bad-boy in action.

Now that I think about it, though, remember that massive line of text in the code from the TextFrame? It sure makes your code look a bit ugly. And what if you had to change the text in the middle of a big project... and you had to hunt down that one line to change it, only to find out an hour later that you need to change it again?

That sounds like a lot of headache and grief just waiting to happen. I wish there was a better way to organize the text of your terminals in a way that didn't involve sifting through rivers of code to change one letter...

Let's discuss that one in the next tutorial, shall we?
(This post was last modified: 09-03-2016, 08:05 PM by Abion47.)
11-07-2015, 11:11 AM
Find


Messages In This Thread
GUI Tutorial Series - by Abion47 - 11-07-2015, 09:27 AM
RE: GUI Tutorial Series - by Abion47 - 11-07-2015, 10:44 AM
RE: GUI Tutorial Series - by Abion47 - 11-07-2015, 11:11 AM
RE: GUI Tutorial Series - by Kanthos - 11-07-2015, 12:38 PM
RE: GUI Tutorial Series - by RaideX - 11-07-2015, 01:28 PM
RE: GUI Tutorial Series - by Abion47 - 11-07-2015, 02:52 PM
RE: GUI Tutorial Series - by Abion47 - 11-08-2015, 03:38 AM
RE: GUI Tutorial Series - by A.M Team - 11-08-2015, 12:46 PM
RE: GUI Tutorial Series - by Abion47 - 11-09-2015, 01:28 AM
RE: GUI Tutorial Series - by Abion47 - 11-09-2015, 02:57 AM
RE: GUI Tutorial Series - by Abion47 - 11-10-2015, 05:06 AM
RE: GUI Tutorial Series - by Vale - 11-10-2015, 08:00 AM
RE: GUI Tutorial Series - by Abion47 - 11-10-2015, 08:03 AM
RE: GUI Tutorial Series - by Abion47 - 11-27-2015, 01:20 AM
RE: GUI Tutorial Series - by Abion47 - 07-12-2016, 07:52 PM
RE: GUI Tutorial Series - by Abion47 - 07-12-2016, 10:04 PM
RE: GUI Tutorial Series - by NewPueblo - 09-03-2016, 12:09 AM
RE: GUI Tutorial Series - by Abion47 - 09-03-2016, 08:02 PM



Users browsing this thread: 1 Guest(s)