size_to_fit() with ui.Button and different fonts
@omz, the size_to_fit() function when used on ui.Buttons does not work that well with all fonts. Was its purpose to only handle the system font?
Some fonts work better than others. But I find at a minimum I have to grow the buttons rect. Some time by 10% other fonts upto 50% for the title to fit in reasonably.
I understand fonts can be very tricky, with base lines etc. But is it your intention that it will work equally well with all fonts?
If not is ok. Just not sure of your intentions
stupid question, but did you set the title and font before calling size to fit? are you also using a button image, or just a title?
I am pretty sure omz's intention was to provide a python wrapper to UIButton's sizeToFit method.
do you have an example of a spcific font/text that doesn't work? Does it actually clip text, or does it just not leave enough of a margin?
@JonB , I think I have done it correct
If you up comment the btn.width =*.3 for example, you can start to tweak it. If you get the right number, then it scales pretty well given you stuck with the font you have tweaked it for. Otherwise it is all over the place unless I missed something important
import ui def letter_logo(text = 'IJ', font =('Arial Rounded MT Bold', 50), bg_color = 'teal'): # hmmm, not great. but still ok. size_to_fit not working as i would # expect it to. however, it could be me. # this sort of icon/button/etc... used often in iOS # the function that action responds to... def action(sender): # not using it here... but could be a counter etc... pass btn = ui.Button(name = 'll') btn.font = font btn.title = text btn.alignment = ui.ALIGN_CENTER btn.border_width = .5 btn.size_to_fit() btn.height = btn.width #btn.width *= 1.3 # at the moment need to tweak these values #btn.height *= 1.3 # at the moment need to tweak these values btn.corner_radius = btn.width / 2 # make it circular btn.bg_color = bg_color btn.tint_color = 'white' # not working at the moment btn.border_color = 'yellow' btn.action = action return btn class MyClass(ui.View): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) btn = letter_logo() btn.x = 10 btn.y = 20 self.add_subview(btn) btn = letter_logo(font = ('Avenir Next Condensed', 50)) btn.x = 200 btn.y = 20 self.add_subview(btn) btn = letter_logo(font = ('Zapfino', 50)) btn.x = 10 btn.y = 150 self.add_subview(btn) if __name__ == '__main__': w = 300 h = 400 f = (0, 0, w, h) mc = MyClass(frame = f, bg_color = 'white', animated = False) mc.present('sheet')
@Phuket2 size to fit, it seems to me, sizes the rectangle to fit. if you set the corner radious to zero, it works fine for me with that font and size.
The easiest solution would be to add 2*corner_radius, but this won't have the nice tight fit you want. Given fonts do not use the full height, you could use some trig to figure out the amount of width needed such that the tallest character in a font does not clip given your corner radius. Though really, if you want something to adjust to the specific character at the end i.e a O will require less extra than an H, that requires much fancier work...
@JonB , for me it does not fit. I mean the 3 fonts in my example. The corner_radius = 0, did not grow or shrink the buttons bounds.
I still get
I understand it's not easy with fonts. But either it works or does not. In my mind this could be a bug or a neglected method. Or it was only ever meant to work with system fonts that are a lot more predictable
For the first two, the problem is you size it to fit.... then change the size!
At least do something like
btn.height = btn.width = w
or maybe for a tighter fit,
btn.height = btn.width = w
There is something funny with zapfino, where it is cut off even with corner radius set to 0 and increasing the width. That can be solved by appending a space, but then the centering is messed up.
i think there is a fontmetics somewhere, either in objc or PIL.ImageFont that might be useful for precision work.
@JonB , hmmm. Yeah it was getting a little tricky. Chicken before the egg thing. But I will look again. It's probably time I shut up and actually try to write something that works and does something 😱
But thanks again for your long lasting patience 👍