omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    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

    Pythonista
    custom draw custom-view
    2
    3
    2883
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Phuket2
      Phuket2 last edited by Phuket2

      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')
      

      Edit

      1 Reply Last reply Reply Quote 0
      • dgelessus
        dgelessus last edited by

        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(), not view.draw().

        Unrelated suggestion, consider making PageIndicator.selected a zero-based index. Then you can write PageIndicator.draw like this (note how you don't need to add + 1 to self.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()
        
        Phuket2 1 Reply Last reply Reply Quote 2
        • Phuket2
          Phuket2 @dgelessus last edited by Phuket2

          @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.

          1 Reply Last reply Reply Quote 0
          • First post
            Last post
          Powered by NodeBB Forums | Contributors