Proposal improve of look and feel of Juce's applications

I really like the idea of having HTML5/CSS support for the Juce GUI. Right now, I create my GUIs in a very “programmer” way. If the graphics, look & feel, and interaction could be developed in HTML, CSS, and other standards of web origin, this would allow graphic designers and UX developers to create UIs for Juce apps, instead of offloading most of the work to the C++ software developers. Incorporating existing standards = HUGE developer/graphic designer base that can create things.

Sean Costello

I’m all in favor of more skinnable graphics (skinnable by users and designers alike), but CSS?

If you’re going to go through the trouble of creating a skinning engine for Juce, make sure it’s powerful enough, if you use something quite as simple as CSS you’re going to bump your head against a lot of problems which will need to be solved by coding again.

BTW, have a look at SASS ( http://sass-lang.com/ ) and LESS ( http://lesscss.org/ ), they will tell you quickly about some of the programming-flaws of CSS…

( Couldn’t one use something like Juce+LUA to do something a bit smarter/more tweakable? )

-bram

Very nice link, I wasn’t aware of.
In all case, it boils down/compiles to CSS, which an engine could implement basically.

I disagree strongly with the Lua argument. Lua is still a programming language, so what you can do in Lua you can do in C++ (and the “compiler” barrier will not hold anymore with projucer). The issue is that a programming language limits the user base. A designer doesn’t want to (use/learn) a programming language.

Anyway, the final conclusions from your posts are:
Current L&F and styling are too limited, too time consuming, too static.

Pro CSS:

  1. CSS is developer independent
  2. CSS is documented and so many example on the web makes it the reference styling language
  3. CSS can be compiled from a higher language
  4. CSS can be debugged by external tools out of the C++/software problem
  5. CSS is dynamic (no compilation needed)
  6. CSS3 transform gives also animation and transformation that’s lacking in the current code
  7. Maintenance is easy for the code since it’s against a standard, so changes in the code is possible if targeting more standard compliance, which is not the case for the current code that can’t “break” user code.

Con CSS:

  1. CSS doesn’t (can’t ?) provide 100% of the need so we could have to rely on C++ code for the missing features
  2. Doing what you want in CSS might be hard depending on your expectations.
  3. We can’t support 100% of CSS, so it’s a “subset” of CSS, not the whole stuff itself

So, the more I think about this, the harder I understand the con-CSS option.
I think to sort this out, I’ll ask you to list what you need in terms of styling options, so we can assert what the tools requires. I’m creating a new thread for this.

Well, looks like you’ve just hit the nail on the “why isn’t anyone listening to me?” head :slight_smile:

Most of the people on here, in case you didn’t notice, are programmers :slight_smile:

I actually agree with this part of the analysis: UI’s should be done by designers and not programmers. And if the UI designer needs a programmer to create his design… bad!
The same goes for website design for example: before it used to be that most websites were a total mess of PHP code interspersed with HTML code.
Then the first separation came when people started using templates: the designers could mess with the templates without bothering to know about code.
Then the second separation came, extracting websites into semantic data (i.e. html) and design data (CSS).

I fully agree that a separation is very useful, even if we almighty programmers think we know how to do everything best.
I was only doubting the choice of CSS, but to be honest CSS-or-not isn’t really that important! As long as there is SOME easy way of skinning a look-and-feel.

  • bram

[quote=“haydxn”]
Most of the people on here, in case you didn’t notice, are programmers :)[/quote]
OMG, how could I have missed it ?
Seriously, I’m not praising for converting people here. If you think the current L&F architecture is good for your need, there’s no discussion, since I’m not trying to make it disappear.
I’m speaking about an actual way to separate style definition from the program itself so we could have more freedom in the development process (and/or afterward).

I do agree, incidentally, that separating design from code is beneficial (though I’m not necessarily sold on CSS). I’m just saying it cuts both ways, and you shouldn’t be surprised at the reactions here!

Why don’t you just implement a CSS module and show us? :wink:

I’ve found two libraries that do this in C++. I think ultralight looks better, but that’s just my opinion.

https://ultralig.ht/

I’m going to see if I can’t get one of them working in my project.

Also, I don’t think JUCE would need to make either one of these an automatic dependency, but modules could probably be created for both to make whatever repetitive work ends up existing easier to do. If these tools are any good, it should be just about as easy to do one as to do both.

Today I was feeling very frustrated with the LookAndFeel approach in JUCE when CSS crossed my mind as a solution and as expected, somebody had already thought about it!

However I’d like to bring a new perspective to this old thread because incorporating CSS doesn’t necessarily mean to me using HTML and CSS to render an interface in the very same way that web browsers do it.

CSS could be simply used as a format to configure a Component in a better way than the current LookAndFeel approach. So all that I’m suggesting is that a “setStyle('font:arial;background:#FFFFFF;align:left)” method is added to every component to replace the current enum ColourIds and replace most of the “setter” methods.

Why do I say “better”? The current LookAndFeel makes changes to the set of Components provided by JUCE quite difficult. If you want to add a new parameter to the ComboBox for example to change the width and color of its border, now you can’t do it without modifying the LookAndFeel base code or creating a brand new custom Component. With CSS, it would be enough to create a base class with a virtual void setStyle(String) from which you could inherit in your custom components. You could then expand the existing JUCE components by inheriting from them and supporting more parameters in the style definition.

The CSS design would also allow to define the appearance of several components in a single file to create different themes in a very clean way (the designer would be able to relate to those CSS settings much better than to the current LookAndFeel list of colours and the current arbitrary set of setter methods to change basic things like the border width or the text-alignment of certain components).

The only disadvantage of this approach is that the parsing of large CSS files could slow down large UI’s. However you could also define a setStyle with an (void*) pointer to leave room for the use of more optimized data structures than the default CSS style text in more demanding situations.

Does it make any sense to you?

Derive from LookAndFeel base class and add your own methods?

Sorry, you are totally right about this. I’m going to remove this bit from my post. Actually I’m not saying to remove the LookAndFeelMethods, just replacing the ColourIds and expanding those to more parameters using the CSS format. This would in fact make those expansions to the LookAndFeel class unnecessary in many cases.

I was contemplating that a lot recently. For colour tables I think, replacing the LookAndFeel::findColour() would be a place to start with…

But I would go the whole nine yards and create a DOM together with the CSS, otherwise CSS makes no sense. And from there the DOM would define, which elements to nest in what kind of Layout, Grid or FlexBox.

Without a DOM, there is no cascading…

1 Like

Creating a CSS engine is no small task. In particular, things like:

  • width: 50% which requires a parent size that may be defined by the size of it’s children,
  • or display: flex which needs information on both parent size and the size of siblings.
  • Also, check out this list of all css properties (https://www.w3.org/Style/CSS/all-properties.en.html)

So rather than rolling our own, it would probably be much, much easier to find an open source css/dom tool and get the Component class to extend whatever that library uses for its DomElement base class. Hopefully we could cut out all the <div>, <span>, <img>, <a href> junk because all of that would just be bloat in this case.

Then, we could have something like

// Component extends some DomElement from another library
Component::Component(): DomElement(){}

// Override the inherited version of drawing to forward to the "legacy" version
void Component::drawDomNode() /*override*/ {
  draw();
}

// default the "legacy" draw function to use the DomElement drawing function
/*virtual*/ void Component::draw() {
   DomElement::drawDomNode(this);
}

// this could be used for custom implementations of draw
CSSStyling Component::getCssStyling() {
  return cssManager.getStylingFor(this);
}

and any overidden versions of draw would work just fine, or better

void MyComponent::draw() {
  auto styling = getCssStyling();
  // do your own default drawing, just as before, but (optionally) with the help of css
}

I mentioned in my post above, but I really don’t think we should start pulling that thread. It may seem like it’ll be easy, but little by little the project will absorb energy until it has either become a brand new web browser, or someone decides to throw it away and use a library.

Besides, what’s the point of people making open source implementations of CSS if nobody then turns that code into something greater?

If the goal of adding CSS to JUCE is to specify layout/styling in a human readable configuration file, why does it have to be CSS?

Qt’s QML worked out fine for them. Maybe it makes more sense to create a different layout/styling system based on JSON/YAML/TOML/whatever that reflects existing JUCE architectures instead of trying to forcefeed us a DOM implementation.

I don’t think I’m speaking just for myself when I say that I really would like an easier styling/layout system than LookAndFeel and Component::Resize, but I don’t want to redesign my component hierarchy to do it.

2 Likes

Yes, QML is what I re-implemented 3 years ago, see here:

I abandoned it a bit, because I was working completely off-GUI, just now coming back to do “full stack audio”. In the meantime, JUCE added the FlexBox and Grid layout, so it seems natural to me to use it.

My personal goal is to have a GUI implementation, that can be completely customised by a designer. In 2019 it makes no sense, to create mockups and give printed specs to the engineer.

I agree, it seems a huge task, but every journey starts with a single step…

1 Like

Because designers are already familiar with it and you don’t have to teach them another syntax

I think a stronger argument is that there are a lot of tools for generating CSS out there. I just think from a pure usability standpoint it would be easier on the development side to have a much more stripped down thing like CSS, that’s very much not CSS. I have more faith in people to learn new things.

It’s not really a question of new syntax. That would be excessive (and imo, a problem of the JUCE module format, where they use their own configuration syntax embedded in the header files rather than something like a yaml file in the root module directory). Not to mention any discussion would be pure bikeshedding.

But regardless I think layout information would be extremely difficult if not impossible to have layout information incorporated into something like CSS for JUCE, at least for existing projects. I know a lot of my layout code for custom components gets complex, and I’m not touching that any time soon for fear of breakage.

IMHO this is the strongest argument to leave it to a layout/colouring engine. Why fixing bugs in 100 products, when you can fix it in one engine?

IMHO this is the strongest argument to leave it to a layout/colouring engine. Why fixing bugs in 100 products, when you can fix it in one engine?

I agree with you 100%, but the issue for me is twofold.

The first is I don’t like the idea of more crap happening at runtime that is fundamentally a compile time constant. Is there such a thing as a compile-time CSS engine? I wouldn’t want to debug that template magic.

The second is that I think in terms of minimum viable product shipping a styling system without layout is much easier and would be much more straightforward to integrate into existing projects that we all have to maintain. Any movement on a layout engine would fundamentally change how we write JUCE GUIs, probably for the better, but there is lot of friction down that road. I don’t like arguing in favor of backwards compatibility, but it’s something I’m concerned with in my own code.

1 Like

In my opinion the layout happens only while resizing, or other animations are calling, so this is not really something that puts stress on the system. Resolving the colours would be done once during setup, and again only when the model/CSS changes. I think it is pretty doable. The fun starts, when you want to animate transitions, but I have ideas already, how to solve that.

Again, the goal is, that nobody has to look into the engine, except the person who designed and maintains it. Apart from that, only design is written.