Overriding tint_color on an inherited ui.View?
I was in the process of making a custom button
ui.Viewwith event hooks for button press as well as button release. I wanted to make a button that would trigger repeated actions when held down. That's all well and good and the eventing works fine, but I also tried to emulate, to the best of my ability, all the features that
ui.Buttonhas, like allowing text and or an icon that makes use of
tint_coloretc. This required overriding the
drawmethod and inserting the
set_needs_display()calls in the appropriate places.
Apparently, however, setting
ui.Viewdoes not trigger the
set_needs_display()to redraw the view. I assumed that
tint_colorwas just a property on
ui.Viewthat, under the covers, did all the fancy things to make the view update itself by default, and that I would be able to override it in a reasonable manner to call
super().tint_color.fset()or something like that followed by a
set_needs_display()to redraw my view. After looking into it a little further,
ui.View.tint_coloris just a plain old attribute. So in order for me to properly handle the redrawing of the
ViewI had to make new property getters and setters named
I really dislike this solution because now the API for my custom button is nonstandard and it makes me feel... dirty... lol
Am I misunderstanding how tint_color works/should work?
One approach would be to simply use a ui.Button, under the hood, and just use the UI.View for touch.
There was also some discussion a while back on using some sort of mocking framework, which I forget the name of, to "extend" built in types, which involved some sort of metaclass magic. maybe @dgelessus or @mikael will remember...
Marvelous suggestions. Thank you!
I would love to know how they do this black magic
tint_colorbuffoonery underneath. I'm always more and more impressed with what is possible within the bounds of this app. It's incredible.
Under the hood, it is all done in c... objc UIViews have a method you can define called tintColorDidChange that you would use to redraw whatever needs redrawing.
if you were implementing your own version using draw, in python, you would indeed use @properties, and getters and setters.
Another similar example of "composting": here is a vertical slider which is a ui.View containing a slider. Most of the key attributes are just sent to and read from the embedded slider. There may a more general approach using getattribute etc to route attributes, or force redraw, etc
The extend option would allow you to use the code you already have for your View, and would be used like this:
#coding: utf-8 from ui import * from composite import Composite import console class YourTouchView(View): ''' Class that handles touch events instead of the underlying button. ''' touch_sink = True def touch_ended(self, touch): console.hud_alert('Custom touch') if __name__ == '__main__': v = View() v.background_color = 'white' v.present('sheet') btn = Button(title='Click me', background_color='white', tint_color='black') my_button = Composite(btn, YourTouchView) v.add_subview(my_button) my_button.center = v.center my_button.tint_color = 'red'
You can also create a reusable ”Chainable” class with the same effect, see the documentation for details. Please note that the whole composite thing is very much beta.
@JonB, ”composting”, lol.
There was also some discussion a while back on using some sort of mocking framework, which I forget the name of, to "extend" built in types
Ah, ProxyTypes is what I was thinking of.