9292# '   to generate the values for the `expand` argument. The defaults are to
9393# '   expand the scale by 5% on each side for continuous variables, and by
9494# '   0.6 units on each side for discrete variables.
95+ # ' @param fallback.palette Function to use when `palette = NULL` and the
96+ # '   palette is not represented in the theme.
9597# ' @param position For position scales, The position of the axis.
9698# ' `left` or `right` for y axes, `top` or `bottom` for x axes.
9799# ' @param call The `call` used to construct the scale for reporting messages.
@@ -107,6 +109,7 @@ continuous_scale <- function(aesthetics, scale_name = deprecated(), palette, nam
107109                             oob  =  censor , expand  =  waiver(), na.value  =  NA ,
108110                             transform  =  " identity" trans  =  deprecated(),
109111                             guide  =  " legend" position  =  " left" 
112+                              fallback.palette  =  NULL ,
110113                             call  =  caller_call(),
111114                             super  =  ScaleContinuous ) {
112115  call  <-  call  %|| % current_call()
@@ -121,6 +124,7 @@ continuous_scale <- function(aesthetics, scale_name = deprecated(), palette, nam
121124  aesthetics  <-  standardise_aes_names(aesthetics )
122125
123126  check_breaks_labels(breaks , labels , call  =  call )
127+   check_fallback_palette(palette , fallback.palette , call  =  call )
124128
125129  position  <-  arg_match0(position , c(" left" " right" " top" " bottom" 
126130
@@ -152,6 +156,7 @@ continuous_scale <- function(aesthetics, scale_name = deprecated(), palette, nam
152156
153157    aesthetics  =  aesthetics ,
154158    palette  =  palette ,
159+     fallback_palette  =  fallback.palette ,
155160
156161    range  =  ContinuousRange $ new(),
157162    limits  =  limits ,
@@ -211,6 +216,7 @@ discrete_scale <- function(aesthetics, scale_name = deprecated(), palette, name
211216                           labels  =  waiver(), limits  =  NULL , expand  =  waiver(),
212217                           na.translate  =  TRUE , na.value  =  NA , drop  =  TRUE ,
213218                           guide  =  " legend" position  =  " left" 
219+                            fallback.palette  =  NULL ,
214220                           call  =  caller_call(),
215221                           super  =  ScaleDiscrete ) {
216222  call  <-  call  %|| % current_call()
@@ -221,6 +227,7 @@ discrete_scale <- function(aesthetics, scale_name = deprecated(), palette, name
221227  aesthetics  <-  standardise_aes_names(aesthetics )
222228
223229  check_breaks_labels(breaks , labels , call  =  call )
230+   check_fallback_palette(palette , fallback.palette , call  =  call )
224231
225232  #  Convert formula input to function if appropriate
226233  limits  <-  allow_lambda(limits )
@@ -251,6 +258,7 @@ discrete_scale <- function(aesthetics, scale_name = deprecated(), palette, name
251258
252259    aesthetics  =  aesthetics ,
253260    palette  =  palette ,
261+     fallback_palette  =  fallback.palette ,
254262
255263    range  =  DiscreteRange $ new(),
256264    limits  =  limits ,
@@ -303,6 +311,7 @@ binned_scale <- function(aesthetics, scale_name = deprecated(), palette, name =
303311                         right  =  TRUE , transform  =  " identity" 
304312                         trans  =  deprecated(), show.limits  =  FALSE ,
305313                         guide  =  " bins" position  =  " left" 
314+                          fallback.palette  =  NULL ,
306315                         call  =  caller_call(),
307316                         super  =  ScaleBinned ) {
308317  if  (lifecycle :: is_present(scale_name )) {
@@ -318,6 +327,7 @@ binned_scale <- function(aesthetics, scale_name = deprecated(), palette, name =
318327  aesthetics  <-  standardise_aes_names(aesthetics )
319328
320329  check_breaks_labels(breaks , labels , call  =  call )
330+   check_fallback_palette(palette , fallback.palette , call  =  call )
321331
322332  position  <-  arg_match0(position , c(" left" " right" " top" " bottom" 
323333
@@ -346,6 +356,7 @@ binned_scale <- function(aesthetics, scale_name = deprecated(), palette, name =
346356
347357    aesthetics  =  aesthetics ,
348358    palette  =  palette ,
359+     fallback_palette  =  fallback.palette ,
349360
350361    range  =  ContinuousRange $ new(),
351362    limits  =  limits ,
@@ -589,7 +600,7 @@ Scale <- ggproto("Scale", NULL,
589600    if  (empty(df )) {
590601      return ()
591602    }
592-     self $ palette  <-  self $ palette  %|| % fallback_palette (self )
603+     self $ palette  <-  self $ palette  %|| % fetch_ggproto (self ,  " fallback_palette " 
593604
594605    aesthetics  <-  intersect(self $ aesthetics , names(df ))
595606    names(aesthetics ) <-  aesthetics 
@@ -1775,6 +1786,15 @@ check_continuous_limits <- function(limits, ...,
17751786  check_length(limits , 2L , arg  =  arg , call  =  call )
17761787}
17771788
1789+ check_fallback_palette  <-  function (pal , fallback , call  =  caller_env()) {
1790+   if  (! is.null(pal ) ||  is.function(fallback )) {
1791+     return (invisible ())
1792+   }
1793+   cli :: cli_abort(
1794+     " When {.code palette = NULL}, the {.arg fallback.palette} must be defined." 
1795+   )
1796+ }
1797+ 
17781798allow_lambda  <-  function (x ) {
17791799  #  we check the 'call' class to prevent interpreting `bquote()` calls as a function
17801800  if  (is_formula(x , lhs  =  FALSE ) &&  ! inherits(x , " call" x ) else  x 
0 commit comments