(sec-module-misc.settingsutilities)= # Module: misc.settingsUtilities What a settings structure looks like as Python: which values it has, what each of them is called, what a value looks like in a script, and which of them differ from the defaults. It works on the dictionary GetDictionaryWithTypeInfo() returns, so every function here runs without a window and can be tested without one. - **Author**: Johannes Gerstmayr - **Date**: 2020-01-25 (as part of GUI.py), 2026-09-24 (own module) (sec-settingsutilities-getcomboboxlistsdict)= ## Function: GetComboBoxListsDict [`GetComboBoxListsDict(exu = None)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L67) - **function description**: The values a settings item of an enum type may take, as {typeName: [values]}. EVERY enum of the module, not a hand-written list of three: this named OutputVariableType, LinearSolverType and ItemType, and timeIntegration.solverType - a DynamicSolverType - was therefore edited as free text, where a typo is a silent wrong value (#2597). A pybind11 enum is recognised by its __members__, so an enum added to the module arrives here by itself. - **input**: - `exu`: the exudyn module - **output**: the dictionary the dialog picks its combo box entries from (sec-settingsutilities-settingsleaflist)= ## Function: SettingsLeafList [`SettingsLeafList(dictionaryWithTypeInfo, path = '')`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L255) - **function description**: every editable value of a settings structure, in tree order - **input**: - `dictionaryWithTypeInfo`: what GetDictionaryWithTypeInfo() returns, or a part of it - `path`: the dotted path the given dictionary sits at, '' for the whole structure - **output**: list of (path, value, valueString, vType, vSize, description); valueString is what the dialog shows in the cell, which is what everything else compares and copies, and value is what the settings structure holds (sec-settingsutilities-enumdisplayname)= ## Function: EnumDisplayName [`EnumDisplayName(valueStr, vType)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L280) - **function description**: the enum value without the type in front of it: Displacement, not OutputVariableType.Displacement An enum is edited in a combo box as wide as the value column, and every entry of a list begins with the same type name - which is already in the type column beside it - so the part that tells the entries apart was pushed out of sight (#2635). Since #2640 this is **the** value string of an enum - what `ConvertValue2String` produces, what the cell shows, and what `ChangedSettings` compares - because shortening only the list left the cell unreadable the moment the box collapsed. The full name lives in exactly one place: `ValueLiteral`, which writes the Python. - **input**: - `valueStr`: the value as str() writes it - `vType`: the type name of the setting - **output**: the value without its type prefix; anything else unchanged, bool included (sec-settingsutilities-enumfullname)= ## Function: EnumFullName [`EnumFullName(displayName, vType)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L303) - **function description**: the inverse of EnumDisplayName: the name Python needs, which `ValueLiteral` writes - **input**: - `displayName`: the value as the combo box shows it - `vType`: the type name of the setting - **output**: the value with its type prefix; an empty string, a bool and an already complete name unchanged (sec-settingsutilities-valueliteral)= ## Function: ValueLiteral [`ValueLiteral(valueStr, vType, dictionaryTypesT = None)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L319) - **function description**: the value as PYTHON writes it: a string is quoted, an enum carries its module - **input**: - `valueStr`: the value as the dialog shows it - `vType`: the type name of the setting - `dictionaryTypesT`: the lists of the types that have a fixed set of values - **output**: a string that can stand on the right hand side of an assignment (sec-settingsutilities-settingscodelines)= ## Function: SettingsCodeLines [`SettingsCodeLines(currentLeaves, referenceValueStrings, prefix, dictionaryTypesT = None)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L338) - **function description**: the settings that differ from a reference, as the lines that set them The comparison is on the string the dialog SHOWS, not on the value: that is what makes a float and an enum comparable at all, and it marks exactly what a user sees in the cell. - **input**: - `currentLeaves`: SettingsLeafList(...), or the same six fields taken from the dialog - `referenceValueStrings`: {path: valueString} of what is compared against - the defaults, or the values a dialog opened with; a path that is not in it counts as unchanged - `prefix`: SettingsPrefix(...) of the structure - `dictionaryTypesT`: the lists of the types that have a fixed set of values - **output**: list of (path, line), in tree order (sec-settingsutilities-compiledsettingsclass)= ## Function: CompiledSettingsClass [`CompiledSettingsClass(settingsStructure)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L371) - **function description**: the class the COMPILED module defines for this structure, which is not always its own A settings structure can be an instance of a Python subclass: `import exudyn` installs one for VisualizationSettings when ~/.exudyn/config.json holds any, so that a stored setting reaches every structure that is created (#2684). Constructing that subclass to find the DEFAULTS would apply the overrides to it and report them as the defaults - measured on the first attempt: openGL.multiSampling came back with 4 as its own default - so everything that shows a difference has to construct the compiled class instead. - **input**: - `settingsStructure`: the structure being edited - **output**: the first class of its mro that the compiled module defines; the structure's own class when it is not a subclass, which is the normal case (sec-settingsutilities-defaultsettingsdictionary)= ## Function: DefaultSettingsDictionary [`DefaultSettingsDictionary(settingsStructure)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L395) - **function description**: the defaults of a settings structure, as its own constructor produces them NOT from a SystemContainer, although that is the state a user really starts from: creating one ATTACHES IT TO THE RUNNING RENDER ENGINE (MainSystemContainer() calls AttachToRenderEngineInternal) and destroying one DETACHES it (Reset() -> DetachFromRenderEngine), so a temporary container opened for a moment takes the render window away from the container that owns it - the window closes (#2625). The settings a container initialises are listed in containerInitialisedSettings above, and #2626 moves them where this function can see them. AND NOT BY CONSTRUCTING ANYTHING when the override settings are in use: the constructor of the compiled class itself applies a stored setting (#2691), so `exudyn.misc.overrideSettings.structureDefaults` holds what it produced BEFORE it was wrapped, and that is used when it is there. - **input**: - `settingsStructure`: the structure being edited - **output**: the dictionary with type info of a fresh structure of the same kind (sec-settingsutilities-settingsvaluestrings)= ## Function: SettingsValueStrings [`SettingsValueStrings(dictionaryWithTypeInfo)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L427) - **function description**: {path: valueString} of a settings structure - what SettingsCodeLines compares against (sec-settingsutilities-findmatches)= ## Function: FindMatches [`FindMatches(leaves, searchText)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L433) - **function description**: the settings a search text finds: the NAMES first, the descriptions second Several hundred values in a tree of folders, and the only way to a setting was knowing which folder it sits in. - **input**: - `leaves`: SettingsLeafList(...) of the settings being searched - `searchText`: what the user typed; case does not matter - **output**: list of (path, label), name hits first, then hits in the path, then hits that are only in the description - those labelled with the part of the description that matched (sec-settingsutilities-settingsprefix)= ## Function: SettingsPrefix [`SettingsPrefix(settingsStructure)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L464) - **function description**: the name a script uses for this settings structure, e.g. SC.visualizationSettings (sec-settingsutilities-changedsettings)= ## Function: ChangedSettings [`ChangedSettings(settingsStructure, reference = None)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L478) - **function description**: every setting that differs from the defaults, as (path, the line that sets it) - **input**: - `settingsStructure`: SC.visualizationSettings or a simulationSettings object - `reference`: {path: valueString} to compare against; the defaults of the structure by default. SettingsValueStrings(structure.GetDictionaryWithTypeInfo()) taken earlier gives the changes since THAT moment instead - **output**: list of (path, line), in tree order; empty if nothing differs *example*: ```python SC.visualizationSettings.openGL.lineWidth = 2 ChangedSettings(SC.visualizationSettings) #[('openGL.lineWidth', 'SC.visualizationSettings.openGL.lineWidth = 2.0')] ``` (sec-settingsutilities-changedsettingscode)= ## Function: ChangedSettingsCode [`ChangedSettingsCode(settingsStructure, reference = None, comment = True)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L502) - **function description**: what ChangedSettings found, as one pastable block of Python - **input**: - `settingsStructure`: SC.visualizationSettings or a simulationSettings object - `reference`: see ChangedSettings - `comment`: True writes one '#' line saying how many settings differ, which is what makes the block readable when it is stored somewhere - **output**: the lines as one string, '' if nothing differs and comment is False - **notes**: This is also what belongs in a solution file that has to be reproducible: simulationSettings.solution.file.information is written into the header of the solution file, and it takes any string. (sec-settingsutilities-printchangedsettings)= ## Function: PrintChangedSettings [`PrintChangedSettings(settingsStructure, reference = None)`](https://github.com/jgerstmayr/EXUDYN/blob/master/python/exudyn/misc/settingsUtilities.py#L529) - **function description**: print what a model changed, as the code that changes it - **input**: - `settingsStructure`: SC.visualizationSettings or a simulationSettings object - `reference`: see ChangedSettings - **output**: None