better theming support #350
Replies: 39 comments
-
Yes, we can do that. Absolutely! |
Beta Was this translation helpful? Give feedback.
-
What's the reason behind elements/lib/src/support/draw_utils.cpp Lines 81 to 104 in 2aea4fc |
Beta Was this translation helpful? Give feedback.
-
Pseudo shadows with varying transparency; purely aesthetics. Same for -0.5.
It should not; but try it out perhaps you'll uncover a bug. Also, I'm not sure if the code implementing round rects is optimized. Cairo does not have direct support for it; so it's all done in the canvas class. |
Beta Was this translation helpful? Give feedback.
-
Ah thinking about it again, there should be some checks here and constrain the corner_radius if it is allowed to be parametizable in the gallery. |
Beta Was this translation helpful? Give feedback.
-
Got any objections for moving almost all color/geometry information into default theme? I would like to have much higher control over the look and experiment a bit (perhaps even make a theme-editor example to see changes on the go). Currently majority of drawing functions have hardcoded values. I would like to move all or almost all of them into the See #62 for an example change which moves |
Beta Was this translation helpful? Give feedback.
-
No objections here. I think my only concern is how to organize the theme to make it easily understandable. But we can cross that bridge when we get there. |
Beta Was this translation helpful? Give feedback.
-
Do you have any recommendations where theme object should/should not be used? I see 3 possible ways:
Currently it's a mix of 2 and 3. Thinking whether only 1 or only 2 or only 3 would be better. |
Beta Was this translation helpful? Give feedback.
-
We used to have 1, but not anymore, because the theme is now globally accessible even at construction time via https://github.com/cycfi/elements/blob/master/lib/include/elements/element/gallery/button.hpp#L41 |
Beta Was this translation helpful? Give feedback.
-
I don't think such at-construction use of theme is good. You need to recreate the widget to apply theme changes - I would prefer it to be only 1 or only 2 or only 3. |
Beta Was this translation helpful? Give feedback.
-
By design, the theme should be valid at construction/elements-build time. I thought about this for quite some time until I arrived at that decision. There are problems with being able to dynamically change the theme on the fly. For one, there are things that are needed at construction time, for optimization reasons. Do you recall the issue with the labels' fonts in the ctor and at draw time? In such cases, the font should be known and set at ctor time, not draw time. The thing that you uncovered is a remnant of the "old" ways where the theme is only available at draw time in the context, and so I had to set the font every time it draws (and that I am fixing now). Moreover, if needed, a rebuild/reboot of the elements view should be effortless, as can be seen in the examples. Basically, you just re-construct the root element held by the view. The lightweight elements hierarchy is very efficient to construct! BTW, in case you missed it, there's a way to "override" a specific theme. You can see that in action here: https://github.com/cycfi/elements/blob/develop/lib/src/element/menu.cpp#L201 For reference: https://github.com/cycfi/elements/blob/develop/lib/include/elements/support/theme.hpp#L133 |
Beta Was this translation helpful? Give feedback.
-
I'm fine with reconstructing the root element, but not sure if it will actually apply the change. If the root element holds a shared pointer to some widget hierarchy, I think you need to reconstruct the entire hierarchy to apply the theme changes. Am I right?
This should be documented on Wiki. But then it means we can use the theme in arbitrary places in code since its a globally accessible object.
|
Beta Was this translation helpful? Give feedback.
-
You rebuild the view In that example, just call: view_.content(
{
share(make_controls(view_)),
share(background)
}
); and it will rebuild the entire thing, with all the shared stuff linking just fine. The root (content) is the root and cannot/should not link to anything. It can't because the view owns it privately.
https://github.com/cycfi/elements/blob/master/lib/src/element/misc.cpp#L119 Aside: you might notice that a one line above is: I hope I am making sense, almost thinking out loud! Let's talk about this some more in our next voice call. |
Beta Was this translation helpful? Give feedback.
-
Ah got it!... See the latest labels work-in-progress code here: https://github.com/cycfi/elements/blob/text_revisit/lib/src/element/misc.cpp#L117)
|
Beta Was this translation helpful? Give feedback.
-
I get the example but I mean such situation: auto ptr = share(make_controls(view_));
view_.content(ptr, share(background));
// change theme...
view_.content(ptr, share(background)); Will this reapply the theme? I think not. I think I need to call
That's exactly what I was asking for - a recommendation when a theme object should be used.
Shouldn't this be a sort of font pointer/reference? If I have multiple labels, which all use the same but non-standard font I don't want to construct multiple expensive font objects. |
Beta Was this translation helpful? Give feedback.
-
Just don't do that :-) The elements inside a view should be self-contained. Yes, just call
Ideally, anywhere where there's a context.
The font is a ref-counted handle. Same fonts are shared: |
Beta Was this translation helpful? Give feedback.
-
Oh, we might not support synthesizing styles. Note: On Mac with Cocoa, Bold, Italic and BoldItalic must have the proper font, or the style is simply not available. It was not always the case. Carbon used to synthesize these styles by playing on weight and slant. Windows still synthesizes Bold, Italic and BoldItalic when the specific stylistic variation font is not present. But that practice is going out of style, IMO. Synthesized styles will never be as good as true weighted fonts (e.g. bold) and italics. Modern fonts support many style variations. https://docs.huihoo.com/apple/wwdc/2012/session_226__core_text_and_fonts.pdf |
Beta Was this translation helpful? Give feedback.
-
Wow, the image looks really good.
Does it mean elements will not support rendering fonts with such styles if they are not in the font itself? I'm fine with it, jus no bad limitations like "not being able to use the font at all when a subset of styles is not in it".
fontconfig is already a dependency of cairo. I have already built it. Now just need to add it to the CMake recipe. |
Beta Was this translation helpful? Give feedback.
-
Did you know that Adobe graphics programs such as Photoshop and Illustrator do not fake bold and italic fonts? And indeed, the MacOS, known for its superiority in typography (and graphics) stopped doing so in the OS level. It makes sense, if you think about it. Faking bold and italics were a necessity in the old days when we have limited fonts available and computer typography was in its infancy. I am an artist and I want Elements to have superiority in aesthetics and design. I have a keen eye on such things and I dislike faking things, especially now that you do not have to because there are a LOT of superb font families available. Perhaps these articles will be more convincing:
Wonderful! |
Beta Was this translation helpful? Give feedback.
-
I like this approach. I know that fake bold does not look really good (already seen it a couple of times when experimenting with bold in CSS, which has 8 levels IIRC - lots of them look the same or have very irregular line thickness depending on the font). I like your attention to details. Recently found an article that was about how many UIs commit the mistake of non-assymetric ranges (where asymetric ranges are standard, basically |
Beta Was this translation helpful? Give feedback.
-
Indeed, a well-designed application should not have any fake fonts in its UI. |
Beta Was this translation helpful? Give feedback.
-
How about a theme editor example? I noticed some colors don't play nicely (eg black background because a lot of code uses |
Beta Was this translation helpful? Give feedback.
-
That will be interesting! |
Beta Was this translation helpful? Give feedback.
-
Somewhat a blind guess but I think we will need to remove all of This is because:
Also, have you thought about making theme not to be a global object? Eg be it a parameter of the |
Beta Was this translation helpful? Give feedback.
-
Good point! I'll need to think about this some more.
I recall you asked this before? Yes, that was originally a part of the context. But remember the construction things? The theme object somehow needs to be available at construction time on many gallery items. |
Beta Was this translation helpful? Give feedback.
-
Yes, even in this issue...
Right, this complicates things. But why is it needed? I'm interested what exactly is taken from the theme. If theme is needed at construction, this means that some elements keep theme data in their state - do we really want that? That state is only used in drawing. |
Beta Was this translation helpful? Give feedback.
-
IMO this creates 2 problems:
|
Beta Was this translation helpful? Give feedback.
-
Yes, and I don't see any other better solution right now. Believe me, I've not taken this lightly when I moved to a global theme. Show me an alternative solution and I will consider it: pick one example in the gallery and try to come up with a non-global theme.
Yes, and we already discussed that before as well. |
Beta Was this translation helpful? Give feedback.
-
Fine. This "prove me by PR" way of dealing with things has been working quite well recently. The task seems simple: just move all of the state that is accessed in gallery element factories to respective drawing functions. There is just 1 problem: some widgets are keeping some state by design. An input box, frame etc will always use the same theme variable. But some elements (eg button) holds the choosen color as a part of its state and each button can have different color regardless of the theme. To solve this problem, we would need buttons etc to either:
Both are problematic, because they do not support arbitrary number of custom-color buttons. And it can be easily predicted that some library users will want to have specific buttons in certain colors regardless of the theme. |
Beta Was this translation helpful? Give feedback.
-
Any work related to making theme non-global is secondary priority, first I would like to develop a good theme editor (with example widgets) in order to test theme and detect all kinds of theme inconsistencies/limitations/bugs. I will create a separate branch for this. Current work notes:
I will post more conclusions as I experiment more with theme editor example. |
Beta Was this translation helpful? Give feedback.
-
This appeared recently:
|
Beta Was this translation helpful? Give feedback.
-
I like the support of being able to set custom
theme
object, but not all variables which impact drawing are thereelements/lib/include/elements/support/theme.hpp
Lines 13 to 20 in 2aea4fc
For example, the button has its own radius variable:
elements/lib/include/elements/element/gallery/button.hpp
Lines 24 to 26 in 2aea4fc
and some color changes too:
elements/lib/include/elements/element/gallery/button.hpp
Lines 38 to 44 in 2aea4fc
Could we move all such variables to the theme so that one can create a theme which changes color and corners of all elements? I would like to be able to create eg a full square-like UI as on this screen.
Beta Was this translation helpful? Give feedback.
All reactions