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 share
import 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')
No idea if this has something to do with your problem, but to tell a view "hey, redraw yourself NOW", you should call
Unrelated suggestion, consider making
PageIndicator.selecteda zero-based index. Then you can write
PageIndicator.drawlike this (note how you don't need to add
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()
PageIndicator.nextlike 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.