Proposal improve of look and feel of Juce's applications


#1

To continue the discussion from the other thread, I was saying:

  1. With upcoming projucer, realtime control of component’s features & painting is within reach, which is very good, but at the same time risky, since it can lead to a more fixed design.
    (The developer will tweak up to the last pixels of his application, but at the same time the final user will not be able to do so)
  2. CSS proved an efficient way to specify the styling of an application.
  3. Current look and feel is too “code based” and unless you only want to change the color at runtime, it’s not possible to specify anything else without recompiling.
  4. Animations and transformations are currently too “manual” in Juce application, if even possible.

On the good side, Juce has a good SVG renderer (even if not complete, it covers 99% of the use case), a good renderer, a good translation engine (but a bad printf’s like string formatting).

I’m proposing the following ideas to improve the end-user configurability:

  1. CSS is a standard, let’s use a “CSS” compliant language to describe the configurability so no new language is required to change the look & feel of the application.
  2. Make the component’s class more CSS’s based, by hooking the CSS’s required functionalities in virtual methods that are calling the usual methods if no rule applies to the component.
  3. Cache the results of computation so CSS’s code is not slower than the current code
  4. Add a CSSLookAndFeel class that’s perform the rendering of components based on CSS’s rules & features & SVG path description (if any required), that is, no more hand-drawn component in the look and feel.
  5. Add an animation & transformation framework that’s at least as good as JQuery/CSS3 (including the possibility for a developer specified callback/customization)

I understand Valley’s remark on the CSS box model complexity, and completely agree, but at the same time, we need a way to position components dynamically at a given time & space.


#2

I have very little spare brain-space to help, but will watch this thread with interest!


#3

I’m very interested about that discussion, and by what has been said previously on 3d interfaces. Do you have any information source about how 3d interfaces are done on video game consoles ? And eventually how I may be able to code myself some parts of that with JUCE ? :mrgreen:

Anyway, I’m feeling some shame to talk about that, because I contribute to help Jules adding new things in its future to do list, and developing fun classes instead of font gl… ehhh i mean instead of AAX :mrgreen:


#4

There seems to be consensus of some sort forming:

  • Projucer style editing of Look and Feel
  • Skinnable interfaces
  • 3D transitions
  • improved animation controls (CSS-3 style?)

I don’t really know how CSS animations work, but if they are regarded as the best, I’ll run with it. But maybe someone can break it down a bit? Some example functions and a very quick run down of involved classes?

Personally, I’m thinking that layout needs to move to 3D, and wrap in with the Component Parent/Child system. So, for instance, I may have a carousel picker class. Each ‘tab’ I add will be positioned in 3D space by the Carousel class. The carousel will have code to rotate as the user interacts, and will allow picking of the frontmost tab, at which point, it will animate that tab and the others to give it focus. When the carousel ‘hides’ it will also animate all it’s children as needed. An interesting on/off transition seems to be a feature of newer interfaces.

(This could probably be done right now, in OpenGL, with some Juce helper functions to put 2D Component Images in, but Juce is still best with only one OpenGL component).

I’m not even sure how an ‘animator class’ would fit in… maybe the carousel has/is an animator and adds movements to the children?

Bruce


#5

Bruce, this site gives about the best 5 minute primer on CSS transformations and easing that I’ve seen:

http://www.the-art-of-web.com/css/css-animation/

I don’t know that I’d describe CSS transformations as the best. JQuery isn’t going anywhere any time soon. If Jules bends to X-Ryl669’s will and implements a a CSS alike interface for components, then CSS animations would be useful for describing common use cases such as:

  1. animations that are essentially naive; you’d never need to write flashing button code again, just apply the ‘flashing button’ style to the button, and let it do its thing.

  2. transformation/presentation animations, I.E. drop a component on a non-receptive target and a style that eases the component size and location back to its source, whilst also iteratively reducing the opacity.

These kinds of thing would be pretty simple to do.

Complex animations can be described in CSS but after while the sensation becomes a bit like trying to solve every text issue with a regexp, for 99% of cases you can, but for 20% of those cases you could have done it far more quickly with a brute force for-next.


#6

OK. More simple than I expected. Close to the sort of thing I was discussing: http://www.the-art-of-web.com/css/infinite-photo-carousel/
Although: I had a fuller 3D world in mind, where all the elements are live, just the world or elements can be moved to focus on a different part, these examples use a trick. But very simple and usable.

So, one point seems to be that the transitions or actions are attached to the object, as opposed to being issued to a central animator?

Bruce


#7

[quote=“Bruce Wheaton”]OK. More simple than I expected. Close to the sort of thing I was discussing: http://www.the-art-of-web.com/css/infinite-photo-carousel/
Although: I had a fuller 3D world in mind, where all the elements are live, just the world or elements can be moved to focus on a different part, these examples use a trick. But very simple and usable.
[/quote]

Nearly all CSS beyond the essential layout stuff comes down to conceiving a neat way to abuse the layout engine.

For CSS that’s close to it. Everything has a style. Styles are specified on elements by inheritance, type, class, id, pseudo-class, or some combination thereof. ANn ‘id’ is (should be) a unique identifier for a specific element on page. A ‘class’ is a tag that you can apply to multiple elements. ‘type’ refers to the element type, I.E. images or links. We could use RTTI to approximate this I guess, but I don’t much like the feel of it. A ‘pseudo-class’ refers to an element in a specific state, I.E. a button that is down rather than up, or an element that is the first entry in a list. The inheritance model describes which styles elements inherit from their containers, but it’s debatable how useful that would be for us.

Finally, you can do fiddly style specifiers like

div.contents > a.title:visited
{
}

which would set a style on any links that have the class ‘title’, and that are contained somewhere inside a div that has the class ‘contents’ when that link is clicked.

This would somewhat override a more general style of the form: a.title:visited{} since this latter style is less specific in terms of its target.

It’s this aspect of style sheets that leaves me feeling them a little overkill for our needs. The broader concepts I like though.

Note also that in the HTML form style sheets aren’t necessarily well suited to custom components. I.E. a complex javascript table view exposes all of its gubbins to the style sheet editor, which may or may not be what you’d want.

Personally I’m less concerned about abstracting the layout from code, especially if the Projucer is all Jules believes it will be. I would like to see more of a delegate/mixin model for the LAF class though. A CSS alike selector system that can choose an appropriate C++ module from those registered with a LAF and apply it to an element would be very powerful, and potentially allow for further decoupling of code.

I.E. let’s say you create a carousel widget. Your widget can draw itself completely natively, but it registers itself as a module with the system component registry, and registers some ‘elements’ that it exposes. If I use your carousel, I can call the LAF and either provide some standard CSS styling that I want applied to elements, and/or some callback methods for custom rendering (I want the reflection to ripple when the carousel is spun). X-Ryl669 was tossing around an idea of an animation pipe-line, and that’s worth throwing in the mix here too. Once I’ve added your component to a parent, and set my style, I’m good to go. Everything takes care of itself.

Components that support the CSS model might have a different paint signature perhaps paint(Graphics& g, Style& s), where the Style would be the current style that should be applied, and may contain callback functions that can be called to do outside work.

(thinking entirely out loud, as I can see at least a few issues with this quick brain dump).


#8

[There’s some thread sprawl going on, so for passers-by, see also: http://www.rawmaterialsoftware.com/viewtopic.php?f=2&t=10098 ]

I’ve forgotten how to merge threads in phpBB, or maybe I don’t have that level of admin. Jules?


#9

AFAICT you do have permission, I think it’s in at the bottom of the page in the quick mods list.


#10

Right-e-o, I’m being slow; merged. Ta Jules.


#11

I’m with you on some of this:

Not so much. The Juce style is to make better code. I think trying to do away with code would be swimming against the stream, and adding a new layer for everyone (except you : ) to learn. I’d rather take the best of the CSS approach and mix it with the juce approach. So there could, for instance, be a style class (that has C++ code in it) that can be attached to a Component. Maybe more than one could be attached, with order determining the effects.

Meh. I suppose all styles could have a common base class that does nothing, and a developer could inherit too. Or maybe stack classes, if you need two actions.

Hopefully wouldn’t be needed if we don’t actually use CSS.

That’s a nice idea - what Jules was going to use in the presumably aborted pre-ProJucer plans. So one ‘Style Class’ would use SVG to paint, thereby being resolution independent and somewhat user editable (for skins).

I’d extend that, so that the object has a position and animation in 3D space in reference to the parent. Haven’t got my head around the callback thing… it sounds a bit bodgey. If a Style is C++ code, and it works by calculating every frame, then that is the callback, right? For more enhanced effects, I think GLSL shaders would be the way to go - vertex or fragment. They can be user editable too.

Bruce


#12

X-Ryl669: I guess what I’m not quite sure about is where you intend to insert CSS behaviour. Border for example is giving me a headache.

Let’s say I have a tree view: does the treeview honor border? Do I need to place the treeview inside a CSS container component that knows how to border and apply the box model? What if I want rounded corners, where does the clipping occur? Does the tree view have to honour overflow? What happens if I set overflow:visible?

:?


#13

I don’t know if it’s relevant to look for what others have done about that, but I do know that a lot a SDK for games provide such functionnalities. For example :

http://clanlib.org/wiki/Main_Page

I would like to do that with JUCE :

http://clanlib.org/wiki/File:Example_gui_3.png

:mrgreen:


#14

valley, the link you provided showed the initial transform in CSS, not what’s supported in CSS3.
If you want to see what you could do with CSS3 model, you’d look here instead: http://lab.hakim.se/scroll-effects/ (scroll each list with a CSS3 compliant browser)
Check the source code, it’s very simple.
Please notice that the animation is expressed in CSS3 not in Javascript. And so are the 3D transform, etc…

I was more thinking of a subset of CSS, than the whole CSS model completely.
I hardly see a link between the DOM and Juce’s component’s hierarchy in an application, so the whole DOM specific stuff would not apply.
We could hack something to vaguely match table’s specific rules to TableListBox for example, and so on, but I would rather avoid that, since this would freeze the interface on the code side.

Concerning the box model I’ve talked before, I was speaking of description we could use inside the LookAndFeel’s implementation for drawing (and for “small” positionning, like padding/margin/width).
Something like:

.TextButton
{
    border-radius: 3px;  // Rounded corner drawing
    background: url("textBackground.svg") no-repeat transparent;
    border: 1px solid;
    padding: 5%;
    margin: 2px;
    font-family: sans-serif;
}

In my view, in the example above, the rule applies to all TextButton, and is self describing.
We could use the Component’s id / name to match a more specific rule:

#ok
{
    background-color: green;
    font-weight: bold;
}

#cancel
{
   background-color: red;
}

And we could abuse the hierarchy to be more specific, for example:

.AlertWindow #ok
{
    background-color: blue;
}

or 

#AlertWindow.ok
{
    background-color: blue;
}

We could also support absolute positioning (only), with “position: absolute; top: 34px; left: 35%;” which is kind of what the Jucer does.
Concerning TreeViewItem and other, they would just use whatever class and rely on it for styling like in the example above.

That doesn’t prevent having an animateComponent() with callback or predefined effects if one prefer using the native code instead of a CSS describion.


#15

[quote=“Wolfen”]I don’t know if it’s relevant to look for what others have done about that, but I do know that a lot a SDK for games provide such functionnalities. For example :

http://clanlib.org/wiki/Main_Page

I would like to do that with JUCE :

http://clanlib.org/wiki/File:Example_gui_3.png

:mrgreen:[/quote]
Me not. Complete nonsense gui.
Anyway the link is very interesting. It’s not the exact same thing, however.


#16

A few weeks ago i had the idea for a (html-like) ComponentLayouter, which could speed up things

class MyComp : public Component
{
  MyComp()
  {
		cl.createFromXML("MainGUI.XML");
		//add some addidional elements
		cl.addOwned(new Textbutton("Push me")).addStyle("left:20px");
		cl.addOwned(new Slider("BlaBla)).addStlye("width:80%");
  };
  
  void resized()
  {
		cl.layoutComponents(this);
  };
  
  ComponentLayouter cl; 

};

But also i thing CSS is a very bad standard (just to overcomplex, imho all this HTML/Javascript/CSS crap needs a completely redesign :wink: )


#17

Of course :lol: I mean that if you can do that, then you can do other more interesting things ! I think that the GUIs of menus, title screens etc. in video games and consoles are really inspiring…


#18

No, the link I provided gave a quick overview with explanation of how CSS transformations work, rather than just a ‘hey cool’ demo. If I was trying to make point I’d have sent him to look at pointless CSS AT-ATs.

OK, I can abuse an otherwise blameless listbox like that (which I did already know), but why would I want to? Like I said earlier, CSS lets you do all kinds of cool stuff, but much like reg-exp when you start getting into the sophisticated stuff, it’s seldom something that couldn’t be more readably expressed in code.

But see that’s what I’ve alluding to all along. CSS is designed to be a web styling system. It’s big and complex. Sure we can cut it down to size, and strip out all the stuff that doesn’t map, but then we don’t have CSS; we just have curly braces and a handful of property names that Jules’d likely have chosen anyway. What’s the gain over a custom XML schema, or possibly better yet, JSON/YAML?

It seems to me we’ve got two (three?) distinct issues going on here, and conflating them I think is getting confusing.

There’s seemingly a desire for a clean integrated way to create dynamic component transforms. There’s also interest in a meta-languge for application styling, this could even be useful in the Projucer as one could paste a complete style (lowercase ‘s’) onto a component in real time. I would like, and I may be alone in this, to see the LAF become a better partner to 3rd party components.

CSS gives a possible road-map that could cover much of the first two scenarios, but IMV it only gets us about 80% if the way there, and that other 20% is going to be clunky. I’ve never made a web site yet where I didn’t have to make design compromises to meet the limitations of some aspect of CSS. I tolerate that on the web because broadly speaking, I appreciate all the other riches that CSS and HTML bring in terms of accessibility, targetable display types, etc. I wont tolerate it in a C++ library though because I feel the ability to implement novel interface choices when the need arises is important.

Regards the border-radius thing though. I asked about treeviews. Buttons are a trivial case. Components that contain other components, but need to perform corner clipping add a lot of complexity to standard library components that’ll be extremely unlikely to ever need that functionality, and again if we go half-way and say border-radius only on a sub-set of components, we’ve now got something that isn’t even a sub-set of CSS, and in terms of accessibility to new developers would be as documentation intensive (explain all the places where our CSS is not that CSS) as a whole new language would be.

I’m still not buying it. I like the idea of giving components a class (or perhaps ‘tag’ since class has another meaning here) array. I could even quite easily be sold on hierarchical selectors. Trying to cling too tightly to CSS, or to imagine away the need for code logic seems to be a stretch though.


#19

[quote=“valley”]
It seems to me we’ve got two (three?) distinct issues going on here, and conflating them I think is getting confusing.

I’m still not buying it. I like the idea of giving components a class (or perhaps ‘tag’ since class has another meaning here) array. I could even quite easily be sold on hierarchical selectors. Trying to cling too tightly to CSS, or to imagine away the need for code logic seems to be a stretch though.[/quote]

+1

I’ve done some nice animations with just alpha and transformations, but I’ve been doing matrix math graphics stuff on and off for decades. There is definitely some room for some nice higher level helpers as well as lower level helpers like gravity and interceptions, but once that gets mixed in with dynamic styling, it’s hard for me to follow.

I, personally, don’t have a real need for a style abstraction layer, so a lot of that discussion hasn’t interested me. But CSS would seem to be an especially bad fit for juce. There is no way to ascend the selector hierarchy, you can’t name rules, you can’t nest rules, you can’t enter values as simple expressions and, for all it’s complexity, it really is still just a style syntax with only the most rudimentary layout functionality. I’ve seen several references to JQuery but, to me jQuery, and especially jQuery mobile, highlight the deficiencies of CSS, not it’s benefits. Most of the magic is through liberal use of run time code and the actual ability to theme using just a css style sheet is remarkably limited. And, when you try to use a fancy animation loading one jQuery web site from another, you generally run smack into the limits of CSS and get graphically unpleasing results.

To be clear, my trouble with CSS isn’t that it is a crappy standard. Many standards are really crappy and, once there is a committee, often overly complex. I just don’t see how it would blend well with a heavily polymorphic system.


#20

I think you have not read the source CSS file for the demo.
I could not figure something clearer.

CSS3 animation declare keyframes, loop mechanism, etc, in a very well documented standard and that’s exactly what an animation system requires.
Transformations are easy to understand (provided you understand a rotation/skew/projection matrix).

There is a real canyon between CSS2 transform and CSS3.
Reusing CSS3 model simplify the documentation task (and, for me documentation is the major task in any code writing), and does not force developer to learn a new “specific” language for styling.

(FYI CSS was not made for the web, but was used for it, I agree 99% of CSS use is done for the web).

The gain is obvious. You don’t learn a new syntax (with all its shortcoming), you don’t have to support peoples making mistake in this specific syntax, you have a documentation for your styling syntax that’s free to use and already written better than you could either do, and you can try your style on something else that your software to make sure it’s working/fast prototyping, you can have designer do their work without bothering the programmer (since designer knows CSS better than you do), etc…

When you have an issue, you can ask whatever CSS guru, and not Jules only for solutions.

As I see it, you could even change the CSS file while your application is running and have the style change in realtime, with no requirement on Projucer anyway.

Ok, so let’s sum this logic up:
CSS is like Pareto law, it give 80% of the need for 20% of the effort. If you need more, I think you’ll use the current system, that is, C++ code that’s making the pixel exact version of your idea. You’ll loose flexibility for a better look, but this choice is yours.

I think you’re misunderstanding here. CSS would be used for styling and not for positioning/clipping/hit testing.
Again, there is no point emulating a DOM tree with simulating the DOM box model, since it does not apply.
I’ve done a CSS styler in the past (check this forum for information), and I can tell you that nothing prevents you from exporting a warning when an unsupported rule is parsed.
When you talk about corner clipping, you might only do alpha testing like it’s the case now for the current components.
In all case, I’m not promoting a “make Juce Acid3 compliant”, but I’m promoting a “make use of THE standard for styling the Juce’s components”. Again if X% of the CSS model doesn’t fit, we (as the standard says) ignore the rules. We can throw a diagnostic, but that’s enough for the case. If you need more, rely on the C++ code/ expression parser/projucer, whatever that’s actually in the pipe.

Currently, the component are already a “hierarchy” based system (through not with a single root like a DOM tree). They already have a some dynamic and static properties (static here is important). You can use these properties for CSS mapping, and I think it’s the best to do.
One can write a Component inspector in half a day, simply using ValueTree introspection and Component::getChildComponent, so we’ll have the tools to show the actual hierarchy to help any designers without actually needing a single line of code in your application. I wonder what you could expect better without a complete redesign.