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.


    Changing button shape using up.Path

    Pythonista
    4
    11
    6238
    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.
    • brumm
      brumm last edited by

      Try changing the draw method in this example.

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

        May be this
        https://github.com/encela95dus/ios_pythonista_examples/blob/master/imagecontext4.py

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

          
          import ui, math
          # Define variables
          btn_counter=-1 # button pressed count
          btn_color=['red','magenta','blue','green','yellow','cyan'] # button colours
          btn_txt=['click again','click one more time','have another go','go again please', 'one last press','finally'] # button text when pressed
          
          def make_polygon(num_sides, x=0, y=0, radius=100, phase=0, line_width=5): 
              path = ui.Path()
              path.move_to(x,y)
              path.line_width = line_width
              for i in range(num_sides):
                  t = 2*math.pi*i/num_sides
                  x1, y1 = radius+radius*math.cos(t+phase), radius+radius*math.sin(t+phase)
                  if i:
                      path.line_to(x+x1, y+y1)
                  else:
                      path.move_to(x+x1,y+y1)
              path.close() 
              return path 
              
          def create_image(w, h, bg, fg):
              img = None
              with ui.ImageContext(w, h) as ctx:  
                  ui.set_color(bg)
                  rect = ui.Path.rect(0,0,w,h)
                  rect.fill()        
                  ui.set_color(fg)
                  path = make_polygon(6, 0, 0, h/2, math.pi/2) 
                  path.fill() 
                  img = ctx.get_image()
              return img   
              
          # Define functions
          # What button1 does when tapped
          def button1_tapped(sender):
            global btn_counter # count number of times the button is pressed
            btn_counter+=1
            if btn_counter<=5: # cycle through button colours
              sender.title = btn_txt[btn_counter] # change button text when pressed
              sender.size_to_fit() # adjust button size to fit new text exactly
              button1.width=button1.width # change button width
              button1.height=button1.width # change button height
              main_bg = (214/255,12/255,140/255)
              button1.background_image = create_image(button1.width, button1.height,
                                                  main_bg, btn_color[btn_counter])
              #button1.bg_color = btn_color[btn_counter] # change button colour when tapped
            else:
              view.remove_subview(button1) # remove button
              some_box.title = 'thank you for your time' # change box text
              some_box.size_to_fit() # change box size to fit new text exactly
              some_box.frame=(view.width*0.38,view.height*0.45,1.1*some_box.width,2*some_box.height) # change box location and size
          
          # Create display, further details see theBackground.py
          view=ui.View()
          view.present('fullscreen')
          view.background_color = (214/255,12/255,140/255)
          
          # Create button
          button1 = ui.Button(title='Click me') # initial button text
          button1.center = (view.width*0.38, view.height*0.45) # Button initial position
          #button1.border_width = 5 # give button a border
          #button1.size_to_fit() # fit button around text exactly
          button1.width = view.width*0.3 # button width
          button1.height = view.height*0.2 # button height
          button1.bg_color = (.3,.31,.32) # button colour (.3,.31,.32,0) fof transparent
          button1.font = ('Chalkduster', 30) # button font type and size
          button1.tint_color=(1,1,1) # button font colour
          button1.action = button1_tapped # needed for when button pressed
          view.add_subview(button1) # display button
          
          # Include non-interactive box
          some_box = ui.Label(
            text='This is not a button', # box text
            background_color=(95/255,96/255,98/255), # box colour
            text_color='white', # box text colour
            alignment=ui.ALIGN_CENTER, # text alignment in box
            number_of_lines=0, # number of lines used in box
            frame=(10, 10, view.width-20, 100)) # box position (10 in, 10 down, view.width-20 wide, 100 high)
          some_box.font=('HoeflerText-BlackItalic', 40) # box font type and size
          view.add_subview(some_box) # show box
          
          1 Reply Last reply Reply Quote 0
          • RoninSage
            RoninSage last edited by

            @brumm thanks for the help but the code In the link did not work when I tried to run it.

            @enceladus this is a start but the button still exists as a rectangle around the hexagon picture. Any tips to make sure that only tapping the shape will activate the button?

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

              Need to write "inside" function.

              # coding: utf-8
              
              import ui, math
              
              class MyButtonClass(ui.View):
                  def __init__(self):
                      self.color = 'red'
                      #touch event are limited to this area (left=100,top=100,right=200,bottom=200)
                      self.x = 100
                      self.y = 100
                      self.height = 100
                      self.width = 100
                      self.main_bg = 'black'
                      self.fg = 'red'
                      
                  def make_polygon(self, num_sides, x=0, y=0, radius=100, phase=0, line_width=5): 
                      path = ui.Path()
                      path.move_to(x,y)
                      path.line_width = line_width
                      for i in range(num_sides):
                          t = 2*math.pi*i/num_sides
                          x1, y1 = radius+radius*math.cos(t+phase), radius+radius*math.sin(t+phase)
                          if i:
                              path.line_to(x+x1, y+y1)
                          else:
                              path.move_to(x+x1,y+y1)
                      path.close() 
                      return path 
                      
              
                  def draw(self):
                      w, h = self.width, self.height
                      ui.set_color(self.main_bg)
                      rect = ui.Path.rect(0,0,w,h)
                      rect.fill()        
                      ui.set_color(self.fg)
                      path = self.make_polygon(6, 0, 0, h/2, math.pi/2) 
                      path.fill() 
                      
                  def inside(self, touch):
                      return True
              
                  def touch_ended(self, touch):
                      if not self.inside(touch):
                          return
                      if self.fg == 'red':
                          self.fg = 'blue'
                      else:
                          self.fg = 'red'
                      self.set_needs_display()
              
              class SpecialButton(object):
                  def __init__(self):
                      self.view = ui.View()
                      self.view.present('fullscreen')
                      self.btn = MyButtonClass()
                      self.view.add_subview(self.btn)
              
              SpecialButton()
              
              
              1 Reply Last reply Reply Quote 0
              • cvp
                cvp last edited by

                Perhaps, inside(touch) could check the color of touch.location?

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

                  Here is an implementation. Not tested well. (Used Brumm code)

                  # coding: utf-8
                  from matplotlib import path
                  
                  import ui, math
                  
                  class MyButtonClass(ui.View):
                      def __init__(self):
                          self.color = 'red'
                          #touch event are limited to this area (left=100,top=100,right=200,bottom=200)
                          self.x = 100
                          self.y = 100
                          self.height = 100
                          self.width = 100
                          self.main_bg = 'black'
                          self.fg = 'red'
                          self.points = []
                          
                      def make_polygon(self, num_sides, x=0, y=0, radius=100, phase=0, line_width=5): 
                          path1 = ui.Path()
                          path1.move_to(x,y)
                          path1.line_width = line_width
                          points = []
                          for i in range(num_sides):
                              t = 2*math.pi*i/num_sides
                              x1, y1 = radius+radius*math.cos(t+phase), radius+radius*math.sin(t+phase)
                              points.append((x+x1, y+y1))
                              if i:
                                  path1.line_to(x+x1, y+y1)
                              else:
                                  path1.move_to(x+x1,y+y1)
                          path1.close() 
                          return (path1, points)
                          
                  
                      def draw(self):
                          w, h = self.width, self.height
                          ui.set_color(self.main_bg)
                          rect = ui.Path.rect(0,0,w,h)
                          rect.fill()        
                          ui.set_color(self.fg)
                          path1, self.points = self.make_polygon(6, 0, 0, h/2, math.pi/2) 
                          path1.fill() 
                          
                      def inside(self, touch):
                          p = path.Path(self.points)
                          return p.contains_points([touch.location])[0]
                  
                      def touch_ended(self, touch):
                          if not self.inside(touch):
                              return
                          if self.fg == 'red':
                              self.fg = 'blue'
                          else:
                              self.fg = 'red'
                          self.set_needs_display()
                  
                  class SpecialButton(object):
                      def __init__(self):
                          self.view = ui.View()
                          self.view.present('fullscreen')
                          self.btn = MyButtonClass()
                          self.view.add_subview(self.btn)
                  
                  SpecialButton()
                  
                  
                  
                  1 Reply Last reply Reply Quote 0
                  • RoninSage
                    RoninSage last edited by

                    @enceladus That last code worked, just a quick question, if I wanted a second button, is there an easy way to do that?

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

                      class MyButtonClass(ui.View):
                          def __init__(self, x, y, height, width):
                              self.x = x
                              self.y = y
                              self.height = height
                              self.width = width
                      
                      class SpecialButton(object):
                          def __init__(self):
                              self.view = ui.View()
                              self.view.present('fullscreen')
                              self.btn = MyButtonClass(100, 100, 100, 100)
                              self.btn2 = MyButtonClass(200, 100, 100, 100)
                              self.view.add_subview(self.btn)
                              self.view.add_subview(self.btn2)
                      

                      python classes

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

                        @brumm thanks, just enough info for me to figure it out.

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