Skip to content

Commit

Permalink
fixed issue with VecField.
Browse files Browse the repository at this point in the history
  • Loading branch information
petteramland committed Nov 9, 2023
1 parent 76c26a7 commit 7b71942
Showing 1 changed file with 136 additions and 135 deletions.
271 changes: 136 additions & 135 deletions ursina/prefabs/vec_field.py
Original file line number Diff line number Diff line change
@@ -1,135 +1,136 @@
from ursina.prefabs.button import Button
from ursina.entity import Entity
from ursina.vec2 import Vec2
from ursina.prefabs.input_field import InputField, ContentTypes
from ursina import color, camera, mouse, round_to_closest


class VecField(Button):
def __init__(self, default_value=Vec2(0.0,0.0), character_limit=8, content_type=ContentTypes.math, **kwargs):
kwargs = dict(parent=camera.ui, scale=(.5,.05), character_limit=character_limit, text='', text_origin=(-.5,0), color=color.black90) | kwargs
super().__init__(**kwargs)
if isinstance(default_value, (int, float)):
default_value = [default_value, ]

self.default_value = default_value
self.fields = []
self.on_value_changed = None
w = 1 / len(default_value) *.5

self.highlight_color = self.color
self.pressed_color = self.color
self._dragging_on = None
self._value_on_drag_start = []
self._temp_value = []

self.data_type = float
if isinstance(default_value[0], int):
self.data_type = int
content_type = ContentTypes.int_math

for i in range(len(default_value)):
field = InputField(str(self.default_value[i])[:self.character_limit], character_limit=self.character_limit, model='quad', parent=self, limit_content_to=content_type,
x=(i*w)+w/2, scale=(w,1), z=-1, color=color._8, font='VeraMono.ttf', submit_on=['enter','tab'])
field.grid = Entity(parent=field, model='wireframe_quad', color=color.dark_gray, z=-1)
field.text_field.scale *= .75
field.on_submit = self.convert_text_to_vector
field.on_value_changed = self.convert_text_to_vector
field.text_field.shortcuts['select_all'] = ('double click', )
field.text_field.shortcuts['select_word'] = []
self.fields.append(field)

self.value = default_value


def convert_text_to_vector(self):
vector = []
for i, field in enumerate(self.fields):
try:
# value = type(self.default_value[i])(eval(field.text[:self.character_limit]))
value = self.data_type(eval(field.text[:self.character_limit]))
if isinstance(value, self.data_type):
vector.append(value)
field.text_field.text_entity.text = str(value)[:8]
except: # invalid/incomplete math
print('invalid')
return
# print('vector:', vector, 'fotype', type(self.default_value))
if not isinstance(self.default_value, (tuple, list)):
vector = type(self.default_value)(*vector)

self.value = vector


@property
def value(self):
if len(self._value) == 1:
return self._value[0]
return self._value

@value.setter
def value(self, value):
self._value = value
if len(value) == 1:
value = value[0]

if self.on_value_changed is not None:
self.on_value_changed()

for i, field in enumerate(self.fields):
field.text = value[i][:self.character_limit]


def input(self, key):
super().input(key)
if key == 'left mouse down':
self._dragging_on = None
self._temp_value = [e for e in self._value]

for i, field in enumerate(self.fields):
if field.hovered:
self._dragging_on = field
self._value_on_drag_start = self.value
return

elif key == 'left mouse up' and self._dragging_on:
self._dragging_on = None
self.value = self._value
self._temp_value = self._value


def update(self):
if mouse.left and self._dragging_on and not self._dragging_on.active:
# print('drag on:', self._dragging_on, mouse.velocity.x)
idx = self.fields.index(self._dragging_on)
if self.data_type == float:
self._temp_value[idx] += mouse.velocity.x
self._value = [round_to_closest(e, .01) for e in self._temp_value]
elif self.data_type == int:
self._temp_value[idx] += mouse.velocity.x * 10
self._value = [int(e) for e in self._temp_value]

for i, field in enumerate(self.fields): # set text temporarily while dragging
field.text_field.text_entity.text = str(self._value[i])[:self.character_limit]



if __name__ == '__main__':
from ursina import *
app = Ursina()
# Entity(parent=camera.ui, model='quad', scale=.05, z=-10)
# field = VecField(text=' field', default_value=Vec3(0,0,0))
def on_value_changed():
print('set value to:', field.value)

field = VecField(text=' int list', default_value=[10,1])
field = VecField(text=' float list', default_value=[1.0,-2.0], y=-.1)
field = VecField(text=' Vec4', default_value=Vec4(1,-2,0,0), y=-.2)
field = VecField(text=' float', default_value=1.0, y=-.3)
field = VecField(text=' int', default_value=0, y=-.4)
# field.on_value_changed = on_value_changed

# Entity(color=color.azure, scale=(.5,.05), model='quad', parent=camera.ui)
# InputField(y=-.1)
Sprite('shore', color=color.dark_gray)
app.run()
from ursina.prefabs.button import Button
from ursina.entity import Entity
from ursina.vec2 import Vec2
from ursina.prefabs.input_field import InputField, ContentTypes
from ursina import color, camera, mouse, round_to_closest


class VecField(Button):
def __init__(self, default_value=Vec2(0.0,0.0), character_limit=8, content_type=ContentTypes.math, **kwargs):
kwargs = dict(parent=camera.ui, scale=(.5,.05), character_limit=character_limit, text='', text_origin=(-.5,0), color=color.black90) | kwargs
super().__init__(**kwargs)
if isinstance(default_value, (int, float)):
default_value = [default_value, ]

self.default_value = default_value
self.fields = []
self.on_value_changed = None
w = 1 / len(default_value) *.5

self.highlight_color = self.color
self.pressed_color = self.color
self._dragging_on = None
self._value_on_drag_start = []
self._temp_value = []

self.data_type = float
if isinstance(default_value[0], int):
self.data_type = int
content_type = ContentTypes.int_math

for i in range(len(default_value)):
field = InputField(str(self.default_value[i])[:self.character_limit], character_limit=self.character_limit, model='quad', parent=self, limit_content_to=content_type,
x=(i*w)+w/2, scale=(w,1), z=-1, color=color._8, font='VeraMono.ttf', submit_on=['enter','tab'])
field.grid = Entity(parent=field, model='wireframe_quad', color=color.dark_gray, z=-1)
field.text_field.scale *= .75
field.on_submit = self.convert_text_to_vector
# field.on_value_changed = self.convert_text_to_vector
field.text_field.shortcuts['select_all'] = ('double click', )
field.text_field.shortcuts['select_word'] = []
self.fields.append(field)

self.value = default_value


def convert_text_to_vector(self):
vector = []
for i, field in enumerate(self.fields):
try:
# value = type(self.default_value[i])(eval(field.text[:self.character_limit]))
value = self.data_type(eval(field.text[:self.character_limit]))
if isinstance(value, self.data_type):
vector.append(value)
field.text_field.text_entity.text = str(value)[:8]
except: # invalid/incomplete math
print('invalid')
return
# print('vector:', vector, 'fotype', type(self.default_value))
if not isinstance(self.default_value, (tuple, list)):
vector = type(self.default_value)(*vector)

self.value = vector


@property
def value(self):
if len(self._value) == 1:
return self._value[0]
return self._value

@value.setter
def value(self, value):
self._value = value
if len(value) == 1:
value = str(value[0])

if self.on_value_changed is not None:
self.on_value_changed()

for i, field in enumerate(self.fields):
# print('---------', field.text, str(value[i]))
field.text = str(value[i])[:self.character_limit]


def input(self, key):
super().input(key)
if key == 'left mouse down':
self._dragging_on = None
self._temp_value = [e for e in self._value]

for i, field in enumerate(self.fields):
if field.hovered:
self._dragging_on = field
self._value_on_drag_start = self.value
return

elif key == 'left mouse up' and self._dragging_on:
self._dragging_on = None
self.value = self._value
self._temp_value = self._value


def update(self):
if mouse.left and self._dragging_on and not self._dragging_on.active:
# print('drag on:', self._dragging_on, mouse.velocity.x)
idx = self.fields.index(self._dragging_on)
if self.data_type == float:
self._temp_value[idx] += mouse.velocity.x
self._value = [round_to_closest(e, .01) for e in self._temp_value]
elif self.data_type == int:
self._temp_value[idx] += mouse.velocity.x * 10
self._value = [int(e) for e in self._temp_value]

for i, field in enumerate(self.fields): # set text temporarily while dragging
field.text_field.text_entity.text = str(self._value[i])[:self.character_limit]



if __name__ == '__main__':
from ursina import *
app = Ursina()
# Entity(parent=camera.ui, model='quad', scale=.05, z=-10)
# field = VecField(text=' field', default_value=Vec3(0,0,0))
def on_value_changed():
print('set value to:', field.value)

field = VecField(text=' int list', default_value=[10,1])
field = VecField(text=' float list', default_value=[1.0,-2.0], y=-.1)
field = VecField(text=' Vec4', default_value=Vec4(1,-2,0,0), y=-.2)
field = VecField(text=' float', default_value=1.0, y=-.3)
field = VecField(text=' int', default_value=0, y=-.4)
# field.on_value_changed = on_value_changed

# Entity(color=color.azure, scale=(.5,.05), model='quad', parent=camera.ui)
# InputField(y=-.1)
Sprite('shore', color=color.dark_gray)
app.run()

0 comments on commit 7b71942

Please sign in to comment.