bascenev1lib.actor.text
Defines Actor(s).
1# Released under the MIT License. See LICENSE for details. 2# 3"""Defines Actor(s).""" 4 5from __future__ import annotations 6 7from enum import Enum 8from typing import TYPE_CHECKING, override 9 10import bascenev1 as bs 11 12if TYPE_CHECKING: 13 from typing import Any, Sequence 14 15 16class Text(bs.Actor): 17 """Text with some tricks.""" 18 19 class Transition(Enum): 20 """Transition types for text.""" 21 22 FADE_IN = 'fade_in' 23 IN_RIGHT = 'in_right' 24 IN_LEFT = 'in_left' 25 IN_BOTTOM = 'in_bottom' 26 IN_BOTTOM_SLOW = 'in_bottom_slow' 27 IN_TOP_SLOW = 'in_top_slow' 28 29 class HAlign(Enum): 30 """Horizontal alignment type.""" 31 32 LEFT = 'left' 33 CENTER = 'center' 34 RIGHT = 'right' 35 36 class VAlign(Enum): 37 """Vertical alignment type.""" 38 39 NONE = 'none' 40 CENTER = 'center' 41 42 class HAttach(Enum): 43 """Horizontal attach type.""" 44 45 LEFT = 'left' 46 CENTER = 'center' 47 RIGHT = 'right' 48 49 class VAttach(Enum): 50 """Vertical attach type.""" 51 52 BOTTOM = 'bottom' 53 CENTER = 'center' 54 TOP = 'top' 55 56 def __init__( 57 self, 58 text: str | bs.Lstr, 59 *, 60 position: tuple[float, float] = (0.0, 0.0), 61 h_align: HAlign = HAlign.LEFT, 62 v_align: VAlign = VAlign.NONE, 63 color: Sequence[float] = (1.0, 1.0, 1.0, 1.0), 64 transition: Transition | None = None, 65 transition_delay: float = 0.0, 66 flash: bool = False, 67 v_attach: VAttach = VAttach.CENTER, 68 h_attach: HAttach = HAttach.CENTER, 69 scale: float = 1.0, 70 transition_out_delay: float | None = None, 71 maxwidth: float | None = None, 72 shadow: float = 0.5, 73 flatness: float = 0.0, 74 vr_depth: float = 0.0, 75 host_only: bool = False, 76 front: bool = False, 77 ): 78 # pylint: disable=too-many-statements 79 # pylint: disable=too-many-branches 80 # pylint: disable=too-many-locals 81 super().__init__() 82 self.node = bs.newnode( 83 'text', 84 delegate=self, 85 attrs={ 86 'text': text, 87 'color': color, 88 'position': position, 89 'h_align': h_align.value, 90 'vr_depth': vr_depth, 91 'v_align': v_align.value, 92 'h_attach': h_attach.value, 93 'v_attach': v_attach.value, 94 'shadow': shadow, 95 'flatness': flatness, 96 'maxwidth': 0.0 if maxwidth is None else maxwidth, 97 'host_only': host_only, 98 'front': front, 99 'scale': scale, 100 }, 101 ) 102 103 if transition is self.Transition.FADE_IN: 104 if flash: 105 raise RuntimeError( 106 'fixme: flash and fade-in currently cant both be on' 107 ) 108 cmb = bs.newnode( 109 'combine', 110 owner=self.node, 111 attrs={ 112 'input0': color[0], 113 'input1': color[1], 114 'input2': color[2], 115 'size': 4, 116 }, 117 ) 118 keys = {transition_delay: 0.0, transition_delay + 0.5: color[3]} 119 if transition_out_delay is not None: 120 keys[transition_delay + transition_out_delay] = color[3] 121 keys[transition_delay + transition_out_delay + 0.5] = 0.0 122 bs.animate(cmb, 'input3', keys) 123 cmb.connectattr('output', self.node, 'color') 124 125 if flash: 126 mult = 2.0 127 tm1 = 0.15 128 tm2 = 0.3 129 cmb = bs.newnode('combine', owner=self.node, attrs={'size': 4}) 130 bs.animate( 131 cmb, 132 'input0', 133 {0.0: color[0] * mult, tm1: color[0], tm2: color[0] * mult}, 134 loop=True, 135 ) 136 bs.animate( 137 cmb, 138 'input1', 139 {0.0: color[1] * mult, tm1: color[1], tm2: color[1] * mult}, 140 loop=True, 141 ) 142 bs.animate( 143 cmb, 144 'input2', 145 {0.0: color[2] * mult, tm1: color[2], tm2: color[2] * mult}, 146 loop=True, 147 ) 148 cmb.input3 = color[3] 149 cmb.connectattr('output', self.node, 'color') 150 151 cmb = self.position_combine = bs.newnode( 152 'combine', owner=self.node, attrs={'size': 2} 153 ) 154 155 if transition is self.Transition.IN_RIGHT: 156 keys = { 157 transition_delay: position[0] + 1300, 158 transition_delay + 0.2: position[0], 159 } 160 o_keys = {transition_delay: 0.0, transition_delay + 0.05: 1.0} 161 bs.animate(cmb, 'input0', keys) 162 cmb.input1 = position[1] 163 bs.animate(self.node, 'opacity', o_keys) 164 elif transition is self.Transition.IN_LEFT: 165 keys = { 166 transition_delay: position[0] - 1300, 167 transition_delay + 0.2: position[0], 168 } 169 o_keys = {transition_delay: 0.0, transition_delay + 0.05: 1.0} 170 if transition_out_delay is not None: 171 keys[transition_delay + transition_out_delay] = position[0] 172 keys[transition_delay + transition_out_delay + 0.2] = ( 173 position[0] - 1300.0 174 ) 175 o_keys[transition_delay + transition_out_delay + 0.15] = 1.0 176 o_keys[transition_delay + transition_out_delay + 0.2] = 0.0 177 bs.animate(cmb, 'input0', keys) 178 cmb.input1 = position[1] 179 bs.animate(self.node, 'opacity', o_keys) 180 elif transition is self.Transition.IN_BOTTOM_SLOW: 181 keys = { 182 transition_delay: -100.0, 183 transition_delay + 1.0: position[1], 184 } 185 o_keys = {transition_delay: 0.0, transition_delay + 0.2: 1.0} 186 cmb.input0 = position[0] 187 bs.animate(cmb, 'input1', keys) 188 bs.animate(self.node, 'opacity', o_keys) 189 elif transition is self.Transition.IN_BOTTOM: 190 keys = { 191 transition_delay: -100.0, 192 transition_delay + 0.2: position[1], 193 } 194 o_keys = {transition_delay: 0.0, transition_delay + 0.05: 1.0} 195 if transition_out_delay is not None: 196 keys[transition_delay + transition_out_delay] = position[1] 197 keys[transition_delay + transition_out_delay + 0.2] = -100.0 198 o_keys[transition_delay + transition_out_delay + 0.15] = 1.0 199 o_keys[transition_delay + transition_out_delay + 0.2] = 0.0 200 cmb.input0 = position[0] 201 bs.animate(cmb, 'input1', keys) 202 bs.animate(self.node, 'opacity', o_keys) 203 elif transition is self.Transition.IN_TOP_SLOW: 204 keys = { 205 transition_delay: 400.0, 206 transition_delay + 3.5: position[1], 207 } 208 o_keys = {transition_delay: 0, transition_delay + 1.0: 1.0} 209 cmb.input0 = position[0] 210 bs.animate(cmb, 'input1', keys) 211 bs.animate(self.node, 'opacity', o_keys) 212 else: 213 assert transition is self.Transition.FADE_IN or transition is None 214 cmb.input0 = position[0] 215 cmb.input1 = position[1] 216 cmb.connectattr('output', self.node, 'position') 217 218 # If we're transitioning out, die at the end of it. 219 if transition_out_delay is not None: 220 bs.timer( 221 transition_delay + transition_out_delay + 1.0, 222 bs.WeakCall(self.handlemessage, bs.DieMessage()), 223 ) 224 225 @override 226 def handlemessage(self, msg: Any) -> Any: 227 assert not self.expired 228 if isinstance(msg, bs.DieMessage): 229 if self.node: 230 self.node.delete() 231 return None 232 return super().handlemessage(msg)
class
Text(bascenev1._actor.Actor):
17class Text(bs.Actor): 18 """Text with some tricks.""" 19 20 class Transition(Enum): 21 """Transition types for text.""" 22 23 FADE_IN = 'fade_in' 24 IN_RIGHT = 'in_right' 25 IN_LEFT = 'in_left' 26 IN_BOTTOM = 'in_bottom' 27 IN_BOTTOM_SLOW = 'in_bottom_slow' 28 IN_TOP_SLOW = 'in_top_slow' 29 30 class HAlign(Enum): 31 """Horizontal alignment type.""" 32 33 LEFT = 'left' 34 CENTER = 'center' 35 RIGHT = 'right' 36 37 class VAlign(Enum): 38 """Vertical alignment type.""" 39 40 NONE = 'none' 41 CENTER = 'center' 42 43 class HAttach(Enum): 44 """Horizontal attach type.""" 45 46 LEFT = 'left' 47 CENTER = 'center' 48 RIGHT = 'right' 49 50 class VAttach(Enum): 51 """Vertical attach type.""" 52 53 BOTTOM = 'bottom' 54 CENTER = 'center' 55 TOP = 'top' 56 57 def __init__( 58 self, 59 text: str | bs.Lstr, 60 *, 61 position: tuple[float, float] = (0.0, 0.0), 62 h_align: HAlign = HAlign.LEFT, 63 v_align: VAlign = VAlign.NONE, 64 color: Sequence[float] = (1.0, 1.0, 1.0, 1.0), 65 transition: Transition | None = None, 66 transition_delay: float = 0.0, 67 flash: bool = False, 68 v_attach: VAttach = VAttach.CENTER, 69 h_attach: HAttach = HAttach.CENTER, 70 scale: float = 1.0, 71 transition_out_delay: float | None = None, 72 maxwidth: float | None = None, 73 shadow: float = 0.5, 74 flatness: float = 0.0, 75 vr_depth: float = 0.0, 76 host_only: bool = False, 77 front: bool = False, 78 ): 79 # pylint: disable=too-many-statements 80 # pylint: disable=too-many-branches 81 # pylint: disable=too-many-locals 82 super().__init__() 83 self.node = bs.newnode( 84 'text', 85 delegate=self, 86 attrs={ 87 'text': text, 88 'color': color, 89 'position': position, 90 'h_align': h_align.value, 91 'vr_depth': vr_depth, 92 'v_align': v_align.value, 93 'h_attach': h_attach.value, 94 'v_attach': v_attach.value, 95 'shadow': shadow, 96 'flatness': flatness, 97 'maxwidth': 0.0 if maxwidth is None else maxwidth, 98 'host_only': host_only, 99 'front': front, 100 'scale': scale, 101 }, 102 ) 103 104 if transition is self.Transition.FADE_IN: 105 if flash: 106 raise RuntimeError( 107 'fixme: flash and fade-in currently cant both be on' 108 ) 109 cmb = bs.newnode( 110 'combine', 111 owner=self.node, 112 attrs={ 113 'input0': color[0], 114 'input1': color[1], 115 'input2': color[2], 116 'size': 4, 117 }, 118 ) 119 keys = {transition_delay: 0.0, transition_delay + 0.5: color[3]} 120 if transition_out_delay is not None: 121 keys[transition_delay + transition_out_delay] = color[3] 122 keys[transition_delay + transition_out_delay + 0.5] = 0.0 123 bs.animate(cmb, 'input3', keys) 124 cmb.connectattr('output', self.node, 'color') 125 126 if flash: 127 mult = 2.0 128 tm1 = 0.15 129 tm2 = 0.3 130 cmb = bs.newnode('combine', owner=self.node, attrs={'size': 4}) 131 bs.animate( 132 cmb, 133 'input0', 134 {0.0: color[0] * mult, tm1: color[0], tm2: color[0] * mult}, 135 loop=True, 136 ) 137 bs.animate( 138 cmb, 139 'input1', 140 {0.0: color[1] * mult, tm1: color[1], tm2: color[1] * mult}, 141 loop=True, 142 ) 143 bs.animate( 144 cmb, 145 'input2', 146 {0.0: color[2] * mult, tm1: color[2], tm2: color[2] * mult}, 147 loop=True, 148 ) 149 cmb.input3 = color[3] 150 cmb.connectattr('output', self.node, 'color') 151 152 cmb = self.position_combine = bs.newnode( 153 'combine', owner=self.node, attrs={'size': 2} 154 ) 155 156 if transition is self.Transition.IN_RIGHT: 157 keys = { 158 transition_delay: position[0] + 1300, 159 transition_delay + 0.2: position[0], 160 } 161 o_keys = {transition_delay: 0.0, transition_delay + 0.05: 1.0} 162 bs.animate(cmb, 'input0', keys) 163 cmb.input1 = position[1] 164 bs.animate(self.node, 'opacity', o_keys) 165 elif transition is self.Transition.IN_LEFT: 166 keys = { 167 transition_delay: position[0] - 1300, 168 transition_delay + 0.2: position[0], 169 } 170 o_keys = {transition_delay: 0.0, transition_delay + 0.05: 1.0} 171 if transition_out_delay is not None: 172 keys[transition_delay + transition_out_delay] = position[0] 173 keys[transition_delay + transition_out_delay + 0.2] = ( 174 position[0] - 1300.0 175 ) 176 o_keys[transition_delay + transition_out_delay + 0.15] = 1.0 177 o_keys[transition_delay + transition_out_delay + 0.2] = 0.0 178 bs.animate(cmb, 'input0', keys) 179 cmb.input1 = position[1] 180 bs.animate(self.node, 'opacity', o_keys) 181 elif transition is self.Transition.IN_BOTTOM_SLOW: 182 keys = { 183 transition_delay: -100.0, 184 transition_delay + 1.0: position[1], 185 } 186 o_keys = {transition_delay: 0.0, transition_delay + 0.2: 1.0} 187 cmb.input0 = position[0] 188 bs.animate(cmb, 'input1', keys) 189 bs.animate(self.node, 'opacity', o_keys) 190 elif transition is self.Transition.IN_BOTTOM: 191 keys = { 192 transition_delay: -100.0, 193 transition_delay + 0.2: position[1], 194 } 195 o_keys = {transition_delay: 0.0, transition_delay + 0.05: 1.0} 196 if transition_out_delay is not None: 197 keys[transition_delay + transition_out_delay] = position[1] 198 keys[transition_delay + transition_out_delay + 0.2] = -100.0 199 o_keys[transition_delay + transition_out_delay + 0.15] = 1.0 200 o_keys[transition_delay + transition_out_delay + 0.2] = 0.0 201 cmb.input0 = position[0] 202 bs.animate(cmb, 'input1', keys) 203 bs.animate(self.node, 'opacity', o_keys) 204 elif transition is self.Transition.IN_TOP_SLOW: 205 keys = { 206 transition_delay: 400.0, 207 transition_delay + 3.5: position[1], 208 } 209 o_keys = {transition_delay: 0, transition_delay + 1.0: 1.0} 210 cmb.input0 = position[0] 211 bs.animate(cmb, 'input1', keys) 212 bs.animate(self.node, 'opacity', o_keys) 213 else: 214 assert transition is self.Transition.FADE_IN or transition is None 215 cmb.input0 = position[0] 216 cmb.input1 = position[1] 217 cmb.connectattr('output', self.node, 'position') 218 219 # If we're transitioning out, die at the end of it. 220 if transition_out_delay is not None: 221 bs.timer( 222 transition_delay + transition_out_delay + 1.0, 223 bs.WeakCall(self.handlemessage, bs.DieMessage()), 224 ) 225 226 @override 227 def handlemessage(self, msg: Any) -> Any: 228 assert not self.expired 229 if isinstance(msg, bs.DieMessage): 230 if self.node: 231 self.node.delete() 232 return None 233 return super().handlemessage(msg)
Text with some tricks.
Text( text: str | babase.Lstr, *, position: tuple[float, float] = (0.0, 0.0), h_align: Text.HAlign = <HAlign.LEFT: 'left'>, v_align: Text.VAlign = <VAlign.NONE: 'none'>, color: Sequence[float] = (1.0, 1.0, 1.0, 1.0), transition: Text.Transition | None = None, transition_delay: float = 0.0, flash: bool = False, v_attach: Text.VAttach = <VAttach.CENTER: 'center'>, h_attach: Text.HAttach = <HAttach.CENTER: 'center'>, scale: float = 1.0, transition_out_delay: float | None = None, maxwidth: float | None = None, shadow: float = 0.5, flatness: float = 0.0, vr_depth: float = 0.0, host_only: bool = False, front: bool = False)
57 def __init__( 58 self, 59 text: str | bs.Lstr, 60 *, 61 position: tuple[float, float] = (0.0, 0.0), 62 h_align: HAlign = HAlign.LEFT, 63 v_align: VAlign = VAlign.NONE, 64 color: Sequence[float] = (1.0, 1.0, 1.0, 1.0), 65 transition: Transition | None = None, 66 transition_delay: float = 0.0, 67 flash: bool = False, 68 v_attach: VAttach = VAttach.CENTER, 69 h_attach: HAttach = HAttach.CENTER, 70 scale: float = 1.0, 71 transition_out_delay: float | None = None, 72 maxwidth: float | None = None, 73 shadow: float = 0.5, 74 flatness: float = 0.0, 75 vr_depth: float = 0.0, 76 host_only: bool = False, 77 front: bool = False, 78 ): 79 # pylint: disable=too-many-statements 80 # pylint: disable=too-many-branches 81 # pylint: disable=too-many-locals 82 super().__init__() 83 self.node = bs.newnode( 84 'text', 85 delegate=self, 86 attrs={ 87 'text': text, 88 'color': color, 89 'position': position, 90 'h_align': h_align.value, 91 'vr_depth': vr_depth, 92 'v_align': v_align.value, 93 'h_attach': h_attach.value, 94 'v_attach': v_attach.value, 95 'shadow': shadow, 96 'flatness': flatness, 97 'maxwidth': 0.0 if maxwidth is None else maxwidth, 98 'host_only': host_only, 99 'front': front, 100 'scale': scale, 101 }, 102 ) 103 104 if transition is self.Transition.FADE_IN: 105 if flash: 106 raise RuntimeError( 107 'fixme: flash and fade-in currently cant both be on' 108 ) 109 cmb = bs.newnode( 110 'combine', 111 owner=self.node, 112 attrs={ 113 'input0': color[0], 114 'input1': color[1], 115 'input2': color[2], 116 'size': 4, 117 }, 118 ) 119 keys = {transition_delay: 0.0, transition_delay + 0.5: color[3]} 120 if transition_out_delay is not None: 121 keys[transition_delay + transition_out_delay] = color[3] 122 keys[transition_delay + transition_out_delay + 0.5] = 0.0 123 bs.animate(cmb, 'input3', keys) 124 cmb.connectattr('output', self.node, 'color') 125 126 if flash: 127 mult = 2.0 128 tm1 = 0.15 129 tm2 = 0.3 130 cmb = bs.newnode('combine', owner=self.node, attrs={'size': 4}) 131 bs.animate( 132 cmb, 133 'input0', 134 {0.0: color[0] * mult, tm1: color[0], tm2: color[0] * mult}, 135 loop=True, 136 ) 137 bs.animate( 138 cmb, 139 'input1', 140 {0.0: color[1] * mult, tm1: color[1], tm2: color[1] * mult}, 141 loop=True, 142 ) 143 bs.animate( 144 cmb, 145 'input2', 146 {0.0: color[2] * mult, tm1: color[2], tm2: color[2] * mult}, 147 loop=True, 148 ) 149 cmb.input3 = color[3] 150 cmb.connectattr('output', self.node, 'color') 151 152 cmb = self.position_combine = bs.newnode( 153 'combine', owner=self.node, attrs={'size': 2} 154 ) 155 156 if transition is self.Transition.IN_RIGHT: 157 keys = { 158 transition_delay: position[0] + 1300, 159 transition_delay + 0.2: position[0], 160 } 161 o_keys = {transition_delay: 0.0, transition_delay + 0.05: 1.0} 162 bs.animate(cmb, 'input0', keys) 163 cmb.input1 = position[1] 164 bs.animate(self.node, 'opacity', o_keys) 165 elif transition is self.Transition.IN_LEFT: 166 keys = { 167 transition_delay: position[0] - 1300, 168 transition_delay + 0.2: position[0], 169 } 170 o_keys = {transition_delay: 0.0, transition_delay + 0.05: 1.0} 171 if transition_out_delay is not None: 172 keys[transition_delay + transition_out_delay] = position[0] 173 keys[transition_delay + transition_out_delay + 0.2] = ( 174 position[0] - 1300.0 175 ) 176 o_keys[transition_delay + transition_out_delay + 0.15] = 1.0 177 o_keys[transition_delay + transition_out_delay + 0.2] = 0.0 178 bs.animate(cmb, 'input0', keys) 179 cmb.input1 = position[1] 180 bs.animate(self.node, 'opacity', o_keys) 181 elif transition is self.Transition.IN_BOTTOM_SLOW: 182 keys = { 183 transition_delay: -100.0, 184 transition_delay + 1.0: position[1], 185 } 186 o_keys = {transition_delay: 0.0, transition_delay + 0.2: 1.0} 187 cmb.input0 = position[0] 188 bs.animate(cmb, 'input1', keys) 189 bs.animate(self.node, 'opacity', o_keys) 190 elif transition is self.Transition.IN_BOTTOM: 191 keys = { 192 transition_delay: -100.0, 193 transition_delay + 0.2: position[1], 194 } 195 o_keys = {transition_delay: 0.0, transition_delay + 0.05: 1.0} 196 if transition_out_delay is not None: 197 keys[transition_delay + transition_out_delay] = position[1] 198 keys[transition_delay + transition_out_delay + 0.2] = -100.0 199 o_keys[transition_delay + transition_out_delay + 0.15] = 1.0 200 o_keys[transition_delay + transition_out_delay + 0.2] = 0.0 201 cmb.input0 = position[0] 202 bs.animate(cmb, 'input1', keys) 203 bs.animate(self.node, 'opacity', o_keys) 204 elif transition is self.Transition.IN_TOP_SLOW: 205 keys = { 206 transition_delay: 400.0, 207 transition_delay + 3.5: position[1], 208 } 209 o_keys = {transition_delay: 0, transition_delay + 1.0: 1.0} 210 cmb.input0 = position[0] 211 bs.animate(cmb, 'input1', keys) 212 bs.animate(self.node, 'opacity', o_keys) 213 else: 214 assert transition is self.Transition.FADE_IN or transition is None 215 cmb.input0 = position[0] 216 cmb.input1 = position[1] 217 cmb.connectattr('output', self.node, 'position') 218 219 # If we're transitioning out, die at the end of it. 220 if transition_out_delay is not None: 221 bs.timer( 222 transition_delay + transition_out_delay + 1.0, 223 bs.WeakCall(self.handlemessage, bs.DieMessage()), 224 )
Instantiates an Actor in the current bascenev1.Activity.
@override
def
handlemessage(self, msg: Any) -> Any:
226 @override 227 def handlemessage(self, msg: Any) -> Any: 228 assert not self.expired 229 if isinstance(msg, bs.DieMessage): 230 if self.node: 231 self.node.delete() 232 return None 233 return super().handlemessage(msg)
General message handling; can be passed any message object.
class
Text.Transition(enum.Enum):
20 class Transition(Enum): 21 """Transition types for text.""" 22 23 FADE_IN = 'fade_in' 24 IN_RIGHT = 'in_right' 25 IN_LEFT = 'in_left' 26 IN_BOTTOM = 'in_bottom' 27 IN_BOTTOM_SLOW = 'in_bottom_slow' 28 IN_TOP_SLOW = 'in_top_slow'
Transition types for text.
class
Text.HAlign(enum.Enum):
30 class HAlign(Enum): 31 """Horizontal alignment type.""" 32 33 LEFT = 'left' 34 CENTER = 'center' 35 RIGHT = 'right'
Horizontal alignment type.
class
Text.VAlign(enum.Enum):
Vertical alignment type.
class
Text.HAttach(enum.Enum):
43 class HAttach(Enum): 44 """Horizontal attach type.""" 45 46 LEFT = 'left' 47 CENTER = 'center' 48 RIGHT = 'right'
Horizontal attach type.
class
Text.VAttach(enum.Enum):
50 class VAttach(Enum): 51 """Vertical attach type.""" 52 53 BOTTOM = 'bottom' 54 CENTER = 'center' 55 TOP = 'top'
Vertical attach type.