Jump to content

The GUI Lib of Babylon.js


Nockawa
 Share

Recommended Posts

Hello people,

I start this topic in order to give you my intents, visibility and get early feedback from you.

I initially developed Canvas2D to serve as the foundation of a new GUI Library that would be built on the top of it. That's why you actually can find many features in the Canvas2D that are related to GUI (Pointer Event, Alignment, Positioning, etc.). Many of you started to write little wrappers to create GUI components on the top of that. Depending of what you're trying to achieve it can be easy/feasible or pretty hard.

I've spent the latest weeks to stabilize Canvas2D and I'm now starting the GUI library (while still fixing C2D bugs being reported, when they're important).

This post will explain you what I've designed so far and what I want to do: I build the GUI Lib for myself but also for you, the community. So the earliest I have your feedback the better chances I can make it the way you want it to be!

So please read, think and give feedback! :)

The GUI library will have the following core features:

  • Data Binding mechanism: in order to display/refresh data in the GUI without having you to write all the wiring manually. You will still be able to do so, but I hope the Data Binding feature will be convenient and easy enough for you to use it. It will also be able to use it to update a model object with data the user would enter via a Form like Window.
  • Commands: GUI is about responding to user input, which triggers events. These events can be encapsulated in a more generic feature which would be the Command one. The simplest example is being the Button control which exposes a single Command: "Click". You as the user, don't care about how is triggered this command, in fact it can be triggered from a Pointer Event Up, but also from a keyboard shortcut. The purpose of Commands is to give you a semantic that you understand and a way to respond to it.
  • Templating/Styling: Each control will have a default look/style, for instance a Button will by default looking like a Bootstrap Button. But in order for the lib to be successful, it's critical to separate logic (i.e. a button is a control design to trigger a single Command called "click") of the rendering. Because you may be fine with the default look of the button or you may not! So I have to give you the tools for you to give a custom look in order for your buttons to blend with you game/app the way you want.
  • State Manager: A button has many states: enabled (default state), disabled (you can't click), hovered (ready to be clicked), pushed (clicked but not released), etc. Each state which is not the default one will give additional changes on the style for the user to be able to identify this state from the others. Transitions between states through animation will also be possible.
  • Content Presenter: when you create a button, most of the time you want its content to be a text, for games you may also want a combination of text and/or picture. But the content of the button should be arbitrary: it could be anything. Remember, the intent of a button is to provide the user a visual info of the command he will trigger by activating the button. Content Presenter will give you the ability to put whatever content you want in controls that are using it. For simple content like Text or number, you won't have anything to do. But for Picture or custom content you will have to rely on what is called a Data Template.
  • Data Template: the Data Template is a way to associate a Visual Rendering (through a Tree of Primitives) corresponding to a given custom data object. For Instance you may want to create a custom type with two fields: Label: string and Picture: string. Then you will associate this custom type to a Primitive tree made of a Group2D containing a Text2D Primitive and a Sprite2D one, you will rely on Data Binding to map the content of the Text2D with the Label field and the Picture of the Sprite2D with the Picture one.

Controls

  • ScrollableContent: this will be more a Control component than a real Control. You'll be able to use it when the logical content of a Control will be bigger than the allocated content. In such case ScrollBar will appear for the user to be able to scroll the content and view what he/she wants.
  • Button: you can guess now what it's about
  • SceneContent: by assigning a Scene and an Active Camera this control will display the content of the Scene through the camera
  • ItemsControl: will be a base class that gives the ability to manage a list of items. You will have a specific Data Template that will be used to render one particular item.
  • ListView: will be the first Control inheriting of ItemsControl, design to display a collection of objects.
  • Then others controls like: Label, CheckBox, Slider, ComboBox, TreeView, Accordion, Menu, ContextMenu, TextBox, ProgressBar, ColorPicker, PasswordBox, TabControl will be designed/developed.
  • Layout Control will also be built: Grid Layout, Responsive Grid Layout, Stack Panel are on the top of my mind.

Some architecture facts

  • The GUI Controls won't be Primitive based classes. It will be classes that instances make their own logical tree that describe a given UI. But it will be from this tree that the Visual Tree (made of Primitives) will be built/updated.
  • DataBinding will be essential to develop Data Template and Styling, but you won't have to necessary rely on it to use the GUI, you can set the data directly if you want: either way will be fine, you choose the one that fits you best.
  • You will be able to declare a Tree of Controls the same way you can declare today a Tree of Primitive, with a new Statement, then a series of attributes and the children attribute that can be used to declare the direct children.
  • No designer will be built in the short term, short term will be about performances and feature range.
  • Performances will be key, I finally will push the best Caching Strategies to make sure static content is drawn as less as possible.
  • You will be able to use if for Screen Space or World Space.

Schedule

  • In four weeks I intend to deliver an alpha version with the bar minimal, for people to try it out
  • Four weeks after I hope to release the first beta with a limited set of stable controls
  • After we will see! :)

By the way, one of the first contribution regarding babylon.js will be the total redesign of the Debug Layer using this lib! It will be a perfect test!

 

Link to comment
Share on other sites

20 minutes ago, NasimiAsl said:

wonderful

i wait to see DataBinding from Webapi2 

any option for websocet and data pushing?

My web skills are very limited right now, so I'm ready to consider anything, but I'll need some help! :)

Can you give me a practical example of what you would like to have/achieve?

Link to comment
Share on other sites

I'm hoping I'm seeing some influence from WPF in your conceptual model - if so I'd be delighted - for me WPF is the culmination of many iterations of GUI frameworks from Microsoft and it has many excellent features. You don't say anything about a declarative means to define the GUI elements and layout. WPF's XAML is very good and you're probably aware there are open-source projects that parse it and generate equivalent HTML5 layout in javascript, so there could be some opportunities for cooperation there. I wish you every success with this project - looking forward to the first releases!

Link to comment
Share on other sites

1 minute ago, Mike Pelton said:

I'm hoping I'm seeing some influence from WPF in your conceptual model - if so I'd be delighted - for me WPF is the culmination of many iterations of GUI frameworks from Microsoft and it has many excellent features. You don't say anything about a declarative means to define the GUI elements and layout. WPF's XAML is very good and you're probably aware there are open-source projects that parse it and generate equivalent HTML5 layout in javascript, so there could be some opportunities for cooperation there. I wish you every success with this project - looking forward to the first releases!

I feel the very same concerning WPF, but I was (rightfully) warned than the inherent complexity of WPF wouldn't be the best thing to replicate, and I agree on this one.

I will borrow some WPF things (you'll see with data binding that it's close, but simpler, because well, I won't write WPF in WebGL all by myself too ;) ), but I have to be very careful of making the learning curve as smooth as possible. WPF is the most advanced and well designed GUI lib imho, but it's also a very complex on to learn. babylon.js is about simplicity and we will keep that for every component we build. That's where the real challenge is: flexible, but yet simple, not always the easiest thing to do but simplicity must win no matter what.

Concerning the declarative point, this is for me a "secondary thing", don't get me wrong, I know it's very important, but even if I will more than welcome contributions, as of today I'm alone and I must make choice.

As a starting point, I was planing to rely on the same kind of declaration as the Canvas2D is using today, it's "code", but somewhat pretty declarative, but you can't make it something like a "resource file". Many people to whom I talked about the feature raised the same concern as you, if there's suggestions/proposition, I'd love to talk and on-board people. But right now my web/js skills are limited (I come from the C++/.net world, just recently came to the web) so these are topics I can't deal all by myself.

Link to comment
Share on other sites

  • 3 weeks later...
3 hours ago, Pryme8 said:

You should message me and we should talk... UI stuff is kinda my specialty.

For now I stick to the plan I wrote in the first post. I've coded GUI Libraries from scratch more than once, I'm pretty comfortable so far. But thanks for the help.

I will share the work as soon as possible for people to give feedback, but at this point I think it's a bit too soon.

But I will have soon a "Button" control working to illustrate some of the main mechanics, I hope we can exchange thoughts at this point.

Link to comment
Share on other sites

  • 3 weeks later...

Hello so you programing something new, i have a request can you minimaze the amount of letters in functions keys and everything, 

i dont know its a personal thing i think. but 
backgroundborderfill : BABYLON.Canvas2D.GetGradientColorBrush(new BABYLON.Color4(1.0, 0.7, 0.7, 1))

this should get the world genuine record for longest object declaration & it
hurts
using abbreviation 
e.g bgborderfill :  BABYLON.C2D.GetGradientColBrush(new BABYLON.Color4(1.0, 0.7, 0.7, 1))

idk i think its all about size on the web and also loading time, i can have an great app but it loads just 2sec longer than one from my opponent due the browser has the phrase all this letters

Link to comment
Share on other sites

4 hours ago, Nabroski said:

Hello so you programing something new, i have a request can you minimaze the amount of letters in functions keys and everything, 

i dont know its a personal thing i think. but 
backgroundborderfill : BABYLON.Canvas2D.GetGradientColorBrush(new BABYLON.Color4(1.0, 0.7, 0.7, 1))

this should get the world genuine record for longest object declaration & it
hurts
using abbreviation 
e.g bgborderfill :  BABYLON.C2D.GetGradientColBrush(new BABYLON.Color4(1.0, 0.7, 0.7, 1))

idk i think its all about size on the web and also loading time, i can have an great app but it loads just 2sec longer than one from my opponent due the browser has the phrase all this letters

Well, for solid color brush you can do: backgroundbordefill: "#FFB4B4FF"

I'm concerned about the size/lenght of methods, but I'm also about their meaning. I don't know how I could have made simpler GetGradientColorBrush, @Prime8 thought this call could create a radial gradient and he's not wrong, because I don't explicitly say in the method's name it's a linear one. GetLinearGradientColorBrush would have be clearer but longer... and I can't remove the "ColorBrush" part, because the language doesn't allow method of the same name returning different types (for obvious reason).

But I'm not the best person to decide where to put the cursor on this matter, my web experience is not good enough. Maybe @Deltakosh has some thoughts to share?

Link to comment
Share on other sites

Hello

Yes, this is my criticism on babylonjs in general, i would shorten some of the words down.

Their is no need to write a essay when programming, and even if i minify the words will not, due the most minifier dont know babylonjs.This blow up everything. 
I have less experience in programming industry or game engines, i see also no win for an inexperience users, be-course the good documentation, and intelligence sense in the playground. 

I also get a point from 1+1=2 & m+m=2 more that

GetfirstVariable plus GetsecondVariable SummaSumarum SetfirstplusSecodVariable

Math equesion are easy to read and understand. 

And i didnt know know that i could simply type 
backgroundbordefill: "#FFB4B4FF"

for
BABYLON.PointerEventTypes.POINTERDOWN you also can type 2 how many bytes are saved ?

their should be an own minifier for babylonjs. i also would use 32bit instead of javascript 64bit :)

We are all artist thank you for take time to talk and collaborate. 

This is my personal opinion.

Best

Link to comment
Share on other sites

13 minutes ago, Nabroski said:

Hello

Yes, this is my criticism on babylonjs in general, i would shorten some of the words down.

Their is no need to write a essay when programming, and even if i minify the words will not, due the most minifier dont know babylonjs.This blow up everything. 
I have less experience in programming industry or game engines, i see also no win for an inexperience users, be-course the good documentation, and intelligence sense in the playground. 

I also get a point from 1+1=2 & m+m=2 more that

GetfirstVariable plus GetsecondVariable SummaSumarum SetfirstplusSecodVariable

Math equesion are easy to read and understand. 

And i didnt know know that i could simply type 
backgroundbordefill: "#FFB4B4FF"

for
BABYLON.PointerEventTypes.POINTERDOWN you also can type 2 how many bytes are saved ?

their should be an own minifier for babylonjs. i also would use 32bit instead of javascript 64bit :)

We are all artist thank you for take time to talk and collaborate. 

This is my personal opinion.

Best

well, I will tell you about my own personal experience, I've been writing 3D Engine and programming professionally since 1995 (not to brag, only for you to get an idea), and I've been through all different phases concerning this topic.

The context was different when we didn't have things like Intellisense, but I assume that nowadays it's a must for everybody developing.

My experience on this topic is the more you hide, the more you'll pay about it later. C++ with short methods name, using #define to redefine things may look very appealing at first, you think you'll save some time, but few months later when you go back on a code you didn't touch for that much time, it's getting a nightmare, and I don't talk about the other people on your team.

For many years now (at least 10) I took the position to not hide things, to be clearer as possible (but still trying to be reasonable, which is subjective), it will end up in long methods name, but it's clear, people should expect the general behavior/purpose only by looking at the name.

The constraint of the js code being download is certainly something I didn't consider "enough", but I don't think I would have changed my mind, because at the end of the day, in production you use gzip compressed jsfile and gzip compression dictionary handle this things just fine, if you have a compressed "mymtd" instead of "mysuperusefulmethoddoingthat" won't change that much in the final compressed file size.

So I guess my point is: use the CDN or compressed hosted js files.

Link to comment
Share on other sites

  • 3 months later...

I prefer long names that describe what a method does as exactly as possible. Everything should be human readable. I don't want to have to think about what the abbreviations in a method name could mean. I wanna see it, understand it, use it. If a method name is too long to understand but it describes what the method does, you should refactor the method and split things up. For file size: i think it doesn't matter at all since you can always compress your code and all names will be shortened anyway.

So I think readability/maintainability should have first priority!

 

Quote

There are only two hard things in Computer Science: cache invalidation and naming things.

-- Phil Karlto

source: https://martinfowler.com/bliki/TwoHardThings.html

(By the way: I used Canvas2D a bit now and besides great performance and good documentation the method names feel pretty good to me, so awesome job @Nockawa!!! :) )

 

Link to comment
Share on other sites

@Nabroski  I hope you realize that I'm not following the convention of the Win32 example you mentioned, I don't remember its name, but it's a conv when you specify the type in the name, like hCursor (h for handle) lpszClassName (lpsz for long pointer string zeroed), yeah I did a lot of Win32 back then, 15 years ago...

I follow the convention of the JSON example you have: instead of naming the position "pos", I do name it "position", same for "attributes", it could have been shortened as "attrb". Now you may think that I use something closer to Win32 because the reality is: thing I'm doing so far are complex, with a lot of different options and separation of concern is hard to get (i.e. everything is defined in the same domain area, I can't really create many domains) so when I have several "position" I can't use the name "position" and let the user figuring out in which context/domain it's expressed. So I use a full name for the user to not have doubt of what we're talking about.

And I won't back down on that, today you have most of the IDE using intellisense, I'm writing TypeScript and if people want to suffer using Javascript: it's their choice, not mine...

Link to comment
Share on other sites

@Nockawa  lpszClassName  looks good and the json too
 

and things like this
BABYLON.C2D.GetGradientColBrush(new BABYLON.Color4(1.0, 0.7, 0.7, 1))
pops out, this is mostly where the bug happens, be course  i as a programmer did not a code cleanup or don't really know what im doing. 

 

Working in shapes always pleases the eye 

Kind of code formatting without code formatting.

//1/2 haiku nabr

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...