-
Notifications
You must be signed in to change notification settings - Fork 139
Themes
ToDo: Finish the Creating a custom theme section.
This wiki discusses grid themes (or "skins"):
- Applying a theme to a
Hypergridinstance - Removing a theme
- Applying a global theme to all instances
- Removing the global theme
- Registering themes — so they can be referenced by name
- Persisting themes — so they can be saved and reloaded later
Advisory: A good understanding of the Hypergrid
propertiescollection objects and the properties stack helps in understanding how themes work. The reader is urged to give the Grid Properties wiki a thorough read before proceeding!
A theme object is a Hypergrid properties collection object, containing look & feel (or "LnF") properties that give the grid a particular appearance, such as halign, color, etc.
Themes should only contain look and feel properties. The following pseudo-properties are specifically ignored if they are included: cells, columnIndexes, columnNames, columns, features, gridRenderer, rows, subgrids, and theme itself (a theme cannot specify a theme).
Themes are applied by copying the properties of a theme object to the grid.theme "layer" of the _properties stack using the grid.applyTheme() method. The Hypergrid.defaults layer also serves as a global theme layer, set using the Hypergrid.applyTheme() function.
Properties of the theme layers are only visible when not masked by properties with the same names in upper layers.
To expose a property in a theme layer (for example the grid.theme layer) that is being masked by a property of the same name in an upper layer (for example the grid.properties layer), remove the property from that specific upper layer. The delete operator won't work on certain properties of the grid.properties layer which are accessors (getters/setters). Instead, use the .properties.delete(propName) method. For example, because backgroundColor is not an accessor, grid.properties.delete('backgroundColor') is the same as delete grid.properties.backgroundColor. However, because gridRendereris a (non-configurable) accessor,delete grid.properties.gridRendererwould not work and you would have to use thedelete(propName)method. Rather than concerning yourself about which properties are accessors and when to use the method instead of the operator, it is easier to just _always_ use the method, which is available in allproperties` collections (as of Hypergrid 3.0.0).
Themes can be applied to grid instances at any time.
Given a grid instance:
var grid = new Hypergrid;And a theme object:
var themeObject = {
backgroundColor: 'black',
color: 'lime'
};The grid.applyTheme() grid method applies the theme to the grid. This method copies properties from the given themeObject to the permanent grid.theme layer.
grid.applyTheme(themeObject);
// or:
grid.theme = themeObject; // as of Hypergrid 3.0.0 you can also use this setterThe grid.properties.theme is another setter that invokes applyTheme(). This setter facilitates specifying theme in a grid state object (see Persisting Grid State) so a theme can be loaded along with the rest of the grid state properties. See below, Loading & Saving Themes.
To remove a theme from a grid instance:
grid.applyTheme(null); // you an also pass `{}` or `undefined` or nothing
// or:
grid.theme = null; // as of 3.0.0To set the global theme:
Hypergrid.applyTheme(themeObject);
// or:
Hypergrid.theme = themeObject;This method copies properties from the given themeObject to the Hypergrid.defaults layer.
The global theme affects all grid instances on the page. Per the Grid Properties wiki, the global theme "layer" exists below the grid instance's theme layer, the properties of which will override those of the global theme.
To remove the global theme from all instances:
Hypergrid.applyTheme(null); // you an also pass `{}` or `undefined` or nothing
// or:
Hypergrid.theme = null; // as of 3.0.0Under the covers, this just reapplies the 'default' theme to the defaults layer (a copy of the original defaults), thereby restoring it to its original state.
Themes can be named or anonymous. Embedding a name in a theme definition makes the theme easily identifiable later on:
themeObject.themeName = 'bob';
console.log('Current theme is', grid.theme.themeName); // logs: "Current theme is bob"As of Hypergrid v2.0.0, themes can be "registered" and thereafter referred to by name. This facilitates easily switching among a set of predefined themes. As of Hypergrid v3.0.0, themes can also be unregistered.
There is a single global theme registry, set with Hypergrid.registerTheme and Hypergrid.registerThemes; and accessible to all grid instances via grid.applyTheme(themeName) and globally via Hypergrid.applyTheme(themeName).
To register a theme:
Hypergrid.registerTheme(themeObject); // `themeName` property required
// or:
Hypergrid.registerTheme(themeName, themeObject); // `themeName` param overrides `themeName` propertyTo register a whole collection of themes all at once:
Hypergrid.registerThemes(themeObjectsCollection); // collection keys override `themeName` propertiesThis makes registering a theme library trivial:
Hypergrid.registerThemes(require('./my-theme-library'));Note that grids are unaffected when a currently applied theme is re-registered with a new theme object.
As of Hypergrid 3.0.0, themes can be unregistered.
To unregister a theme, use one of the following overloads of registerTheme:
Hypergrid.registerTheme(themeName); // as of 3.0.0To unregister all themes:
Hypergrid.registerThemes(); // as of 3.0.0Note that grids are unaffected when a currently applied theme is unregistered.
Named themes are applied by applyTheme similarly to the way explicit theme objects were, except now we provide a theme name rather than an theme object:
grid.applyTheme(themeName); // string overload
// or:
grid.theme = themeName; // as of 3.0.0
// or:
grid.properties.theme = themeName;To apply a registered them as the global theme:
Hypergrid.applyTheme(themeName);
// or:
Hypergrid.theme = themeName`Note that any reference to a theme by name requires it to have been previously registered.
Use gird.properties.themeName to determine what theme is currently applied. This will be one of:
- When an instance theme is applied:
- The theme name when known
- Else
undefinedfor anonymous themes (applied using theapplyTheme(object)overload; registered themes cannot be anonymous)
- Else, when a global theme is applied:
- The global theme's name when known
- Else
undefinedfor an anonymous global theme
- Else, when neither an instance theme nor a global them are applied:
'default'
Note that grid.properties.theme will generally also return the theme name, although it differs subtly from grid.theme.themeName in that it will never return 'default'; and when the applied theme is not a registered theme, it will return the theme object itself. The reason for this is that this property is engineered for persisting state. Specifically, it returns:
-
undefinedwhen theme is undefined (excluded entirely byJSON.stringify) - Else, the theme name when the theme is registered; or
- Else, the theme object when the theme is unregistered.
If it is the theme name that is persisted, it is the application developer's responsibility to make sure the required themes are properly registered before the state is reloaded later.
The theme grid property contains the currently applied theme. This will be:
- A theme object for an anonymous or unregistered theme; or
- A theme name (string) for a registered theme.
Therefore, an applied theme will be output with the grid state object (see grid.saveState()).
It is not necessary to call applyTheme to load a theme with the rest of grid state,
var stateObject = {
..., // other properties
theme: myTheme
};
var grid = new Hypergrid({ state: stateObject }); // either at grid instantiation
grid.loadState(stateObject); // or later, after instantiation[ This section needs to be finished. ]