Sandbox Logo
06 May 2020

Exploring Panorama

Panorama is the UI system Valve uses in Source 2. Here's how I'm hoping to use it in Sandbox.
Garry Newman
Programmer
UK

Internally it's like VGUI with panels and controls, but with the scheme stuff replaced with xml and css for styles. 

So it's technically not a HTML renderer, like webkit, but at the same time it's kind of rendering html, so it is.
Here's what some of the Panorama from CS:GO looks like. There's also some documentation on Valve's wiki. This isn't what it looks like in Sandbox.

Layout File


The layout file is an xml file. It kind of looks like html but it's harder coded. It can pull in styles and javascript files.

Stylesheet File


The stylesheet files are an enhanced css, they have new/different properties and @defines.

Javascript File


This is standard javascript with some exposed game engine bindings. 
We don't need javascript. We have hotloading c#. So javascript can get fucked.
Game UI using stylesheets is my wet dream. 

One change I made was add .less support so we could have nested properties to make things more readable.

There's a few new properties in Panorama that are a bit too verbose for me, and some that don't behave like in regular css. 

I'm going to look at fixing it all up at one point, but for now I've left it as it is.
I ended up writing my own layout system. There were enough changes I wanted to make to justify it. I'm still developing and testing, but here's what it looks like so far.
In Panorama each element name has to match a control. I got rid of that. If an element doesn't match a control it creates a normal blank panel. That way you don't have to create classes for everything, you can style via the element. They're also case insensitive now.

I made it so you can have inner text, and that'll be used for the content of the control if appropriate. This means you don't have to html encode special characters because they're not in an attribute, making things a bit more readable. This obviously doesn't account for localization right now - but I'm going to do something similar to what we do for Rust there.
If you look at the layout, you can see that it has "@text=" as one of the properties. This binds it to the value on the context object (which is by default the panel that applied the layout). So what this means is that if "InformationText" changes on that instance, it automatically updates that property. 

You can also see that we have onclick/onmouseover etc functions. These are calling the c# function on the panel.

One big benefit of Panorama over using something like Coherent is that we have access to the panels, just like we did in GMod. So if you want to code all your UI instead of using layouts, you can totally do that.
I'm still exploring which controls to take from Panorama and which are worth implementing in c#. There's no way I want to re-implementing shit like the TextEntry control or scrolling - which already work great.

Here's my little experimental panel so far.

I chose to start with Panorama because it's in Source 2 but also it's in CS:GO and  and we have access to that via the Garry's Mod license, and I don't think Valve would be pissed that I'm dipping my toes in like this.

I'm avoiding messing too much with the internals because I don't know if this is the exact same code that is in S2, so don't want to end up in merge hell.