Tutorial 5
From NaviWiki
Contents |
Tutorial 5 - "Peeking Pragmatically at Programmatic Navis"
Wouldn't it be sweet if we could just ditch '.html' files altogether? Why not just generate the HTML at run-time and feed that to Navi to use as a page?
Too good to be true? No way, we can do it!
Your First Programmatic Navi
using namespace NaviLibrary::NaviUtilities;
std::string myHTML = "<html><body><p>Hello world!</p></body></html>";
naviMgr->createNavi("myProgrammaticNavi", htmlToDataURI(myHTML), NaviPosition(Center), 512, 512);
Obviously the key function here is 'NaviUtilities::htmlToDataURI(std::string)'. It takes a string containing your HTML and converts it into a 'Data URI'.
A Data URI?
A Data URI is simply a string that contains an encoded representation of some data (HTML/Image/Sound, etc.). It can be fed into certain browsers wherever a URL is normally used. Thus, you can generate HTML at run-time, convert it into a 'Data URI' and feed it directly to Navi as if it were a URL to some page.
Local Specifiers
Because Navi parses your HTML string before converting it into a Data URI, it can do some pretty nifty things for you.
Data URI's have no real location, thus you cannot use 'relative' links/URL's in your page (there is no folder it is running from!). The trick is to use the 'local://' specifier. The utility function, 'NaviUtilities::htmlToDataURI(std::string)', will replace all instances of 'local://' in your HTML string with the absolute path to your NaviLocal folder (or whatever you set it to at NaviManager::Startup).
So let's say you have 'happyimage.jpg' in your NaviLocal folder. We could then write our HTML string like this (remember to escape your double-quotes!):
std::string myHTML = "<html><body><p>Hello world!</p><img src=\"local://happyimage.jpg\" /></body></html>";
Simple and clean.
OGRE Resource Specifiers
This is a pretty experimental feature because of the slight overhead of real-time encoding of Data URI's within Data URI's, however I shall teach you this dark art anyways. (I recommend specifying resources under 1MB for best performance)
Similar to how you may use 'local://' specifiers, you may also specify an OGRE resource to embed in your HTML string. The utility function, 'NaviUtilities::htmlToDataURI(std::string)', will replace all recognized specifiers with their equivalent 'Data URI' if the file is found.
Additionally, if you specify one of the following filetypes, its contents will be parsed for local and resource specifiers and translated accordingly:
.html, .htm, .shtml, .php, .asp, .xhtml, .xml, .js, .cgi, .css
There are two syntaxes for an OGRE resource specifier, both of which are required to be encased within double-quotes to be considered valid:
"resource://Group/Filename.ext" -- This version assumes default resource group "resource://Filename.ext"
Heres an example of how to write a HTML string using a resource specifier, again using 'happyimage.jpg'.
std::string myHTML = "<html><body><p>Hello world!</p><img src=\"resource://happyimage.jpg\" /></body></html>";
If you had an '.html' file in some OGRE resource directory, you can use 'NaviUtilities::resourceToDataURI()' to convert it and use it. Remember, regular '.html' files in the 'NaviLocal' folder will not be parsed for local/resource specifiers. Only when you convert it to a Data URI using one of the utility functions may you use local/resource specifiers in your HTML/JS/CSS.
Pearls of Wisdom
This programmatic stuff is pretty handy when it comes to security. You may wish to encode some of your security-critical Javascript/resources into Base64-encoded Data URI's and store them inline inside your application.
Encoding Data URI's in advance saves a few cycles, here's some really useful links on the subject.
If you haven't checked out NaviUtilities.h yet, I highly recommend you do so. I've verbosely documented some rather useful utilities available for use wherever you use NaviLibrary.
Who knows what else you might wish to do with this, you just need to get creative. For example, you might wish to take a screenshot of your game, encode it into a jpeg, and then transmit it to some website as a Data URI.
That concludes the contents of this tutorial, I hope you learned a thing or two (I know I did). Good luck and have fun. :P

