1#-----------------------------------------------------------------------------
2# Copyright (c) 2012 - 2021, Anaconda, Inc., and Bokeh Contributors.
3# All rights reserved.
4#
5# The full license is in the file LICENSE.txt, distributed with this software.
6#-----------------------------------------------------------------------------
7''' Mix-in classes that bulk add groups of properties to Bokeh models.
8
9Some groups of properties often show up in Bokeh models together. For
10instance, any model that exposes a fill color property for use when
11rendering will almost always want to expose a fill alpha as well. To
12reduce boilerplate code and simplify defining models with these sets
13of properties, use the mix-in classes in this module:
14
15* |FillProps| --- properties for fill color and alpha
16
17* |HatchProps| --- properties for hatching pattern, color, alpha, etc.
18
19* |LineProps| --- properties for line color, dashing, width, etc.
20
21* |TextProps| --- properties for text color, font, etc.
22
23To include these properties in a Bokeh model, use the |Include| property
24as shown here:
25
26.. code-block:: python
27
28    class SomeGlyph(Glyph):
29
30        fill_props = Include(FillProps, use_prefix=False, help="""
31        The %s values for the annular wedges.
32        """)
33
34This adds all the fill properties ``fill_color`` and ``fill_alpha`` to this
35model with one simple statement. Note that the help string contains a
36placeholder format `%s`. When docs for this class are rendered by the
37:ref:`bokeh.sphinxext.bokeh_model` Sphinx extension, the placeholder will
38be replaced with more information specific to each property. The setting
39``use_prefix`` means that the names of the properties added to ``SomeGlyph``
40are exactly ``fill_alpha`` and ``fill_color``. Some situations require a
41different usage, for more information see the docs for |Include|.
42
43.. |Include| replace:: :class:`~bokeh.core.properties.Include`
44
45.. |FillProps| replace:: :class:`~bokeh.core.property_mixins.FillProps`
46.. |HatchProps| replace:: :class:`~bokeh.core.property_mixins.HatchProps`
47.. |LineProps| replace:: :class:`~bokeh.core.property_mixins.LineProps`
48.. |TextProps| replace:: :class:`~bokeh.core.property_mixins.TextProps`
49
50.. |miter_join| image:: /_images/miter_join.png
51    :height: 15
52.. |round_join| image:: /_images/round_join.png
53    :height: 15
54.. |bevel_join| image:: /_images/bevel_join.png
55    :height: 15
56
57.. |butt_cap| image:: /_images/butt_cap.png
58    :height: 12
59.. |round_cap| image:: /_images/round_cap.png
60    :height: 12
61.. |square_cap| image:: /_images/square_cap.png
62    :height: 12
63
64'''
65#-----------------------------------------------------------------------------
66# Boilerplate
67#-----------------------------------------------------------------------------
68import logging # isort:skip
69log = logging.getLogger(__name__)
70
71#-----------------------------------------------------------------------------
72# Imports
73#-----------------------------------------------------------------------------
74
75# Bokeh imports
76from .enums import (
77    FontStyle,
78    HatchPattern,
79    HatchPatternAbbreviation,
80    LineCap,
81    LineJoin,
82    TextAlign,
83    TextBaseline,
84)
85from .has_props import HasProps
86from .properties import (
87    Alpha,
88    AlphaSpec,
89    Color,
90    ColorSpec,
91    DashPattern,
92    DashPatternSpec,
93    Dict,
94    Enum,
95    Float,
96    FontSize,
97    FontSizeSpec,
98    FontStyleSpec,
99    HatchPatternSpec,
100    IntSpec,
101    LineCapSpec,
102    LineJoinSpec,
103    Instance,
104    Int,
105    Nullable,
106    NumberSpec,
107    Size,
108    String,
109    StringSpec,
110    TextAlignSpec,
111    TextBaselineSpec,
112    value,
113)
114
115#-----------------------------------------------------------------------------
116# Globals and constants
117#-----------------------------------------------------------------------------
118
119__all__ = (
120    'FillProps',
121    'HatchProps',
122    'LineProps',
123    'TextProps',
124    'ScalarFillProps',
125    'ScalarHatchProps',
126    'ScalarLineProps',
127    'ScalarTextProps',
128)
129
130#-----------------------------------------------------------------------------
131# Private API
132#-----------------------------------------------------------------------------
133
134_color_help = """
135A color to use to %s with.
136"""
137
138_alpha_help = """
139An alpha value to use to %s with.
140"""
141
142_line_width_help = """
143Stroke width in units of pixels.
144"""
145
146_line_join_help = """
147How path segments should be joined together.
148
149Acceptable values are:
150
151- ``'miter'`` |miter_join|
152- ``'round'`` |round_join|
153- ``'bevel'`` |bevel_join|
154
155"""
156
157_line_cap_help = """
158How path segments should be terminated.
159
160Acceptable values are:
161
162- ``'butt'`` |butt_cap|
163- ``'round'`` |round_cap|
164- ``'square'`` |square_cap|
165
166"""
167
168_text_font_help = """
169Name of a font to use for rendering text, e.g., ``'times'``, ``'helvetica'``.
170
171"""
172
173_text_font_style_help = """
174A style to use for rendering text.
175
176Acceptable values are:
177
178- ``'normal'`` normal text
179- ``'italic'`` *italic text*
180- ``'bold'`` **bold text**
181- ``"bold italic"`` ***bold italic text***
182
183"""
184
185_text_align_help = """
186Horizontal anchor point to use when rendering text.
187
188Acceptable values are:
189
190- ``'left'``
191- ``'right'``
192- ``'center'``
193
194"""
195
196_text_baseline_help = """
197Vertical anchor point to use when rendering text.
198
199Acceptable values are:
200
201- ``'top'``
202- ``'middle'``
203- ``'bottom'``
204- ``'alphabetic'``
205- ``'hanging'``
206- ``'ideographic'``
207
208"""
209
210_text_line_height_help = """
211In multi-line text, how much additional space should be allocated for
212each line. The value is provided as a number, but should be treated as
213a percentage of font size. The default is 120%. Setting it to 1.0, so
214100%, means no additional space will be used.
215"""
216
217_hatch_scale_help = """
218A rough measure of the 'size' of the hatching pattern. Generally speaking, the
219higher the number, the more spread out the pattern will be.
220"""
221
222_hatch_pattern_help = """
223Built-in patterns are can either be specified as long names:
224
225%s
226
227or as one-letter abbreviations:
228
229%s
230""" % (", ". join(HatchPattern), ", ". join(repr(x) for x in HatchPatternAbbreviation))
231
232_hatch_weight_help = """
233A width value for line-strokes used in hatching.
234"""
235
236#----------------------------------------------------------------------------
237# General API
238#----------------------------------------------------------------------------
239
240class FillProps(HasProps):
241    ''' Properties relevant to rendering fill regions.
242
243    Mirrors the BokehJS ``properties.FillVector`` class.
244
245    '''
246
247    fill_color = ColorSpec(default="gray", help=_color_help % "fill paths")
248    fill_alpha = AlphaSpec(help=_alpha_help % "fill paths")
249
250class ScalarFillProps(HasProps):
251    ''' Properties relevant to rendering fill regions.
252
253    Mirrors the BokehJS ``properties.Fill`` class.
254
255    '''
256
257    fill_color = Nullable(Color, default="gray", help=_color_help  % "fill paths")
258    fill_alpha = Alpha(help=_alpha_help)
259
260class HatchProps(HasProps):
261    ''' Properties relevant to rendering fill regions.
262
263    Mirrors the BokehJS ``properties.HatchVector`` class.
264
265    '''
266
267    hatch_color = ColorSpec(default="black", help=_color_help % "hatching")
268    hatch_alpha = AlphaSpec(help=_alpha_help % "hatching")
269    hatch_scale = NumberSpec(default=12.0, accept_datetime=False, accept_timedelta=False, help=_hatch_scale_help)
270    hatch_pattern = HatchPatternSpec(default=None, help=_hatch_pattern_help)
271    hatch_weight = NumberSpec(default=1.0, accept_datetime=False, accept_timedelta=False, help=_hatch_weight_help)
272    hatch_extra = Dict(String, Instance("bokeh.models.textures.Texture"))
273
274class ScalarHatchProps(HasProps):
275    ''' Properties relevant to rendering fill regions.
276
277    Mirrors the BokehJS ``properties.Hatch`` class.
278
279    '''
280
281    hatch_color = Nullable(Color, default="black", help=_color_help % "hatching")
282    hatch_alpha = Alpha(help=_alpha_help % "hatching")
283    hatch_scale = Size(default=12.0, help=_hatch_scale_help)
284    hatch_pattern = Nullable(String, help=_hatch_pattern_help)  # String to accommodate user custom values
285    hatch_weight = Size(default=1.0, help=_hatch_weight_help)
286    hatch_extra = Dict(String, Instance("bokeh.models.textures.Texture"))
287
288class LineProps(HasProps):
289    ''' Properties relevant to rendering path operations.
290
291    Mirrors the BokehJS ``properties.LineVector`` class.
292
293    '''
294
295    line_color = ColorSpec(default="black", help=_color_help % "stroke paths")
296    line_alpha = AlphaSpec(help=_alpha_help % "stroke paths")
297    line_width = NumberSpec(default=1, accept_datetime=False, accept_timedelta=False, help=_line_width_help)
298    line_join = LineJoinSpec(default="bevel", help=_line_join_help)
299    line_cap = LineCapSpec(default="butt", help=_line_cap_help)
300    line_dash = DashPatternSpec(default=[], help="""How should the line be dashed.""")
301    line_dash_offset = IntSpec(default=0, help="""The distance into the ``line_dash`` (in pixels) that the pattern should start from.""")
302
303
304class ScalarLineProps(HasProps):
305    ''' Properties relevant to rendering path operations.
306
307    Mirrors the BokehJS ``properties.Line`` class.
308
309    '''
310
311    line_color = Nullable(Color, default="black", help=_color_help % "stroke paths")
312    line_alpha = Alpha(help=_alpha_help % "stroke paths")
313    line_width = Float(default=1, help=_line_width_help)
314    line_join = Enum(LineJoin, default="bevel", help=_line_join_help)
315    line_cap = Enum(LineCap, default="butt", help=_line_cap_help)
316    line_dash = DashPattern(default=[], help="""How should the line be dashed.""")
317    line_dash_offset = Int(default=0, help="""The distance into the ``line_dash`` (in pixels) that the pattern should start from.""")
318
319
320class TextProps(HasProps):
321    ''' Properties relevant to rendering text.
322
323    Mirrors the BokehJS ``properties.TextVector`` class.
324
325    .. note::
326        There is currently only support for filling text. An interface
327        to stroke the outlines of text has not yet been exposed.
328
329    '''
330
331    text_color = ColorSpec(default="#444444", help=_color_help % "fill text")
332    text_alpha = AlphaSpec(help=_alpha_help % "fill text")
333    text_font = StringSpec(default=value("helvetica"), help=_text_font_help)
334    text_font_size = FontSizeSpec(default=value("16px"))
335    text_font_style = FontStyleSpec(default="normal", help=_text_font_style_help)
336    text_align = TextAlignSpec(default="left", help=_text_align_help)
337    text_baseline = TextBaselineSpec(default="bottom", help=_text_baseline_help)
338    text_line_height = NumberSpec(default=1.2, help=_text_line_height_help)
339
340class ScalarTextProps(HasProps):
341    ''' Properties relevant to rendering text.
342
343    Mirrors the BokehJS ``properties.Text`` class.
344
345    .. note::
346        There is currently only support for filling text. An interface
347        to stroke the outlines of text has not yet been exposed.
348
349    '''
350
351    text_color = Nullable(Color, default="#444444", help=_color_help % "fill text")
352    text_alpha = Alpha(help=_alpha_help % "fill text")
353    text_font = String(default="helvetica", help=_text_font_help)
354    text_font_size = FontSize("16px") # XXX not great XXX why?
355    text_font_style = Enum(FontStyle, default="normal", help=_text_font_style_help)
356    text_align = Enum(TextAlign, default="left", help=_text_align_help)
357    text_baseline = Enum(TextBaseline, default="bottom", help=_text_baseline_help)
358    text_line_height = Float(default=1.2, help=_text_line_height_help)
359
360#-----------------------------------------------------------------------------
361# Dev API
362#-----------------------------------------------------------------------------
363
364#-----------------------------------------------------------------------------
365# Code
366#-----------------------------------------------------------------------------
367