first commit
This commit is contained in:
commit
417e54da96
5696 changed files with 900003 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
105
kivy_venv/share/kivy-examples/canvas/bezier.py
Normal file
105
kivy_venv/share/kivy-examples/canvas/bezier.py
Normal file
|
@ -0,0 +1,105 @@
|
|||
'''
|
||||
Bezier Example
|
||||
==============
|
||||
|
||||
This example shows a closed Bezier curve computed from a polygon. You
|
||||
should see a purple polygon, a red bezier curve computed from the polygon,
|
||||
and two sliders. You can drag points on the polygon to recompute the curve.
|
||||
The two sliders control the dash length of the dashed lines making up the two
|
||||
shapes.
|
||||
|
||||
'''
|
||||
from kivy.app import App
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.uix.slider import Slider
|
||||
from kivy.graphics import Color, Bezier, Line
|
||||
|
||||
|
||||
class BezierTest(FloatLayout):
|
||||
|
||||
def __init__(self, points=[], loop=False, *args, **kwargs):
|
||||
super(BezierTest, self).__init__(*args, **kwargs)
|
||||
self.d = 10 # pixel tolerance when clicking on a point
|
||||
self.points = points
|
||||
self.loop = loop
|
||||
self.current_point = None # index of point being dragged
|
||||
|
||||
with self.canvas:
|
||||
Color(1.0, 0.0, 0.0)
|
||||
|
||||
self.bezier = Bezier(
|
||||
points=self.points,
|
||||
segments=150,
|
||||
loop=self.loop,
|
||||
dash_length=100,
|
||||
dash_offset=10)
|
||||
|
||||
Color(1.0, 0.0, 1.0)
|
||||
self.line = Line(
|
||||
points=self.points + self.points[:2],
|
||||
dash_offset=10,
|
||||
dash_length=100)
|
||||
|
||||
s = Slider(y=0, pos_hint={'x': .3}, size_hint=(.7, None), height=50)
|
||||
s.bind(value=self._set_bezier_dash_offset)
|
||||
self.add_widget(s)
|
||||
|
||||
s = Slider(y=50, pos_hint={'x': .3}, size_hint=(.7, None), height=50)
|
||||
s.bind(value=self._set_line_dash_offset)
|
||||
self.add_widget(s)
|
||||
|
||||
def _set_bezier_dash_offset(self, instance, value):
|
||||
# effect to reduce length while increase offset
|
||||
self.bezier.dash_length = 100 - value
|
||||
self.bezier.dash_offset = value
|
||||
|
||||
def _set_line_dash_offset(self, instance, value):
|
||||
# effect to reduce length while increase offset
|
||||
self.line.dash_length = 100 - value
|
||||
self.line.dash_offset = value
|
||||
|
||||
def on_touch_down(self, touch):
|
||||
if self.collide_point(touch.pos[0], touch.pos[1]):
|
||||
for i, p in enumerate(list(zip(self.points[::2],
|
||||
self.points[1::2]))):
|
||||
if (abs(touch.pos[0] - self.pos[0] - p[0]) < self.d and
|
||||
abs(touch.pos[1] - self.pos[1] - p[1]) < self.d):
|
||||
self.current_point = i + 1
|
||||
return True
|
||||
return super(BezierTest, self).on_touch_down(touch)
|
||||
|
||||
def on_touch_up(self, touch):
|
||||
if self.collide_point(touch.pos[0], touch.pos[1]):
|
||||
if self.current_point:
|
||||
self.current_point = None
|
||||
return True
|
||||
return super(BezierTest, self).on_touch_up(touch)
|
||||
|
||||
def on_touch_move(self, touch):
|
||||
if self.collide_point(touch.pos[0], touch.pos[1]):
|
||||
c = self.current_point
|
||||
if c:
|
||||
self.points[(c - 1) * 2] = touch.pos[0] - self.pos[0]
|
||||
self.points[(c - 1) * 2 + 1] = touch.pos[1] - self.pos[1]
|
||||
self.bezier.points = self.points
|
||||
self.line.points = self.points + self.points[:2]
|
||||
return True
|
||||
return super(BezierTest, self).on_touch_move(touch)
|
||||
|
||||
|
||||
class Main(App):
|
||||
|
||||
def build(self):
|
||||
from math import cos, sin, radians
|
||||
x = y = 150
|
||||
z = 100
|
||||
# Pacman !
|
||||
points = [x, y]
|
||||
for i in range(45, 360, 45):
|
||||
i = radians(i)
|
||||
points.extend([x + cos(i) * z, y + sin(i) * z])
|
||||
return BezierTest(points=points, loop=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
Main().run()
|
72
kivy_venv/share/kivy-examples/canvas/canvas_stress.py
Normal file
72
kivy_venv/share/kivy-examples/canvas/canvas_stress.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
'''
|
||||
Canvas stress
|
||||
=============
|
||||
|
||||
This example tests the performance of our Graphics engine by drawing large
|
||||
numbers of small squares. You should see a black canvas with buttons and a
|
||||
label at the bottom. Pressing the buttons adds small colored squares to the
|
||||
canvas.
|
||||
|
||||
'''
|
||||
|
||||
from kivy.uix.button import Button
|
||||
from kivy.uix.widget import Widget
|
||||
from kivy.uix.label import Label
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.app import App
|
||||
from kivy.graphics import Color, Rectangle
|
||||
from random import random as r
|
||||
from functools import partial
|
||||
|
||||
|
||||
class StressCanvasApp(App):
|
||||
|
||||
def add_rects(self, label, wid, count, *largs):
|
||||
label.text = str(int(label.text) + count)
|
||||
with wid.canvas:
|
||||
for x in range(count):
|
||||
Color(r(), 1, 1, mode='hsv')
|
||||
Rectangle(pos=(r() * wid.width + wid.x,
|
||||
r() * wid.height + wid.y), size=(20, 20))
|
||||
|
||||
def double_rects(self, label, wid, *largs):
|
||||
count = int(label.text)
|
||||
self.add_rects(label, wid, count, *largs)
|
||||
|
||||
def reset_rects(self, label, wid, *largs):
|
||||
label.text = '0'
|
||||
wid.canvas.clear()
|
||||
|
||||
def build(self):
|
||||
wid = Widget()
|
||||
|
||||
label = Label(text='0')
|
||||
|
||||
btn_add100 = Button(text='+ 100 rects',
|
||||
on_press=partial(self.add_rects, label, wid, 100))
|
||||
|
||||
btn_add500 = Button(text='+ 500 rects',
|
||||
on_press=partial(self.add_rects, label, wid, 500))
|
||||
|
||||
btn_double = Button(text='x 2',
|
||||
on_press=partial(self.double_rects, label, wid))
|
||||
|
||||
btn_reset = Button(text='Reset',
|
||||
on_press=partial(self.reset_rects, label, wid))
|
||||
|
||||
layout = BoxLayout(size_hint=(1, None), height=50)
|
||||
layout.add_widget(btn_add100)
|
||||
layout.add_widget(btn_add500)
|
||||
layout.add_widget(btn_double)
|
||||
layout.add_widget(btn_reset)
|
||||
layout.add_widget(label)
|
||||
|
||||
root = BoxLayout(orientation='vertical')
|
||||
root.add_widget(wid)
|
||||
root.add_widget(layout)
|
||||
|
||||
return root
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
StressCanvasApp().run()
|
84
kivy_venv/share/kivy-examples/canvas/circle.py
Normal file
84
kivy_venv/share/kivy-examples/canvas/circle.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
'''
|
||||
Circle Example
|
||||
==============
|
||||
|
||||
This example exercises circle (ellipse) drawing. You should see sliders at the
|
||||
top of the screen with the Kivy logo below it. The sliders control the
|
||||
angle start and stop and the height and width scales. There is a button
|
||||
to reset the sliders. The logo used for the circle's background image is
|
||||
from the kivy/data directory. The entire example is coded in the
|
||||
kv language description.
|
||||
'''
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
|
||||
kv = '''
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: sp(100)
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Slider:
|
||||
id: e1
|
||||
min: -360.
|
||||
max: 360.
|
||||
Label:
|
||||
text: 'angle_start = {}'.format(e1.value)
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Slider:
|
||||
id: e2
|
||||
min: -360.
|
||||
max: 360.
|
||||
value: 360
|
||||
Label:
|
||||
text: 'angle_end = {}'.format(e2.value)
|
||||
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: sp(100)
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Slider:
|
||||
id: wm
|
||||
min: 0
|
||||
max: 2
|
||||
value: 1
|
||||
Label:
|
||||
text: 'Width mult. = {}'.format(wm.value)
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Slider:
|
||||
id: hm
|
||||
min: 0
|
||||
max: 2
|
||||
value: 1
|
||||
Label:
|
||||
text: 'Height mult. = {}'.format(hm.value)
|
||||
Button:
|
||||
text: 'Reset ratios'
|
||||
on_press: wm.value = 1; hm.value = 1
|
||||
|
||||
FloatLayout:
|
||||
canvas:
|
||||
Color:
|
||||
rgb: 1, 1, 1
|
||||
Ellipse:
|
||||
pos: 100, 100
|
||||
size: 200 * wm.value, 201 * hm.value
|
||||
source: 'data/logo/kivy-icon-512.png'
|
||||
angle_start: e1.value
|
||||
angle_end: e2.value
|
||||
|
||||
'''
|
||||
|
||||
|
||||
class CircleApp(App):
|
||||
def build(self):
|
||||
return Builder.load_string(kv)
|
||||
|
||||
|
||||
CircleApp().run()
|
91
kivy_venv/share/kivy-examples/canvas/fbo_canvas.py
Normal file
91
kivy_venv/share/kivy-examples/canvas/fbo_canvas.py
Normal file
|
@ -0,0 +1,91 @@
|
|||
'''
|
||||
FBO Canvas
|
||||
==========
|
||||
|
||||
This demonstrates a layout using an FBO (Frame Buffer Off-screen)
|
||||
instead of a plain canvas. You should see a black canvas with a
|
||||
button labelled 'FBO' in the bottom left corner. Clicking it
|
||||
animates the button moving right to left.
|
||||
'''
|
||||
|
||||
__all__ = ('FboFloatLayout', )
|
||||
|
||||
from kivy.graphics import Color, Rectangle, Canvas, ClearBuffers, ClearColor
|
||||
from kivy.graphics.fbo import Fbo
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.properties import ObjectProperty, NumericProperty
|
||||
from kivy.app import App
|
||||
from kivy.core.window import Window
|
||||
from kivy.animation import Animation
|
||||
from kivy.factory import Factory
|
||||
|
||||
|
||||
class FboFloatLayout(FloatLayout):
|
||||
|
||||
texture = ObjectProperty(None, allownone=True)
|
||||
|
||||
alpha = NumericProperty(1)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.canvas = Canvas()
|
||||
with self.canvas:
|
||||
self.fbo = Fbo(size=self.size)
|
||||
self.fbo_color = Color(1, 1, 1, 1)
|
||||
self.fbo_rect = Rectangle()
|
||||
|
||||
with self.fbo:
|
||||
ClearColor(0, 0, 0, 0)
|
||||
ClearBuffers()
|
||||
|
||||
# wait that all the instructions are in the canvas to set texture
|
||||
self.texture = self.fbo.texture
|
||||
super(FboFloatLayout, self).__init__(**kwargs)
|
||||
|
||||
def add_widget(self, *args, **kwargs):
|
||||
# trick to attach graphics instruction to fbo instead of canvas
|
||||
canvas = self.canvas
|
||||
self.canvas = self.fbo
|
||||
ret = super(FboFloatLayout, self).add_widget(*args, **kwargs)
|
||||
self.canvas = canvas
|
||||
return ret
|
||||
|
||||
def remove_widget(self, *args, **kwargs):
|
||||
canvas = self.canvas
|
||||
self.canvas = self.fbo
|
||||
super(FboFloatLayout, self).remove_widget(*args, **kwargs)
|
||||
self.canvas = canvas
|
||||
|
||||
def on_size(self, instance, value):
|
||||
self.fbo.size = value
|
||||
self.texture = self.fbo.texture
|
||||
self.fbo_rect.size = value
|
||||
|
||||
def on_pos(self, instance, value):
|
||||
self.fbo_rect.pos = value
|
||||
|
||||
def on_texture(self, instance, value):
|
||||
self.fbo_rect.texture = value
|
||||
|
||||
def on_alpha(self, instance, value):
|
||||
self.fbo_color.rgba = (1, 1, 1, value)
|
||||
|
||||
|
||||
class ScreenLayerApp(App):
|
||||
def build(self):
|
||||
|
||||
f = FboFloatLayout()
|
||||
b = Factory.Button(text="FBO", size_hint=(None, None))
|
||||
f.add_widget(b)
|
||||
|
||||
def anim_btn(*args):
|
||||
if b.pos[0] == 0:
|
||||
Animation(x=f.width - b.width).start(b)
|
||||
else:
|
||||
Animation(x=0).start(b)
|
||||
b.bind(on_press=anim_btn)
|
||||
|
||||
return f
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ScreenLayerApp().run()
|
BIN
kivy_venv/share/kivy-examples/canvas/kiwi.jpg
Normal file
BIN
kivy_venv/share/kivy-examples/canvas/kiwi.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
296
kivy_venv/share/kivy-examples/canvas/lines.py
Normal file
296
kivy_venv/share/kivy-examples/canvas/lines.py
Normal file
|
@ -0,0 +1,296 @@
|
|||
'''
|
||||
Line (SmoothLine) Experiment
|
||||
============================
|
||||
|
||||
This demonstrates the experimental and unfinished SmoothLine feature
|
||||
for fast line drawing. You should see a multi-segment
|
||||
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
|
||||
animations. The Cap and Joint buttons don't work: SmoothLine has not
|
||||
implemented these features yet.
|
||||
'''
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.properties import OptionProperty, NumericProperty, ListProperty, \
|
||||
BooleanProperty
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.lang import Builder
|
||||
from kivy.clock import Clock
|
||||
from math import cos, sin
|
||||
|
||||
Builder.load_string('''
|
||||
<LinePlayground>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: .4, .4, 1, root.alpha
|
||||
Line:
|
||||
points: self.points
|
||||
joint: self.joint
|
||||
cap: self.cap
|
||||
width: self.linewidth
|
||||
close: self.close
|
||||
dash_length: self.dash_length
|
||||
dash_offset: self.dash_offset
|
||||
dashes: self.dashes
|
||||
Color:
|
||||
rgba: .8, .8, .8, root.alpha_controlline
|
||||
Line:
|
||||
points: self.points
|
||||
close: self.close
|
||||
dash_length: self.dash_length
|
||||
dash_offset: self.dash_offset
|
||||
dashes: self.dashes
|
||||
Color:
|
||||
rgba: 1, .4, .4, root.alpha
|
||||
Line:
|
||||
points: self.points2
|
||||
joint: self.joint
|
||||
cap: self.cap
|
||||
width: self.linewidth
|
||||
close: self.close
|
||||
dash_length: self.dash_length
|
||||
dash_offset: self.dash_offset
|
||||
dashes: self.dashes
|
||||
|
||||
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
|
||||
|
||||
Label:
|
||||
text: 'Close'
|
||||
ToggleButton:
|
||||
text: 'Close line'
|
||||
on_press: root.close = self.state == 'down'
|
||||
|
||||
Label:
|
||||
text: 'Dashes'
|
||||
GridLayout:
|
||||
rows: 1
|
||||
ToggleButton:
|
||||
group: 'dashes'
|
||||
text: 'none'
|
||||
state: 'down'
|
||||
allow_no_selection: False
|
||||
size_hint_x: None
|
||||
width: self.texture_size[0]
|
||||
padding_x: '5dp'
|
||||
on_state:
|
||||
if self.state == 'down': root.dashes = []
|
||||
if self.state == 'down': root.dash_length = 1
|
||||
if self.state == 'down': root.dash_offset = 0
|
||||
ToggleButton:
|
||||
id: constant
|
||||
group: 'dashes'
|
||||
text: 'Constant: '
|
||||
allow_no_selection: False
|
||||
size_hint_x: None
|
||||
width: self.texture_size[0]
|
||||
padding_x: '5dp'
|
||||
on_state:
|
||||
if self.state == 'down': root.dashes = []
|
||||
if self.state == 'down': root.dash_length = \
|
||||
int(dash_len.text or 1)
|
||||
if self.state == 'down': root.dash_offset = \
|
||||
int(dash_offset.text or 0)
|
||||
Label:
|
||||
text: 'len'
|
||||
size_hint_x: None
|
||||
width: self.texture_size[0]
|
||||
padding_x: '5dp'
|
||||
TextInput:
|
||||
id: dash_len
|
||||
size_hint_x: None
|
||||
width: '30dp'
|
||||
input_filter: 'int'
|
||||
multiline: False
|
||||
text: '1'
|
||||
on_text: if constant.state == 'down': \
|
||||
root.dash_length = int(self.text or 1)
|
||||
Label:
|
||||
text: 'offset'
|
||||
size_hint_x: None
|
||||
width: self.texture_size[0]
|
||||
padding_x: '5dp'
|
||||
TextInput:
|
||||
id: dash_offset
|
||||
size_hint_x: None
|
||||
width: '30dp'
|
||||
input_filter: 'int'
|
||||
multiline: False
|
||||
text: '0'
|
||||
on_text: if constant.state == 'down': \
|
||||
root.dash_offset = int(self.text or 0)
|
||||
ToggleButton:
|
||||
id: dash_list
|
||||
group: 'dashes'
|
||||
text: 'List: '
|
||||
allow_no_selection: False
|
||||
size_hint_x: None
|
||||
width: self.texture_size[0]
|
||||
padding_x: '5dp'
|
||||
on_state:
|
||||
if self.state == 'down': root.dashes = list(map(lambda\
|
||||
x: int(x or 0), dash_list_in.text.split(',')))
|
||||
if self.state == 'down': root.dash_length = 1
|
||||
if self.state == 'down': root.dash_offset = 0
|
||||
TextInput:
|
||||
id: dash_list_in
|
||||
size_hint_x: None
|
||||
width: '180dp'
|
||||
multiline: False
|
||||
text: '4,3,10,15'
|
||||
on_text: if dash_list.state == 'down': root.dashes = \
|
||||
list(map(lambda x: int(x or 0), self.text.split(',')))
|
||||
|
||||
AnchorLayout:
|
||||
GridLayout:
|
||||
cols: 1
|
||||
size_hint: None, None
|
||||
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 = []
|
||||
|
||||
''')
|
||||
|
||||
|
||||
class LinePlayground(FloatLayout):
|
||||
|
||||
alpha_controlline = NumericProperty(1.0)
|
||||
alpha = NumericProperty(0.5)
|
||||
close = BooleanProperty(False)
|
||||
points = ListProperty([(500, 500),
|
||||
[300, 300, 500, 300],
|
||||
[500, 400, 600, 400]])
|
||||
points2 = ListProperty([])
|
||||
joint = OptionProperty('none', options=('round', 'miter', 'bevel', 'none'))
|
||||
cap = OptionProperty('none', options=('round', 'square', 'none'))
|
||||
linewidth = NumericProperty(10.0)
|
||||
dt = NumericProperty(0)
|
||||
dash_length = NumericProperty(1)
|
||||
dash_offset = NumericProperty(0)
|
||||
dashes = ListProperty([])
|
||||
|
||||
_update_points_animation_ev = None
|
||||
|
||||
def on_touch_down(self, touch):
|
||||
if super(LinePlayground, self).on_touch_down(touch):
|
||||
return True
|
||||
touch.grab(self)
|
||||
self.points.append(touch.pos)
|
||||
return True
|
||||
|
||||
def on_touch_move(self, touch):
|
||||
if touch.grab_current is self:
|
||||
self.points[-1] = touch.pos
|
||||
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)
|
||||
|
||||
def animate(self, do_animation):
|
||||
if do_animation:
|
||||
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()
|
||||
|
||||
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
|
||||
for i in range(int(w / step)):
|
||||
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
|
||||
|
||||
|
||||
class TestLineApp(App):
|
||||
def build(self):
|
||||
return LinePlayground()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
TestLineApp().run()
|
183
kivy_venv/share/kivy-examples/canvas/lines_extended.py
Normal file
183
kivy_venv/share/kivy-examples/canvas/lines_extended.py
Normal file
|
@ -0,0 +1,183 @@
|
|||
'''
|
||||
Lines Extended Demo
|
||||
===================
|
||||
|
||||
This demonstrates how to use the extended line drawing routines such
|
||||
as circles, ellipses, and rectangles. You should see a static image of
|
||||
labelled shapes on the screen.
|
||||
'''
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from kivy.uix.widget import Widget
|
||||
from kivy.lang import Builder
|
||||
|
||||
Builder.load_string('''
|
||||
<LineEllipse1>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: 1, .1, .1, .9
|
||||
Line:
|
||||
width: 2.
|
||||
ellipse: (self.x, self.y, self.width, self.height)
|
||||
Label:
|
||||
center: root.center
|
||||
text: 'Ellipse'
|
||||
|
||||
<LineEllipse2>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: 1, .1, .1, .9
|
||||
Line:
|
||||
width: 2.
|
||||
ellipse: (self.x, self.y, self.width, self.height, 90, 180)
|
||||
Label:
|
||||
center: root.center
|
||||
text: 'Ellipse from 90 to 180'
|
||||
|
||||
# fun result with low segments!
|
||||
<LineEllipse3>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: 1, .1, .1, .9
|
||||
Line:
|
||||
width: 2.
|
||||
ellipse: (self.x, self.y, self.width, self.height, 90, 720, 10)
|
||||
Label:
|
||||
center: root.center
|
||||
text: 'Ellipse from 90 to 720\\n10 segments'
|
||||
halign: 'center'
|
||||
|
||||
<LineCircle1>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: .1, 1, .1, .9
|
||||
Line:
|
||||
width: 2.
|
||||
circle:
|
||||
(self.center_x, self.center_y, min(self.width, self.height)
|
||||
/ 2)
|
||||
Label:
|
||||
center: root.center
|
||||
text: 'Circle'
|
||||
|
||||
<LineCircle2>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: .1, 1, .1, .9
|
||||
Line:
|
||||
width: 2.
|
||||
circle:
|
||||
(self.center_x, self.center_y, min(self.width, self.height)
|
||||
/ 2, 90, 180)
|
||||
Label:
|
||||
center: root.center
|
||||
text: 'Circle from 90 to 180'
|
||||
|
||||
<LineCircle3>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: .1, 1, .1, .9
|
||||
Line:
|
||||
width: 2.
|
||||
circle:
|
||||
(self.center_x, self.center_y, min(self.width, self.height)
|
||||
/ 2, 90, 180, 10)
|
||||
Label:
|
||||
center: root.center
|
||||
text: 'Circle from 90 to 180\\n10 segments'
|
||||
halign: 'center'
|
||||
|
||||
<LineCircle4>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: .1, 1, .1, .9
|
||||
Line:
|
||||
width: 2.
|
||||
circle:
|
||||
(self.center_x, self.center_y, min(self.width, self.height)
|
||||
/ 2, 0, 360)
|
||||
Label:
|
||||
center: root.center
|
||||
text: 'Circle from 0 to 360'
|
||||
halign: 'center'
|
||||
|
||||
<LineRectangle>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: .1, .1, 1, .9
|
||||
Line:
|
||||
width: 2.
|
||||
rectangle: (self.x, self.y, self.width, self.height)
|
||||
Label:
|
||||
center: root.center
|
||||
text: 'Rectangle'
|
||||
|
||||
<LineBezier>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: .1, .1, 1, .9
|
||||
Line:
|
||||
width: 2.
|
||||
bezier:
|
||||
(self.x, self.y, self.center_x - 40, self.y + 100,
|
||||
self.center_x + 40, self.y - 100, self.right, self.y)
|
||||
Label:
|
||||
center: root.center
|
||||
text: 'Bezier'
|
||||
''')
|
||||
|
||||
|
||||
class LineEllipse1(Widget):
|
||||
pass
|
||||
|
||||
|
||||
class LineEllipse2(Widget):
|
||||
pass
|
||||
|
||||
|
||||
class LineEllipse3(Widget):
|
||||
pass
|
||||
|
||||
|
||||
class LineCircle1(Widget):
|
||||
pass
|
||||
|
||||
|
||||
class LineCircle2(Widget):
|
||||
pass
|
||||
|
||||
|
||||
class LineCircle3(Widget):
|
||||
pass
|
||||
|
||||
|
||||
class LineCircle4(Widget):
|
||||
pass
|
||||
|
||||
|
||||
class LineRectangle(Widget):
|
||||
pass
|
||||
|
||||
|
||||
class LineBezier(Widget):
|
||||
pass
|
||||
|
||||
|
||||
class LineExtendedApp(App):
|
||||
def build(self):
|
||||
root = GridLayout(cols=2, padding=50, spacing=50)
|
||||
root.add_widget(LineEllipse1())
|
||||
root.add_widget(LineEllipse2())
|
||||
root.add_widget(LineEllipse3())
|
||||
root.add_widget(LineCircle1())
|
||||
root.add_widget(LineCircle2())
|
||||
root.add_widget(LineCircle3())
|
||||
root.add_widget(LineCircle4())
|
||||
root.add_widget(LineRectangle())
|
||||
root.add_widget(LineBezier())
|
||||
return root
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
LineExtendedApp().run()
|
57
kivy_venv/share/kivy-examples/canvas/mesh.py
Normal file
57
kivy_venv/share/kivy-examples/canvas/mesh.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
'''
|
||||
Mesh test
|
||||
=========
|
||||
|
||||
This demonstrates the use of a mesh mode to distort an image. You should see
|
||||
a line of buttons across the bottom of a canvas. Pressing them displays
|
||||
the mesh, a small circle of points, with different mesh.mode settings.
|
||||
'''
|
||||
|
||||
from kivy.uix.button import Button
|
||||
from kivy.uix.widget import Widget
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.app import App
|
||||
from kivy.graphics import Mesh
|
||||
from functools import partial
|
||||
from math import cos, sin, pi
|
||||
|
||||
|
||||
class MeshTestApp(App):
|
||||
|
||||
def change_mode(self, mode, *largs):
|
||||
self.mesh.mode = mode
|
||||
|
||||
def build_mesh(self):
|
||||
""" returns a Mesh of a rough circle. """
|
||||
vertices = []
|
||||
indices = []
|
||||
step = 10
|
||||
istep = (pi * 2) / float(step)
|
||||
for i in range(step):
|
||||
x = 300 + cos(istep * i) * 100
|
||||
y = 300 + sin(istep * i) * 100
|
||||
vertices.extend([x, y, 0, 0])
|
||||
indices.append(i)
|
||||
return Mesh(vertices=vertices, indices=indices)
|
||||
|
||||
def build(self):
|
||||
wid = Widget()
|
||||
with wid.canvas:
|
||||
self.mesh = self.build_mesh()
|
||||
|
||||
layout = BoxLayout(size_hint=(1, None), height=50)
|
||||
for mode in ('points', 'line_strip', 'line_loop', 'lines',
|
||||
'triangle_strip', 'triangle_fan'):
|
||||
button = Button(text=mode)
|
||||
button.bind(on_release=partial(self.change_mode, mode))
|
||||
layout.add_widget(button)
|
||||
|
||||
root = BoxLayout(orientation='vertical')
|
||||
root.add_widget(wid)
|
||||
root.add_widget(layout)
|
||||
|
||||
return root
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
MeshTestApp().run()
|
101
kivy_venv/share/kivy-examples/canvas/mesh_manipulation.py
Normal file
101
kivy_venv/share/kivy-examples/canvas/mesh_manipulation.py
Normal file
|
@ -0,0 +1,101 @@
|
|||
'''
|
||||
Mesh Manipulation Example
|
||||
=========================
|
||||
|
||||
This demonstrates creating a mesh and using it to deform the texture (the
|
||||
kivy log). You should see the kivy logo with a five sliders to right.
|
||||
The sliders change the mesh points' x and y offsets, radius, and a
|
||||
'wobble' deformation's magnitude and speed.
|
||||
|
||||
This example is developed in gabriel's blog post at
|
||||
http://kivy.org/planet/2014/01/kivy-image-manipulations-with-mesh-and-textures/
|
||||
'''
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
from kivy.core.image import Image as CoreImage
|
||||
from kivy.properties import ListProperty, ObjectProperty, NumericProperty
|
||||
from kivy.clock import Clock
|
||||
from kivy.core.window import Window
|
||||
from math import sin, cos, pi
|
||||
|
||||
|
||||
kv = '''
|
||||
BoxLayout:
|
||||
Widget:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: 1, 1, 1, 1
|
||||
Mesh:
|
||||
vertices: app.mesh_points
|
||||
indices: range(len(app.mesh_points) // 4)
|
||||
texture: app.mesh_texture
|
||||
mode: 'triangle_fan'
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
size_hint_x: None
|
||||
width: 100
|
||||
Slider:
|
||||
value: app.offset_x
|
||||
on_value: app.offset_x = args[1]
|
||||
min: -1
|
||||
max: 1
|
||||
Slider:
|
||||
value: app.offset_y
|
||||
on_value: app.offset_y = args[1]
|
||||
min: -1
|
||||
max: 1
|
||||
Slider:
|
||||
value: app.radius
|
||||
on_value: app.radius = args[1]
|
||||
min: 10
|
||||
max: 1000
|
||||
Slider:
|
||||
value: app.sin_wobble
|
||||
on_value: app.sin_wobble = args[1]
|
||||
min: -50
|
||||
max: 50
|
||||
Slider:
|
||||
value: app.sin_wobble_speed
|
||||
on_value: app.sin_wobble_speed = args[1]
|
||||
min: 0
|
||||
max: 50
|
||||
step: 1
|
||||
'''
|
||||
|
||||
|
||||
class MeshBallApp(App):
|
||||
mesh_points = ListProperty([])
|
||||
mesh_texture = ObjectProperty(None)
|
||||
radius = NumericProperty(500)
|
||||
offset_x = NumericProperty(.5)
|
||||
offset_y = NumericProperty(.5)
|
||||
sin_wobble = NumericProperty(0)
|
||||
sin_wobble_speed = NumericProperty(0)
|
||||
|
||||
def build(self):
|
||||
self.mesh_texture = CoreImage('data/logo/kivy-icon-512.png').texture
|
||||
Clock.schedule_interval(self.update_points, 0)
|
||||
return Builder.load_string(kv)
|
||||
|
||||
def update_points(self, *args):
|
||||
""" replace self.mesh_points based on current slider positions.
|
||||
Called continuously by a timer because this only sample code.
|
||||
"""
|
||||
points = [Window.width / 2, Window.height / 2, .5, .5]
|
||||
i = 0
|
||||
while i < 2 * pi:
|
||||
i += 0.01 * pi
|
||||
points.extend([
|
||||
Window.width / 2 + cos(i) * (self.radius + self.sin_wobble *
|
||||
sin(i * self.sin_wobble_speed)),
|
||||
Window.height / 2 + sin(i) * (self.radius + self.sin_wobble *
|
||||
sin(i * self.sin_wobble_speed)),
|
||||
self.offset_x + sin(i),
|
||||
self.offset_y + cos(i)])
|
||||
|
||||
self.mesh_points = points
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
MeshBallApp().run()
|
BIN
kivy_venv/share/kivy-examples/canvas/mtexture1.png
Normal file
BIN
kivy_venv/share/kivy-examples/canvas/mtexture1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
kivy_venv/share/kivy-examples/canvas/mtexture2.png
Normal file
BIN
kivy_venv/share/kivy-examples/canvas/mtexture2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
110
kivy_venv/share/kivy-examples/canvas/multitexture.py
Normal file
110
kivy_venv/share/kivy-examples/canvas/multitexture.py
Normal file
|
@ -0,0 +1,110 @@
|
|||
'''
|
||||
Multitexture Example
|
||||
====================
|
||||
|
||||
This example blends two textures: the image mtexture1.png of the letter K
|
||||
and the image mtexture2.png of an orange circle. You should see an orange
|
||||
K clipped to a circle. It uses a custom shader, written in glsl
|
||||
(OpenGL Shading Language), stored in a local string.
|
||||
|
||||
Note the image mtexture1.png is a white 'K' on a transparent background, which
|
||||
makes it hard to see.
|
||||
'''
|
||||
|
||||
from kivy.clock import Clock
|
||||
from kivy.app import App
|
||||
from kivy.uix.widget import Widget
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.lang import Builder
|
||||
from kivy.core.window import Window
|
||||
from kivy.graphics import RenderContext, Color, Rectangle, BindTexture
|
||||
|
||||
|
||||
fs_multitexture = '''
|
||||
$HEADER$
|
||||
|
||||
// New uniform that will receive texture at index 1
|
||||
uniform sampler2D texture1;
|
||||
|
||||
void main(void) {
|
||||
|
||||
// multiple current color with both texture (0 and 1).
|
||||
// currently, both will use exactly the same texture coordinates.
|
||||
gl_FragColor = frag_color * \
|
||||
texture2D(texture0, tex_coord0) * \
|
||||
texture2D(texture1, tex_coord0);
|
||||
}
|
||||
'''
|
||||
|
||||
|
||||
kv = """
|
||||
<MultitextureLayout>:
|
||||
|
||||
Image:
|
||||
source: "mtexture1.png"
|
||||
size_hint: .3,.3
|
||||
id: 1
|
||||
pos: 0,200
|
||||
Image:
|
||||
source: "mtexture2.png"
|
||||
size_hint: .3,.3
|
||||
id: 2
|
||||
pos: 200,200
|
||||
|
||||
MultitextureWidget:
|
||||
|
||||
"""
|
||||
|
||||
Builder.load_string(kv)
|
||||
|
||||
|
||||
class MultitextureWidget(Widget):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.canvas = RenderContext()
|
||||
# setting shader.fs to new source code automatically compiles it.
|
||||
self.canvas.shader.fs = fs_multitexture
|
||||
with self.canvas:
|
||||
Color(1, 1, 1)
|
||||
|
||||
# here, we are binding a custom texture at index 1
|
||||
# this will be used as texture1 in shader.
|
||||
# The filenames are misleading: they do not correspond to the
|
||||
# index here or in the shader.
|
||||
BindTexture(source='mtexture2.png', index=1)
|
||||
|
||||
# create a rectangle with texture (will be at index 0)
|
||||
Rectangle(size=(150, 150), source='mtexture1.png', pos=(500, 200))
|
||||
|
||||
# set the texture1 to use texture index 1
|
||||
self.canvas['texture1'] = 1
|
||||
|
||||
# call the constructor of parent
|
||||
# if they are any graphics objects, they will be added on our new
|
||||
# canvas
|
||||
super(MultitextureWidget, self).__init__(**kwargs)
|
||||
|
||||
# We'll update our glsl variables in a clock
|
||||
Clock.schedule_interval(self.update_glsl, 0)
|
||||
|
||||
def update_glsl(self, *largs):
|
||||
# This is needed for the default vertex shader.
|
||||
self.canvas['projection_mat'] = Window.render_context['projection_mat']
|
||||
self.canvas['modelview_mat'] = Window.render_context['modelview_mat']
|
||||
|
||||
|
||||
class MultitextureLayout(FloatLayout):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.size = kwargs['size']
|
||||
super(MultitextureLayout, self).__init__(**kwargs)
|
||||
|
||||
|
||||
class MultitextureApp(App):
|
||||
|
||||
def build(self):
|
||||
return MultitextureLayout(size=(600, 600))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
MultitextureApp().run()
|
65
kivy_venv/share/kivy-examples/canvas/repeat_texture.py
Normal file
65
kivy_venv/share/kivy-examples/canvas/repeat_texture.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
'''
|
||||
Repeat Texture on Resize
|
||||
========================
|
||||
|
||||
This examples repeats the letter 'K' (mtexture1.png) 64 times in a window.
|
||||
You should see 8 rows and 8 columns of white K letters, along a label
|
||||
showing the current size. As you resize the window, it stays an 8x8.
|
||||
This example includes a label with a colored background.
|
||||
|
||||
Note the image mtexture1.png is a white 'K' on a transparent background, which
|
||||
makes it hard to see.
|
||||
'''
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.image import Image
|
||||
from kivy.uix.label import Label
|
||||
from kivy.properties import ObjectProperty, ListProperty
|
||||
from kivy.lang import Builder
|
||||
|
||||
kv = '''
|
||||
<LabelOnBackground>:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgb: self.background
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
|
||||
FloatLayout:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgb: 1, 1, 1
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
texture: app.texture
|
||||
|
||||
LabelOnBackground:
|
||||
text: '{} (try to resize the window)'.format(root.size)
|
||||
color: (0.4, 1, 1, 1)
|
||||
background: (.3, .3, .3)
|
||||
pos_hint: {'center_x': .5, 'center_y': .5 }
|
||||
size_hint: None, None
|
||||
height: 30
|
||||
width: 250
|
||||
|
||||
'''
|
||||
|
||||
|
||||
class LabelOnBackground(Label):
|
||||
background = ListProperty((0.2, 0.2, 0.2))
|
||||
|
||||
|
||||
class RepeatTexture(App):
|
||||
|
||||
texture = ObjectProperty()
|
||||
|
||||
def build(self):
|
||||
self.texture = Image(source='mtexture1.png').texture
|
||||
self.texture.wrap = 'repeat'
|
||||
self.texture.uvsize = (8, 8)
|
||||
return Builder.load_string(kv)
|
||||
|
||||
|
||||
RepeatTexture().run()
|
35
kivy_venv/share/kivy-examples/canvas/rotation.py
Normal file
35
kivy_venv/share/kivy-examples/canvas/rotation.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
'''
|
||||
Rotation Example
|
||||
================
|
||||
|
||||
This example rotates a button using PushMatrix and PopMatrix. You should see
|
||||
a static button with the words 'hello world' rotated at a 45 degree angle.
|
||||
'''
|
||||
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
|
||||
kv = '''
|
||||
FloatLayout:
|
||||
|
||||
Button:
|
||||
text: 'hello world'
|
||||
size_hint: None, None
|
||||
pos_hint: {'center_x': .5, 'center_y': .5}
|
||||
canvas.before:
|
||||
PushMatrix
|
||||
Rotate:
|
||||
angle: 45
|
||||
origin: self.center
|
||||
canvas.after:
|
||||
PopMatrix
|
||||
'''
|
||||
|
||||
|
||||
class RotationApp(App):
|
||||
def build(self):
|
||||
return Builder.load_string(kv)
|
||||
|
||||
|
||||
RotationApp().run()
|
153
kivy_venv/share/kivy-examples/canvas/rounded_rectangle.py
Normal file
153
kivy_venv/share/kivy-examples/canvas/rounded_rectangle.py
Normal file
|
@ -0,0 +1,153 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from kivy.app import App
|
||||
from kivy.uix.widget import Widget
|
||||
from kivy.graphics import Color, Ellipse, Rectangle, RoundedRectangle
|
||||
from kivy.lang import Builder
|
||||
|
||||
TEXTURE = 'kiwi.jpg'
|
||||
YELLOW = (1, .7, 0)
|
||||
ORANGE = (1, .45, 0)
|
||||
RED = (1, 0, 0)
|
||||
WHITE = (1, 1, 1)
|
||||
|
||||
|
||||
class RoundedRectangleWidget(Widget):
|
||||
def prepare(self):
|
||||
with self.canvas:
|
||||
Color(*WHITE)
|
||||
|
||||
# Rectangle of default size 100x100
|
||||
Rectangle(pos=(50, 400))
|
||||
|
||||
# RoundedRectangles of default size 100x100:
|
||||
|
||||
# Textured:
|
||||
RoundedRectangle(
|
||||
pos=(175, 400), radius=[0, 50, 0, 50], source=TEXTURE)
|
||||
|
||||
# Colored:
|
||||
Color(*YELLOW)
|
||||
RoundedRectangle(pos=(300, 400), radius=[0, 50, 0, 50])
|
||||
|
||||
# Textured + Colored
|
||||
# Color(.3,.3,.3, 1)
|
||||
RoundedRectangle(
|
||||
pos=(425, 400), radius=[0, 50, 0, 50], source=TEXTURE)
|
||||
|
||||
# Possible radius arguments:
|
||||
# 1) Same value for each corner
|
||||
Color(*ORANGE)
|
||||
|
||||
# With same radius 20x20
|
||||
RoundedRectangle(pos=(50, 275), radius=[20])
|
||||
|
||||
# With same radius dimensions 20x40
|
||||
RoundedRectangle(pos=(175, 275), radius=[(20, 40)])
|
||||
|
||||
# 2) Different values for each corner
|
||||
Color(*RED)
|
||||
|
||||
# With different radiuses NxN:
|
||||
RoundedRectangle(pos=(300, 275), radius=[10, 20, 30, 40])
|
||||
|
||||
# With different radiuses:
|
||||
RoundedRectangle(
|
||||
pos=(425, 275),
|
||||
radius=[(10, 20), (20, 30), (30, 40), (40, 50)])
|
||||
|
||||
# Default ellipses
|
||||
Color(*WHITE)
|
||||
Ellipse(pos=(50, 150))
|
||||
Ellipse(pos=(175, 150))
|
||||
Ellipse(pos=(300, 150))
|
||||
Ellipse(pos=(425, 150))
|
||||
|
||||
# Radius dimensions can't be bigger than half of the figure side
|
||||
RoundedRectangle(pos=(175, 150), radius=[9000], source=TEXTURE)
|
||||
|
||||
# Segments parameter defines how many segments each corner has.
|
||||
# More segments - more roundness
|
||||
Color(*RED)
|
||||
RoundedRectangle(pos=(300, 150), radius=[9000])
|
||||
RoundedRectangle(pos=(425, 150), radius=[9000], segments=15)
|
||||
|
||||
Color(*ORANGE)
|
||||
RoundedRectangle(pos=(425, 150), radius=[9000], segments=2)
|
||||
|
||||
Color(*YELLOW)
|
||||
RoundedRectangle(pos=(425, 150), radius=[9000], segments=1)
|
||||
|
||||
# Various sizes
|
||||
# You can cut corners by setting segments to 1.
|
||||
# You can set different segment count to corners,
|
||||
# by using a list useful for lowering vertex count
|
||||
# by using small amount on small corners, while using
|
||||
# bigger amount on bigger corners.
|
||||
RoundedRectangle(
|
||||
pos=(50, 25),
|
||||
radius=[40],
|
||||
segments=[1, 1, 10, 10],
|
||||
size=(125, 100))
|
||||
|
||||
# If radius dimension is 0, then the corner will be sharp
|
||||
# (90 degrees). It is also possible to mix tuple values
|
||||
# with numeric
|
||||
Color(*ORANGE)
|
||||
RoundedRectangle(
|
||||
pos=(200, 25),
|
||||
radius=[(40, 20),
|
||||
45.5, 45.5, 0],
|
||||
segments=[2, 3, 3, 1], size=(125, 100))
|
||||
|
||||
Color(*RED)
|
||||
RoundedRectangle(
|
||||
pos=(350, 25),
|
||||
radius=[(40, 40), (40, 40), (20, 20), (20, 20)],
|
||||
segments=[2, 3, 3, 2],
|
||||
size=(150, 100))
|
||||
|
||||
|
||||
class DrawRoundedRectanglesApp(App):
|
||||
def build(self):
|
||||
kv = '''
|
||||
Widget:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: 1, 1,1, 1
|
||||
|
||||
RoundedRectangle:
|
||||
pos: 575, 400
|
||||
size: 100, 100
|
||||
radius: [0, 50, 0, 50]
|
||||
source: 'kiwi.jpg'
|
||||
|
||||
Color:
|
||||
rgba: 0, 0.8, 0.8, 1
|
||||
|
||||
RoundedRectangle:
|
||||
pos: 575, 275
|
||||
size: 100, 100
|
||||
radius: [(10, 20), (20, 30), (30, 40), (40, 50)]
|
||||
|
||||
RoundedRectangle:
|
||||
pos: 575, 150
|
||||
size: 100, 100
|
||||
radius: [9000]
|
||||
segments: 15
|
||||
|
||||
RoundedRectangle:
|
||||
pos: 550, 25
|
||||
size: 150, 100
|
||||
segments: [1, 2, 1, 3]
|
||||
radius: [30, 40, 30, 40]
|
||||
|
||||
'''
|
||||
widget = RoundedRectangleWidget()
|
||||
widget.prepare()
|
||||
kvrect = Builder.load_string(kv)
|
||||
widget.add_widget(kvrect)
|
||||
return widget
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
DrawRoundedRectanglesApp().run()
|
37
kivy_venv/share/kivy-examples/canvas/scale.py
Normal file
37
kivy_venv/share/kivy-examples/canvas/scale.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
'''
|
||||
Scaling Example
|
||||
================
|
||||
|
||||
This example scales a button using PushMatrix and PopMatrix. It shows
|
||||
a static button with the words 'hello world', stretched about its centre by
|
||||
a factor of 1.5 horizontally and 5 vertically.
|
||||
'''
|
||||
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
|
||||
kv = '''
|
||||
FloatLayout:
|
||||
|
||||
Button:
|
||||
text: 'hello world'
|
||||
size_hint: None, None
|
||||
pos_hint: {'center_x': .5, 'center_y': .5}
|
||||
canvas.before:
|
||||
PushMatrix
|
||||
Scale:
|
||||
x: 1.5
|
||||
y: 5
|
||||
origin: self.center
|
||||
canvas.after:
|
||||
PopMatrix
|
||||
'''
|
||||
|
||||
|
||||
class ScalingApp(App):
|
||||
def build(self):
|
||||
return Builder.load_string(kv)
|
||||
|
||||
|
||||
ScalingApp().run()
|
85
kivy_venv/share/kivy-examples/canvas/stencil_canvas.py
Normal file
85
kivy_venv/share/kivy-examples/canvas/stencil_canvas.py
Normal file
|
@ -0,0 +1,85 @@
|
|||
'''
|
||||
Stencil demo
|
||||
============
|
||||
|
||||
This is a test of the stencil graphics instruction inside the stencil view
|
||||
widget. When you use a stencil, nothing will be drawn outside the bounding
|
||||
box. All the graphics will draw only in the stencil view.
|
||||
|
||||
You can "draw" a stencil view by touch & draw. The touch down will set the
|
||||
position, and the drag will set the size.
|
||||
'''
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.core.window import Window
|
||||
from kivy.graphics import Color, Rectangle
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.uix.button import Button
|
||||
from kivy.uix.label import Label
|
||||
from kivy.uix.stencilview import StencilView
|
||||
from random import random as r
|
||||
from functools import partial
|
||||
|
||||
|
||||
class StencilTestWidget(StencilView):
|
||||
'''Drag to define stencil area
|
||||
'''
|
||||
|
||||
def on_touch_down(self, touch):
|
||||
self.pos = touch.pos
|
||||
self.size = (1, 1)
|
||||
|
||||
def on_touch_move(self, touch):
|
||||
self.size = (touch.x - touch.ox, touch.y - touch.oy)
|
||||
|
||||
|
||||
class StencilCanvasApp(App):
|
||||
|
||||
def add_rects(self, label, wid, count, *largs):
|
||||
label.text = str(int(label.text) + count)
|
||||
with wid.canvas:
|
||||
for x in range(count):
|
||||
Color(r(), 1, 1, mode='hsv')
|
||||
Rectangle(pos=(r() * wid.width + wid.x,
|
||||
r() * wid.height + wid.y), size=(10, 10))
|
||||
|
||||
def reset_stencil(self, wid, *largs):
|
||||
wid.pos = (0, 0)
|
||||
wid.size = Window.size
|
||||
|
||||
def reset_rects(self, label, wid, *largs):
|
||||
label.text = '0'
|
||||
wid.canvas.clear()
|
||||
|
||||
def build(self):
|
||||
wid = StencilTestWidget(size_hint=(None, None), size=Window.size)
|
||||
|
||||
label = Label(text='0')
|
||||
|
||||
btn_add500 = Button(text='+ 200 rects')
|
||||
btn_add500.bind(on_press=partial(self.add_rects, label, wid, 200))
|
||||
|
||||
btn_reset = Button(text='Reset Rectangles')
|
||||
btn_reset.bind(on_press=partial(self.reset_rects, label, wid))
|
||||
|
||||
btn_stencil = Button(text='Reset Stencil')
|
||||
btn_stencil.bind(on_press=partial(self.reset_stencil, wid))
|
||||
|
||||
layout = BoxLayout(size_hint=(1, None), height=50)
|
||||
layout.add_widget(btn_add500)
|
||||
layout.add_widget(btn_reset)
|
||||
layout.add_widget(btn_stencil)
|
||||
layout.add_widget(label)
|
||||
|
||||
root = BoxLayout(orientation='vertical')
|
||||
rfl = FloatLayout()
|
||||
rfl.add_widget(wid)
|
||||
root.add_widget(rfl)
|
||||
root.add_widget(layout)
|
||||
|
||||
return root
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
StencilCanvasApp().run()
|
146
kivy_venv/share/kivy-examples/canvas/tesselate.py
Normal file
146
kivy_venv/share/kivy-examples/canvas/tesselate.py
Normal file
|
@ -0,0 +1,146 @@
|
|||
'''
|
||||
Tesselate Demonstration
|
||||
=======================
|
||||
|
||||
This demonstrates the experimental library for tesselating polygons. You
|
||||
should see a hollow square with some buttons below it. You can click and
|
||||
drag to create additional shapes, watching the number of vertices and elements
|
||||
at the top of the screen. The 'debug' button toggles showing the mesh in
|
||||
different colors.
|
||||
'''
|
||||
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.graphics import Mesh, Color
|
||||
from kivy.graphics.tesselator import Tesselator, WINDING_ODD, TYPE_POLYGONS
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.lang import Builder
|
||||
from kivy.logger import Logger
|
||||
|
||||
Builder.load_string("""
|
||||
<ShapeBuilder>:
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: "48dp"
|
||||
spacing: "2dp"
|
||||
padding: "2dp"
|
||||
|
||||
ToggleButton:
|
||||
text: "Debug"
|
||||
id: debug
|
||||
on_release: root.build()
|
||||
Button:
|
||||
text: "New shape"
|
||||
on_release: root.push_shape()
|
||||
Button:
|
||||
text: "Build"
|
||||
on_release: root.build()
|
||||
Button:
|
||||
text: "Reset"
|
||||
on_release: root.reset()
|
||||
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: "48dp"
|
||||
top: root.top
|
||||
spacing: "2dp"
|
||||
padding: "2dp"
|
||||
Label:
|
||||
id: status
|
||||
text: "Status"
|
||||
""")
|
||||
|
||||
|
||||
class ShapeBuilder(FloatLayout):
|
||||
def __init__(self, **kwargs):
|
||||
super(ShapeBuilder, self).__init__(**kwargs)
|
||||
self.shapes = [
|
||||
[100, 100, 300, 100, 300, 300, 100, 300],
|
||||
[150, 150, 250, 150, 250, 250, 150, 250]
|
||||
] # the 'hollow square' shape
|
||||
self.shape = []
|
||||
self.build()
|
||||
|
||||
def on_touch_down(self, touch):
|
||||
if super(ShapeBuilder, self).on_touch_down(touch):
|
||||
return True
|
||||
Logger.info('tesselate: on_touch_down (%5.2f, %5.2f)' % touch.pos)
|
||||
self.shape.extend(touch.pos)
|
||||
self.build()
|
||||
return True
|
||||
|
||||
def on_touch_move(self, touch):
|
||||
if super(ShapeBuilder, self).on_touch_move(touch):
|
||||
return True
|
||||
Logger.info('tesselate: on_touch_move (%5.2f, %5.2f)' % touch.pos)
|
||||
self.shape.extend(touch.pos)
|
||||
self.build()
|
||||
return True
|
||||
|
||||
def on_touch_up(self, touch):
|
||||
if super(ShapeBuilder, self).on_touch_up(touch):
|
||||
return True
|
||||
Logger.info('tesselate: on_touch_up (%5.2f, %5.2f)' % touch.pos)
|
||||
self.push_shape()
|
||||
self.build()
|
||||
|
||||
def push_shape(self):
|
||||
self.shapes.append(self.shape)
|
||||
self.shape = []
|
||||
|
||||
def build(self):
|
||||
tess = Tesselator()
|
||||
count = 0
|
||||
for shape in self.shapes:
|
||||
if len(shape) >= 3:
|
||||
tess.add_contour(shape)
|
||||
count += 1
|
||||
if self.shape and len(self.shape) >= 3:
|
||||
tess.add_contour(self.shape)
|
||||
count += 1
|
||||
if not count:
|
||||
return
|
||||
ret = tess.tesselate(WINDING_ODD, TYPE_POLYGONS)
|
||||
Logger.info('tesselate: build: tess.tesselate returns {}'.format(ret))
|
||||
self.canvas.after.clear()
|
||||
|
||||
debug = self.ids.debug.state == "down"
|
||||
if debug:
|
||||
with self.canvas.after:
|
||||
c = 0
|
||||
for vertices, indices in tess.meshes:
|
||||
Color(c, 1, 1, mode="hsv")
|
||||
c += 0.3
|
||||
indices = [0]
|
||||
for i in range(1, len(vertices) // 4):
|
||||
if i > 0:
|
||||
indices.append(i)
|
||||
indices.append(i)
|
||||
indices.append(0)
|
||||
indices.append(i)
|
||||
indices.pop(-1)
|
||||
Mesh(vertices=vertices, indices=indices, mode="lines")
|
||||
else:
|
||||
with self.canvas.after:
|
||||
Color(1, 1, 1, 1)
|
||||
for vertices, indices in tess.meshes:
|
||||
Mesh(vertices=vertices, indices=indices,
|
||||
mode="triangle_fan")
|
||||
|
||||
self.ids.status.text = "Shapes: {} - Vertex: {} - Elements: {}".format(
|
||||
count, tess.vertex_count, tess.element_count)
|
||||
|
||||
def reset(self):
|
||||
self.shapes = []
|
||||
self.shape = []
|
||||
self.ids.status.text = "Shapes: {} - Vertex: {} - Elements: {}".format(
|
||||
0, 0, 0)
|
||||
self.canvas.after.clear()
|
||||
|
||||
|
||||
class TessApp(App):
|
||||
def build(self):
|
||||
return ShapeBuilder()
|
||||
|
||||
|
||||
TessApp().run()
|
143
kivy_venv/share/kivy-examples/canvas/texture.py
Normal file
143
kivy_venv/share/kivy-examples/canvas/texture.py
Normal file
|
@ -0,0 +1,143 @@
|
|||
'''
|
||||
Texture Wrapping and Coordinates Example
|
||||
========================================
|
||||
|
||||
This example changes texture properties and the properties
|
||||
of its containing rectangle. You should see some a multicolored
|
||||
texture with sliders to the left and below and buttons at the
|
||||
bottom of the screen. The image texture_example_image.png is
|
||||
rendered into the rectangle. Sliders change the number of copies of the
|
||||
texture (the tex_coords), the size of enclosing rectangle (the taw_height
|
||||
and taw_width) while the buttons change how the texture is rendered when more
|
||||
than one copy is in the rectangle (the
|
||||
texture_wrap).
|
||||
|
||||
'''
|
||||
|
||||
|
||||
from kivy.uix.widget import Widget
|
||||
from kivy.properties import ObjectProperty, ListProperty, StringProperty
|
||||
from kivy.lang import Builder
|
||||
from kivy.clock import Clock
|
||||
from kivy.base import runTouchApp
|
||||
|
||||
|
||||
class TextureAccessibleWidget(Widget):
|
||||
texture = ObjectProperty(None)
|
||||
tex_coords = ListProperty([0, 0, 1, 0, 1, 1, 0, 1])
|
||||
texture_wrap = StringProperty('clamp_to_edge')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(TextureAccessibleWidget, self).__init__(**kwargs)
|
||||
Clock.schedule_once(self.texture_init, 0)
|
||||
|
||||
def texture_init(self, *args):
|
||||
self.texture = self.canvas.children[-1].texture
|
||||
|
||||
def on_texture_wrap(self, instance, value):
|
||||
self.texture.wrap = value
|
||||
|
||||
|
||||
root = Builder.load_string('''
|
||||
<TextureAccessibleWidget>:
|
||||
canvas:
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
source: 'texture_example_image.png'
|
||||
tex_coords: root.tex_coords
|
||||
|
||||
<SliderWithValue@BoxLayout>:
|
||||
min: 0.0
|
||||
max: 1.0
|
||||
value: slider.value
|
||||
Slider:
|
||||
id: slider
|
||||
orientation: root.orientation
|
||||
min: root.min
|
||||
max: root.max
|
||||
value: 1.0
|
||||
Label:
|
||||
size_hint: None, None
|
||||
size: min(root.size), min(root.size)
|
||||
text: str(slider.value)[:4]
|
||||
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
BoxLayout:
|
||||
SliderWithValue:
|
||||
orientation: 'vertical'
|
||||
size_hint_x: None
|
||||
width: dp(40)
|
||||
min: 0
|
||||
max: 5
|
||||
value: 1
|
||||
on_value: taw.tex_coords[5] = self.value
|
||||
on_value: taw.tex_coords[7] = self.value
|
||||
SliderWithValue:
|
||||
orientation: 'vertical'
|
||||
size_hint_x: None
|
||||
width: dp(40)
|
||||
min: 0
|
||||
max: taw_container.height
|
||||
value: 0.5*taw_container.height
|
||||
on_value: taw.height = self.value
|
||||
AnchorLayout:
|
||||
id: taw_container
|
||||
anchor_x: 'left'
|
||||
anchor_y: 'bottom'
|
||||
TextureAccessibleWidget:
|
||||
id: taw
|
||||
size_hint: None, None
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: dp(80)
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
size_hint_x: None
|
||||
width: dp(80)
|
||||
Label:
|
||||
text: 'size'
|
||||
text_size: self.size
|
||||
halign: 'right'
|
||||
valign: 'middle'
|
||||
Label:
|
||||
text: 'tex_coords'
|
||||
text_size: self.size
|
||||
halign: 'left'
|
||||
valign: 'middle'
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
SliderWithValue:
|
||||
min: 0
|
||||
max: taw_container.width
|
||||
value: 0.5*taw_container.width
|
||||
on_value: taw.width = self.value
|
||||
SliderWithValue:
|
||||
min: 0.
|
||||
max: 5.
|
||||
value: 1.
|
||||
on_value: taw.tex_coords[2] = self.value
|
||||
on_value: taw.tex_coords[4] = self.value
|
||||
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: dp(50)
|
||||
Label:
|
||||
text: 'texture wrap:'
|
||||
text_size: self.size
|
||||
valign: 'middle'
|
||||
halign: 'center'
|
||||
Button:
|
||||
text: 'clamp_to_edge'
|
||||
on_press: taw.texture_wrap = 'clamp_to_edge'
|
||||
Button:
|
||||
text: 'repeat'
|
||||
on_press: taw.texture_wrap = 'repeat'
|
||||
Button:
|
||||
text: 'mirrored_repeat'
|
||||
on_press: taw.texture_wrap = 'mirrored_repeat'
|
||||
''')
|
||||
|
||||
|
||||
runTouchApp(root)
|
BIN
kivy_venv/share/kivy-examples/canvas/texture_example_image.png
Normal file
BIN
kivy_venv/share/kivy-examples/canvas/texture_example_image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
Loading…
Add table
Add a link
Reference in a new issue