Open wow2006 opened 7 years ago
Hi Ahmed,
I've never done this myself but I'm pretty sure you want to be creating a new Theme. Virtually every class that nanogui draws inherits from the Widget
class, so you can call setTheme
for the object(s) you wish to change. The default theme implementation is worth checking out for guidance.
One thing worth calling to your attention is the treatment of fonts, NanoGUI only vendors one font face and the resources are generated by cmake
itself. So if you need different font faces you basically have three options:
.ttf
extension).option
that would allow users to specify extra ttf
files to include.Happy to advise on (3) if you are interested but don't know how to do that, but the maintainer of nanogui is traveling / generally very busy so I'm not sure when (3) would get merged in if you did it :wink:
Update: another alternative that may actually be the easiest occurred to me. In your parent CMakeLists.txt
, before you add nanogui, you could also file(COPY ...
any .ttf
files you want into nanogui/resources
next to the other font files and it should "just work"!
Hi Stephen,
Thanks for your detailed answer. I am currently thinking to set Theme variables from json or yaml file as a start. What do u think?!
Since mTheme is built-in to the Widget class, and each property of Theme is just a member variable, subclassing Theme and adding new member variables doesn't provide any type safety. Any ideas on a good way to add new properties to the Theme class? Maybe I'm not seeing how Theme was meant to be used.
@wow2006 sorry for dropping off, json
and yaml
are very similar. If you're using the python side I'd say do whichever you prefer, the python json
library is excellent, but frontmatter
for yaml is also very easy to use (and largely the same interface). I guess in my opinion json
makes a little more sense if you are just reading in theme.json
, AKA the file you are parsing is only describing the theme. Yaml (in my experience) tends to be a meta layer on top of something (e.g. the yaml "frontmatter" for a markdown or restructured text document. So things like the title of the blog post and an abstract might appear in the yaml section at the top, and the blog post itself is the remainder of the document.
If you're in C++, I'd go with whatever is easiest to wield. I've never personally looked into json
or yaml
for C++ but I'm sure there are some nice lightweight parsers out there. You could also look at xml
, tinyxml2
is really easy to use.
In addition to using xml out of convenience for C++, it has the added benefit of tree-like structuring. So if you are already parsing an xml file, you could (if you're feeling really motivated), go as far as to define the entire layout of the GUI with the xml file. This is what Java switched to with FXML. Implementing this would probably get pretty tricky though, I don't see a transparent way to include callbacks etc in the xml itself. In all honesty, my gui generation code pretty much always ends up just being some long long method simply enumerating out everything I want to :wink:
@austensatterlee that's a great question, but I'm really not sure it's designed to be extensible. To my understanding the actual widget drawing for things like buttons, textboxes, etc are largely just passed through to NanoVG (nanogui builds on top of this, in some senses nanogui is "just" c++ bindings for NanoVG + fullstack opengl setup and teardown... + convenience classes like shaders, ...).
In short, I have absolutely no idea how the theme is actually used but I would be willing to bet that the member types of the theme class in nanogui are just being housed together to call the nanovg c functions. I would start looking at the simpler ones such as button on label and try and figure out where the theme comes into play? I've never even made my own theme for this, let alone tried to expand it x0
If anyone is interested, I took a stab at making the theme a little more extensible. Here's a link to the commit. I used the JSON for Modern C++ library to store all the theme attributes. This allowed me to serialize the theme easily. Also, you can set default values when you reference an attribute in case it is undefined.
I'm still not completely satisfied with this approach. I'm not thrilled with introducing a new dependency. There is still no type safety, and attributes are reference with strings during run-time. Also, I think ideally referencing an undefined attribute would trigger a compile-time error.
This all might be getting a little off topic for the scope of nanogui, but I'd love to hear from anyone with suggestions or references to past work that have dealt with this problem.
Hello,
I really want to customise GUI. If this way to global customise or specific widget theme?
Best regards, Ahmed Abdel Aal