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.


    Sudoku cell with notes

    Pythonista
    4
    12
    2710
    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.
    • JonB
      JonB last edited by

      Not sure if you have ever played sodoku through the nyt games app or website, their interface is nice -- you tap a cell to select it, then you can tag "allowable" values in a cell by tapping a separate keyboard entry -- each value tapped gets shown in the cell as smaller text. A custom keyboard may be what you want here, since you can add buttons to go to next cell vertically or horizontally, etc.
      @cvp has some good example of how to make custom keyboards.

      A custom view class can define a custom draw method, which gets called initially them whenever you call set_needs_display. That sets up a drawing context for you, so all you need to do is use the ui.path draw/stroke methods. A custom view also let a you define touch handling methods, so might be better than a button.

      The alternative for drawing is you have to define your own context, and stuff the resulting image into an image view.

      1 Reply Last reply Reply Quote 1
      • cvp
        cvp @jm2466 last edited by

        @jm2466 not sure, as usual, that I correctly understand, but try this

        import ui
        
        class MyButton(ui.View):           
        	def __init__(self, seconds=True, *args, **kwargs):
        		super().__init__(*args, **kwargs)
        		y = 0
        		for row in range(3):
        			x = 0
        			for col in range(3):
        				n = ui.Button()
        				n.frame = (x,y,self.width/3,self.height/3)
        				n.border_width = 1
        				n.title = str(1+row+3*col)
        				n.action = self.note_action
        				self.add_subview(n)
        				x += self.width/3
        			y += self.height/3
        	def note_action(self,sender):
        		for n in self.subviews:
        			self.remove_subview(n)
        		b = ui.Button()
        		b.frame = (0,0,self.width,self.height)
        		b.border_width = 1
        		b.title = sender.title
        		self.add_subview(b)
        		
        v = ui.View()
        v.background_color = 'white'
        v.name = 'Sudoku cell with notes'
        
        d = 69
        e = 11
        w = 4*e + 3*d
        v.frame = (0,0,w,w)
        y = e
        for row in range(3):
        	x = e
        	for col in range(3):
        		b = MyButton(frame=(x,y,d,d))
        		v.add_subview(b)
        		x += d + e
        	y += d + e
        
        v.present('sheet')
        

        1 Reply Last reply Reply Quote 0
        • cvp
          cvp @jm2466 last edited by

          @jm2466 of course, you can make this script better, for instance by disabling digits already tapped

          	def note_action(self,sender):
          		for n in self.subviews:
          			self.remove_subview(n)
          		b = ui.Button()
          		b.frame = (0,0,self.width,self.height)
          		b.name = 'cell'
          		b.border_width = 1
          		b.title = sender.title
          		self.add_subview(b)
          		self.desactivate(sender.title)
          	def desactivate(self,note):
          		for myb in self.superview.subviews:
          			for sv in myb.subviews:
          				if sv.name == 'note':
          					if sv.title == note:
          						sv.enabled = False		
          

          1 Reply Last reply Reply Quote 1
          • jm2466
            jm2466 last edited by

            Thanks for the replies!

            I was able to create a custom view suggested by JonB to draw the grid lines. I also experimented with multiple sub views on a button but cvp’s example is definitely more complete.

            One other thing I need is a toggle button per say but basically a button that changes from normal to a “depressed” look when tapped.

            Another thing is scaling the font on the label/button. I want to make this work for different screen sizes (iPhone and iPad) and be as dynamic as possible. I am planning to size the cells based on the screen width which is in pixels. I did not see anything on the button for font size but did see a scaling on the label, however that just seems to be a best fit if more text is added (did not test it). I would like the single number in the cell to be larger than notes numbers.

            With those and the replies I think I have what I need to start putting this together.

            Thanks again!

            cvp 1 Reply Last reply Reply Quote 0
            • cvp
              cvp @jm2466 last edited by

              @jm2466 said:

              did not see anything on the button for font size

              	def note_action(self,sender):
              		for n in self.subviews:
              			self.remove_subview(n)
              		b = ui.Button()
              		b.frame = (0,0,self.width,self.height)
              		b.name = 'cell'
              		b.border_width = 1
              		b.title = sender.title
              		b.font = ('Menlo',32)
              		self.add_subview(b)
              		self.desactivate(sender.title)
              

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

                Perfect! Thanks!

                Can you now write a button that toggles to look pressed??? 😀

                cvp 2 Replies Last reply Reply Quote 0
                • cvp
                  cvp @jm2466 last edited by

                  @jm2466 not before tomorrow, sorry, time to sleep for a very old man 👴🏻

                  1 Reply Last reply Reply Quote 0
                  • cvp
                    cvp @jm2466 last edited by cvp

                    @jm2466 ok, did it quickly but not very nice...

                    Edit: try with different d =, like d = 16

                    	def note_action(self,sender):
                    		for n in self.subviews:
                    			self.remove_subview(n)
                    		bt = ui.Button()
                    		bt.frame = (0,0,self.width,self.height)
                    		bt.name = 'cell'
                    		bt.border_width = 1
                    		bt.title = sender.title
                    		with ui.ImageContext(bt.width,bt.height) as ctx:
                    			d = 8
                    			x = 0
                    			y = 0
                    			wp = bt.width - 2*d
                    			hp = bt.height - 2*d
                    			path1 = ui.Path()
                    			r,g,b,alpha = (0.8,0.8,0.8,1)
                    			ui.set_color((r,g,b))
                    			path1.move_to(x  ,y)
                    			path1.line_to(x+d,y+d)
                    			path1.line_to(x+d,y+d+hp)
                    			path1.line_to(x  ,y+d+hp+d)
                    			path1.close()
                    			path1.fill()
                    			path1.stroke()
                    			path2 = ui.Path()
                    			r,g,b = (r-0.05,g-0.05,b-0.05)
                    			ui.set_color((r,g,b))
                    			path2.move_to(x  ,y)
                    			path2.line_to(x+d,y+d)
                    			path2.line_to(x+d+wp,y+d)
                    			path2.line_to(x+d+wp+d,y)
                    			path2.close()
                    			path2.fill()
                    			path2.stroke()
                    			path3 = ui.Path()
                    			r,g,b = (r-0.05,g-0.05,b-0.05)
                    			ui.set_color((r,g,b))
                    			path3.move_to(x+d+wp+d,y)
                    			path3.line_to(x+d+wp+d,y+d+hp+d)
                    			path3.line_to(x+d+wp,y+d+hp)
                    			path3.line_to(x+d+wp,y+d)
                    			path3.close()
                    			path3.fill()
                    			path3.stroke()
                    			path4 = ui.Path()
                    			r,g,b = (r-0.05,g-0.05,b-0.05)
                    			ui.set_color((r,g,b))
                    			path4.move_to(x+d+wp+d,y+d+hp+d)
                    			path4.line_to(x,y+d+hp+d)
                    			path4.line_to(x+d,y+d+hp)
                    			path4.line_to(x+d+wp,y+d+hp)
                    			path4.close()
                    			path4.fill()
                    			path4.stroke()
                    			bt.background_image = ctx.get_image()
                    		bt.font = ('Menlo',32)
                    		self.add_subview(bt)
                    		self.desactivate(sender.title)
                    

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

                      Thanks again! Have been busy with work and have not had a chance to work on this. Hopefully will in a few days.

                      cvp 1 Reply Last reply Reply Quote 0
                      • cvp
                        cvp @jm2466 last edited by

                        @jm2466 Cool, work first... If you want another look, please tell me

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