1 /* 2 * Copyright 2022 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.ux.material.libmonet.dynamiccolor; 18 19 import com.google.ux.material.libmonet.hct.Hct; 20 import com.google.ux.material.libmonet.palettes.TonalPalette; 21 import com.google.ux.material.libmonet.utils.MathUtils; 22 23 /** 24 * Provides important settings for creating colors dynamically, and 6 color palettes. Requires: 1. A 25 * color. (source color) 2. A theme. (Variant) 3. Whether or not its dark mode. 4. Contrast level. 26 * (-1 to 1, currently contrast ratio 3.0 and 7.0) 27 */ 28 public class DynamicScheme { 29 public final int sourceColorArgb; 30 public final Hct sourceColorHct; 31 public final Variant variant; 32 public final boolean isDark; 33 public final double contrastLevel; 34 35 public final TonalPalette primaryPalette; 36 public final TonalPalette secondaryPalette; 37 public final TonalPalette tertiaryPalette; 38 public final TonalPalette neutralPalette; 39 public final TonalPalette neutralVariantPalette; 40 public final TonalPalette errorPalette; 41 DynamicScheme( Hct sourceColorHct, Variant variant, boolean isDark, double contrastLevel, TonalPalette primaryPalette, TonalPalette secondaryPalette, TonalPalette tertiaryPalette, TonalPalette neutralPalette, TonalPalette neutralVariantPalette)42 public DynamicScheme( 43 Hct sourceColorHct, 44 Variant variant, 45 boolean isDark, 46 double contrastLevel, 47 TonalPalette primaryPalette, 48 TonalPalette secondaryPalette, 49 TonalPalette tertiaryPalette, 50 TonalPalette neutralPalette, 51 TonalPalette neutralVariantPalette) { 52 this.sourceColorArgb = sourceColorHct.toInt(); 53 this.sourceColorHct = sourceColorHct; 54 this.variant = variant; 55 this.isDark = isDark; 56 this.contrastLevel = contrastLevel; 57 58 this.primaryPalette = primaryPalette; 59 this.secondaryPalette = secondaryPalette; 60 this.tertiaryPalette = tertiaryPalette; 61 this.neutralPalette = neutralPalette; 62 this.neutralVariantPalette = neutralVariantPalette; 63 this.errorPalette = TonalPalette.fromHueAndChroma(25.0, 84.0); 64 } 65 66 /** 67 * Given a set of hues and set of hue rotations, locate which hues the source color's hue is 68 * between, apply the rotation at the same index as the first hue in the range, and return the 69 * rotated hue. 70 * 71 * @param sourceColorHct The color whose hue should be rotated. 72 * @param hues A set of hues. 73 * @param rotations A set of hue rotations. 74 * @return Color's hue with a rotation applied. 75 */ getRotatedHue(Hct sourceColorHct, double[] hues, double[] rotations)76 public static double getRotatedHue(Hct sourceColorHct, double[] hues, double[] rotations) { 77 final double sourceHue = sourceColorHct.getHue(); 78 if (rotations.length == 1) { 79 return MathUtils.sanitizeDegreesDouble(sourceHue + rotations[0]); 80 } 81 final int size = hues.length; 82 for (int i = 0; i <= (size - 2); i++) { 83 final double thisHue = hues[i]; 84 final double nextHue = hues[i + 1]; 85 if (thisHue < sourceHue && sourceHue < nextHue) { 86 return MathUtils.sanitizeDegreesDouble(sourceHue + rotations[i]); 87 } 88 } 89 // If this statement executes, something is wrong, there should have been a rotation 90 // found using the arrays. 91 return sourceHue; 92 } 93 getHct(DynamicColor dynamicColor)94 public Hct getHct(DynamicColor dynamicColor) { 95 return dynamicColor.getHct(this); 96 } 97 getArgb(DynamicColor dynamicColor)98 public int getArgb(DynamicColor dynamicColor) { 99 return dynamicColor.getArgb(this); 100 } 101 getPrimaryPaletteKeyColor()102 public int getPrimaryPaletteKeyColor() { 103 return getArgb(new MaterialDynamicColors().primaryPaletteKeyColor()); 104 } 105 getSecondaryPaletteKeyColor()106 public int getSecondaryPaletteKeyColor() { 107 return getArgb(new MaterialDynamicColors().secondaryPaletteKeyColor()); 108 } 109 getTertiaryPaletteKeyColor()110 public int getTertiaryPaletteKeyColor() { 111 return getArgb(new MaterialDynamicColors().tertiaryPaletteKeyColor()); 112 } 113 getNeutralPaletteKeyColor()114 public int getNeutralPaletteKeyColor() { 115 return getArgb(new MaterialDynamicColors().neutralPaletteKeyColor()); 116 } 117 getNeutralVariantPaletteKeyColor()118 public int getNeutralVariantPaletteKeyColor() { 119 return getArgb(new MaterialDynamicColors().neutralVariantPaletteKeyColor()); 120 } 121 getBackground()122 public int getBackground() { 123 return getArgb(new MaterialDynamicColors().background()); 124 } 125 getOnBackground()126 public int getOnBackground() { 127 return getArgb(new MaterialDynamicColors().onBackground()); 128 } 129 getSurface()130 public int getSurface() { 131 return getArgb(new MaterialDynamicColors().surface()); 132 } 133 getSurfaceDim()134 public int getSurfaceDim() { 135 return getArgb(new MaterialDynamicColors().surfaceDim()); 136 } 137 getSurfaceBright()138 public int getSurfaceBright() { 139 return getArgb(new MaterialDynamicColors().surfaceBright()); 140 } 141 getSurfaceContainerLowest()142 public int getSurfaceContainerLowest() { 143 return getArgb(new MaterialDynamicColors().surfaceContainerLowest()); 144 } 145 getSurfaceContainerLow()146 public int getSurfaceContainerLow() { 147 return getArgb(new MaterialDynamicColors().surfaceContainerLow()); 148 } 149 getSurfaceContainer()150 public int getSurfaceContainer() { 151 return getArgb(new MaterialDynamicColors().surfaceContainer()); 152 } 153 getSurfaceContainerHigh()154 public int getSurfaceContainerHigh() { 155 return getArgb(new MaterialDynamicColors().surfaceContainerHigh()); 156 } 157 getSurfaceContainerHighest()158 public int getSurfaceContainerHighest() { 159 return getArgb(new MaterialDynamicColors().surfaceContainerHighest()); 160 } 161 getOnSurface()162 public int getOnSurface() { 163 return getArgb(new MaterialDynamicColors().onSurface()); 164 } 165 getSurfaceVariant()166 public int getSurfaceVariant() { 167 return getArgb(new MaterialDynamicColors().surfaceVariant()); 168 } 169 getOnSurfaceVariant()170 public int getOnSurfaceVariant() { 171 return getArgb(new MaterialDynamicColors().onSurfaceVariant()); 172 } 173 getInverseSurface()174 public int getInverseSurface() { 175 return getArgb(new MaterialDynamicColors().inverseSurface()); 176 } 177 getInverseOnSurface()178 public int getInverseOnSurface() { 179 return getArgb(new MaterialDynamicColors().inverseOnSurface()); 180 } 181 getOutline()182 public int getOutline() { 183 return getArgb(new MaterialDynamicColors().outline()); 184 } 185 getOutlineVariant()186 public int getOutlineVariant() { 187 return getArgb(new MaterialDynamicColors().outlineVariant()); 188 } 189 getShadow()190 public int getShadow() { 191 return getArgb(new MaterialDynamicColors().shadow()); 192 } 193 getScrim()194 public int getScrim() { 195 return getArgb(new MaterialDynamicColors().scrim()); 196 } 197 getSurfaceTint()198 public int getSurfaceTint() { 199 return getArgb(new MaterialDynamicColors().surfaceTint()); 200 } 201 getPrimary()202 public int getPrimary() { 203 return getArgb(new MaterialDynamicColors().primary()); 204 } 205 getOnPrimary()206 public int getOnPrimary() { 207 return getArgb(new MaterialDynamicColors().onPrimary()); 208 } 209 getPrimaryContainer()210 public int getPrimaryContainer() { 211 return getArgb(new MaterialDynamicColors().primaryContainer()); 212 } 213 getOnPrimaryContainer()214 public int getOnPrimaryContainer() { 215 return getArgb(new MaterialDynamicColors().onPrimaryContainer()); 216 } 217 getInversePrimary()218 public int getInversePrimary() { 219 return getArgb(new MaterialDynamicColors().inversePrimary()); 220 } 221 getSecondary()222 public int getSecondary() { 223 return getArgb(new MaterialDynamicColors().secondary()); 224 } 225 getOnSecondary()226 public int getOnSecondary() { 227 return getArgb(new MaterialDynamicColors().onSecondary()); 228 } 229 getSecondaryContainer()230 public int getSecondaryContainer() { 231 return getArgb(new MaterialDynamicColors().secondaryContainer()); 232 } 233 getOnSecondaryContainer()234 public int getOnSecondaryContainer() { 235 return getArgb(new MaterialDynamicColors().onSecondaryContainer()); 236 } 237 getTertiary()238 public int getTertiary() { 239 return getArgb(new MaterialDynamicColors().tertiary()); 240 } 241 getOnTertiary()242 public int getOnTertiary() { 243 return getArgb(new MaterialDynamicColors().onTertiary()); 244 } 245 getTertiaryContainer()246 public int getTertiaryContainer() { 247 return getArgb(new MaterialDynamicColors().tertiaryContainer()); 248 } 249 getOnTertiaryContainer()250 public int getOnTertiaryContainer() { 251 return getArgb(new MaterialDynamicColors().onTertiaryContainer()); 252 } 253 getError()254 public int getError() { 255 return getArgb(new MaterialDynamicColors().error()); 256 } 257 getOnError()258 public int getOnError() { 259 return getArgb(new MaterialDynamicColors().onError()); 260 } 261 getErrorContainer()262 public int getErrorContainer() { 263 return getArgb(new MaterialDynamicColors().errorContainer()); 264 } 265 getOnErrorContainer()266 public int getOnErrorContainer() { 267 return getArgb(new MaterialDynamicColors().onErrorContainer()); 268 } 269 getPrimaryFixed()270 public int getPrimaryFixed() { 271 return getArgb(new MaterialDynamicColors().primaryFixed()); 272 } 273 getPrimaryFixedDim()274 public int getPrimaryFixedDim() { 275 return getArgb(new MaterialDynamicColors().primaryFixedDim()); 276 } 277 getOnPrimaryFixed()278 public int getOnPrimaryFixed() { 279 return getArgb(new MaterialDynamicColors().onPrimaryFixed()); 280 } 281 getOnPrimaryFixedVariant()282 public int getOnPrimaryFixedVariant() { 283 return getArgb(new MaterialDynamicColors().onPrimaryFixedVariant()); 284 } 285 getSecondaryFixed()286 public int getSecondaryFixed() { 287 return getArgb(new MaterialDynamicColors().secondaryFixed()); 288 } 289 getSecondaryFixedDim()290 public int getSecondaryFixedDim() { 291 return getArgb(new MaterialDynamicColors().secondaryFixedDim()); 292 } 293 getOnSecondaryFixed()294 public int getOnSecondaryFixed() { 295 return getArgb(new MaterialDynamicColors().onSecondaryFixed()); 296 } 297 getOnSecondaryFixedVariant()298 public int getOnSecondaryFixedVariant() { 299 return getArgb(new MaterialDynamicColors().onSecondaryFixedVariant()); 300 } 301 getTertiaryFixed()302 public int getTertiaryFixed() { 303 return getArgb(new MaterialDynamicColors().tertiaryFixed()); 304 } 305 getTertiaryFixedDim()306 public int getTertiaryFixedDim() { 307 return getArgb(new MaterialDynamicColors().tertiaryFixedDim()); 308 } 309 getOnTertiaryFixed()310 public int getOnTertiaryFixed() { 311 return getArgb(new MaterialDynamicColors().onTertiaryFixed()); 312 } 313 getOnTertiaryFixedVariant()314 public int getOnTertiaryFixedVariant() { 315 return getArgb(new MaterialDynamicColors().onTertiaryFixedVariant()); 316 } 317 getControlActivated()318 public int getControlActivated() { 319 return getArgb(new MaterialDynamicColors().controlActivated()); 320 } 321 getControlNormal()322 public int getControlNormal() { 323 return getArgb(new MaterialDynamicColors().controlNormal()); 324 } 325 getControlHighlight()326 public int getControlHighlight() { 327 return getArgb(new MaterialDynamicColors().controlHighlight()); 328 } 329 getTextPrimaryInverse()330 public int getTextPrimaryInverse() { 331 return getArgb(new MaterialDynamicColors().textPrimaryInverse()); 332 } 333 getTextSecondaryAndTertiaryInverse()334 public int getTextSecondaryAndTertiaryInverse() { 335 return getArgb(new MaterialDynamicColors().textSecondaryAndTertiaryInverse()); 336 } 337 getTextPrimaryInverseDisableOnly()338 public int getTextPrimaryInverseDisableOnly() { 339 return getArgb(new MaterialDynamicColors().textPrimaryInverseDisableOnly()); 340 } 341 getTextSecondaryAndTertiaryInverseDisabled()342 public int getTextSecondaryAndTertiaryInverseDisabled() { 343 return getArgb(new MaterialDynamicColors().textSecondaryAndTertiaryInverseDisabled()); 344 } 345 getTextHintInverse()346 public int getTextHintInverse() { 347 return getArgb(new MaterialDynamicColors().textHintInverse()); 348 } 349 } 350