File modules/cms/ui/themes/ThemeStyle.class.php

Last commit: Thu Dec 26 19:53:54 2024 +0100	Jan Dankert	The ThemeStyle is now able to mix colors and all colors are now internally hold as RGB; New Group background colors in the UI.
1 <?php 2 3 4 namespace cms\ui\themes; 5 6 7 use cms\base\Configuration as C; 8 use util\text\Converter; 9 10 class ThemeStyle 11 { 12 private $name; 13 14 private $textColor = [0,0,0]; // 'black', default text color 15 private $backgroundColor = [217,217,217]; // '#d9d9d9', default background color 16 17 private $inactiveBackgroundColor; 18 19 private $mainTextColor ; 20 private $mainBackgroundColor; 21 private $mainGroupBackgroundColor; 22 private $mainTitleBackgroundColor; 23 private $mainTitleTextColor; 24 25 private $navBackgroundColor; 26 private $navGroupBackgroundColor; 27 private $navTextColor; 28 private $navTitleBackgroundColor; 29 private $navTitleTextColor; 30 31 private $dialogTitleBackgroundColor; 32 private $dialogTitleTextColor; 33 private $dialogBackgroundColor; 34 private $dialogGroupBackgroundColor; 35 private $dialogTextColor; 36 37 private $themeColor; 38 private $arrowColor; 39 private $imageColor; 40 41 private $noticeOkColor = '#00d95a'; 42 private $noticeInfoColor = '#86caff'; 43 private $noticeWarningColor = '#FBDE2D'; 44 private $noticeErrorColor = '#f54b07'; 45 46 private $transitionDuration = '0.2s'; 47 48 49 const COLORS =[ 50 'aliceblue' =>'#f0f8ff', 51 'antiquewhite'=>'#faebd7', 52 'aqua' =>'#00ffff', 53 'aquamarine' =>'#7fffd4', 54 'azure' =>'#f0ffff', 55 'beige' =>'#f5f5dc', 56 'bisque' =>'#ffe4c4', 57 'black' =>'#000000', 58 'blanchedalmond'=>'#ffebcd', 59 'blue' =>'#0000ff', 60 'blueviolet' =>'#8a2be2', 61 'brown' =>'#a52a2a', 62 'burlywood' =>'#deb887', 63 'cadetblue' =>'#5f9ea0', 64 'chartreuse' =>'#7fff00', 65 'chocolate' =>'#d2691e', 66 'coral' =>'#ff7f50', 67 'cornflowerblue'=>'#6495ed', 68 'cornsilk' =>'#fff8dc', 69 'crimson' =>'#dc143c', 70 'cyan' =>'#00ffff', 71 'darkblue' => '#00008b', 72 'darkcyan' => '#008b8b', 73 'darkgoldenrod'=> '#b8860b', 74 'darkgray' => '#a9a9a9', 75 'darkgrey' => '#a9a9a9', 76 'darkgreen' => '#006400', 77 'darkkhaki' => '#bdb76b', 78 'darkmagenta' => '#8b008b', 79 'darkolivegreen' => '#556b2f', 80 'darkorange' => '#ff8c00', 81 'darkorchid' => '#9932cc', 82 'darkred' => '#8b0000', 83 'darksalmon' => '#e9967a', 84 'darkseagreen' => '#8fbc8f', 85 'darkslateblue' => '#483d8b', 86 'darkslategray' => '#2f4f4f', 87 'darkslategrey' => '#2f4f4f', 88 'darkturquoise' => '#00ced1', 89 'darkviolet' => '#9400d3', 90 'deeppink' => '#ff1493', 91 'deepskyblue' => '#00bfff', 92 'dimgray' => '#696969', 93 'dimgrey' => '#696969', 94 'dodgerblue' => '#1e90ff', 95 'firebrick' => '#b22222', 96 'floralwhite' => '#fffaf0', 97 'forestgreen' => '#228b22', 98 'fuchsia' => '#ff00ff', 99 'gainsboro' => '#dcdcdc', 100 'ghostwhite' => '#f8f8ff', 101 'gold' => '#ffd700', 102 'goldenrod' => '#daa520', 103 'gray' => '#808080', 104 'grey' => '#808080', 105 'green' => '#008000', 106 'greenyellow' => '#adff2f', 107 'honeydew' => '#f0fff0', 108 'hotpink' => '#ff69b4', 109 'indianred' => '#cd5c5c', 110 'indigo' => '#4b0082', 111 'ivory' => '#fffff0', 112 'khaki' => '#f0e68c', 113 'lavender' => '#e6e6fa', 114 'lavenderblush' => '#fff0f5', 115 'lawngreen' => '#7cfc00', 116 'lemonchiffon' => '#fffacd', 117 'lightblue' => '#add8e6', 118 'lightcoral' => '#f08080', 119 'lightcyan' => '#e0ffff', 120 'lightgoldenrodyellow' => '#fafad2', 121 'lightgray' => '#d3d3d3', 122 'lightgrey' => '#d3d3d3', 123 'lightgreen' => '#90ee90', 124 'lightpink' => '#ffb6c1', 125 'lightsalmon' => '#ffa07a', 126 'lightseagreen' => '#20b2aa', 127 'lightskyblue' => '#87cefa', 128 'lightslategray' => '#778899', 129 'lightslategrey' => '#778899', 130 'lightsteelblue' => '#b0c4de', 131 'lightyellow' => '#ffffe0', 132 'lime' => '#00ff00', 133 'limegreen' => '#32cd32', 134 'linen' => '#faf0e6', 135 'magenta' => '#ff00ff', 136 'maroon' => '#800000', 137 'mediumaquamarine' => '#66cdaa', 138 'mediumblue' => '#0000cd', 139 'mediumorchid' => '#ba55d3', 140 'mediumpurple' => '#9370d8', 141 'mediumseagreen' => '#3cb371', 142 'mediumslateblue' => '#7b68ee', 143 'mediumspringgreen' => '#00fa9a', 144 'mediumturquoise' => '#48d1cc', 145 'mediumvioletred' => '#c71585', 146 'midnightblue' => '#191970', 147 'mintcream' => '#f5fffa', 148 'mistyrose' => '#ffe4e1', 149 'moccasin' => '#ffe4b5', 150 'navajowhite' => '#ffdead', 151 'navy' => '#000080', 152 'oldlace' => '#fdf5e6', 153 'olive' => '#808000', 154 'olivedrab' => '#6b8e23', 155 'orange' => '#ffa500', 156 'orangered' => '#ff4500', 157 'orchid' => '#da70d6', 158 'palegoldenrod' => '#eee8aa', 159 'palegreen' => '#98fb98', 160 'paleturquoise' => '#afeeee', 161 'palevioletred' => '#d87093', 162 'papayawhip' => '#ffefd5', 163 'peachpuff' => '#ffdab9', 164 'peru' => '#cd853f', 165 'pink' => '#ffc0cb', 166 'plum' => '#dda0dd', 167 'powderblue' => '#b0e0e6', 168 'purple' => '#800080', 169 'red' => '#ff0000', 170 'rosybrown' => '#bc8f8f', 171 'royalblue' => '#4169e1', 172 'saddlebrown' => '#8b4513', 173 'salmon' => '#fa8072', 174 'sandybrown' => '#f4a460', 175 'seagreen' => '#2e8b57', 176 'seashell' => '#fff5ee', 177 'sienna' => '#a0522d', 178 'silver' => '#c0c0c0', 179 'skyblue' => '#87ceeb', 180 'slateblue' => '#6a5acd', 181 'slategray' => '#708090', 182 'slategrey' => '#708090', 183 'snow' => '#fffafa', 184 'springgreen' => '#00ff7f', 185 'steelblue' => '#4682b4', 186 'tan' => '#d2b48c', 187 'teal' => '#008080', 188 'thistle' => '#d8bfd8', 189 'tomato' => '#ff6347', 190 'turquoise' => '#40e0d0', 191 'violet' => '#ee82ee', 192 'wheat' => '#f5deb3', 193 'white' => '#ffffff', 194 'whitesmoke' => '#f5f5f5', 195 'yellow' => '#ffff00', 196 'yellowgreen' => '#9acd32' 197 ]; 198 199 /** 200 * ThemeStyle constructor. 201 */ 202 public function __construct( $config ) 203 { 204 if ( is_string( $config ) ) 205 $config = C::subset('style')->get( $config,[]); // user style config 206 207 $this->setValues( $config ); 208 $this->fillMissingValues(); 209 } 210 211 212 213 protected function setValues( $styleConfig ) { 214 215 foreach( $styleConfig as $property=>$value ) { 216 $property = Converter::toCamelCase($property); 217 if ( property_exists($this,$property ) ) { 218 if ( substr($property,-5) == 'Color') 219 // - Converting color names to HEX 220 // - Converting HEX to RGB values 221 $this->$property = $this->hex2rgb(self::getColorHexCodeForName($value)); 222 else 223 $this->$property = $value; 224 225 } 226 } 227 } 228 229 230 /** 231 * Fill empty values with a default value. 232 */ 233 protected function fillMissingValues() { 234 235 if ( ! $this->mainTitleBackgroundColor ) 236 $this->mainTitleBackgroundColor = $this->backgroundColor; 237 238 if ( ! $this->mainTitleTextColor ) 239 $this->mainTitleTextColor = $this->textColor; 240 241 if ( ! $this->mainBackgroundColor ) 242 $this->mainBackgroundColor = $this->backgroundColor; 243 244 if ( ! $this->mainTextColor ) 245 $this->mainTextColor = $this->textColor; 246 247 if ( ! $this->mainGroupBackgroundColor ) 248 $this->mainGroupBackgroundColor = $this->mix($this->mainBackgroundColor,$this->mainTextColor,0.95); 249 250 if ( ! $this->themeColor ) 251 $this->themeColor = $this->mainTitleBackgroundColor; 252 253 if ( ! $this->inactiveBackgroundColor ) 254 $this->inactiveBackgroundColor = $this->backgroundColor; 255 256 257 if ( ! $this->navTextColor ) 258 $this->navTextColor = $this->mainTextColor; 259 260 if ( ! $this->navBackgroundColor ) 261 $this->navBackgroundColor = $this->mainBackgroundColor; 262 263 if ( ! $this->navGroupBackgroundColor ) 264 $this->navGroupBackgroundColor = $this->mix($this->navBackgroundColor,$this->navTextColor,0.95); 265 266 if ( ! $this->navTitleTextColor ) 267 $this->navTitleTextColor= $this->navTextColor; 268 269 if ( ! $this->navTitleBackgroundColor ) 270 $this->navTitleBackgroundColor = $this->navBackgroundColor; 271 272 273 if ( ! $this->dialogTitleTextColor ) 274 $this->dialogTitleTextColor = $this->mainTitleTextColor; 275 276 if ( ! $this->dialogTitleBackgroundColor ) 277 $this->dialogTitleBackgroundColor = $this->mainTitleBackgroundColor; 278 279 if ( ! $this->dialogTextColor ) 280 $this->dialogTextColor = $this->mainTextColor; 281 282 if ( ! $this->dialogBackgroundColor ) 283 $this->dialogBackgroundColor = $this->mainBackgroundColor; 284 285 if ( ! $this->dialogGroupBackgroundColor ) 286 $this->dialogGroupBackgroundColor = $this->mix($this->dialogBackgroundColor,$this->dialogTextColor,0.95); 287 288 if ( ! $this->arrowColor ) 289 $this->arrowColor = $this->themeColor; 290 291 if ( ! $this->imageColor ) 292 $this->imageColor = $this->mainTitleTextColor; 293 } 294 295 296 /** 297 * Get all colors from the theme in HEX format. 298 * @return array 299 */ 300 public function getProperties() { 301 302 return array_map( function ($rgb) { 303 if ( is_array($rgb)) 304 return $this->rgb2hex($rgb); 305 else 306 return $rgb; 307 },get_object_vars($this) 308 ); 309 } 310 311 /** 312 * Theme color. 313 * 314 * This color is mainly used for colorizing status bars in a web browser. 315 * 316 * @return string 317 */ 318 public function getThemeColor() 319 { 320 return $this->rgb2hex($this->themeColor); 321 } 322 323 324 /** 325 * mix 326 * 327 * @param mixed $color_1 328 * @param mixed $color_2 329 * @param mixed $weight 330 * 331 * @return array 332 */ 333 protected function mix($color_1 = array(0, 0, 0), $color_2 = array(0, 0, 0), $weight = 0.5) 334 { 335 $f = function ($x) use ($weight) { 336 return $weight * $x; 337 }; 338 339 $g = function ($x) use ($weight) { 340 return (1 - $weight) * $x; 341 }; 342 343 $h = function ($x, $y) { 344 return round($x + $y); 345 }; 346 347 return array_map($h, array_map($f, $color_1), array_map($g, $color_2)); 348 } 349 /** 350 * tint 351 * 352 * @param mixed $color 353 * @param mixed $weight 354 * 355 * @return void 356 */ 357 protected function tint($color, $weight = 0.5) 358 { 359 $t = $color; 360 361 if (is_string($color)) { 362 $t = hex2rgb($color); 363 } 364 365 $u = $this->mix($t, array(255, 255, 255), $weight); 366 367 if (is_string($color)) { 368 return rgb2hex($u); 369 } 370 371 return $u; 372 } 373 374 /** 375 * tone 376 * 377 * @param mixed $color 378 * @param mixed $weight 379 * 380 * @return void 381 */ 382 protected function tone($color, $weight = 0.5) 383 { 384 $t = $color; 385 386 if (is_string($color)) { 387 $t = hex2rgb($color); 388 } 389 390 $u = $this->mix($t, array(128, 128, 128), $weight); 391 392 if (is_string($color)) { 393 return rgb2hex($u); 394 } 395 396 return $u; 397 } 398 399 /** 400 * shade 401 * 402 * @param mixed $color 403 * @param mixed $weight 404 * 405 * @return void 406 */ 407 protected function shade($color, $weight = 0.5) 408 { 409 $t = $color; 410 411 if (is_string($color)) { 412 $t = hex2rgb($color); 413 } 414 415 $u = $this->mix($t, array(0, 0, 0), $weight); 416 417 if (is_string($color)) { 418 return rgb2hex($u); 419 } 420 421 return $u; 422 } 423 424 /** 425 * hex2rgb 426 * 427 * @param mixed $hex 428 * 429 * @return array|float[]|int[]|void 430 */ 431 protected function hex2rgb($hex) 432 { 433 $hex = str_replace('#', '', $hex); 434 435 if ( strlen($hex) != 3 && strlen($hex) != 6 ) 436 throw new \InvalidArgumentException("Hex color '".$hex."' is not valid."); 437 438 $hexToDecimal = function ($x) { 439 if (strlen($x)==1) 440 $x = $x.$x; // the short hex notation: "F" becomes "FF". 441 return hexdec($x); 442 }; 443 444 return array_map($hexToDecimal, str_split($hex, strlen($hex)/3)); 445 } 446 447 /** 448 * rgb2hex 449 * 450 * @param mixed $rgb 451 * 452 * @return string 453 */ 454 protected function rgb2hex($rgb = array(0, 0, 0)) 455 { 456 $f = function ($x) { 457 return str_pad(dechex($x), 2, "0", STR_PAD_LEFT); 458 }; 459 460 return "#" . implode("", array_map($f, $rgb)); 461 } 462 463 464 /** 465 * Translates a color name into its hexadecimal code. 466 * 467 * If the name is not found, then the name will be returned. 468 * 469 * @param $colorName 470 * @return string 471 */ 472 protected static function getColorHexCodeForName($colorName ) { 473 474 $colorName = strtolower($colorName); 475 476 return isset(self::COLORS[$colorName])?self::COLORS[$colorName]:$colorName; 477 } 478 }
Download modules/cms/ui/themes/ThemeStyle.class.php
History Thu, 26 Dec 2024 19:53:54 +0100 Jan Dankert The ThemeStyle is now able to mix colors and all colors are now internally hold as RGB; New Group background colors in the UI. Mon, 22 Feb 2021 23:51:21 +0100 Jan Dankert Better look of styles. Sat, 13 Feb 2021 00:11:23 +0100 Jan Dankert New: Transition-Duration is controllable via style configuration. So there is no need for a dedicated FX on/off-switch in the profile. Fri, 12 Feb 2021 00:43:08 +0100 Jan Dankert New: Style colors; Fix: Mobile navigation, global search. Wed, 10 Feb 2021 22:04:26 +0100 Jan Dankert Provide the theme configuration through a class.