Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Theming class for ui. only a start and idea.
-
Just to be clear up front, I am new to python and pythonista. The code below could be utter garbage. Just state, in case you are new also.
I wrote this code on my learning journey. Also putting together what I have been learning here in the forum. I am sure for most here, it's very simple code you could code in your sleep. For me was not that easy or straight fwd. I wrote a few iterations, getting the abstraction better on each iteration.
It's just the beginning of a class that is attempting to be a very generic Theming Class (for the want of a better word). My idea (practice) was to minimise the code and abstract it as much as I could. I think it's not too bad. If you strip out the data and comments, very little code. But, yes, very incomplete.
I am pretty sure there is a better way to get all the attributes of a class generically rather than calling dir(obj). But ok, it works. That's what I could do now.
The other thing I realise is that _theme_obj could be optimised by iterating over the theme_dict items rather than the attributes returned by dir(obj). Not so worried about speed at the moment. Just wanted it to work.
Any comments appreciated, but not expected.
import ui __THEME_DARK__ = { 'my_view_bg_color':'orange', 'background_color':(1,0,0,.5), 'border_width':1, 'tint_color':'white', 'corner_radius':3, 'width':80, 'center':(0,0), # replace with function in the init of theme class. just to know you can } class theme (object): def __init__(self, view): self.view = view self.theme_dict = __THEME_DARK__ # i am sure there is an elgant way to early bind the function in the dict. guessing the order of declaration, would allow me to specify in the dict. self.theme_dict['center'] = self._center() self.theme_view(self.view) def theme_view(self, view): #handle the view, differently from the subviews.. i would think this would be the normal requirement. view.bg_color = self.theme_dict['my_view_bg_color'] for obj in view.subviews: self._theme_obj(obj) def _theme_obj(self, obj): for attr in dir(obj): if attr in self.theme_dict: setattr(obj,attr,self.theme_dict[attr]) def _center(self): return (300,300) if __name__ == '__main__': #print dir(ui.Button) v = ui.View() v.name = 'Demo' button = ui.Button(title='Help me!') v.add_subview(button) t = theme(v) v.present('sheet')
-
Here is another approach to this problem.
https://omz-forums.appspot.com/pythonista/post/6431680306872320I think applying styles uniformly to all views will not produce the results you expect... Sometimes a label wants a border, other times not, for example. Different controls want to have different corner radius, or bg color, etc. Degelesus's solution was to use the name field to specify the type of control. I suppose this is a case where a "tag" would be useful, then you could implement your own sort of CSS system, but a prefix to the name field works too.
-
@JonB, yes I agree with you about theming Is full of special cases. (Styling is probably a better name) But I wanted to get it as generic as I could (data driven), before branching out into code. I looked at the code you pointed to me in your post, no disrespect to the author , but I was trying to come up with very tight code. Also, no try: statements. In my code I don't see the need for any try: statements. Should not fail!Explicit.
Of course can look at the type of each object to conditionally give it a special treatment, as well as could look at the prefix of the name. And yes, this is where a Tag property would come in extremely handy.
Also my example attempts to also supply a function/method for attributes that can not be expressed in the dict. Not a great example what I did , but I think a starting point.
Sure my inexperience with Python is evident, but I will keep trying :) I know, it's simple stuff, but will keep trying to crawl before walking :)