@@ -266,23 +266,23 @@ element_grob.element_line <- function(element, x = 0:1, y = 0:1,
266266 )
267267}
268268
269-
270-
271- # ' Define new elements for a theme's element tree
269+ # ' Define and register new theme elements
272270# '
273- # ' Each theme has an element tree that defines which theme elements inherit
274- # ' theme parameters from which other elements. The function `el_def()` can be used
275- # ' to define new or modified elements for this tree.
271+ # ' The underlying structure of a ggplot2 theme is defined via the element tree, which
272+ # ' specifies for each theme element what type it should have and whether it inherits from
273+ # ' a parent element. In some use cases, it may be necessary to modify or extend this
274+ # ' element tree and provide default settings for newly defined theme elements.
276275# '
277- # ' @param class The name of the element class. Examples are "element_line" or
278- # ' "element_text" or "unit", or one of the two reserved keywords "character" or
279- # ' "margin". The reserved keyword "character" implies a character
280- # ' or numeric vector, not a class called "character". The keyword
281- # ' "margin" implies a unit vector of length 4, as created by [margin()].
282- # ' @param inherit A vector of strings, naming the elements that this
283- # ' element inherits from.
284- # ' @param description An optional character vector providing a description
285- # ' for the element.
276+ # ' The function `register_theme_elements()` provides the option to globally register new
277+ # ' theme elements with ggplot2. In general, for each new theme element both an element
278+ # ' definition and a corresponding entry in the element tree should be provided. See
279+ # ' examples for details. For extension package that use this functionality, it is
280+ # ' recommended to call `register_theme_elements()` from the `.onLoad()` function.
281+ # ' @param ... Element specifications
282+ # ' @param element_tree Addition of or modification to the element tree, which specifies the
283+ # ' inheritance relationship of the theme elements. The element tree must be provided as
284+ # ' a list of named element definitions created with el_def().
285+ # ' @param complete If `TRUE` (the default), elements are set to inherit from blank elements.
286286# ' @examples
287287# ' # define a new coord that includes a panel annotation
288288# ' coord_annotate <- function(label = "panel annotation") {
@@ -297,9 +297,8 @@ element_grob.element_line <- function(element, x = 0:1, y = 0:1,
297297# ' )
298298# ' }
299299# '
300- # ' # update the default theme by adding a new `panel.annotation`
301- # ' # theme element
302- # ' old <- theme_update(
300+ # ' # register a new theme element `panel.annotation`
301+ # ' register_theme_elements(
303302# ' panel.annotation = element_text(color = "blue", hjust = 0.95, vjust = 0.05),
304303# ' element_tree = list(panel.annotation = el_def("element_text", "text"))
305304# ' )
@@ -309,18 +308,74 @@ element_grob.element_line <- function(element, x = 0:1, y = 0:1,
309308# ' geom_point() +
310309# ' coord_annotate("annotation in blue")
311310# '
312- # ' # revert to original default theme
313- # ' theme_set(old)
311+ # ' # revert to original ggplot2 settings
312+ # ' reset_theme_settings()
313+ # ' @keywords internal
314+ # ' @export
315+ register_theme_elements <- function (... , element_tree = NULL , complete = TRUE ) {
316+ old <- ggplot_global $ theme_default
317+ t <- theme(... , complete = complete )
318+ ggplot_global $ theme_default <- ggplot_global $ theme_default %+ replace % t
319+
320+ # Merge element trees
321+ ggplot_global $ element_tree <- defaults(element_tree , ggplot_global $ element_tree )
322+
323+ invisible (old )
324+ }
325+
326+ # ' @rdname register_theme_elements
327+ # ' @details
328+ # ' The function `reset_theme_settings()` restores the default element tree, discards
329+ # ' all new element definitions, and (unless turned off) resets the currently active
330+ # ' theme to the default.
331+ # ' @param reset_current If `TRUE` (the default), the currently active theme is
332+ # ' reset to the default theme.
333+ # ' @keywords internal
334+ # ' @export
335+ reset_theme_settings <- function (reset_current = TRUE ) {
336+ ggplot_global $ element_tree <- .element_tree
337+
338+ # reset the underlying fallback default theme
339+ ggplot_global $ theme_default <- theme_grey()
340+
341+ if (isTRUE(reset_current )) {
342+ # reset the currently active theme
343+ ggplot_global $ theme_current <- ggplot_global $ theme_default
344+ }
345+ }
346+
347+ # ' @rdname register_theme_elements
348+ # ' @details
349+ # ' The function `get_element_tree()` returns the currently active element tree.
350+ # ' @keywords internal
351+ # ' @export
352+ get_element_tree <- function () {
353+ ggplot_global $ element_tree
354+ }
355+
356+ # ' @rdname register_theme_elements
357+ # ' @details
358+ # ' The function `el_def()` is used to define new or modified element types and
359+ # ' element inheritance relationships for the element tree.
360+ # ' @param class The name of the element class. Examples are "element_line" or
361+ # ' "element_text" or "unit", or one of the two reserved keywords "character" or
362+ # ' "margin". The reserved keyword "character" implies a character
363+ # ' or numeric vector, not a class called "character". The keyword
364+ # ' "margin" implies a unit vector of length 4, as created by [margin()].
365+ # ' @param inherit A vector of strings, naming the elements that this
366+ # ' element inherits from.
367+ # ' @param description An optional character vector providing a description
368+ # ' for the element.
314369# ' @keywords internal
315370# ' @export
316371el_def <- function (class = NULL , inherit = NULL , description = NULL ) {
317372 list (class = class , inherit = inherit , description = description )
318373}
319374
320375
321- # This data structure represents the theme elements and the inheritance
322- # among them. (In the future, .element_tree should be removed in favor
323- # of direct assignment to ggplot_global$element_tree, see below.)
376+ # This data structure represents the default theme elements and the inheritance
377+ # among them. It should not be read from directly, since users may modify the
378+ # current element tree stored in ggplot_global$element_tree
324379.element_tree <- list (
325380 line = el_def(" element_line" ),
326381 rect = el_def(" element_rect" ),
@@ -424,8 +479,6 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) {
424479 aspect.ratio = el_def(" character" )
425480)
426481
427- ggplot_global $ element_tree <- .element_tree
428-
429482# Check that an element object has the proper class
430483#
431484# Given an element object and the name of the element, this function
0 commit comments