button.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. # Copyright © 2024 Noah Vogt <noah@noahvogt.com>
  2. # This program is free software: you can redistribute it and/or modify
  3. # it under the terms of the GNU General Public License as published by
  4. # the Free Software Foundation, either version 3 of the License, or
  5. # (at your option) any later version.
  6. # This program is distributed in the hope that it will be useful,
  7. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. # GNU General Public License for more details.
  10. # You should have received a copy of the GNU General Public License
  11. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. from kivy.uix.button import Button
  13. from kivy.properties import ListProperty # pylint: disable=no-name-in-module
  14. class AutoResizeButton(Button):
  15. """A button that adjusts its label font size dynamically."""
  16. original_pos = ListProperty([0, 0])
  17. def __init__(self, **kwargs):
  18. super().__init__(**kwargs)
  19. self.dragged = False
  20. # pylint: disable=no-member
  21. self.bind( # type: ignore
  22. size=self.adjust_font_size, text=self.adjust_font_size
  23. )
  24. def adjust_font_size(self, *args):
  25. """Dynamically adjusts font size to fit the button's bounds."""
  26. if not self.text:
  27. return
  28. # Define the minimum and maximum font size
  29. min_font_size = 10
  30. max_font_size = min(self.width, self.height) * 0.5
  31. # Perform a binary search to find the best font size
  32. best_font_size = min_font_size
  33. while min_font_size <= max_font_size:
  34. current_font_size = (min_font_size + max_font_size) // 2
  35. self.font_size = current_font_size
  36. self.texture_update() # Update texture to get new texture_size
  37. # Check if the text fits within the button's bounds
  38. if (
  39. self.texture_size[0] <= self.width * 0.9
  40. and self.texture_size[1] <= self.height * 0.9
  41. ):
  42. best_font_size = current_font_size
  43. min_font_size = current_font_size + 1
  44. else:
  45. max_font_size = current_font_size - 1
  46. # Apply the best font size
  47. self.font_size = best_font_size