2
2
3
3
from pathlib import Path
4
4
from types import SimpleNamespace
5
- from typing import Dict , Tuple
5
+ from typing import Tuple
6
6
7
7
import ipyvuetify as v
8
8
from IPython .display import HTML , Javascript , display
9
- from traitlets import Bool , HasTraits , observe
9
+ from ipyvuetify ._version import semver
10
+ from ipywidgets import Widget
11
+ from traitlets import Bool , HasTraits , Unicode , link
10
12
11
13
import sepal_ui .scripts .utils as su
12
14
from sepal_ui .conf import config
31
33
# define all the colors that we want to use in the theme
32
34
#
33
35
34
- DARK_THEME : Dict [str , str ] = {
35
- "primary" : "#b3842e" ,
36
- "accent" : "#a1458e" ,
37
- "secondary" : "#324a88" ,
38
- "success" : "#3f802a" ,
39
- "info" : "#79b1c9" ,
40
- "warning" : "#b8721d" ,
41
- "error" : "#a63228" ,
42
- "main" : "#24221f" , # Are not traits
43
- "darker" : "#1a1a1a" , # Are not traits
44
- "bg" : "#121212" , # Are not traits
45
- "menu" : "#424242" , # Are not traits
46
- }
47
- "colors used for the dark theme"
48
-
49
- LIGHT_THEME : Dict [str , str ] = {
50
- "primary" : v .theme .themes .light .primary ,
51
- "accent" : v .theme .themes .light .accent ,
52
- "secondary" : v .theme .themes .light .secondary ,
53
- "success" : v .theme .themes .light .success ,
54
- "info" : v .theme .themes .light .info ,
55
- "warning" : v .theme .themes .light .warning ,
56
- "error" : v .theme .themes .light .error ,
57
- "main" : "#2e7d32" ,
58
- "darker" : "#005005" ,
59
- "bg" : "#FFFFFF" ,
60
- "menu" : "#FFFFFF" ,
61
- }
62
- "colors used for the light theme"
63
36
64
37
TYPES : Tuple [str , ...] = (
65
38
"info" ,
66
39
"primary" ,
40
+ "primary_contarst" ,
67
41
"secondary" ,
42
+ "secondary_contrast" ,
68
43
"accent" ,
69
44
"error" ,
70
45
"success" ,
71
46
"warning" ,
72
47
"anchor" ,
48
+ "main" ,
49
+ "darker" ,
50
+ "bg" ,
51
+ "menu" ,
73
52
)
74
53
"The different types defined by ipyvuetify"
75
54
55
+
56
+ class ThemeColors (Widget ):
57
+
58
+ _model_name = Unicode ("ThemeColorsModel" ).tag (sync = True )
59
+
60
+ _model_module = Unicode ("jupyter-vuetify" ).tag (sync = True )
61
+
62
+ _view_module_version = Unicode (semver ).tag (sync = True )
63
+
64
+ _model_module_version = Unicode (semver ).tag (sync = True )
65
+
66
+ _theme_name = Unicode ().tag (sync = True )
67
+
68
+ primary = Unicode ().tag (sync = True )
69
+ primary_contrast = Unicode ().tag (sync = True )
70
+ secondary = Unicode ().tag (sync = True )
71
+ secondary_contrast = Unicode ().tag (sync = True )
72
+ accent = Unicode ().tag (sync = True )
73
+ error = Unicode ().tag (sync = True )
74
+ info = Unicode ().tag (sync = True )
75
+ success = Unicode ().tag (sync = True )
76
+ warning = Unicode ().tag (sync = True )
77
+ anchor = Unicode (None , allow_none = True ).tag (sync = True )
78
+ main = Unicode ().tag (sync = True )
79
+ bg = Unicode ().tag (sync = True )
80
+ menu = Unicode ().tag (sync = True )
81
+ darker = Unicode ().tag (sync = True )
82
+
83
+
84
+ dark_theme_colors = ThemeColors (
85
+ _theme_name = "dark" ,
86
+ primary = "#76591e" ,
87
+ primary_contrast = "#bf8f2d" , # a bit lighter than the primary color
88
+ secondary = "#363e4f" ,
89
+ secondary_contrast = "#5d76ab" ,
90
+ error = "#a63228" ,
91
+ info = "#c5c6c9" ,
92
+ success = "#3f802a" ,
93
+ warning = "#b8721d" ,
94
+ accent = "#272727" ,
95
+ anchor = "#f3f3f3" ,
96
+ main = "#24221f" ,
97
+ darker = "#1a1a1a" ,
98
+ bg = "#121212" ,
99
+ menu = "#424242" ,
100
+ )
101
+
102
+ light_theme_colors = ThemeColors (
103
+ _theme_name = "light" ,
104
+ primary = "#5BB624" ,
105
+ primary_contrast = "#76b353" ,
106
+ accent = "#f3f3f3" ,
107
+ anchor = "#f3f3f3" ,
108
+ secondary = "#2199C4" ,
109
+ secondary_contrast = "#5d76ab" ,
110
+ success = v .theme .themes .light .success ,
111
+ info = v .theme .themes .light .info ,
112
+ warning = v .theme .themes .light .warning ,
113
+ error = v .theme .themes .light .error ,
114
+ main = "#2196f3" , # used by appbar and versioncard
115
+ darker = "#ffffff" , # used for the navdrawer
116
+ bg = "#FFFFFF" ,
117
+ menu = "#FFFFFF" ,
118
+ )
119
+
120
+ DARK_THEME = {k : v for k , v in dark_theme_colors .__dict__ ["_trait_values" ].items () if k in TYPES }
121
+ "colors used for the dark theme"
122
+
123
+ LIGHT_THEME = {k : v for k , v in light_theme_colors .__dict__ ["_trait_values" ].items () if k in TYPES }
124
+ "colors used for the light theme"
125
+
126
+
127
+ # override the default theme with the custom ones
128
+ v .theme .themes .light = light_theme_colors
129
+ v .theme .themes .dark = dark_theme_colors
130
+
76
131
################################################################################
77
132
# define classes and method to make the application responsive
78
133
#
@@ -92,47 +147,29 @@ class SepalColor(HasTraits, SimpleNamespace):
92
147
_dark_theme : Bool = Bool (True if get_theme () == "dark" else False ).tag (sync = True )
93
148
"Whether to use dark theme or not. By changing this value, the theme value will be stored in the conf file. Is only intended to be accessed in development mode."
94
149
95
- new_colors : dict = {}
96
- "Dictionary with name:color structure."
97
-
98
- @observe ("_dark_theme" )
99
- def __init__ (self , * _ , ** new_colors ) -> None :
100
- """Custom simple name space to store and access to the sepal_ui colors and with a magic method to display theme.
150
+ def __init__ (self ) -> None :
151
+ """Custom simple name space to store and access to the sepal_ui colors and with a magic method to display theme."""
152
+ link ((self , "_dark_theme" ), (v .theme , "dark" ))
153
+ v .theme .observe (lambda * x : self .set_colors (), "dark" )
101
154
102
- Args:
103
- **new_colors (optional): the new colors to set in hexadecimal as a dict (experimental)
104
- """
105
- # set vuetify theme
106
- v .theme .dark = self ._dark_theme
155
+ self .set_colors ()
107
156
157
+ def set_colors (self ) -> None :
158
+ """Set the current hexadecimal color in the object."""
108
159
# Get get current theme name
109
160
self .theme_name = "dark" if self ._dark_theme else "light"
110
161
111
162
# Save "new" theme in configuration file
112
163
su .set_config ("theme" , self .theme_name )
113
164
114
- self .kwargs = DARK_THEME if self ._dark_theme else LIGHT_THEME
115
- self .kwargs = new_colors or self .kwargs
116
-
117
- # Even if the theme.themes.dark_theme trait could trigger the change on all elms
118
- # we have to replace the default values every time:
119
- theme = getattr (v .theme .themes , self .theme_name )
120
-
121
- # TODO: Would be awesome to find a way to create traits for the new colors and
122
- # assign them here directly
123
- [setattr (theme , color_name , color ) for color_name , color in self .kwargs .items ()]
124
-
125
- # Now instantiate the namespace
126
- SimpleNamespace .__init__ (self , ** self .kwargs )
127
- HasTraits .__init__ (self )
128
-
129
- return
165
+ self .colors_dict = DARK_THEME if self ._dark_theme else LIGHT_THEME
166
+ SimpleNamespace .__init__ (self , ** self .colors_dict )
130
167
131
168
def _repr_html_ (self , * _ ) -> str :
132
169
"""Rich display of the color palette in an HTML frontend."""
133
170
s = 60
134
171
html = f"<h3>Current theme: { self .theme_name } </h3><table>"
135
- items = {k : v for k , v in self .kwargs .items ()}.items ()
172
+ items = {k : v for k , v in self .colors_dict .items ()}.items ()
136
173
137
174
for name , color in items :
138
175
c = su .to_colors (color )
0 commit comments