|
6 | 6 | from math import sqrt, tan, pi |
7 | 7 |
|
8 | 8 | import time |
9 | | -try: |
10 | | - clock = time.perf_counter # time.clock is deprecated in Python 3.3, gone in 3.8 |
11 | | -except: |
12 | | - clock = time.clock |
| 9 | + |
| 10 | +# vpython provides clock in its namespace |
| 11 | +clock = time.perf_counter |
| 12 | + |
13 | 13 | import sys |
14 | 14 | from . import __version__, __gs_version__ |
15 | 15 | from ._notebook_helpers import _isnotebook |
|
97 | 97 | 'right':'q', 'top':'r', 'bottom':'s', '_cloneid':'t', |
98 | 98 | 'logx':'u', 'logy':'v', 'dot':'w', 'dot_radius':'x', |
99 | 99 | 'markers':'y', 'legend':'z', 'label':'A', 'delta':'B', 'marker_color':'C', |
100 | | - 'size_units':'D', 'userpan':'E', 'scroll':'F'} |
| 100 | + 'size_units':'D', 'userpan':'E', 'scroll':'F', 'choices':'G'} |
101 | 101 |
|
102 | 102 | # methods are X in {'m': '23X....'} |
103 | 103 | # pos is normally updated as an attribute, but for interval-based trails, it is updated (multiply) as a method |
|
113 | 113 | 'marker_color'] |
114 | 114 |
|
115 | 115 | __textattrs = ['text', 'align', 'caption', 'title', 'xtitle', 'ytitle', 'selected', 'label', 'capture', |
116 | | - 'append_to_caption', 'append_to_title', 'bind', 'unbind', 'pause', 'GSprint'] |
| 116 | + 'append_to_caption', 'append_to_title', 'bind', 'unbind', 'pause', 'GSprint', 'choices'] |
117 | 117 |
|
118 | 118 | def _encode_attr2(sendval, val, ismethods): |
119 | 119 | s = '' |
120 | 120 | if sendval in __vecattrs: # it would be good to do some kind of compression of doubles |
121 | 121 | s += "{:.16G},{:.16G},{:.16G}".format(val[0], val[1], val[2]) |
122 | 122 | elif sendval in __textattrs: |
123 | | - # '\n' doesn't survive JSON transmission, so we replace '\n' with '<br>' (and convert back in glowcomm) |
124 | | - if not isinstance(val, str): val = print_to_string(val) |
125 | | - val = val.replace('\n', '<br>') |
| 123 | + if sendval == 'choices': |
| 124 | + s2 = '' |
| 125 | + for v in val: |
| 126 | + s2 += v+' ' |
| 127 | + val = s2[0:-1] |
| 128 | + else: |
| 129 | + # '\n' doesn't survive JSON transmission, so we replace '\n' with '<br>' (and convert back in glowcomm) |
| 130 | + if not isinstance(val, str): val = print_to_string(val) |
| 131 | + val = val.replace('\n', '<br>') |
126 | 132 | s += val |
127 | 133 | elif sendval == 'rotate': |
128 | 134 | for p in val: |
@@ -556,7 +562,7 @@ class standardAttributes(baseObj): |
556 | 562 | 'extrusion':[ ['pos', 'color', 'start_face_color', 'end_face_color'], |
557 | 563 | [ 'axis', 'size', 'up' ], |
558 | 564 | ['path', 'shape', 'visible', 'opacity','shininess', 'emissive', |
559 | | - 'show_start_face', 'show_end_face', |
| 565 | + 'show_start_face', 'show_end_face', 'smooth', |
560 | 566 | 'make_trail', 'trail_type', 'interval', 'show_start_face', 'show_end_face', |
561 | 567 | 'retain', 'trail_color', 'trail_radius', 'texture', 'pickable' ], |
562 | 568 | ['red', 'green', 'blue','length', 'width', 'height'] ], |
@@ -2702,7 +2708,7 @@ def rotate(self, angle=0, axis=None, origin=None): |
2702 | 2708 | c = self._canvas |
2703 | 2709 | if axis is None: axis = c.up |
2704 | 2710 | if origin is not None and origin != self.pos: |
2705 | | - origin = self.pos + (self.pos-origin).rotate(angle=angle, axis=axis) |
| 2711 | + origin = origin + (self.pos-origin).rotate(angle=angle, axis=axis) |
2706 | 2712 | else: |
2707 | 2713 | origin = self.pos |
2708 | 2714 | if c._axis.diff_angle(axis) > 1e-6: |
@@ -3098,7 +3104,6 @@ def handle_event(self, evt): ## events and scene info updates |
3098 | 3104 | # Set attribute_vector.value, which avoids nullifying the |
3099 | 3105 | # on_change functions that detect changes in e.g. obj.pos.y |
3100 | 3106 | obj._pos.value = list_to_vec(p) |
3101 | | - obj._origin = obj._pos |
3102 | 3107 | s = evt['size'] |
3103 | 3108 | obj._size.value = obj._size0 = list_to_vec(s) |
3104 | 3109 | obj._axis.value = obj._size._x*norm(obj._axis) |
@@ -3543,7 +3548,10 @@ def choices(self): |
3543 | 3548 | return self._choices |
3544 | 3549 | @choices.setter |
3545 | 3550 | def choices(self, value): |
3546 | | - raise AttributeError('choices cannot be modified after a menu is created') |
| 3551 | + self._choices = value |
| 3552 | + if not self._constructing: |
| 3553 | + self.addattr('choices') |
| 3554 | + #raise AttributeError('choices cannot be modified after a menu is created') |
3547 | 3555 |
|
3548 | 3556 | @property |
3549 | 3557 | def index(self): |
@@ -3784,6 +3792,16 @@ def shape(self): |
3784 | 3792 | def shape(self, value): |
3785 | 3793 | raise AttributeError('shape cannot be changed after extrusion is created') |
3786 | 3794 |
|
| 3795 | + @property |
| 3796 | + def smooth(self): |
| 3797 | + if self._constructing: |
| 3798 | + return self._smooth |
| 3799 | + else: |
| 3800 | + return None |
| 3801 | + @smooth.setter |
| 3802 | + def smooth(self, value): |
| 3803 | + raise AttributeError('smooth cannot be changed after extrusion is created') |
| 3804 | + |
3787 | 3805 | @property |
3788 | 3806 | def show_start_face(self): |
3789 | 3807 | if self._constructing: |
|
0 commit comments