1 /* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_CHECKABLE_CHECKABLE_THEME_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_CHECKABLE_CHECKABLE_THEME_H 18 19 #include "base/utils/system_properties.h" 20 #include "core/common/container.h" 21 #include "core/components/theme/theme.h" 22 #include "core/components/theme/theme_constants.h" 23 #include "core/components/theme/theme_constants_defines.h" 24 25 namespace OHOS::Ace { 26 27 class CheckableTheme : public virtual Theme { 28 DECLARE_ACE_TYPE(CheckableTheme, Theme); 29 30 public: 31 ~CheckableTheme() override = default; 32 GetPointColor()33 const Color& GetPointColor() const 34 { 35 return pointColor_; 36 } GetActiveColor()37 const Color& GetActiveColor() const 38 { 39 return activeColor_; 40 } GetInactiveColor()41 const Color& GetInactiveColor() const 42 { 43 return inactiveColor_; 44 } GetFocusColor()45 const Color& GetFocusColor() const 46 { 47 return focusColor_; 48 } GetWidth()49 const Dimension& GetWidth() const 50 { 51 return width_; 52 } GetHeight()53 const Dimension& GetHeight() const 54 { 55 return height_; 56 } GetHotZoneHorizontalPadding()57 const Dimension& GetHotZoneHorizontalPadding() const 58 { 59 return hotZoneHorizontalPadding_; 60 } GetHotZoneVerticalPadding()61 const Dimension& GetHotZoneVerticalPadding() const 62 { 63 return hotZoneVerticalPadding_; 64 } GetAspectRatio()65 double GetAspectRatio() const 66 { 67 return aspectRatio_; 68 } GetDefaultWidth()69 const Dimension& GetDefaultWidth() const 70 { 71 return defaultWidth_; 72 } GetDefaultHeight()73 const Dimension& GetDefaultHeight() const 74 { 75 return defaultHeight_; 76 } GetRadioInnerSizeRatio()77 double GetRadioInnerSizeRatio() const 78 { 79 return radioInnerSizeRatio_; 80 } GetNeedFocus()81 bool GetNeedFocus() const 82 { 83 return needFocus_; 84 } IsBackgroundSolid()85 bool IsBackgroundSolid() const 86 { 87 return backgroundSolid_; 88 } GetBorderWidth()89 const Dimension& GetBorderWidth() const 90 { 91 return borderWidth_; 92 } 93 SetHoverColor(const Color & hoverColor)94 void SetHoverColor(const Color& hoverColor) 95 { 96 hoverColor_ = hoverColor; 97 } 98 GetHoverColor()99 const Color& GetHoverColor() const 100 { 101 return hoverColor_; 102 } 103 SetClickEffectColor(const Color & clickEffectColor)104 void SetClickEffectColor(const Color& clickEffectColor) 105 { 106 clickEffectColor_ = clickEffectColor; 107 } 108 GetClickEffectColor()109 const Color& GetClickEffectColor() const 110 { 111 return clickEffectColor_; 112 } 113 GetInactivePointColor()114 const Color& GetInactivePointColor() const 115 { 116 return inactivePointColor_; 117 } 118 GetShadowColor()119 const Color& GetShadowColor() const 120 { 121 return shadowColor_; 122 } 123 GetShadowWidth()124 const Dimension& GetShadowWidth() const 125 { 126 return shadowWidth_; 127 } 128 GetHoverRadius()129 const Dimension& GetHoverRadius() const 130 { 131 return hoverRadius_; 132 } 133 GetDefaultPaddingSize()134 const Dimension& GetDefaultPaddingSize() const 135 { 136 return defaultPaddingSize_; 137 } 138 GetFocusRadius()139 const Dimension& GetFocusRadius() const 140 { 141 return focusRadius_; 142 } 143 GetFocusPaintPadding()144 const Dimension& GetFocusPaintPadding() const 145 { 146 return focusPaintPadding_; 147 } 148 GetHoverDuration()149 double GetHoverDuration() const 150 { 151 return hoverDuration_; 152 } 153 GetHoverToTouchDuration()154 double GetHoverToTouchDuration() const 155 { 156 return hoverToTouchDuration_; 157 } 158 GetTouchDuration()159 double GetTouchDuration() const 160 { 161 return touchDuration_; 162 } GetTickResourceId()163 const InternalResource::ResourceId& GetTickResourceId() const 164 { 165 return tickResourceId_; 166 } GetDotResourceId()167 const InternalResource::ResourceId& GetDotResourceId() const 168 { 169 return dotResourceId_; 170 } 171 172 protected: 173 CheckableTheme() = default; 174 175 Color pointColor_; 176 Color activeColor_; 177 Color inactiveColor_; 178 Color inactivePointColor_; 179 Color focusColor_; 180 Color hoverColor_; 181 Color clickEffectColor_; 182 Color shadowColor_; 183 Dimension width_; 184 Dimension height_; 185 Dimension hotZoneHorizontalPadding_; 186 Dimension hotZoneVerticalPadding_; 187 Dimension defaultWidth_; 188 Dimension defaultHeight_; 189 Dimension borderWidth_; 190 Dimension shadowWidth_; 191 Dimension hoverRadius_; 192 Dimension defaultPaddingSize_; 193 Dimension focusRadius_; 194 Dimension focusPaintPadding_; 195 double hoverDuration_ = 0.0f; 196 double hoverToTouchDuration_ = 0.0f; 197 double touchDuration_ = 0.0f; 198 double aspectRatio_ = 1.0; 199 double radioInnerSizeRatio_ = 0.5; 200 bool needFocus_ = true; 201 bool backgroundSolid_ = true; 202 const float ratio_ = 1.8f; 203 InternalResource::ResourceId tickResourceId_ = InternalResource::ResourceId::RADIO_TICK_SVG; 204 InternalResource::ResourceId dotResourceId_ = InternalResource::ResourceId::RADIO_DOT_SVG; 205 }; 206 207 class CheckboxTheme : public CheckableTheme { 208 DECLARE_ACE_TYPE(CheckboxTheme, CheckableTheme); 209 210 public: 211 class Builder { 212 public: 213 Builder() = default; 214 ~Builder() = default; 215 Build(const RefPtr<ThemeConstants> & themeConstants)216 RefPtr<CheckboxTheme> Build(const RefPtr<ThemeConstants>& themeConstants) const 217 { 218 RefPtr<CheckboxTheme> theme = AceType::Claim(new CheckboxTheme()); 219 if (!themeConstants) { 220 LOGI("Build AppTheme error, themeConstants is null!"); 221 return theme; 222 } 223 ParsePattern(themeConstants, theme); 224 return theme; 225 } 226 227 private: ParsePattern(const RefPtr<ThemeConstants> & themeConstants,const RefPtr<CheckboxTheme> & theme)228 void ParsePattern(const RefPtr<ThemeConstants>& themeConstants, const RefPtr<CheckboxTheme>& theme) const 229 { 230 RefPtr<ThemeStyle> checkboxPattern = themeConstants->GetPatternByName(THEME_PATTERN_CHECKBOX); 231 if (!checkboxPattern) { 232 LOGE("Pattern of checkbox is null, please check!"); 233 return; 234 } 235 theme->width_ = checkboxPattern->GetAttr<Dimension>("checkbox_size", 0.0_vp); 236 theme->height_ = theme->width_; 237 theme->hotZoneHorizontalPadding_ = checkboxPattern->GetAttr<Dimension>("checkbox_hotzone_padding", 0.0_vp); 238 theme->defaultWidth_ = checkboxPattern->GetAttr<Dimension>("checkbox_default_size", 0.0_vp); 239 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 240 theme->defaultPaddingSize_ = 241 checkboxPattern->GetAttr<Dimension>("checkbox_default_padding_size", 2.0_vp); 242 theme->defaultWidth_ = checkboxPattern->GetAttr<Dimension>("checkbox_default_size_twelve", 24.0_vp); 243 } 244 theme->hotZoneVerticalPadding_ = theme->hotZoneHorizontalPadding_; 245 theme->defaultHeight_ = theme->defaultWidth_; 246 theme->needFocus_ = static_cast<bool>(checkboxPattern->GetAttr<double>("checkbox_need_focus", 0.0)); 247 theme->backgroundSolid_ = 248 static_cast<bool>(checkboxPattern->GetAttr<double>("checkbox_inactive_background_solid", 0.0)); 249 theme->borderWidth_ = checkboxPattern->GetAttr<Dimension>("checkbox_border_width", 0.0_vp); 250 theme->checkStroke_ = checkboxPattern->GetAttr<Dimension>("checkbox_stroke_width", 0.0_vp); 251 theme->shadowColor_ = checkboxPattern->GetAttr<Color>("checkbox_shadow_color", Color()); 252 theme->shadowWidth_ = checkboxPattern->GetAttr<Dimension>("checkbox_shadow_width", 0.0_vp); 253 theme->pointColor_ = checkboxPattern->GetAttr<Color>("fg_color_checked", Color::RED); 254 theme->activeColor_ = checkboxPattern->GetAttr<Color>("bg_color_checked", Color::RED); 255 theme->inactiveColor_ = checkboxPattern->GetAttr<Color>("bg_border_color_unchecked", Color::RED); 256 theme->focusColor_ = checkboxPattern->GetAttr<Color>("focus_border_color", Color::RED); 257 theme->borderRadius_ = checkboxPattern->GetAttr<Dimension>("bg_border_radius", 0.0_vp); 258 theme->hoverColor_ = checkboxPattern->GetAttr<Color>("hover_border_color", Color::RED); 259 theme->clickEffectColor_ = checkboxPattern->GetAttr<Color>("click_effect_color", Color::RED); 260 theme->inactivePointColor_ = checkboxPattern->GetAttr<Color>("bg_color_unchecked", Color::RED); 261 theme->hoverRadius_ = checkboxPattern->GetAttr<Dimension>("hover_border_radius", 0.0_vp); 262 theme->focusRadius_ = checkboxPattern->GetAttr<Dimension>("focus_border_radius", 0.0_vp); 263 theme->focusPaintPadding_ = checkboxPattern->GetAttr<Dimension>("focus_paint_padding", 0.0_vp); 264 theme->hoverDuration_ = checkboxPattern->GetAttr<double>("hover_animation_duration", 0.0); 265 theme->hoverToTouchDuration_ = checkboxPattern->GetAttr<double>("hover_to_press_animation_duration", 0.0); 266 theme->touchDuration_ = checkboxPattern->GetAttr<double>("touch_animation_duration", 0.0); 267 theme->colorAnimationDuration_ = checkboxPattern->GetAttr<double>("color_animation_duration", 0.0); 268 269 if (SystemProperties::GetDeviceType() != DeviceType::CAR) { 270 return; 271 } 272 SetCheckboxSize(themeConstants, theme); 273 } 274 SetCheckboxSize(const RefPtr<ThemeConstants> & themeConstants,const RefPtr<CheckboxTheme> & theme)275 void SetCheckboxSize(const RefPtr<ThemeConstants>& themeConstants, const RefPtr<CheckboxTheme>& theme) const 276 { 277 RefPtr<ThemeStyle> checkboxPattern = themeConstants->GetPatternByName(THEME_PATTERN_CHECKBOX); 278 // width/height/borderRadius not exist in theme 279 theme->width_ = checkboxPattern->GetAttr<Dimension>("width", 26.0_vp); 280 theme->height_ = theme->width_; 281 theme->borderRadius_ = checkboxPattern->GetAttr<Dimension>("hover_border_radius", 4.0_vp); 282 theme->hotZoneHorizontalPadding_ = 283 checkboxPattern->GetAttr<Dimension>("hotzone_padding_horizontal", 11.0_vp); 284 theme->hotZoneVerticalPadding_ = theme->hotZoneHorizontalPadding_; 285 } 286 }; 287 GetBorderRadius()288 const Dimension& GetBorderRadius() const 289 { 290 return borderRadius_; 291 } 292 GetCheckStroke()293 const Dimension& GetCheckStroke() const 294 { 295 return checkStroke_; 296 } 297 GetColorAnimationDuration()298 double GetColorAnimationDuration() const 299 { 300 return colorAnimationDuration_; 301 } 302 303 private: 304 Dimension borderRadius_; 305 Dimension checkStroke_; 306 double colorAnimationDuration_ = 0.0; 307 }; 308 309 class SwitchTheme : public CheckableTheme { 310 DECLARE_ACE_TYPE(SwitchTheme, CheckableTheme); 311 312 public: 313 class Builder { 314 public: 315 Builder() = default; 316 ~Builder() = default; 317 Build(const RefPtr<ThemeConstants> & themeConstants)318 RefPtr<SwitchTheme> Build(const RefPtr<ThemeConstants>& themeConstants) const 319 { 320 RefPtr<SwitchTheme> theme = AceType::Claim(new SwitchTheme()); 321 if (!themeConstants) { 322 LOGE("Build AppTheme error, themeConstants is null!"); 323 return theme; 324 } 325 ParsePattern(themeConstants, theme); 326 return theme; 327 } 328 329 private: ParsePattern(const RefPtr<ThemeConstants> & themeConstants,const RefPtr<SwitchTheme> & theme)330 void ParsePattern(const RefPtr<ThemeConstants>& themeConstants, const RefPtr<SwitchTheme>& theme) const 331 { 332 RefPtr<ThemeStyle> switchPattern = themeConstants->GetPatternByName(THEME_PATTERN_SWITCH); 333 if (!switchPattern) { 334 LOGE("Pattern of switch is null, please check!"); 335 return; 336 } 337 theme->width_ = switchPattern->GetAttr<Dimension>("switch_pattern_width", 0.0_vp); 338 theme->height_ = switchPattern->GetAttr<Dimension>("switch_pattern_height", 0.0_vp); 339 theme->hotZoneHorizontalPadding_ = 340 switchPattern->GetAttr<Dimension>("switch_hotzone_horizontal_padding", 0.0_vp); 341 theme->hotZoneVerticalPadding_ = 342 switchPattern->GetAttr<Dimension>("switch_hotzone_vertical_padding", 0.0_vp); 343 theme->aspectRatio_ = switchPattern->GetAttr<double>("switch_aspect_ratio", 0.0); 344 theme->backgroundSolid_ = 345 static_cast<bool>(switchPattern->GetAttr<double>("switch_inactive_background_solid", 0.0)); 346 theme->defaultWidth_ = switchPattern->GetAttr<Dimension>("switch_default_width", 0.0_vp); 347 theme->defaultHeight_ = switchPattern->GetAttr<Dimension>("switch_default_height", 0.0_vp); 348 theme->needFocus_ = static_cast<bool>(switchPattern->GetAttr<double>("switch_need_focus", 0.0)); 349 theme->borderWidth_ = switchPattern->GetAttr<Dimension>("switch_border_width", 0.0_vp); 350 theme->shadowColor_ = switchPattern->GetAttr<Color>("switch_shadow_color", Color()); 351 theme->shadowWidth_ = switchPattern->GetAttr<Dimension>("switch_pattern_shadow_width", 0.0_vp); 352 theme->pointColor_ = switchPattern->GetAttr<Color>("fg_color_checked", Color::RED); 353 theme->activeColor_ = switchPattern->GetAttr<Color>("bg_color_checked", Color::RED); 354 theme->inactiveColor_ = switchPattern->GetAttr<Color>("bg_color_unchecked", Color::RED); 355 theme->focusColor_ = switchPattern->GetAttr<Color>("focus_border_color", Color::RED); 356 theme->hoverColor_ = switchPattern->GetAttr<Color>("hover_border_color", Color::RED); 357 theme->hoverRadius_ = switchPattern->GetAttr<Dimension>("hover_border_radius", 0.0_vp); 358 theme->inactivePointColor_ = switchPattern->GetAttr<Color>("fg_color_unchecked", Color::RED); 359 theme->clickEffectColor_ = switchPattern->GetAttr<Color>("click_effect_color", Color::RED); 360 theme->focusPaintPadding_ = switchPattern->GetAttr<Dimension>("focus_paint_padding", 0.0_vp); 361 theme->hoverDuration_ = switchPattern->GetAttr<double>("hover_animation_duration", 0.0); 362 theme->hoverToTouchDuration_ = switchPattern->GetAttr<double>("hover_to_press_animation_duration", 0.0); 363 theme->touchDuration_ = switchPattern->GetAttr<double>("touch_animation_duration", 0.0); 364 theme->colorAnimationDuration_ = switchPattern->GetAttr<double>("color_animation_duration", 0.0); 365 theme->pointAnimationDuration_ = switchPattern->GetAttr<double>("point_animation_duration", 0.0); 366 theme->interactiveHoverColor_ = switchPattern->GetAttr<Color>("interactive_hover", Color::RED); 367 theme->interactivePressedColor_ = switchPattern->GetAttr<Color>("interactive_pressed", Color::RED); 368 if (SystemProperties::GetDeviceType() != DeviceType::CAR) { 369 return; 370 } 371 theme->width_ = switchPattern->GetAttr<Dimension>(SWITCH_WIDTH, 40.0_vp); 372 theme->height_ = switchPattern->GetAttr<Dimension>(SWITCH_HEIGHT, 26.0_vp); 373 theme->shadowWidth_ = switchPattern->GetAttr<Dimension>(SWITCH_SHADOW_WIDTH, 2.0_vp); 374 theme->hotZoneHorizontalPadding_ = switchPattern->GetAttr<Dimension>(SWITCH_HORIZONTAL_PADDING, 4.0_vp); 375 theme->hotZoneVerticalPadding_ = switchPattern->GetAttr<Dimension>(SWITCH_VERTICAL_PADDING, 13.0_vp); 376 } 377 }; 378 GetRatio()379 float GetRatio() const 380 { 381 return ratio_; 382 } 383 GetColorAnimationDuration()384 double GetColorAnimationDuration() const 385 { 386 return colorAnimationDuration_; 387 } 388 GetPointAnimationDuration()389 double GetPointAnimationDuration() const 390 { 391 return pointAnimationDuration_; 392 } 393 GetInteractiveHoverColor()394 const Color& GetInteractiveHoverColor() const 395 { 396 return interactiveHoverColor_; 397 } 398 GetInteractivePressedColor()399 const Color& GetInteractivePressedColor() const 400 { 401 return interactivePressedColor_; 402 } 403 404 private: 405 double colorAnimationDuration_ = 0.0; 406 double pointAnimationDuration_ = 0.0; 407 Color interactiveHoverColor_; 408 Color interactivePressedColor_; 409 }; 410 411 class RadioTheme : public CheckableTheme { 412 DECLARE_ACE_TYPE(RadioTheme, CheckableTheme); 413 414 public: 415 class Builder { 416 public: 417 Builder() = default; 418 ~Builder() = default; 419 Build(const RefPtr<ThemeConstants> & themeConstants)420 RefPtr<RadioTheme> Build(const RefPtr<ThemeConstants>& themeConstants) const 421 { 422 RefPtr<RadioTheme> theme = AceType::Claim(new RadioTheme()); 423 if (!themeConstants) { 424 return theme; 425 } 426 ParsePattern(themeConstants, theme); 427 return theme; 428 } 429 430 private: ParsePattern(const RefPtr<ThemeConstants> & themeConstants,const RefPtr<RadioTheme> & theme)431 void ParsePattern(const RefPtr<ThemeConstants>& themeConstants, const RefPtr<RadioTheme>& theme) const 432 { 433 RefPtr<ThemeStyle> radioPattern = themeConstants->GetPatternByName(THEME_PATTERN_RADIO); 434 if (!radioPattern) { 435 LOGW("find pattern of radio fail"); 436 return; 437 } 438 theme->width_ = radioPattern->GetAttr<Dimension>("radio_size", 0.0_vp); 439 theme->height_ = theme->width_; 440 theme->hotZoneHorizontalPadding_ = radioPattern->GetAttr<Dimension>("radio_hotzone_padding", 0.0_vp); 441 theme->hotZoneVerticalPadding_ = theme->hotZoneHorizontalPadding_; 442 theme->defaultWidth_ = radioPattern->GetAttr<Dimension>("radio_default_size", 0.0_vp); 443 theme->defaultHeight_ = theme->defaultWidth_; 444 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 445 theme->width_ = radioPattern->GetAttr<Dimension>("radio_size_api_twelve", 24.0_vp); 446 theme->height_ = theme->width_; 447 theme->defaultPaddingSize_ = radioPattern->GetAttr<Dimension>("radio_default_padding_size", 2.0_vp); 448 theme->defaultWidth_ = radioPattern->GetAttr<Dimension>("radio_default_size_api_twelve", 24.0_vp); 449 theme->defaultHeight_ = theme->defaultWidth_; 450 } 451 theme->radioInnerSizeRatio_ = radioPattern->GetAttr<double>("radio_inner_size_ratio", 0.0); 452 theme->needFocus_ = static_cast<bool>(radioPattern->GetAttr<double>("radio_need_focus", 0.0)); 453 theme->backgroundSolid_ = 454 static_cast<bool>(radioPattern->GetAttr<double>("radio_inactive_background_solid", 0.0)); 455 theme->borderWidth_ = radioPattern->GetAttr<Dimension>("radio_border_width", 0.0_vp); 456 theme->shadowColor_ = radioPattern->GetAttr<Color>("radio_shadow_color", Color()); 457 theme->shadowWidth_ = radioPattern->GetAttr<Dimension>("radio_shadow_width", 0.0_vp); 458 theme->pointColor_ = radioPattern->GetAttr<Color>("fg_color_checked", Color::RED); 459 theme->activeColor_ = radioPattern->GetAttr<Color>("bg_color_checked", Color::RED); 460 theme->inactiveColor_ = radioPattern->GetAttr<Color>("bg_color_unchecked", Color::RED); 461 theme->inactivePointColor_ = radioPattern->GetAttr<Color>("fg_color_unchecked", Color::RED); 462 theme->focusColor_ = radioPattern->GetAttr<Color>("bg_focus_outline_color", Color::RED); 463 theme->hoverColor_ = radioPattern->GetAttr<Color>("hover_border_color", Color::RED); 464 theme->clickEffectColor_ = radioPattern->GetAttr<Color>("click_effect_color", Color::RED); 465 theme->focusPaintPadding_ = radioPattern->GetAttr<Dimension>("focus_paint_padding", 0.0_vp); 466 theme->hoverDuration_ = radioPattern->GetAttr<double>("hover_animation_duration", 0.0); 467 theme->hoverToTouchDuration_ = radioPattern->GetAttr<double>("hover_to_press_animation_duration", 0.0); 468 theme->touchDuration_ = radioPattern->GetAttr<double>("touch_animation_duration", 0.0); 469 if (SystemProperties::GetDeviceType() != DeviceType::CAR) { 470 return; 471 } 472 theme->width_ = radioPattern->GetAttr<Dimension>(RADIO_WIDTH, 26.0_vp); 473 theme->height_ = theme->width_; 474 theme->hotZoneHorizontalPadding_ = radioPattern->GetAttr<Dimension>(RADIO_PADDING, 11.0_vp); 475 theme->hotZoneVerticalPadding_ = theme->hotZoneHorizontalPadding_; 476 SetRadioSize(themeConstants, theme); 477 } 478 SetRadioSize(const RefPtr<ThemeConstants> & themeConstants,const RefPtr<RadioTheme> & theme)479 void SetRadioSize(const RefPtr<ThemeConstants>& themeConstants, const RefPtr<RadioTheme>& theme) const 480 { 481 RefPtr<ThemeStyle> radioPattern = themeConstants->GetPatternByName(THEME_PATTERN_RADIO); 482 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) { 483 theme->width_ = radioPattern->GetAttr<Dimension>("radio_size_api_twelve", 24.0_vp); 484 theme->height_ = theme->width_; 485 } 486 } 487 }; 488 }; 489 490 } // namespace OHOS::Ace 491 492 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_CHECKABLE_CHECKABLE_THEME_H 493