update pyglet
This commit is contained in:
parent
cd93500d02
commit
411da185eb
@ -8,7 +8,7 @@ import traceback
|
||||
import threading
|
||||
import multiprocessing
|
||||
|
||||
# TODO 默认位置配置文件+可自定义工作路径
|
||||
# TODO 默认位置配置文件+可自定义工作路径iu
|
||||
|
||||
|
||||
hi = """Difficult Rocket is writen by shenjackyuanjie
|
||||
|
@ -11,7 +11,8 @@ github: @shenjackyuanjie
|
||||
gitee: @shenjackyuanjie
|
||||
"""
|
||||
|
||||
__version__ = '0.6.1'
|
||||
version = '0.6.1'
|
||||
__version__ = version
|
||||
|
||||
playing = False
|
||||
|
||||
|
@ -16,7 +16,7 @@ from ..api import translate
|
||||
from libs import pyglet
|
||||
from libs.pyglet.gui import widgets
|
||||
from libs.pyglet.sprite import Sprite
|
||||
from libs.pyglet.graphics import Batch
|
||||
from libs.pyglet.graphics import Batch, Group
|
||||
from libs.pyglet.image import AbstractImage
|
||||
|
||||
__all__ = ['Parts']
|
||||
@ -38,3 +38,29 @@ class Parts(widgets.WidgetBase):
|
||||
super().__init__(x, y, width, height)
|
||||
self.sprite = Sprite(img=textures, x=x, y=y, batch=batch)
|
||||
self._value = 0
|
||||
|
||||
|
||||
class InputBox(widgets.WidgetBase):
|
||||
"""
|
||||
input box
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
x: int,
|
||||
y: int,
|
||||
width: int,
|
||||
height: int,
|
||||
batch: Batch,
|
||||
group: Group,
|
||||
message: str = ''):
|
||||
super().__init__(x, y, width, height)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self.enabled
|
||||
|
||||
def _update_position(self):
|
||||
pass
|
||||
|
||||
a = InputBox(1, 2, 3, 4, 5, 6, 7)
|
||||
|
||||
|
@ -44,7 +44,7 @@ import sys
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
#: The release version
|
||||
version = '2.0.dev9'
|
||||
version = '2.0.dev11'
|
||||
__version__ = version
|
||||
|
||||
if sys.version_info < (3, 6):
|
||||
|
@ -113,8 +113,8 @@ of the system clock.
|
||||
|
||||
import time
|
||||
|
||||
from operator import attrgetter
|
||||
from heapq import heappush, heappop, heappushpop
|
||||
from operator import attrgetter
|
||||
from collections import deque
|
||||
|
||||
|
||||
@ -271,7 +271,10 @@ class Clock:
|
||||
break
|
||||
|
||||
# execute the callback
|
||||
item.func(now - item.last_ts, *item.args, **item.kwargs)
|
||||
try:
|
||||
item.func(now - item.last_ts, *item.args, **item.kwargs)
|
||||
except ReferenceError:
|
||||
pass # weakly-referenced object no longer exists.
|
||||
|
||||
if item.interval:
|
||||
|
||||
|
@ -219,12 +219,6 @@ class GlyphTextureAtlas(image.Texture):
|
||||
y = 0
|
||||
line_height = 0
|
||||
|
||||
def apply_blend_state(self):
|
||||
"""Set the OpenGL blend state for the glyphs in this texture.
|
||||
"""
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||
glEnable(GL_BLEND)
|
||||
|
||||
def fit(self, image):
|
||||
"""Place `image` within this texture.
|
||||
|
||||
|
@ -232,6 +232,12 @@ class BufferObject(AbstractBuffer):
|
||||
ptr = ctypes.cast(glMapBuffer(self.target, GL_WRITE_ONLY), ctypes.POINTER(ctypes.c_byte * self.size)).contents
|
||||
return ptr
|
||||
|
||||
def map_range(self, start, size, ptr_type):
|
||||
glBindBuffer(self.target, self.id)
|
||||
ptr = ctypes.cast(glMapBufferRange(self.target, start, size, GL_MAP_WRITE_BIT), ptr_type).contents
|
||||
glUnmapBuffer(self.target)
|
||||
return ptr
|
||||
|
||||
def unmap(self):
|
||||
glUnmapBuffer(self.target)
|
||||
|
||||
@ -277,7 +283,7 @@ class MappableBufferObject(BufferObject, AbstractMappable):
|
||||
def __init__(self, size, target, usage):
|
||||
super(MappableBufferObject, self).__init__(size, target, usage)
|
||||
self.data = (ctypes.c_byte * size)()
|
||||
self.data_ptr = ctypes.cast(self.data, ctypes.c_void_p).value
|
||||
self.data_ptr = ctypes.addressof(self.data)
|
||||
self._dirty_min = sys.maxsize
|
||||
self._dirty_max = 0
|
||||
|
||||
@ -320,7 +326,7 @@ class MappableBufferObject(BufferObject, AbstractMappable):
|
||||
data = (ctypes.c_byte * size)()
|
||||
ctypes.memmove(data, self.data, min(size, self.size))
|
||||
self.data = data
|
||||
self.data_ptr = ctypes.cast(self.data, ctypes.c_void_p).value
|
||||
self.data_ptr = ctypes.addressof(self.data)
|
||||
|
||||
self.size = size
|
||||
|
||||
|
@ -52,19 +52,72 @@ def clamp(num, min_val, max_val):
|
||||
|
||||
|
||||
class Vec2(tuple):
|
||||
"""A two dimensional vector represented as an X Y coordinate pair.
|
||||
|
||||
:parameters:
|
||||
`x` : int or float :
|
||||
The X coordinate of the vector.
|
||||
`y` : int or float :
|
||||
The Y coordinate of the vector.
|
||||
|
||||
Vectors must be created with either 0 or 2 values. If no arguments are provided a vector with the coordinates 0, 0 is created.
|
||||
|
||||
Vectors are stored as a tuple and therefore immutable and cannot be modified directly
|
||||
"""
|
||||
|
||||
def __new__(cls, *args):
|
||||
assert len(args) in (0, 2), "0 or 2 values are required for Vec2 types."
|
||||
return super().__new__(Vec2, args or (0, 0))
|
||||
|
||||
@staticmethod
|
||||
def from_polar(mag, angle):
|
||||
"""Create a new vector from the given polar coodinates.
|
||||
|
||||
:parameters:
|
||||
`mag` : int or float :
|
||||
The magnitude of the vector.
|
||||
`angle` : int or float :
|
||||
The angle of the vector in radians.
|
||||
|
||||
:returns: A new vector with the given angle and magnitude.
|
||||
:rtype: Vec2
|
||||
"""
|
||||
return Vec2(mag * _math.cos(angle), mag * _math.sin(angle))
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
"""The X coordinate of the vector.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self[0]
|
||||
|
||||
@property
|
||||
def y(self):
|
||||
"""The Y coordinate of the vector.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self[1]
|
||||
|
||||
@property
|
||||
def heading(self):
|
||||
"""The angle of the vector in radians.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return _math.atan2(self[1], self[0])
|
||||
|
||||
@property
|
||||
def mag(self):
|
||||
"""The magnitude, or length of the vector. The distance between the coordinates and the origin.
|
||||
|
||||
Alias of abs(self).
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self.__abs__()
|
||||
|
||||
def __add__(self, other):
|
||||
return Vec2(self[0] + other[0], self[1] + other[1])
|
||||
|
||||
@ -86,26 +139,143 @@ class Vec2(tuple):
|
||||
def __round__(self, ndigits=None):
|
||||
return Vec2(*(round(v, ndigits) for v in self))
|
||||
|
||||
def __radd__(self, other):
|
||||
"""Reverse add. Required for functionality with sum()
|
||||
"""
|
||||
if other == 0:
|
||||
return self
|
||||
else:
|
||||
return self.__add__(other)
|
||||
|
||||
def from_magnitude(self, magnitude):
|
||||
"""Create a new Vector of the given magnitude by normalizing, then scaling the vector. The heading remains unchanged.
|
||||
|
||||
:parameters:
|
||||
`magnitude` : int or float :
|
||||
The magnitude of the new vector.
|
||||
|
||||
:returns: A new vector with the magnitude.
|
||||
:rtype: Vec2
|
||||
"""
|
||||
return self.normalize().scale(magnitude)
|
||||
|
||||
def from_heading(self, heading):
|
||||
"""Create a new vector of the same magnitude with the given heading. I.e. Rotate the vector to the heading.
|
||||
|
||||
:parameters:
|
||||
`heading` : int or float :
|
||||
The angle of the new vector in radians.
|
||||
|
||||
:returns: A new vector with the given heading.
|
||||
:rtype: Vec2
|
||||
"""
|
||||
mag = self.__abs__()
|
||||
return Vec2(mag * _math.cos(heading), mag * _math.sin(heading))
|
||||
|
||||
def limit(self, max):
|
||||
"""Limit the magnitude of the vector to the value used for the max parameter.
|
||||
|
||||
:parameters:
|
||||
`max` : int or float :
|
||||
The maximum magnitude for the vector.
|
||||
|
||||
:returns: Either self or a new vector with the maximum magnitude.
|
||||
:rtype: Vec2
|
||||
"""
|
||||
if self[0] ** 2 + self[1] ** 2 > max * max:
|
||||
return self.from_magnitude(max)
|
||||
return self
|
||||
|
||||
def lerp(self, other, alpha):
|
||||
"""Create a new vector lineraly interpolated between this vector and another vector.
|
||||
|
||||
:parameters:
|
||||
`other` : Vec2 :
|
||||
The vector to be linerly interpolated to.
|
||||
`alpha` : float or int :
|
||||
The amount of interpolation.
|
||||
Some value between 0.0 (this vector) and 1.0 (other vector).
|
||||
0.5 is halfway inbetween.
|
||||
|
||||
:returns: A new interpolated vector.
|
||||
:rtype: Vec2
|
||||
"""
|
||||
return Vec2(self[0] + (alpha * (other[0] - self[0])),
|
||||
self[1] + (alpha * (other[1] - self[1])))
|
||||
|
||||
def scale(self, value):
|
||||
"""Multiply the vector by a scalar value.
|
||||
|
||||
:parameters:
|
||||
`value` : int or float :
|
||||
The ammount to be scaled by
|
||||
|
||||
:returns: A new vector scaled by the value.
|
||||
:rtype: Vec2
|
||||
"""
|
||||
return Vec2(self[0] * value, self[1] * value)
|
||||
|
||||
def rotate(self, angle):
|
||||
"""Create a new Vector rotated by the angle. The magnitude remains unchanged.
|
||||
|
||||
:parameters:
|
||||
`angle` : int or float :
|
||||
The angle to rotate by
|
||||
|
||||
:returns: A new rotated vector of the same magnitude.
|
||||
:rtype: Vec2
|
||||
"""
|
||||
mag = self.mag
|
||||
heading = self.heading
|
||||
return Vec2(mag * _math.cos(heading + angle), mag * _math.sin(heading+angle))
|
||||
|
||||
def distance(self, other):
|
||||
"""Calculate the distance between this vector and another 2D vector.
|
||||
|
||||
:parameters:
|
||||
`other` : Vec2 :
|
||||
The other vector
|
||||
|
||||
:returns: The distance between the two vectors.
|
||||
:rtype: float
|
||||
"""
|
||||
return _math.sqrt(((other[0] - self[0]) ** 2) + ((other[1] - self[1]) ** 2))
|
||||
|
||||
def normalize(self):
|
||||
"""Normalize the vector to have a magnitude of 1. i.e. make it a unit vector.
|
||||
|
||||
:returns: A unit vector with the same heading.
|
||||
:rtype: Vec2
|
||||
"""
|
||||
d = self.__abs__()
|
||||
if d:
|
||||
return Vec2(self[0] / d, self[1] / d)
|
||||
return self
|
||||
|
||||
def clamp(self, min_val, max_val):
|
||||
"""Restrict the value of the X and Y components of the vector to be within the given values.
|
||||
|
||||
:parameters:
|
||||
`min_val` : int or float :
|
||||
The minimum value
|
||||
`max_val` : int or float :
|
||||
The maximum value
|
||||
|
||||
:returns: A new vector with clamped X and Y components.
|
||||
:rtype: Vec2
|
||||
"""
|
||||
return Vec2(clamp(self[0], min_val, max_val), clamp(self[1], min_val, max_val))
|
||||
|
||||
def dot(self, other):
|
||||
"""Calculate the dot product of this vector and another 2D vector.
|
||||
|
||||
:parameters:
|
||||
`other` : Vec2 :
|
||||
The other vector.
|
||||
|
||||
:returns: The dot product of the two vectors.
|
||||
:rtype: float
|
||||
"""
|
||||
return self[0] * other[0] + self[1] * other[1]
|
||||
|
||||
def __getattr__(self, attrs):
|
||||
@ -121,6 +291,20 @@ class Vec2(tuple):
|
||||
|
||||
|
||||
class Vec3(tuple):
|
||||
"""A three dimensional vector represented as a X Y Z coordinates.
|
||||
|
||||
:parameters:
|
||||
`x` : int or float :
|
||||
The X coordinate of the vector.
|
||||
`y` : int or float :
|
||||
The Y coordinate of the vector.
|
||||
`z` : int or float :
|
||||
The Z coordinate of the vector.
|
||||
|
||||
3D Vectors must be created with either 0 or 3 values. If no arguments are provided a vector with the coordinates 0, 0, 0 is created.
|
||||
|
||||
Vectors are stored as a tuple and therefore immutable and cannot be modified directly
|
||||
"""
|
||||
|
||||
def __new__(cls, *args):
|
||||
assert len(args) in (0, 3), "0 or 3 values are required for Vec3 types."
|
||||
@ -128,15 +312,37 @@ class Vec3(tuple):
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
"""The X coordinate of the vector.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self[0]
|
||||
|
||||
@property
|
||||
def y(self):
|
||||
"""The Y coordinate of the vector.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self[1]
|
||||
|
||||
@property
|
||||
def z(self):
|
||||
"""The Z coordinate of the vector.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self[2]
|
||||
|
||||
@property
|
||||
def mag(self):
|
||||
"""The magnitude, or length of the vector. The distance between the coordinates and the origin.
|
||||
|
||||
Alias of abs(self).
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self.__abs__()
|
||||
|
||||
def __add__(self, other):
|
||||
return Vec3(self[0] + other[0], self[1] + other[1], self[2] + other[2])
|
||||
@ -159,34 +365,133 @@ class Vec3(tuple):
|
||||
def __round__(self, ndigits=None):
|
||||
return Vec3(*(round(v, ndigits) for v in self))
|
||||
|
||||
def __radd__(self, other):
|
||||
"""Reverse add. Required for functionality with sum()
|
||||
"""
|
||||
if other == 0:
|
||||
return self
|
||||
else:
|
||||
return self.__add__(other)
|
||||
|
||||
def from_magnitude(self, magnitude):
|
||||
"""Create a new Vector of the given magnitude by normalizing, then scaling the vector. The rotation remains unchanged.
|
||||
|
||||
:parameters:
|
||||
`magnitude` : int or float :
|
||||
The magnitude of the new vector.
|
||||
|
||||
:returns: A new vector with the magnitude.
|
||||
:rtype: Vec3
|
||||
"""
|
||||
return self.normalize().scale(magnitude)
|
||||
|
||||
def limit(self, max):
|
||||
"""Limit the magnitude of the vector to the value used for the max parameter.
|
||||
|
||||
:parameters:
|
||||
`max` : int or float :
|
||||
The maximum magnitude for the vector.
|
||||
|
||||
:returns: Either self or a new vector with the maximum magnitude.
|
||||
:rtype: Vec3
|
||||
"""
|
||||
if self[0] ** 2 + self[1] ** 2 + self[2] **2 > max * max * max:
|
||||
return self.from_magnitude(max)
|
||||
return self
|
||||
|
||||
def cross(self, other):
|
||||
"""Calculate the cross product of this vector and another 3D vector.
|
||||
|
||||
:parameters:
|
||||
`other` : Vec3 :
|
||||
The other vector.
|
||||
|
||||
:returns: The cross product of the two vectors.
|
||||
:rtype: float
|
||||
"""
|
||||
return Vec3((self[1] * other[2]) - (self[2] * other[1]),
|
||||
(self[2] * other[0]) - (self[0] * other[2]),
|
||||
(self[0] * other[1]) - (self[1] * other[0]))
|
||||
|
||||
def dot(self, other):
|
||||
"""Calculate the dot product of this vector and another 3D vector.
|
||||
|
||||
:parameters:
|
||||
`other` : Vec3 :
|
||||
The other vector.
|
||||
|
||||
:returns: The dot product of the two vectors.
|
||||
:rtype: float
|
||||
"""
|
||||
return self[0] * other[0] + self[1] * other[1] + self[2] * other[2]
|
||||
|
||||
def lerp(self, other, alpha):
|
||||
"""Create a new vector lineraly interpolated between this vector and another vector.
|
||||
|
||||
:parameters:
|
||||
`other` : Vec3 :
|
||||
The vector to be linerly interpolated to.
|
||||
`alpha` : float or int :
|
||||
The amount of interpolation.
|
||||
Some value between 0.0 (this vector) and 1.0 (other vector).
|
||||
0.5 is halfway inbetween.
|
||||
|
||||
:returns: A new interpolated vector.
|
||||
:rtype: Vec3
|
||||
"""
|
||||
return Vec3(self[0] + (alpha * (other[0] - self[0])),
|
||||
self[1] + (alpha * (other[1] - self[1])),
|
||||
self[2] + (alpha * (other[2] - self[2])))
|
||||
|
||||
def scale(self, value):
|
||||
"""Multiply the vector by a scalar value.
|
||||
|
||||
:parameters:
|
||||
`value` : int or float :
|
||||
The ammount to be scaled by
|
||||
|
||||
:returns: A new vector scaled by the value.
|
||||
:rtype: Vec3
|
||||
"""
|
||||
return Vec3(self[0] * value, self[1] * value, self[2] * value)
|
||||
|
||||
def distance(self, other):
|
||||
"""Calculate the distance between this vector and another 3D vector.
|
||||
|
||||
:parameters:
|
||||
`other` : Vec3 :
|
||||
The other vector
|
||||
|
||||
:returns: The distance between the two vectors.
|
||||
:rtype: float
|
||||
"""
|
||||
return _math.sqrt(((other[0] - self[0]) ** 2) +
|
||||
((other[1] - self[1]) ** 2) +
|
||||
((other[2] - self[2]) ** 2))
|
||||
|
||||
def normalize(self):
|
||||
"""Normalize the vector to have a magnitude of 1. i.e. make it a unit vector.
|
||||
|
||||
:returns: A unit vector with the same rotation.
|
||||
:rtype: Vec3
|
||||
"""
|
||||
d = self.__abs__()
|
||||
if d:
|
||||
return Vec3(self[0] / d, self[1] / d, self[2] / d)
|
||||
return self
|
||||
|
||||
def clamp(self, min_val, max_val):
|
||||
"""Restrict the value of the X, Y and Z components of the vector to be within the given values.
|
||||
|
||||
:parameters:
|
||||
`min_val` : int or float :
|
||||
The minimum value
|
||||
`max_val` : int or float :
|
||||
The maximum value
|
||||
|
||||
:returns: A new vector with clamped X, Y and Z components.
|
||||
:rtype: Vec3
|
||||
"""
|
||||
return Vec3(clamp(self[0], min_val, max_val),
|
||||
clamp(self[1], min_val, max_val),
|
||||
clamp(self[2], min_val, max_val))
|
||||
@ -246,6 +551,12 @@ class Vec4(tuple):
|
||||
def __round__(self, ndigits=None):
|
||||
return Vec4(*(round(v, ndigits) for v in self))
|
||||
|
||||
def __radd__(self, other):
|
||||
if other == 0:
|
||||
return self
|
||||
else:
|
||||
return self.__add__(other)
|
||||
|
||||
def lerp(self, other, alpha):
|
||||
return Vec4(self[0] + (alpha * (other[0] - self[0])),
|
||||
self[1] + (alpha * (other[1] - self[1])),
|
||||
|
@ -312,7 +312,7 @@ class _ShapeBase:
|
||||
|
||||
@color.setter
|
||||
def color(self, values):
|
||||
self._rgb = list(map(int, values))
|
||||
self._rgb = tuple(map(int, values))
|
||||
self._update_color()
|
||||
|
||||
@property
|
||||
@ -663,7 +663,7 @@ class Ellipse(_ShapeBase):
|
||||
class Sector(_ShapeBase):
|
||||
def __init__(self, x, y, radius, segments=None, angle=math.tau, start_angle=0,
|
||||
color=(255, 255, 255), batch=None, group=None):
|
||||
"""Create a sector of a circle.
|
||||
"""Create a Sector of a circle.
|
||||
|
||||
The sector's anchor point (x, y) defaults to the center of the circle.
|
||||
|
||||
@ -705,7 +705,7 @@ class Sector(_ShapeBase):
|
||||
self._batch = batch or Batch()
|
||||
self._group = _ShapeGroup(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, group)
|
||||
|
||||
self._vertex_list = self._batch.add(self._segments * 3, GL_TRIANGLES, self._group, 'v2f', 'c4B')
|
||||
self._vertex_list = self._batch.add(self._segments * 3, GL_TRIANGLES, self._group, 'position2f', 'colors4Bn')
|
||||
self._update_position()
|
||||
self._update_color()
|
||||
|
||||
@ -729,14 +729,27 @@ class Sector(_ShapeBase):
|
||||
triangle = x, y, *points[i - 1], *point
|
||||
vertices.extend(triangle)
|
||||
|
||||
self._vertex_list.vertices[:] = vertices
|
||||
self._vertex_list.position[:] = vertices
|
||||
|
||||
def _update_color(self):
|
||||
self._vertex_list.colors[:] = [*self._rgb, int(self._opacity)] * self._segments * 3
|
||||
|
||||
@property
|
||||
def angle(self):
|
||||
"""The angle of the sector.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self._angle
|
||||
|
||||
@angle.setter
|
||||
def angle(self, value):
|
||||
self._angle = value
|
||||
self._update_position()
|
||||
|
||||
@property
|
||||
def radius(self):
|
||||
"""The radius of the circle.
|
||||
"""The radius of the sector.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
@ -1154,7 +1167,7 @@ class BorderedRectangle(_ShapeBase):
|
||||
|
||||
@border_color.setter
|
||||
def border_color(self, values):
|
||||
self._brgb = list(map(int, values))
|
||||
self._brgb = tuple(map(int, values))
|
||||
self._update_color()
|
||||
|
||||
|
||||
|
@ -209,12 +209,13 @@ class InlineElement:
|
||||
self.advance = advance
|
||||
self._position = None
|
||||
|
||||
position = property(lambda self: self._position,
|
||||
doc="""Position of the element within the
|
||||
document. Read-only.
|
||||
@property
|
||||
def position(self):
|
||||
"""Position of the element within the document. Read-only.
|
||||
|
||||
:type: int
|
||||
""")
|
||||
"""
|
||||
return self._position
|
||||
|
||||
def place(self, layout, x, y):
|
||||
"""Construct an instance of the element at the given coordinates.
|
||||
@ -269,7 +270,7 @@ class AbstractDocument(event.EventDispatcher):
|
||||
_next_paragraph_re = re.compile(u'[\n\u2029]')
|
||||
|
||||
def __init__(self, text=''):
|
||||
super(AbstractDocument, self).__init__()
|
||||
super().__init__()
|
||||
self._text = u''
|
||||
self._elements = []
|
||||
if text:
|
||||
@ -302,10 +303,9 @@ class AbstractDocument(event.EventDispatcher):
|
||||
|
||||
:rtype: int
|
||||
"""
|
||||
# Tricky special case where the $ in pattern matches before the \n at
|
||||
# the end of the string instead of the end of the string.
|
||||
if (self._text[:pos + 1].endswith('\n') or
|
||||
self._text[:pos + 1].endswith(u'\u2029')):
|
||||
# Tricky special case where the $ in pattern matches before the
|
||||
# \n at the end of the string instead of the end of the string.
|
||||
if self._text[:pos + 1].endswith('\n') or self._text[:pos + 1].endswith(u'\u2029'):
|
||||
return pos
|
||||
|
||||
m = self._previous_paragraph_re.search(self._text, 0, pos + 1)
|
||||
@ -456,8 +456,8 @@ class AbstractDocument(event.EventDispatcher):
|
||||
def insert_element(self, position, element, attributes=None):
|
||||
"""Insert a element into the document.
|
||||
|
||||
See the :py:class:`~pyglet.text.document.InlineElement` class documentation for details of
|
||||
usage.
|
||||
See the :py:class:`~pyglet.text.document.InlineElement` class
|
||||
documentation for details of usage.
|
||||
|
||||
:Parameters:
|
||||
`position` : int
|
||||
@ -582,7 +582,7 @@ class UnformattedDocument(AbstractDocument):
|
||||
"""
|
||||
|
||||
def __init__(self, text=''):
|
||||
super(UnformattedDocument, self).__init__(text)
|
||||
super().__init__(text)
|
||||
self.styles = {}
|
||||
|
||||
def get_style_runs(self, attribute):
|
||||
@ -593,15 +593,13 @@ class UnformattedDocument(AbstractDocument):
|
||||
return self.styles.get(attribute)
|
||||
|
||||
def set_style(self, start, end, attributes):
|
||||
return super(UnformattedDocument, self).set_style(
|
||||
0, len(self.text), attributes)
|
||||
return super().set_style(0, len(self.text), attributes)
|
||||
|
||||
def _set_style(self, start, end, attributes):
|
||||
self.styles.update(attributes)
|
||||
|
||||
def set_paragraph_style(self, start, end, attributes):
|
||||
return super(UnformattedDocument, self).set_paragraph_style(
|
||||
0, len(self.text), attributes)
|
||||
return super().set_paragraph_style(0, len(self.text), attributes)
|
||||
|
||||
def get_font_runs(self, dpi=None):
|
||||
ft = self.get_font(dpi=dpi)
|
||||
@ -614,8 +612,7 @@ class UnformattedDocument(AbstractDocument):
|
||||
bold = self.styles.get('bold', False)
|
||||
italic = self.styles.get('italic', False)
|
||||
stretch = self.styles.get('stretch', False)
|
||||
return font.load(font_name, font_size,
|
||||
bold=bold, italic=italic, stretch=stretch, dpi=dpi)
|
||||
return font.load(font_name, font_size, bold=bold, italic=italic, stretch=stretch, dpi=dpi)
|
||||
|
||||
def get_element_runs(self):
|
||||
return runlist.ConstRunIterator(len(self._text), None)
|
||||
@ -630,7 +627,7 @@ class FormattedDocument(AbstractDocument):
|
||||
|
||||
def __init__(self, text=''):
|
||||
self._style_runs = {}
|
||||
super(FormattedDocument, self).__init__(text)
|
||||
super().__init__(text)
|
||||
|
||||
def get_style_runs(self, attribute):
|
||||
try:
|
||||
@ -670,7 +667,7 @@ class FormattedDocument(AbstractDocument):
|
||||
return _ElementIterator(self._elements, len(self._text))
|
||||
|
||||
def _insert_text(self, start, text, attributes):
|
||||
super(FormattedDocument, self)._insert_text(start, text, attributes)
|
||||
super()._insert_text(start, text, attributes)
|
||||
|
||||
len_text = len(text)
|
||||
for runs in self._style_runs.values():
|
||||
@ -686,7 +683,7 @@ class FormattedDocument(AbstractDocument):
|
||||
runs.set_run(start, start + len_text, value)
|
||||
|
||||
def _delete_text(self, start, end):
|
||||
super(FormattedDocument, self)._delete_text(start, end)
|
||||
super()._delete_text(start, end)
|
||||
for runs in self._style_runs.values():
|
||||
runs.delete(start, end)
|
||||
|
||||
@ -728,7 +725,8 @@ class _FontStyleRunsRangeIterator:
|
||||
|
||||
class _NoStyleRangeIterator:
|
||||
# XXX subclass runlist
|
||||
def ranges(self, start, end):
|
||||
@staticmethod
|
||||
def ranges(start, end):
|
||||
yield start, end, None
|
||||
|
||||
def __getitem__(self, index):
|
||||
|
@ -89,7 +89,7 @@ class ImageElement(pyglet.text.document.InlineElement):
|
||||
super().__init__(ascent, descent, self.width)
|
||||
|
||||
def place(self, layout, x, y):
|
||||
group = _InlineElementGroup(self.image.get_texture(), 0, layout._group)
|
||||
group = _InlineElementGroup(self.image.get_texture(), 0, layout.group)
|
||||
x1 = x
|
||||
y1 = y + self.descent
|
||||
x2 = x + self.width
|
||||
|
@ -324,12 +324,12 @@ class _GlyphBox(_AbstractBox):
|
||||
|
||||
def place(self, layout, i, x, y, context):
|
||||
assert self.glyphs
|
||||
|
||||
try:
|
||||
group = layout.groups[self.owner]
|
||||
group = layout.group_cache[self.owner]
|
||||
except KeyError:
|
||||
group = layout.default_group_class(texture=self.owner, order=1, program=get_default_layout_shader(),
|
||||
parent=layout._group)
|
||||
layout.groups[self.owner] = group
|
||||
group = layout.default_group_class(self.owner, get_default_layout_shader(), order=1, parent=layout.group)
|
||||
layout.group_cache[self.owner] = group
|
||||
|
||||
n_glyphs = self.length
|
||||
vertices = []
|
||||
@ -644,7 +644,7 @@ def get_default_decoration_shader():
|
||||
|
||||
|
||||
class TextLayoutGroup(graphics.Group):
|
||||
def __init__(self, texture, order=1, program=None, parent=None):
|
||||
def __init__(self, texture, program, order=1, parent=None):
|
||||
"""Create a text layout rendering group.
|
||||
|
||||
The group is created internally when a :py:class:`~pyglet.text.Label`
|
||||
@ -652,7 +652,7 @@ class TextLayoutGroup(graphics.Group):
|
||||
"""
|
||||
super().__init__(order=order, parent=parent)
|
||||
self.texture = texture
|
||||
self.program = program or get_default_layout_shader()
|
||||
self.program = program
|
||||
|
||||
def set_state(self):
|
||||
self.program.use()
|
||||
@ -687,7 +687,7 @@ class TextLayoutGroup(graphics.Group):
|
||||
class ScrollableTextLayoutGroup(graphics.Group):
|
||||
scissor_area = 0, 0, 0, 0
|
||||
|
||||
def __init__(self, texture, order=1, program=None, parent=None):
|
||||
def __init__(self, texture, program, order=1, parent=None):
|
||||
"""Default rendering group for :py:class:`~pyglet.text.layout.ScrollableTextLayout`.
|
||||
|
||||
The group maintains internal state for specifying the viewable
|
||||
@ -696,7 +696,7 @@ class ScrollableTextLayoutGroup(graphics.Group):
|
||||
"""
|
||||
super().__init__(order=order, parent=parent)
|
||||
self.texture = texture
|
||||
self.program = program or get_default_layout_shader()
|
||||
self.program = program
|
||||
|
||||
def set_state(self):
|
||||
self.program.use()
|
||||
@ -732,14 +732,14 @@ class IncrementalTextLayoutGroup(ScrollableTextLayoutGroup):
|
||||
|
||||
|
||||
class TextDecorationGroup(graphics.Group):
|
||||
def __init__(self, order=0, program=None, parent=None):
|
||||
def __init__(self, program, order=0, parent=None):
|
||||
"""Create a text decoration rendering group.
|
||||
|
||||
The group is created internally when a :py:class:`~pyglet.text.Label`
|
||||
is created; applications usually do not need to explicitly create it.
|
||||
"""
|
||||
super().__init__(order=order, parent=parent)
|
||||
self.program = program or get_default_decoration_shader()
|
||||
self.program = program
|
||||
|
||||
def set_state(self):
|
||||
self.program.use()
|
||||
@ -756,14 +756,14 @@ class TextDecorationGroup(graphics.Group):
|
||||
class ScrollableTextDecorationGroup(graphics.Group):
|
||||
scissor_area = 0, 0, 0, 0
|
||||
|
||||
def __init__(self, order=0, program=None, parent=None):
|
||||
def __init__(self, program, order=0, parent=None):
|
||||
"""Create a text decoration rendering group.
|
||||
|
||||
The group is created internally when a :py:class:`~pyglet.text.Label`
|
||||
is created; applications usually do not need to explicitly create it.
|
||||
"""
|
||||
super().__init__(order=order, parent=parent)
|
||||
self.program = program or get_default_decoration_shader()
|
||||
self.program = program
|
||||
|
||||
def set_state(self):
|
||||
self.program.use()
|
||||
@ -867,12 +867,13 @@ class TextLayout:
|
||||
self.content_width = 0
|
||||
self.content_height = 0
|
||||
|
||||
self._group = group
|
||||
self._user_group = group
|
||||
|
||||
self.background_decoration_group = TextDecorationGroup(order=0, parent=self._group)
|
||||
self.foreground_decoration_group = TextDecorationGroup(order=2, parent=self._group)
|
||||
decoration_shader = get_default_decoration_shader()
|
||||
self.background_decoration_group = TextDecorationGroup(decoration_shader, order=0, parent=self._user_group)
|
||||
self.foreground_decoration_group = TextDecorationGroup(decoration_shader, order=2, parent=self._user_group)
|
||||
|
||||
self.groups = {}
|
||||
self.group_cache = {}
|
||||
|
||||
if batch is None:
|
||||
batch = graphics.Batch()
|
||||
@ -892,6 +893,10 @@ class TextLayout:
|
||||
self._dpi = dpi or 96
|
||||
self.document = document
|
||||
|
||||
@property
|
||||
def group(self):
|
||||
return self._user_group
|
||||
|
||||
@property
|
||||
def dpi(self):
|
||||
"""Get DPI used by this layout.
|
||||
@ -1021,10 +1026,10 @@ class TextLayout:
|
||||
dx = x - self._x
|
||||
dy = y - self._y
|
||||
for vertex_list in self._vertex_lists:
|
||||
vertices = vertex_list.vertices[:]
|
||||
vertices = vertex_list.position[:]
|
||||
vertices[::2] = [x + dx for x in vertices[::2]]
|
||||
vertices[1::2] = [y + dy for y in vertices[1::2]]
|
||||
vertex_list.vertices[:] = vertices
|
||||
vertex_list.position[:] = vertices
|
||||
self._x = x
|
||||
self._y = y
|
||||
|
||||
@ -1256,7 +1261,7 @@ class TextLayout:
|
||||
box.delete(self)
|
||||
self._vertex_lists = []
|
||||
self._boxes = []
|
||||
self.groups.clear()
|
||||
self.group_cache.clear()
|
||||
|
||||
if not self._document or not self._document.text:
|
||||
return
|
||||
@ -1776,8 +1781,10 @@ class ScrollableTextLayout(TextLayout):
|
||||
self._update_scissor_area()
|
||||
|
||||
def _update_scissor_area(self):
|
||||
if not self.document.text:
|
||||
return
|
||||
area = self._get_left(), self._get_bottom(self._get_lines()), self._width, self._height
|
||||
for group in self.groups.values():
|
||||
for group in self.group_cache.values():
|
||||
group.scissor_area = area
|
||||
|
||||
def _update(self):
|
||||
@ -1930,8 +1937,10 @@ class IncrementalTextLayout(TextLayout, EventDispatcher):
|
||||
self._update_scissor_area()
|
||||
|
||||
def _update_scissor_area(self):
|
||||
if not self.document.text:
|
||||
return
|
||||
area = self._get_left(), self._get_bottom(self._get_lines()), self._width, self._height
|
||||
for group in self.groups.values():
|
||||
for group in self.group_cache.values():
|
||||
group.scissor_area = area
|
||||
|
||||
def _init_document(self):
|
||||
@ -2263,7 +2272,7 @@ class IncrementalTextLayout(TextLayout, EventDispatcher):
|
||||
def anchor_x(self, anchor_x):
|
||||
self._anchor_x = anchor_x
|
||||
self._update_scissor_area()
|
||||
self._update()
|
||||
self._init_document()
|
||||
|
||||
@property
|
||||
def anchor_y(self):
|
||||
@ -2273,7 +2282,7 @@ class IncrementalTextLayout(TextLayout, EventDispatcher):
|
||||
def anchor_y(self, anchor_y):
|
||||
self._anchor_y = anchor_y
|
||||
self._update_scissor_area()
|
||||
self._update()
|
||||
self._init_document()
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
|
14
tests/muti_window.py
Normal file
14
tests/muti_window.py
Normal file
@ -0,0 +1,14 @@
|
||||
"""
|
||||
writen by shenjackyuanjie
|
||||
mail: 3695888@qq.com
|
||||
github: @shenjackyuanjie
|
||||
gitee: @shenjackyuanjie
|
||||
"""
|
||||
|
||||
from libs import pyglet
|
||||
|
||||
a_w = pyglet.window.Window(width=400, height=400, resizable=True)
|
||||
|
||||
b_w = pyglet.window.Window(width=400, height=400, resizable=True)
|
||||
|
||||
pyglet.app.run()
|
Loading…
Reference in New Issue
Block a user