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.
77
kivy_venv/share/kivy-examples/3Drendering/main.py
Normal file
77
kivy_venv/share/kivy-examples/3Drendering/main.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
'''
|
||||
3D Rotating Monkey Head
|
||||
========================
|
||||
|
||||
This example demonstrates using OpenGL to display a rotating monkey head. This
|
||||
includes loading a Blender OBJ file, shaders written in OpenGL's Shading
|
||||
Language (GLSL), and using scheduled callbacks.
|
||||
|
||||
The monkey.obj file is an OBJ file output from the Blender free 3D creation
|
||||
software. The file is text, listing vertices and faces and is loaded
|
||||
using a class in the file objloader.py. The file simple.glsl is
|
||||
a simple vertex and fragment shader written in GLSL.
|
||||
'''
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.clock import Clock
|
||||
from kivy.core.window import Window
|
||||
from kivy.uix.widget import Widget
|
||||
from kivy.resources import resource_find
|
||||
from kivy.graphics.transformation import Matrix
|
||||
from kivy.graphics.opengl import glEnable, glDisable, GL_DEPTH_TEST
|
||||
from kivy.graphics import RenderContext, Callback, PushMatrix, PopMatrix, \
|
||||
Color, Translate, Rotate, Mesh, UpdateNormalMatrix
|
||||
from objloader import ObjFile
|
||||
|
||||
|
||||
class Renderer(Widget):
|
||||
def __init__(self, **kwargs):
|
||||
self.canvas = RenderContext(compute_normal_mat=True)
|
||||
self.canvas.shader.source = resource_find('simple.glsl')
|
||||
self.scene = ObjFile(resource_find("monkey.obj"))
|
||||
super(Renderer, self).__init__(**kwargs)
|
||||
with self.canvas:
|
||||
self.cb = Callback(self.setup_gl_context)
|
||||
PushMatrix()
|
||||
self.setup_scene()
|
||||
PopMatrix()
|
||||
self.cb = Callback(self.reset_gl_context)
|
||||
Clock.schedule_interval(self.update_glsl, 1 / 60.)
|
||||
|
||||
def setup_gl_context(self, *args):
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
|
||||
def reset_gl_context(self, *args):
|
||||
glDisable(GL_DEPTH_TEST)
|
||||
|
||||
def update_glsl(self, delta):
|
||||
asp = self.width / float(self.height)
|
||||
proj = Matrix().view_clip(-asp, asp, -1, 1, 1, 100, 1)
|
||||
self.canvas['projection_mat'] = proj
|
||||
self.canvas['diffuse_light'] = (1.0, 1.0, 0.8)
|
||||
self.canvas['ambient_light'] = (0.1, 0.1, 0.1)
|
||||
self.rot.angle += delta * 100
|
||||
|
||||
def setup_scene(self):
|
||||
Color(1, 1, 1, 1)
|
||||
PushMatrix()
|
||||
Translate(0, 0, -3)
|
||||
self.rot = Rotate(1, 0, 1, 0)
|
||||
m = list(self.scene.objects.values())[0]
|
||||
UpdateNormalMatrix()
|
||||
self.mesh = Mesh(
|
||||
vertices=m.vertices,
|
||||
indices=m.indices,
|
||||
fmt=m.vertex_format,
|
||||
mode='triangles',
|
||||
)
|
||||
PopMatrix()
|
||||
|
||||
|
||||
class RendererApp(App):
|
||||
def build(self):
|
||||
return Renderer()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
RendererApp().run()
|
7966
kivy_venv/share/kivy-examples/3Drendering/monkey.obj
Normal file
7966
kivy_venv/share/kivy-examples/3Drendering/monkey.obj
Normal file
File diff suppressed because it is too large
Load diff
147
kivy_venv/share/kivy-examples/3Drendering/objloader.py
Normal file
147
kivy_venv/share/kivy-examples/3Drendering/objloader.py
Normal file
|
@ -0,0 +1,147 @@
|
|||
class MeshData(object):
|
||||
def __init__(self, **kwargs):
|
||||
self.name = kwargs.get("name")
|
||||
self.vertex_format = [
|
||||
(b'v_pos', 3, 'float'),
|
||||
(b'v_normal', 3, 'float'),
|
||||
(b'v_tc0', 2, 'float')]
|
||||
self.vertices = []
|
||||
self.indices = []
|
||||
|
||||
def calculate_normals(self):
|
||||
for i in range(len(self.indices) / (3)):
|
||||
fi = i * 3
|
||||
v1i = self.indices[fi]
|
||||
v2i = self.indices[fi + 1]
|
||||
v3i = self.indices[fi + 2]
|
||||
|
||||
vs = self.vertices
|
||||
p1 = [vs[v1i + c] for c in range(3)]
|
||||
p2 = [vs[v2i + c] for c in range(3)]
|
||||
p3 = [vs[v3i + c] for c in range(3)]
|
||||
|
||||
u, v = [0, 0, 0], [0, 0, 0]
|
||||
for j in range(3):
|
||||
v[j] = p2[j] - p1[j]
|
||||
u[j] = p3[j] - p1[j]
|
||||
|
||||
n = [0, 0, 0]
|
||||
n[0] = u[1] * v[2] - u[2] * v[1]
|
||||
n[1] = u[2] * v[0] - u[0] * v[2]
|
||||
n[2] = u[0] * v[1] - u[1] * v[0]
|
||||
|
||||
for k in range(3):
|
||||
self.vertices[v1i + 3 + k] = n[k]
|
||||
self.vertices[v2i + 3 + k] = n[k]
|
||||
self.vertices[v3i + 3 + k] = n[k]
|
||||
|
||||
|
||||
class ObjFile:
|
||||
def finish_object(self):
|
||||
if self._current_object is None:
|
||||
return
|
||||
|
||||
mesh = MeshData()
|
||||
idx = 0
|
||||
for f in self.faces:
|
||||
verts = f[0]
|
||||
norms = f[1]
|
||||
tcs = f[2]
|
||||
for i in range(3):
|
||||
# get normal components
|
||||
n = (0.0, 0.0, 0.0)
|
||||
if norms[i] != -1:
|
||||
n = self.normals[norms[i] - 1]
|
||||
|
||||
# get texture coordinate components
|
||||
t = (0.0, 0.0)
|
||||
if tcs[i] != -1:
|
||||
t = self.texcoords[tcs[i] - 1]
|
||||
|
||||
# get vertex components
|
||||
v = self.vertices[verts[i] - 1]
|
||||
|
||||
data = [v[0], v[1], v[2], n[0], n[1], n[2], t[0], t[1]]
|
||||
mesh.vertices.extend(data)
|
||||
|
||||
tri = [idx, idx + 1, idx + 2]
|
||||
mesh.indices.extend(tri)
|
||||
idx += 3
|
||||
|
||||
self.objects[self._current_object] = mesh
|
||||
# mesh.calculate_normals()
|
||||
self.faces = []
|
||||
|
||||
def __init__(self, filename, swapyz=False):
|
||||
"""Loads a Wavefront OBJ file. """
|
||||
self.objects = {}
|
||||
self.vertices = []
|
||||
self.normals = []
|
||||
self.texcoords = []
|
||||
self.faces = []
|
||||
|
||||
self._current_object = None
|
||||
|
||||
material = None
|
||||
for line in open(filename, "r"):
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
if line.startswith('s'):
|
||||
continue
|
||||
values = line.split()
|
||||
if not values:
|
||||
continue
|
||||
if values[0] == 'o':
|
||||
self.finish_object()
|
||||
self._current_object = values[1]
|
||||
# elif values[0] == 'mtllib':
|
||||
# self.mtl = MTL(values[1])
|
||||
# elif values[0] in ('usemtl', 'usemat'):
|
||||
# material = values[1]
|
||||
if values[0] == 'v':
|
||||
v = list(map(float, values[1:4]))
|
||||
if swapyz:
|
||||
v = v[0], v[2], v[1]
|
||||
self.vertices.append(v)
|
||||
elif values[0] == 'vn':
|
||||
v = list(map(float, values[1:4]))
|
||||
if swapyz:
|
||||
v = v[0], v[2], v[1]
|
||||
self.normals.append(v)
|
||||
elif values[0] == 'vt':
|
||||
self.texcoords.append(list(map(float, values[1:3])))
|
||||
elif values[0] == 'f':
|
||||
face = []
|
||||
texcoords = []
|
||||
norms = []
|
||||
for v in values[1:]:
|
||||
w = v.split('/')
|
||||
face.append(int(w[0]))
|
||||
if len(w) >= 2 and len(w[1]) > 0:
|
||||
texcoords.append(int(w[1]))
|
||||
else:
|
||||
texcoords.append(-1)
|
||||
if len(w) >= 3 and len(w[2]) > 0:
|
||||
norms.append(int(w[2]))
|
||||
else:
|
||||
norms.append(-1)
|
||||
self.faces.append((face, norms, texcoords, material))
|
||||
self.finish_object()
|
||||
|
||||
|
||||
def MTL(filename):
|
||||
contents = {}
|
||||
mtl = None
|
||||
return
|
||||
for line in open(filename, "r"):
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
values = line.split()
|
||||
if not values:
|
||||
continue
|
||||
if values[0] == 'newmtl':
|
||||
mtl = contents[values[1]] = {}
|
||||
elif mtl is None:
|
||||
raise ValueError("mtl file doesn't start with newmtl stmt")
|
||||
mtl[values[0]] = values[1:]
|
||||
return contents
|
47
kivy_venv/share/kivy-examples/3Drendering/simple.glsl
Normal file
47
kivy_venv/share/kivy-examples/3Drendering/simple.glsl
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* simple.glsl
|
||||
|
||||
simple diffuse lighting based on laberts cosine law; see e.g.:
|
||||
http://en.wikipedia.org/wiki/Lambertian_reflectance
|
||||
http://en.wikipedia.org/wiki/Lambert%27s_cosine_law
|
||||
*/
|
||||
---VERTEX SHADER-------------------------------------------------------
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
attribute vec3 v_pos;
|
||||
attribute vec3 v_normal;
|
||||
|
||||
uniform mat4 modelview_mat;
|
||||
uniform mat4 projection_mat;
|
||||
|
||||
varying vec4 normal_vec;
|
||||
varying vec4 vertex_pos;
|
||||
|
||||
void main (void) {
|
||||
//compute vertex position in eye_space and normalize normal vector
|
||||
vec4 pos = modelview_mat * vec4(v_pos,1.0);
|
||||
vertex_pos = pos;
|
||||
normal_vec = vec4(v_normal,0.0);
|
||||
gl_Position = projection_mat * pos;
|
||||
}
|
||||
|
||||
|
||||
---FRAGMENT SHADER-----------------------------------------------------
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
varying vec4 normal_vec;
|
||||
varying vec4 vertex_pos;
|
||||
|
||||
uniform mat4 normal_mat;
|
||||
|
||||
void main (void){
|
||||
//correct normal, and compute light vector (assume light at the eye)
|
||||
vec4 v_normal = normalize( normal_mat * normal_vec ) ;
|
||||
vec4 v_light = normalize( vec4(0,0,0,1) - vertex_pos );
|
||||
//reflectance based on lamberts law of cosine
|
||||
float theta = clamp(dot(v_normal, v_light), 0.0, 1.0);
|
||||
gl_FragColor = vec4(theta, theta, theta, 1.0);
|
||||
}
|
Binary file not shown.
72
kivy_venv/share/kivy-examples/RST_Editor/editor.kv
Normal file
72
kivy_venv/share/kivy-examples/RST_Editor/editor.kv
Normal file
|
@ -0,0 +1,72 @@
|
|||
#:kivy 1.1.0
|
||||
|
||||
Root:
|
||||
text_input: text_input
|
||||
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: 30
|
||||
Button:
|
||||
text: 'Load'
|
||||
on_release: root.show_load()
|
||||
Button:
|
||||
text: 'Save'
|
||||
on_release: root.show_save()
|
||||
|
||||
BoxLayout:
|
||||
TextInput:
|
||||
id: text_input
|
||||
text: ''
|
||||
|
||||
RstDocument:
|
||||
text: text_input.text
|
||||
show_errors: True
|
||||
|
||||
<LoadDialog>:
|
||||
BoxLayout:
|
||||
size: root.size
|
||||
pos: root.pos
|
||||
orientation: "vertical"
|
||||
FileChooserListView:
|
||||
id: filechooser
|
||||
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: 30
|
||||
Button:
|
||||
text: "Cancel"
|
||||
on_release: root.cancel()
|
||||
|
||||
Button:
|
||||
text: "Load"
|
||||
on_release: root.load(filechooser.path, filechooser.selection)
|
||||
|
||||
<SaveDialog>:
|
||||
text_input: text_input
|
||||
BoxLayout:
|
||||
size: root.size
|
||||
pos: root.pos
|
||||
orientation: "vertical"
|
||||
FileChooserListView:
|
||||
id: filechooser
|
||||
on_selection: text_input.text = self.selection and self.selection[0] or ''
|
||||
|
||||
TextInput:
|
||||
id: text_input
|
||||
size_hint_y: None
|
||||
height: 30
|
||||
multiline: False
|
||||
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: 30
|
||||
Button:
|
||||
text: "Cancel"
|
||||
on_release: root.cancel()
|
||||
|
||||
Button:
|
||||
text: "Save"
|
||||
on_release: root.save(filechooser.path, text_input.text)
|
||||
|
64
kivy_venv/share/kivy-examples/RST_Editor/main.py
Normal file
64
kivy_venv/share/kivy-examples/RST_Editor/main.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
from kivy.app import App
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.factory import Factory
|
||||
from kivy.properties import ObjectProperty
|
||||
from kivy.uix.popup import Popup
|
||||
|
||||
import os
|
||||
|
||||
|
||||
class LoadDialog(FloatLayout):
|
||||
load = ObjectProperty(None)
|
||||
cancel = ObjectProperty(None)
|
||||
|
||||
|
||||
class SaveDialog(FloatLayout):
|
||||
save = ObjectProperty(None)
|
||||
text_input = ObjectProperty(None)
|
||||
cancel = ObjectProperty(None)
|
||||
|
||||
|
||||
class Root(FloatLayout):
|
||||
loadfile = ObjectProperty(None)
|
||||
savefile = ObjectProperty(None)
|
||||
text_input = ObjectProperty(None)
|
||||
|
||||
def dismiss_popup(self):
|
||||
self._popup.dismiss()
|
||||
|
||||
def show_load(self):
|
||||
content = LoadDialog(load=self.load, cancel=self.dismiss_popup)
|
||||
self._popup = Popup(title="Load file", content=content,
|
||||
size_hint=(0.9, 0.9))
|
||||
self._popup.open()
|
||||
|
||||
def show_save(self):
|
||||
content = SaveDialog(save=self.save, cancel=self.dismiss_popup)
|
||||
self._popup = Popup(title="Save file", content=content,
|
||||
size_hint=(0.9, 0.9))
|
||||
self._popup.open()
|
||||
|
||||
def load(self, path, filename):
|
||||
with open(os.path.join(path, filename[0])) as stream:
|
||||
self.text_input.text = stream.read()
|
||||
|
||||
self.dismiss_popup()
|
||||
|
||||
def save(self, path, filename):
|
||||
with open(os.path.join(path, filename), 'w') as stream:
|
||||
stream.write(self.text_input.text)
|
||||
|
||||
self.dismiss_popup()
|
||||
|
||||
|
||||
class Editor(App):
|
||||
pass
|
||||
|
||||
|
||||
Factory.register('Root', cls=Root)
|
||||
Factory.register('LoadDialog', cls=LoadDialog)
|
||||
Factory.register('SaveDialog', cls=SaveDialog)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
Editor().run()
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
title=Compass
|
||||
author=Nik Klever
|
||||
orientation=portrait
|
25
kivy_venv/share/kivy-examples/android/compass/compass.kv
Normal file
25
kivy_venv/share/kivy-examples/android/compass/compass.kv
Normal file
|
@ -0,0 +1,25 @@
|
|||
#:kivy 1.7.0
|
||||
|
||||
FloatLayout:
|
||||
|
||||
canvas:
|
||||
Color:
|
||||
rgb: .98, .98, .98
|
||||
Rectangle:
|
||||
size: self.size
|
||||
|
||||
Image:
|
||||
source: 'rose.png'
|
||||
|
||||
Image:
|
||||
source: 'needle.png'
|
||||
|
||||
canvas.before:
|
||||
PushMatrix
|
||||
Rotate:
|
||||
angle: app.needle_angle
|
||||
axis: 0, 0, 1
|
||||
origin: self.center
|
||||
|
||||
canvas.after:
|
||||
PopMatrix
|
77
kivy_venv/share/kivy-examples/android/compass/main.py
Normal file
77
kivy_venv/share/kivy-examples/android/compass/main.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
'''
|
||||
Compass example
|
||||
===============
|
||||
|
||||
This example is a demonstration of Hardware class usage.
|
||||
But it has severals drawbacks, like using only the magnetic sensor, and
|
||||
extrapolating values to get the orientation. The compass is absolutely not
|
||||
accurate.
|
||||
|
||||
The right way would be to get the accelerometer + magnetic, and computer
|
||||
everything according to the phone orientation. This is not the purpose of this
|
||||
example right now.
|
||||
|
||||
You can compile it with::
|
||||
|
||||
./build.py --package org.test.compass --name compass \
|
||||
--private ~/code/kivy/examples/android/compass \
|
||||
--window --version 1.0 debug installd
|
||||
'''
|
||||
|
||||
|
||||
import kivy
|
||||
kivy.require('1.7.0')
|
||||
|
||||
from jnius import autoclass
|
||||
from math import floor
|
||||
from kivy.app import App
|
||||
from kivy.properties import NumericProperty
|
||||
from kivy.clock import Clock
|
||||
from kivy.vector import Vector
|
||||
from kivy.animation import Animation
|
||||
|
||||
Hardware = autoclass('org.renpy.android.Hardware')
|
||||
|
||||
|
||||
class CompassApp(App):
|
||||
|
||||
needle_angle = NumericProperty(0)
|
||||
|
||||
def build(self):
|
||||
self._anim = None
|
||||
Hardware.magneticFieldSensorEnable(True)
|
||||
Clock.schedule_interval(self.update_compass, 1 / 10.)
|
||||
|
||||
def update_compass(self, *args):
|
||||
# read the magnetic sensor from the Hardware class
|
||||
(x, y, z) = Hardware.magneticFieldSensorReading()
|
||||
|
||||
# calculate the angle
|
||||
needle_angle = Vector(x, y).angle((0, 1)) + 90.
|
||||
|
||||
# fix animation transition around the unit circle
|
||||
if (self.needle_angle % 360) - needle_angle > 180:
|
||||
needle_angle += 360
|
||||
elif (self.needle_angle % 360) - needle_angle < -180:
|
||||
needle_angle -= 360
|
||||
# add the number of revolutions to the result
|
||||
needle_angle += 360 * floor(self.needle_angle / 360.)
|
||||
|
||||
# animate the needle
|
||||
if self._anim:
|
||||
self._anim.stop(self)
|
||||
self._anim = Animation(needle_angle=needle_angle, d=.2, t='out_quad')
|
||||
self._anim.start(self)
|
||||
|
||||
def on_pause(self):
|
||||
# when you are going on pause, don't forget to stop the sensor
|
||||
Hardware.magneticFieldSensorEnable(False)
|
||||
return True
|
||||
|
||||
def on_resume(self):
|
||||
# reactivate the sensor when you are back to the app
|
||||
Hardware.magneticFieldSensorEnable(True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CompassApp().run()
|
BIN
kivy_venv/share/kivy-examples/android/compass/needle.png
Normal file
BIN
kivy_venv/share/kivy-examples/android/compass/needle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
BIN
kivy_venv/share/kivy-examples/android/compass/rose.png
Normal file
BIN
kivy_venv/share/kivy-examples/android/compass/rose.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
title=TakePicture
|
||||
author=Mathieu Virbel
|
||||
orientation=portrait
|
80
kivy_venv/share/kivy-examples/android/takepicture/main.py
Normal file
80
kivy_venv/share/kivy-examples/android/takepicture/main.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
'''
|
||||
Take picture
|
||||
============
|
||||
|
||||
.. author:: Mathieu Virbel <mat@kivy.org>
|
||||
|
||||
Little example to demonstrate how to start an Intent, and get the result.
|
||||
When you use the Android.startActivityForResult(), the result will be
|
||||
dispatched into onActivityResult. You can catch the event with the
|
||||
android.activity API from python-for-android project.
|
||||
|
||||
If you want to compile it, don't forget to add the CAMERA permission::
|
||||
|
||||
./build.py --name 'TakePicture' --package org.test.takepicture \
|
||||
--permission CAMERA --version 1 \
|
||||
--private ~/code/kivy/examples/android/takepicture \
|
||||
debug installd
|
||||
|
||||
'''
|
||||
|
||||
__version__ = '0.1'
|
||||
|
||||
from kivy.app import App
|
||||
from os.path import exists
|
||||
from jnius import autoclass, cast
|
||||
from android import activity, mActivity
|
||||
from functools import partial
|
||||
from kivy.clock import Clock
|
||||
from kivy.uix.scatter import Scatter
|
||||
from kivy.properties import StringProperty
|
||||
|
||||
from PIL import Image
|
||||
|
||||
Intent = autoclass('android.content.Intent')
|
||||
MediaStore = autoclass('android.provider.MediaStore')
|
||||
Uri = autoclass('android.net.Uri')
|
||||
Environment = autoclass('android.os.Environment')
|
||||
|
||||
|
||||
class Picture(Scatter):
|
||||
source = StringProperty(None)
|
||||
|
||||
|
||||
class TakePictureApp(App):
|
||||
def build(self):
|
||||
self.index = 0
|
||||
activity.bind(on_activity_result=self.on_activity_result)
|
||||
|
||||
def get_filename(self):
|
||||
while True:
|
||||
self.index += 1
|
||||
fn = (Environment.getExternalStorageDirectory().getPath() +
|
||||
'/takepicture{}.jpg'.format(self.index))
|
||||
if not exists(fn):
|
||||
return fn
|
||||
|
||||
def take_picture(self):
|
||||
intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
|
||||
self.last_fn = self.get_filename()
|
||||
self.uri = Uri.parse('file://' + self.last_fn)
|
||||
self.uri = cast('android.os.Parcelable', self.uri)
|
||||
intent.putExtra(MediaStore.EXTRA_OUTPUT, self.uri)
|
||||
mActivity.startActivityForResult(intent, 0x123)
|
||||
|
||||
def on_activity_result(self, requestCode, resultCode, intent):
|
||||
if requestCode == 0x123:
|
||||
Clock.schedule_once(partial(self.add_picture, self.last_fn), 0)
|
||||
|
||||
def add_picture(self, fn, *args):
|
||||
im = Image.open(fn)
|
||||
width, height = im.size
|
||||
im.thumbnail((width / 4, height / 4), Image.ANTIALIAS)
|
||||
im.save(fn, quality=95)
|
||||
self.root.add_widget(Picture(source=fn, center=self.root.center))
|
||||
|
||||
def on_pause(self):
|
||||
return True
|
||||
|
||||
|
||||
TakePictureApp().run()
|
BIN
kivy_venv/share/kivy-examples/android/takepicture/shadow32.png
Normal file
BIN
kivy_venv/share/kivy-examples/android/takepicture/shadow32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
|
@ -0,0 +1,40 @@
|
|||
#:kivy 1.0
|
||||
#:import win kivy.core.window
|
||||
|
||||
Widget:
|
||||
canvas:
|
||||
Color:
|
||||
rgb: .85, .87, .88
|
||||
Rectangle:
|
||||
size: self.size
|
||||
|
||||
Button:
|
||||
text: 'Take a picture'
|
||||
width: self.texture_size[0] + dp(40)
|
||||
height: '48dp'
|
||||
on_release: app.take_picture()
|
||||
|
||||
<Picture>:
|
||||
on_size: self.center = win.Window.center
|
||||
size: image.size
|
||||
size_hint: None, None
|
||||
|
||||
Image:
|
||||
id: image
|
||||
source: root.source
|
||||
|
||||
# create initial image to be 400 pixels width
|
||||
size: 400, 400
|
||||
|
||||
# add shadow background
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: 1, 1, 1, 1
|
||||
BorderImage:
|
||||
source: 'shadow32.png'
|
||||
border: (36, 36, 36, 36)
|
||||
size:(self.width + 72, self.height + 72)
|
||||
pos: (-36, -36)
|
||||
|
||||
|
||||
|
Binary file not shown.
42
kivy_venv/share/kivy-examples/animation/animate.py
Normal file
42
kivy_venv/share/kivy-examples/animation/animate.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
'''
|
||||
Widget animation
|
||||
================
|
||||
|
||||
This example demonstrates creating and applying a multi-part animation to
|
||||
a button widget. You should see a button labelled 'plop' that will move with
|
||||
an animation when clicked.
|
||||
'''
|
||||
|
||||
import kivy
|
||||
kivy.require('1.0.7')
|
||||
|
||||
from kivy.animation import Animation
|
||||
from kivy.app import App
|
||||
from kivy.uix.button import Button
|
||||
|
||||
|
||||
class TestApp(App):
|
||||
|
||||
def animate(self, instance):
|
||||
# create an animation object. This object could be stored
|
||||
# and reused each call or reused across different widgets.
|
||||
# += is a sequential step, while &= is in parallel
|
||||
animation = Animation(pos=(100, 100), t='out_bounce')
|
||||
animation += Animation(pos=(200, 100), t='out_bounce')
|
||||
animation &= Animation(size=(500, 500))
|
||||
animation += Animation(size=(100, 50))
|
||||
|
||||
# apply the animation on the button, passed in the "instance" argument
|
||||
# Notice that default 'click' animation (changing the button
|
||||
# color while the mouse is down) is unchanged.
|
||||
animation.start(instance)
|
||||
|
||||
def build(self):
|
||||
# create a button, and attach animate() method as a on_press handler
|
||||
button = Button(size_hint=(None, None), text='plop',
|
||||
on_press=self.animate)
|
||||
return button
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
TestApp().run()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
152
kivy_venv/share/kivy-examples/application/app_suite.py
Normal file
152
kivy_venv/share/kivy-examples/application/app_suite.py
Normal file
|
@ -0,0 +1,152 @@
|
|||
'''
|
||||
Suite of Application Builders
|
||||
=============================
|
||||
|
||||
This explores different methods of starting an application. If you run
|
||||
this without a command line parameter, you should see a menu in your terminal.
|
||||
You can also run this with a 'r' parameter to pick a random method.
|
||||
There are lots of logging options to make this easier to debug: the execution
|
||||
order may not be obvious. Each time you run the command, only one kivy
|
||||
application is created.
|
||||
|
||||
This uses the file testkvfile.kv and the file app_suite_data/testkvdir.kv.
|
||||
|
||||
'''
|
||||
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
import re
|
||||
from random import choice
|
||||
|
||||
import kivy
|
||||
kivy.require('1.8.0') # 1.8 is when kv_directory became part of app.
|
||||
from kivy.app import App
|
||||
from kivy.uix.button import Button
|
||||
from kivy.lang import Builder
|
||||
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
# Note that importing FloatLayout causes Kivy to execute, including
|
||||
# starting up the Logger and some other messages.
|
||||
print("** In main program, done with imports")
|
||||
|
||||
|
||||
class TestBuildApp(App):
|
||||
""" Use build() function to return a widget. """
|
||||
def build(self):
|
||||
""" Build called by kivy when an App is started.
|
||||
Called after trying to load a .kv file.
|
||||
Returns a new Button as a root widget.
|
||||
"""
|
||||
print("** inside build()")
|
||||
return Button(text='hello from TestBuildApp')
|
||||
|
||||
|
||||
class TestKVFileApp(App):
|
||||
"""
|
||||
Empty class, but name used to find .kv file. The filename is the lowercase
|
||||
version of the class, i.e. 'testkvfileapp.kv'. If not found, it strips
|
||||
off the final 'app', i.e. 'testkvfile.kv'. If not file is found, and no
|
||||
other method sets the self.root, the program will run with an empty screen.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class TestKVDirApp(App):
|
||||
"""
|
||||
Empty class except for setting class variable kv_directory.
|
||||
This directory sets the directory in which to search for the .kv file.
|
||||
The name of the kv file is still governed by the class name and the .kv
|
||||
file should still have one root widget.
|
||||
"""
|
||||
kv_directory = 'app_suite_data'
|
||||
|
||||
|
||||
class TestKVStringApp(App):
|
||||
"""
|
||||
Use a build() function and use the kivy.lang.Builder function to parse up a
|
||||
Kivy language string.
|
||||
"""
|
||||
def build(self):
|
||||
""" Called by kivy run(). """
|
||||
print("** inside build()")
|
||||
widget = Builder.load_string(
|
||||
"Button:\n text: 'hello from TestKVStringApp'")
|
||||
print("** widget built")
|
||||
return widget
|
||||
|
||||
|
||||
class TestPrebuiltApp(App):
|
||||
""" Use the Builder to create a top level widget at the beginning
|
||||
of the Python program, then use a dummy class for that widget.
|
||||
This costs a bit more in start-up time. """
|
||||
kv = "<Prebuilt>\n Button:\n text:'hello from TestPrebuiltApp'"
|
||||
Builder.load_string(kv)
|
||||
print("** in TestPrebuiltApp, class initialization built <Prebuilt>")
|
||||
|
||||
class Prebuilt(FloatLayout):
|
||||
""" Empty class to cause setting root to <Prebuilt> tag and
|
||||
set inheritance """
|
||||
pass
|
||||
|
||||
def build(self):
|
||||
""" called, returns instance matching tag . """
|
||||
return self.Prebuilt()
|
||||
|
||||
|
||||
def print_class(class_name):
|
||||
""" Read this file and print the section with the class name specified.)"""
|
||||
filename = sys.argv[0]
|
||||
with open(filename) as f:
|
||||
data = f.read()
|
||||
regex = "^(class " + class_name + "\\b.*?)^\\S"
|
||||
match = re.search(regex, data, flags=re.MULTILINE | re.DOTALL)
|
||||
if match:
|
||||
print(match.group(1))
|
||||
|
||||
|
||||
# the __name__ idiom executes when run from command line but not from import.
|
||||
if __name__ == '__main__':
|
||||
dash = "-" * 40
|
||||
|
||||
arg = sys.argv[1][0].lower() if len(sys.argv) > 1 else "h"
|
||||
print(dash)
|
||||
|
||||
if arg == 'r':
|
||||
arg = choice('bfds')
|
||||
|
||||
if arg == 'b':
|
||||
print_class("TestBuildApp")
|
||||
TestBuildApp().run()
|
||||
elif arg == 'f':
|
||||
print_class("TestKVFileApp")
|
||||
TestKVFileApp().run()
|
||||
elif arg == 'd':
|
||||
print_class("TestKVDirApp")
|
||||
TestKVDirApp().run()
|
||||
elif arg == 's':
|
||||
print_class("TestKVStringApp")
|
||||
TestKVStringApp().run()
|
||||
elif arg == 'p':
|
||||
print_class("TestPrebuiltApp")
|
||||
TestPrebuiltApp().run()
|
||||
else: # help
|
||||
print("""
|
||||
This demo runs different application windows based on a command line argument.
|
||||
|
||||
Try using one of these:
|
||||
b - Use build() method to return a widget
|
||||
d - Use a kv file from a different directory
|
||||
f - Use a kv file with the widget object
|
||||
p - Use prebuilt widget inside a layout
|
||||
s - Use a kivy language string to create the widget
|
||||
r - pick one of the options at random.
|
||||
|
||||
h - show this help message.
|
||||
|
||||
After closing the application window, this program will exit.
|
||||
While the run() method does return, kivy cannot run another
|
||||
application window after one has been closed.
|
||||
""")
|
||||
|
||||
print(dash)
|
||||
print("This program is gratified to be of use.")
|
|
@ -0,0 +1,4 @@
|
|||
#:kivy 1.0
|
||||
|
||||
Button:
|
||||
text: 'Hello from app_suite_data/testkvdir.kv'
|
24
kivy_venv/share/kivy-examples/application/app_with_build.py
Normal file
24
kivy_venv/share/kivy-examples/application/app_with_build.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
'''
|
||||
Application example using build() + return
|
||||
==========================================
|
||||
|
||||
An application can be built if you return a widget on build(), or if you set
|
||||
self.root.
|
||||
'''
|
||||
|
||||
import kivy
|
||||
kivy.require('1.0.7')
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.button import Button
|
||||
|
||||
|
||||
class TestApp(App):
|
||||
|
||||
def build(self):
|
||||
# return a Button() as a root widget
|
||||
return Button(text='hello world')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
TestApp().run()
|
49
kivy_venv/share/kivy-examples/application/app_with_config.py
Normal file
49
kivy_venv/share/kivy-examples/application/app_with_config.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
from kivy.properties import ConfigParserProperty
|
||||
|
||||
KV = '''
|
||||
FloatLayout:
|
||||
BoxLayout:
|
||||
size_hint: .5, .5
|
||||
pos_hint: {'center': (.5, .5)}
|
||||
|
||||
orientation: 'vertical'
|
||||
|
||||
TextInput:
|
||||
text: app.text
|
||||
on_text: app.text = self.text
|
||||
|
||||
Slider:
|
||||
min: 0
|
||||
max: 100
|
||||
value: app.number
|
||||
on_value: app.number = self.value
|
||||
'''
|
||||
|
||||
|
||||
class ConfigApp(App):
|
||||
number = ConfigParserProperty(
|
||||
0, 'general', 'number',
|
||||
'app', val_type=float
|
||||
)
|
||||
text = ConfigParserProperty(
|
||||
'', 'general', 'text',
|
||||
'app', val_type=str
|
||||
)
|
||||
|
||||
def build_config(self, config):
|
||||
config.setdefaults(
|
||||
'general',
|
||||
{
|
||||
'number': 0,
|
||||
'text': 'test'
|
||||
}
|
||||
)
|
||||
|
||||
def build(self):
|
||||
return Builder.load_string(KV)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ConfigApp().run()
|
25
kivy_venv/share/kivy-examples/application/app_with_kv.py
Normal file
25
kivy_venv/share/kivy-examples/application/app_with_kv.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
'''
|
||||
Application built from a .kv file
|
||||
==================================
|
||||
|
||||
This shows how to implicitly use a .kv file for your application. You
|
||||
should see a full screen button labelled "Hello from test.kv".
|
||||
|
||||
After Kivy instantiates a subclass of App, it implicitly searches for a .kv
|
||||
file. The file test.kv is selected because the name of the subclass of App is
|
||||
TestApp, which implies that kivy should try to load "test.kv". That file
|
||||
contains a root Widget.
|
||||
'''
|
||||
|
||||
import kivy
|
||||
kivy.require('1.0.7')
|
||||
|
||||
from kivy.app import App
|
||||
|
||||
|
||||
class TestApp(App):
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
TestApp().run()
|
|
@ -0,0 +1,27 @@
|
|||
'''
|
||||
Application from a .kv in a Template Directory
|
||||
==============================================
|
||||
|
||||
This example shows how you can change the directory for the .kv file. You
|
||||
should see "Hello from template1/test.ky" as a button.
|
||||
|
||||
As kivy instantiates the TestApp subclass of App, the variable kv_directory
|
||||
is set. Kivy then implicitly searches for a .kv file matching the name
|
||||
of the subclass in that directory, finding the file template1/test.kv. That
|
||||
file contains the root widget.
|
||||
|
||||
|
||||
'''
|
||||
|
||||
import kivy
|
||||
kivy.require('1.0.7')
|
||||
|
||||
from kivy.app import App
|
||||
|
||||
|
||||
class TestApp(App):
|
||||
kv_directory = 'template1'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
TestApp().run()
|
|
@ -0,0 +1,4 @@
|
|||
#:kivy 1.0
|
||||
|
||||
Button:
|
||||
text: 'Hello from template1/test.kv'
|
4
kivy_venv/share/kivy-examples/application/test.kv
Normal file
4
kivy_venv/share/kivy-examples/application/test.kv
Normal file
|
@ -0,0 +1,4 @@
|
|||
#:kivy 1.0
|
||||
|
||||
Button:
|
||||
text: 'Hello from test.kv'
|
4
kivy_venv/share/kivy-examples/application/testkvfile.kv
Normal file
4
kivy_venv/share/kivy-examples/application/testkvfile.kv
Normal file
|
@ -0,0 +1,4 @@
|
|||
#:kivy 1.0
|
||||
|
||||
Button:
|
||||
text: 'Hello from testkvfile.kv'
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
90
kivy_venv/share/kivy-examples/async/asyncio_advanced.py
Normal file
90
kivy_venv/share/kivy-examples/async/asyncio_advanced.py
Normal file
|
@ -0,0 +1,90 @@
|
|||
'''Example shows the recommended way of how to run Kivy with the Python built
|
||||
in asyncio event loop as just another async coroutine.
|
||||
'''
|
||||
import asyncio
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.lang.builder import Builder
|
||||
|
||||
kv = '''
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
BoxLayout:
|
||||
ToggleButton:
|
||||
id: btn1
|
||||
group: 'a'
|
||||
text: 'Sleeping'
|
||||
allow_no_selection: False
|
||||
on_state: if self.state == 'down': label.status = self.text
|
||||
ToggleButton:
|
||||
id: btn2
|
||||
group: 'a'
|
||||
text: 'Swimming'
|
||||
allow_no_selection: False
|
||||
on_state: if self.state == 'down': label.status = self.text
|
||||
ToggleButton:
|
||||
id: btn3
|
||||
group: 'a'
|
||||
text: 'Reading'
|
||||
allow_no_selection: False
|
||||
state: 'down'
|
||||
on_state: if self.state == 'down': label.status = self.text
|
||||
Label:
|
||||
id: label
|
||||
status: 'Reading'
|
||||
text: 'Beach status is "{}"'.format(self.status)
|
||||
'''
|
||||
|
||||
|
||||
class AsyncApp(App):
|
||||
|
||||
other_task = None
|
||||
|
||||
def build(self):
|
||||
return Builder.load_string(kv)
|
||||
|
||||
def app_func(self):
|
||||
'''This will run both methods asynchronously and then block until they
|
||||
are finished
|
||||
'''
|
||||
self.other_task = asyncio.ensure_future(self.waste_time_freely())
|
||||
|
||||
async def run_wrapper():
|
||||
# we don't actually need to set asyncio as the lib because it is
|
||||
# the default, but it doesn't hurt to be explicit
|
||||
await self.async_run(async_lib='asyncio')
|
||||
print('App done')
|
||||
self.other_task.cancel()
|
||||
|
||||
return asyncio.gather(run_wrapper(), self.other_task)
|
||||
|
||||
async def waste_time_freely(self):
|
||||
'''This method is also run by the asyncio loop and periodically prints
|
||||
something.
|
||||
'''
|
||||
try:
|
||||
i = 0
|
||||
while True:
|
||||
if self.root is not None:
|
||||
status = self.root.ids.label.status
|
||||
print('{} on the beach'.format(status))
|
||||
|
||||
# get some sleep
|
||||
if self.root.ids.btn1.state != 'down' and i >= 2:
|
||||
i = 0
|
||||
print('Yawn, getting tired. Going to sleep')
|
||||
self.root.ids.btn1.trigger_action()
|
||||
|
||||
i += 1
|
||||
await asyncio.sleep(2)
|
||||
except asyncio.CancelledError as e:
|
||||
print('Wasting time was canceled', e)
|
||||
finally:
|
||||
# when canceled, print that it finished
|
||||
print('Done wasting time')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(AsyncApp().app_func())
|
||||
loop.close()
|
59
kivy_venv/share/kivy-examples/async/asyncio_basic.py
Normal file
59
kivy_venv/share/kivy-examples/async/asyncio_basic.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
'''Example shows the recommended way of how to run Kivy with the Python built
|
||||
in asyncio event loop as just another async coroutine.
|
||||
'''
|
||||
import asyncio
|
||||
|
||||
from kivy.app import async_runTouchApp
|
||||
from kivy.lang.builder import Builder
|
||||
|
||||
kv = '''
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Button:
|
||||
id: btn
|
||||
text: 'Press me'
|
||||
BoxLayout:
|
||||
Label:
|
||||
id: label
|
||||
text: 'Button is "{}"'.format(btn.state)
|
||||
'''
|
||||
|
||||
|
||||
async def run_app_happily(root, other_task):
|
||||
'''This method, which runs Kivy, is run by the asyncio loop as one of the
|
||||
coroutines.
|
||||
'''
|
||||
# we don't actually need to set asyncio as the lib because it is the
|
||||
# default, but it doesn't hurt to be explicit
|
||||
await async_runTouchApp(root, async_lib='asyncio') # run Kivy
|
||||
print('App done')
|
||||
# now cancel all the other tasks that may be running
|
||||
other_task.cancel()
|
||||
|
||||
|
||||
async def waste_time_freely():
|
||||
'''This method is also run by the asyncio loop and periodically prints
|
||||
something.
|
||||
'''
|
||||
try:
|
||||
while True:
|
||||
print('Sitting on the beach')
|
||||
await asyncio.sleep(2)
|
||||
except asyncio.CancelledError as e:
|
||||
print('Wasting time was canceled', e)
|
||||
finally:
|
||||
# when canceled, print that it finished
|
||||
print('Done wasting time')
|
||||
|
||||
if __name__ == '__main__':
|
||||
def root_func():
|
||||
'''This will run both methods asynchronously and then block until they
|
||||
are finished
|
||||
'''
|
||||
root = Builder.load_string(kv) # root widget
|
||||
other_task = asyncio.ensure_future(waste_time_freely())
|
||||
return asyncio.gather(run_app_happily(root, other_task), other_task)
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(root_func())
|
||||
loop.close()
|
93
kivy_venv/share/kivy-examples/async/trio_advanced.py
Normal file
93
kivy_venv/share/kivy-examples/async/trio_advanced.py
Normal file
|
@ -0,0 +1,93 @@
|
|||
'''Example shows the recommended way of how to run Kivy with a trio
|
||||
event loop as just another async coroutine.
|
||||
'''
|
||||
import trio
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.lang.builder import Builder
|
||||
|
||||
kv = '''
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
BoxLayout:
|
||||
ToggleButton:
|
||||
id: btn1
|
||||
group: 'a'
|
||||
text: 'Sleeping'
|
||||
allow_no_selection: False
|
||||
on_state: if self.state == 'down': label.status = self.text
|
||||
ToggleButton:
|
||||
id: btn2
|
||||
group: 'a'
|
||||
text: 'Swimming'
|
||||
allow_no_selection: False
|
||||
on_state: if self.state == 'down': label.status = self.text
|
||||
ToggleButton:
|
||||
id: btn3
|
||||
group: 'a'
|
||||
text: 'Reading'
|
||||
allow_no_selection: False
|
||||
state: 'down'
|
||||
on_state: if self.state == 'down': label.status = self.text
|
||||
Label:
|
||||
id: label
|
||||
status: 'Reading'
|
||||
text: 'Beach status is "{}"'.format(self.status)
|
||||
'''
|
||||
|
||||
|
||||
class AsyncApp(App):
|
||||
|
||||
nursery = None
|
||||
|
||||
def build(self):
|
||||
return Builder.load_string(kv)
|
||||
|
||||
async def app_func(self):
|
||||
'''trio needs to run a function, so this is it. '''
|
||||
|
||||
async with trio.open_nursery() as nursery:
|
||||
'''In trio you create a nursery, in which you schedule async
|
||||
functions to be run by the nursery simultaneously as tasks.
|
||||
|
||||
This will run all two methods starting in random order
|
||||
asynchronously and then block until they are finished or canceled
|
||||
at the `with` level. '''
|
||||
self.nursery = nursery
|
||||
|
||||
async def run_wrapper():
|
||||
# trio needs to be set so that it'll be used for the event loop
|
||||
await self.async_run(async_lib='trio')
|
||||
print('App done')
|
||||
nursery.cancel_scope.cancel()
|
||||
|
||||
nursery.start_soon(run_wrapper)
|
||||
nursery.start_soon(self.waste_time_freely)
|
||||
|
||||
async def waste_time_freely(self):
|
||||
'''This method is also run by trio and periodically prints something.
|
||||
'''
|
||||
try:
|
||||
i = 0
|
||||
while True:
|
||||
if self.root is not None:
|
||||
status = self.root.ids.label.status
|
||||
print('{} on the beach'.format(status))
|
||||
|
||||
# get some sleep
|
||||
if self.root.ids.btn1.state != 'down' and i >= 2:
|
||||
i = 0
|
||||
print('Yawn, getting tired. Going to sleep')
|
||||
self.root.ids.btn1.trigger_action()
|
||||
|
||||
i += 1
|
||||
await trio.sleep(2)
|
||||
except trio.Cancelled as e:
|
||||
print('Wasting time was canceled', e)
|
||||
finally:
|
||||
# when canceled, print that it finished
|
||||
print('Done wasting time')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
trio.run(AsyncApp().app_func)
|
58
kivy_venv/share/kivy-examples/async/trio_basic.py
Normal file
58
kivy_venv/share/kivy-examples/async/trio_basic.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
'''Example shows the recommended way of how to run Kivy with a trio
|
||||
event loop as just another async coroutine.
|
||||
'''
|
||||
import trio
|
||||
from kivy.app import async_runTouchApp
|
||||
from kivy.lang.builder import Builder
|
||||
|
||||
kv = '''
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Button:
|
||||
id: btn
|
||||
text: 'Press me'
|
||||
BoxLayout:
|
||||
Label:
|
||||
id: label
|
||||
text: 'Button is "{}"'.format(btn.state)
|
||||
'''
|
||||
|
||||
|
||||
async def run_app_happily(root, nursery):
|
||||
'''This method, which runs Kivy, is run by trio as one of the coroutines.
|
||||
'''
|
||||
# trio needs to be set so that it'll be used for the event loop
|
||||
await async_runTouchApp(root, async_lib='trio') # run Kivy
|
||||
print('App done')
|
||||
# now cancel all the other tasks that may be running
|
||||
nursery.cancel_scope.cancel()
|
||||
|
||||
|
||||
async def waste_time_freely():
|
||||
'''This method is also run by trio and periodically prints something.'''
|
||||
try:
|
||||
while True:
|
||||
print('Sitting on the beach')
|
||||
await trio.sleep(2)
|
||||
except trio.Cancelled as e:
|
||||
print('Wasting time was canceled', e)
|
||||
finally:
|
||||
# when canceled, print that it finished
|
||||
print('Done wasting time')
|
||||
|
||||
if __name__ == '__main__':
|
||||
async def root_func():
|
||||
'''trio needs to run a function, so this is it. '''
|
||||
|
||||
root = Builder.load_string(kv) # root widget
|
||||
async with trio.open_nursery() as nursery:
|
||||
'''In trio you create a nursery, in which you schedule async
|
||||
functions to be run by the nursery simultaneously as tasks.
|
||||
|
||||
This will run all two methods starting in random order
|
||||
asynchronously and then block until they are finished or canceled
|
||||
at the `with` level. '''
|
||||
nursery.start_soon(run_app_happily, root, nursery)
|
||||
nursery.start_soon(waste_time_freely)
|
||||
|
||||
trio.run(root_func)
|
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
59
kivy_venv/share/kivy-examples/audio/audio.kv
Normal file
59
kivy_venv/share/kivy-examples/audio/audio.kv
Normal file
|
@ -0,0 +1,59 @@
|
|||
#:kivy 1.0
|
||||
#:import kivy kivy
|
||||
|
||||
<AudioBackground>:
|
||||
orientation: 'vertical'
|
||||
canvas:
|
||||
Color:
|
||||
rgb: 1, 1, 1
|
||||
Rectangle:
|
||||
source: 'data/images/background.jpg'
|
||||
size: self.size
|
||||
|
||||
BoxLayout:
|
||||
padding: 10
|
||||
spacing: 10
|
||||
size_hint: 1, None
|
||||
pos_hint: {'top': 1}
|
||||
height: 44
|
||||
Image:
|
||||
size_hint: None, None
|
||||
size: 24, 24
|
||||
source: 'data/logo/kivy-icon-24.png'
|
||||
Label:
|
||||
height: 24
|
||||
text_size: self.size
|
||||
color: (1, 1, 1, .8)
|
||||
text: 'Kivy %s - Audio sample' % kivy.__version__
|
||||
valign: 'middle'
|
||||
|
||||
Label:
|
||||
text: 'Audio example'
|
||||
font_size: 32
|
||||
size_hint_y: None
|
||||
|
||||
BoxLayout:
|
||||
Slider:
|
||||
min: 0.0
|
||||
max: 1.0
|
||||
value: 1.0
|
||||
on_value: app.set_volume(self.value)
|
||||
orientation: "vertical"
|
||||
size_hint_x: None
|
||||
width: "48dp"
|
||||
|
||||
StackLayout:
|
||||
id: sl
|
||||
|
||||
Button:
|
||||
text: 'Stop and release all audio'
|
||||
size_hint_y: None
|
||||
height: '50sp'
|
||||
on_press: app.release_audio()
|
||||
|
||||
<AudioButton>:
|
||||
size_hint: None,0.333
|
||||
width: self.height
|
||||
text_size: self.size
|
||||
font_size: '12sp'
|
||||
valign: 'middle'
|
81
kivy_venv/share/kivy-examples/audio/main.py
Normal file
81
kivy_venv/share/kivy-examples/audio/main.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
'''
|
||||
Audio example
|
||||
=============
|
||||
|
||||
This example plays sounds of different formats. You should see a grid of
|
||||
buttons labelled with filenames. Clicking on the buttons will play, or
|
||||
restart, each sound. Not all sound formats will play on all platforms.
|
||||
|
||||
All the sounds are from the http://woolyss.com/chipmusic-samples.php
|
||||
"THE FREESOUND PROJECT", Under Creative Commons Sampling Plus 1.0 License.
|
||||
|
||||
'''
|
||||
|
||||
import kivy
|
||||
kivy.require('1.0.8')
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.button import Button
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.core.audio import SoundLoader
|
||||
from kivy.properties import StringProperty, ObjectProperty, NumericProperty
|
||||
from glob import glob
|
||||
from os.path import dirname, join, basename
|
||||
|
||||
|
||||
class AudioButton(Button):
|
||||
|
||||
filename = StringProperty(None)
|
||||
sound = ObjectProperty(None, allownone=True)
|
||||
volume = NumericProperty(1.0)
|
||||
|
||||
def on_press(self):
|
||||
if self.sound is None:
|
||||
self.sound = SoundLoader.load(self.filename)
|
||||
# stop the sound if it's currently playing
|
||||
if self.sound.state != 'stop':
|
||||
self.sound.stop()
|
||||
self.sound.volume = self.volume
|
||||
self.sound.play()
|
||||
|
||||
def release_audio(self):
|
||||
if self.sound:
|
||||
self.sound.stop()
|
||||
self.sound.unload()
|
||||
self.sound = None
|
||||
|
||||
def set_volume(self, volume):
|
||||
self.volume = volume
|
||||
if self.sound:
|
||||
self.sound.volume = volume
|
||||
|
||||
|
||||
class AudioBackground(BoxLayout):
|
||||
pass
|
||||
|
||||
|
||||
class AudioApp(App):
|
||||
|
||||
def build(self):
|
||||
|
||||
root = AudioBackground(spacing=5)
|
||||
for fn in glob(join(dirname(__file__), '*.wav')):
|
||||
btn = AudioButton(
|
||||
text=basename(fn[:-4]).replace('_', ' '), filename=fn,
|
||||
size_hint=(None, None), halign='center',
|
||||
size=(128, 128), text_size=(118, None))
|
||||
root.ids.sl.add_widget(btn)
|
||||
|
||||
return root
|
||||
|
||||
def release_audio(self):
|
||||
for audiobutton in self.root.ids.sl.children:
|
||||
audiobutton.release_audio()
|
||||
|
||||
def set_volume(self, value):
|
||||
for audiobutton in self.root.ids.sl.children:
|
||||
audiobutton.set_volume(value)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
AudioApp().run()
|
42
kivy_venv/share/kivy-examples/audio/pitch.py
Normal file
42
kivy_venv/share/kivy-examples/audio/pitch.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
# encoding: utf8
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.core.audio import SoundLoader
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.button import Button
|
||||
|
||||
from sys import version_info
|
||||
|
||||
|
||||
NOTES = (
|
||||
('Do', 1),
|
||||
('Ré', 9 / 8.),
|
||||
('Mi', 5 / 4.),
|
||||
('Fa', 4 / 3.),
|
||||
('Sol', 3 / 2.),
|
||||
('La', 5 / 3.),
|
||||
('Si', 15 / 8.),
|
||||
)
|
||||
|
||||
|
||||
class Test(App):
|
||||
def build(self):
|
||||
self.sound = SoundLoader.load(
|
||||
'/usr/lib64/python{}.{}/test/audiodata/pluck-pcm32.wav'
|
||||
.format(*version_info[0:2])
|
||||
)
|
||||
root = BoxLayout()
|
||||
for octave in range(-2, 3):
|
||||
for note, pitch in NOTES:
|
||||
button = Button(text=note)
|
||||
button.pitch = pitch * 2 ** octave
|
||||
button.bind(on_release=self.play_note)
|
||||
root.add_widget(button)
|
||||
return root
|
||||
|
||||
def play_note(self, button):
|
||||
self.sound.pitch = button.pitch
|
||||
self.sound.play()
|
||||
|
||||
|
||||
Test().run()
|
Binary file not shown.
59
kivy_venv/share/kivy-examples/camera/main.py
Normal file
59
kivy_venv/share/kivy-examples/camera/main.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
'''
|
||||
Camera Example
|
||||
==============
|
||||
|
||||
This example demonstrates a simple use of the camera. It shows a window with
|
||||
a buttoned labelled 'play' to turn the camera on and off. Note that
|
||||
not finding a camera, perhaps because gstreamer is not installed, will
|
||||
throw an exception during the kv language processing.
|
||||
|
||||
'''
|
||||
|
||||
# Uncomment these lines to see all the messages
|
||||
# from kivy.logger import Logger
|
||||
# import logging
|
||||
# Logger.setLevel(logging.TRACE)
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
import time
|
||||
Builder.load_string('''
|
||||
<CameraClick>:
|
||||
orientation: 'vertical'
|
||||
Camera:
|
||||
id: camera
|
||||
resolution: (640, 480)
|
||||
play: False
|
||||
ToggleButton:
|
||||
text: 'Play'
|
||||
on_press: camera.play = not camera.play
|
||||
size_hint_y: None
|
||||
height: '48dp'
|
||||
Button:
|
||||
text: 'Capture'
|
||||
size_hint_y: None
|
||||
height: '48dp'
|
||||
on_press: root.capture()
|
||||
''')
|
||||
|
||||
|
||||
class CameraClick(BoxLayout):
|
||||
def capture(self):
|
||||
'''
|
||||
Function to capture the images and give them the names
|
||||
according to their captured time and date.
|
||||
'''
|
||||
camera = self.ids['camera']
|
||||
timestr = time.strftime("%Y%m%d_%H%M%S")
|
||||
camera.export_to_png("IMG_{}.png".format(timestr))
|
||||
print("Captured")
|
||||
|
||||
|
||||
class TestCamera(App):
|
||||
|
||||
def build(self):
|
||||
return CameraClick()
|
||||
|
||||
|
||||
TestCamera().run()
|
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()
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue