Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MDRaisedButton - Elevation #1327

Closed
arncode90 opened this issue Aug 30, 2022 · 25 comments · Fixed by #1336
Closed

MDRaisedButton - Elevation #1327

arncode90 opened this issue Aug 30, 2022 · 25 comments · Fixed by #1336
Labels
Priority: 1/Critical Should be fixed as soon as possible, before next release Type: Bug Bug report/Bug fix

Comments

@arncode90
Copy link

Description of the Bug

MDRaisedButton still showing an elevation (when the button is clicked), even I set the elevation to 0.

Code and Logs

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

KV = '''
<RaisedBtn@MDRaisedButton>
    elevation: 0
    shadow_offset: (0,0)
    shadow_radius: 0
    shadow_softness: 0
    ripple_scale: .1
    
MDScreen:
    MDBoxLayout:
        md_bg_color: 1, 1, 0, 1
        size_hint: 0.9, 0.7
        orientation: "vertical"
        pos_hint: {'center_x':.5, 'y':0.1}

        ScreenManager:
            MiniScreen:
                name: "one"

            MiniScreen2:
                name: "two"

<MiniScreen@MDScreen>:
    MDBoxLayout:
        orientation: "vertical"
        MDWidget:
        MDBoxLayout:
            orientation: "vertical"
            spacing: dp(10)
            adaptive_height: True

            RaisedBtn:
                size_hint_x: 1
                text: "Login"
                on_press: 
                    root.parent.current = 'two'
        MDWidget:   
        
<MiniScreen2@MDScreen>:
    MDBoxLayout:
        orientation: "vertical"
        MDWidget:
        MDBoxLayout:
            orientation: "vertical"
            spacing: dp(10)
            adaptive_height: True

            RaisedBtn:
                size_hint_x: 1
                text: "Register"
                # on_press: print(f"{self.text}")
                on_press: root.parent.current = 'one'
        MDWidget:   
'''


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


Test().run()

Video

2022-08-29.23-41-05.mov

Versions

  • OS: Windows
  • Python: v3.7.6
  • Kivy: v2.1.0
  • KivyMD: 1.1.0.dev0, git-Unknown, 2022-08-28
@HeaTTheatR HeaTTheatR added the Type: Bug Bug report/Bug fix label Aug 30, 2022
@mp-007
Copy link
Contributor

mp-007 commented Aug 31, 2022

@arncode90 When you run your code. What it's your opengl version?
image

@HeaTTheatR
Copy link
Member

@mp-007
Снимок экрана 2022-08-31 в 17 18 14

@arncode90
Copy link
Author

Sry, late reply.
This is the GL info:

[INFO ] [GL ] Using the "OpenGL" graphics system
[INFO ] [GL ] GLEW initialization succeeded
[INFO ] [GL ] Backend used
[INFO ] [GL ] OpenGL version <b'4.0.0 - Build 10.18.10.5161'>
[INFO ] [GL ] OpenGL vendor <b'Intel'>
[INFO ] [GL ] OpenGL renderer <b'Intel(R) HD Graphics'>
[INFO ] [GL ] OpenGL parsed version: 4, 0
[INFO ] [GL ] Shading version <b'4.00 - Build 10.18.10.5161'>
[INFO ] [GL ] Texture max size <16384>
[INFO ] [GL ] Texture max units <16>

@mp-007
Copy link
Contributor

mp-007 commented Aug 31, 2022

(Hypothesis) I think elevation shader is not compatible with opengl>3.0 because it used gl_FragColor which it's deprecated. So maybe, the elevation is not correctly updated in your example because of that.

@arncode90
Copy link
Author

arncode90 commented Aug 31, 2022

ok ty for yor time checking this issue..
thats mean you all can use elevation shader without problem using the latest KivyMD version

i will go for 1.0.2 then xD

yes, my shadow seems like flat grey-ish
seems like u said, OpenGL version not compatible maybe

i dont know much about system etc,
but how about the app shutdown?
no error logcat shown..

i tested 2 same code, just only with 2 different button.
One with MDRaised and other one is MDFillRoundFlatButton

The one with MDRaisedButton crashed
Compiling im using Colab

@arncode90
Copy link
Author

Here my logcat from phone (i deleted some unnecessary line):

[INFO ] [Kivy ] v2.1.0
[INFO ] [Python ] v3.9.9 (main, Aug 29 2022, 14:34:32)
[INFO ] [Logger ] Purge log fired. Processing...
[INFO ] [Logger ] Purge finished!
[INFO ] [Factory ] 189 symbols loaded
[INFO ] [KivyMD ] 1.1.0.dev0, git-Unknown, 2022-08-29
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_pil (img_ffpyplayer ignored)
[INFO ] [Text ] Provider: sdl2
[INFO ] [Window ] Provider: sdl2
[INFO ] [GL ] Using the "OpenGL ES 2" graphics system
[INFO ] [GL ] Backend used
[INFO ] [GL ] OpenGL version <b'OpenGL ES 3.2 V@0502.0 (GIT@03e27f8, I326e6aff90, 1604374052)
[INFO ] [GL ] OpenGL vendor <b'Qualcomm'>
[INFO ] [GL ] OpenGL renderer <b'Adreno (TM) 610'>
[INFO ] [GL ] OpenGL parsed version: 3, 2
[INFO ] [GL ] Texture max size <16384>
[INFO ] [GL ] Texture max units <16>
[INFO ] [Window ] auto add sdl2 input provider
[INFO ] [Window ] virtual keyboard not allowed, single mode, not docked
[WARNING] [Base ] Unknown provider
[INFO ] [Base ] Start application main loop
[INFO ] [GL ] NPOT texture support is available

App crashed and the logcat ended here.
So it seems like you said, not compatible with OpenGL>3 i guess

@arncode90
Copy link
Author

arncode90 commented Aug 31, 2022

Sry, but can i ask something?

The code @ kivymd/uix/button/button.py (Line 1017)

Clock.schedule_once(self.create_anim_raised)

Clock.schedule_once(self.create_anim_raised)

it refer to the method below:

    def create_anim_raised(self, *args) -> None:
        self._elevation_raised = self.elevation + 1.2
        self._anim_raised = Animation(elevation=self.elevation + 1, d=0.15)

It has something to do / related to the system?

Because if I edit the "create_anim_raised" method in Line 1020 (like code below), the elevation bug not showing when running on my Windows (not yet check when running on the phone).

    def create_anim_raised(self, *args) -> None:
        if self.elevation != 0:
            self._elevation_raised = self.elevation + 1.2
            self._anim_raised = Animation(elevation=self.elevation + 1, d=0.15)

@mp-007
Copy link
Contributor

mp-007 commented Aug 31, 2022

I think this function is Ok when shadow is correctly rendering. I'm not an expert in Shader, but I hope someone will find a way to make shader compatible for all opengl version.

@arncode90
Copy link
Author

Ok mp-007
ty for your time

@HeaTTheatR HeaTTheatR added the Priority: 1/Critical Should be fixed as soon as possible, before next release label Aug 31, 2022
@mp-007
Copy link
Contributor

mp-007 commented Sep 1, 2022

Finally find the problem. It's the smoothstep function that doesn't work properly in opengl>3.0

If I change the elevation.frag by that, it's seem to work:

float happy_smoothstep(float a, float b, float x) {
    float t = clamp((x - a) / (b - a), 0.0, 1.0);
 
    return t * t * (3.0 - (2.0 * t));
}

float roundedBoxSDF(vec2 centerPosition, vec2 size, vec4 radius) {
    radius.xy = (centerPosition.x > 0.0) ? radius.xy : radius.zw;
    radius.x = (centerPosition.y > 0.0) ? radius.x : radius.y;

    vec2 q = abs(centerPosition) - (size - shadow_softness) + radius.x;
    return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - radius.x;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    // Smooth the result (free antialiasing).
    float smoothedAlpha = 1.0 - happy_smoothstep(0.0, 0.0, 1.0);
    // Get the resultant shape.
    vec4 quadColor = mix(
        vec4(
            shadow_color[0],
            shadow_color[1],
            shadow_color[2],
            0.0
        ),
        shadow_color,
        smoothedAlpha
    );
    // Apply a drop shadow effect.
    float shadowDistance = roundedBoxSDF(
        fragCoord.xy - mouse.xy - (size / 2.0), size / 2.0, shadow_radius
    );
    float shadowAlpha = 1.0 - smoothstep(
        -shadow_softness, shadow_softness, shadowDistance
    );
    fragColor = mix(quadColor, shadow_color, shadowAlpha - smoothedAlpha);

@HeaTTheatR can you check if this fix work on your side. Note: you can happy_smoothstep for an other name ;)

@HeaTTheatR
Copy link
Member

@mp-007

[INFO   ]    [Shader      ] fragment shader: <b"ERROR: 0:62: '{' : syntax error: syntax error">
[ERROR  ] [Shader      ] <fragment> failed to compile (gl:0)

@HeaTTheatR
Copy link
Member

@mp-007 Don't pay attention, this is my typo. I'll check it on my computer. Will you be able to do PR later if it works on my computer as well?

@mp-007
Copy link
Contributor

mp-007 commented Sep 1, 2022

@HeaTTheatR Yes I can make a PR if it works on your computer.

@HeaTTheatR
Copy link
Member

@mp-007 Please remind me exactly what problem is being solved by your new shader changes?

@mp-007
Copy link
Contributor

mp-007 commented Sep 1, 2022

I don't know why but smoothstep return value is not correct on by computer (opengl 4.6). When I rewrite the function from the documentation (https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml), it's working now.

actual elevation.frag
image

new elevation.frag
image

@mp-007
Copy link
Contributor

mp-007 commented Sep 1, 2022

I have done more test and the problem is only the first smoothstep. If I used this, it's working:

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    // Smooth the result (free antialiasing).
    float a = 0.0;
    float b = 1.0;
    float smoothedAlpha = 1.0 - smoothstep(a, a, b);
    // Get the resultant shape.
    ...

Starting from opengl 4.0, there's a genDtype. I think you have to specified the type (float) to get the same result when you have opengl>4.0.
image

@HeaTTheatR
Copy link
Member

HeaTTheatR commented Sep 1, 2022

@mp-007 OK, let's make a PR, but please leave the old code commented out. And call the happy_smoothstep method adjust_smoothstep :)

@mp-007
Copy link
Contributor

mp-007 commented Sep 1, 2022

@HeaTTheatR Like I said in my last comment, I don't need to create a new function. Just by specified the input type, it's working. At the end, my only changes are:

    // Smooth the result (free antialiasing).
    float edge0 = 0.0;
    float smoothedAlpha = 1.0 - smoothstep(0.0, edge0, 1.0);
    // Get the resultant shape.
   ...

I will make a PR with this changes.

@HeaTTheatR
Copy link
Member

@mp-007 OK.

@HeaTTheatR
Copy link
Member

@mp-007 OK, thanks for this PR!

@mp-007
Copy link
Contributor

mp-007 commented Sep 1, 2022

by commented this part in elevation.py, seem to fix this issue.

    def check_for_relative_pos(self, *args) -> None:
        """
        Checks if the widget has relative position properties and if necessary
        binds Window.on_draw call to update window position
        """

        # if self.pos == self.window_pos:
        #     return
        # else:
        self._has_relative_position = True

        Window.bind(on_draw=self.update_window_position)

Can we considered all widgets to have relative position?

@HeaTTheatR
Copy link
Member

@mp-007 We need to do this thoroughly. Both static widgets with elevation behavior and widgets with elevation behavior that are inside Scrollview...

mp-007 added a commit to mp-007/KivyMD that referenced this issue Sep 2, 2022
possible fix for issue kivymd#1327
@T-Dynamos
Copy link
Collaborator

Here my logcat from phone (i deleted some unnecessary line):

[INFO ] [Kivy ] v2.1.0 [INFO ] [Python ] v3.9.9 (main, Aug 29 2022, 14:34:32) [INFO ] [Logger ] Purge log fired. Processing... [INFO ] [Logger ] Purge finished! [INFO ] [Factory ] 189 symbols loaded [INFO ] [KivyMD ] 1.1.0.dev0, git-Unknown, 2022-08-29 [INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_pil (img_ffpyplayer ignored) [INFO ] [Text ] Provider: sdl2 [INFO ] [Window ] Provider: sdl2 [INFO ] [GL ] Using the "OpenGL ES 2" graphics system [INFO ] [GL ] Backend used [INFO ] [GL ] OpenGL version <b'OpenGL ES 3.2 V@0502.0 (GIT@03e27f8, I326e6aff90, 1604374052) [INFO ] [GL ] OpenGL vendor <b'Qualcomm'> [INFO ] [GL ] OpenGL renderer <b'Adreno (TM) 610'> [INFO ] [GL ] OpenGL parsed version: 3, 2 [INFO ] [GL ] Texture max size <16384> [INFO ] [GL ] Texture max units <16> [INFO ] [Window ] auto add sdl2 input provider [INFO ] [Window ] virtual keyboard not allowed, single mode, not docked [WARNING] [Base ] Unknown provider [INFO ] [Base ] Start application main loop [INFO ] [GL ] NPOT texture support is available

App crashed and the logcat ended here. So it seems like you said, not compatible with OpenGL>3 i guess

I was talking about this
kivy/kivy#7993 (comment)
Pydroid result
img

@Fretless14
Copy link

Hey guys I think I am having a similar issue here, but only happens when scrolling.
I'm on version 1.1.1, Kivy version 2.1.0, and running on Python 3.10

Here's a video of it:
https://github.com/kivymd/KivyMD/assets/67965278/24f2bad5-c6c4-45cd-a08e-9af7ca81cc9e

Here is my code (it is a little hacked together since it's my first time working with kivy/kivyMD, sorry for the formatting here I can't change it):

`
from kivymd.app import MDApp
from kivy.uix.recycleview import RecycleView
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import ObjectProperty, ListProperty
from kivy.clock import Clock
from kivy.input.motionevent import MotionEvent
from kivymd.uix.button import MDRectangleFlatButton
from kivymd.uix.menu import MDDropdownMenu
from kivymd.uix.button import MDRaisedButton

Builder.load_string('''
:
canvas.before:
Color:
rgba: 1,1,1, 1
Rectangle:
size: self.size
pos: self.pos

numText: ''
titleText: ''
subgroupText: ''
widthText: ''

TextInput:
	id: num
	text:root.numText
	size_hint_x: 0.05
	padding: [10, (self.height - self.line_height) / 2]
	background_normal: 'rounded_normal.png'
	background_active: 'rounded_active.png'
	readonly: 'true'
	halign: 'center'
	
TextInput:
	id: title
	text:root.titleText
	size_hint_x: 0.3
	padding: [10, (self.height - self.line_height) / 2]
	background_normal: 'rounded_normal.png'
	background_active: 'rounded_active.png'
	# readonly: 'false'

MDRaisedButton:
    id: group_dropdown_button
    text: "Group 1"
    pos_hint: {"center_x": .5, "center_y": .5}
    elevation: 0
    on_release: root.dropdown.open()  
	
TextInput:
	id: subgroup
	text:root.subgroupText
	size_hint_x: 0.1
	padding: [10, (self.height - self.line_height) / 2]
	background_normal: 'rounded_normal.png'
	background_active: 'rounded_active.png'
	halign: 'center'
	readonly: 'true'
			
TextInput:
	id: width
	text:root.widthText
	size_hint_x: 0.1
	padding: [10, (self.height - self.line_height) / 2]
	background_normal: 'rounded_normal.png'
	background_active: 'rounded_active.png'
	halign: 'center'
	readonly: 'true'

:
id: newTable
viewclass: 'Cols'
scroll_type: ['bars', 'content']
scroll_wheel_distance: dp(114)
bar_width: dp(0)
canvas.before:
Color:
rgba: 0.98, 0.98, 0.98, 1
Rectangle:
pos: self.pos
size: self.size
RecycleGridLayout:
cols:1
default_size: None, dp(40)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'lr-tb'
spacing: dp(2)
# col_force_default: False
# col_default_width: 200
# cols_minimum: {0: 100, 1: 300, 2: 150}

''')

class NewTable(RecycleView):
list_items = ListProperty([])

def __init__(self, **kwargs):
	super(NewTable, self).__init__(**kwargs)
	self.scroll_timeout = 0.01  # set the scroll timeout to 0.1 seconds
	self.always_overscroll = False

	self.data = [{'numText': str(n+1), 'titleText': "-", 'groupText': "-", 'subgroupText': "-",
				  'widthText': "-", 'paren': self, 'index': n} for n in range(100)]


def on_touch_move(self, touch):
	if isinstance(touch, MotionEvent) and 'button' in touch.profile:
		return True  # Prevent mouse drag scrolling
	return super(NewTable, self).on_touch_move(touch)


def which_edit(self, *args):
	'''This will print the index of the box which is currently edited'''
	...

class Cols(BoxLayout):
paren = ObjectProperty() #the instance of the NewTable
index = None

def __init__(self, **kwargs):
	super(Cols, self).__init__(**kwargs)
	Clock.schedule_once(self.update)
	self.group_items = [
					{
						"text": f"Vocal",
						"viewclass": "OneLineListItem",
						"on_release": lambda x=f"Group 1": self.dropdown_callback(x),
					},
					{
						"text": f"Guitar",
						"viewclass": "OneLineListItem",
						"on_release": lambda x=f"Group 2": self.dropdown_callback(x),
					},
					{
						"text": f"Drums",
						"viewclass": "OneLineListItem",
						"on_release": lambda x=f"Group 3": self.dropdown_callback(x),
					}
	]

	self.dropdown = MDDropdownMenu(
		caller=self.ids.group_dropdown_button,
		items=self.group_items,
		width_mult=2,
		position="center",		# DOESNT WORK IF BOTTOM
		radius=[10, 10, 10, 10],
		elevation=0
	)

def update(self, *args):
	self.paren.list_items.append(self)
	self.ids.title.bind(text=self.paren.which_edit)

# def on_touch_down(self, touch):
#
# 	if super(Cols, self).on_touch_down(touch):
# 		return True
# 	if self.collide_point(*touch.pos):
# 		global rowIndex
# 		rowIndex = self.index
# 		self.ids.CellText.focus = True
# 		return True

def dropdown_callback(self, text_item):
	self.ids.group_dropdown_button.text = text_item
	self.dropdown.dismiss()
	print(text_item)

def refresh_view_attrs(self, newTable, index, data):
''' Catch and handle the view changes '''
self.index = index
return super(Cols, self).refresh_view_attrs(
newTable, index, data)

def on_touch_down(self, touch):
if super(Cols, self).on_touch_down(touch):
return True
if self.collide_point(*touch.pos):
global rowIndex
rowIndex = self.index

class TestApp(MDApp):
def build(self):
return NewTable()

if name == 'main':
TestApp().run()
`

@Fretless14
Copy link

Found out a small work around is switching out MDRaisedButton for MDFillRoundFlatButton, so not a big deal for me :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority: 1/Critical Should be fixed as soon as possible, before next release Type: Bug Bug report/Bug fix
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants