class PlayButton(ButtonBehavior, AsyncImage): angle = NumericProperty() def __init__(self, **kwargs): super().__init__(**kwargs) self.source = 'play.png' self.anim = Animation(angle=360, duration=2) self.anim += Animation(angle=360, duration=2) self.anim.repeat = True self.running = False def on_press(self): self.source = 'play_blue.png' def start(self): self.running = True self.anim.start(self) self.source = 'cog.png' self.disabled = True def ready(self): self.anim.cancel(self) self.disabled = False self.source = 'play.png' self.angle = 0 def on_angle(self, instance, values): """ Only needed so spinner goes after 360. """ self.angle %= 360
class MDCheckbox(ThemableBehavior, CircularRippleBehavior, ToggleButtonBehavior, Label): active = BooleanProperty(False) _checkbox_icon = StringProperty( u"{}".format(md_icons['square-o'])) _radio_icon = StringProperty(u"{}".format(md_icons['circle-o'])) _icon_active = StringProperty(u"{}".format(md_icons['check-square'])) def __init__(self, **kwargs): super(MDCheckbox, self).__init__(**kwargs) self.register_event_type('on_active') self.check_anim_out = Animation(font_size=0, duration=.1, t='out_quad') self.check_anim_in = Animation(font_size=sp(24), duration=.1, t='out_quad') self.check_anim_out.bind( on_complete=lambda *x: self.check_anim_in.start(self)) def on_state(self, *args): if self.state == 'down': self.check_anim_in.cancel(self) self.check_anim_out.start(self) self._radio_icon = u"{}".format(md_icons['dot-circle']) self._checkbox_icon = u"{}".format(md_icons['check-square']) self.active = True else: self.check_anim_in.cancel(self) self.check_anim_out.start(self) self._radio_icon = u"{}".format(md_icons['circle-o']) self._checkbox_icon = u"{}".format( md_icons['square-o']) self.active = False def on_active(self, instance, value): self.state = 'down' if value else 'normal'
class MDCheckbox(ThemableBehavior, CircularRippleBehavior, ToggleButtonBehavior, Label): active = BooleanProperty(False) _checkbox_icon = StringProperty( u"{}".format(md_icons['md-check-box-outline-blank'])) _radio_icon = StringProperty(u"{}".format(md_icons['md-radio-button-off'])) _icon_active = StringProperty(u"{}".format(md_icons['md-check-box'])) def __init__(self, **kwargs): super(MDCheckbox, self).__init__(**kwargs) self.register_event_type('on_active') self.check_anim_out = Animation(font_size=0, duration=.1, t='out_quad') self.check_anim_in = Animation(font_size=sp(24), duration=.1, t='out_quad') self.check_anim_out.bind( on_complete=lambda *x: self.check_anim_in.start(self)) def on_state(self, *args): if self.state == 'down': self.check_anim_in.cancel(self) self.check_anim_out.start(self) self._radio_icon = u"{}".format(md_icons['md-radio-button-on']) self._checkbox_icon = u"{}".format(md_icons['md-check-box']) self.active = True else: self.check_anim_in.cancel(self) self.check_anim_out.start(self) self._radio_icon = u"{}".format(md_icons['md-radio-button-off']) self._checkbox_icon = u"{}".format( md_icons['md-check-box-outline-blank']) self.active = False def on_active(self, instance, value): self.state = 'down' if value else 'normal'
class KivyPlayer(FloatLayout): def __init__(self, **kwargs): super(self.__class__, self).__init__(**kwargs) def hide_bars(self, instance, playing): if playing: self.list_button.state = 'normal' self.animationAB = Animation(y=self.height) self.action_bar.disabled = True self.animationAB.start(self.action_bar) else: self.action_bar.disabled = False self.action_bar.top = self.height if hasattr(self, 'animationAB'): self.animationAB.cancel(self.action_bar) def toggle_mute(self, instance, state): if state == 'down': self.video_controller.video.volume = 0 else: self.video_controller.video.volume = 1 def show_load_list(self): content = LoadDialog(load=self.load_list, cancel=self.dismiss_popup) self._popup = Popup(title="Load a file list", content=content, size_hint=(1, 1)) self._popup.open() def load_list(self, path, filename): json_data = open(os.path.join(path, filename[0])) data = json.load(json_data) json_data.close() self.load_from_json(data) self.dismiss_popup() def load_from_json(self, data): self.playlist.clear_widgets() for val in data['results']: t = val['talk'] video = self.video_controller.video meta = _meta % (t['id'], _api) surl = _surl % t['id'] item = ListItem(video, meta, surl, text=t['name']) self.playlist.add_widget(item) self.list_button.state = 'down' def dismiss_popup(self): self._popup.dismiss() def search(self, text): url = _search % (text, _api) req = UrlRequest(url, self.got_search) def got_search(self, req, results): self.load_from_json(results)
class MessagePopup(ModalView): _max = 3 slots = [None for _ in range(_max)] replace = 0 def __init__(self, **kwargs): self.message = kwargs.pop("message") self.fade = None self.dismiss_schedule = None super().__init__(**kwargs) # find a vacant slot or create one for i in range(self._max): if not self.slots[i]: empty_slot = i break else: empty_slot = MessagePopup.replace MessagePopup.replace += 1 if MessagePopup.replace >= self._max: MessagePopup.replace = 0 self.slots[empty_slot].dismiss() self.slot_index = empty_slot self.pos_hint = {"center_x": .5, "center_y": .15 + .05 * empty_slot} self.slots[empty_slot] = self def on_touch_down(self, touch): pass def on_touch_move(self, touch): pass def on_touch_up(self, touch): pass def open(self, *largs, **kwargs): super().open(*largs, **kwargs) # schedule fading animation self.dismiss_schedule = Clock.schedule_once(self.close, 1.6) def close(self, *args): # start fading animation self.fade = Animation(opacity=0, t="in_sine", duration=0.6) self.fade.start(self) # fully dismiss popup after animation self.dismiss_schedule = Clock.schedule_once(self.dismiss, 0.6) def dismiss(self, *largs, **kwargs): super().dismiss(*largs, **kwargs) if self.fade: self.fade.cancel(self) if self.dismiss_schedule: self.dismiss_schedule.cancel() self.slots[self.slot_index] = None
class Arrow(ButtonBehavior, Image): color = ListProperty([.761, .761, .761, 1]) lwidth = NumericProperty(1.) duration = NumericProperty(.1) transition = OptionProperty('linear', options=[ 'linear', 'out_elastic', 'out_back', 'in_out_back', 'in_elastic', 'in_back', 'in_bounce', 'in_out_bounce', 'in_out_expo', 'out_quart', 'out_sine' ]) direction = OptionProperty(None, options=['left', 'right', 'up', 'down']) _anim = ObjectProperty() _radius = NumericProperty() _transition = StringProperty('linear') def on_transition(self, *args): self._transition = args[1] def on_direction(self, *args): if args[1] == 'right': self.source = 'images/arrow-right.png' elif args[1] == 'left': self.source = 'images/arrow-left.png' elif args[1] == 'up': self.source = 'images/arrow-up.png' elif args[1] == 'down': self.source = 'images/arrow-down.png' def on_touch_down(self, touch): if self.collide_point(*touch.pos): if not self._radius: self._anim = Animation(_radius=self.height * 1.2, d=self.duration, t=self._transition) self._anim.start(self) return super().on_touch_down(touch) def on_touch_up(self, touch): if self._radius: self._anim.cancel(self) self._radius = 0 return super().on_touch_up(touch)
class GameOverScreen(Screen): def __init__(self, **kwargs): super(GameOverScreen, self).__init__(**kwargs) self.rising_text = Animation(y=0, duration=2, t='out_bounce') # t is the transition, bouncy for meme value. def on_touch_down(self, touch, *args): self.manager.restart() def on_pre_enter(self): self.rising_text.start(self.txt) def on_leave(self): self.rising_text.cancel(self.txt) # Stop the animation before leaving self.txt.y = self.text_y
class DevouredAccident(Accident): name = 'Devoured' headlines = [ "devoured by the infamous slug monster. Bad luck!", "just swallowed by the terrible slug monster!", "next on the long list of the slug monster's victims!", "has never suspected he's gonna end up as a snack!", "devoured by the legendary slug monster from the nearby swamps!" ] sound = 'assets/sounds/Accidents/Devoured.mp3' image = 'atlas://assets/accidents/accidents/slug monster' def __init__(self, **kwargs): super().__init__(name=self.name, headlines=self.headlines, sound=self.sound, image=self.image, **kwargs) def happen(self): super().happen() self.monster = Image(source=self.image) self.monster.size_hint = (2, 2) self.monster.x = self.slug.body.x - 800 self.monster.y = self.slug.body.y - 15 self.slug.add_widget(self.monster) self.monster_animation = Animation(x=500, d=self.slug.running_time / 6) self.monster_animation.bind(on_progress=self.chase) self.monster_animation.start(self.monster) def chase(self, animation, monster, progression): if monster.x >= self.slug.body.x - 20 and not self.slug.devoured: self.slug.devoured = True self.slug.run_animation.stop(self.slug) self.monster_animation.cancel(self.monster) def reset(self): # Set the devoured property of the slug to False. self.slug.devoured = False # Check if the sound is still playing and if it is, stop it. if self.sound.state == 'play': self.sound.stop() # Remove the monster widget. self.slug.remove_widget(self.monster)
class StartScreen(Screen): click_sound = SoundLoader.load('sound/Water Drop Low-SoundBible.com-1501529809.mp3') def on_pre_enter(self): if self.manager.music.state == 'stop': self.manager.music.play() self.bounce = Animation(size_hint= (0.35, 0.35))\ + Animation(size_hint= (0.3,0.3)) self.bounce.repeat = True self.bounce.start(self.ids.owl) self.bounce.start(self.ids.questions) def on_leave(self): self.bounce.cancel(self.ids.owl) self.bounce.cancel(self.ids.questions) def onClickSound(self): self.click_sound.play()
class ChooseQuiz(Screen): click_sound = SoundLoader.load('sound/Water Drop Low-SoundBible.com-1501529809.mp3') def on_pre_enter(self): self.animate_buttons = Animation(size_hint = (0.0, 0.0))\ + Animation(size_hint = (1.0,1.0)) self.animate_buttons.start(self.ids.layout) def setOption(self, text): self.parent.option = text def onClickSound(self): self.click_sound.play() def on_leave(self): if self.manager.music.state == 'play': self.manager.music.stop() self.animate_buttons.cancel(self.ids.layout)
class HeadunitWidget(Widget): anim = 0 bt_connected_anim = 0 greeting = StringProperty('صباح الخير') lang = StringProperty('ar') is_greeting_visible = BooleanProperty(False) def update(self, dt): self.time_and_date.update(dt) def toggle(self, dt): if (self.is_greeting_visible): self.hide_greeting() self.is_greeting_visible = False else: self.show_greeting() self.is_greeting_visible = True def handle_bt_connected(self, dt): self.bt_connected() def hide_greeting(self): if (self.anim): self.anim.cancel(self.time_and_date) self.anim = Animation(scale=1, duration=0.3, t='in_out_cubic') self.anim &= Animation(y=0, duration=0.3, t='in_out_cubic') self.anim.start(self.time_and_date) def show_greeting(self): if (self.anim): self.anim.cancel(self.time_and_date) self.anim = Animation(scale=0.6, duration=0.3, t='in_out_cubic') self.anim &= Animation(y=dp(150), duration=0.3, t='in_out_cubic') self.anim.start(self.time_and_date) def bt_connected(self): if (self.bt_connected_anim): self.bt_connected_anim.cancel(self.bt_connection) self.anim = Animation(scale=0.6, duration=0.3, t='in_out_cubic') self.anim.start(self.bt_connection)
class KoalaPaw(Image): def __init__(self, parent): super(KoalaPaw, self).__init__() self.size = PANDA_SIZE y = parent.pos[1] + Window.height / 50.0 if parent.pos[0] < Window.width // 2: self.direction = 1 self.pos = [-self.size[0], y] else: self.direction = -1 self.pos = [Window.width, y] self.source = 'img/koalas/%s' self.source = 'img/koalas/%s.png' % self.direction def animation(self): if self.direction == 1: x = self.parent.x else: x = self.parent.right + self.parent.width / 4.0 x -= self.parent.width / 2.0 y = self.parent.y - self.parent.height / 2 self.anim = Animation(x=x, y=y, d=0.5) self.anim.bind(on_complete=self.reverse_animation) self.anim.start(self) def reverse_animation(self, *args): self.parent.grab() self.source = 'img/koalas/p_%s.png' % self.direction if self.direction == 1: x = - self.width else: x = Window.width + self.width anim = Animation(x=x, y=self.parent.y - self.parent.height, d=0.5) anim.start(self) def game_over(self): self.anim.cancel(self) self.parent.remove_widget(self)
class VideoController(FloatLayout): playing = ObjectProperty(None) def on_playing(self, instance, value): if value: self.animationVB = Animation(top=0) self.control_bar.disabled = True self.animationVB.start(self.control_bar) else: self.play_pause.state = 'normal' self.control_bar.disabled = False self.control_bar.y = 0 def on_touch_down(self, touch): if self.collide_point(*touch.pos): if hasattr(self, 'animationVB'): self.animationVB.cancel(self.control_bar) self.play_pause.state = 'normal' return super(self.__class__, self).on_touch_down(touch)
class KoalaPaw(Image): def __init__(self, parent): super(KoalaPaw, self).__init__() self.size = PANDA_SIZE y = parent.pos[1] + Window.height / 50.0 if parent.pos[0] < Window.width // 2: self.direction = 1 self.pos = [-self.size[0], y] else: self.direction = -1 self.pos = [Window.width, y] self.source = 'img/koalas/%s' self.source = 'img/koalas/%s.png' % self.direction def animation(self): if self.direction == 1: x = self.parent.x else: x = self.parent.right + self.parent.width / 4.0 x -= self.parent.width / 2.0 y = self.parent.y - self.parent.height / 2 self.anim = Animation(x=x, y=y, d=0.5) self.anim.bind(on_complete=self.reverse_animation) self.anim.start(self) def reverse_animation(self, *args): self.parent.grab() self.source = 'img/koalas/p_%s.png' % self.direction if self.direction == 1: x = -self.width else: x = Window.width + self.width anim = Animation(x=x, y=self.parent.y - self.parent.height, d=0.5) anim.start(self) def game_over(self): self.anim.cancel(self) self.parent.remove_widget(self)
class motor_controller(App): angle = NumericProperty(360) max_speed = NumericProperty(_MAXSPEED) def __init__(self, motor, **kwargs): super(motor_controller, self).__init__(**kwargs) self.motor = motor self.anim = Animation(angle=0, duration=2) self.anim += Animation(angle=0, duration=2) self.anim.repeat = True def build(self): return MotorController() def set_speed(self): speed_value = self.root.ids.speed_value self.motor.speed = speed_value.value def power_button(self, instance, value): speed_value = self.root.ids.speed_value self.motor.power = value speed_value.disabled = not value if value: self.anim.start(self) else: self.anim.cancel(self) def change_direction(self): direction = self.root.ids.direction self.motor.change_dir() if self.motor.forward: direction.background_down = "reverse.png" direction.background_normal = "forward.png" else: direction.background_down = "forward.png" direction.background_normal = "reverse.png" def on_angle(self, item, angle): if angle == 0: item.angle = 360 if self.motor.forward else -360
class InfoLabel(ShortLabel): """Special label widget that automatically displays a message from the app class and blinks when the text is changed.""" bgcolor = ListProperty([1, 1, 0, 0]) blinker = ObjectProperty() def on_text(self, instance, text): del instance app = App.get_running_app() if self.blinker: self.stop_blinking() if text: no_bg = [.5, .5, .5, 0] yes_bg = app.theme.info_background self.blinker = Animation(bgcolor=yes_bg, duration=0.33) + Animation(bgcolor=no_bg, duration=0.33) + Animation(bgcolor=yes_bg, duration=0.33) + Animation(bgcolor=no_bg, duration=0.33) + Animation(bgcolor=yes_bg, duration=0.33) + Animation(bgcolor=no_bg, duration=0.33) + Animation(bgcolor=yes_bg, duration=0.33) + Animation(bgcolor=no_bg, duration=0.33) + Animation(bgcolor=yes_bg, duration=0.33) + Animation(bgcolor=no_bg, duration=0.33) + Animation(bgcolor=yes_bg, duration=0.33) + Animation(bgcolor=no_bg, duration=0.33) + Animation(bgcolor=yes_bg, duration=0.33) + Animation(bgcolor=no_bg, duration=0.33) self.blinker.start(self) def stop_blinking(self, *_): if self.blinker: self.blinker.cancel(self) self.bgcolor = [1, 1, 0, 0]
class SpinnerLabel(FloatLayout): angle = NumericProperty(0) color = StringProperty("#FFFFFF") icon = StringProperty('spinner') def __init__(self, **kwargs): super().__init__(**kwargs) self.anim = Animation(angle=360, duration=1) self.anim += Animation(angle=360, duration=1) self.anim.repeat = True self.anim.start(self) def on_angle(self, item, angle): if angle == 360: item.angle = 0 def stop_anim(self): self.anim.cancel(self) def start_anim(self): self.anim.start(self)
class QuestionPanel(PanelBase): answerPanel=ObjectProperty(None) def animate(self): self.anim=Animation(y=self.parent.top,d=self.levelSpeed/2,t="linear") self.anim.bind(on_complete=self.next_question) self.anim.start(self) if self.answerPanel.disabled: self.answerPanel.disabled=False def endPros(self): if hasattr(self,"anim"): self.anim.cancel(self) anim=Animation(opacity=0,d=self.levelSpeed/10,t="linear") anim.bind(on_complete=self.go_wait) anim.start(self) def go_wait(self,ins,val): self.y=-self.height-10 self.opacity=1 def next_question(self,instance,val): self.answerPanel.disabled=True self.y=-self.height-10 self.opacity=1 self.answerPanel.animate()
class MessageBox(RelativeLayout): padding = ListProperty([12, 12]) color = ListProperty([1, 1, 1, 1]) text = StringProperty('') def __init__(self, **kwargs): self._anim = None super(MessageBox, self).__init__(**kwargs) def show(self, text='', duration=10): self.hide() self.text = text self._anim = Animation(opacity=1, d=1, t='in_out_expo') self._anim += Animation(opacity=0, d=max(1, duration-1), t='in_out_expo') self._anim.start(self) def hide(self): if self._anim is not None: self._anim.cancel(self) self._anim = None self.opacity = 0
class IncrediblyCrudeClock(Label): a = NumericProperty(60) # seconds def set_time(self, time): self.a = time def start(self): Animation.cancel_all(self) # stop any current animations self.anim = Animation(a=0, duration=self.a) def finish_callback(animation, incr_crude_clock): create_simple_popup( "No More Time", "No Time Remaining, Please Talk to an Associate for More Time" ).open() if self.parent.name == 'mygrid': self.parent.playbutton.disabled = True self.anim.bind(on_complete=finish_callback) self.anim.start(self) def pause(self): self.anim.cancel(self) def add_time(self, time): self.anim.cancel(self) self.a += time if self.parent.name == 'mygrid': self.parent.playbutton.disabled = False self.start() def on_a(self, instance, value): hours = math.floor(value / 3600) minutes = math.floor((value % 3600) / 60) seconds = math.floor((value % 60)) self.text = "{:02d}".format(hours) + ":" + "{:02d}".format( minutes) + ":" + "{:02d}".format(seconds)
class LevelUpScreen(Screen): def __init__(self, **kwargs): super(LevelUpScreen, self).__init__(**kwargs) self.rising_text = Animation(y=0, duration=2, t='out_bounce') # t is the transition, bouncy for meme value. def on_touch_up(self, touch, **kwargs): """#def game_start(dt): #self.parent.game.update_loop = Clock.schedule_interval(self.parent.game.update, 1/UPDATE_RATE) game_start = self.parent.game.game_start Clock.schedule_once(game.game_start, self.parent.transition.duration) # Restarts update loop, put this before transition or risk memes. self.parent.current = 'game'""" self.parent.game_start() def on_pre_enter(self): self.rising_text.start(self.txt) def on_leave(self): self.rising_text.cancel(self.txt) # Stop the animation before leaving self.txt.y = -400
class KivyPlayer(FloatLayout): def hide_bars(self, instance, playing): if playing: self.list_button.state = "normal" self.animationAB = Animation(y=self.height) self.action_bar.disabled = True self.animationAB.start(self.action_bar) else: self.action_bar.disabled = False self.action_bar.top = self.height if hasattr(self, "animationAB"): self.animationAB.cancel(self.action_bar) def toggle_mute(self, instance, state): if state == "down": self.video_controller.video.volume = 0 else: self.video_controller.video.volume = 1 def show_load_list(self): pass def search(self, text): pass
class Score(TitleScreen): def __init__(self, **kwargs): super().__init__(**kwargs) self.press_ok_anim2 = None self.out_anim_1 = None self.out_anim_2 = None App.get_running_app().add_callback( CEC_CMD_MAP["OK"], "score", partial(self.goto_func, App.get_running_app().load_game)) App.get_running_app().add_callback( CEC_CMD_MAP["RED"], "score", partial( self.goto_func, partial(App.get_running_app().goto_screen, s_name='options'))) def start_secondary_anims(self, anim, widget, direction): if direction == 'in': # The "Press OK" label is animated manually, because it has a special fade-in # animation. However, we want it to fade out just like the other widgets. Hence, # we set auto_anim to True after it has been animated it. Later, we override the # reset_widgets function to set auto_anim back to False after calling super's # reset_widgets. self.press_ok_anim2 = Animation(opacity=1) + Animation(opacity=0.5) self.press_ok_anim2.repeat = True Clock.schedule_once( lambda dt: self.press_ok_anim2.start(self.ids.press_ok), 0.2) else: self.ids.press_ok.auto_anim = True self.press_ok_anim2.cancel(self.ids.press_ok) return super().start_secondary_anims(anim, widget, direction) def reset_widgets(self): # See explanation above super().reset_widgets() self.ids.press_ok.auto_anim = False
class MessageBox(RelativeLayout): padding = ListProperty([12, 12]) color = ListProperty([1, 1, 1, 1]) text = StringProperty('') def __init__(self, **kwargs): self._anim = None super(MessageBox, self).__init__(**kwargs) def show(self, text='', duration=10): self.hide() self.text = text self._anim = Animation(opacity=1, d=1, t='in_out_expo') self._anim += Animation(opacity=0, d=max(1, duration - 1), t='in_out_expo') self._anim.start(self) def hide(self): if self._anim is not None: self._anim.cancel(self) self._anim = None self.opacity = 0
class AnswerPanel(PanelBase): ready=False centerx=None centery=None questionPanel=ObjectProperty(None) statePanel=ObjectProperty(None) level="Basic" stage=NumericProperty(1) def on_stage(self,ins,val): if not val or val==0: return if val==1: self.levelSpeed=12 self.questionPanel.levelSpeed=12 elif val==2: self.levelSpeed=10 self.questionPanel.levelSpeed=10 elif val==3: self.levelSpeed=9 self.questionPanel.levelSpeed=9 elif val==4: self.levelSpeed=8 self.questionPanel.levelSpeed=8 self.stage=val def animate(self): self.anim=Animation(x=-self.width,d=self.levelSpeed/4,t="in_sine") self.anim.bind(on_complete=self.next_answer) self.anim.start(self) def generateNextAnswer(self,a,b,c,d,ranswer): self.abtn.text=str(a) self.bbtn.text=str(b) self.cbtn.text=str(c) self.dbtn.text=str(d) self.reanswer=str(ranswer) def answerClick(self): self.disabled=True if hasattr(self,"anim"): self.anim.cancel(self) if hasattr(self.questionPanel,"anim"): self.questionPanel.endPros() def makeAnswerPanel(self,ans): idx=randint(0,3) for a in range(len(ans)): if idx==a: tmp=ans[a] ans[a]=ans[3] ans[3]=tmp self.generateNextAnswer(ans[0],ans[1],ans[2],ans[3],ans[idx]) def next_answer(self,instance,val): self.prepare_next(dt=None) @mainthread def prepare_next(self,dt): self.generateGameQuestion(self.level) self.y=self.parent.height/2-self.height/1.5 self.x=-self.width-10 anim=Animation(x=10,d=self.levelSpeed/4,t="in_out_back") anim.bind(on_complete=self.prepareQuestionPanel) anim.start(self) def prepareQuestionPanel(self,ins,val): if hasattr(self.questionPanel,"anim"): self.questionPanel.go_wait(ins=None,val=None) self.questionPanel.opacity=1 self.questionPanel.animate() @mainthread def showRightAns(self): MediaPlayer().play("pick") self.parent.score +=5 self.statePanel.qLabel.text="[color=#00FFFF]Doğru Bildiniz!Tebrikler[/color]" self.statePanel.showAnim() anim=Animation(y=-self.height,d=self.levelSpeed/5) anim.bind(on_complete=self.next_answer) anim.start(self) @mainthread def showWrongAns(self): MediaPlayer().play("loose") self.statePanel.qLabel.text="[color=#d62d20]Bilemediniz!! "+str(self.reanswer)+"[/color]" self.statePanel.showAnim() self.animate() @mainthread def generateGameQuestion(self,level=None): self.disabled=True if self.stage<=2: ky=KyMath() ky.generateStage(level=level) ky.findSolution() ans1,ans2,ans3=ky.generateRandomAns(self.level) ans=[] ans.append(ans1) ans.append(ans2) ans.append(ans3) ans.append(ky.solution) self.parent.ans=ky.solution txt="("+str(ky.num1)+")"+ky.taskToStr(ky.task)+"("+str(ky.num2)+")=?" self.questionPanel.qLabel.text=txt self.makeAnswerPanel(ans) elif self.stage>2: ky=KyEquationResolver() ky.generateRandomNum(self.level) ky.generateTask() numx,num=ky.findSolutions() num1x,num1,num2x,num2,num3x,num3=ky.generateRandomAns(numx,num) ans=[] str1=self.checkZeroAnOne(ky,num1x,num1) str2=self.checkZeroAnOne(ky,num2x,num2) str3=self.checkZeroAnOne(ky,num3x,num3) soli=self.checkZeroAnOne(ky,numx,num) ans.append(str1) ans.append(str2) ans.append(str3) ans.append(soli) self.parent.ans=soli txt1=self.checkZeroAnOne(ky,ky.num1,ky.num2) txt2=self.checkZeroAnOne(ky,ky.num3,ky.num4) txt="("+txt1+")+("+txt2+")" self.questionPanel.qLabel.text=txt self.makeAnswerPanel(ans) else: self.parent.game_end=True def checkZeroAnOne(self,ky,xnum,num): if num==0 and xnum==0: return "0" elif xnum==0 and num!=0: return ky.markerToStr(num)+str(abs(num)) elif xnum!=0 and num==0: return ky.markerToStr(xnum)+str(abs(xnum))+"x" elif (xnum==1 or xnum==-1) and num!=0: return ky.markerToStr(xnum)+"x"+ky.markerToStr(num)+str(abs(num)) elif (xnum==1 or xnum==-1) and num==0: return ky.markerToStr(xnum)+"x" else: return str(xnum)+"x"+ky.markerToStr(num)+str(abs(num))
class ImmersiveLayout(StencilView): immersed = BooleanProperty(None) '''State of the layout. If True, the dock is hidden. ''' auto_show = BooleanProperty(True) '''Boolean specifying whether input events trigger the ImmersiveLayout to exit immersive mode.''' auto_hide = BooleanProperty(True) '''Boolean specifying whether the dock will hide after **timeout** seconds.''' timeout = NumericProperty(5) '''Time after the last input event (keyboard, touch, mouse) after which the dock is hidden. If set to 0, the layout will stay opened until manually closed.''' animation_duration = NumericProperty(0.75) '''Speed at which the dock opens, in seconds. ''' max_dock_size = NumericProperty(0.2) '''Maximum dock size as a fraction of the ImmersiveLayout's size. ''' fade = BooleanProperty(True) '''Boolean specifying whether the dock fades into view when opening. ''' transition = StringProperty('in_out_sine') '''The name of the animation transition type to use when animating. Defaults to 'out_cubic'.''' _anim_progress = NumericProperty(1 * (not immersed)) ''' Internal parameter monitoring the progress of the dock's opening animation. 1 is opened, 0 is closed.''' _anim = ObjectProperty(None) '''Animation. ''' _scheduled_close = ObjectProperty(None, allownone=True) '''Scheduled close event. ''' main_panel = ObjectProperty(None, allownone=True) '''Automatically bound to whatever widget is added as the main panel.''' dock = ObjectProperty(None, allownone=True) '''Automatically bound to whatever widget is added as the dock.''' def __init__(self, **kwargs): super(ImmersiveLayout, self).__init__(**kwargs) self._anim = Animation(_anim_progress=1 * (not self.immersed), duration=self.animation_duration, t=self.transition) Window.bind(on_keyboard=self._keyboard_handler) self.register_event_type('on_enter_immersive') self.register_event_type('on_exit_immersive') self.register_event_type('on_finished_entering') self.register_event_type('on_finished_exiting') def _keyboard_handler(self, window, key, *args): """ If auto_show is True. The first keyboard event will open the dock and block. If the dock is opened, then the key events will be passed """ if self.auto_show: immersed = self.immersed #self.immersed = False self.exit_immersive_mode() self._schedule_close() # If the dock was opened, pass on the event, otherwise block it from the system return immersed def add_widget(self, widget, index=0): """ The first two widget we add are the containers for the main panel and dock, _main_panel and _dock, this is done automatically by instantiating the class. After, when the user adds widgets to the ImmersiveLayout, we add the first widget supplied to the the _main_panel and the second widget to the _dock. """ if len(self.children) == 0: super(ImmersiveLayout, self).add_widget(widget) self._main_panel = widget elif len(self.children) == 1: super(ImmersiveLayout, self).add_widget(widget) self._dock = widget elif self.main_panel is None: self._main_panel.add_widget(widget) self.main_panel = widget elif self.dock is None: self._dock.add_widget(widget) self.dock = widget def cancel_scheduled_close(self): """ Cancel a scheduled close and schedule a new one. """ if self._scheduled_close: self._scheduled_close.cancel() def _schedule_close(self, *args): """ Schedules a close event for the dock. """ if self.timeout > 0: self.cancel_scheduled_close() self._scheduled_close = Clock.schedule_once( self.enter_immersive_mode, self.timeout) def toggle_state(self, *args): """ Toggle the state of immersion """ if self.immersed: self.exit_immersive_mode() else: self.enter_immersive_mode() def enter_immersive_mode(self, *args): """ Enter immersive mode. """ self._anim.cancel(self) self._anim = Animation(_anim_progress=0, duration=self.animation_duration, t=self.transition) self._anim.start(self) self._anim.bind( on_complete=lambda *x: self.dispatch('on_finished_entering')) self.immersed = True self.dispatch('on_enter_immersive') def exit_immersive_mode(self, *args): """ Exit immersive mode. """ self._anim.cancel(self) self._anim = Animation(_anim_progress=1, duration=self.animation_duration, t=self.transition) self._anim.start(self) self.immersed = False self._anim.bind( on_complete=lambda *x: self.dispatch('on_finished_exiting')) self.dispatch('on_exit_immersive') # Schedule a close event if auto_hide is enabled. if self.auto_hide: self._schedule_close() def on_enter_immersive(self, *args): """ Signals the beginning of the event to enter immersive mode. """ pass def on_finished_entering(self, *args): """ Signals the end of the event to enter immersive mode. """ pass def on_exit_immersive(self, *args): """ Signals the beginning of the event to leave immersive mode. """ pass def on_finished_exiting(self, *args): """ Signals the end of the event to exit immersive mode. """ pass def on_auto_hide(self, *args): if self.timeout > 0: # Store the value of the timeout in case we turn on auto_hide again. self._timeout = self.timeout if self._scheduled_close: self._scheduled_close.cancel() self.timeout = self._timeout * self.auto_hide if self.auto_hide: self._schedule_close() def on_touch_down(self, touch): if self.auto_show: immersed = self.immersed if not self.immersed: self.cancel_scheduled_close() self.exit_immersive_mode() # While the dock is hidden, do not pass the touch event through. if immersed: return else: super(ImmersiveLayout, self).on_touch_down(touch) else: super(ImmersiveLayout, self).on_touch_down(touch)
class Cow(Image): alpha = NumericProperty(0) source = StringProperty('') def __init__(self, x, index, on_horizon=False): super(Cow, self).__init__() self.size = [COW_WIDTH, COW_HEIGHT] self.direction = random.choice((-1, 1)) self.file = 'img/cows/cow_0{0}/'.format(random.randint(1, 2)) self.balloon = None self.index = index self.expression = None # self.answer = None self.is_flying = False if on_horizon: y = BOTTOM_BORDER self.source = self.file + '{0}.png'.format(self.direction) self.pos = [x, y] self.__move() else: y = random.randint( int(2 * BOTTOM_BORDER), int(Window.height - COW_HEIGHT)) # print int(2 * BOTTOM_BORDER), Window.height - COW_HEIGHT, 'sdsd' self.pos = [x, y] self.fall() # I guess there is another word for stealing cows. # Maybe it's 'stealing?' # Anyway i put it this way ^_^ # self.horizon = horizon Clock.schedule_interval( self.__reduce_transparency, VELOCITY_UPDATE_TIME) def __reduce_transparency(self, timing=None): # print 'alpha', self.alpha if self.alpha >= 1: return False self.alpha += 0.05 def fall(self, *args): try: self.fly_anim.cancel(self) # self.remove_widget(self.balloon) except AttributeError: pass self.source = self.file + 'fall_{0}.png'.format(self.direction) duration = 0.6 if self.center[1] <= Window.height / 2 else 1.3 anim = Animation(x=self.x, y=BOTTOM_BORDER, d=duration) anim.bind(on_complete=lambda *args: self.__move()) anim.start(self) def __fly(self, *args): # self.is_flying = True self.source = self.file + '{0}.png'.format(self.direction) self.fly_anim = Animation( x=self.x, y=Window.height, d=FLYING_TIME, t='in_quad') # self.fly_anim.bind(on_complete=lambda *args: self.fall()) self.fly_anim.bind(on_progress=self.__check_if_flew_away) self.fly_anim.start(self) def __move(self, *args): self.is_flying = False if random.random() <= 0.8: self.direction = random.choice((-1, 1)) self.source = self.file + '{0}.zip'.format(self.direction) self.anim_delay = 0.1 dx = self.direction * \ random.randint(0.3 * COW_WIDTH, 0.9 * COW_WIDTH) x = int(self.x + dx) self.move_anim = Animation(x=x, y=BOTTOM_BORDER) self.move_anim.bind(on_complete=self.__move) self.move_anim.start(self) else: self.stop() def __check_if_flew_away(self, *args): if self.y >= Window.height: try: self.fly_anim.cancel(self) self.parent.lose_the_cow(self) # print 'flew away' except AttributeError: pass return def check_collision_with(self, another_cow=None): if self.is_flying: return # or another_cow.is_flying: # print self.parent # print self.index # self.parent.lose_the_cow(self) # del self # self.parent.lose_the_cow(self) # if self.x <= another_cow.right and self.right >= another_cow.x: # collision = True, True # self.x -= 3 # elif self.x >= another_cow.x and self.x <= another_cow.right: # self.x += 3 # collision = True, True # else: # collision = False, False collision = False if self.x <= 0: self.x = 3 collision = True elif self.right >= Window.width: self.x -= 3 collision = True if collision: self.stop() def stop(self): try: self.move_anim.cancel(self) except AttributeError: pass self.source = self.file + '{0}.png'.format(self.direction) Clock.schedule_once(self.__move, random.uniform(0.5, 1.5)) def get_kidnapped(self): self.is_flying = True try: self.move_anim.cancel(self) except AttributeError: pass if self.balloon: return Clock.unschedule(self.__move) self.balloon = Balloon() self.balloon.center = self.center[0], self.top + COW_WIDTH / 2 self.add_widget(self.balloon) # self.balloons.append(balloon) self.balloon.inflate() self.__fly() def check_answer(self, value): if self.balloon and self.balloon.answer == value: self.remove_widget(self.balloon) self.balloon = None self.fall() return True return False def collide_point(self, x, y=None): if (not self.is_flying and x >= self.x - COW_WIDTH and x <= self.right + 10): # print self.x, x return True else: return False def game_over(self): self.remove_widget(self.balloon) self.balloon = None self.fall()
class ZIScatter(Scatter): zoom_image = ObjectProperty(Widget()) init_pos = ObjectProperty((75, 70)) def __init__(self, **kwargs): super(ZIScatter, self).__init__(**kwargs) self.anim = Animation() # Physics simple animation on touch up Clock.schedule_interval(self.clear_canvas, 0) Clock.schedule_interval(self.control_pos, 0) def clear_canvas(self, dt): self.canvas.clear() def is_leaving_its_box(self): #check if scatter is leaving its box s = self.scale x, y = self.pos w, h = self.size container = c = self.zoom_image #check every corner limitx = limity = False if (x > c.x or x + w * s < c.x + c.width): limitx = True if (y > c.y or y + h * s < c.y + c.height): limity = True return (limitx, limity) def fix_after_leaving_its_box(self): #check if scatter is leaving its box s = self.scale x, y = self.pos w, h = self.size container = c = self.zoom_image #check every corner limitx = limity = False if x > c.x: x = c.x if x + w * s < c.x + c.width: x = c.x + c.width - w * s if y > c.y: y = c.y if y + h * s < c.y + c.height: y = c.y + c.height - h * s self.pos = (x, y) def control_pos(self, dt): if self.scale <= 1.03: self.reset() pass #avoid scatter leaving its box while physics animation is going on (after touch up) if len(self._touches) > 0: return limitx, limity = self.is_leaving_its_box() if limitx == True or limity == True: self.anim.cancel(self) self.fix_after_leaving_its_box() def transform_with_touch(self, touch): init_pos = self.center init_scale = self.scale init_touch_len = len(self._touches) #super(ZIScatter, self).transform__with__touch(touch) # just do a simple one finger drag if len(self._touches ) == 1 and self.scale > 1.05: #THIS IS NOT IN ORIGINAL SCATTER: # _last_touch_pos has last pos in correct parent space, # just like incoming touch dx = (touch.x - self._last_touch_pos[touch][0]) \ * self.do_translation_x dy = (touch.y - self._last_touch_pos[touch][1]) \ * self.do_translation_y self.apply_transform(Matrix().translate(dx, dy, 0)) #return elif len( self._touches ) == 1 and self.scale < 1.05: #THIS IS NOT IN ORIGINAL SCATTER: return else: #TO AVOID RETURN IN ORIGINAL SCATTER # we have more than one touch... points = [Vector(self._last_touch_pos[t]) for t in self._touches] # we only want to transform if the touch is part of the two touches # furthest apart! So first we find anchor, the point to transform # around as the touch farthest away from touch anchor = max(points, key=lambda p: p.distance(touch.pos)) # now we find the touch farthest away from anchor, if its not the # same as touch. Touch is not one of the two touches used to transform farthest = max(points, key=anchor.distance) if points.index(farthest) != self._touches.index(touch): return # ok, so we have touch, and anchor, so we can actually compute the # transformation old_line = Vector(*touch.ppos) - anchor new_line = Vector(*touch.pos) - anchor angle = radians(new_line.angle(old_line)) * self.do_rotation self.apply_transform(Matrix().rotate(angle, 0, 0, 1), anchor=anchor) if self.do_scale: scale = new_line.length() / old_line.length() new_scale = scale * self.scale if new_scale < self.scale_min or new_scale > self.scale_max: scale = 1.0 self.apply_transform(Matrix().scale(scale, scale, scale), anchor=anchor) #avoid scatter leaving its box limitx, limity = self.is_leaving_its_box() if limitx or limity: #cancel previous apply_transform if init_touch_len == 1: ddx = ddy = 0 if limitx: ddx = -dx if limity: ddy = -dy self.apply_transform(Matrix().translate(ddx, ddy, 0)) else: if self.do_scale: #self.apply_transform(Matrix().scale(scale/init_scale, scale/init_scale, scale/init_scale), # anchor=anchor) # control #limitx, limity = self.is_leaving_its_box() #if limitx or limity: self.fix_after_leaving_its_box() def on_touch_down(self, touch): ret = super(ZIScatter, self).on_touch_down(touch) x, y = touch.x, touch.y #if not self.zoom_image.image.collide_point(x,y): # # did not touch the mask area # return True # if the touch isnt on the widget we do nothing if self.zoom_image.collide_point(x, y): if touch.is_double_tap: self.reset() #if not self.parent.image.collide_point(x,y): # # did not touch the mask area # touch.ud["outside"] = True # return False return ret def on_touch_up(self, touch): if touch.grab_current is not self: return super(ZIScatter, self).on_touch_up(touch) """ x, y = touch.x, touch.y # if the touch isnt on the widget we do nothing if self.zoom_image.collide_point(x, y): super(ZIScatter, self).on_touch_up(touch) """ ###TAKEN FROM ORIGINAL SCATTER x, y = touch.x, touch.y # if the touch isnt on the widget we do nothing, just try children if self.zoom_image.collide_point(x, y): #MODIFIED ORIGINAL SCATTER !! if not touch.grab_current == self: touch.push() touch.apply_transform_2d(self.to_local) if super(Scatter, self).on_touch_up(touch): touch.pop() return True touch.pop() # remove it from our saved touches if touch in self._touches and touch.grab_state: touch.ungrab(self) del self._last_touch_pos[touch] self._touches.remove(touch) # stop propagating if its within our bounds if self.collide_point(x, y): pass #eturn True #MODIFIED ORIGINAL SCATTER !! # physics behaviour on touch up, fade speed down on the same direction return False duration = d = 1.5 dx = touch.dx * 3 * d dy = touch.dy * 3 * d #print dx, dy adx = abs(dx) ady = abs(dy) if adx > 0 and ady > 0: #if adx > 400 : #if ady > 400 : V = Vector(self.center) Vd = Vector((dx, dy)) destination = V + Vd anim = Animation(center=destination, d=d, t='out_expo', s=1 / 150.) self.anim.stop(self) self.anim = anim self.anim.start(self) self.previous_anim_dest = destination return False def reset(self): self.center = self.init_pos self.scale = 1
class MainScreen(Screen): list = DictProperty(dictionary) def __init__(self, **kwargs): super(MainScreen, self).__init__(**kwargs) self._keyboard = Window.request_keyboard(self._keyboard_closed, self) self._keyboard.bind(on_key_down=self._on_keyboard_down) self.motConVehicleVelocity = '0' self.server_address = "/tmp/mySocket" self.sock = socket.socket() self.data = {} self.left_turn_signal = True self.right_turn_signal = True self.light_one = Animation(color=[.92, .73, .44, 1]) + Animation( color=[.33, .33, .33, 1]) self.light_one.repeat = True self.light_two = Animation(color=[.92, .73, .44, .75]) + Animation( color=[.33, .33, .33, 1]) self.light_two.repeat = True self.light_three = Animation(color=[.92, .73, .44, .5]) + Animation( color=[.33, .33, .33, 1]) self.light_three.repeat = True Clock.schedule_once(self._finish_init) def _finish_init(self, dt): logging.info("Kivy has finished loading.") logging.info("Starting thread to read from socket : " + self.server_address) Thread(target=self.main).start() def main(self): # Create a UDS socket sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) # Connect the socket to the port where the server is listening # print ('connecting to %s' % server_address, file=sys.stderr) try: sock.connect(self.server_address) logging.info("Socket connected to: " + self.server_address) except socket.error as msg: logging.critical(msg) sys.exit(1) try: # Send data # message = b'This is the message. It will be repeated.' # print ('sending "%s"' % message, file=sys.stderr) # sock.sendall(message) amount_received = 0 # amount_expected = len(message) # while amount_received < amount_expected: while True: data = sock.recv(4096) # amount_received += len(data) try: self.data = loads(data.decode()) self.list = self.data self.update(self.data) except: logging.critical("ERROR loading data") finally: # print ('closing socket', file=sys.stderr) sock.close() logging.info("Socket Closed" + self.server_address) # pass def animate_left_lights(self, data): self.left_turn_signal = False self.light_one.start(self.ids.left1) self.light_two.start(self.ids.left2) self.light_three.start(self.ids.left3) def animate_right_lights(self, data): self.right_turn_signal = False self.light_one.start(self.ids.right1) self.light_two.start(self.ids.right2) self.light_three.start(self.ids.right3) def stop_animate_right_lights(self, data): self.light_one.cancel(self.ids.right1) self.light_two.cancel(self.ids.right2) self.light_three.cancel(self.ids.right3) self.ids.right1.color = [1, 1, 1, 1] self.ids.right2.color = [.92, .73, .44, 0] self.ids.right3.color = [.92, .73, .44, 0] self.right_turn_signal = True def stop_animate_left_lights(self, data): self.light_one.cancel(self.ids.left1) self.light_two.cancel(self.ids.left2) self.light_three.cancel(self.ids.left3) self.ids.left1.color = [1, 1, 1, 1] self.ids.left2.color = [.92, .73, .44, 0] self.ids.left3.color = [.92, .73, .44, 0] self.left_turn_signal = True def set_lights(self, turn_signal): self.turn_signal = turn_signal net_gauge = ListProperty([1, 1, 1, 1]) soc = ListProperty([1, 1, 1, 1]) @mainthread def update(self, data): if self.data['gpio5'] == 1 and self.right_turn_signal: self.animate_right_lights(data) elif self.data['gpio5'] == 0: self.stop_animate_right_lights(data) if self.data['gpio6'] == 1 and self.left_turn_signal: self.animate_left_lights(data) elif self.data['gpio6'] == 0: self.stop_animate_left_lights(data) self.soc = self.soc_color(data['soc']) self.net_gauge = percentColor(self.data['netPower']) # --------------------------------- self.manager.raw_data_screen.populate(data) self.manager.dev_screen.update(data) App.get_running_app().update(data) self.net_gauge = percentColor(self.data['netPower']) def soc_color(self, num): range_key_dict = RangeKeyDict({ (0, 26): [.99, .40, .34, 1], (26, 51): [.99, .71, .36, 1], (51, 76): [.99, .84, .21, 1], (76, 101): [.36, .83, .59, 1] }) return range_key_dict[num] def _keyboard_closed(self): self._keyboard.unbind(on_key_down=self._on_keyboard_down) self._keyboard = None def _on_keyboard_down(self, keyboard, keycode, text, modifiers): if keycode[1] == '1': self.manager.current = 'settings_screen_name' elif keycode[1] == '2': self.manager.current = 'main_screen_name' elif keycode[1] == '3': self.manager.current = 'dev_screen_name' elif keycode[1] == '4': self.manager.current = 'raw_data_screen_name' elif keycode[1] == '5': self.manager.current = 'error_screen_name' elif keycode[1] == '9': App.get_running_app().stop() return True
class AtomWidget(BoardItem, Widget): bg_color = ListProperty(Colors.BLACK(0.0)) color = ListProperty(Colors.BLACK()) color_alpha = ListProperty(Colors.BLACK(0.33)) anim = ObjectProperty(None, allownone=True) spacing = NumericProperty(0) status = NumericProperty(0) atom = ObjectProperty(None, rebind=True) index = ObjectProperty(None) def __init__(self, **kwargs): Widget.__init__(self, **kwargs) self.bind(index=self.move_to) # BoardItem.__init__(self, *args, **kwargs)#, atom, index, status) def move_to(self, *args): if self.anim: self.anim.cancel(self) self.anim = None self.anim = Animation(pos=self.parent.index_to_pos(self.index), transition="out_bounce", d=VERY_FAST) self.anim.start(self) def to_string(self): return u"{}[sub]{}[/sub]".format( self.atom.atom, self.atom.number if self.atom.number > 1 else "") def select(self): if self.status == BoardItemStatus.EMPTY: if self.anim: self.anim.cancel(self) self.anim = None self.anim = Animation(bg_color=self.color_alpha, d=FAST) self.anim.start(self) self.marked() self.status = BoardItemStatus.MARKED def unselect(self): if self.status == BoardItemStatus.MARKED: if self.anim: self.anim.cancel(self) self.anim = None self.anim = Animation(bg_color=Colors.BLACK(0.0), d=VERY_FAST) self.anim.start(self) self.empty() self.status = BoardItemStatus.EMPTY def deactivate(self): if self.status == BoardItemStatus.MARKED: if self.anim: self.anim.cancel(self) self.anim = None self.anim = Animation(bg_color=Colors.BLACK(0.0), d=VERY_FAST) self.anim.start(self) self.checked() self.status = BoardItemStatus.CHECKED def collide_point(self, x, y): return (self.center_x - x) ** 2 + \ (self.center_y - y) ** 2 <= \ ((self.width - 3 * self.spacing) / 2) ** 2
# animaçoes em paralelo, duas animacoes ao mesmo tempo anim = Animation(pos=(80, 10)) anim &= Animation(size=(800, 800), duration=2.) anim.start(widget) # animacao em que se repete ao terminar anim = Animation(x=50) + Animation(size=(80, 80), duration=2.) anim.repeat = True anim.start(widget) Animation.cancel_all(widget, 'x') #cancelar todas animacoes # CARACTERISTICAS anim.start(widget) #inicia uma animacao anim.stop(widget) #para uma animacao anim.cancel(widget) #apara a animacaoe evento on_complete noa sera executado Animation.stop_all(widget, 'x') #para e afeta todas a s animacoes Animation.cancel_all(widget, 'y') #para e afeta todas a s animacoes stop_property(widget, 'x') #para e remove a propriedade da animacao do widget cancel_property(widget, 'y') #para e remove a propriedade da animacao do widget anim.duration = 2.0 # tempo duracao de animacao anim.transition = 'in_quad' # funcao de transicao, pode ser da propeia classe que vc criou anim.step = 1.0 / 30.0 # 30 FPS na animacao anim.have_properties_to_animate #retona true se widget tem uma animacao #EVENTOS anim.on_start #dispara quando a niamacaoe iniciada anim.on_complete #dispara quandoa animacao termina anim.on_progress #dispara euqnato a animcao seta sendo executada
class FrontPanel(GridLayout): pasttime = StringProperty('00:00:00') nexttime = StringProperty('00:00:00') duration = NumericProperty(-1) position = NumericProperty(0) volume = NumericProperty(1.0) state = OptionProperty('stop', options=('play', 'pause', 'stop')) controller = ObjectProperty(None, allownone=True) def __init__(self, **kwargs): self._anim = None super(FrontPanel, self).__init__(**kwargs) self.bind(position=self._on_seektime, duration=self._on_seektime) def show(self, duration=20): if self._anim is not None: self._anim.cancel(self) self._anim = None self._anim = Animation(opacity=1, d=1, t='in_out_expo') self._anim += Animation(opacity=1, d=max(1, duration-4), t='linear') self._anim += Animation(opacity=0, d=max(1, duration-7), t='in_out_expo') self._anim.start(self) def hide(self): if self._anim is not None: self._anim.cancel(self) self._anim = None self.opacity = 0 def seek(self, percent): if self.controller is None: return self.controller.seek(percent) def dispatch(self, event_type, *largs): if self.is_event_type(event_type): return super(FrontPanel, self).dispatch(event_type, *largs) controller = self.controller if controller is not None and controller.is_event_type(event_type): return controller.dispatch(event_type, *largs) def on_touch_down(self, touch): if self.opacity < .8: return True return super(FrontPanel, self).on_touch_down(touch) def on_touch_move(self, touch): if self.opacity < .8: return True return super(FrontPanel, self).on_touch_move(touch) def on_touch_up(self, touch): if self.opacity < .8: return True return super(FrontPanel, self).on_touch_up(touch) def on_controller(self, instance, value): controller = value if controller is None: return controller.bind(state=self.setter('state'), duration=self.setter('duration'), position=self.setter('position'), volume=self.setter('volume')) self.bind(state=controller.setter('state'), volume=controller.setter('volume')) def _on_seektime(self, *largs): if self.controller is None or self.duration == 0: self.pasttime = '00:00:00' self.nexttime = '00:00:00' return def seektime(seek): hours = int(seek / 3600) minutes = int(seek / 60) - (hours * 60) seconds = int(seek) - (hours * 3600 + minutes * 60) return '%02d:%02d:%02d' % (hours, minutes, seconds) seek = self.position / float(self.duration) self.pasttime = seektime(self.duration * seek) self.nexttime = seektime(self.duration * (1. - seek))
class Leaf(Image): expression = StringProperty() source = StringProperty('') def __init__(self, pos, size, difficulty): super(Leaf, self).__init__() self.pos = pos self.size = size self.difficulty = difficulty self.truth = True self.taken = False if pos[0] < Window.width / 2: source = random.choice(('Leaf_1.png', 'Leaf_4.png')) self.left = True else: source = random.choice(('Leaf_2.png', 'Leaf_3.png')) self.left = False self.source = 'img/koalas/' + source self.add_expression() self.start_animation() def add_expression(self): if random.random() <= 0.5: self.truth = True else: self.truth = False if random.random() <= 0.7: expression = generator.get_expression(self.truth, self.difficulty) else: expression = generator.get_bool_expression( self.truth, self.difficulty) self.expression = expression def start_animation(self): self.anim = Animation(x=self.x, y=-self.height, d=6) self.anim.bind(on_complete=self.reach_bottom) self.anim.start(self) def reach_bottom(self, *args): if self.truth: self.parent.remove_life() else: self.parent.add_points() self.destroy() def eat_leaf(self): if self.truth: self.parent.add_points() else: self.parent.remove_life() koala = KoalaPaw(self) self.add_widget(koala) koala.animation() def on_touch_down(self, touch): if self.collide_point(touch.x, touch.y) and not self.taken: self.eat_leaf() self.taken = True def grab(self, *args): self.anim.cancel(self) if self.left: x = -self.width else: x = Window.width + self.width y = self.y - self.height anim = Animation(x=x, y=y, d=0.5) anim.start(self) def destroy(self, *args): self.anim.cancel(self) try: self.parent.remove_widget(self) except AttributeError: pass def game_over(self): for child in self.children: if isinstance(child, KoalaPaw): child.game_over() anim = Animation(x=self.x, y=-self.height, d=0.5) anim.bind(on_complete=self.destroy) anim.start(self)
class TransitionBase(EventDispatcher): """Transition class is used to animate 2 screens within the :class:`ScreenManager`. This class act as a base for others implementation, like :class:`SlideTransition`, :class:`SwapTransition`. :Events: `on_progress`: Transition object, progression float Fired during the animation of the transition `on_complete`: Transition object Fired when the transition is fininshed. """ screen_out = ObjectProperty() """Property that contain the screen to hide. Automatically set by the :class:`ScreenManager`. :class:`screen_out` is a :class:`~kivy.properties.ObjectProperty`, default to None. """ screen_in = ObjectProperty() """Property that contain the screen to show. Automatically set by the :class:`ScreenManager`. :class:`screen_in` is a :class:`~kivy.properties.ObjectProperty`, default to None. """ duration = NumericProperty(0.7) """Duration in seconds of the transition. :class:`duration` is a :class:`~kivy.properties.NumericProperty`, default to .7 (= 700ms) """ manager = ObjectProperty() """Screen manager object, set when the screen is added within a manager. :data:`manager` is a :class:`~kivy.properties.ObjectProperty`, default to None, read-only. """ is_active = BooleanProperty() """Indicate if the transition is currently active :data:`is_active` is a :class:`~kivy.properties.BooleanProperty`, default to False, read-only. """ # privates _anim = ObjectProperty(allownone=True) def __init__(self, **kw): self.register_event_type("on_progress") self.register_event_type("on_complete") super(TransitionBase, self).__init__(**kw) def start(self, manager): """(internal) Start the transition. This is automatically called by the :class:`ScreenManager`. """ self.manager = manager self._anim = Animation(d=self.duration, s=0) self._anim.bind(on_progress=self._on_progress, on_complete=self._on_complete) self.add_screen(self.screen_in) self.screen_in.transition_progress = 0.0 self.screen_in.transition_mode = "in" self.screen_out.transition_progress = 0.0 self.screen_out.transition_mode = "out" self.is_active = True self._anim.start(self) self.dispatch("on_progress", 0) def stop(self): """(internal) Stop the transition. This is automatically called by the :class:`ScreenManager`. """ if self._anim: self._anim.cancel(self) self.dispatch("on_complete") self._anim = None self.is_active = False def add_screen(self, screen): """(internal) Used to add a screen into the :class:`ScreenManager` """ self.manager.real_add_widget(screen) def remove_screen(self, screen): """(internal) Used to remove a screen into the :class:`ScreenManager` """ self.manager.real_remove_widget(screen) def on_complete(self): self.remove_screen(self.screen_out) def on_progress(self, progression): pass def _on_progress(self, *l): progress = l[-1] self.screen_in.transition_progress = progress self.screen_out.transition_progress = 1.0 - progress self.dispatch("on_progress", progress) def _on_complete(self, *l): self.is_active = False self.dispatch("on_complete") self._anim = None
class DoorScreen(Screen): poll_for_resume = None return_to_screen = 'home' countdown_image = ObjectProperty() spindle_raise_label = ObjectProperty() def __init__(self, **kwargs): super(DoorScreen, self).__init__(**kwargs) self.sm = kwargs['screen_manager'] self.m = kwargs['machine'] self.jd = kwargs['job'] self.db = kwargs['database'] self.l = kwargs['localization'] self.header_label.text = self.l.get_bold('Interrupt bar pushed!') self.anim_spindle_label = Animation( opacity=1, duration=1.5) + Animation(opacity=0, duration=0.5) + Animation( opacity=0, duration=1.5) + Animation(opacity=1, duration=0.5) self.anim_countdown_img = Animation( opacity=0, duration=1.5) + Animation(opacity=1, duration=0.5) + Animation( opacity=1, duration=1.5) + Animation(opacity=0, duration=0.5) self.anim_stop_bar = Animation(x=150, duration=0.3) + Animation( x=153, duration=0.2) + Animation(x=151, duration=0.2) + Animation( x=152, duration=0.2) + Animation(x=152, duration=0.2) + Animation( x=152, duration=0.2) + Animation( x=152, duration=1.6) + Animation( x=140, duration=2) + Animation(x=140, duration=2) self.anim_stop_img = Animation(opacity=0, duration=0.3) + Animation( opacity=1, duration=0.2) + Animation(opacity=0.8, duration=0.2) + Animation( opacity=1, duration=0.2) + Animation( opacity=0.8, duration=0.2) + Animation( opacity=1, duration=0.2) + Animation( opacity=1, duration=1.6) + Animation( opacity=0, duration=2) + Animation(opacity=0, duration=2) self.anim_spindle_label_end = Animation(opacity=0, duration=0.5) self.anim_countdown_img_end = Animation(opacity=0, duration=0.5) def on_pre_enter(self): self.resume_button.disabled = True self.cancel_button.disabled = True self.resume_button.opacity = 0 self.cancel_button.opacity = 0 def on_enter(self): if not str(self.m.state()).startswith('Door:0'): print(str(self.m.state())) self.anim_countdown_img.repeat = True self.anim_spindle_label.repeat = True Clock.schedule_once(self.start_spindle_label_animation, 1.4) self.poll_for_resume = Clock.schedule_interval( lambda dt: self.check_spindle_has_raised(), 0.2) else: Clock.schedule_once(self.ready_to_resume, 0.2) self.db.send_event( 1, "Job paused", "Paused job (Interrupt bar pushed): " + self.jd.job_name, 3) self.start_x_beam_animation(0) def on_pre_leave(self): if self.poll_for_resume != None: Clock.unschedule(self.poll_for_resume) self.anim_stop_bar.repeat = False self.anim_stop_img.repeat = False def on_leave(self): self.spindle_raise_label.text = self.l.get_str( 'Preparing to resume, please wait') + '...' def start_x_beam_animation(self, dt): self.anim_stop_bar.start(self.x_beam) self.anim_stop_img.start(self.stop_img) def start_spindle_label_animation(self, dt): if not str(self.m.state()).startswith('Door:0'): self.anim_spindle_label.start(self.spindle_raise_label) self.anim_countdown_img.start(self.countdown_image) def check_spindle_has_raised(self): if (str(self.m.state()).startswith('Door:0') or not (str(self.m.state()).startswith('Door'))): Clock.unschedule(self.poll_for_resume) self.anim_spindle_label.repeat = False self.anim_countdown_img.repeat = False self.anim_spindle_label.cancel(self.spindle_raise_label) self.anim_countdown_img.cancel(self.countdown_image) self.anim_countdown_img_end.start(self.countdown_image) Clock.schedule_once(self.ready_to_resume, 0.2) self.start_x_beam_animation(1.5) def ready_to_resume(self, dt): self.resume_button.opacity = 1 self.cancel_button.opacity = 1 self.resume_button.disabled = False self.cancel_button.disabled = False self.anim_stop_bar.repeat = True self.anim_stop_img.repeat = True self.spindle_raise_label.text = '...' + self.l.get_str( 'ready to resume') self.spindle_raise_label.opacity = 1 def resume_stream(self): # Job resumed, send event self.db.send_event(0, 'Job resumed', 'Resumed job: ' + self.jd.job_name, 4) self.m.resume_after_a_hard_door() self.return_to_app() def cancel_stream(self): if self.return_to_screen == 'go': self.sm.get_screen('job_incomplete').prep_this_screen( 'cancelled', event_number=False) self.return_to_screen = 'job_incomplete' else: self.m.s.cancel_sequential_stream(reset_grbl_after_cancel=False) self.m.cancel_after_a_hard_door() self.return_to_app() def return_to_app(self): if self.sm.has_screen(self.return_to_screen): self.sm.current = self.return_to_screen else: self.sm.current = 'lobby'
class InventoryItem(BoxLayout): btn_save = ObjectProperty() btn_delete = ObjectProperty() def __init__(self, **kwargs): super(InventoryItem, self).__init__(**kwargs) self.btn_delete = ImageButton(source="delete.png", on_release=self.deleteInventory) self.btn_save = ImageButton(source="save.png", on_release=self.saveInventory) def editInventory(self): print "Edit inventory" self.txt_clave.disabled = False self.txt_producto.disabled = False self.txt_existencias.disabled = False self.txt_minimo.disabled = False self.txt_maximo.disabled = False self.txt_precio.disabled = False self.txt_producto.focus = True self.lay_buttons.remove_widget(self.btn_edit) self.lay_buttons.add_widget(self.btn_delete) self.lay_buttons.add_widget(self.btn_save) def saveInventory(self, w): if not hasattr(self, "dataitem"): self.dataitem = Inventarios() self.dataitem.Clave = self.txt_clave.text self.dataitem.Producto = self.txt_producto.text self.dataitem.Existencias = self.txt_existencias.text self.dataitem.Minimo = self.txt_minimo.text self.dataitem.Maximo = self.txt_maximo.text self.dataitem.Precio = self.txt_precio.text self.dataitem.PUser = app.root.user # inventoryitem.save() AsyncSave(callback=self.item_saved, objsave=self.dataitem) self.lay_buttons.remove_widget(self.btn_delete) self.lay_buttons.remove_widget(self.btn_save) self.loading = RotatedImage(source="newloading.png") self.anim = Animation(angle=360, duration=5) self.anim.bind(on_complete=self.item_timeout) self.anim.start(self.loading) self.lay_buttons.add_widget(self.loading) def item_saved(self, dt): self.anim.cancel(self.loading) self.lay_buttons.remove_widget(self.loading) self.lay_buttons.add_widget(self.btn_edit) # disable all self.txt_clave.disabled = True self.txt_producto.disabled = True self.txt_existencias.disabled = True self.txt_minimo.disabled = True self.txt_maximo.disabled = True self.txt_precio.disabled = True def item_timeout(self, anim, w): print "SAVE TIMEOUT" def deleteInventory(self, w): print "Deleting" self.dataitem.delete() app.root.inventario.lst_inventory.remove_widget(self)
class ImmersiveLayout(StencilView): immersed = BooleanProperty(None) '''State of the layout. If True, the dock is hidden. ''' auto_show = BooleanProperty(True) '''Boolean specifying whether input events trigger the ImmersiveLayout to exit immersive mode.''' auto_hide = BooleanProperty(True) '''Boolean specifying whether the dock will hide after **timeout** seconds.''' timeout = NumericProperty(5) '''Time after the last input event (keyboard, touch, mouse) after which the dock is hidden. If set to 0, the layout will stay opened until manually closed.''' animation_duration = NumericProperty(0.75) '''Speed at which the dock opens, in seconds. ''' max_dock_size = NumericProperty(0.2) '''Maximum dock size as a fraction of the ImmersiveLayout's size. ''' fade = BooleanProperty(True) '''Boolean specifying whether the dock fades into view when opening. ''' transition = StringProperty('in_out_sine') '''The name of the animation transition type to use when animating. Defaults to 'out_cubic'.''' _anim_progress = NumericProperty(1 * (not immersed)) ''' Internal parameter monitoring the progress of the dock's opening animation. 1 is opened, 0 is closed.''' _anim = ObjectProperty(None) '''Animation. ''' _scheduled_close = ObjectProperty(None, allownone=True) '''Scheduled close event. ''' main_panel = ObjectProperty(None, allownone=True) '''Automatically bound to whatever widget is added as the main panel.''' dock = ObjectProperty(None, allownone=True) '''Automatically bound to whatever widget is added as the dock.''' def __init__(self, **kwargs): super(ImmersiveLayout, self).__init__(**kwargs) self._anim = Animation(_anim_progress=1 * (not self.immersed), duration=self.animation_duration, t=self.transition) Window.bind(on_keyboard=self._keyboard_handler) self.register_event_type('on_enter_immersive') self.register_event_type('on_exit_immersive') self.register_event_type('on_finished_entering') self.register_event_type('on_finished_exiting') def _keyboard_handler(self, window, key, *args): """ If auto_show is True. The first keyboard event will open the dock and block. If the dock is opened, then the key events will be passed """ if self.auto_show: immersed = self.immersed #self.immersed = False self.exit_immersive_mode() self._schedule_close() # If the dock was opened, pass on the event, otherwise block it from the system return immersed def add_widget(self, widget, index=0): """ The first two widget we add are the containers for the main panel and dock, _main_panel and _dock, this is done automatically by instantiating the class. After, when the user adds widgets to the ImmersiveLayout, we add the first widget supplied to the the _main_panel and the second widget to the _dock. """ if len(self.children) == 0: super(ImmersiveLayout, self).add_widget(widget) self._main_panel = widget elif len(self.children) == 1: super(ImmersiveLayout, self).add_widget(widget) self._dock = widget elif self.main_panel is None: self._main_panel.add_widget(widget) self.main_panel = widget elif self.dock is None: self._dock.add_widget(widget) self.dock = widget def cancel_scheduled_close(self): """ Cancel a scheduled close and schedule a new one. """ if self._scheduled_close: self._scheduled_close.cancel() def _schedule_close(self, *args): """ Schedules a close event for the dock. """ if self.timeout > 0: self.cancel_scheduled_close() self._scheduled_close = Clock.schedule_once(self.enter_immersive_mode, self.timeout) def toggle_state(self, *args): """ Toggle the state of immersion """ if self.immersed: self.exit_immersive_mode() else: self.enter_immersive_mode() def enter_immersive_mode(self, *args): """ Enter immersive mode. """ self._anim.cancel(self) self._anim = Animation(_anim_progress=0, duration=self.animation_duration, t=self.transition) self._anim.start(self) self._anim.bind(on_complete=lambda *x: self.dispatch('on_finished_entering')) self.immersed = True self.dispatch('on_enter_immersive') def exit_immersive_mode(self, *args): """ Exit immersive mode. """ self._anim.cancel(self) self._anim = Animation(_anim_progress=1, duration=self.animation_duration, t=self.transition) self._anim.start(self) self.immersed = False self._anim.bind(on_complete=lambda *x: self.dispatch('on_finished_exiting')) self.dispatch('on_exit_immersive') # Schedule a close event if auto_hide is enabled. if self.auto_hide: self._schedule_close() def on_enter_immersive(self, *args): """ Signals the beginning of the event to enter immersive mode. """ pass def on_finished_entering(self, *args): """ Signals the end of the event to enter immersive mode. """ pass def on_exit_immersive(self, *args): """ Signals the beginning of the event to leave immersive mode. """ pass def on_finished_exiting(self, *args): """ Signals the end of the event to exit immersive mode. """ pass def on_auto_hide(self, *args): if self.timeout > 0: # Store the value of the timeout in case we turn on auto_hide again. self._timeout = self.timeout if self._scheduled_close: self._scheduled_close.cancel() self.timeout = self._timeout * self.auto_hide if self.auto_hide: self._schedule_close() def on_touch_down(self, touch): if self.auto_show: immersed = self.immersed if not self.immersed: self.cancel_scheduled_close() self.exit_immersive_mode() # While the dock is hidden, do not pass the touch event through. if immersed: return else: super(ImmersiveLayout, self).on_touch_down(touch) else: super(ImmersiveLayout, self).on_touch_down(touch)
class PickerScreen(Screen): def on_pre_enter(self): self.layout = search(self, 'layout') self.background = search(self, 'background') self.scrollview = search(self, 'scrollview') self.focus = None # set the background to the correct position self.on_picker_scroll(None, None) self.scrollview.bind(scroll_x=self.on_picker_scroll) self.scrollview.bind(pos=self.on_picker_move) images = get_images() width = math.ceil((len(images) / 2.0 * 312) / 1280.0) self.max_width = width * 1280 # set the width to be much great than the screen # somewhat proportionally to the number of images rellayout = search(self, 'rellayout') rellayout.size_hint = (width, 1) grid = search(self, 'grid') Loader.loading_image = CoreImage('images/loading.gif') Loader.num_workers = 4 Loader.max_upload_per_frame = 4 for image in get_images(): widget = Factory.AsyncImage(source=image, allow_stretch=True) widget.bind(on_touch_down=self.on_image_touch) grid.add_widget(widget) self.scrollview_hidden = False self._scrollview_pos_hint = self.scrollview.pos_hint self._scrollview_pos = self.scrollview.pos self._sv_hide_ani = None self._sv_show_ani = None self._focus_hide_ani = None self._focus_show_ani = None self._focus_widget = Image(source='images/loading.gif') self._focus_widget.allow_stretch = True self._focus_widget.pos_hint = {'center_x': .5} self._focus_widget.y = 1024 self._focus_widget.size_hint = None, None self._focus_widget.size = (600, 600) self._focus_widget.bind(on_touch_down=self.on_image_touch) self.layout.add_widget(self._focus_widget) def on_image_touch(self, widget, mouse_point): if widget.collide_point(mouse_point.x, mouse_point.y): # show the focus widget if self.scrollview_hidden: self.scrollview_hidden = False # cancel scrollview hiding animation try: self._sv_hide_ani.cancel(self.scrollview) except AttributeError: pass # show the scrollview x, y = self._scrollview_pos self._sv_show_ani = Animation(x=x, y=y, t='in_out_quad', duration=.5) self._sv_show_ani.start(self.scrollview) # cancel the focus widget show animation try: self._focus_show_ani.cancel(self._focus_widget) except AttributeError: pass # hide the focus widget self._focus_hide_ani = Animation(y=1024, size=(600, 600), t='in_out_quad', duration=.5) self._focus_hide_ani.start(self._focus_widget) # hide the focus widget elif self._focus_widget is not widget: self.scrollview_hidden = True # cancel the scrollview show animation try: self._sv_show_ani.cancel(self.scrollview) except AttributeError: pass # hide the scrollview self.sv_hide_ani = Animation(x=0, y=-450, t='in_out_quad', duration=.5) self.sv_hide_ani.start(self.scrollview) # make sure the focus animation is finished try: self._focus_hide_ani.cancel(self._focus_widget) except AttributeError: pass # set the focus widget to have the same image as the one picked # do a bit of mangling to get a more detailed image filename = os.path.join(detail, os.path.basename(widget.source)) self._focus_widget.source = filename # show the focus widget self._focus_show_ani = Animation(y=200, size=(800, 800), t='in_out_quad', duration=.5) self._focus_show_ani.start(self._focus_widget) def on_picker_move(self, widget, arg): if widget is self.scrollview: x, y = self.background.pos self.background.pos = (x, -arg[1] / 50) def on_picker_scroll(self, value1, value2): self.background.pos = (self.scrollview.scroll_x * -600 - 100, self.background.pos[1]) return False
class Help(OverlayView): target_widget = ObjectProperty(None, allownone=True, baseclass=Widget) def __init__(self, **kwargs): super(Help, self).__init__(**kwargs) self._anim_open = Animation(d=0.4) self._anim_open.fbind('on_complete', self._on_anim_open_complete) self._anim_dismiss = Animation(d=0.4) self._anim_dismiss.fbind('on_complete', self._on_anim_dismiss_complete) self._current_anim = None def open(self, *largs): if self._current_anim: return if self._window is not None: Logger.warning('ModalView: you can only open once.') return # search window self._window = self._search_window() if not self._window: Logger.warning('ModalView: cannot open view, no window found.') return self._window.add_widget(self) self._window.bind(on_keyboard=self._handle_keyboard) self._align_center() self.pos = (0, -self.height) target_widget = self.target_widget if target_widget: target_widget.bind(center=self._align_center) else: self._window.bind(on_resize=self._align_center) anim = self._anim_open anim.animated_properties.update(self._create_open_properties()) anim.start(self) self._current_anim = anim def dismiss(self, *largs, **kwargs): if self._current_anim is self._anim_open: self._anim_open.cancel(self) anim = self._anim_dismiss if self._current_anim is anim: return anim.animated_properties.update(self._create_dismiss_properties()) anim.start(self) self._current_anim = anim def _on_anim_open_complete(self, *args): self._current_anim = None self.dispatch('on_open') def _on_anim_dismiss_complete(self, *args): self._current_anim = None self.dispatch('on_dismiss') self._real_remove_widget() def _create_open_properties(self): target_widget = self.target_widget if target_widget: center = target_widget.to_window(*target_widget.center) else: center = self._window.center return {'center': center} def _create_dismiss_properties(self): return {'top': 0} def _align_center(self, *l): if self.target_widget: self.size = self.target_widget.size else: self.size = self._window.size self._update_animation() def _update_animation(self, *args): anim = self._current_anim if anim: anim.cancel(self) if anim is self._anim_open: properties = self._create_open_properties() else: properties = self._create_dismiss_properties() anim.animated_properties.update(properties) anim.start(self) def _real_remove_widget(self): super(Help, self)._real_remove_widget() target_widget = self.target_widget if target_widget: target_widget.unbind(center=self._align_center)
class TransitionBase(EventDispatcher): '''Transition class is used to animate 2 screens within the :class:`ScreenManager`. This class act as a base for others implementation, like :class:`SlideTransition`, :class:`SwapTransition`. :Events: `on_progress`: Transition object, progression float Fired during the animation of the transition `on_complete`: Transition object Fired when the transition is fininshed. ''' screen_out = ObjectProperty() '''Property that contain the screen to hide. Automatically set by the :class:`ScreenManager`. :class:`screen_out` is a :class:`~kivy.properties.ObjectProperty`, default to None. ''' screen_in = ObjectProperty() '''Property that contain the screen to show. Automatically set by the :class:`ScreenManager`. :class:`screen_in` is a :class:`~kivy.properties.ObjectProperty`, default to None. ''' duration = NumericProperty(.7) '''Duration in seconds of the transition. :class:`duration` is a :class:`~kivy.properties.NumericProperty`, default to .7 (= 700ms) ''' manager = ObjectProperty() '''Screen manager object, set when the screen is added within a manager. :data:`manager` is a :class:`~kivy.properties.ObjectProperty`, default to None, read-only. ''' is_active = BooleanProperty(False) '''Indicate if the transition is currently active :data:`is_active` is a :class:`~kivy.properties.BooleanProperty`, default to False, read-only. ''' # privates _anim = ObjectProperty(allownone=True) def __init__(self, **kw): self.register_event_type('on_progress') self.register_event_type('on_complete') super(TransitionBase, self).__init__(**kw) def start(self, manager): '''(internal) Start the transition. This is automatically called by the :class:`ScreenManager`. ''' if self.is_active: raise ScreenManagerException('start() is called twice!') self.manager = manager self._anim = Animation(d=self.duration, s=0) self._anim.bind(on_progress=self._on_progress, on_complete=self._on_complete) self.add_screen(self.screen_in) self.screen_in.transition_progress = 0. self.screen_in.transition_state = 'in' self.screen_out.transition_progress = 0. self.screen_out.transition_state = 'out' self.screen_in.dispatch('on_pre_enter') self.screen_out.dispatch('on_pre_leave') self.is_active = True self._anim.start(self) self.dispatch('on_progress', 0) def stop(self): '''(internal) Stop the transition. This is automatically called by the :class:`ScreenManager`. ''' if self._anim: self._anim.cancel(self) self.dispatch('on_complete') self._anim = None self.is_active = False def add_screen(self, screen): '''(internal) Used to add a screen into the :class:`ScreenManager` ''' self.manager.real_add_widget(screen) def remove_screen(self, screen): '''(internal) Used to remove a screen into the :class:`ScreenManager` ''' self.manager.real_remove_widget(screen) def on_complete(self): self.remove_screen(self.screen_out) def on_progress(self, progression): pass def _on_progress(self, *l): progress = l[-1] self.screen_in.transition_progress = progress self.screen_out.transition_progress = 1. - progress self.dispatch('on_progress', progress) def _on_complete(self, *l): self.is_active = False self.dispatch('on_complete') self.screen_in.dispatch('on_enter') self.screen_out.dispatch('on_leave') self._anim = None
class PickerScreen(Screen): def on_pre_enter(self): self.layout = search(self, 'layout') self.background = search(self, 'background') self.scrollview = search(self, 'scrollview') self.focus = None # set the background to the correct position self.on_picker_scroll(None, None) self.scrollview.bind(scroll_x=self.on_picker_scroll) self.scrollview.bind(pos=self.on_picker_move) images = get_images() width = math.ceil((len(images) / 2.0 * 312) / 1280.0) self.max_width = width * 1280 # set the width to be much great than the screen # somewhat proportionally to the number of images rellayout = search(self, 'rellayout') rellayout.size_hint = (width,1) grid = search(self, 'grid') Loader.loading_image = CoreImage('images/loading.gif') Loader.num_workers = 4 Loader.max_upload_per_frame = 4 for image in get_images(): widget = Factory.AsyncImage(source=image, allow_stretch=True) widget.bind(on_touch_down=self.on_image_touch) grid.add_widget(widget) self.scrollview_hidden = False self._scrollview_pos_hint = self.scrollview.pos_hint self._scrollview_pos = self.scrollview.pos self._sv_hide_ani = None self._sv_show_ani = None self._focus_hide_ani = None self._focus_show_ani = None self._focus_widget = Image(source='images/loading.gif') self._focus_widget.allow_stretch = True self._focus_widget.pos_hint = {'center_x': .5} self._focus_widget.y = 1024 self._focus_widget.size_hint = None, None self._focus_widget.size = (600, 600) self._focus_widget.bind(on_touch_down=self.on_image_touch) self.layout.add_widget(self._focus_widget) def on_image_touch(self, widget, mouse_point): if widget.collide_point(mouse_point.x, mouse_point.y): # show the focus widget if self.scrollview_hidden: self.scrollview_hidden = False # cancel scrollview hiding animation try: self._sv_hide_ani.cancel(self.scrollview) except AttributeError: pass # show the scrollview x, y = self._scrollview_pos self._sv_show_ani = Animation(x=x, y=y, t='in_out_quad', duration=.5) self._sv_show_ani.start(self.scrollview) # cancel the focus widget show animation try: self._focus_show_ani.cancel(self._focus_widget) except AttributeError: pass # hide the focus widget self._focus_hide_ani = Animation(y=1024, size=(600,600), t='in_out_quad', duration=.5) self._focus_hide_ani.start(self._focus_widget) # hide the focus widget elif self._focus_widget is not widget: self.scrollview_hidden = True # cancel the scrollview show animation try: self._sv_show_ani.cancel(self.scrollview) except AttributeError: pass # hide the scrollview self.sv_hide_ani = Animation(x=0, y=-450, t='in_out_quad', duration=.5) self.sv_hide_ani.start(self.scrollview) # make sure the focus animation is finished try: self._focus_hide_ani.cancel(self._focus_widget) except AttributeError: pass # set the focus widget to have the same image as the one picked # do a bit of mangling to get a more detailed image filename = os.path.join(detail, os.path.basename(widget.source)) self._focus_widget.source = filename # show the focus widget self._focus_show_ani = Animation(y=200, size=(800, 800), t='in_out_quad', duration=.5) self._focus_show_ani.start(self._focus_widget) def on_picker_move(self, widget, arg): if widget is self.scrollview: x, y = self.background.pos self.background.pos = (x, -arg[1] / 50) def on_picker_scroll(self, value1, value2): self.background.pos = (self.scrollview.scroll_x*-600 - 100, self.background.pos[1]) return False
class Leaf(Image): expression = StringProperty() source = StringProperty('') def __init__(self, pos, size, difficulty): super(Leaf, self).__init__() self.pos = pos self.size = size self.difficulty = difficulty self.truth = True self.taken = False if pos[0] < Window.width / 2: source = random.choice(('Leaf_1.png', 'Leaf_4.png')) self.left = True else: source = random.choice(('Leaf_2.png', 'Leaf_3.png')) self.left = False self.source = 'img/koalas/' + source self.add_expression() self.start_animation() def add_expression(self): if random.random() <= 0.5: self.truth = True else: self.truth = False if random.random() <= 0.7: expression = generator.get_expression(self.truth, self.difficulty) else: expression = generator.get_bool_expression(self.truth, self.difficulty) self.expression = expression def start_animation(self): self.anim = Animation(x=self.x, y=-self.height, d=6) self.anim.bind(on_complete=self.reach_bottom) self.anim.start(self) def reach_bottom(self, *args): if self.truth: self.parent.remove_life() else: self.parent.add_points() self.destroy() def eat_leaf(self): if self.truth: self.parent.add_points() else: self.parent.remove_life() koala = KoalaPaw(self) self.add_widget(koala) koala.animation() def on_touch_down(self, touch): if self.collide_point(touch.x, touch.y) and not self.taken: self.eat_leaf() self.taken = True def grab(self, *args): self.anim.cancel(self) if self.left: x = -self.width else: x = Window.width + self.width y = self.y - self.height anim = Animation(x=x, y=y, d=0.5) anim.start(self) def destroy(self, *args): self.anim.cancel(self) try: self.parent.remove_widget(self) except AttributeError: pass def game_over(self): for child in self.children: if isinstance(child, KoalaPaw): child.game_over() anim = Animation(x=self.x, y=-self.height, d=0.5) anim.bind(on_complete=self.destroy) anim.start(self)
class TransitionBase(EventDispatcher): '''Transition class is used to animate 2 screens within the :class:`ScreenManager`. This class act as a base for others implementation, like :class:`SlideTransition`, :class:`SwapTransition`. :Events: `on_progress`: Transition object, progression float Fired during the animation of the transition `on_complete`: Transition object Fired when the transition is fininshed. ''' screen_out = ObjectProperty() '''Property that contain the screen to hide. Automatically set by the :class:`ScreenManager`. :class:`screen_out` is a :class:`~kivy.properties.ObjectProperty`, default to None. ''' screen_in = ObjectProperty() '''Property that contain the screen to show. Automatically set by the :class:`ScreenManager`. :class:`screen_in` is a :class:`~kivy.properties.ObjectProperty`, default to None. ''' duration = NumericProperty(.7) '''Duration in seconds of the transition. :class:`duration` is a :class:`~kivy.properties.NumericProperty`, default to .7 (= 700ms) ''' manager = ObjectProperty() '''Screen manager object, set when the screen is added within a manager. :data:`manager` is a :class:`~kivy.properties.ObjectProperty`, default to None, read-only. ''' is_active = BooleanProperty(False) '''Indicate if the transition is currently active :data:`is_active` is a :class:`~kivy.properties.BooleanProperty`, default to False, read-only. ''' # privates _anim = ObjectProperty(allownone=True) __events__ = ('on_progress', 'on_complete') def start(self, manager): '''(internal) Start the transition. This is automatically called by the :class:`ScreenManager`. ''' if self.is_active: raise ScreenManagerException('start() is called twice!') self.manager = manager self._anim = Animation(d=self.duration, s=0) self._anim.bind(on_progress=self._on_progress, on_complete=self._on_complete) self.add_screen(self.screen_in) self.screen_in.transition_progress = 0. self.screen_in.transition_state = 'in' self.screen_out.transition_progress = 0. self.screen_out.transition_state = 'out' self.screen_in.dispatch('on_pre_enter') self.screen_out.dispatch('on_pre_leave') self.is_active = True self._anim.start(self) self.dispatch('on_progress', 0) def stop(self): '''(internal) Stop the transition. This is automatically called by the :class:`ScreenManager`. ''' if self._anim: self._anim.cancel(self) self.dispatch('on_complete') self._anim = None self.is_active = False def add_screen(self, screen): '''(internal) Used to add a screen into the :class:`ScreenManager` ''' self.manager.real_add_widget(screen) def remove_screen(self, screen): '''(internal) Used to remove a screen into the :class:`ScreenManager` ''' self.manager.real_remove_widget(screen) def on_complete(self): self.remove_screen(self.screen_out) def on_progress(self, progression): pass def _on_progress(self, *l): progress = l[-1] self.screen_in.transition_progress = progress self.screen_out.transition_progress = 1. - progress self.dispatch('on_progress', progress) def _on_complete(self, *l): self.is_active = False self.dispatch('on_complete') self.screen_in.dispatch('on_enter') self.screen_out.dispatch('on_leave') self._anim = None
class MDCheckbox(CircularRippleBehavior, ToggleButtonBehavior, MDIcon): active = BooleanProperty(False) checkbox_icon_normal = StringProperty("checkbox-blank-outline") checkbox_icon_down = StringProperty("checkbox-marked-outline") radio_icon_normal = StringProperty("checkbox-blank-circle-outline") radio_icon_down = StringProperty("checkbox-marked-circle-outline") selected_color = ListProperty() unselected_color = ListProperty() disabled_color = ListProperty() _current_color = ListProperty([0.0, 0.0, 0.0, 0.0]) def __init__(self, **kwargs): self.check_anim_out = Animation(font_size=0, duration=0.1, t="out_quad") self.check_anim_in = Animation(font_size=sp(24), duration=0.1, t="out_quad") super().__init__(**kwargs) self.selected_color = self.theme_cls.primary_color self.unselected_color = self.theme_cls.secondary_text_color self.disabled_color = self.theme_cls.divider_color self._current_color = self.unselected_color self.check_anim_out.bind( on_complete=lambda *x: self.check_anim_in.start(self)) self.bind( checkbox_icon_normal=self.update_icon, checkbox_icon_down=self.update_icon, radio_icon_normal=self.update_icon, radio_icon_down=self.update_icon, group=self.update_icon, selected_color=self.update_color, unselected_color=self.update_color, disabled_color=self.update_color, disabled=self.update_color, state=self.update_color, ) self.update_icon() self.update_color() def update_icon(self, *args): if self.state == "down": self.icon = (self.radio_icon_down if self.group else self.checkbox_icon_down) else: self.icon = (self.radio_icon_normal if self.group else self.checkbox_icon_normal) def update_color(self, *args): if self.disabled: self._current_color = self.disabled_color elif self.state == "down": self._current_color = self.selected_color else: self._current_color = self.unselected_color def on_state(self, *args): if self.state == "down": self.check_anim_in.cancel(self) self.check_anim_out.start(self) self.update_icon() self.active = True else: self.check_anim_in.cancel(self) self.check_anim_out.start(self) self.update_icon() self.active = False def on_active(self, *args): self.state = "down" if self.active else "normal"
class InventoryItem(BoxLayout): btn_save = ObjectProperty() btn_delete = ObjectProperty() def __init__(self, **kwargs): super(InventoryItem, self).__init__(**kwargs) self.btn_delete = ImageButton(source="delete.png", on_release=self.deleteInventory) self.btn_save = ImageButton(source="save.png", on_release=self.saveInventory) def editInventory(self): print "Edit inventory" self.txt_clave.disabled = False self.txt_producto.disabled = False self.txt_existencias.disabled = False self.txt_minimo.disabled = False self.txt_maximo.disabled = False self.txt_precio.disabled = False self.txt_producto.focus = True self.lay_buttons.remove_widget(self.btn_edit) self.lay_buttons.add_widget(self.btn_delete) self.lay_buttons.add_widget(self.btn_save) def saveInventory(self, w): if not hasattr(self, "dataitem"): self.dataitem = Inventarios() self.dataitem.Clave = self.txt_clave.text self.dataitem.Producto = self.txt_producto.text self.dataitem.Existencias = self.txt_existencias.text self.dataitem.Minimo = self.txt_minimo.text self.dataitem.Maximo = self.txt_maximo.text self.dataitem.Precio = self.txt_precio.text self.dataitem.PUser = app.root.user #inventoryitem.save() AsyncSave(callback=self.item_saved, objsave=self.dataitem) self.lay_buttons.remove_widget(self.btn_delete) self.lay_buttons.remove_widget(self.btn_save) self.loading = RotatedImage(source="newloading.png") self.anim = Animation(angle=360, duration=5) self.anim.bind(on_complete=self.item_timeout) self.anim.start(self.loading) self.lay_buttons.add_widget(self.loading) def item_saved(self, dt): self.anim.cancel(self.loading) self.lay_buttons.remove_widget(self.loading) self.lay_buttons.add_widget(self.btn_edit) #disable all self.txt_clave.disabled = True self.txt_producto.disabled = True self.txt_existencias.disabled = True self.txt_minimo.disabled = True self.txt_maximo.disabled = True self.txt_precio.disabled = True def item_timeout(self, anim, w): print "SAVE TIMEOUT" def deleteInventory(self, w): print "Deleting" self.dataitem.delete() app.root.inventario.lst_inventory.remove_widget(self)
class MDCheckbox(CircularRippleBehavior, ToggleButtonBehavior, MDIcon): active = BooleanProperty(False) """ Indicates if the checkbox is active or inactive. :attr:`active` is a :class:`~kivy.properties.BooleanProperty` and defaults to `False`. """ checkbox_icon_normal = StringProperty("checkbox-blank-outline") """ Background icon of the checkbox used for the default graphical representation when the checkbox is not pressed. :attr:`checkbox_icon_normal` is a :class:`~kivy.properties.StringProperty` and defaults to `'checkbox-blank-outline'`. """ checkbox_icon_down = StringProperty("checkbox-marked-outline") """ Background icon of the checkbox used for the default graphical representation when the checkbox is pressed. :attr:`checkbox_icon_down` is a :class:`~kivy.properties.StringProperty` and defaults to `'checkbox-marked-outline'`. """ radio_icon_normal = StringProperty("checkbox-blank-circle-outline") """ Background icon (when using the ``group`` option) of the checkbox used for the default graphical representation when the checkbox is not pressed. :attr:`radio_icon_normal` is a :class:`~kivy.properties.StringProperty` and defaults to `'checkbox-blank-circle-outline'`. """ radio_icon_down = StringProperty("checkbox-marked-circle-outline") """ Background icon (when using the ``group`` option) of the checkbox used for the default graphical representation when the checkbox is pressed. :attr:`radio_icon_down` is a :class:`~kivy.properties.StringProperty` and defaults to `'checkbox-marked-circle-outline'`. """ selected_color = ListProperty() """ Selected color in ``rgba`` format. :attr:`selected_color` is a :class:`~kivy.properties.ListProperty` and defaults to `[]`. """ unselected_color = ListProperty() """ Unelected color in ``rgba`` format. :attr:`unselected_color` is a :class:`~kivy.properties.ListProperty` and defaults to `[]`. """ disabled_color = ListProperty() """ Disabled color in ``rgba`` format. :attr:`disabled_color` is a :class:`~kivy.properties.ListProperty` and defaults to `[]`. """ _current_color = ListProperty([0.0, 0.0, 0.0, 0.0]) def __init__(self, **kwargs): self.check_anim_out = Animation(font_size=0, duration=0.1, t="out_quad") self.check_anim_in = Animation(font_size=sp(24), duration=0.1, t="out_quad") super().__init__(**kwargs) self.selected_color = self.theme_cls.primary_color self.unselected_color = self.theme_cls.secondary_text_color self.disabled_color = self.theme_cls.divider_color self._current_color = self.unselected_color self.check_anim_out.bind( on_complete=lambda *x: self.check_anim_in.start(self)) self.bind( checkbox_icon_normal=self.update_icon, checkbox_icon_down=self.update_icon, radio_icon_normal=self.update_icon, radio_icon_down=self.update_icon, group=self.update_icon, selected_color=self.update_color, unselected_color=self.update_color, disabled_color=self.update_color, disabled=self.update_color, state=self.update_color, ) self.theme_cls.bind(primary_color=self.update_primary_color) self.update_icon() self.update_color() def update_primary_color(self, instance, value): self.selected_color = value def update_icon(self, *args): if self.state == "down": self.icon = (self.radio_icon_down if self.group else self.checkbox_icon_down) else: self.icon = (self.radio_icon_normal if self.group else self.checkbox_icon_normal) def update_color(self, *args): if self.disabled: self._current_color = self.disabled_color elif self.state == "down": self._current_color = self.selected_color else: self._current_color = self.unselected_color def on_state(self, *args): if self.state == "down": self.check_anim_in.cancel(self) self.check_anim_out.start(self) self.update_icon() if self.group: self._release_group(self) self.active = True else: self.check_anim_in.cancel(self) self.check_anim_out.start(self) self.update_icon() self.active = False def on_active(self, *args): self.state = "down" if self.active else "normal"
class GameLayout(GridLayout): GAME_CONFIG_SECTION = "game" POSITION_MATCH_KEYBIND = ord('a') SHAPE_MATCH_KEYBIND = ord('f') CLEAR_INTERVAL = 0.2 EVALUATE_INTERVAL = 0.3 DEFAULT_BUTTON_COLOR = (0.8, 0.8, 0.8, 1) BTN_SIZE_HINT = (0.3, 0.3) RAND_RANGE = range(9) STATS_POPUP_SIZE_HINT = (.35, .35) INFO_LABEL_SIZE_HINT = (.1, .1) GRID_SIZE = 9 MIN_TIME = 0.3 iter = NumericProperty(None) p_errors = NumericProperty(None) s_errors = NumericProperty(None) def _get_config(self, opt_name): return self.parent.config.get(self.GAME_CONFIG_SECTION, opt_name) def _get_config_vals(self): self.history = int(self._get_config("level")) self.max_iter = int(self._get_config("max_iter")) + self.history self.step_duration = float(self._get_config("step_duration")) self.shape_display_duration = float(self._get_config("item_display")) self.start_noise_level = float(self._get_config("start_noise_level")) self.final_noise_level = float(self._get_config("final_noise_level")) self.shape_type = str(self._get_config("shape_type")) def _action_keys(self, window, key, *args): # bind to 'position match' and 'shape match' if key == self.POSITION_MATCH_KEYBIND and not self.p_clicked: self.p_btn.trigger_action() elif key == self.SHAPE_MATCH_KEYBIND and not self.n_clicked: self.n_btn.trigger_action() def build(self): self._get_config_vals() self.cols = 3 self.rows = 5 self.spacing = 5 # animate noise application visibility = 1 - self.final_noise_level self.noise_animation = Animation(shape_visibility=visibility, duration=self.shape_display_duration) def create_info_label(): return Label(size_hint=self.INFO_LABEL_SIZE_HINT) position_info = create_info_label() shape_info = create_info_label() overall_info = create_info_label() def update_position_info(instance, value): position_info.text = "Incorrect positions: %s" % value self.bind(p_errors=update_position_info) def update_shape_info(instance, value): shape_info.text = "Incorrect shapes: %s" % value self.bind(s_errors=update_shape_info) def update_overall_info(instance, value): overall_info.text = "%s / %s" % (value, self.max_iter) self.bind(iter=update_overall_info) self.add_widget(position_info) self.add_widget(shape_info) self.add_widget(overall_info) self.cells = [] cell_shape_cls = Shapes.get(self.shape_type) for _ in xrange(self.GRID_SIZE): label = cell_shape_cls(self.start_noise_level) self.cells.append(label) self.add_widget(label) self.p_btn = Button(text="A: Position match", size_hint=self.BTN_SIZE_HINT, on_release=self.position_callback) self.add_widget(self.p_btn) self.n_btn = Button(text="F: Shape match", size_hint=self.BTN_SIZE_HINT, on_release=self.shape_callback) self.add_widget(self.n_btn) level_info = Label(text="[color=000000]%s-back[/color]" % self.history, font_size="25sp", markup=True, size_hint=self.INFO_LABEL_SIZE_HINT) self.add_widget(level_info) # disable buttons at the start self.p_btn.disabled = True self.n_btn.disabled = True def position_callback(self, instance): self.p_clicked = True def shape_callback(self, instance): self.n_clicked = True def _rand(self, default_choice, choice_history): """Make items from the past more likely to be selected.""" return random.choice(default_choice + choice_history + choice_history) def rand_shape(self): return self._rand(self.RAND_RANGE, self.shapes) def rand_position(self): return self._rand(self.RAND_RANGE, self.positions) def new_cell(self, dt=None): self.a_shape, self.a_position = self.rand_shape(), self.rand_position() self.actual_cell = self.cells[self.a_position] self.actual_cell.set_shape(self.a_shape) self.noise_animation.start(self.actual_cell) self.p_clicked = False self.n_clicked = False def start(self): self.iter = 1 self.s_errors = 0 self.p_errors = 0 self.tested_positions = 0.0 self.tested_shapes = 0.0 self.p_clicked = False self.n_clicked = False self.positions = [] self.shapes = [] Clock.schedule_once(self.new_cell, self.MIN_TIME) Clock.schedule_interval(self._step, self.step_duration) self._schedule_cell_clearing() def _evaluate(self, dt): # using xor self.p_err = (self.positions[0] == self.a_position) != self.p_clicked self.n_err = (self.shapes[0] == self.a_shape) != self.n_clicked self.p_errors += self.p_err self.s_errors += self.n_err self.tested_positions += self.positions[0] == self.a_position self.tested_shapes += self.shapes[0] == self.a_shape # change buttons background color depending on success/fail if self.positions[0] == self.a_position or self.p_clicked: self.p_btn.background_color = RED if self.p_err else GREEN if self.shapes[0] == self.a_shape or self.n_clicked: self.n_btn.background_color = RED if self.n_err else GREEN def _display_statistics(self, position, shape, success): layout = BoxLayout(orientation="vertical") msg = self._format_statistics(position, shape, success) layout.add_widget(Label(text=msg, font_size='20sp')) def to_menu(instance): popup.dismiss() self.parent.manager.move_to_previous_screen() anchor_layout = AnchorLayout(anchor_x='right', anchor_y='center') btn = Button(text="ok", on_press=to_menu, size_hint=self.BTN_SIZE_HINT) anchor_layout.add_widget(btn) layout.add_widget(anchor_layout) popup = Popup(title='Game finished', content=layout, auto_dismiss=True, size_hint=self.STATS_POPUP_SIZE_HINT) popup.open() def _clear_cell(self, dt): self.noise_animation.cancel(self.actual_cell) self.actual_cell.clear() def _schedule_cell_clearing(self): Clock.schedule_once(self._clear_cell, self.shape_display_duration) def _on_finish(self): Clock.unschedule(self._step) Window.unbind(on_keyboard=self._action_keys) self.p_btn.disabled = True self.n_btn.disabled = True position, shape, success = self._compute_statistics() App.get_running_app().add_result(self.history, position, shape, success, self.iter) self._display_statistics(position, shape, success) def _compute_statistics(self): if not self.tested_positions: c_position = 100.0 else: c_position = (1 - self.p_errors / self.tested_positions) * 100 if not self.tested_shapes: c_shape = 100.0 else: c_shape = (1 - self.s_errors / self.tested_shapes) * 100 tested_items = self.tested_positions + self.tested_shapes if not tested_items: s_rate = 100.0 else: all_errors = self.p_errors + self.s_errors s_rate = 1 - (all_errors / tested_items) s_rate *= 100 if c_position < 0: c_position = 0 if c_shape < 0: c_shape = 0 if s_rate < 0: s_rate = 0 return c_position, c_shape, s_rate def _step(self, dt): if self.iter >= self.history and self.iter < self.max_iter: Clock.schedule_once(self._evaluate, dt - self.EVALUATE_INTERVAL) if self.iter >= self.max_iter: self._on_finish() return else: self._schedule_cell_clearing() if len(self.positions) >= self.history: del (self.positions[0]) del (self.shapes[0]) self.positions.append(self.a_position) self.shapes.append(self.a_shape) self.new_cell() # enable buttons if it make sense to click if self.iter >= self.history: self.p_btn.background_color = self.DEFAULT_BUTTON_COLOR self.n_btn.background_color = self.DEFAULT_BUTTON_COLOR self.p_btn.disabled = False self.n_btn.disabled = False Window.bind(on_keyboard=self._action_keys) self.iter += 1 def _format_statistics(self, c_position, c_shape, s_rate): return "Samples count: %s\n"\ "Correct positions: %.2f%%\n"\ "Correct shapes: %.2f%%\n"\ "Overall success: %.2f%%" % (self.iter - self.history, c_position, c_shape, s_rate)
class TransitionBase(EventDispatcher): '''TransitionBase is used to animate 2 screens within the :class:`ScreenManager`. This class acts as a base for other implementations like the :class:`SlideTransition` and :class:`SwapTransition`. :Events: `on_progress`: Transition object, progression float Fired during the animation of the transition. `on_complete`: Transition object Fired when the transition is fininshed. ''' screen_out = ObjectProperty() '''Property that contains the screen to hide. Automatically set by the :class:`ScreenManager`. :class:`screen_out` is an :class:`~kivy.properties.ObjectProperty` and defaults to None. ''' screen_in = ObjectProperty() '''Property that contains the screen to show. Automatically set by the :class:`ScreenManager`. :class:`screen_in` is an :class:`~kivy.properties.ObjectProperty` and defaults to None. ''' duration = NumericProperty(.4) '''Duration in seconds of the transition. :class:`duration` is a :class:`~kivy.properties.NumericProperty` and defaults to .4 (= 400ms). .. versionchanged:: 1.8.0 Default duration has been changed from 700ms to 400ms. ''' manager = ObjectProperty() ''':class:`ScreenManager` object, set when the screen is added to a manager. :attr:`manager` is an :class:`~kivy.properties.ObjectProperty` and defaults to None, read-only. ''' is_active = BooleanProperty(False) '''Indicate whether the transition is currently active or not. :attr:`is_active` is a :class:`~kivy.properties.BooleanProperty` and defaults to False, read-only. ''' # privates _anim = ObjectProperty(allownone=True) __events__ = ('on_progress', 'on_complete') def start(self, manager): '''(internal) Starts the transition. This is automatically called by the :class:`ScreenManager`. ''' if self.is_active: raise ScreenManagerException('start() is called twice!') self.manager = manager self._anim = Animation(d=self.duration, s=0) self._anim.bind(on_progress=self._on_progress, on_complete=self._on_complete) self.add_screen(self.screen_in) self.screen_in.transition_progress = 0. self.screen_in.transition_state = 'in' self.screen_out.transition_progress = 0. self.screen_out.transition_state = 'out' self.screen_in.dispatch('on_pre_enter') self.screen_out.dispatch('on_pre_leave') self.is_active = True self._anim.start(self) self.dispatch('on_progress', 0) def stop(self): '''(internal) Stops the transition. This is automatically called by the :class:`ScreenManager`. ''' if self._anim: self._anim.cancel(self) self.dispatch('on_complete') self._anim = None self.is_active = False def add_screen(self, screen): '''(internal) Used to add a screen to the :class:`ScreenManager`. ''' self.manager.real_add_widget(screen) def remove_screen(self, screen): '''(internal) Used to remove a screen from the :class:`ScreenManager`. ''' self.manager.real_remove_widget(screen) def on_complete(self): self.remove_screen(self.screen_out) def on_progress(self, progression): pass def _on_progress(self, *l): progress = l[-1] self.screen_in.transition_progress = progress self.screen_out.transition_progress = 1. - progress self.dispatch('on_progress', progress) def _on_complete(self, *l): self.is_active = False self.dispatch('on_complete') self.screen_in.dispatch('on_enter') self.screen_out.dispatch('on_leave') self._anim = None
class MapCursor(Rectangle): def __init__(self, map, map_size, tile_size, hue, **kwargs): super(MapCursor, self).__init__(**kwargs) self.map = map self.tile_size = tile_size self.hue = hue # pass it's own hue to itself self.size = (tile_size, tile_size) self.cursor_anim_1 = '' self.cursor_anim_2 = '' self.pos = (0, 0) self.map_size = map_size self.x_coord = 0 self.y_coord = 0 self.hide_cursor() def change_map_size(self, x_max, y_max, tile_size): self.map_size = (x_max, y_max) self.tile_size = tile_size # self.pos = (0, 0) self.move_cursor(0, 0) def increment_x(self, x): border_len = self.map.border_len x_coord = self.x_coord + x if 0 > x_coord: return if x_coord > self.map_size[0] - 1: return self.x_coord = x_coord self.pos = int(x_coord * (self.tile_size + (1 * border_len))), self.pos[1] # anim = Animation( # pos=(int(x_coord * (self.tile_size + (1*border_len))), self.pos[1]), # duration=.01) # anim.start(self) def increment_y(self, y): border_len = self.map.border_len y_coord = self.y_coord + y if 0 > y_coord: return if y_coord > self.map_size[1] - 1: return self.y_coord = y_coord self.pos = self.pos[0], int(y_coord * (self.tile_size + (1 * border_len))) # anim = Animation( # pos=(self.pos[0], int(y_coord * (self.tile_size + (1*border_len)))), # duration=.01) # anim.start(self) def move_cursor(self, touch_x, touch_y): touch_x = int(touch_x) touch_y = int(touch_y) self.x_coord, self.y_coord = touch_x, touch_y # self.current_coordinates = (touch_x, touch_y) # print('\nCurrent Cursor Position: (%d, %d)' % (self.pos[0]/32, self.pos[1]/32)) # print('Moving cursor to pos = (%d, %d).' % (touch_x, touch_y)) anim = Animation(pos=(touch_x * self.tile_size, touch_y * self.tile_size), duration=.1) anim.start(self) def move_cursor_by_pos(self, new_pos): Animation(pos=new_pos, duration=.1).start(self) def begin_cursor_animation(self): # Highlighting Widget Animation self.reveal_cursor() self.cursor_anim_1 = Animation(a=.75, duration=.5) self.cursor_anim_2 = Animation(a=0, duration=.5) self.cursor_anim_1.bind( on_complete=lambda x, y: self.cursor_anim_2.start(self.hue)) self.cursor_anim_2.bind( on_complete=lambda x, y: self.cursor_anim_1.start(self.hue)) self.cursor_anim_1.repeat = False if self.cursor_anim_1: self.cursor_anim_1.start(self.hue) def cancel_cursor_animation(self, dt=0, *args): # Cancel Animation if isinstance(self.cursor_anim_1, Animation): self.cursor_anim_1.cancel(self) self.cursor_anim_2.cancel(self) self.cursor_anim_1.unbind( on_complete=lambda: self.cursor_anim_2.start(self)) self.cursor_anim_2.unbind( on_complete=lambda: self.cursor_anim_1.start(self)) self.cursor_anim_1 = '' self.cursor_anim_2 = '' def hide_cursor(self, *args): self.hue.a = 0 def reveal_cursor(self, *args): self.hue.a = 0.75