KivyMD icon indicating copy to clipboard operation
KivyMD copied to clipboard

MDFloatingActionButtonSpeedDial does not work with MDNavigationRail

Open blurryrox opened this issue 2 years ago • 4 comments

So i am trying to add a MDFloatingActionButtonSpeedDial into a screen navigated through the MDNavigationRail items but it doesn't even show up.

When i try removing the MDNavigationRail part, the FAB shows up which i find weird, this may be a bug, or i am doing something wrong i am not sure. Here's my coede:

main.py:

from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager, Screen

class CfgScreen(Screen):    
    data = {
        "Add user": "account-plus-outline"
        }

    def __init__(self, **kwargs):
        super(CfgScreen, self).__init__(**kwargs)

class MainApp(MDApp):   

    def build(self):
        self.theme_cls.primary_palette = "Teal"
        sm = ScreenManager()
        sm.add_widget(CfgScreen(name="cfg"))

        return sm

if __name__=="__main__":
    MainApp().run()

main.kv

CfgScreen:

<CfgScreen>:
    name: "cfg"
    BoxLayout:
        orientation: "horizontal"
        MDNavigationRail:
            md_bg_color: app.theme_cls.primary_color
            MDNavigationRailItem:
                id: navigation_rail
                icon: "account-details-outline"
        ScreenManager:
            id: sm_cfg
            Screen:
                name: "cfg_user_account"
                MDFloatingActionButtonSpeedDial:
                    data: root.data
                    root_button_anim: True

Screenshots

With MDNavigationRail: wnav

Without the MDNavigationRail part: wonav

Versions

  • OS: Windows 10
  • Python: 3.10.6
  • Kivy: 2.1.0
  • KivyMD: 1.0.2

blurryrox avatar Aug 24 '22 15:08 blurryrox

@blurryrox Please change your code so that there is nothing in it that does not relate to reproducing the error.

HeaTTheatR avatar Aug 24 '22 16:08 HeaTTheatR

@blurryrox Please change your code so that there is nothing in it that does not relate to reproducing the error.

edited

blurryrox avatar Aug 24 '22 16:08 blurryrox

@HeaTTheatR After a few experimenting, i suspect that MDNavigationRail push the next box out of the screen, as it slides to the next screen, i can see it shows up for a little bit of sliding between the current and next screen.

And after adjusting the buttons position more to the left in kivymd/uix/buttons/buttons.py, it shows up perfectly.

blurryrox avatar Aug 25 '22 03:08 blurryrox

@blurryrox OK, I'll check it out.

HeaTTheatR avatar Aug 25 '22 03:08 HeaTTheatR

It's solved? Because I'm already with this same problem, a simple way to cause the bug:

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

kv = """
MDBoxLayout:
    MDNavigationRail:
        id: nav_rail
        MDNavigationRailItem:
            text: "Home"
            icon: "home-outline"
    MDScreenManager:
        Screen:
            MDFloatingActionButtonSpeedDial:
                icon: 'menu'
                data: {'Remove': 'minus-circle', 'Add': 'plus-circle'}
                hint_animation: True
                on_release_stack_button: print(*args)
"""


class MyApp(MDApp):

    def build(self):
        return Builder.load_string(kv)


if __name__ == '__main__':
    MyApp().run()

I'm with Kivy 2.2.0.dev0 and kivymd 1.2.0.dev0

The button show, but on enter the button don't show the labels, you can implement another screen inside the screenmanager and change the screen, you will see that the button location change.

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

kv = """
MDBoxLayout:
    MDNavigationRail:
        id: nav_rail
        MDNavigationRailItem:
            text: "Home"
            icon: "home-outline"
    MDScreenManager:
        id: manager
        MDScreen:
            Button:
                text: 'Goto settings'
                on_press:
                    manager.transition.direction = 'left'
                    manager.current = 'settings'
            MDFloatingActionButtonSpeedDial:
                icon: 'menu'
                data: {'Remove': 'minus-circle', 'Add': 'plus-circle'}
                hint_animation: True
                on_release_stack_button: print(*args)
        MDScreen:
            name: 'settings'
            MDFloatingActionButtonSpeedDial:
                icon: 'menu'
                data: {'Remove': 'minus-circle', 'Add': 'plus-circle'}
                hint_animation: True
                on_release_stack_button: print(*args)
"""


class MyApp(MDApp):

    def build(self):
        return Builder.load_string(kv)


if __name__ == '__main__':
    MyApp().run()

If you pay attention, you will see the labels out of the screen limits.

RicardoDazzling avatar Jul 17 '23 20:07 RicardoDazzling

Hello! I can't call a pull request, but I solved the issue. I changed to it:

1 - Add a object property named _width with default value 0; 2 - Update all Window.width and self.parent.width for self._width; 3 - Add a Method named _update_width:

+    def _update_width(self, *args):
+        self._width = self.parent.width

4 - Add a boolean property with False such default; 5 - Inside set_pos_bottom_buttons:

+        if not self._binded:
+            if self.parent is not None:
+                self._update_width()
+                self.parent.bind(width=self._update_width)
+                self.bind(_width=self._update_pos_buttons)
+                self._binded = True
+            else:
+                self._width = Window.width

Now the width was updated with the parent, and not the window.

RicardoDazzling avatar Jul 18 '23 13:07 RicardoDazzling