saeblundr
saeblundr

Reputation: 35

How to correctly scale MDIconButton?

I want to scale an MDIconButton based on my brush size. PushMatrix/PullMatrix appears to be applying to all following widgets in the canvas, instead of just the button widget as expected.

I have found that this does not occur with a stock standard kivy Button widget, but was hoping to continue using the kivymd MDIconButton for the animations and other behaviors / dressings.

Currently I use a label over the top to add additional details to my button, which makes this implementation seem the most straightforward in my mind. I imagine the problem is being caused by one of the behaviors the MDIconButton inherits from, but have not yet been able to isolate exactly which one.

from kivy.app import App
from kivy.lang import Builder

from kivymd.button import MDRaisedButton, MDIconButton

class TestApp(App):
    def build(self):
        return Builder.load_string('''
BoxLayout:
    orientation: 'vertical'

    BoxLayout:
        size_hint_y: None
        height: dp(42)
        orientation: 'horizontal'

        ##Button:
        MDIconButton:
            _scale: 1
            on_release: self._scale = (((self._scale*3) + 1) % 3) / 3
            ##text: 'brush'
            icon: 'brush'
            theme_text_color: 'Custom'
            text_color: 1,1,1,1
            canvas.before:
                PushMatrix
                Scale:
                    origin: self.center
                    x: self._scale or 1.
                    y: self._scale or 1.
            canvas.after:
                PopMatrix

    Widget:
        id: palette
        size_hint_y: None
        height: dp(42)
        canvas.before:
            Color:
                rgb: 1,0,0
            Rectangle:
                size: self.size
                pos: self.pos

    Widget:
        id: sketchpad
        canvas.before:
            Color:
                rgb: 1,1,0
            Rectangle:
                size: self.size
                pos: self.pos
''')


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

The MDIconButton icon: 'brush' should cycle between 3 sizes, leaving the rest of the widgets at their normal size (correct behavior seen when replacing MDIconButton with Button and changing icon: to text:).

Is there a better/different way to change the icon size, avoiding this problem altogether?

Upvotes: 1

Views: 2892

Answers (1)

John Anderson
John Anderson

Reputation: 38822

Your question asks how to correctly scale the MDIconButton. I cannot claim that this is correct, but here is a hack that accomplishes it. Note that the icon is just a character in a font, so its size can be adjusted by adjusting the font size. To accomplish this, I extended BoxLayout (only because it is your root) to include a set_font_size() method:

class MyBoxLayout(BoxLayout):
    def set_font_size(self, *args):
        butt = self.ids.mdIconButt
        label = butt.ids.content

        # adjust font size for the icon
        label.font_size *= 1.1

        # adjust the size of the buttons containers
        butt.height *= 1.1
        butt.width *= 1.1
        butt.parent.height *= 1.1

Then, in your kv string:

MyBoxLayout:
    orientation: 'vertical'

    BoxLayout:
        size_hint_y: None
        height: dp(42)
        orientation: 'horizontal'

        ##Button:
        MDIconButton:
            id: mdIconButt  # id to make it easy to find this widget
            on_release: root.set_font_size()  # call the new method
            icon: 'brush'
            theme_text_color: 'Custom'
            text_color: 1,1,1,1
    .
    .
    .

Note that this is fiddling with the MDIconButton internals, so expect it to break on any change to kivyMD.

You can actually accomplish most of this by simply replacing your on_release for the MDIconButton to:

on_release: self.ids.content.font_size *= 1.1

But then only the icon size changes, and the MDIconButton and its container do not.

Upvotes: 2

Related Questions