commiting in case the kivy trial fails
This commit is contained in:
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.
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.
17
freechat-client/share/kivy-examples/widgets/accordion_1.py
Normal file
17
freechat-client/share/kivy-examples/widgets/accordion_1.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from kivy.uix.accordion import Accordion, AccordionItem
|
||||
from kivy.uix.label import Label
|
||||
from kivy.app import App
|
||||
|
||||
|
||||
class AccordionApp(App):
|
||||
def build(self):
|
||||
root = Accordion()
|
||||
for x in range(5):
|
||||
item = AccordionItem(title='Title %d' % x)
|
||||
item.add_widget(Label(text='Very big content\n' * 10))
|
||||
root.add_widget(item)
|
||||
return root
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
AccordionApp().run()
|
||||
32
freechat-client/share/kivy-examples/widgets/actionbar.py
Normal file
32
freechat-client/share/kivy-examples/widgets/actionbar.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from kivy.base import runTouchApp
|
||||
from kivy.lang import Builder
|
||||
|
||||
runTouchApp(Builder.load_string('''
|
||||
ActionBar:
|
||||
pos_hint: {'top':1}
|
||||
ActionView:
|
||||
use_separator: True
|
||||
ActionPrevious:
|
||||
title: 'Action Bar'
|
||||
with_previous: False
|
||||
ActionOverflow:
|
||||
ActionButton:
|
||||
icon: 'atlas://data/images/defaulttheme/audio-volume-high'
|
||||
ActionButton:
|
||||
important: True
|
||||
text: 'Important'
|
||||
ActionButton:
|
||||
text: 'Btn2'
|
||||
ActionButton:
|
||||
text: 'Btn3'
|
||||
ActionButton:
|
||||
text: 'Btn4'
|
||||
ActionGroup:
|
||||
text: 'Group1'
|
||||
ActionButton:
|
||||
text: 'Btn5'
|
||||
ActionButton:
|
||||
text: 'Btn6'
|
||||
ActionButton:
|
||||
text: 'Btn7'
|
||||
'''))
|
||||
35
freechat-client/share/kivy-examples/widgets/asyncimage.py
Normal file
35
freechat-client/share/kivy-examples/widgets/asyncimage.py
Normal file
@@ -0,0 +1,35 @@
|
||||
'''
|
||||
Asynchronous image loading
|
||||
==========================
|
||||
|
||||
Test of the widget AsyncImage.
|
||||
We are just putting it in a CenteredAsyncImage for being able to center the
|
||||
image on screen without doing upscale like the original AsyncImage.
|
||||
'''
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.image import AsyncImage
|
||||
from kivy.lang import Builder
|
||||
|
||||
|
||||
Builder.load_string('''
|
||||
<CenteredAsyncImage>:
|
||||
size_hint: 0.8, 0.8
|
||||
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
|
||||
mipmap: True
|
||||
''')
|
||||
|
||||
|
||||
class CenteredAsyncImage(AsyncImage):
|
||||
pass
|
||||
|
||||
|
||||
class TestAsyncApp(App):
|
||||
def build(self):
|
||||
url = ('https://upload.wikimedia.org/wikipedia/commons/thumb/8/89/'
|
||||
'STS-116_spacewalk_1.jpg/1024px-STS-116_spacewalk_1.jpg')
|
||||
return CenteredAsyncImage(source=url)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
TestAsyncApp().run()
|
||||
@@ -0,0 +1,54 @@
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
|
||||
Builder.load_string('''
|
||||
<Demo>:
|
||||
cols: 1
|
||||
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Button:
|
||||
size_hint_x: 0.4
|
||||
pos_hint: {'x': 0}
|
||||
text: 'pos_hint: x=0'
|
||||
|
||||
Button:
|
||||
size_hint_x: 0.2
|
||||
pos_hint: {'center_x': 0.5}
|
||||
text: 'pos_hint: center_x=0.5'
|
||||
|
||||
Button:
|
||||
size_hint_x: 0.4
|
||||
pos_hint: {'right': 1}
|
||||
text: 'pos_hint: right=1'
|
||||
|
||||
BoxLayout:
|
||||
Button:
|
||||
size_hint_y: 0.4
|
||||
pos_hint: {'y': 0}
|
||||
text: 'pos_hint: y=0'
|
||||
|
||||
Button:
|
||||
size_hint_y: 0.2
|
||||
pos_hint: {'center_y': .5}
|
||||
text: 'pos_hint: center_y=0.5'
|
||||
|
||||
Button:
|
||||
size_hint_y: 0.4
|
||||
pos_hint: {'top': 1}
|
||||
text: 'pos_hint: top=1'
|
||||
''')
|
||||
|
||||
|
||||
class Demo(GridLayout):
|
||||
pass
|
||||
|
||||
|
||||
class DemoApp(App):
|
||||
def build(self):
|
||||
return Demo()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
DemoApp().run()
|
||||
59
freechat-client/share/kivy-examples/widgets/bubble_test.py
Normal file
59
freechat-client/share/kivy-examples/widgets/bubble_test.py
Normal file
@@ -0,0 +1,59 @@
|
||||
'''
|
||||
Bubble
|
||||
======
|
||||
|
||||
Test of the widget Bubble.
|
||||
'''
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.uix.button import Button
|
||||
from kivy.lang import Builder
|
||||
from kivy.uix.bubble import Bubble
|
||||
|
||||
Builder.load_string('''
|
||||
<cut_copy_paste>
|
||||
size_hint: (None, None)
|
||||
size: (160, 120)
|
||||
pos_hint: {'center_x': .5, 'y': .6}
|
||||
BubbleButton:
|
||||
text: 'Cut'
|
||||
BubbleButton:
|
||||
text: 'Copy'
|
||||
BubbleButton:
|
||||
text: 'Paste'
|
||||
''')
|
||||
|
||||
|
||||
class cut_copy_paste(Bubble):
|
||||
pass
|
||||
|
||||
|
||||
class BubbleShowcase(FloatLayout):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(BubbleShowcase, self).__init__(**kwargs)
|
||||
self.but_bubble = Button(text='Press to show bubble')
|
||||
self.but_bubble.bind(on_release=self.show_bubble)
|
||||
self.add_widget(self.but_bubble)
|
||||
|
||||
def show_bubble(self, *l):
|
||||
if not hasattr(self, 'bubb'):
|
||||
self.bubb = bubb = cut_copy_paste()
|
||||
self.add_widget(bubb)
|
||||
else:
|
||||
values = ('left_top', 'left_mid', 'left_bottom', 'top_left',
|
||||
'top_mid', 'top_right', 'right_top', 'right_mid',
|
||||
'right_bottom', 'bottom_left', 'bottom_mid', 'bottom_right')
|
||||
index = values.index(self.bubb.arrow_pos)
|
||||
self.bubb.arrow_pos = values[(index + 1) % len(values)]
|
||||
|
||||
|
||||
class TestBubbleApp(App):
|
||||
|
||||
def build(self):
|
||||
return BubbleShowcase()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
TestBubbleApp().run()
|
||||
33
freechat-client/share/kivy-examples/widgets/camera.py
Normal file
33
freechat-client/share/kivy-examples/widgets/camera.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
|
||||
|
||||
kv = '''
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
|
||||
Camera:
|
||||
id: camera
|
||||
resolution: 399, 299
|
||||
|
||||
BoxLayout:
|
||||
orientation: 'horizontal'
|
||||
size_hint_y: None
|
||||
height: '48dp'
|
||||
Button:
|
||||
text: 'Start'
|
||||
on_release: camera.play = True
|
||||
|
||||
Button:
|
||||
text: 'Stop'
|
||||
on_release: camera.play = False
|
||||
'''
|
||||
|
||||
|
||||
class CameraApp(App):
|
||||
def build(self):
|
||||
return Builder.load_string(kv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CameraApp().run()
|
||||
@@ -0,0 +1,50 @@
|
||||
'''
|
||||
Carousel example with button inside.
|
||||
This is a tiny test for testing the scroll distance/timeout
|
||||
And ensure the down/up are dispatched if no gesture is done.
|
||||
'''
|
||||
from kivy.uix.carousel import Carousel
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
|
||||
Builder.load_string('''
|
||||
<Page>:
|
||||
cols: 3
|
||||
Label:
|
||||
text: str(id(root))
|
||||
Button
|
||||
Button
|
||||
Button
|
||||
Button
|
||||
text: 'load(page 3)'
|
||||
on_release:
|
||||
carousel = root.parent.parent
|
||||
carousel.load_slide(carousel.slides[2])
|
||||
Button
|
||||
Button
|
||||
text: 'prev'
|
||||
on_release:
|
||||
root.parent.parent.load_previous()
|
||||
Button
|
||||
Button
|
||||
text: 'next'
|
||||
on_release:
|
||||
root.parent.parent.load_next()
|
||||
''')
|
||||
|
||||
|
||||
class Page(GridLayout):
|
||||
pass
|
||||
|
||||
|
||||
class TestApp(App):
|
||||
def build(self):
|
||||
root = Carousel()
|
||||
for x in range(10):
|
||||
root.add_widget(Page())
|
||||
return root
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
TestApp().run()
|
||||
BIN
freechat-client/share/kivy-examples/widgets/cityCC0.mpg
Normal file
BIN
freechat-client/share/kivy-examples/widgets/cityCC0.mpg
Normal file
Binary file not shown.
BIN
freechat-client/share/kivy-examples/widgets/cityCC0.png
Normal file
BIN
freechat-client/share/kivy-examples/widgets/cityCC0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 690 KiB |
225
freechat-client/share/kivy-examples/widgets/codeinput.py
Normal file
225
freechat-client/share/kivy-examples/widgets/codeinput.py
Normal file
@@ -0,0 +1,225 @@
|
||||
from kivy.app import App
|
||||
from kivy.extras.highlight import KivyLexer
|
||||
from kivy.uix.spinner import Spinner, SpinnerOption
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.codeinput import CodeInput
|
||||
from kivy.uix.behaviors import EmacsBehavior
|
||||
from kivy.uix.popup import Popup
|
||||
from kivy.properties import ListProperty
|
||||
from kivy.core.window import Window
|
||||
from kivy.core.text import LabelBase
|
||||
from pygments import lexers
|
||||
import codecs
|
||||
import os
|
||||
|
||||
example_text = '''
|
||||
---------------------Python----------------------------------
|
||||
import kivy
|
||||
kivy.require('1.0.6') # replace with your current kivy version !
|
||||
from kivy.app import App
|
||||
from kivy.uix.button import Button
|
||||
|
||||
class MyApp(App):
|
||||
def build(self):
|
||||
return Button(text='Hello World')
|
||||
|
||||
if __name__ == '__main__':
|
||||
MyApp().run()
|
||||
----------------------Java-----------------------------------
|
||||
|
||||
public static byte toUnsignedByte(int intVal) {
|
||||
byte byteVal;
|
||||
return (byte)(intVal & 0xFF);
|
||||
}
|
||||
---------------------kv lang---------------------------------
|
||||
#:kivy 1.0
|
||||
|
||||
<YourWidget>:
|
||||
canvas:
|
||||
Color:
|
||||
rgb: .5, .5, .5
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
---------------------HTML------------------------------------
|
||||
<!-- Place this tag where you want the +1 button to render. -->
|
||||
<div class="g-plusone" data-annotation="inline" data-width="300"></div>
|
||||
|
||||
<!-- Place this tag after the last +1 button tag. -->
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var po = document.createElement('script');
|
||||
po.type = 'text/javascript';
|
||||
po.async = true;
|
||||
po.src = 'https://apis.google.com/js/plusone.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(po, s);
|
||||
})();
|
||||
</script>
|
||||
----------------------Emacs key bindings---------------------
|
||||
This CodeInput inherits from EmacsBehavior, so you can use Emacs key bindings
|
||||
if you want! To try out Emacs key bindings, set the "Key bindings" option to
|
||||
"Emacs". Experiment with the shortcuts below on some of the text in this window
|
||||
(just be careful not to delete the cheat sheet before you have made note of the
|
||||
commands!)
|
||||
|
||||
Shortcut Description
|
||||
-------- -----------
|
||||
Control + a Move cursor to the beginning of the line
|
||||
Control + e Move cursor to the end of the line
|
||||
Control + f Move cursor one character to the right
|
||||
Control + b Move cursor one character to the left
|
||||
Alt + f Move cursor to the end of the word to the right
|
||||
Alt + b Move cursor to the start of the word to the left
|
||||
Alt + Backspace Delete text left of the cursor to the beginning of word
|
||||
Alt + d Delete text right of the cursor to the end of the word
|
||||
Alt + w Copy selection
|
||||
Control + w Cut selection
|
||||
Control + y Paste selection
|
||||
'''
|
||||
|
||||
|
||||
class Fnt_SpinnerOption(SpinnerOption):
|
||||
pass
|
||||
|
||||
|
||||
class LoadDialog(Popup):
|
||||
|
||||
def load(self, path, selection):
|
||||
self.choosen_file = [None, ]
|
||||
self.choosen_file = selection
|
||||
Window.title = selection[0][selection[0].rfind(os.sep) + 1:]
|
||||
self.dismiss()
|
||||
|
||||
def cancel(self):
|
||||
self.dismiss()
|
||||
|
||||
|
||||
class SaveDialog(Popup):
|
||||
|
||||
def save(self, path, selection):
|
||||
_file = codecs.open(selection, 'w', encoding='utf8')
|
||||
_file.write(self.text)
|
||||
Window.title = selection[selection.rfind(os.sep) + 1:]
|
||||
_file.close()
|
||||
self.dismiss()
|
||||
|
||||
def cancel(self):
|
||||
self.dismiss()
|
||||
|
||||
|
||||
class CodeInputWithBindings(EmacsBehavior, CodeInput):
|
||||
'''CodeInput with keybindings.
|
||||
To add more bindings, add the behavior before CodeInput in the class
|
||||
definition.
|
||||
'''
|
||||
pass
|
||||
|
||||
|
||||
class CodeInputTest(App):
|
||||
|
||||
files = ListProperty([None, ])
|
||||
|
||||
def build(self):
|
||||
b = BoxLayout(orientation='vertical')
|
||||
languages = Spinner(
|
||||
text='language',
|
||||
values=sorted(['KvLexer', ] + list(lexers.LEXERS.keys())))
|
||||
|
||||
languages.bind(text=self.change_lang)
|
||||
|
||||
menu = BoxLayout(
|
||||
size_hint_y=None,
|
||||
height='30pt')
|
||||
fnt_size = Spinner(
|
||||
text='12',
|
||||
values=list(map(str, list(range(5, 40)))))
|
||||
fnt_size.bind(text=self._update_size)
|
||||
|
||||
fonts = [
|
||||
file for file in LabelBase._font_dirs_files
|
||||
if file.endswith('.ttf')]
|
||||
|
||||
fnt_name = Spinner(
|
||||
text='RobotoMono',
|
||||
option_cls=Fnt_SpinnerOption,
|
||||
values=fonts)
|
||||
fnt_name.bind(text=self._update_font)
|
||||
mnu_file = Spinner(
|
||||
text='File',
|
||||
values=('Open', 'SaveAs', 'Save', 'Close'))
|
||||
mnu_file.bind(text=self._file_menu_selected)
|
||||
key_bindings = Spinner(
|
||||
text='Key bindings',
|
||||
values=('Default key bindings', 'Emacs key bindings'))
|
||||
key_bindings.bind(text=self._bindings_selected)
|
||||
|
||||
menu.add_widget(mnu_file)
|
||||
menu.add_widget(fnt_size)
|
||||
menu.add_widget(fnt_name)
|
||||
menu.add_widget(languages)
|
||||
menu.add_widget(key_bindings)
|
||||
b.add_widget(menu)
|
||||
|
||||
self.codeinput = CodeInputWithBindings(
|
||||
lexer=KivyLexer(),
|
||||
font_size=12,
|
||||
text=example_text,
|
||||
key_bindings='default',
|
||||
)
|
||||
|
||||
b.add_widget(self.codeinput)
|
||||
|
||||
return b
|
||||
|
||||
def _update_size(self, instance, size):
|
||||
self.codeinput.font_size = float(size)
|
||||
|
||||
def _update_font(self, instance, fnt_name):
|
||||
instance.font_name = self.codeinput.font_name = fnt_name
|
||||
|
||||
def _file_menu_selected(self, instance, value):
|
||||
if value == 'File':
|
||||
return
|
||||
instance.text = 'File'
|
||||
if value == 'Open':
|
||||
if not hasattr(self, 'load_dialog'):
|
||||
self.load_dialog = LoadDialog()
|
||||
self.load_dialog.open()
|
||||
self.load_dialog.bind(choosen_file=self.setter('files'))
|
||||
elif value == 'SaveAs':
|
||||
if not hasattr(self, 'saveas_dialog'):
|
||||
self.saveas_dialog = SaveDialog()
|
||||
self.saveas_dialog.text = self.codeinput.text
|
||||
self.saveas_dialog.open()
|
||||
elif value == 'Save':
|
||||
if self.files[0]:
|
||||
_file = codecs.open(self.files[0], 'w', encoding='utf8')
|
||||
_file.write(self.codeinput.text)
|
||||
_file.close()
|
||||
elif value == 'Close':
|
||||
if self.files[0]:
|
||||
self.codeinput.text = ''
|
||||
Window.title = 'untitled'
|
||||
|
||||
def _bindings_selected(self, instance, value):
|
||||
value = value.split(' ')[0]
|
||||
self.codeinput.key_bindings = value.lower()
|
||||
|
||||
def on_files(self, instance, values):
|
||||
if not values[0]:
|
||||
return
|
||||
_file = codecs.open(values[0], 'r', encoding='utf8')
|
||||
self.codeinput.text = _file.read()
|
||||
_file.close()
|
||||
|
||||
def change_lang(self, instance, z):
|
||||
if z == 'KvLexer':
|
||||
lx = KivyLexer()
|
||||
else:
|
||||
lx = lexers.get_lexer_by_name(lexers.LEXERS[z][2][0])
|
||||
self.codeinput.lexer = lx
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CodeInputTest().run()
|
||||
53
freechat-client/share/kivy-examples/widgets/codeinputtest.kv
Normal file
53
freechat-client/share/kivy-examples/widgets/codeinputtest.kv
Normal file
@@ -0,0 +1,53 @@
|
||||
#:import os os
|
||||
<Fnt_SpinnerOption>:
|
||||
font_name: self.text
|
||||
|
||||
<LoadDialog>:
|
||||
title: filechooser.path
|
||||
choosen_file: None
|
||||
BoxLayout:
|
||||
size: root.size
|
||||
pos: root.pos
|
||||
orientation: "vertical"
|
||||
FileChooserListView:
|
||||
id: filechooser
|
||||
path: os.getcwd()
|
||||
|
||||
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
|
||||
path: os.getcwd()
|
||||
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)
|
||||
234
freechat-client/share/kivy-examples/widgets/colorpicker.py
Normal file
234
freechat-client/share/kivy-examples/widgets/colorpicker.py
Normal file
@@ -0,0 +1,234 @@
|
||||
from kivy.app import App
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.scatter import Scatter
|
||||
from kivy.uix.popup import Popup
|
||||
from kivy.properties import ObjectProperty, StringProperty
|
||||
from kivy.graphics import Color, Point
|
||||
|
||||
from math import sqrt
|
||||
from os import walk
|
||||
from os.path import dirname, join
|
||||
|
||||
from kivy.lang import Builder
|
||||
|
||||
Builder.load_string('''
|
||||
#:import os os
|
||||
<Picture>:
|
||||
# each time a picture is created, the image can delay the loading
|
||||
# as soon as the image is loaded, ensure that the center is changed
|
||||
# to the center of the screen.
|
||||
on_size: self.center = app.main_root_widget.center
|
||||
size: img.size
|
||||
size_hint: None, None
|
||||
on_touch_down: if self.collide_point(*args[1].pos): app.current_image = img
|
||||
|
||||
Image:
|
||||
id: img
|
||||
source: root.source
|
||||
|
||||
# create initial image to be 400 pixels width
|
||||
size: 400, 400 / self.image_ratio
|
||||
|
||||
# add shadow background
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: 1, 1, 1, 1
|
||||
BorderImage:
|
||||
source: '../demo/pictures/shadow32.png'
|
||||
border: (36, 36, 36, 36)
|
||||
size:(self.width + 72, self.height + 72)
|
||||
pos: (-36, -36)
|
||||
|
||||
<ColorSelector>:
|
||||
color: 1, 1, 1, 1
|
||||
title: 'Color Slector'
|
||||
content:content
|
||||
BoxLayout:
|
||||
id: content
|
||||
orientation: 'vertical'
|
||||
ColorPicker:
|
||||
id: clr_picker
|
||||
color: root.color
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: '27sp'
|
||||
Button:
|
||||
text: 'ok'
|
||||
on_release:
|
||||
root.color = clr_picker.color
|
||||
root.dismiss()
|
||||
Button:
|
||||
text: 'cancel'
|
||||
on_release: root.dismiss()
|
||||
|
||||
<LeftPanel@BoxLayout>
|
||||
orientation: 'vertical'
|
||||
padding: '2pt'
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: .5, .4, .9, .2
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
Label:
|
||||
size_hint_y: None
|
||||
font_size: '18sp'
|
||||
text_size: self.width, None
|
||||
valign: 'middle'
|
||||
halign: 'center'
|
||||
height: self.texture.size[1] if self.texture else 10
|
||||
text:
|
||||
("Selected Image:\\n" + app.current_image.source.split(os.sep)[-1]
|
||||
if app.current_image else 'None')
|
||||
Button:
|
||||
text: 'Brush'
|
||||
size_hint_y: None
|
||||
height: self.parent.width
|
||||
on_release:
|
||||
app.color_selector.open()
|
||||
app.color_mode = 'brush'
|
||||
Image:
|
||||
color: app.color_selector.color
|
||||
source: '../demo/touchtracer/particle.png'
|
||||
allow_stretch: True
|
||||
size: self.parent.size
|
||||
pos: self.parent.pos
|
||||
Button:
|
||||
text: 'cursor'
|
||||
on_release: app.color_mode = 'cursor'
|
||||
Button:
|
||||
text: 'clear'
|
||||
on_release:
|
||||
app.handle_clear()
|
||||
|
||||
<MainRootWidget>
|
||||
current_image: None
|
||||
client_area: client_area
|
||||
RelativeLayout:
|
||||
id: client_area
|
||||
Splitter:
|
||||
sizable_from: 'left'
|
||||
size_hint: None, 1
|
||||
width: '99dp'
|
||||
LeftPanel:
|
||||
|
||||
''')
|
||||
|
||||
|
||||
def calculate_points(x1, y1, x2, y2, steps=5):
|
||||
dx = x2 - x1
|
||||
dy = y2 - y1
|
||||
dist = sqrt(dx * dx + dy * dy)
|
||||
if dist < steps:
|
||||
return
|
||||
o = []
|
||||
m = dist / steps
|
||||
for i in range(1, int(m)):
|
||||
mi = i / m
|
||||
lastx = x1 + dx * mi
|
||||
lasty = y1 + dy * mi
|
||||
o.extend([lastx, lasty])
|
||||
return o
|
||||
|
||||
|
||||
class ColorSelector(Popup):
|
||||
pass
|
||||
|
||||
|
||||
class Picture(Scatter):
|
||||
|
||||
source = StringProperty(None)
|
||||
'''path to the Image to be loaded
|
||||
'''
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Picture, self).__init__(**kwargs)
|
||||
self._app = App.get_running_app()
|
||||
|
||||
def on_touch_down(self, touch):
|
||||
_app = self._app
|
||||
if (_app.color_mode[0] == 'c' or
|
||||
not self.collide_point(*touch.pos)):
|
||||
return super(Picture, self).on_touch_down(touch)
|
||||
ud = touch.ud
|
||||
ud['group'] = g = str(touch.uid)
|
||||
_pos = list(self.ids.img.to_widget(*touch.pos))
|
||||
_pos[0] += self.parent.x
|
||||
with self.ids.img.canvas.after:
|
||||
ud['color'] = Color(*_app.color_selector.color, group=g)
|
||||
ud['lines'] = Point(points=(_pos),
|
||||
source='../demo/touchtracer/particle.png',
|
||||
pointsize=5, group=g)
|
||||
touch.grab(self)
|
||||
return True
|
||||
|
||||
def on_touch_move(self, touch):
|
||||
if touch.grab_current is not self:
|
||||
return
|
||||
_app = self._app
|
||||
if _app.color_mode[0] == 'c' or not self.collide_point(*touch.pos):
|
||||
return super(Picture, self).on_touch_move(touch)
|
||||
ud = touch.ud
|
||||
_pos = list(self.ids.img.to_widget(*touch.pos))
|
||||
_pos[0] += self.parent.x
|
||||
points = ud['lines'].points
|
||||
oldx, oldy = points[-2], points[-1]
|
||||
points = calculate_points(oldx, oldy, _pos[0], _pos[1])
|
||||
if points:
|
||||
try:
|
||||
lp = ud['lines'].add_point
|
||||
for idx in range(0, len(points), 2):
|
||||
lp(points[idx], points[idx + 1])
|
||||
except GraphicException:
|
||||
pass
|
||||
|
||||
def on_touch_up(self, touch):
|
||||
if touch.grab_current is not self:
|
||||
return
|
||||
_app = self._app
|
||||
if _app.color_mode[0] == 'c':
|
||||
return super(Picture, self).on_touch_up(touch)
|
||||
touch.ungrab(self)
|
||||
ud = touch.ud
|
||||
self.canvas.remove_group(ud['group'])
|
||||
|
||||
|
||||
class MainRootWidget(BoxLayout):
|
||||
|
||||
clent_area = ObjectProperty(None)
|
||||
# The Client Area in which all editing is Done
|
||||
|
||||
def on_parent(self, instance, parent):
|
||||
if parent:
|
||||
_dir = join(dirname(__file__), 'lists/fruit_images/')
|
||||
for image in list(walk(_dir))[0][2]:
|
||||
if image.find('512') > -1:
|
||||
self.client_area.add_widget(Picture(source=_dir + image))
|
||||
|
||||
|
||||
class MainApp(App):
|
||||
|
||||
main_root_widget = ObjectProperty(None)
|
||||
# we will be accessing this later as App.main_root_widget
|
||||
|
||||
current_image = ObjectProperty(None)
|
||||
'''This is a handle to the currently selected image on which the effects
|
||||
would be applied.'''
|
||||
|
||||
color_mode = StringProperty('cursor')
|
||||
'''This defines the current mode `brush` or `cursor`. `brush` mode allows
|
||||
adding brush strokes to the currently selected Image.
|
||||
'''
|
||||
|
||||
def build(self):
|
||||
self.color_selector = ColorSelector()
|
||||
self.main_root_widget = MainRootWidget()
|
||||
return self.main_root_widget
|
||||
|
||||
def handle_clear(self):
|
||||
if self.current_image:
|
||||
self.current_image.canvas.after.clear()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
MainApp().run()
|
||||
62
freechat-client/share/kivy-examples/widgets/colorusage.py
Normal file
62
freechat-client/share/kivy-examples/widgets/colorusage.py
Normal file
@@ -0,0 +1,62 @@
|
||||
from kivy.app import App
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from kivy.lang import Builder
|
||||
|
||||
Builder.load_string("""
|
||||
#:import hex kivy.utils.get_color_from_hex
|
||||
|
||||
<Root>:
|
||||
cols: 2
|
||||
canvas:
|
||||
Color:
|
||||
rgba: 1, 1, 1, 1
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
|
||||
Label:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgb: 39/255., 174/255., 96/255.
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
text: "rgb: 39/255., 174/255., 96/255."
|
||||
Label:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: 39/255., 174/255., 96/255., 1
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
text: "rgba: 39/255., 174/255., 96/255., 1"
|
||||
Label:
|
||||
canvas.before:
|
||||
Color:
|
||||
hsv: 145/360., 77.6/100, 68.2/100
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
text: "hsv: 145/360., 77.6/100, 68.2/100"
|
||||
Label:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: hex('#27ae60')
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
text: "rgba: hex('#27ae60')"
|
||||
""")
|
||||
|
||||
|
||||
class Root(GridLayout):
|
||||
pass
|
||||
|
||||
|
||||
class ColorusageApp(App):
|
||||
def build(self):
|
||||
return Root()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ColorusageApp().run()
|
||||
@@ -0,0 +1,83 @@
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from kivy.uix.button import Button
|
||||
from kivy.uix.behaviors import CompoundSelectionBehavior
|
||||
from kivy.uix.behaviors import FocusBehavior
|
||||
from kivy.app import runTouchApp
|
||||
|
||||
|
||||
class SelectableGrid(FocusBehavior, CompoundSelectionBehavior, GridLayout):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(SelectableGrid, self).__init__(**kwargs)
|
||||
|
||||
def print_selection(*l):
|
||||
print('selected: ', [x.text for x in self.selected_nodes])
|
||||
self.bind(selected_nodes=print_selection)
|
||||
|
||||
def keyboard_on_key_down(self, window, keycode, text, modifiers):
|
||||
if super(SelectableGrid, self).keyboard_on_key_down(
|
||||
window, keycode, text, modifiers):
|
||||
return True
|
||||
if self.select_with_key_down(window, keycode, text, modifiers):
|
||||
return True
|
||||
return False
|
||||
|
||||
def keyboard_on_key_up(self, window, keycode):
|
||||
if super(SelectableGrid, self).keyboard_on_key_up(window, keycode):
|
||||
return True
|
||||
if self.select_with_key_up(window, keycode):
|
||||
return True
|
||||
return False
|
||||
|
||||
def goto_node(self, key, last_node, last_node_idx):
|
||||
''' This function is used to go to the node by typing the number
|
||||
of the text of the button.
|
||||
'''
|
||||
node, idx = super(SelectableGrid, self).goto_node(key, last_node,
|
||||
last_node_idx)
|
||||
if node != last_node:
|
||||
return node, idx
|
||||
|
||||
items = list(enumerate(self.get_selectable_nodes()))
|
||||
'''If self.nodes_order_reversed (the default due to using
|
||||
self.children which is reversed), the index is counted from the
|
||||
starts of the selectable nodes, like normal but the nodes are traversed
|
||||
in the reverse order.
|
||||
'''
|
||||
# start searching after the last selected node
|
||||
if not self.nodes_order_reversed:
|
||||
items = items[last_node_idx + 1:] + items[:last_node_idx + 1]
|
||||
else:
|
||||
items = items[:last_node_idx][::-1] + items[last_node_idx:][::-1]
|
||||
|
||||
for i, child in items:
|
||||
if child.text.startswith(key):
|
||||
return child, i
|
||||
return node, idx
|
||||
|
||||
def select_node(self, node):
|
||||
node.background_color = (1, 0, 0, 1)
|
||||
return super(SelectableGrid, self).select_node(node)
|
||||
|
||||
def deselect_node(self, node):
|
||||
node.background_color = (1, 1, 1, 1)
|
||||
super(SelectableGrid, self).deselect_node(node)
|
||||
|
||||
def do_touch(self, instance, touch):
|
||||
if ('button' in touch.profile and touch.button in
|
||||
('scrollup', 'scrolldown', 'scrollleft', 'scrollright')) or\
|
||||
instance.collide_point(*touch.pos):
|
||||
self.select_with_touch(instance, touch)
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
root = SelectableGrid(cols=5, up_count=5, multiselect=True, scroll_count=1)
|
||||
for i in range(40):
|
||||
c = Button(text=str(i))
|
||||
c.bind(on_touch_down=root.do_touch)
|
||||
root.add_widget(c)
|
||||
|
||||
|
||||
runTouchApp(root)
|
||||
82
freechat-client/share/kivy-examples/widgets/customcollide.py
Normal file
82
freechat-client/share/kivy-examples/widgets/customcollide.py
Normal file
@@ -0,0 +1,82 @@
|
||||
'''
|
||||
Custom shape & collide widget
|
||||
=============================
|
||||
|
||||
This is a Triangle widget with a triangle shape based on 3 points (p1, p2, p3),
|
||||
plus a custom collision function.
|
||||
|
||||
The p1, p2, p3 are automatically calculated from the position and the size of
|
||||
the Widget bounding box. We are using them to draw the triangle shape.
|
||||
(Please note in the kv the special case for Scatter.)
|
||||
|
||||
Then we need to setup a new collision function to collide only on the triangle.
|
||||
We are using a external method that will check if a point is inside a polygon
|
||||
(we consider our triangle as a polygon).
|
||||
'''
|
||||
|
||||
|
||||
import kivy
|
||||
kivy.require('1.0.8')
|
||||
|
||||
from kivy.uix.scatter import Scatter
|
||||
from kivy.properties import ListProperty
|
||||
from kivy.lang import Builder
|
||||
|
||||
|
||||
Builder.load_string('''
|
||||
<Triangle>:
|
||||
# example for doing a triangle
|
||||
# this will automatically recalculate pX from pos/size
|
||||
p1: 0, 0
|
||||
p2: self.width, 0
|
||||
p3: self.width / 2, self.height
|
||||
|
||||
# If you use a Widget instead of Scatter as base class, you need that:
|
||||
#p1: self.pos
|
||||
#p2: self.right, self.y
|
||||
#p3: self.center_x, self.top
|
||||
|
||||
# draw something
|
||||
canvas:
|
||||
Color:
|
||||
rgb: 1, 0, 0
|
||||
Triangle:
|
||||
points: self.p1 + self.p2 + self.p3
|
||||
''')
|
||||
|
||||
|
||||
def point_inside_polygon(x, y, poly):
|
||||
'''Taken from http://www.ariel.com.au/a/python-point-int-poly.html
|
||||
'''
|
||||
n = len(poly)
|
||||
inside = False
|
||||
p1x = poly[0]
|
||||
p1y = poly[1]
|
||||
for i in range(0, n + 2, 2):
|
||||
p2x = poly[i % n]
|
||||
p2y = poly[(i + 1) % n]
|
||||
if y > min(p1y, p2y):
|
||||
if y <= max(p1y, p2y):
|
||||
if x <= max(p1x, p2x):
|
||||
if p1y != p2y:
|
||||
xinters = (y - p1y) * (p2x - p1x) / (p2y - p1y) + p1x
|
||||
if p1x == p2x or x <= xinters:
|
||||
inside = not inside
|
||||
p1x, p1y = p2x, p2y
|
||||
return inside
|
||||
|
||||
|
||||
class Triangle(Scatter):
|
||||
p1 = ListProperty([0, 0])
|
||||
p2 = ListProperty([0, 0])
|
||||
p3 = ListProperty([0, 0])
|
||||
|
||||
def collide_point(self, x, y):
|
||||
x, y = self.to_local(x, y)
|
||||
return point_inside_polygon(x, y,
|
||||
self.p1 + self.p2 + self.p3)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from kivy.base import runTouchApp
|
||||
runTouchApp(Triangle(size_hint=(None, None)))
|
||||
200
freechat-client/share/kivy-examples/widgets/effectwidget.py
Normal file
200
freechat-client/share/kivy-examples/widgets/effectwidget.py
Normal file
@@ -0,0 +1,200 @@
|
||||
'''
|
||||
Example usage of the effectwidget.
|
||||
|
||||
Currently highly experimental.
|
||||
'''
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.effectwidget import EffectWidget
|
||||
from kivy.uix.spinner import Spinner
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.lang import Builder
|
||||
from kivy.properties import ObjectProperty
|
||||
|
||||
from kivy.uix.effectwidget import (MonochromeEffect,
|
||||
InvertEffect,
|
||||
ScanlinesEffect,
|
||||
ChannelMixEffect,
|
||||
ScanlinesEffect,
|
||||
FXAAEffect,
|
||||
PixelateEffect,
|
||||
HorizontalBlurEffect,
|
||||
VerticalBlurEffect)
|
||||
|
||||
|
||||
class ComparisonWidget(EffectWidget):
|
||||
pass
|
||||
|
||||
|
||||
class ComparisonWidget(EffectWidget):
|
||||
pass
|
||||
|
||||
|
||||
class EffectSpinner(Spinner):
|
||||
pass
|
||||
|
||||
|
||||
class SpinnerRow(BoxLayout):
|
||||
effectwidget = ObjectProperty()
|
||||
|
||||
def update_effectwidget(self, *args):
|
||||
effects = []
|
||||
for child in self.children[::-1]:
|
||||
text = child.text
|
||||
if text == 'none':
|
||||
pass
|
||||
if text == 'fxaa':
|
||||
effects.append(FXAAEffect())
|
||||
if text == 'monochrome':
|
||||
effects.append(MonochromeEffect())
|
||||
if text == 'invert':
|
||||
effects.append(InvertEffect())
|
||||
if text == 'mix':
|
||||
effects.append(ChannelMixEffect())
|
||||
if text == 'flash':
|
||||
effects.append(FlashEffect())
|
||||
if text == 'blur_h':
|
||||
effects.append(HorizontalBlurEffect())
|
||||
if text == 'blur_v':
|
||||
effects.append(VerticalBlurEffect())
|
||||
if text == 'postprocessing':
|
||||
effects.append(ScanlinesEffect())
|
||||
if text == 'pixelate':
|
||||
effects.append(PixelateEffect())
|
||||
|
||||
if self.effectwidget:
|
||||
self.effectwidget.effects = effects
|
||||
|
||||
|
||||
example = Builder.load_string('''
|
||||
#:import Vector kivy.vector.Vector
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
FloatLayout:
|
||||
ComparisonWidget:
|
||||
pos_hint: {'x': 0, 'y': 0}
|
||||
size_hint: 0.5, 1
|
||||
id: effect1
|
||||
ComparisonWidget:
|
||||
pos_hint: {'x': pos_slider.value, 'y': 0}
|
||||
size_hint: 0.5, 1
|
||||
id: effect2
|
||||
background_color: (rs.value, gs.value, bs.value, als.value)
|
||||
SpinnerRow:
|
||||
effectwidget: effect1
|
||||
text: 'left effects'
|
||||
SpinnerRow:
|
||||
effectwidget: effect2
|
||||
text: 'right effects'
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: sp(40)
|
||||
Label:
|
||||
text: 'control overlap:'
|
||||
Slider:
|
||||
min: 0
|
||||
max: 0.5
|
||||
value: 0.5
|
||||
id: pos_slider
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: sp(40)
|
||||
Label:
|
||||
text: 'right bg r,g,b,a'
|
||||
Slider:
|
||||
min: 0
|
||||
max: 1
|
||||
value: 0
|
||||
id: rs
|
||||
Slider:
|
||||
min: 0
|
||||
max: 1
|
||||
value: 0
|
||||
id: gs
|
||||
Slider:
|
||||
min: 0
|
||||
max: 1
|
||||
value: 0
|
||||
id: bs
|
||||
Slider:
|
||||
min: 0
|
||||
max: 1
|
||||
value: 0
|
||||
id: als
|
||||
|
||||
|
||||
<ComparisonWidget>:
|
||||
Widget:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: 1, 0, 0, 1
|
||||
Ellipse:
|
||||
pos: Vector(self.pos) + 0.5*Vector(self.size)
|
||||
size: 0.4*Vector(self.size)
|
||||
Color:
|
||||
rgba: 0, 1, 0.3, 1
|
||||
Ellipse:
|
||||
pos: Vector(self.pos) + 0.1*Vector(self.size)
|
||||
size: 0.6*Vector(self.size)
|
||||
Color:
|
||||
rgba: 0.5, 0.3, 0.8, 1
|
||||
Ellipse:
|
||||
pos: Vector(self.pos) + Vector([0, 0.6])*Vector(self.size)
|
||||
size: 0.4*Vector(self.size)
|
||||
Color:
|
||||
rgba: 1, 0.8, 0.1, 1
|
||||
Ellipse:
|
||||
pos: Vector(self.pos) + Vector([0.5, 0])*Vector(self.size)
|
||||
size: 0.4*Vector(self.size)
|
||||
Color:
|
||||
rgba: 0, 0, 0.8, 1
|
||||
Line:
|
||||
points:
|
||||
[self.x, self.y,
|
||||
self.x + self.width, self.y + 0.3*self.height,
|
||||
self.x + 0.2*self.width, self.y + 0.1*self.height,
|
||||
self.x + 0.85*self.width, self.y + 0.72*self.height,
|
||||
self.x + 0.31*self.width, self.y + 0.6*self.height,
|
||||
self.x, self.top]
|
||||
width: 1
|
||||
Color:
|
||||
rgba: 0, 0.9, 0.1, 1
|
||||
Line:
|
||||
points:
|
||||
[self.x + self.width, self.y + self.height,
|
||||
self.x + 0.35*self.width, self.y + 0.6*self.height,
|
||||
self.x + 0.7*self.width, self.y + 0.15*self.height,
|
||||
self.x + 0.2*self.width, self.y + 0.22*self.height,
|
||||
self.x + 0.3*self.width, self.y + 0.92*self.height]
|
||||
width: 2
|
||||
|
||||
<SpinnerRow>:
|
||||
orientation: 'horizontal'
|
||||
size_hint_y: None
|
||||
height: dp(40)
|
||||
text: ''
|
||||
Label:
|
||||
text: root.text
|
||||
EffectSpinner:
|
||||
on_text: root.update_effectwidget()
|
||||
EffectSpinner:
|
||||
on_text: root.update_effectwidget()
|
||||
EffectSpinner:
|
||||
on_text: root.update_effectwidget()
|
||||
|
||||
<EffectSpinner>:
|
||||
text: 'none'
|
||||
values:
|
||||
['none', 'fxaa', 'monochrome',
|
||||
'invert', 'mix',
|
||||
'blur_h', 'blur_v',
|
||||
'postprocessing', 'pixelate',]
|
||||
''')
|
||||
|
||||
|
||||
class EffectApp(App):
|
||||
def build(self):
|
||||
return example
|
||||
|
||||
|
||||
EffectApp().run()
|
||||
47
freechat-client/share/kivy-examples/widgets/effectwidget2.py
Normal file
47
freechat-client/share/kivy-examples/widgets/effectwidget2.py
Normal file
@@ -0,0 +1,47 @@
|
||||
'''
|
||||
This is an example of creating your own effect by writing a glsl string.
|
||||
'''
|
||||
|
||||
from kivy.base import runTouchApp
|
||||
from kivy.lang import Builder
|
||||
from kivy.uix.effectwidget import EffectWidget, EffectBase
|
||||
|
||||
|
||||
# The effect string is glsl code defining an effect function.
|
||||
effect_string = '''
|
||||
vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
|
||||
{
|
||||
// Note that time is a uniform variable that is automatically
|
||||
// provided to all effects.
|
||||
float red = color.x * abs(sin(time*2.0));
|
||||
float green = color.y; // No change
|
||||
float blue = color.z * (1.0 - abs(sin(time*2.0)));
|
||||
return vec4(red, green, blue, color.w);
|
||||
}
|
||||
'''
|
||||
|
||||
|
||||
class DemoEffect(EffectWidget):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.effect_reference = EffectBase(glsl=effect_string)
|
||||
super(DemoEffect, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
widget = Builder.load_string('''
|
||||
DemoEffect:
|
||||
effects: [self.effect_reference] if checkbox.active else []
|
||||
orientation: 'vertical'
|
||||
Button:
|
||||
text: 'Some text so you can see what happens.'
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: dp(50)
|
||||
Label:
|
||||
text: 'Enable effect?'
|
||||
CheckBox:
|
||||
id: checkbox
|
||||
active: True
|
||||
''')
|
||||
|
||||
|
||||
runTouchApp(widget)
|
||||
@@ -0,0 +1,63 @@
|
||||
'''
|
||||
This example demonstrates creating and usind an AdvancedEffectBase. In
|
||||
this case, we use it to efficiently pass the touch coordinates into the shader.
|
||||
'''
|
||||
|
||||
from kivy.base import runTouchApp
|
||||
from kivy.properties import ListProperty
|
||||
from kivy.lang import Builder
|
||||
from kivy.uix.effectwidget import EffectWidget, AdvancedEffectBase
|
||||
|
||||
|
||||
effect_string = '''
|
||||
uniform vec2 touch;
|
||||
|
||||
vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
|
||||
{
|
||||
vec2 distance = 0.025*(coords - touch);
|
||||
float dist_mag = (distance.x*distance.x + distance.y*distance.y);
|
||||
vec3 multiplier = vec3(abs(sin(dist_mag - time)));
|
||||
return vec4(multiplier * color.xyz, 1.0);
|
||||
}
|
||||
'''
|
||||
|
||||
|
||||
class TouchEffect(AdvancedEffectBase):
|
||||
touch = ListProperty([0.0, 0.0])
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TouchEffect, self).__init__(*args, **kwargs)
|
||||
self.glsl = effect_string
|
||||
|
||||
self.uniforms = {'touch': [0.0, 0.0]}
|
||||
|
||||
def on_touch(self, *args, **kwargs):
|
||||
self.uniforms['touch'] = [float(i) for i in self.touch]
|
||||
|
||||
|
||||
class TouchWidget(EffectWidget):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(TouchWidget, self).__init__(*args, **kwargs)
|
||||
self.effect = TouchEffect()
|
||||
self.effects = [self.effect]
|
||||
|
||||
def on_touch_down(self, touch):
|
||||
super(TouchWidget, self).on_touch_down(touch)
|
||||
self.on_touch_move(touch)
|
||||
|
||||
def on_touch_move(self, touch):
|
||||
self.effect.touch = touch.pos
|
||||
|
||||
|
||||
root = Builder.load_string('''
|
||||
TouchWidget:
|
||||
Button:
|
||||
text: 'Some text!'
|
||||
Image:
|
||||
source: 'data/logo/kivy-icon-512.png'
|
||||
allow_stretch: True
|
||||
keep_ratio: False
|
||||
''')
|
||||
|
||||
|
||||
runTouchApp(root)
|
||||
111
freechat-client/share/kivy-examples/widgets/fbowidget.py
Normal file
111
freechat-client/share/kivy-examples/widgets/fbowidget.py
Normal file
@@ -0,0 +1,111 @@
|
||||
'''
|
||||
FBO example
|
||||
===========
|
||||
|
||||
This is an example of how to use FBO (Frame Buffer Object) to speedup graphics.
|
||||
An Fbo is like a texture that you can draw on it.
|
||||
|
||||
By default, all the children are added in the canvas of the parent.
|
||||
When you are displaying thousand of widget, you'll do thousands of graphics
|
||||
instructions each frame.
|
||||
The idea is to do this drawing only one time in a Fbo, and then, draw the Fbo
|
||||
every frame instead of all children's graphics instructions.
|
||||
|
||||
We created a FboFloatLayout that create his canvas, and a Fbo.
|
||||
After the Fbo is created, we are adding Color and Rectangle instruction to
|
||||
display the texture of the Fbo itself.
|
||||
The overload of on_pos/on_size are here to update size of Fbo if needed, and
|
||||
adapt the position/size of the rectangle too.
|
||||
|
||||
Then, when a child is added or removed, we are redirecting addition/removal of
|
||||
graphics instruction to our Fbo. This is why add_widget/remove_widget are
|
||||
overloaded too.
|
||||
|
||||
.. note::
|
||||
|
||||
This solution can be helpful but not ideal. Multisampling are not available
|
||||
in Framebuffer. We will work to add the support of it if the hardware is
|
||||
capable of, but it could be not the same.
|
||||
|
||||
'''
|
||||
|
||||
|
||||
# needed to create Fbo, must be resolved in future kivy version
|
||||
from kivy.core.window import Window
|
||||
|
||||
from kivy.graphics import Color, Rectangle, Canvas
|
||||
from kivy.graphics.fbo import Fbo
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.properties import ObjectProperty
|
||||
|
||||
|
||||
class FboFloatLayout(FloatLayout):
|
||||
|
||||
texture = ObjectProperty(None, allownone=True)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.canvas = Canvas()
|
||||
with self.canvas:
|
||||
self.fbo = Fbo(size=self.size)
|
||||
Color(1, 1, 1)
|
||||
self.fbo_rect = Rectangle()
|
||||
|
||||
# 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, *largs):
|
||||
# trick to attach graphics instruction to fbo instead of canvas
|
||||
canvas = self.canvas
|
||||
self.canvas = self.fbo
|
||||
ret = super(FboFloatLayout, self).add_widget(*largs)
|
||||
self.canvas = canvas
|
||||
return ret
|
||||
|
||||
def remove_widget(self, *largs):
|
||||
canvas = self.canvas
|
||||
self.canvas = self.fbo
|
||||
super(FboFloatLayout, self).remove_widget(*largs)
|
||||
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
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from kivy.uix.button import Button
|
||||
from kivy.app import App
|
||||
|
||||
class TestFboApp(App):
|
||||
def build(self):
|
||||
|
||||
# test with FboFloatLayout or FloatLayout
|
||||
# comment/uncomment to test it
|
||||
root = FboFloatLayout()
|
||||
# root = FloatLayout()
|
||||
|
||||
# this part of creation can be slow. try to optimize the loop a
|
||||
# little bit.
|
||||
s = 30
|
||||
size = (s, s)
|
||||
sh = (None, None)
|
||||
add = root.add_widget
|
||||
print('Creating 5000 widgets...')
|
||||
for i in range(5000):
|
||||
x = (i % 40) * s
|
||||
y = int(i / 40) * s
|
||||
add(Button(text=str(i), pos=(x, y), size_hint=sh, size=size))
|
||||
if i % 1000 == 1000 - 1:
|
||||
print(5000 - i - 1, 'left...')
|
||||
|
||||
return root
|
||||
|
||||
TestFboApp().run()
|
||||
@@ -0,0 +1,98 @@
|
||||
from kivy.app import App
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.label import Label
|
||||
from kivy.uix.behaviors import FocusBehavior
|
||||
from kivy.graphics import Color, Rectangle
|
||||
|
||||
|
||||
class FocusWithColor(FocusBehavior):
|
||||
''' Class that when focused, changes its background color to red.
|
||||
'''
|
||||
|
||||
_color = None
|
||||
_rect = None
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(FocusWithColor, self).__init__(**kwargs)
|
||||
with self.canvas:
|
||||
self._color = Color(1, 1, 1, .2)
|
||||
self._rect = Rectangle(size=self.size, pos=self.pos)
|
||||
self.bind(size=self._update_rect, pos=self._update_rect)
|
||||
|
||||
def _update_rect(self, instance, value):
|
||||
self._rect.pos = instance.pos
|
||||
self._rect.size = instance.size
|
||||
|
||||
def on_focused(self, instance, value, *largs):
|
||||
self._color.rgba = [1, 0, 0, .2] if value else [1, 1, 1, .2]
|
||||
|
||||
|
||||
class FocusLabel(FocusWithColor, Label):
|
||||
'''A label, which in addition to turn red when focused, it also sets the
|
||||
keyboard input to the text of the label.
|
||||
'''
|
||||
|
||||
def keyboard_on_key_down(self, window, keycode, text, modifiers):
|
||||
'''We call super before doing anything else to enable tab cycling
|
||||
by FocusBehavior. If we wanted to use tab for ourselves, we could just
|
||||
not call it, or call it if we didn't need tab.
|
||||
'''
|
||||
if super(FocusLabel, self).keyboard_on_key_down(window, keycode,
|
||||
text, modifiers):
|
||||
return True
|
||||
self.text = keycode[1]
|
||||
return True
|
||||
|
||||
|
||||
class FocusGridLayout(FocusWithColor, GridLayout):
|
||||
pass
|
||||
|
||||
|
||||
class FocusBoxLayout(FocusWithColor, BoxLayout):
|
||||
pass
|
||||
|
||||
|
||||
class FocusApp(App):
|
||||
|
||||
def build(self):
|
||||
root = FocusBoxLayout(padding=[10, 10], spacing=10)
|
||||
self.grid1 = grid1 = FocusGridLayout(cols=4, padding=[10, 10],
|
||||
spacing=10)
|
||||
self.grid2 = grid2 = FocusGridLayout(cols=4, padding=[10, 10],
|
||||
spacing=10)
|
||||
root.add_widget(FocusLabel(text='Left', size_hint_x=0.4))
|
||||
root.add_widget(grid1)
|
||||
root.add_widget(grid2)
|
||||
root.add_widget(FocusLabel(text='Right', size_hint_x=0.4))
|
||||
|
||||
for i in range(40):
|
||||
grid1.add_widget(FocusLabel(text='l' + str(i)))
|
||||
for i in range(40):
|
||||
grid2.add_widget(FocusLabel(text='r' + str(i)))
|
||||
|
||||
# make elements 29, 9 un-focusable. The widgets are displayed in
|
||||
# reverse order, so 9 = 39 - 10
|
||||
grid2.children[30].text = grid1.children[14].text =\
|
||||
grid2.children[15].text = grid1.children[34].text = 'Skip me'
|
||||
grid2.children[15].is_focusable = False
|
||||
grid2.children[30].is_focusable = False
|
||||
# similarly, make 39 - 14 = 25, and 5 un-focusable
|
||||
grid1.children[14].is_focusable = False
|
||||
grid1.children[34].is_focusable = False
|
||||
# don't move focus passed this element
|
||||
grid2.children[35].focus_next = StopIteration
|
||||
grid2.children[35].text = 'Stop forward'
|
||||
|
||||
# exchange the links between the sides so that it'll skip to the other
|
||||
# side in the middle. Remember that children are displayed reversed
|
||||
# in layouts.
|
||||
grid1.children[10].focus_next = grid2.children[9]
|
||||
grid2.children[10].focus_next = grid1.children[9]
|
||||
grid1.children[10].text = '-->'
|
||||
grid2.children[10].text = '<--'
|
||||
return root
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
FocusApp().run()
|
||||
31
freechat-client/share/kivy-examples/widgets/image_mipmap.py
Normal file
31
freechat-client/share/kivy-examples/widgets/image_mipmap.py
Normal file
@@ -0,0 +1,31 @@
|
||||
'''
|
||||
Image mipmap
|
||||
============
|
||||
|
||||
Difference between a mipmapped image and no mipmap image.
|
||||
The lower image is normal, and the top image is mipmapped.
|
||||
'''
|
||||
|
||||
import kivy
|
||||
kivy.require('1.0.7')
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.scatter import ScatterPlane
|
||||
from kivy.uix.image import Image
|
||||
from os.path import join
|
||||
|
||||
|
||||
class LabelMipmapTest(App):
|
||||
def build(self):
|
||||
s = ScatterPlane(scale=.5)
|
||||
filename = join(kivy.kivy_data_dir, 'logo', 'kivy-icon-256.png')
|
||||
l1 = Image(source=filename, pos=(400, 100), size=(256, 256))
|
||||
l2 = Image(source=filename, pos=(400, 356), size=(256, 256),
|
||||
mipmap=True)
|
||||
s.add_widget(l1)
|
||||
s.add_widget(l2)
|
||||
return s
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
LabelMipmapTest().run()
|
||||
@@ -0,0 +1,42 @@
|
||||
import kivy
|
||||
kivy.require('1.0.8')
|
||||
|
||||
from kivy.core.window import Window
|
||||
from kivy.uix.widget import Widget
|
||||
|
||||
|
||||
class MyKeyboardListener(Widget):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(MyKeyboardListener, self).__init__(**kwargs)
|
||||
self._keyboard = Window.request_keyboard(
|
||||
self._keyboard_closed, self, 'text')
|
||||
if self._keyboard.widget:
|
||||
# If it exists, this widget is a VKeyboard object which you can use
|
||||
# to change the keyboard layout.
|
||||
pass
|
||||
self._keyboard.bind(on_key_down=self._on_keyboard_down)
|
||||
|
||||
def _keyboard_closed(self):
|
||||
print('My keyboard have been closed!')
|
||||
self._keyboard.unbind(on_key_down=self._on_keyboard_down)
|
||||
self._keyboard = None
|
||||
|
||||
def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
|
||||
print('The key', keycode, 'have been pressed')
|
||||
print(' - text is %r' % text)
|
||||
print(' - modifiers are %r' % modifiers)
|
||||
|
||||
# Keycode is composed of an integer + a string
|
||||
# If we hit escape, release the keyboard
|
||||
if keycode[1] == 'escape':
|
||||
keyboard.release()
|
||||
|
||||
# Return True to accept the key. Otherwise, it will be used by
|
||||
# the system.
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from kivy.base import runTouchApp
|
||||
runTouchApp(MyKeyboardListener())
|
||||
28
freechat-client/share/kivy-examples/widgets/label_mipmap.py
Normal file
28
freechat-client/share/kivy-examples/widgets/label_mipmap.py
Normal file
@@ -0,0 +1,28 @@
|
||||
'''
|
||||
Label mipmap
|
||||
============
|
||||
|
||||
This show how to create a mipmapped label, and the visual difference between a
|
||||
non mipmapped and mipmapped label.
|
||||
'''
|
||||
|
||||
import kivy
|
||||
kivy.require('1.0.7')
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.scatter import ScatterPlane
|
||||
from kivy.uix.label import Label
|
||||
|
||||
|
||||
class LabelMipmapTest(App):
|
||||
def build(self):
|
||||
s = ScatterPlane(scale=.5)
|
||||
l1 = Label(text='Kivy rulz', font_size=98, pos=(400, 100), mipmap=True)
|
||||
l2 = Label(text='Kivy rulz', font_size=98, pos=(400, 328))
|
||||
s.add_widget(l1)
|
||||
s.add_widget(l2)
|
||||
return s
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
LabelMipmapTest().run()
|
||||
193
freechat-client/share/kivy-examples/widgets/label_sizing.py
Normal file
193
freechat-client/share/kivy-examples/widgets/label_sizing.py
Normal file
@@ -0,0 +1,193 @@
|
||||
|
||||
"""
|
||||
Label textsize
|
||||
============
|
||||
|
||||
This example shows how to size a Label to its content (texture_size) and how
|
||||
setting text_size controls text wrapping.
|
||||
"""
|
||||
from kivy.app import App
|
||||
from kivy.clock import Clock
|
||||
from kivy.lang import Builder
|
||||
from kivy.properties import StringProperty, NumericProperty, BooleanProperty
|
||||
|
||||
# Copied from https://en.wikipedia.org/wiki/A_Tale_of_Two_Cities
|
||||
# Published in 1859 and public domain.
|
||||
# The newline after the title will help demonstrate halign
|
||||
_example_title_text = 'A Tale of Two Cities, by Charles Dickens\n'
|
||||
_example_text = """It was the best of times, it was the worst of times,
|
||||
it was the age of wisdom, it was the age of foolishness, it was the epoch of
|
||||
belief, it was the epoch of incredulity, it was the season of Light, it was
|
||||
the season of Darkness, it was the spring of hope, it was the winter of
|
||||
despair, we had everything before us, we had nothing before us, we were all
|
||||
going direct to Heaven, we were all going direct the other way - in short,
|
||||
the period was so far like the present period, that some of its noisiest
|
||||
authorities insisted on its being received, for good or for evil, in the
|
||||
superlative degree of comparison only.
|
||||
"""
|
||||
|
||||
# Note: Many of the Widgets (StackLayout, ToggleButton, Spinner) have
|
||||
# defaults set at the bottom of the KV, where DemoLabel and HeadingLabel
|
||||
# are also defined.
|
||||
_kv_code = """
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
|
||||
HeadingLabel:
|
||||
text: 'These modify all demonstration Labels'
|
||||
|
||||
StackLayout:
|
||||
# Button is a subclass of Label and can be sized
|
||||
# to text in the same way
|
||||
|
||||
Button:
|
||||
text: 'Reset'
|
||||
on_press: app.reset_words()
|
||||
|
||||
ToggleButton:
|
||||
text: 'Shorten'
|
||||
on_state:
|
||||
app.shorten=self.state=='down'
|
||||
|
||||
ToggleButton:
|
||||
text: 'max_lines=3'
|
||||
on_state:
|
||||
app.max_lines=3 if self.state=='down' else 0
|
||||
|
||||
Spinner:
|
||||
text: 'bottom'
|
||||
values: 'bottom', 'middle', 'top'
|
||||
on_text: app.valign=self.text
|
||||
|
||||
Spinner:
|
||||
text: 'left'
|
||||
values: 'left', 'center', 'right', 'justify'
|
||||
on_text: app.halign=self.text
|
||||
|
||||
GridLayout:
|
||||
id: grid_layout
|
||||
cols: 2
|
||||
height: cm(6)
|
||||
size_hint_y: None
|
||||
|
||||
HeadingLabel:
|
||||
text: "Default, no text_size set"
|
||||
|
||||
HeadingLabel:
|
||||
text: 'text_size bound to size'
|
||||
|
||||
DemoLabel:
|
||||
id: left_content
|
||||
disabled_color: 0, 0, 0, 0
|
||||
|
||||
DemoLabel:
|
||||
id: right_content
|
||||
text_size: self.size
|
||||
padding: dp(6), dp(6)
|
||||
|
||||
ToggleButton:
|
||||
text: 'Disable left'
|
||||
on_state:
|
||||
left_content.disabled=self.state=='down'
|
||||
|
||||
# Need one Widget without size_hint_y: None, so that BoxLayout fills
|
||||
# available space.
|
||||
HeadingLabel:
|
||||
text: 'text_size width set, size bound to texture_size'
|
||||
text_size: self.size
|
||||
size_hint_y: 1
|
||||
|
||||
DemoLabel:
|
||||
id: bottom_content
|
||||
# This Label wraps and expands its height to fit the text because
|
||||
# only text_size width is set and the Label size binds to texture_size.
|
||||
text_size: self.width, None
|
||||
size: self.texture_size
|
||||
padding: mm(4), mm(4)
|
||||
size_hint_y: None
|
||||
|
||||
# The column heading labels have their width set by the parent,
|
||||
# but determine their height from the text.
|
||||
<HeadingLabel@Label>:
|
||||
bold: True
|
||||
padding: dp(6), dp(4)
|
||||
valign: 'bottom'
|
||||
height: self.texture_size[1]
|
||||
text_size: self.width, None
|
||||
size_hint_y: None
|
||||
|
||||
<ToggleButton,Button>:
|
||||
padding: dp(10), dp(8)
|
||||
size_hint: None, None
|
||||
size: self.texture_size
|
||||
|
||||
# This inherits Button and the modifications above, so reset size
|
||||
<Spinner>:
|
||||
size: sp(68), self.texture_size[1]
|
||||
|
||||
<DemoLabel@Label>:
|
||||
halign: app.halign
|
||||
valign: app.valign
|
||||
shorten: app.shorten
|
||||
max_lines: app.max_lines
|
||||
|
||||
canvas:
|
||||
Color:
|
||||
rgb: 68/255.0, 164/255.0, 201/255.0
|
||||
Line:
|
||||
rectangle: self.x, self.y, self.width, self.height
|
||||
|
||||
<StackLayout>:
|
||||
size_hint_y: None
|
||||
spacing: dp(6)
|
||||
padding: dp(6), dp(4)
|
||||
height: self.minimum_height
|
||||
"""
|
||||
|
||||
|
||||
class LabelTextureSizeExample(App):
|
||||
# All Labels use these properties, set to Label defaults
|
||||
valign = StringProperty('bottom')
|
||||
halign = StringProperty('left')
|
||||
shorten = BooleanProperty(False)
|
||||
max_lines = NumericProperty(0)
|
||||
|
||||
def build(self):
|
||||
self._add_word_ev = None
|
||||
return Builder.load_string(_kv_code)
|
||||
|
||||
def on_start(self):
|
||||
widget_ids = self.root.ids
|
||||
self.text_content_widgets = (widget_ids.left_content,
|
||||
widget_ids.right_content,
|
||||
widget_ids.bottom_content)
|
||||
self.reset_words()
|
||||
|
||||
def reset_words(self):
|
||||
if self._add_word_ev is not None:
|
||||
self._add_word_ev.cancel()
|
||||
self._add_word_ev = None
|
||||
for content_widget in self.text_content_widgets:
|
||||
content_widget.text = _example_title_text
|
||||
# initialize words generator
|
||||
self.words = (word for word in _example_text.split())
|
||||
self.add_word()
|
||||
|
||||
def add_word(self, dt=None):
|
||||
try:
|
||||
word = next(self.words)
|
||||
except StopIteration:
|
||||
return
|
||||
|
||||
for content_widget in self.text_content_widgets:
|
||||
content_widget.text += word + ' '
|
||||
|
||||
pause_time = 0.03 * len(word)
|
||||
if word.endswith(','):
|
||||
pause_time += 0.6
|
||||
|
||||
self._add_word_ev = Clock.schedule_once(self.add_word, pause_time)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
LabelTextureSizeExample().run()
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
'''
|
||||
Label textsize
|
||||
============
|
||||
|
||||
This example shows how the textsize and line_height property are used
|
||||
to format label widget
|
||||
'''
|
||||
|
||||
import kivy
|
||||
kivy.require('1.0.7')
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.label import Label
|
||||
|
||||
|
||||
_long_text = ("""Lorem ipsum dolor sit amet, consectetur adipiscing elit. """
|
||||
"""Phasellus odio nisi, pellentesque molestie adipiscing vitae, aliquam """
|
||||
"""at tellus. Fusce quis est ornare erat pulvinar elementum ut sed """
|
||||
"""felis. Donec vel neque mauris. In sit amet nunc sit amet diam dapibus"""
|
||||
""" lacinia. In sodales placerat mauris, ut euismod augue laoreet at. """
|
||||
"""Integer in neque non odio fermentum volutpat nec nec nulla. Donec et """
|
||||
"""risus non mi viverra posuere. Phasellus cursus augue purus, eget """
|
||||
"""volutpat leo. Phasellus sed dui vitae ipsum mattis facilisis vehicula"""
|
||||
""" eu justo.\n\n"""
|
||||
"""Quisque neque dolor, egestas sed venenatis eget, porta id ipsum. Ut """
|
||||
"""faucibus, massa vitae imperdiet rutrum, sem dolor rhoncus magna, non """
|
||||
"""lacinia nulla risus non dui. Nulla sit amet risus orci. Nunc libero """
|
||||
"""justo, interdum eu pulvinar vel, pulvinar et lectus. Phasellus sed """
|
||||
"""luctus diam. Pellentesque non feugiat dolor. Cras at dolor velit, """
|
||||
"""gravida congue velit. Aliquam erat volutpat. Nullam eu nunc dui, quis"""
|
||||
""" sagittis dolor. Ut nec dui eget odio pulvinar placerat. Pellentesque"""
|
||||
""" mi metus, tristique et placerat ac, pulvinar vel quam. Nam blandit """
|
||||
"""magna a urna imperdiet molestie. Nullam ut nisi eget enim laoreet """
|
||||
"""sodales sit amet a felis.\n""")
|
||||
|
||||
|
||||
class LabelTextSizeTest(App):
|
||||
def build(self):
|
||||
z = Label(
|
||||
text=_long_text,
|
||||
text_size=(600, None),
|
||||
line_height=1.5
|
||||
)
|
||||
return z
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
LabelTextSizeTest().run()
|
||||
@@ -0,0 +1,21 @@
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
|
||||
root = Builder.load_string('''
|
||||
Label:
|
||||
text:
|
||||
('[b]Hello[/b] [color=ff0099]World[/color]\\n'
|
||||
'[color=ff0099]Hello[/color] [b]World[/b]\\n'
|
||||
'[b]Hello[/b] [color=ff0099]World[/color]')
|
||||
markup: True
|
||||
font_size: '64pt'
|
||||
''')
|
||||
|
||||
|
||||
class LabelWithMarkup(App):
|
||||
def build(self):
|
||||
return root
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
LabelWithMarkup().run()
|
||||
@@ -0,0 +1,18 @@
|
||||
# Dynamic kv classes
|
||||
|
||||
from kivy.lang import Builder
|
||||
from kivy.base import runTouchApp
|
||||
|
||||
root = Builder.load_string('''
|
||||
<ImageButton@Button>:
|
||||
source: None
|
||||
Image:
|
||||
source: root.source
|
||||
center: root.center
|
||||
|
||||
ImageButton:
|
||||
source: 'kivy/data/logo/kivy-icon-512.png'
|
||||
''')
|
||||
|
||||
|
||||
runTouchApp(root)
|
||||
64
freechat-client/share/kivy-examples/widgets/pagelayout.py
Normal file
64
freechat-client/share/kivy-examples/widgets/pagelayout.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from kivy.base import runTouchApp
|
||||
from kivy.lang import Builder
|
||||
|
||||
kv = '''
|
||||
PageLayout:
|
||||
BoxLayout:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: 216/255., 195/255., 88/255., 1
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
|
||||
orientation: 'vertical'
|
||||
Label:
|
||||
size_hint_y: None
|
||||
height: 1.5 * self.texture_size[1]
|
||||
text: 'page 1'
|
||||
|
||||
Button:
|
||||
text: 'test'
|
||||
on_press: print("test")
|
||||
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
canvas:
|
||||
Color:
|
||||
rgba: 109/255., 8/255., 57/255., 1
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
|
||||
Label:
|
||||
text: 'page 2'
|
||||
|
||||
AsyncImage:
|
||||
source: 'http://kivy.org/logos/kivy-logo-black-64.png'
|
||||
|
||||
GridLayout:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: 37/255., 39/255., 30/255., 1
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
|
||||
cols: 2
|
||||
Label:
|
||||
text: 'page 3'
|
||||
AsyncImage:
|
||||
source: 'http://kivy.org/slides/kivyandroid-thumb.jpg'
|
||||
Button:
|
||||
text: 'test'
|
||||
on_press: print("test last page")
|
||||
AsyncImage:
|
||||
source: 'http://kivy.org/slides/kivypictures-thumb.jpg'
|
||||
Widget
|
||||
AsyncImage:
|
||||
source: 'http://kivy.org/slides/particlepanda-thumb.jpg'
|
||||
'''
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
runTouchApp(Builder.load_string(kv))
|
||||
35
freechat-client/share/kivy-examples/widgets/popup_with_kv.py
Normal file
35
freechat-client/share/kivy-examples/widgets/popup_with_kv.py
Normal file
@@ -0,0 +1,35 @@
|
||||
'''
|
||||
Example to show a Popup usage with the content from kv lang.
|
||||
'''
|
||||
from kivy.uix.popup import Popup
|
||||
from kivy.uix.button import Button
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
|
||||
Builder.load_string('''
|
||||
<CustomPopup>:
|
||||
size_hint: .5, .5
|
||||
auto_dismiss: False
|
||||
title: 'Hello world'
|
||||
Button:
|
||||
text: 'Click me to dismiss'
|
||||
on_press: root.dismiss()
|
||||
|
||||
''')
|
||||
|
||||
|
||||
class CustomPopup(Popup):
|
||||
pass
|
||||
|
||||
|
||||
class TestApp(App):
|
||||
def build(self):
|
||||
b = Button(on_press=self.show_popup, text="Show Popup")
|
||||
return b
|
||||
|
||||
def show_popup(self, b):
|
||||
p = CustomPopup()
|
||||
p.open()
|
||||
|
||||
|
||||
TestApp().run()
|
||||
Binary file not shown.
@@ -0,0 +1,119 @@
|
||||
from random import sample
|
||||
from string import ascii_lowercase
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
|
||||
|
||||
kv = """
|
||||
<Row@BoxLayout>:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgba: 0.5, 0.5, 0.5, 1
|
||||
Rectangle:
|
||||
size: self.size
|
||||
pos: self.pos
|
||||
value: ''
|
||||
Label:
|
||||
text: root.value
|
||||
|
||||
<Test>:
|
||||
canvas:
|
||||
Color:
|
||||
rgba: 0.3, 0.3, 0.3, 1
|
||||
Rectangle:
|
||||
size: self.size
|
||||
pos: self.pos
|
||||
rv: rv
|
||||
orientation: 'vertical'
|
||||
GridLayout:
|
||||
cols: 3
|
||||
rows: 2
|
||||
size_hint_y: None
|
||||
height: dp(108)
|
||||
padding: dp(8)
|
||||
spacing: dp(16)
|
||||
Button:
|
||||
text: 'Populate list'
|
||||
on_press: root.populate()
|
||||
Button:
|
||||
text: 'Sort list'
|
||||
on_press: root.sort()
|
||||
Button:
|
||||
text: 'Clear list'
|
||||
on_press: root.clear()
|
||||
BoxLayout:
|
||||
spacing: dp(8)
|
||||
Button:
|
||||
text: 'Insert new item'
|
||||
on_press: root.insert(new_item_input.text)
|
||||
TextInput:
|
||||
id: new_item_input
|
||||
size_hint_x: 0.6
|
||||
hint_text: 'value'
|
||||
padding: dp(10), dp(10), 0, 0
|
||||
BoxLayout:
|
||||
spacing: dp(8)
|
||||
Button:
|
||||
text: 'Update first item'
|
||||
on_press: root.update(update_item_input.text)
|
||||
TextInput:
|
||||
id: update_item_input
|
||||
size_hint_x: 0.6
|
||||
hint_text: 'new value'
|
||||
padding: dp(10), dp(10), 0, 0
|
||||
Button:
|
||||
text: 'Remove first item'
|
||||
on_press: root.remove()
|
||||
|
||||
RecycleView:
|
||||
id: rv
|
||||
scroll_type: ['bars', 'content']
|
||||
scroll_wheel_distance: dp(114)
|
||||
bar_width: dp(10)
|
||||
viewclass: 'Row'
|
||||
RecycleBoxLayout:
|
||||
default_size: None, dp(56)
|
||||
default_size_hint: 1, None
|
||||
size_hint_y: None
|
||||
height: self.minimum_height
|
||||
orientation: 'vertical'
|
||||
spacing: dp(2)
|
||||
"""
|
||||
|
||||
Builder.load_string(kv)
|
||||
|
||||
|
||||
class Test(BoxLayout):
|
||||
|
||||
def populate(self):
|
||||
self.rv.data = [{'value': ''.join(sample(ascii_lowercase, 6))}
|
||||
for x in range(50)]
|
||||
|
||||
def sort(self):
|
||||
self.rv.data = sorted(self.rv.data, key=lambda x: x['value'])
|
||||
|
||||
def clear(self):
|
||||
self.rv.data = []
|
||||
|
||||
def insert(self, value):
|
||||
self.rv.data.insert(0, {'value': value or 'default value'})
|
||||
|
||||
def update(self, value):
|
||||
if self.rv.data:
|
||||
self.rv.data[0]['value'] = value or 'default new value'
|
||||
self.rv.refresh_from_data()
|
||||
|
||||
def remove(self):
|
||||
if self.rv.data:
|
||||
self.rv.data.pop(0)
|
||||
|
||||
|
||||
class TestApp(App):
|
||||
def build(self):
|
||||
return Test()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
TestApp().run()
|
||||
128
freechat-client/share/kivy-examples/widgets/rstexample.py
Normal file
128
freechat-client/share/kivy-examples/widgets/rstexample.py
Normal file
@@ -0,0 +1,128 @@
|
||||
'''
|
||||
QuickReference for Rst
|
||||
======================
|
||||
|
||||
This is a markup example: [b]Hello[/b] [i]world[/i]
|
||||
And if i really want to write my code: &bl; Hello world &br;
|
||||
|
||||
And video widget
|
||||
----------------
|
||||
|
||||
.. video:: cityCC0.mpg
|
||||
|
||||
|
||||
Inline Markup
|
||||
-------------
|
||||
|
||||
- *emphasis*
|
||||
- **strong emphasis**
|
||||
- `interpreted text`
|
||||
- ``inline literal``
|
||||
- reference_
|
||||
- `phrase reference`_
|
||||
- anonymous__
|
||||
- _`inline internal target`
|
||||
|
||||
.. _top:
|
||||
|
||||
Internal crossreferences, like example_, or bottom_.
|
||||
|
||||
Image
|
||||
-----
|
||||
|
||||
Woot!
|
||||
|
||||
What about a little image ?
|
||||
|
||||
.. image:: kivy/data/logo/kivy-icon-256.png
|
||||
|
||||
Grid
|
||||
----
|
||||
|
||||
+------------+------------+-----------+
|
||||
| Header 1 | Header 2 | Header 3 |
|
||||
+============+============+===========+
|
||||
| body row 1 | column 2 | column 3 |
|
||||
+------------+------------+-----------+
|
||||
| body row 2 | column 2 | column 3 |
|
||||
+------------+------------+-----------+
|
||||
| body row 3 | column 2 | column 3 |
|
||||
+------------+------------+-----------+
|
||||
|
||||
Term list
|
||||
---------
|
||||
|
||||
:Authors:
|
||||
Tony J. (Tibs) Ibbs,
|
||||
David Goodger
|
||||
(and sundry other good-natured folks)
|
||||
|
||||
.. _example:
|
||||
|
||||
:Version: 1.0 of 2001/08/08
|
||||
:Dedication: To my father.
|
||||
|
||||
Definition list
|
||||
---------------
|
||||
|
||||
what
|
||||
Definition lists associate a term with a definition.
|
||||
|
||||
how
|
||||
The term is a one-line phrase, and the definition is one or more paragraphs
|
||||
or body elements, indented relative to the term. Blank lines are not allowed
|
||||
between term and definition.
|
||||
|
||||
|
||||
Block quotes
|
||||
------------
|
||||
|
||||
Block quotes are just:
|
||||
|
||||
Indented paragraphs,
|
||||
|
||||
and they may nest.
|
||||
|
||||
Admonitions
|
||||
-----------
|
||||
|
||||
.. warning::
|
||||
|
||||
This is just a Test.
|
||||
|
||||
.. note::
|
||||
|
||||
And this is just a note. Let's test some literal::
|
||||
|
||||
$ echo 'Hello world'
|
||||
Hello world
|
||||
|
||||
Ordered list
|
||||
------------
|
||||
|
||||
#. My item number one
|
||||
#. My item number two with some more content
|
||||
and it's continuing on the second line?
|
||||
#. My third item::
|
||||
|
||||
Oh wait, we can put code!
|
||||
|
||||
#. My four item::
|
||||
|
||||
No way.
|
||||
|
||||
.. _bottom:
|
||||
|
||||
Go to top_'''
|
||||
|
||||
from kivy.uix.rst import RstDocument
|
||||
from kivy.app import App
|
||||
|
||||
|
||||
class RstApp(App):
|
||||
def build(self):
|
||||
return RstDocument(text=__doc__)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
RstApp().run()
|
||||
53
freechat-client/share/kivy-examples/widgets/scatter.kv
Normal file
53
freechat-client/share/kivy-examples/widgets/scatter.kv
Normal file
@@ -0,0 +1,53 @@
|
||||
#:kivy 1.0
|
||||
|
||||
<MyScatter>:
|
||||
canvas:
|
||||
Color:
|
||||
hsv: 0, 1, .5
|
||||
Rectangle:
|
||||
size: self.size
|
||||
|
||||
canvas.after:
|
||||
Color:
|
||||
hsv: .1, 1, .5
|
||||
a: .2
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.bbox[1]
|
||||
|
||||
Color:
|
||||
rgb: 0, 1, 0
|
||||
Line:
|
||||
points: [self.x, self.top, self.right, self.top]
|
||||
Line:
|
||||
points: [self.x, self.y, self.x, self.top]
|
||||
Line:
|
||||
points: [self.center_x, self.y, self.center_x, self.top]
|
||||
Line:
|
||||
points: [self.x, self.center_y, self.right, self.center_y]
|
||||
|
||||
Line:
|
||||
points: [self.center[0], self.center[1], self.right, self.top]
|
||||
|
||||
|
||||
BoxLayout:
|
||||
size: root.size
|
||||
orientation: 'vertical'
|
||||
Label:
|
||||
text: 'Position\n' + str(root.pos)
|
||||
text_size: (root.width, None)
|
||||
Label:
|
||||
text: 'Size\n' + str(root.size)
|
||||
text_size: (root.width, None)
|
||||
Label:
|
||||
text: 'Center\n' + str(root.center)
|
||||
text_size: (root.width, None)
|
||||
Label:
|
||||
text: 'Bounding Box\n' + str(root.bbox)
|
||||
text_size: (root.width, None)
|
||||
Label:
|
||||
text: 'Top\n' + str(root.top)
|
||||
text_size: (root.width, None)
|
||||
Label:
|
||||
text: 'Right\n' + str(root.right)
|
||||
text_size: (root.width, None)
|
||||
16
freechat-client/share/kivy-examples/widgets/scatter.py
Normal file
16
freechat-client/share/kivy-examples/widgets/scatter.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from kivy.uix.scatter import Scatter
|
||||
from kivy.app import App
|
||||
|
||||
|
||||
class MyScatter(Scatter):
|
||||
pass
|
||||
|
||||
|
||||
class ScatterApp(App):
|
||||
def build(self):
|
||||
s = MyScatter(size=(400, 400), size_hint=(None, None))
|
||||
s.top = 500
|
||||
return s
|
||||
|
||||
|
||||
ScatterApp().run()
|
||||
106
freechat-client/share/kivy-examples/widgets/screenmanager.py
Normal file
106
freechat-client/share/kivy-examples/widgets/screenmanager.py
Normal file
@@ -0,0 +1,106 @@
|
||||
from kivy.app import App
|
||||
from kivy.uix.screenmanager import ScreenManager, Screen
|
||||
from kivy.properties import NumericProperty
|
||||
from kivy.lang import Builder
|
||||
|
||||
Builder.load_string('''
|
||||
#:import random random.random
|
||||
#:import SlideTransition kivy.uix.screenmanager.SlideTransition
|
||||
#:import SwapTransition kivy.uix.screenmanager.SwapTransition
|
||||
#:import WipeTransition kivy.uix.screenmanager.WipeTransition
|
||||
#:import FadeTransition kivy.uix.screenmanager.FadeTransition
|
||||
#:import RiseInTransition kivy.uix.screenmanager.RiseInTransition
|
||||
#:import FallOutTransition kivy.uix.screenmanager.FallOutTransition
|
||||
#:import NoTransition kivy.uix.screenmanager.NoTransition
|
||||
|
||||
<CustomScreen>:
|
||||
hue: random()
|
||||
canvas:
|
||||
Color:
|
||||
hsv: self.hue, .5, .3
|
||||
Rectangle:
|
||||
size: self.size
|
||||
|
||||
Label:
|
||||
font_size: 42
|
||||
text: root.name
|
||||
|
||||
Button:
|
||||
text: 'Next screen'
|
||||
size_hint: None, None
|
||||
pos_hint: {'right': 1}
|
||||
size: 150, 50
|
||||
on_release: root.manager.current = root.manager.next()
|
||||
|
||||
Button:
|
||||
text: 'Previous screen'
|
||||
size_hint: None, None
|
||||
size: 150, 50
|
||||
on_release: root.manager.current = root.manager.previous()
|
||||
|
||||
BoxLayout:
|
||||
size_hint: .5, None
|
||||
height: 250
|
||||
pos_hint: {'center_x': .5}
|
||||
orientation: 'vertical'
|
||||
|
||||
Button:
|
||||
text: 'Use SlideTransition with "up" direction'
|
||||
on_release: root.manager.transition = \
|
||||
SlideTransition(direction="up")
|
||||
|
||||
Button:
|
||||
text: 'Use SlideTransition with "down" direction'
|
||||
on_release: root.manager.transition = \
|
||||
SlideTransition(direction="down")
|
||||
|
||||
Button:
|
||||
text: 'Use SlideTransition with "left" direction'
|
||||
on_release: root.manager.transition = \
|
||||
SlideTransition(direction="left")
|
||||
|
||||
Button:
|
||||
text: 'Use SlideTransition with "right" direction'
|
||||
on_release: root.manager.transition = \
|
||||
SlideTransition(direction="right")
|
||||
|
||||
Button:
|
||||
text: 'Use SwapTransition'
|
||||
on_release: root.manager.transition = SwapTransition()
|
||||
|
||||
Button:
|
||||
text: 'Use WipeTransition'
|
||||
on_release: root.manager.transition = WipeTransition()
|
||||
|
||||
Button:
|
||||
text: 'Use FadeTransition'
|
||||
on_release: root.manager.transition = FadeTransition()
|
||||
|
||||
Button:
|
||||
text: 'Use FallOutTransition'
|
||||
on_release: root.manager.transition = FallOutTransition()
|
||||
|
||||
Button:
|
||||
text: 'Use RiseInTransition'
|
||||
on_release: root.manager.transition = RiseInTransition()
|
||||
Button:
|
||||
text: 'Use NoTransition'
|
||||
on_release: root.manager.transition = NoTransition(duration=0)
|
||||
''')
|
||||
|
||||
|
||||
class CustomScreen(Screen):
|
||||
hue = NumericProperty(0)
|
||||
|
||||
|
||||
class ScreenManagerApp(App):
|
||||
|
||||
def build(self):
|
||||
root = ScreenManager()
|
||||
for x in range(4):
|
||||
root.add_widget(CustomScreen(name='Screen %d' % x))
|
||||
return root
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ScreenManagerApp().run()
|
||||
16
freechat-client/share/kivy-examples/widgets/scrollview.kv
Normal file
16
freechat-client/share/kivy-examples/widgets/scrollview.kv
Normal file
@@ -0,0 +1,16 @@
|
||||
#:kivy 1.0.4
|
||||
<ScrollView>:
|
||||
canvas:
|
||||
Color:
|
||||
rgb: 1, 0, 0
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
|
||||
<GridLayout>:
|
||||
canvas:
|
||||
Color:
|
||||
rgb: 1, 1, 0
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
40
freechat-client/share/kivy-examples/widgets/scrollview.py
Normal file
40
freechat-client/share/kivy-examples/widgets/scrollview.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import kivy
|
||||
kivy.require('1.0.8')
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.button import Button
|
||||
from kivy.uix.scrollview import ScrollView
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
|
||||
|
||||
class ScrollViewApp(App):
|
||||
|
||||
def build(self):
|
||||
|
||||
# create a default grid layout with custom width/height
|
||||
layout = GridLayout(cols=1, padding=10, spacing=10,
|
||||
size_hint=(None, None), width=500)
|
||||
|
||||
# when we add children to the grid layout, its size doesn't change at
|
||||
# all. we need to ensure that the height will be the minimum required
|
||||
# to contain all the childs. (otherwise, we'll child outside the
|
||||
# bounding box of the childs)
|
||||
layout.bind(minimum_height=layout.setter('height'))
|
||||
|
||||
# add button into that grid
|
||||
for i in range(30):
|
||||
btn = Button(text=str(i), size=(480, 40),
|
||||
size_hint=(None, None))
|
||||
layout.add_widget(btn)
|
||||
|
||||
# create a scroll view, with a size < size of the grid
|
||||
root = ScrollView(size_hint=(None, None), size=(500, 320),
|
||||
pos_hint={'center_x': .5, 'center_y': .5}, do_scroll_x=False)
|
||||
root.add_widget(layout)
|
||||
|
||||
return root
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
ScrollViewApp().run()
|
||||
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
title=main
|
||||
author=seesaw
|
||||
orientation=portrait
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 27 KiB |
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 305 KiB |
@@ -0,0 +1,63 @@
|
||||
#:kivy 1.0.9
|
||||
<AnimatedButton>:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgb: (1, 1, 1)
|
||||
BorderImage:
|
||||
border: root.border if root.border else (16, 16, 16, 16)
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
texture: self.texture_background
|
||||
|
||||
<gifScatter>
|
||||
on_size: self.center = win.Window.center
|
||||
size: imag.size
|
||||
size_hint: None, None
|
||||
Image:
|
||||
id: imag
|
||||
source: 'data/images/simple_cv_joint_animated.gif'
|
||||
on_touch_down: root.parent.parent.parent.currentObj = self
|
||||
|
||||
<zipScatter>
|
||||
on_size: self.center = win.Window.center
|
||||
size: imag.size
|
||||
size_hint: None, None
|
||||
Image:
|
||||
id: imag
|
||||
source: 'data/images/cube.zip'
|
||||
anim_delay: 0.05
|
||||
on_touch_down: root.parent.parent.parent.currentObj = self
|
||||
|
||||
<jpgScatter>
|
||||
on_size: self.center = win.Window.center
|
||||
size: imag.size
|
||||
size_hint: None, None
|
||||
Image:
|
||||
id: imag
|
||||
source: 'data/images/bird.zip'
|
||||
on_touch_down: root.parent.parent.parent.currentObj = self
|
||||
|
||||
<Right_Frame>
|
||||
size_hint: (.2, 1)
|
||||
padding: 10
|
||||
cols: 1
|
||||
canvas:
|
||||
Color:
|
||||
rgba: .1,.45,.31,.9
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size:self.size
|
||||
Label:
|
||||
halign: 'center'
|
||||
text_size: self.size
|
||||
text: root.currentObj.source if root.currentObj else 'click on a Image to change it\'s properties'
|
||||
Label:
|
||||
id: spdlbl
|
||||
halign: 'center'
|
||||
text_size: self.size
|
||||
text: 'No Image selected' if not root.currentObj else 'Animation speed: %f FPS' %(1/root.currentObj.anim_delay) if root.currentObj.anim_delay > 0 else 'Animation speed: 0 FPS'
|
||||
Slider:
|
||||
min:0
|
||||
max: 100 if root.currentObj else 0
|
||||
value: (1/root.currentObj.anim_delay) if (root.currentObj and root.currentObj.anim_delay>0) else 0
|
||||
on_value: root.on_value(self, args[1], spdlbl)
|
||||
@@ -0,0 +1,150 @@
|
||||
import kivy
|
||||
kivy.require('1.0.8')
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.uix.gridlayout import GridLayout
|
||||
from uix.custom_button import AnimatedButton
|
||||
from kivy.uix.scatter import Scatter
|
||||
from kivy.properties import ObjectProperty
|
||||
|
||||
|
||||
class gifScatter(Scatter):
|
||||
def __init__(self, **kwargs):
|
||||
super(gifScatter, self).__init__()
|
||||
|
||||
|
||||
class zipScatter(Scatter):
|
||||
def __init__(self, **kwargs):
|
||||
super(zipScatter, self).__init__()
|
||||
|
||||
|
||||
class jpgScatter(Scatter):
|
||||
def __init__(self, **kwargs):
|
||||
super(jpgScatter, self).__init__()
|
||||
|
||||
|
||||
class Right_Frame(GridLayout):
|
||||
|
||||
currentObj = ObjectProperty(None)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Right_Frame, self).__init__()
|
||||
|
||||
def on_value(self, *l):
|
||||
if self.currentObj:
|
||||
if abs(l[1]) <= 0:
|
||||
self.currentObj.anim_delay = -1
|
||||
l[2].text = 'Animation speed: %f FPS' % 0
|
||||
else:
|
||||
self.currentObj.anim_delay = 1 / l[1]
|
||||
l[2].text = 'Animation speed: %f FPS' % (
|
||||
1 / self.currentObj.anim_delay)
|
||||
else:
|
||||
l[0].max = 0
|
||||
l[2].text = 'No Image selected'
|
||||
|
||||
|
||||
class mainclass(FloatLayout):
|
||||
|
||||
currentObj = ObjectProperty(None)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(mainclass, self).__init__()
|
||||
|
||||
# initialize variables
|
||||
self.sign = .10
|
||||
|
||||
# setup Layouts
|
||||
layout = GridLayout(size_hint=(1, 1), cols=3, rows=1)
|
||||
left_frame = GridLayout(size_hint=(.25, 1), cols=1)
|
||||
client_frame = FloatLayout(size_hint=(1, 1))
|
||||
self.right_frame = Right_Frame()
|
||||
|
||||
# setup buttons in left frame
|
||||
but_load_gif = AnimatedButton(text='load gif', halign='center')
|
||||
but_load_zip_png = AnimatedButton(text='load zipped\n png/s',
|
||||
halign='center')
|
||||
but_load_zip_jpg = AnimatedButton(text='load zipped\n jpg/s',
|
||||
halign='center')
|
||||
but_animated = AnimatedButton(text='animated button\n'
|
||||
'made using\nSequenced Images\n press to animate',
|
||||
halign='center',
|
||||
background_normal='data/images/button_white.png',
|
||||
background_down='data/images/button_white_animated.zip')
|
||||
but_animated_normal = AnimatedButton(text='borderless\n'
|
||||
'animated button\npress to stop',
|
||||
halign='center',
|
||||
background_down='data/images/button_white.png',
|
||||
background_normal='data/images/button_white_animated.zip')
|
||||
but_animated_borderless = AnimatedButton(text='Borderless',
|
||||
background_normal='data/images/info.png',
|
||||
background_down='data/images/info.zip', halign='center')
|
||||
but_animated_bordered = AnimatedButton(text='With Border',
|
||||
background_normal='data/images/info.png',
|
||||
background_down='data/images/info.zip', halign='center')
|
||||
|
||||
# Handle button press/release
|
||||
def load_images(*l):
|
||||
if l[0].text == 'load gif' or l[0].text == 'load gif\n from cache':
|
||||
l[0].text = 'load gif\n from cache'
|
||||
sctr = gifScatter()
|
||||
if (l[0].text == 'load zipped\n png/s' or
|
||||
l[0].text == 'load zipped\n png/s from cache'):
|
||||
l[0].text = 'load zipped\n png/s from cache'
|
||||
sctr = zipScatter()
|
||||
if (l[0].text == 'load zipped\n jpg/s' or
|
||||
l[0].text == 'load zipped\n jpg/s from cache'):
|
||||
l[0].text = 'load zipped\n jpg/s from cache'
|
||||
sctr = jpgScatter()
|
||||
|
||||
client_frame.add_widget(sctr, 1)
|
||||
|
||||
# position scatter
|
||||
sctr.pos = (240 + self.sign, 200 + self.sign)
|
||||
self.sign += 10
|
||||
if self.sign > 200:
|
||||
self.sign = 10
|
||||
sctr.pos = (300, 200 - self.sign)
|
||||
|
||||
# bind function on on_release
|
||||
but_load_gif.bind(on_release=load_images)
|
||||
but_load_zip_png.bind(on_release=load_images)
|
||||
but_load_zip_jpg.bind(on_release=load_images)
|
||||
|
||||
# add widgets to left frame
|
||||
left_frame.add_widget(but_load_gif)
|
||||
left_frame.add_widget(but_load_zip_png)
|
||||
left_frame.add_widget(but_load_zip_jpg)
|
||||
left_frame.add_widget(but_animated)
|
||||
left_frame.add_widget(but_animated_normal)
|
||||
left_frame.add_widget(but_animated_borderless)
|
||||
left_frame.add_widget(but_animated_bordered)
|
||||
|
||||
# set/remove border for borderless widgets (16,16,16,16) by default
|
||||
but_animated_normal.border = \
|
||||
but_animated_borderless.border = (0, 0, 0, 0)
|
||||
|
||||
# add widgets to the main layout
|
||||
layout.add_widget(left_frame)
|
||||
layout.add_widget(client_frame)
|
||||
layout.add_widget(self.right_frame)
|
||||
|
||||
# add main layout to root
|
||||
self.add_widget(layout)
|
||||
|
||||
def on_currentObj(self, *l):
|
||||
self.right_frame.currentObj = self.currentObj
|
||||
|
||||
|
||||
class mainApp(App):
|
||||
|
||||
def build(self):
|
||||
upl = mainclass()
|
||||
upl.size_hint = (1, 1)
|
||||
upl.pos_hint = {'top': 0, 'right': 1}
|
||||
return upl
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mainApp().run()
|
||||
@@ -0,0 +1,7 @@
|
||||
'''
|
||||
UIX
|
||||
===
|
||||
|
||||
The `uix` contains all the class for creating and arranging Custom Widgets.
|
||||
A widget is an element of a graphical user interface.
|
||||
'''
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,101 @@
|
||||
|
||||
__all__ = ('AnimatedButton')
|
||||
|
||||
from kivy.factory import Factory
|
||||
from kivy.uix.label import Label
|
||||
from kivy.uix.image import Image
|
||||
from kivy.graphics import *
|
||||
from kivy.properties import StringProperty, OptionProperty, \
|
||||
ObjectProperty, BooleanProperty
|
||||
|
||||
|
||||
class AnimatedButton(Label):
|
||||
|
||||
state = OptionProperty('normal', options=('normal', 'down'))
|
||||
allow_stretch = BooleanProperty(True)
|
||||
keep_ratio = BooleanProperty(False)
|
||||
border = ObjectProperty(None)
|
||||
anim_delay = ObjectProperty(None)
|
||||
background_normal = StringProperty(
|
||||
'atlas://data/images/defaulttheme/button')
|
||||
texture_background = ObjectProperty(None)
|
||||
background_down = StringProperty(
|
||||
'atlas://data/images/defaulttheme/button_pressed')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(AnimatedButton, self).__init__(**kwargs)
|
||||
|
||||
self.register_event_type('on_press')
|
||||
self.register_event_type('on_release')
|
||||
# borderImage.border by default is ...
|
||||
self.border = (16, 16, 16, 16)
|
||||
# Image to display depending on state
|
||||
self.img = Image(
|
||||
source=self.background_normal,
|
||||
allow_stretch=self.allow_stretch,
|
||||
keep_ratio=self.keep_ratio,
|
||||
mipmap=True)
|
||||
|
||||
# reset animation if anim_delay is changed
|
||||
def anim_reset(*l):
|
||||
self.img.anim_delay = self.anim_delay
|
||||
|
||||
self.bind(anim_delay=anim_reset)
|
||||
self.anim_delay = .1
|
||||
# update self.texture when image.texture changes
|
||||
self.img.bind(texture=self.on_tex_changed)
|
||||
self.on_tex_changed()
|
||||
|
||||
# update image source when background image is changed
|
||||
def background_changed(*l):
|
||||
self.img.source = self.background_normal
|
||||
self.anim_delay = .1
|
||||
|
||||
self.bind(background_normal=background_changed)
|
||||
|
||||
def on_tex_changed(self, *largs):
|
||||
self.texture_background = self.img.texture
|
||||
|
||||
def _do_press(self):
|
||||
self.state = 'down'
|
||||
|
||||
def _do_release(self):
|
||||
self.state = 'normal'
|
||||
|
||||
def on_touch_down(self, touch):
|
||||
if not self.collide_point(touch.x, touch.y):
|
||||
return False
|
||||
if repr(self) in touch.ud:
|
||||
return False
|
||||
touch.grab(self)
|
||||
touch.ud[repr(self)] = True
|
||||
_animdelay = self.img.anim_delay
|
||||
self.img.source = self.background_down
|
||||
self.img.anim_delay = _animdelay
|
||||
self._do_press()
|
||||
self.dispatch('on_press')
|
||||
return True
|
||||
|
||||
def on_touch_move(self, touch):
|
||||
return repr(self) in touch.ud
|
||||
|
||||
def on_touch_up(self, touch):
|
||||
if touch.grab_current is not self:
|
||||
return
|
||||
assert(repr(self) in touch.ud)
|
||||
touch.ungrab(self)
|
||||
_animdelay = self.img._coreimage.anim_delay
|
||||
self.img.source = self.background_normal
|
||||
self.anim_delay = _animdelay
|
||||
self._do_release()
|
||||
self.dispatch('on_release')
|
||||
return True
|
||||
|
||||
def on_press(self):
|
||||
pass
|
||||
|
||||
def on_release(self):
|
||||
pass
|
||||
|
||||
|
||||
Factory.register('AnimatedButton', cls=AnimatedButton)
|
||||
93
freechat-client/share/kivy-examples/widgets/settings.py
Normal file
93
freechat-client/share/kivy-examples/widgets/settings.py
Normal file
@@ -0,0 +1,93 @@
|
||||
from kivy.app import App
|
||||
from kivy.uix.button import Button
|
||||
from kivy.uix.boxlayout import BoxLayout
|
||||
from kivy.uix.label import Label
|
||||
from kivy.uix.popup import Popup
|
||||
from kivy.uix.settings import (SettingsWithSidebar,
|
||||
SettingsWithSpinner,
|
||||
SettingsWithTabbedPanel)
|
||||
from kivy.properties import OptionProperty, ObjectProperty
|
||||
|
||||
|
||||
class SettingsApp(App):
|
||||
|
||||
display_type = OptionProperty('normal', options=['normal', 'popup'])
|
||||
|
||||
settings_popup = ObjectProperty(None, allownone=True)
|
||||
|
||||
def build(self):
|
||||
|
||||
paneltype = Label(text='What kind of settings panel to use?')
|
||||
|
||||
sidebar_button = Button(text='Sidebar')
|
||||
sidebar_button.bind(on_press=lambda j: self.set_settings_cls(
|
||||
SettingsWithSidebar))
|
||||
spinner_button = Button(text='Spinner')
|
||||
spinner_button.bind(on_press=lambda j: self.set_settings_cls(
|
||||
SettingsWithSpinner))
|
||||
tabbed_button = Button(text='TabbedPanel')
|
||||
tabbed_button.bind(on_press=lambda j: self.set_settings_cls(
|
||||
SettingsWithTabbedPanel))
|
||||
|
||||
buttons = BoxLayout(orientation='horizontal')
|
||||
buttons.add_widget(sidebar_button)
|
||||
buttons.add_widget(spinner_button)
|
||||
buttons.add_widget(tabbed_button)
|
||||
|
||||
displaytype = Label(text='How to display the settings?')
|
||||
display_buttons = BoxLayout(orientation='horizontal')
|
||||
onwin_button = Button(text='on window')
|
||||
onwin_button.bind(on_press=lambda j: self.set_display_type('normal'))
|
||||
popup_button = Button(text='in a popup')
|
||||
popup_button.bind(on_press=lambda j: self.set_display_type('popup'))
|
||||
display_buttons.add_widget(onwin_button)
|
||||
display_buttons.add_widget(popup_button)
|
||||
|
||||
instruction = Label(text='Click to open the settings panel:')
|
||||
settings_button = Button(text='Open settings')
|
||||
settings_button.bind(on_press=self.open_settings)
|
||||
|
||||
layout = BoxLayout(orientation='vertical')
|
||||
layout.add_widget(paneltype)
|
||||
layout.add_widget(buttons)
|
||||
layout.add_widget(displaytype)
|
||||
layout.add_widget(display_buttons)
|
||||
layout.add_widget(instruction)
|
||||
layout.add_widget(settings_button)
|
||||
|
||||
return layout
|
||||
|
||||
def on_settings_cls(self, *args):
|
||||
self.destroy_settings()
|
||||
|
||||
def set_settings_cls(self, panel_type):
|
||||
self.settings_cls = panel_type
|
||||
|
||||
def set_display_type(self, display_type):
|
||||
self.destroy_settings()
|
||||
self.display_type = display_type
|
||||
|
||||
def display_settings(self, settings):
|
||||
if self.display_type == 'popup':
|
||||
p = self.settings_popup
|
||||
if p is None:
|
||||
self.settings_popup = p = Popup(content=settings,
|
||||
title='Settings',
|
||||
size_hint=(0.8, 0.8))
|
||||
if p.content is not settings:
|
||||
p.content = settings
|
||||
p.open()
|
||||
else:
|
||||
super(SettingsApp, self).display_settings(settings)
|
||||
|
||||
def close_settings(self, *args):
|
||||
if self.display_type == 'popup':
|
||||
p = self.settings_popup
|
||||
if p is not None:
|
||||
p.dismiss()
|
||||
else:
|
||||
super(SettingsApp, self).close_settings()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
SettingsApp().run()
|
||||
80
freechat-client/share/kivy-examples/widgets/shorten_text.py
Normal file
80
freechat-client/share/kivy-examples/widgets/shorten_text.py
Normal file
@@ -0,0 +1,80 @@
|
||||
'''
|
||||
Demonstrate shorten / number of line in label
|
||||
=============================================
|
||||
|
||||
--------------- ------- -------------------------------------------------------
|
||||
Number of lines Shorten Behavior
|
||||
--------------- ------- -------------------------------------------------------
|
||||
0 (unlimited) False Default behavior
|
||||
1 False Display as much as possible, at least one word
|
||||
N False Display as much as possible
|
||||
0 (unlimited) True Default behavior (as kivy <= 1.7 series)
|
||||
1 True Display as much as possible, shorten long word.
|
||||
N True Display as much as possible, shorten long word.
|
||||
--------------- ------- -------------------------------------------------------
|
||||
|
||||
'''
|
||||
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.lang import Builder
|
||||
|
||||
kv = '''
|
||||
<LabeledSlider@Slider>:
|
||||
step: 1
|
||||
Label:
|
||||
text: '{}'.format(int(root.value))
|
||||
size: self.texture_size
|
||||
top: root.center_y - sp(20)
|
||||
center_x: root.value_pos[0]
|
||||
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
BoxLayout:
|
||||
spacing: '10dp'
|
||||
padding: '4dp'
|
||||
size_hint_y: None
|
||||
height: '48dp'
|
||||
LabeledSlider:
|
||||
id: slider
|
||||
value: 500
|
||||
min: 25
|
||||
max: root.width
|
||||
on_value: self.value = int(self.value)
|
||||
ToggleButton:
|
||||
id: shorten
|
||||
text: 'Shorten'
|
||||
LabeledSlider:
|
||||
id: max_lines
|
||||
value: 0
|
||||
min: 0
|
||||
max: 5
|
||||
|
||||
AnchorLayout:
|
||||
RelativeLayout:
|
||||
size_hint: None, None
|
||||
size: slider.value, 50
|
||||
canvas:
|
||||
Color:
|
||||
rgb: .4, .4, .4
|
||||
Rectangle:
|
||||
size: self.size
|
||||
Label:
|
||||
size_hint: 1, 1
|
||||
text_size: self.size
|
||||
shorten: shorten.state == 'down'
|
||||
max_lines: max_lines.value
|
||||
valign: 'middle'
|
||||
halign: 'center'
|
||||
color: (1, 1, 1, 1)
|
||||
font_size: 22
|
||||
text: 'Michaelangelo Smith'
|
||||
'''
|
||||
|
||||
|
||||
class ShortenText(App):
|
||||
def build(self):
|
||||
return Builder.load_string(kv)
|
||||
|
||||
|
||||
ShortenText().run()
|
||||
17
freechat-client/share/kivy-examples/widgets/spinner.py
Normal file
17
freechat-client/share/kivy-examples/widgets/spinner.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from kivy.uix.spinner import Spinner
|
||||
from kivy.base import runTouchApp
|
||||
|
||||
spinner = Spinner(
|
||||
text='Home',
|
||||
values=('Home', 'Work', 'Other', 'Custom'),
|
||||
size_hint=(None, None), size=(100, 44),
|
||||
pos_hint={'center_x': .5, 'center_y': .5})
|
||||
|
||||
|
||||
def show_selected_value(spinner, text):
|
||||
print('The spinner', spinner, 'has text', text)
|
||||
|
||||
|
||||
spinner.bind(text=show_selected_value)
|
||||
|
||||
runTouchApp(spinner)
|
||||
74
freechat-client/share/kivy-examples/widgets/splitter.py
Normal file
74
freechat-client/share/kivy-examples/widgets/splitter.py
Normal file
@@ -0,0 +1,74 @@
|
||||
from kivy.base import runTouchApp
|
||||
from kivy.lang import Builder
|
||||
|
||||
bl = Builder.load_string('''
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: sp(60)
|
||||
Label:
|
||||
text: 'keep_within_parent?'
|
||||
CheckBox:
|
||||
id: in_parent_box
|
||||
active: False
|
||||
Label:
|
||||
text: 'rescale_with_parent?'
|
||||
CheckBox:
|
||||
id: rescale_box
|
||||
active: False
|
||||
BoxLayout:
|
||||
orientation: 'horizontal'
|
||||
Button:
|
||||
text: 'left btn'
|
||||
size_hint_x: 0.3
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Button:
|
||||
text: "Btn0"
|
||||
BoxLayout:
|
||||
Splitter:
|
||||
sizable_from: 'right'
|
||||
keep_within_parent: in_parent_box.active
|
||||
rescale_with_parent: rescale_box.active
|
||||
Button:
|
||||
text: 'Btn5'
|
||||
Button:
|
||||
text: 'Btn6'
|
||||
BoxLayout:
|
||||
sizable_from: 'top'
|
||||
BoxLayout:
|
||||
orientation: 'horizontal'
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Button:
|
||||
text: "Btn1"
|
||||
Splitter:
|
||||
sizable_from: 'top'
|
||||
keep_within_parent: in_parent_box.active
|
||||
rescale_with_parent: rescale_box.active
|
||||
Button:
|
||||
text: "Btn2"
|
||||
Splitter:
|
||||
sizable_from: 'left'
|
||||
keep_within_parent: in_parent_box.active
|
||||
rescale_with_parent: rescale_box.active
|
||||
Button:
|
||||
text: "Btn3"
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
size_hint_x: 0.3
|
||||
Button:
|
||||
text: 'right btn'
|
||||
Splitter:
|
||||
sizable_from: 'bottom'
|
||||
keep_within_parent: in_parent_box.active
|
||||
rescale_with_parent: rescale_box.active
|
||||
Button:
|
||||
text: 'Btn7'
|
||||
Button:
|
||||
text: 'right btn'
|
||||
''')
|
||||
|
||||
|
||||
runTouchApp(bl)
|
||||
@@ -0,0 +1,317 @@
|
||||
'''
|
||||
TabbedPanel
|
||||
============
|
||||
|
||||
Test of the widget TabbedPanel showing all capabilities.
|
||||
'''
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.animation import Animation
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelHeader
|
||||
from kivy.factory import Factory
|
||||
|
||||
|
||||
class StandingHeader(TabbedPanelHeader):
|
||||
pass
|
||||
|
||||
|
||||
class CloseableHeader(TabbedPanelHeader):
|
||||
pass
|
||||
|
||||
|
||||
Factory.register('StandingHeader', cls=StandingHeader)
|
||||
Factory.register('CloseableHeader', cls=CloseableHeader)
|
||||
|
||||
from kivy.lang import Builder
|
||||
|
||||
Builder.load_string('''
|
||||
<TabShowcase>
|
||||
but: _but
|
||||
Button:
|
||||
id: _but
|
||||
text: 'Press to show Tabbed Panel'
|
||||
on_release: root.show_tab()
|
||||
|
||||
<StandingHeader>
|
||||
color: 0,0,0,0
|
||||
disabled_color: self.color
|
||||
Scatter:
|
||||
do_translation: False
|
||||
do_scale: False
|
||||
do_rotation: False
|
||||
auto_bring_to_front: False
|
||||
rotation: 70
|
||||
size_hint: None, None
|
||||
size: lbl.size
|
||||
center_x: root.center_x
|
||||
center_y: root.center_y
|
||||
Label:
|
||||
id: lbl
|
||||
text: root.text
|
||||
size: root.size
|
||||
color: 1, 1, 1, .5 if self.disabled else 1
|
||||
pos: 0,0
|
||||
|
||||
<PanelLeft>
|
||||
size_hint: (.45, .45)
|
||||
pos_hint: {'center_x': .25, 'y': .55}
|
||||
# replace the default tab with our custom tab class
|
||||
default_tab_cls: sh.__class__
|
||||
do_default_tab: True
|
||||
default_tab_content: default_content.__self__
|
||||
tab_width: 40
|
||||
tab_height: 70
|
||||
FloatLayout:
|
||||
RstDocument:
|
||||
id: default_content
|
||||
text: '\\n'.join(("Standing tabs", "-------------",\
|
||||
"Tabs in \\'%s\\' position" %root.tab_pos))
|
||||
Image:
|
||||
id: tab_2_content
|
||||
source: 'data/images/defaulttheme-0.png'
|
||||
Image:
|
||||
id: tab_3_content
|
||||
source: 'data/images/image-loading.gif'
|
||||
StandingHeader:
|
||||
id: sh
|
||||
content: tab_2_content.__self__
|
||||
text: 'tab 2'
|
||||
StandingHeader:
|
||||
content: tab_3_content
|
||||
text: 'tab 3'
|
||||
|
||||
<CloseableHeader>
|
||||
color: 0,0,0,0
|
||||
disabled_color: self.color
|
||||
# variable tab_width
|
||||
text: 'tabx'
|
||||
size_hint_x: None
|
||||
width: self.texture_size[0] + 40
|
||||
BoxLayout:
|
||||
pos: root.pos
|
||||
size_hint: None, None
|
||||
size: root.size
|
||||
padding: 3
|
||||
Label:
|
||||
id: lbl
|
||||
text: root.text
|
||||
BoxLayout:
|
||||
size_hint: None, 1
|
||||
orientation: 'vertical'
|
||||
width: 22
|
||||
Image:
|
||||
source: 'tools/theming/defaulttheme/close.png'
|
||||
on_touch_down:
|
||||
if self.collide_point(*args[1].pos) :\
|
||||
root.panel.remove_widget(root)
|
||||
|
||||
|
||||
<PanelRight>
|
||||
tab_pos: 'top_right'
|
||||
size_hint: (.45, .45)
|
||||
pos_hint: {'center_x': .75, 'y': .55}
|
||||
# replace the default tab with our custom tab
|
||||
default_tab: def_tab
|
||||
# allow variable tab width
|
||||
tab_width: None
|
||||
FloatLayout:
|
||||
RstDocument:
|
||||
id: default_content
|
||||
text: '\\n'.join(("Closeable tabs", "---------------",\
|
||||
"- The tabs above are also scrollable",\
|
||||
"- Tabs in \\'%s\\' position" %root.tab_pos))
|
||||
Image:
|
||||
id: tab_2_content
|
||||
source: 'data/images/defaulttheme-0.png'
|
||||
BoxLayout:
|
||||
id: tab_3_content
|
||||
BubbleButton:
|
||||
text: 'Press to add new tab'
|
||||
on_release: root.add_header()
|
||||
BubbleButton:
|
||||
text: 'Press set this tab as default'
|
||||
on_release: root.default_tab = tab3
|
||||
CloseableHeader:
|
||||
id: def_tab
|
||||
text: 'default tab'
|
||||
content:default_content.__self__
|
||||
panel: root
|
||||
CloseableHeader:
|
||||
text: 'tab2'
|
||||
content: tab_2_content.__self__
|
||||
panel: root
|
||||
CloseableHeader:
|
||||
id: tab3
|
||||
text: 'tab3'
|
||||
content: tab_3_content.__self__
|
||||
panel: root
|
||||
CloseableHeader:
|
||||
panel: root
|
||||
CloseableHeader:
|
||||
panel: root
|
||||
CloseableHeader:
|
||||
panel: root
|
||||
CloseableHeader:
|
||||
panel: root
|
||||
CloseableHeader:
|
||||
panel: root
|
||||
CloseableHeader:
|
||||
panel: root
|
||||
CloseableHeader:
|
||||
panel: root
|
||||
|
||||
<PanelbLeft>
|
||||
tab_pos: 'bottom_left'
|
||||
size_hint: (.45, .45)
|
||||
pos_hint: {'center_x': .25, 'y': .02}
|
||||
do_default_tab: False
|
||||
|
||||
TabbedPanelItem:
|
||||
id: settings
|
||||
text: 'Settings'
|
||||
RstDocument:
|
||||
text: '\\n'.join(("Normal tabs", "-------------",\
|
||||
"Tabs in \\'%s\\' position" %root.tab_pos))
|
||||
TabbedPanelItem:
|
||||
text: 'tab2'
|
||||
BubbleButton:
|
||||
text: 'switch to settings'
|
||||
on_press: root.switch_to(settings)
|
||||
TabbedPanelItem:
|
||||
text: 'tab3'
|
||||
Image:
|
||||
source: 'data/images/image-loading.gif'
|
||||
|
||||
<PanelbRight>
|
||||
tab_pos: 'right_top'
|
||||
size_hint: (.45, .45)
|
||||
pos_hint: {'center_x': .75, 'y': .02}
|
||||
default_tab: def_tab
|
||||
tab_height: img.width
|
||||
FloatLayout:
|
||||
RstDocument:
|
||||
id: default_content
|
||||
text: '\\n'.join(("Image tabs","-------------",\
|
||||
"1. Normal image tab","2. Image with Text","3. Rotated Image",\
|
||||
"4. Tabs in \\'%s\\' position" %root.tab_pos))
|
||||
Image:
|
||||
id: tab_2_content
|
||||
source: 'data/images/defaulttheme-0.png'
|
||||
VideoPlayer:
|
||||
id: tab_3_content
|
||||
source: 'cityCC0.mpg'
|
||||
TabbedPanelHeader:
|
||||
id: def_tab
|
||||
content:default_content.__self__
|
||||
border: 0, 0, 0, 0
|
||||
background_down: 'cityCC0.png'
|
||||
background_normal:'sequenced_images/data/images/info.png'
|
||||
TabbedPanelHeader:
|
||||
id: tph
|
||||
content: tab_2_content.__self__
|
||||
BoxLayout:
|
||||
pos: tph.pos
|
||||
size: tph.size
|
||||
orientation: 'vertical'
|
||||
Image:
|
||||
source: 'sequenced_images/data/images/info.png'\
|
||||
if tph.state == 'normal' else 'cityCC0.png'
|
||||
Label:
|
||||
text: 'text & img'
|
||||
TabbedPanelHeader:
|
||||
id: my_header
|
||||
content: tab_3_content.__self__
|
||||
Scatter:
|
||||
do_translation: False
|
||||
do_scale: False
|
||||
do_rotation: False
|
||||
auto_bring_to_front: False
|
||||
rotation: 90
|
||||
size_hint: None, None
|
||||
size: img.size
|
||||
center: my_header.center
|
||||
Image:
|
||||
id: img
|
||||
source: 'sequenced_images/data/images/info.png'\
|
||||
if my_header.state == 'normal' else 'cityCC0.png'
|
||||
size: my_header.size
|
||||
allow_stretch: True
|
||||
keep_ratio: False
|
||||
''')
|
||||
|
||||
|
||||
class Tp(TabbedPanel):
|
||||
|
||||
# override tab switching method to animate on tab switch
|
||||
def switch_to(self, header):
|
||||
anim = Animation(opacity=0, d=.24, t='in_out_quad')
|
||||
|
||||
def start_anim(_anim, child, in_complete, *lt):
|
||||
_anim.start(child)
|
||||
|
||||
def _on_complete(*lt):
|
||||
if header.content:
|
||||
header.content.opacity = 0
|
||||
anim = Animation(opacity=1, d=.43, t='in_out_quad')
|
||||
start_anim(anim, header.content, True)
|
||||
super(Tp, self).switch_to(header)
|
||||
|
||||
anim.bind(on_complete=_on_complete)
|
||||
if self.current_tab.content:
|
||||
start_anim(anim, self.current_tab.content, False)
|
||||
else:
|
||||
_on_complete()
|
||||
|
||||
|
||||
class PanelLeft(Tp):
|
||||
pass
|
||||
|
||||
|
||||
class PanelRight(Tp):
|
||||
|
||||
def add_header(self):
|
||||
self.add_widget(CloseableHeader(panel=self))
|
||||
|
||||
|
||||
class PanelbLeft(Tp):
|
||||
pass
|
||||
|
||||
|
||||
class PanelbRight(Tp):
|
||||
pass
|
||||
|
||||
|
||||
class TabShowcase(FloatLayout):
|
||||
|
||||
def show_tab(self):
|
||||
if not hasattr(self, 'tab'):
|
||||
self.tab = tab = PanelLeft()
|
||||
self.add_widget(tab)
|
||||
self.tab1 = tab = PanelRight()
|
||||
self.add_widget(tab)
|
||||
self.tab2 = tab = PanelbRight()
|
||||
self.add_widget(tab)
|
||||
self.tab3 = tab = PanelbLeft()
|
||||
self.add_widget(tab)
|
||||
self.but.text = \
|
||||
'Tabs in variable positions, press to change to top_left'
|
||||
else:
|
||||
values = ('left_top', 'left_mid', 'left_bottom', 'top_left',
|
||||
'top_mid', 'top_right', 'right_top', 'right_mid',
|
||||
'right_bottom', 'bottom_left', 'bottom_mid', 'bottom_right')
|
||||
index = values.index(self.tab.tab_pos)
|
||||
self.tab.tab_pos = self.tab1.tab_pos = self.tab2.tab_pos\
|
||||
= self.tab3.tab_pos = values[(index + 1) % len(values)]
|
||||
self.but.text = 'Tabs in \'%s\' position,' % self.tab.tab_pos\
|
||||
+ '\n press to change to next pos'
|
||||
|
||||
|
||||
class TestTabApp(App):
|
||||
|
||||
def build(self):
|
||||
return TabShowcase()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
TestTabApp().run()
|
||||
50
freechat-client/share/kivy-examples/widgets/tabbedpanel.py
Normal file
50
freechat-client/share/kivy-examples/widgets/tabbedpanel.py
Normal file
@@ -0,0 +1,50 @@
|
||||
'''
|
||||
TabbedPanel
|
||||
============
|
||||
|
||||
Test of the widget TabbedPanel.
|
||||
'''
|
||||
|
||||
from kivy.app import App
|
||||
from kivy.uix.tabbedpanel import TabbedPanel
|
||||
from kivy.lang import Builder
|
||||
|
||||
Builder.load_string("""
|
||||
|
||||
<Test>:
|
||||
size_hint: .5, .5
|
||||
pos_hint: {'center_x': .5, 'center_y': .5}
|
||||
do_default_tab: False
|
||||
|
||||
TabbedPanelItem:
|
||||
text: 'first tab'
|
||||
Label:
|
||||
text: 'First tab content area'
|
||||
TabbedPanelItem:
|
||||
text: 'tab2'
|
||||
BoxLayout:
|
||||
Label:
|
||||
text: 'Second tab content area'
|
||||
Button:
|
||||
text: 'Button that does nothing'
|
||||
TabbedPanelItem:
|
||||
text: 'tab3'
|
||||
RstDocument:
|
||||
text:
|
||||
'\\n'.join(("Hello world", "-----------",
|
||||
"You are in the third tab."))
|
||||
|
||||
""")
|
||||
|
||||
|
||||
class Test(TabbedPanel):
|
||||
pass
|
||||
|
||||
|
||||
class TabbedPanelApp(App):
|
||||
def build(self):
|
||||
return Test()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
TabbedPanelApp().run()
|
||||
49
freechat-client/share/kivy-examples/widgets/textalign.kv
Normal file
49
freechat-client/share/kivy-examples/widgets/textalign.kv
Normal file
@@ -0,0 +1,49 @@
|
||||
#:kivy 1.0
|
||||
|
||||
<BoundedLabel>:
|
||||
canvas.before:
|
||||
Color:
|
||||
rgb: 1, 0, 0
|
||||
Rectangle:
|
||||
pos: self.pos
|
||||
size: self.size
|
||||
|
||||
<Selector>:
|
||||
grid: _grid
|
||||
Label:
|
||||
pos_hint: {'top': 1}
|
||||
size_hint_y: None
|
||||
height: 50
|
||||
font_size: 16
|
||||
text: 'Demonstration of text valign and halign'
|
||||
GridLayout:
|
||||
id: _grid
|
||||
rows: 3
|
||||
cols: 3
|
||||
spacing: 10
|
||||
size_hint: (None, None)
|
||||
pos_hint: {'center_x': .5, 'center_y': .5}
|
||||
BoxLayout:
|
||||
size_hint_y: None
|
||||
height: 50
|
||||
ToggleButton:
|
||||
halign: 'center'
|
||||
group: 'case'
|
||||
text: 'label.text_size =\n(None, None)'
|
||||
on_release: root.app.select(0)
|
||||
state: 'down'
|
||||
ToggleButton:
|
||||
halign: 'center'
|
||||
group: 'case'
|
||||
text: 'label.text_size =\n(label.width, None)'
|
||||
on_release: root.app.select(1)
|
||||
ToggleButton:
|
||||
halign: 'center'
|
||||
group: 'case'
|
||||
text: 'label.text_size =\n(None, label.height)'
|
||||
on_release: root.app.select(2)
|
||||
ToggleButton:
|
||||
halign: 'center'
|
||||
group: 'case'
|
||||
text: 'label.text_size =\n(label.width, label.height)'
|
||||
on_release: root.app.select(3)
|
||||
48
freechat-client/share/kivy-examples/widgets/textalign.py
Normal file
48
freechat-client/share/kivy-examples/widgets/textalign.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from kivy.app import App
|
||||
from kivy.uix.label import Label
|
||||
from kivy.uix.floatlayout import FloatLayout
|
||||
from kivy.properties import ObjectProperty
|
||||
|
||||
|
||||
class BoundedLabel(Label):
|
||||
pass
|
||||
|
||||
|
||||
class Selector(FloatLayout):
|
||||
app = ObjectProperty(None)
|
||||
grid = ObjectProperty(None)
|
||||
|
||||
|
||||
class TextAlignApp(App):
|
||||
|
||||
def select(self, case):
|
||||
for _child in self.selector.grid.children[:]:
|
||||
self.selector.grid.remove_widget(_child)
|
||||
for valign in ('bottom', 'middle', 'top'):
|
||||
for halign in ('left', 'center', 'right'):
|
||||
label = BoundedLabel(text='V: %s\nH: %s' % (valign, halign),
|
||||
size_hint=(None, None),
|
||||
size=(150, 150),
|
||||
halign=halign, valign=valign)
|
||||
if case == 0:
|
||||
label.text_size = (None, None)
|
||||
elif case == 1:
|
||||
label.text_size = (label.width, None)
|
||||
elif case == 2:
|
||||
label.text_size = (None, label.height)
|
||||
else:
|
||||
label.text_size = label.size
|
||||
self.selector.grid.add_widget(label)
|
||||
|
||||
self.selector.grid.bind(minimum_size=self.selector.grid.setter('size'))
|
||||
|
||||
def build(self):
|
||||
self.root = FloatLayout()
|
||||
self.selector = Selector(app=self)
|
||||
self.root.add_widget(self.selector)
|
||||
self.grid = None
|
||||
self.select(0)
|
||||
return self.root
|
||||
|
||||
|
||||
TextAlignApp().run()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user