kivymd / KivyMD

KivyMD is a collection of Material Design compliant widgets for use with Kivy, a framework for cross-platform, touch-enabled graphical applications. https://youtube.com/c/KivyMD https://twitter.com/KivyMD https://habr.com/ru/users/kivymd https://stackoverflow.com/tags/kivymd
https://kivymd.readthedocs.io
MIT License
2.23k stars 672 forks source link

Dispatch ripple_effect before on_release is dispatched #1105

Closed kengoon closed 3 years ago

kengoon commented 3 years ago

Description of the Feature

I noticed that the ripple effect does not behave as a normal android native ripple effect does. When a button or card is clicked the ripple_effect dispatches the same time as the on_release event which makes it useless in that state.

If a clock or something can be used to hold back the on_release event, making it wait for the ripple_effect to finish it job before dispatching, just like a normal native android ripple_effect does. That would be great

HeaTTheatR commented 3 years ago

@kengoon Sorry, I do not understand the essence of the problem ...

kengoon commented 3 years ago

@HeaTTheatR

below are two separate applications, the first video contains a kivy application, while the second contains an android native application

https://user-images.githubusercontent.com/42192162/137749251-d6b90b45-804e-4242-ac12-8961be294a96.mp4

In the above video, The ripple effect occurs the same time as the on_release event

https://user-images.githubusercontent.com/42192162/137749656-0259e222-39d2-4723-899a-feaa36ec1b88.mp4

In the above video, The onClick event occurs only after the ripple_effect has finished its job

kengoon commented 3 years ago

@HeaTTheatR below is a video of what is expected, which I have to implement with a Clock.schedule_once which is not actually straightforward and not ideal (speaking for myself in this context)

https://user-images.githubusercontent.com/42192162/137763737-233bf825-8cb2-4b90-a8f2-92c246ef7bab.mp4

HeaTTheatR commented 3 years ago

@kengoon Unfortunately your videos don't show anything. Please attach the minimum code instead of the video.

HeaTTheatR commented 3 years ago

@kengoon Here's a video demonstrating that the on_release event is not called at the start of the ripple animation.

https://user-images.githubusercontent.com/16930280/137784038-ade935ec-9a6a-4a50-b78e-bc25572be4f4.mov

kengoon commented 3 years ago

@HeaTTheatR from your video I think you clicked and held the mouse button for some time, which is not the situation I was talking about.

Let us assume we want our user to click a button and it will change to a new screen. The code will look like this

from kivy.lang import Builder
from kivymd.app import MDApp

kv = '''
ScreenManager:
    Screen:
        name: "s1"
        MDRaisedButton:
            text: "Screen 1"
            pos_hint: {"center_x": .5, "center_y": .5}
            on_release: 
                print("S1 On Release Event")
                root.current = "s2"
    Screen:
        name: "s2"
        MDRaisedButton:
            text: "Screen 2"
            pos_hint: {"center_x": .5, "center_y": .5}
            on_release: 
                print("S2 On Release Event")
                root.current = "s1"
'''

class TestApp(MDApp):
    def build(self):
        return Builder.load_string(kv)

TestApp().run()

Now, when you run this code, you will notice that the ripple effect does not finish its job before opening a new screen, I also noticed from the code log that the print statement works only when the ripple effect finishes its job. That means that the screen change takes effect before the print statement. [does that mean thatprintruns on a separate thread? because it is only Thread that can do such an act]. I also clicked and held the button to simulate what you did on your end

below is gif of the outcome: ripple1

This code below show that I click the mouse once without clicking and holding the mouse key and it has to wait for 1 second for the ripple effect to complete its job

from kivy.lang import Builder
from kivymd.app import MDApp

kv = '''
#:import Clock kivy.clock.Clock
ScreenManager:
    Screen:
        name: "s1"
        MDRaisedButton:
            text: "Screen 1"
            pos_hint: {"center_x": .5, "center_y": .5}
            on_release: Clock.schedule_once(lambda x: exec('root.current = "s2"'), 1)
    Screen:
        name: "s2"
        MDRaisedButton:
            text: "Screen 2"
            pos_hint: {"center_x": .5, "center_y": .5}
            on_release: Clock.schedule_once(lambda x: exec('root.current = "s1"'), 1)
'''

class TestApp(MDApp):
    def build(self):
        return Builder.load_string(kv)

TestApp().run()

below is a gif of the outcome ripple2

HeaTTheatR commented 3 years ago

@kengoon This code below show that I click the mouse once without clicking and holding the mouse key and it has to wait for 1 second for the ripple effect to complete its job

on_release: Clock.schedule_once(lambda x: exec('root.current = "s2"'), 1)
HeaTTheatR commented 3 years ago

@kengoon The ripple effect does not stop the execution of any application events. This can be clearly seen in the video:

https://user-images.githubusercontent.com/16930280/137797320-e216e7ea-2358-49d9-ad47-c25f33e8bdee.mov

kengoon commented 3 years ago

@HeaTTheatR I don't understand where you are heading..., but to elaborate more, going back to the video of the android native app I posted above (https://user-images.githubusercontent.com/42192162/137749656-0259e222-39d2-4723-899a-feaa36ec1b88.mp4) I just simulated the same thing they did to explain to you that the ripple effect would not be useful if its use is not shown

Also going back to my previous comment:

@HeaTTheatR below is a video of what is expected, which I have to implement with a Clock.schedule_once which is not actually straightforward and not ideal (speaking for myself in this context)

20211018_163205.mp4

I was trying to please the eyes of my user by the color of the ripple effect when they click it, but that will not have shown without the Clock because the screen changes immediately

@kengoon The ripple effect does not stop the execution of any application events. This can be clearly seen in the video:

2021-10-18.22.48.39.mov

yes it is True but an event that will occur might prevent the appearance of ripple effect (example: changing of screen) like I showed in my comment above

HeaTTheatR commented 3 years ago

@kengoon You can use the on__finishing_ripple event:


from kivy.lang import Builder

from kivymd.app import MDApp

KV = '''
MDScreen:

    MDRaisedButton:
        text: "MDRaisedButton"
        pos_hint: {"center_x": .5, "center_y": .5}
        on_release: print("On release event")
        on__finishing_ripple: if not args[1]: print("On finishing ripple effect")
'''

class Test(MDApp):
    def build(self):
        return Builder.load_string(KV)

Test().run()```
kengoon commented 3 years ago

@HeaTTheatR Yea that will solve my case thanks a lot for your time, you can close the issue