bastd.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 9 10import ba 11 12if TYPE_CHECKING: 13 from typing import Any, Sequence 14 15 16class Text(ba.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 | ba.Lstr, 59 position: tuple[float, float] = (0.0, 0.0), 60 h_align: HAlign = HAlign.LEFT, 61 v_align: VAlign = VAlign.NONE, 62 color: Sequence[float] = (1.0, 1.0, 1.0, 1.0), 63 transition: Transition | None = None, 64 transition_delay: float = 0.0, 65 flash: bool = False, 66 v_attach: VAttach = VAttach.CENTER, 67 h_attach: HAttach = HAttach.CENTER, 68 scale: float = 1.0, 69 transition_out_delay: float | None = None, 70 maxwidth: float | None = None, 71 shadow: float = 0.5, 72 flatness: float = 0.0, 73 vr_depth: float = 0.0, 74 host_only: bool = False, 75 front: bool = False, 76 ): 77 # pylint: disable=too-many-statements 78 # pylint: disable=too-many-branches 79 # pylint: disable=too-many-locals 80 super().__init__() 81 self.node = ba.newnode( 82 'text', 83 delegate=self, 84 attrs={ 85 'text': text, 86 'color': color, 87 'position': position, 88 'h_align': h_align.value, 89 'vr_depth': vr_depth, 90 'v_align': v_align.value, 91 'h_attach': h_attach.value, 92 'v_attach': v_attach.value, 93 'shadow': shadow, 94 'flatness': flatness, 95 'maxwidth': 0.0 if maxwidth is None else maxwidth, 96 'host_only': host_only, 97 'front': front, 98 'scale': scale, 99 }, 100 ) 101 102 if transition is self.Transition.FADE_IN: 103 if flash: 104 raise RuntimeError( 105 'fixme: flash and fade-in currently cant both be on' 106 ) 107 cmb = ba.newnode( 108 'combine', 109 owner=self.node, 110 attrs={ 111 'input0': color[0], 112 'input1': color[1], 113 'input2': color[2], 114 'size': 4, 115 }, 116 ) 117 keys = {transition_delay: 0.0, transition_delay + 0.5: color[3]} 118 if transition_out_delay is not None: 119 keys[transition_delay + transition_out_delay] = color[3] 120 keys[transition_delay + transition_out_delay + 0.5] = 0.0 121 ba.animate(cmb, 'input3', keys) 122 cmb.connectattr('output', self.node, 'color') 123 124 if flash: 125 mult = 2.0 126 tm1 = 0.15 127 tm2 = 0.3 128 cmb = ba.newnode('combine', owner=self.node, attrs={'size': 4}) 129 ba.animate( 130 cmb, 131 'input0', 132 {0.0: color[0] * mult, tm1: color[0], tm2: color[0] * mult}, 133 loop=True, 134 ) 135 ba.animate( 136 cmb, 137 'input1', 138 {0.0: color[1] * mult, tm1: color[1], tm2: color[1] * mult}, 139 loop=True, 140 ) 141 ba.animate( 142 cmb, 143 'input2', 144 {0.0: color[2] * mult, tm1: color[2], tm2: color[2] * mult}, 145 loop=True, 146 ) 147 cmb.input3 = color[3] 148 cmb.connectattr('output', self.node, 'color') 149 150 cmb = self.position_combine = ba.newnode( 151 'combine', owner=self.node, attrs={'size': 2} 152 ) 153 154 if transition is self.Transition.IN_RIGHT: 155 keys = { 156 transition_delay: position[0] + 1300, 157 transition_delay + 0.2: position[0], 158 } 159 o_keys = {transition_delay: 0.0, transition_delay + 0.05: 1.0} 160 ba.animate(cmb, 'input0', keys) 161 cmb.input1 = position[1] 162 ba.animate(self.node, 'opacity', o_keys) 163 elif transition is self.Transition.IN_LEFT: 164 keys = { 165 transition_delay: position[0] - 1300, 166 transition_delay + 0.2: position[0], 167 } 168 o_keys = {transition_delay: 0.0, transition_delay + 0.05: 1.0} 169 if transition_out_delay is not None: 170 keys[transition_delay + transition_out_delay] = position[0] 171 keys[transition_delay + transition_out_delay + 0.2] = ( 172 position[0] - 1300.0 173 ) 174 o_keys[transition_delay + transition_out_delay + 0.15] = 1.0 175 o_keys[transition_delay + transition_out_delay + 0.2] = 0.0 176 ba.animate(cmb, 'input0', keys) 177 cmb.input1 = position[1] 178 ba.animate(self.node, 'opacity', o_keys) 179 elif transition is self.Transition.IN_BOTTOM_SLOW: 180 keys = { 181 transition_delay: -100.0, 182 transition_delay + 1.0: position[1], 183 } 184 o_keys = {transition_delay: 0.0, transition_delay + 0.2: 1.0} 185 cmb.input0 = position[0] 186 ba.animate(cmb, 'input1', keys) 187 ba.animate(self.node, 'opacity', o_keys) 188 elif transition is self.Transition.IN_BOTTOM: 189 keys = { 190 transition_delay: -100.0, 191 transition_delay + 0.2: position[1], 192 } 193 o_keys = {transition_delay: 0.0, transition_delay + 0.05: 1.0} 194 if transition_out_delay is not None: 195 keys[transition_delay + transition_out_delay] = position[1] 196 keys[transition_delay + transition_out_delay + 0.2] = -100.0 197 o_keys[transition_delay + transition_out_delay + 0.15] = 1.0 198 o_keys[transition_delay + transition_out_delay + 0.2] = 0.0 199 cmb.input0 = position[0] 200 ba.animate(cmb, 'input1', keys) 201 ba.animate(self.node, 'opacity', o_keys) 202 elif transition is self.Transition.IN_TOP_SLOW: 203 keys = { 204 transition_delay: 400.0, 205 transition_delay + 3.5: position[1], 206 } 207 o_keys = {transition_delay: 0, transition_delay + 1.0: 1.0} 208 cmb.input0 = position[0] 209 ba.animate(cmb, 'input1', keys) 210 ba.animate(self.node, 'opacity', o_keys) 211 else: 212 assert transition is self.Transition.FADE_IN or transition is None 213 cmb.input0 = position[0] 214 cmb.input1 = position[1] 215 cmb.connectattr('output', self.node, 'position') 216 217 # If we're transitioning out, die at the end of it. 218 if transition_out_delay is not None: 219 ba.timer( 220 transition_delay + transition_out_delay + 1.0, 221 ba.WeakCall(self.handlemessage, ba.DieMessage()), 222 ) 223 224 def handlemessage(self, msg: Any) -> Any: 225 assert not self.expired 226 if isinstance(msg, ba.DieMessage): 227 if self.node: 228 self.node.delete() 229 return None 230 return super().handlemessage(msg)
class
Text(ba._actor.Actor):
17class Text(ba.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 | ba.Lstr, 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 = ba.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 = ba.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 ba.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 = ba.newnode('combine', owner=self.node, attrs={'size': 4}) 130 ba.animate( 131 cmb, 132 'input0', 133 {0.0: color[0] * mult, tm1: color[0], tm2: color[0] * mult}, 134 loop=True, 135 ) 136 ba.animate( 137 cmb, 138 'input1', 139 {0.0: color[1] * mult, tm1: color[1], tm2: color[1] * mult}, 140 loop=True, 141 ) 142 ba.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 = ba.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 ba.animate(cmb, 'input0', keys) 162 cmb.input1 = position[1] 163 ba.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 ba.animate(cmb, 'input0', keys) 178 cmb.input1 = position[1] 179 ba.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 ba.animate(cmb, 'input1', keys) 188 ba.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 ba.animate(cmb, 'input1', keys) 202 ba.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 ba.animate(cmb, 'input1', keys) 211 ba.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 ba.timer( 221 transition_delay + transition_out_delay + 1.0, 222 ba.WeakCall(self.handlemessage, ba.DieMessage()), 223 ) 224 225 def handlemessage(self, msg: Any) -> Any: 226 assert not self.expired 227 if isinstance(msg, ba.DieMessage): 228 if self.node: 229 self.node.delete() 230 return None 231 return super().handlemessage(msg)
Text with some tricks.
Text( text: str | ba._language.Lstr, position: tuple[float, float] = (0.0, 0.0), h_align: bastd.actor.text.Text.HAlign = <HAlign.LEFT: 'left'>, v_align: bastd.actor.text.Text.VAlign = <VAlign.NONE: 'none'>, color: Sequence[float] = (1.0, 1.0, 1.0, 1.0), transition: bastd.actor.text.Text.Transition | None = None, transition_delay: float = 0.0, flash: bool = False, v_attach: bastd.actor.text.Text.VAttach = <VAttach.CENTER: 'center'>, h_attach: bastd.actor.text.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 | ba.Lstr, 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 = ba.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 = ba.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 ba.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 = ba.newnode('combine', owner=self.node, attrs={'size': 4}) 130 ba.animate( 131 cmb, 132 'input0', 133 {0.0: color[0] * mult, tm1: color[0], tm2: color[0] * mult}, 134 loop=True, 135 ) 136 ba.animate( 137 cmb, 138 'input1', 139 {0.0: color[1] * mult, tm1: color[1], tm2: color[1] * mult}, 140 loop=True, 141 ) 142 ba.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 = ba.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 ba.animate(cmb, 'input0', keys) 162 cmb.input1 = position[1] 163 ba.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 ba.animate(cmb, 'input0', keys) 178 cmb.input1 = position[1] 179 ba.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 ba.animate(cmb, 'input1', keys) 188 ba.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 ba.animate(cmb, 'input1', keys) 202 ba.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 ba.animate(cmb, 'input1', keys) 211 ba.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 ba.timer( 221 transition_delay + transition_out_delay + 1.0, 222 ba.WeakCall(self.handlemessage, ba.DieMessage()), 223 )
Instantiates an Actor in the current ba.Activity.
def
handlemessage(self, msg: Any) -> Any:
225 def handlemessage(self, msg: Any) -> Any: 226 assert not self.expired 227 if isinstance(msg, ba.DieMessage): 228 if self.node: 229 self.node.delete() 230 return None 231 return super().handlemessage(msg)
General message handling; can be passed any message object.
Inherited Members
- ba._actor.Actor
- autoretain
- on_expire
- expired
- exists
- is_alive
- activity
- getactivity
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.
Inherited Members
- enum.Enum
- name
- value
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.
Inherited Members
- enum.Enum
- name
- value
class
Text.VAlign(enum.Enum):
Vertical alignment type.
Inherited Members
- enum.Enum
- name
- value
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.
Inherited Members
- enum.Enum
- name
- value
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.
Inherited Members
- enum.Enum
- name
- value