-
Notifications
You must be signed in to change notification settings - Fork 143
Themes
ToDo: Finish the Creating a custom theme section.
This wiki discusses grid themes (or "skins"):
- Applying a theme to a
Hypergrid
instance - 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
properties
collection 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 the
delete(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 all
properties` 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 setter
The 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.0
To 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.0
Under 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` property
To register a whole collection of themes all at once:
Hypergrid.registerThemes(themeObjectsCollection); // collection keys override `themeName` properties
This 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.0
To unregister all themes:
Hypergrid.registerThemes(); // as of 3.0.0
Note 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
undefined
for 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
undefined
for 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:
-
undefined
when 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. ]