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.
Help with draw method in custom class
-
I am trying to create a page dot view, for the want of a better word. When you see the dots/circles at a bottom of a view in iOS to indicate there are multiple pages. Normally you swipe and the dots lite up and dim. What I have listed below all works as far as the numbers go. I took out all the print statements. There is something I don't understand in the draw statement. When the view is first draw, it's drawn correctly. But when I try to change the dot color in the draw function, it does not work. As I say, I am sure the logic is ok as I had print statements everywhere, I am sure it's something about the draw function and ImageContext objects I don't understand.
It's rough at the moment, but the idea is to get it right to shareimport ui class PageIndicator(ui.View): def __init__(self, *args, **kwargs): self.num_pages = 10 self.w = 10 self.h = 10 self.factor = .6 self.selected = 2 self.on_color = 'orange' self.off_color = 'black' self.frame = (0,0, self.w * self.num_pages, self.h) def layout(self): self.width = self.w * self.num_pages self.height = self.h def next(self): if self.selected == self.num_pages: self.selected = 1 else: self.selected += 1 # self.draw() # edit from @dgelessus , self.set_needs_display() def draw(self): ui.set_color(self.off_color) for i in range(0,self.num_pages +1): oval = ui.Path.oval(self.w * i, 0, self.w * self.factor, self.h * self.factor) if (i + 1) == self.selected: ui.set_color(self.on_color) oval.fill() ui.set_color(self.off_color) else: oval.fill() class TestClass(ui.View): def __init__(self, image_mask = None, *args, **kwargs): ui.View.__init__(self, *args, **kwargs) self.pg_ind = PageIndicator() self.add_subview(self.pg_ind) btn = ui.Button(title = 'Next Page') btn.action = self.next_page btn.width = 100 btn.height = 32 btn.border_width = .5 btn.corner_radius = 3 btn.bg_color = 'black' btn.tint_color = 'orange' self.add_subview(btn) btn.center = self.center def next_page(self, sender): self.pg_ind.next() def layout(self): pg_ind = self.pg_ind pg_ind.y = self.bounds.height - (pg_ind.h + 10) pg_ind.x = (self.bounds.width / 2 ) - (pg_ind.width / 2) if __name__ == '__main__': f = (0,0, 320, 480) tc = TestClass( frame = f, bg_color = 'white') tc.present('sheet')
Edit
-
No idea if this has something to do with your problem, but to tell a view "hey, redraw yourself NOW", you should call
view.set_needs_display()
, notview.draw()
.Unrelated suggestion, consider making
PageIndicator.selected
a zero-based index. Then you can writePageIndicator.draw
like this (note how you don't need to add+ 1
toself.num_pages
anymore):def draw(self): ui.set_color(self.off_color) for i in range(self.num_pages): oval = ui.Path.oval(self.w * i, 0, self.w * self.factor, self.h * self.factor) if i == self.selected: ui.set_color(self.on_color) oval.fill() ui.set_color(self.off_color) else: oval.fill()
And
PageIndicator.next
like this (modulo is awesome in cases like these):def next(self): self.selected = self.selected % self.num_pages self.set_needs_display()
-
@dgelessus , super cool. The problem was the set_needs_display().works as expected now, have to say, it's pretty nice. I know what you mean about the zero base. Things started going wrong so I started adjusting things. But just happy it's working. Will go and look at your other ideas. I also have another mistake with scaling the rects for the ovals also. It's just top,left based. But now the basics are working I can get excited again 😱👍
Edit : I also meant to say thank you.