2015-02-01 11:57:16 +00:00
|
|
|
'''
|
|
|
|
Line (SmoothLine) Experiment
|
|
|
|
============================
|
|
|
|
|
|
|
|
This demonstrates the experimental and unfinished SmoothLine feature
|
2015-02-02 01:09:20 +00:00
|
|
|
for fast line drawing. You should see a multi-segment
|
2015-02-01 11:57:16 +00:00
|
|
|
path at the top of the screen, and sliders and buttons along the bottom.
|
|
|
|
You can click to add new points to the segment, change the transparency
|
|
|
|
and width of the line, or hit 'Animate' to see a set of sine and cosine
|
2015-02-02 01:09:20 +00:00
|
|
|
animations. The Cap and Joint buttons don't work: SmoothLine has not
|
2015-02-01 11:57:16 +00:00
|
|
|
implemented these features yet.
|
|
|
|
'''
|
|
|
|
|
2012-09-21 22:08:49 +00:00
|
|
|
from kivy.app import App
|
2012-09-24 13:41:13 +00:00
|
|
|
from kivy.properties import OptionProperty, NumericProperty, ListProperty, \
|
|
|
|
BooleanProperty
|
2012-09-21 22:08:49 +00:00
|
|
|
from kivy.uix.floatlayout import FloatLayout
|
|
|
|
from kivy.lang import Builder
|
2012-09-21 23:02:19 +00:00
|
|
|
from kivy.clock import Clock
|
|
|
|
from math import cos, sin
|
2012-09-21 22:08:49 +00:00
|
|
|
|
|
|
|
Builder.load_string('''
|
|
|
|
<LinePlayground>:
|
|
|
|
canvas:
|
|
|
|
Color:
|
|
|
|
rgba: .4, .4, 1, root.alpha
|
2014-05-27 16:31:26 +00:00
|
|
|
SmoothLine:
|
2012-09-21 22:08:49 +00:00
|
|
|
points: self.points
|
|
|
|
joint: self.joint
|
|
|
|
cap: self.cap
|
|
|
|
width: self.linewidth
|
2012-09-24 13:41:13 +00:00
|
|
|
close: self.close
|
2012-09-21 22:08:49 +00:00
|
|
|
Color:
|
|
|
|
rgba: .8, .8, .8, root.alpha_controlline
|
2014-05-27 16:31:26 +00:00
|
|
|
SmoothLine:
|
2012-09-21 22:08:49 +00:00
|
|
|
points: self.points
|
2012-09-24 13:41:13 +00:00
|
|
|
close: self.close
|
2012-09-21 23:02:19 +00:00
|
|
|
Color:
|
|
|
|
rgba: 1, .4, .4, root.alpha
|
2014-05-27 16:31:26 +00:00
|
|
|
SmoothLine:
|
2012-09-21 23:02:19 +00:00
|
|
|
points: self.points2
|
|
|
|
joint: self.joint
|
|
|
|
cap: self.cap
|
|
|
|
width: self.linewidth
|
2012-09-24 13:41:13 +00:00
|
|
|
close: self.close
|
2012-09-21 22:08:49 +00:00
|
|
|
|
|
|
|
GridLayout:
|
|
|
|
cols: 2
|
|
|
|
size_hint: 1, None
|
|
|
|
height: 44 * 5
|
|
|
|
|
|
|
|
GridLayout:
|
|
|
|
cols: 2
|
|
|
|
|
|
|
|
Label:
|
|
|
|
text: 'Alpha'
|
|
|
|
Slider:
|
|
|
|
value: root.alpha
|
|
|
|
on_value: root.alpha = float(args[1])
|
|
|
|
min: 0.
|
|
|
|
max: 1.
|
|
|
|
Label:
|
|
|
|
text: 'Alpha Control Line'
|
|
|
|
Slider:
|
|
|
|
value: root.alpha_controlline
|
|
|
|
on_value: root.alpha_controlline = float(args[1])
|
|
|
|
min: 0.
|
|
|
|
max: 1.
|
|
|
|
Label:
|
|
|
|
text: 'Width'
|
|
|
|
Slider:
|
|
|
|
value: root.linewidth
|
|
|
|
on_value: root.linewidth = args[1]
|
|
|
|
min: 1
|
|
|
|
max: 40
|
|
|
|
Label:
|
|
|
|
text: 'Cap'
|
|
|
|
GridLayout:
|
|
|
|
rows: 1
|
|
|
|
ToggleButton:
|
|
|
|
group: 'cap'
|
|
|
|
text: 'none'
|
|
|
|
on_press: root.cap = self.text
|
|
|
|
ToggleButton:
|
|
|
|
group: 'cap'
|
|
|
|
text: 'round'
|
|
|
|
on_press: root.cap = self.text
|
|
|
|
ToggleButton:
|
|
|
|
group: 'cap'
|
|
|
|
text: 'square'
|
|
|
|
on_press: root.cap = self.text
|
|
|
|
Label:
|
|
|
|
text: 'Joint'
|
|
|
|
GridLayout:
|
|
|
|
rows: 1
|
|
|
|
ToggleButton:
|
|
|
|
group: 'joint'
|
|
|
|
text: 'none'
|
|
|
|
on_press: root.joint = self.text
|
|
|
|
ToggleButton:
|
|
|
|
group: 'joint'
|
|
|
|
text: 'round'
|
|
|
|
on_press: root.joint = self.text
|
|
|
|
ToggleButton:
|
|
|
|
group: 'joint'
|
|
|
|
text: 'miter'
|
|
|
|
on_press: root.joint = self.text
|
|
|
|
ToggleButton:
|
|
|
|
group: 'joint'
|
|
|
|
text: 'bevel'
|
|
|
|
on_press: root.joint = self.text
|
|
|
|
|
2012-09-24 13:41:13 +00:00
|
|
|
Label:
|
|
|
|
text: 'Close'
|
|
|
|
ToggleButton:
|
|
|
|
text: 'Close line'
|
|
|
|
on_press: root.close = self.state == 'down'
|
|
|
|
|
2012-09-21 22:08:49 +00:00
|
|
|
AnchorLayout:
|
2012-09-21 23:02:19 +00:00
|
|
|
GridLayout:
|
|
|
|
cols: 1
|
2012-09-21 22:08:49 +00:00
|
|
|
size_hint: None, None
|
2012-09-21 23:02:19 +00:00
|
|
|
size: self.minimum_size
|
|
|
|
ToggleButton:
|
|
|
|
size_hint: None, None
|
|
|
|
size: 100, 44
|
|
|
|
text: 'Animate'
|
|
|
|
on_state: root.animate(self.state == 'down')
|
|
|
|
Button:
|
|
|
|
size_hint: None, None
|
|
|
|
size: 100, 44
|
|
|
|
text: 'Clear'
|
|
|
|
on_press: root.points = root.points2 = []
|
2012-09-21 22:08:49 +00:00
|
|
|
|
|
|
|
''')
|
|
|
|
|
|
|
|
|
|
|
|
class LinePlayground(FloatLayout):
|
2016-06-22 01:23:15 +00:00
|
|
|
|
2012-09-21 22:08:49 +00:00
|
|
|
alpha_controlline = NumericProperty(1.0)
|
|
|
|
alpha = NumericProperty(0.5)
|
2012-09-24 13:41:13 +00:00
|
|
|
close = BooleanProperty(False)
|
2015-12-24 19:26:16 +00:00
|
|
|
points = ListProperty([(500, 500),
|
2016-01-05 19:45:28 +00:00
|
|
|
[300, 300, 500, 300],
|
2015-12-24 19:26:16 +00:00
|
|
|
[500, 400, 600, 400]])
|
2012-09-21 23:02:19 +00:00
|
|
|
points2 = ListProperty([])
|
2012-09-21 22:08:49 +00:00
|
|
|
joint = OptionProperty('none', options=('round', 'miter', 'bevel', 'none'))
|
|
|
|
cap = OptionProperty('none', options=('round', 'square', 'none'))
|
|
|
|
linewidth = NumericProperty(10.0)
|
2012-09-21 23:02:19 +00:00
|
|
|
dt = NumericProperty(0)
|
2012-09-21 22:08:49 +00:00
|
|
|
|
2016-06-22 01:23:15 +00:00
|
|
|
_update_points_animation_ev = None
|
|
|
|
|
2012-09-21 22:08:49 +00:00
|
|
|
def on_touch_down(self, touch):
|
|
|
|
if super(LinePlayground, self).on_touch_down(touch):
|
|
|
|
return True
|
|
|
|
touch.grab(self)
|
2016-01-05 19:45:28 +00:00
|
|
|
self.points.append(touch.pos)
|
2012-09-21 22:08:49 +00:00
|
|
|
return True
|
|
|
|
|
|
|
|
def on_touch_move(self, touch):
|
|
|
|
if touch.grab_current is self:
|
2016-01-05 19:45:28 +00:00
|
|
|
self.points[-1] = touch.pos
|
2012-09-21 22:08:49 +00:00
|
|
|
return True
|
|
|
|
return super(LinePlayground, self).on_touch_move(touch)
|
|
|
|
|
|
|
|
def on_touch_up(self, touch):
|
|
|
|
if touch.grab_current is self:
|
|
|
|
touch.ungrab(self)
|
|
|
|
return True
|
|
|
|
return super(LinePlayground, self).on_touch_up(touch)
|
|
|
|
|
2012-09-21 23:02:19 +00:00
|
|
|
def animate(self, do_animation):
|
|
|
|
if do_animation:
|
2016-06-22 01:23:15 +00:00
|
|
|
self._update_points_animation_ev = Clock.schedule_interval(
|
|
|
|
self.update_points_animation, 0)
|
|
|
|
elif self._update_points_animation_ev is not None:
|
|
|
|
self._update_points_animation_ev.cancel()
|
2012-09-21 23:02:19 +00:00
|
|
|
|
|
|
|
def update_points_animation(self, dt):
|
|
|
|
cy = self.height * 0.6
|
|
|
|
cx = self.width * 0.1
|
|
|
|
w = self.width * 0.8
|
|
|
|
step = 20
|
|
|
|
points = []
|
|
|
|
points2 = []
|
|
|
|
self.dt += dt
|
2012-12-28 15:11:20 +00:00
|
|
|
for i in range(int(w / step)):
|
2012-09-21 23:02:19 +00:00
|
|
|
x = i * step
|
|
|
|
points.append(cx + x)
|
|
|
|
points.append(cy + cos(x / w * 8. + self.dt) * self.height * 0.2)
|
|
|
|
points2.append(cx + x)
|
|
|
|
points2.append(cy + sin(x / w * 8. + self.dt) * self.height * 0.2)
|
|
|
|
self.points = points
|
|
|
|
self.points2 = points2
|
|
|
|
|
2012-09-21 22:08:49 +00:00
|
|
|
|
|
|
|
class TestLineApp(App):
|
|
|
|
def build(self):
|
|
|
|
return LinePlayground()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
TestLineApp().run()
|