diff --git a/libs/pyglet/shapes.py b/libs/pyglet/shapes.py index 8ae19c3..1ee329d 100644 --- a/libs/pyglet/shapes.py +++ b/libs/pyglet/shapes.py @@ -419,13 +419,13 @@ class ShapeBase(ABC): return if batch is not None and self._batch is not None: - self._batch.migrate(self._vertex_list, self._draw_mode, - self._group, batch) + self._batch.migrate(self._vertex_list, self._draw_mode, self._group, batch) self._batch = batch else: self._vertex_list.delete() self._batch = batch self._create_vertex_list() + self._update_vertices() class Arc(ShapeBase): @@ -1703,7 +1703,6 @@ class Polygon(ShapeBase): self._create_vertex_list() self._update_vertices() - self._update_color() def _create_vertex_list(self): self._vertex_list = self._group.program.vertex_list( diff --git a/libs/pyglet/text/caret.py b/libs/pyglet/text/caret.py index cd90851..eaa4781 100644 --- a/libs/pyglet/text/caret.py +++ b/libs/pyglet/text/caret.py @@ -67,7 +67,7 @@ class Caret: _mark = None - def __init__(self, layout, batch=None, color=(0, 0, 0)): + def __init__(self, layout, batch=None, color=(0, 0, 0, 255)): """Create a caret for a layout. By default the layout's batch is used, so the caret does not need to @@ -78,15 +78,23 @@ class Caret: Layout to control. `batch` : `~pyglet.graphics.Batch` Graphics batch to add vertices to. - `color` : (int, int, int) - RGB tuple with components in range [0, 255]. + `color` : (int, int, int, int) + An RGBA or RGB tuple with components in the range [0, 255]. + RGB colors will be treated as having an opacity of 255. """ from pyglet import gl self._layout = layout batch = batch or layout.batch group = layout.foreground_decoration_group - colors = (*color, 255, *color, 255) + + # Handle both 3 and 4 byte colors + r, g, b, *a = color + + # The alpha value when not in a hidden blink state + self._visible_alpha = a[0] if a else 255 + + colors = r, g, b, self._visible_alpha, r, g, b, self._visible_alpha self._list = group.program.vertex_list(2, gl.GL_LINES, batch, group, colors=('Bn', colors)) self._ideal_x = None @@ -108,10 +116,13 @@ class Caret: def _blink(self, dt): if self.PERIOD: self._blink_visible = not self._blink_visible + if self._visible and self._active and self._blink_visible: - alpha = 255 + alpha = self._visible_alpha else: alpha = 0 + + # Only set the alpha rather than entire colors self._list.colors[3] = alpha self._list.colors[7] = alpha @@ -140,19 +151,33 @@ class Caret: @property def color(self): - """Caret color. + """An RGBA tuple of the current caret color - The default caret color is ``[0, 0, 0]`` (black). Each RGB color - component is in the range 0 to 255. + When blinking off, the alpha channel will be set to ``0``. The + default caret color when visible is ``(0, 0, 0, 255)`` (opaque black). - :type: (int, int, int) + You may set the color to an RGBA or RGB color tuple. + + .. warning:: This setter can fail for a short time after layout / window init! + + Use ``__init__``'s ``color`` keyword argument instead if you + run into this problem. + + Each color channel must be between 0 and 255, inclusive. If the color + set to an RGB color, the previous alpha channel value will be used. + + :type: (int, int, int, int) """ - return self._list.colors[:3] + return self._list.colors[:4] @color.setter def color(self, color): - self._list.colors[:3] = color - self._list.colors[4:7] = color + r, g, b, *_a = color + + # Preserve alpha when setting an RGB color + a = _a[0] if _a else self._list.colors[3] + + self._list.colors[:] = r, g, b, a, r, g, b, a @property def position(self):