Need Help on populating user colors with Stylesheet change.

A forum for research and development of the user interface of FreeCAD
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Need Help on populating user colors with Stylesheet change.

Post by chennes »

Thank you for weighing in! You are absolutely right about the challenges here, but I think that we can make some headway this time around.

First, because there are exactly zero "themes" in existence right now, any metadata format we develop for them doesn't have a pre-existing author's work to worry about. Second, for external WBs, we already have a solid database of those, I can create the necessary metadata files and submit them as PRs to each repo because there aren't actually that many. For macros this is harder, of course. But finally, I think we start out with the file being optional: if it exists, the author gets some extra features in the Addon Manager, etc. but their addon will work without it.

I'd love to just adopt someone else's metadata file format (as long as it is extensible). We are far from the only program that wants to have plugin metadata! Kunda1 posted about the QGIS format -- it's very simple (possibly too simple), and parsing it is nearly trivial. If we need to support non-string metadata, we probably need to move up the foodchain in terms of the wire format -- Qt provides a very easy-to-use JSON reader, and JSON has the advantage of being very light-weight to parse once it's been read in. And of course, we have Xerces-C as our XML parser, which supports SAX and DOM, and has all the bells and whistles. My feeling is that it's overkill for something that should be kept deliberately simple like metadata, but of course if we use XML we'll never run into a "oh, I didn't think anyone would want to do that!" situation.

Once we agree on a wire format, I think things get a bit easier, because we can design it for extensibility and versioning from the start, so that it's not a huge step to change/augment the format later on. We can start simple, and grow as we need it. We don't have to solve all the metadata problems all at once :) .

As you say, FreeCAD is a bit "different" -- I'm hoping to have the Theme stuff working by the end of the week. Obviously that will just be a prototype, and we can then start hammering it into its final shape, but I'd like to choose at least the wire format pretty soon here. Of course, the advantage of starting with the Theme stuff is that we can test the format out for a bit without it affecting anything else, and once we're happy with it, roll it out elsewhere. And it's easy enough to write the Theme code to support several different wire formats while we are working on it. I don't mind implementing several and letting people see them and work with them a bit to get a feel for how they are to author.
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
hyarion
Posts: 139
Joined: Fri Jun 26, 2020 6:08 pm

Re: Need Help on populating user colors with Stylesheet change.

Post by hyarion »

As long as we keep it simple I don't see why people would object to a standard (we should of cause make a proposal post and ping people).
And as soon as the minimal standard gets implemented in freecad I don't see why addon devs wouldn't want to support it.

If addon developers wants to add additional data in their metadata file it could be done in an addon specific namespace, similar to how mozilla's extensions to css are prepended with "-moz-". This way nothing shouldn't collide and we could easily adopt new features if/when needed.
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Need Help on populating user colors with Stylesheet change.

Post by chennes »

Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Need Help on populating user colors with Stylesheet change.

Post by chennes »

While we are debating the merits of the various metadata formats I'm continuing to develop the rest of the system. Right now my proposal is that a Theme consists of some or all of the following files:
  • metadata.* (required)
  • [theme_name].cfg (required)
  • [theme_name].qss
  • pre.FCMacro
  • post.FCMacro
  • Any other files referenced by the cfg file
The metadata is used by the user interface to display information about the theme in the Add-on Manager.

The theme_name.cfg is a user.cfg file consisting only of the settings that the theme wishes to set. It is scanned when "Apply" is clicked and applied as though the user had manually made those changes to their preferences. Later manual changes override the theme, but at any time a user can click "Reapply" to reapply the theme. A backup of the previous user.cfg is taken prior to application to allow reversion of the changes.

theme_name.qss is a stylesheet, which must also be referenced by the appropriate setting in the CFG file. A theme does not have to ship with its own stylesheet, it could reference one of the other built-in stylesheets by setting the appropriate value in the CFG file. Thus, this file is technically optional.

pre.FCMacro is a macro that is run as soon as the user clicks "Apply" or "Reapply", but before any other actions are taken. Any exception that propagates out of this macro stops the application of the theme. It can be used to check dependencies, display a welcome message, calculate the billionth digit of pi... whatever.

post.FCMacro is a macro that is run after the application of the theme is complete (that is, all user preferences have been updated). It can be used to verify installation, etc. Any exception that propagates out of this function is displayed as an error message to the user, and the application of the theme is optionally reverted, at the user's choice.
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
User avatar
turn211
Posts: 162
Joined: Mon Feb 01, 2021 11:37 pm

Re: Need Help on populating user colors with Stylesheet change.

Post by turn211 »

Will Icon theme packs be able to be added at a later date or should we totally disregard them in this new theme enabler?
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Need Help on populating user colors with Stylesheet change.

Post by chennes »

My thinking is that when we support icon themes it will be a parameter in user.cfg, so this will automatically support it when it’s there.
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Need Help on populating user colors with Stylesheet change.

Post by chennes »

OK, I think we've got the "package.xml" metadata file format in shape for some testing, so now I'm back to working on the themes. The format of the package.xml file leads to some changes to the theme data, because a package can potentially contain multiple themes. So my new theme structure proposal is:

Code: Select all

Package Directory/
  package.xml
  Theme A/
    Theme A.cfg
    Theme A.qss
    pre.FCMacro
    post.FCMacro
    (any other files the theme needs, e.g. icons, etc. referenced by .cfg file)
  Theme B/
    Theme B.cfg
    etc.
The directory name for the theme must match exactly the contents of the "<name>" element for the theme in the package.xml file. Technically that folder doesn't have to contain any of the listed elements, they are all optional from a code perspective. But it is allowed to contain one (and only one) .cfg file, which contains the user preferences that this theme sets. Those preferences most likely will reference a stylesheet, so that stylesheet will also be included in nearly all cases. "pre.FCMacro" is a macro run before applying the preferences: if it returns False, the application of the theme is aborted. "post.FCMacro" is a macro run after applying the preferences: if it returns False the preferences are rolled back to their original state prior to the theme application.

My hope is to have a "Save as new..." option in the Theme menu that takes your current visual settings and automatically creates this structure for you. That way the Theme creation process is as simple as possible, and it's very easy for users to save off their current settings as a local theme. To do that, I need to compile a list of all of the user preferences that relate to visual style that should be included by default. To start with this will just include the build-in workbenches, but in the long run I'd like to find a way to make it extensible.

@turn211, do you already have a list of all of the items whose color you want a theme to set (excluding the things in the QSS file)?
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Need Help on populating user colors with Stylesheet change.

Post by chennes »

I had a go at generating the list of things that a normal Theme would potentially want to set:

Code: Select all

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<FCParameters>
  <FCParamGroup Name="Root">
    <FCParamGroup Name="BaseApp">
      <FCParamGroup Name="Preferences">
        <FCParamGroup Name="Mod">
          <FCParamGroup Name="Draft">
            <FCUInt Name="constructioncolor" Value="746455039"/>
            <FCInt Name="gridTransparency" Value="0"/>
            <FCUInt Name="gridColor" Value="842157055"/>
            <FCUInt Name="snapcolor" Value="4294967295"/>
            <FCText Name="textfont"></FCText>
          </FCParamGroup>
          <FCParamGroup Name="Mesh">
            <FCUInt Name="MeshColor" Value="3435973887"/>
            <FCUInt Name="LineColor" Value="255"/>
            <FCUInt Name="BackfaceColor" Value="3435973887"/>
            <FCInt Name="MeshTransparency" Value="0"/>
            <FCInt Name="LineTransparency" Value="0"/>
          </FCParamGroup>
          <FCParamGroup Name="Arch">
            <FCUInt Name="WallColor" Value="3604403967"/>
            <FCUInt Name="StructureColor" Value="2527705855"/>
            <FCUInt Name="RebarColor" Value="3111475967"/>
            <FCUInt Name="WindowColor" Value="556614399"/>
            <FCUInt Name="WindowGlassColor" Value="1572326399"/>
            <FCUInt Name="PanelColor" Value="3416289279"/>
            <FCUInt Name="ColorHelpers" Value="674321151"/>
            <FCUInt Name="defaultSpaceColor" Value="4280090879"/>
          </FCParamGroup>
          <FCParamGroup Name="Start">
            <FCUInt Name="BackgroundColor1" Value="1414812927"/>
            <FCUInt Name="BackgroundTextColor" Value="4294967295"/>
            <FCUInt Name="PageColor" Value="690563583"/>
            <FCUInt Name="PageTextColor" Value="3789677055"/>
            <FCUInt Name="BoxColor" Value="1296911871"/>
            <FCUInt Name="LinkColor" Value="3099197439"/>
            <FCUInt Name="BackgroundColor2" Value="2141107711"/>
            <FCText Name="Template"></FCText>
            <FCText Name="BackgroundImage"></FCText>
            <FCBool Name="UseStyleSheet" Value="0"/>
            <FCText Name="FontFamily"></FCText>
          </FCParamGroup>
          <FCParamGroup Name="TechDraw">
            <FCParamGroup Name="Labels">
              <FCText Name="LabelFont">MS Shell Dlg 2</FCText>
            </FCParamGroup>
            <FCParamGroup Name="Decorations">
              <FCUInt Name="SectionColor" Value="255"/>
              <FCUInt Name="CenterColor" Value="255"/>
              <FCUInt Name="VertexColor" Value="255"/>
              <FCUInt Name="HighlightColor" Value="255"/>
            </FCParamGroup>
            <FCParamGroup Name="Colors">
              <FCUInt Name="Hatch" Value="255"/>
              <FCUInt Name="Background" Value="3553874943"/>
              <FCUInt Name="PreSelectColor" Value="4294902015"/>
              <FCUInt Name="HiddenColor" Value="255"/>
              <FCUInt Name="SelectColor" Value="16711935"/>
              <FCUInt Name="NormalColor" Value="255"/>
              <FCUInt Name="CutSurfaceColor" Value="3553874943"/>
              <FCUInt Name="GeomHatch" Value="255"/>
              <FCUInt Name="FaceColor" Value="4294967295"/>
              <FCBool Name="ClearFace" Value="1"/>
            </FCParamGroup>
          </FCParamGroup>
          <FCParamGroup Name="Path">
            <FCUInt Name="DefaultNormalPathColor" Value="11141375"/>
            <FCUInt Name="DefaultRapidPathColor" Value="2852126975"/>
            <FCInt Name="DefaultPathLineWidth" Value="1"/>
            <FCUInt Name="DefaultPathMarkerColor" Value="1442775295"/>
            <FCUInt Name="DefaultExtentsColor" Value="3823363071"/>
            <FCUInt Name="DefaultProbePathColor" Value="4294903295"/>
            <FCUInt Name="DefaultHighlightPathColor" Value="4286382335"/>
            <FCUInt Name="DefaultBBoxSelectionColor" Value="3372220415"/>
            <FCUInt Name="DefaultBBoxNormalColor" Value="4294967295"/>
          </FCParamGroup>
        </FCParamGroup>
        <FCParamGroup Name="View">
          <FCUInt Name="BacklightColor" Value="3755991039"/>
          <FCUInt Name="BackgroundColor" Value="336897023"/>
          <FCUInt Name="BackgroundColor2" Value="1701144063"/>
          <FCUInt Name="BackgroundColor3" Value="757935615"/>
          <FCUInt Name="BackgroundColor4" Value="1869583359"/>
          <FCBool Name="Simple" Value="0"/>
          <FCBool Name="Gradient" Value="1"/>
          <FCBool Name="UseBackgroundColorMid" Value="0"/>
          <FCUInt Name="HighlightColor" Value="4294907903"/>
          <FCUInt Name="SelectionColor" Value="704588287"/>
          <FCUInt Name="DefaultShapeColor" Value="3435973887"/>
          <FCBool Name="RandomColor" Value="0"/>
          <FCUInt Name="DefaultShapeLineColor" Value="421075455"/>
          <FCUInt Name="DefaultShapeVertexColor" Value="421075455"/>
          <FCUInt Name="BoundingBoxColor" Value="4294967295"/>
          <FCUInt Name="AnnotationTextColor" Value="3823363071"/>
          <FCUInt Name="SketchEdgeColor" Value="4294967295"/>
          <FCUInt Name="SketchVertexColor" Value="4294967295"/>
          <FCUInt Name="EditedEdgeColor" Value="4294967295"/>
          <FCUInt Name="EditedVertexColor" Value="4280680703"/>
          <FCUInt Name="ConstructionColor" Value="56575"/>
          <FCUInt Name="ExternalColor" Value="3425924095"/>
          <FCUInt Name="InvalidSketchColor" Value="4285333759"/>
          <FCUInt Name="FullyConstrainedColor" Value="16711935"/>
          <FCUInt Name="InternalAlignedGeoColor" Value="2998042623"/>
          <FCUInt Name="FullyConstraintElementColor" Value="2161156351"/>
          <FCUInt Name="FullyConstraintConstructionElementColor" Value="2410282495"/>
          <FCUInt Name="FullyConstraintInternalAlignmentColor" Value="3739142399"/>
          <FCUInt Name="FullyConstraintConstructionPointColor" Value="4287987967"/>
          <FCUInt Name="ConstrainedIcoColor" Value="4280680703"/>
          <FCUInt Name="NonDrivingConstrDimColor" Value="2555903"/>
          <FCUInt Name="ConstrainedDimColor" Value="4280680703"/>
          <FCUInt Name="ExprBasedConstrDimColor" Value="4286523135"/>
          <FCUInt Name="DeactivatedConstrDimColor" Value="2139062271"/>
          <FCUInt Name="CursorTextColor" Value="65535"/>
          <FCUInt Name="CursorCrosshairColor" Value="4294967295"/>
          <FCUInt Name="CreateLineColor" Value="3435973887"/>
        </FCParamGroup>
        <FCParamGroup Name="OutputWindow">
          <FCUInt Name="colorText" Value="4294967295"/>
          <FCUInt Name="colorLogging" Value="3117350911"/>
          <FCUInt Name="colorWarning" Value="4290999551"/>
          <FCUInt Name="colorError" Value="4287006463"/>
        </FCParamGroup>
        <FCParamGroup Name="TreeView">
          <FCUInt Name="TreeEditColor" Value="4042260735"/>
          <FCUInt Name="TreeActiveColor" Value="3537037823"/>
        </FCParamGroup>
        <FCParamGroup Name="Editor">
          <FCUInt Name="Text" Value="4294967040"/>
          <FCUInt Name="Bookmark" Value="15921664"/>
          <FCUInt Name="Breakpoint" Value="3992977408"/>
          <FCUInt Name="Keyword" Value="195493632"/>
          <FCUInt Name="Comment" Value="14483456"/>
          <FCUInt Name="Block comment" Value="2526452224"/>
          <FCUInt Name="Number" Value="1625816832"/>
          <FCUInt Name="String" Value="4283782400"/>
          <FCUInt Name="Character" Value="4281611264"/>
          <FCUInt Name="Class name" Value="4003397632"/>
          <FCUInt Name="Define name" Value="3784704000"/>
          <FCUInt Name="Operator" Value="3553875968"/>
          <FCUInt Name="Python output" Value="3705447680"/>
          <FCUInt Name="Python error" Value="4287203584"/>
          <FCUInt Name="Current line highlight" Value="774778368"/>
          <FCText Name="Font">MS Shell Dlg 2</FCText>
        </FCParamGroup>
        <FCParamGroup Name="MainWindow">
          <FCBool Name="TiledBackground" Value="0"/>
          <FCText Name="StyleSheet">ProDark.qss</FCText>
        </FCParamGroup>
      </FCParamGroup>
    </FCParamGroup>  
  </FCParamGroup>
</FCParameters>
I think I am probably going to have to just implement it and see if I caught everything, I can't think of a good way of checking to see if this is comprehensive.
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
User avatar
turn211
Posts: 162
Joined: Mon Feb 01, 2021 11:37 pm

Re: Need Help on populating user colors with Stylesheet change.

Post by turn211 »

chennes wrote: Mon Apr 19, 2021 5:53 pm @turn211, do you already have a list of all of the items whose color you want a theme to set (excluding the things in the QSS file)?
My Development Computer blew a tire. Needs new motherboard. Till I'm back up running you can use the following for a "Complete" ProDark theme. Look great. Nice work.

Code: Select all

Preferences > General > Editor 
Text = #d4d4d4
Bookmark = #00ffff
Breakpoint = #ff0000
Keyword = #569cd6
Comment = #6a9955
Block Comment = #ce9178
Number = #b5cea8
String = #ce9178
Character = #ff0000
Class name = #4ec9b0
Define name = #dcdcaa
Operator = #d4d4d4
Python Output = #aaaa7f
Python error = #fd7c62
Current line highlight = #2a2a2a

Preference > General > Output window
Normal Messages = #d4d4d4
Log messages = #55aaff
Warnings = #fd7c62
Errors = #ff0000

Preferences > Display > Colors
Enable preselection highlighting = #e1e114
Enable selection highlighting = #1cad1c
Simple color = #3c3c3c
Object being edited = #ce9178
Active container = #ff55ff

Prefences > Start > Start page options
Background color = #3c3c3c
Background text color = #fffbf7
Page background color = #333333
Page text color = #adadad
Box background color = #3c3c3c
Link color = #55aaff

Preferences > Sketcher > Colors
Reference constraint color = #00aaff
Coordinate text color = #55aaff
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Need Help on populating user colors with Stylesheet change.

Post by chennes »

In order to enable a "Save as theme..." feature, we need to have a list of which user preferences are "themable". I am imagining a user interface that looks something like this:
Screenshot 2021-04-20 103418.png
Screenshot 2021-04-20 103418.png (38.64 KiB) Viewed 3290 times
(Obviously the real version will be scrollable, dynamically generated, etc.)


To enable this, we need "template" *.cfg files, listing out the things that get saved in the theme: in the above example, there are a whole bunch of templates, which get read in and presented to the user as checkable boxes. All of this is pretty straightforward. And for external workbenches, the storage location of those cfg files is obvious. But what about for internal stuff? Where should those configuration template files go?
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
Post Reply