-
-
Notifications
You must be signed in to change notification settings - Fork 328
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
76c26a7
commit 7b71942
Showing
1 changed file
with
136 additions
and
135 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |