diff --git a/examples/widgets/sequenced_images/android.txt b/examples/widgets/sequenced_images/android.txt new file mode 100644 index 000000000..b74f94e21 --- /dev/null +++ b/examples/widgets/sequenced_images/android.txt @@ -0,0 +1,3 @@ +title=main +author=seesaw +orientation=portrait diff --git a/examples/widgets/sequenced_images/data/images/ClickHereButton-animated.zip b/examples/widgets/sequenced_images/data/images/ClickHereButton-animated.zip new file mode 100644 index 000000000..290ac85ef Binary files /dev/null and b/examples/widgets/sequenced_images/data/images/ClickHereButton-animated.zip differ diff --git a/examples/widgets/sequenced_images/data/images/RingGreen.zip b/examples/widgets/sequenced_images/data/images/RingGreen.zip new file mode 100644 index 000000000..3681a8afd Binary files /dev/null and b/examples/widgets/sequenced_images/data/images/RingGreen.zip differ diff --git a/examples/widgets/sequenced_images/data/images/busy-stick-figures-animated.gif b/examples/widgets/sequenced_images/data/images/busy-stick-figures-animated.gif new file mode 100644 index 000000000..5ae0c16ca Binary files /dev/null and b/examples/widgets/sequenced_images/data/images/busy-stick-figures-animated.gif differ diff --git a/examples/widgets/sequenced_images/data/images/button_white.png b/examples/widgets/sequenced_images/data/images/button_white.png new file mode 100644 index 000000000..5971c93a5 Binary files /dev/null and b/examples/widgets/sequenced_images/data/images/button_white.png differ diff --git a/examples/widgets/sequenced_images/data/images/button_white_animated.zip b/examples/widgets/sequenced_images/data/images/button_white_animated.zip new file mode 100644 index 000000000..243223e10 Binary files /dev/null and b/examples/widgets/sequenced_images/data/images/button_white_animated.zip differ diff --git a/examples/widgets/sequenced_images/data/images/info.png b/examples/widgets/sequenced_images/data/images/info.png new file mode 100644 index 000000000..1593d5577 Binary files /dev/null and b/examples/widgets/sequenced_images/data/images/info.png differ diff --git a/examples/widgets/sequenced_images/data/images/info.zip b/examples/widgets/sequenced_images/data/images/info.zip new file mode 100644 index 000000000..8f5c26e3c Binary files /dev/null and b/examples/widgets/sequenced_images/data/images/info.zip differ diff --git a/examples/widgets/sequenced_images/main.kv b/examples/widgets/sequenced_images/main.kv new file mode 100644 index 000000000..7bf55ed37 --- /dev/null +++ b/examples/widgets/sequenced_images/main.kv @@ -0,0 +1,56 @@ +: + 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 + + + on_size: self.center = win.Window.center + size: imag.size + size_hint: None, None + Image: + id: imag + source: 'data/images/busy-stick-figures-animated.gif' + on_touch_down: root.parent.parent.parent.currentObj = self + + + on_size: self.center = win.Window.center + size: imag.size + size_hint: None, None + Image: + id: imag + source: 'data/images/RingGreen.zip' + anim_delay: 0.05 + on_touch_down: root.parent.parent.parent.currentObj = self + + + on_size: self.center = win.Window.center + size: imag.size + size_hint: None, None + Image: + id: imag + source: 'data/images/ClickHereButton-animated.zip' + on_touch_down: root.parent.parent.parent.currentObj = self + + + size_hint: (.2, 1) + padding: 10 + cols: 1 + 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: 'Animation speed: %f FPS' %(1/root.currentObj.anim_delay) if root.currentObj else 'No Image selected' + Slider: + min:0 + max: 100 if root.currentObj else 0 + value: (1/root.currentObj.anim_delay) if root.currentObj else 0 + on_value: root.on_value(self, args[1], spdlbl) diff --git a/examples/widgets/sequenced_images/main.py b/examples/widgets/sequenced_images/main.py new file mode 100644 index 000000000..fe4ebc0a6 --- /dev/null +++ b/examples/widgets/sequenced_images/main.py @@ -0,0 +1,148 @@ +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.image import Image +from kivy.uix.scatter import Scatter +from kivy.uix.stencilview import StencilView +from kivy.properties import ObjectProperty +from kivy.core import window + + +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 = 0 + 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 = StencilView( pos_hint = {'top':0, 'right':0}) + self.right_frame = Right_Frame() + + #setup buttons in left frame + but_load_gif = AnimatedButton(text = 'load gif') + but_load_zip_png = AnimatedButton(text = 'load zipped\n png/s') + but_load_zip_jpg = AnimatedButton(text = 'load zipped\n jpg/s') + 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') + but_animated_bordered = AnimatedButton(text = 'With Border',\ + background_normal = 'data/images/info.png',\ + background_down = 'data/images/info.zip') + + #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) + + #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__ in ('__main__', '__android__'): + mainApp().run() diff --git a/examples/widgets/sequenced_images/uix/__init__.py b/examples/widgets/sequenced_images/uix/__init__.py new file mode 100644 index 000000000..899b04a78 --- /dev/null +++ b/examples/widgets/sequenced_images/uix/__init__.py @@ -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. +''' diff --git a/examples/widgets/sequenced_images/uix/custom_button.py b/examples/widgets/sequenced_images/uix/custom_button.py new file mode 100644 index 000000000..509b64163 --- /dev/null +++ b/examples/widgets/sequenced_images/uix/custom_button.py @@ -0,0 +1,100 @@ + +__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('data/images/button.png') + + texture_background = ObjectProperty(None) + + background_down = StringProperty('data/images/button_pressed.png') + + 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 self in touch.ud: + return False + touch.grab(self) + touch.ud[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 self in touch.ud + + def on_touch_up(self, touch): + if touch.grab_current is not self: + return + assert(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)