• RoninSage

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

    posted in Pythonista read more
  • RoninSage

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

    posted in Pythonista read more
  • RoninSage

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

    posted in Pythonista read more
  • RoninSage

    I want to have a button that has a different shape than a rectangle. I think ui.Path is the way to go but I am having trouble implementing it. I have code for a simple button press. Could I get some help changing it so the button changes to say a hexagon?

    
    import ui
    # 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
    # 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=1.5*button1.width # change button width
        button1.height=2*button1.height # change button height
        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', hide_title_bar=True)
    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
    
    

    posted in Pythonista read more
  • RoninSage

    @cvp perfect, that simplified all the repetions and I still understand what is going on, thanks heaps.

    posted in Pythonista read more
  • RoninSage

    I have created code that works and does what I want it to do, however, I feel like there is a more condensed way to do this. By creating my own keyboard I can limit the inputs that are available, I can also stop that annoying little bar coming up at the bottom of the screen.

    Below the comment

    # functions that define key button actions

    I feel there is a lot of repetition that could be done more efficiently. Also, below the comment

    # Create key buttons

    again, there is also a lot of repetition. I am sure there is a simple iterative way to approach this, but I am at a loss as to how to do it.

    Thanks for you help.

    
    import ui, itertools
    import numpy as np
    from objc_util import *
    
    # Define variables
    # Create display, further details see theBackground.py
    view=ui.View()
    view.present('fullscreen', hide_title_bar=True)
    view.background_color = ('lightgreen')
    answers=[]
    
    # Counters
    ent_count=0
    
    # Define functions
    # function that allows you to define font as a number using font_list[]
    def get_font_list():
      UIFont = ObjCClass('UIFont')
      return list(itertools.chain(*[UIFont.fontNamesForFamilyName_(str(x))
            for x in UIFont.familyNames()]))
    font_list = get_font_list()
    for i in range(len(font_list)):
      font_list[i]=str(font_list[i])
    
    # function that adds all keys to the screen
    def add_keyboard1(some_list):
      for key in some_list:
        view.add_subview(some_list[key])
    
    # function that removes all keys from the screen
    def remove_keyboard1(some_list):
      for key in range(0,len(some_list)):
        view.remove_subview(some_list[key])
    
    # function to create key buttons
    def create_btn(btn_label,btn_name,btn_x,btn_y,btn_width):
      btn_name.bg_color = (95/255,96/255,98/255,0.8) # button colour
      btn_name.tint_color=(141/255,198/255,63/255) # button font colour
      btn_name.center = (btn_x+view.width*0.215, btn_y-view.height*0.1) # button position
      btn_name.border_width = .5 # add border to button
      btn_name.width = btn_width # button width
      btn_name.height = view.width*0.04 # button height
      btn_name.font = (font_list[7], 20) # button font type and size
      btn_name.corner_radius = view.width * 0.002 # rounds button corners
      view.add_subview(btn_name) # draw button
    
    # functions that define key button actions
    def btn1_tap(sender):
      txt_fld.text=txt_fld.text +'1'
    def btn2_tap(sender):
      txt_fld.text=txt_fld.text +'2'
    def btn3_tap(sender):
      txt_fld.text=txt_fld.text +'3'
    def btn4_tap(sender):
      txt_fld.text=txt_fld.text +'4'
    def btn5_tap(sender):
      txt_fld.text=txt_fld.text +'5'
    def btn6_tap(sender):
      txt_fld.text=txt_fld.text +'6'
    def btn7_tap(sender):
      txt_fld.text=txt_fld.text +'7'
    def btn8_tap(sender):
      txt_fld.text=txt_fld.text +'8'
    def btn9_tap(sender):
      txt_fld.text=txt_fld.text +'9'
    def btn0_tap(sender):
      txt_fld.text=txt_fld.text +'0'
    def btndel_tap(sender):
      txt_fld.text=txt_fld.text[:-1]
    def btnq_tap(sender):
      txt_fld.text=txt_fld.text +'q'
    def btnw_tap(sender):
      txt_fld.text=txt_fld.text +'w'
    def btne_tap(sender):
      txt_fld.text=txt_fld.text +'e'
    def btnr_tap(sender):
      txt_fld.text=txt_fld.text +'r'
    def btnt_tap(sender):
      txt_fld.text=txt_fld.text +'t'
    def btny_tap(sender):
      txt_fld.text=txt_fld.text +'y'
    def btnu_tap(sender):
      txt_fld.text=txt_fld.text +'u'
    def btni_tap(sender):
      txt_fld.text=txt_fld.text +'i'
    def btno_tap(sender):
      txt_fld.text=txt_fld.text +'o'
    def btnp_tap(sender):
      txt_fld.text=txt_fld.text +'p'
    def btnsf_tap(sender):
      txt_fld.text=txt_fld.text +'๐Ÿ™'
    def btna_tap(sender):
      txt_fld.text=txt_fld.text +'a'
    def btns_tap(sender):
      txt_fld.text=txt_fld.text +'s'
    def btnd_tap(sender):
      txt_fld.text=txt_fld.text +'d'
    def btnf_tap(sender):
      txt_fld.text=txt_fld.text +'f'
    def btng_tap(sender):
      txt_fld.text=txt_fld.text +'g'
    def btnh_tap(sender):
      txt_fld.text=txt_fld.text +'h'
    def btnj_tap(sender):
      txt_fld.text=txt_fld.text +'j'
    def btnk_tap(sender):
      txt_fld.text=txt_fld.text +'k'
    def btnl_tap(sender):
      txt_fld.text=txt_fld.text +'l'
    def btnhf_tap(sender):
      txt_fld.text=txt_fld.text +'๐Ÿ™‚'
    def btnz_tap(sender):
      txt_fld.text=txt_fld.text +'z'
    def btnx_tap(sender):
      txt_fld.text=txt_fld.text +'x'
    def btnc_tap(sender):
      txt_fld.text=txt_fld.text +'c'
    def btnv_tap(sender):
      txt_fld.text=txt_fld.text +'v'
    def btnb_tap(sender):
      txt_fld.text=txt_fld.text +'b'
    def btnn_tap(sender):
      txt_fld.text=txt_fld.text +'n'
    def btnm_tap(sender):
      txt_fld.text=txt_fld.text +'m'
    def btnm_tap(sender):
      txt_fld.text=txt_fld.text +'m'
    def btnenter_tap(sender):
      global ent_count
      if len(txt_fld.text)!=0:
        ent_count+=1
        if ent_count<3: # after 3rd entry stops input
          answers.append(txt_fld.text) # records all inputs
          txt_fld.text='' # clears entry after enter is pressed
        else:
          answers.append(txt_fld.text) # records last input
          view.remove_subview(txt_fld) # clears textfield
          some_box.text='My time is a valuable thing' # changes box text
          remove_keyboard1(all_btns) # clears all keys
          view.close()
    
    # Create key buttons
    btn1 = ui.Button(title='1')
    create_btn('1',btn1,view.width*0.0,view.height*0.66,view.width*0.04)
    btn1.action = btn1_tap
    btn2 = ui.Button(title='2')
    create_btn('2',btn2,view.width*0.05,view.height*0.66,view.width*0.04)
    btn2.action = btn2_tap
    btn3 = ui.Button(title='3')
    create_btn('3',btn3,view.width*0.1,view.height*0.66,view.width*0.04)
    btn3.action = btn3_tap
    btn4 = ui.Button(title='4')
    create_btn('4',btn4,view.width*0.15,view.height*0.66,view.width*0.04)
    btn4.action = btn4_tap
    btn5 = ui.Button(title='5')
    create_btn('5',btn5,view.width*0.2,view.height*0.66,view.width*0.04)
    btn5.action = btn5_tap
    btn6 = ui.Button(title='6')
    create_btn('6',btn6,view.width*0.25,view.height*0.66,view.width*0.04)
    btn6.action = btn6_tap
    btn7 = ui.Button(title='7')
    create_btn('7',btn7,view.width*0.3,view.height*0.66,view.width*0.04)
    btn7.action = btn7_tap
    btn8 = ui.Button(title='8')
    create_btn('8',btn8,view.width*0.35,view.height*0.66,view.width*0.04)
    btn8.action = btn8_tap
    btn9 = ui.Button(title='9')
    create_btn('9',btn9,view.width*0.4,view.height*0.66,view.width*0.04)
    btn9.action = btn9_tap
    btn0 = ui.Button(title='0')
    create_btn('0',btn0,view.width*0.45,view.height*0.66,view.width*0.04)
    btn0.action = btn0_tap
    btndel = ui.Button(title='delete')
    create_btn('delete',btndel,view.width*0.505,view.height*0.66,view.width*0.09)
    btndel.action = btndel_tap
    btnq = ui.Button(title='q')
    create_btn('q',btnq,view.width*0.025,view.height*0.73,view.width*0.04)
    btnq.action = btnq_tap
    btnw = ui.Button(title='w')
    create_btn('w',btnw,view.width*0.075,view.height*0.73,view.width*0.04)
    btnw.action = btnw_tap
    btne = ui.Button(title='e')
    create_btn('e',btne,view.width*0.125,view.height*0.73,view.width*0.04)
    btne.action = btne_tap
    btnr = ui.Button(title='r')
    create_btn('r',btnr,view.width*0.175,view.height*0.73,view.width*0.04)
    btnr.action = btnr_tap
    btnt = ui.Button(title='t')
    create_btn('t',btnt,view.width*0.225,view.height*0.73,view.width*0.04)
    btnt.action = btnt_tap
    btny = ui.Button(title='y')
    create_btn('y',btny,view.width*0.275,view.height*0.73,view.width*0.04)
    btny.action = btny_tap
    btnu = ui.Button(title='u')
    create_btn('u',btnu,view.width*0.325,view.height*0.73,view.width*0.04)
    btnu.action = btnu_tap
    btni = ui.Button(title='i')
    create_btn('i',btni,view.width*0.375,view.height*0.73,view.width*0.04)
    btni.action = btni_tap
    btno = ui.Button(title='o')
    create_btn('o',btno,view.width*0.425,view.height*0.73,view.width*0.04)
    btno.action = btno_tap
    btnp = ui.Button(title='p')
    create_btn('p',btnp,view.width*0.475,view.height*0.73,view.width*0.04)
    btnp.action = btnp_tap
    btnsf = ui.Button(title='๐Ÿ™')
    create_btn('๐Ÿ™',btnsf,view.width*0.525,view.height*0.73,view.width*0.04)
    btnsf.action = btnsf_tap
    btna = ui.Button(title='a')
    create_btn('a',btna,view.width*0.05,view.height*0.8,view.width*0.04)
    btna.action = btna_tap
    btns = ui.Button(title='s')
    create_btn('s',btns,view.width*0.1,view.height*0.8,view.width*0.04)
    btns.action = btns_tap
    btnd = ui.Button(title='d')
    create_btn('d',btnd,view.width*0.15,view.height*0.8,view.width*0.04)
    btnd.action = btnd_tap
    btnf = ui.Button(title='f')
    create_btn('f',btnf,view.width*0.2,view.height*0.8,view.width*0.04)
    btnf.action = btnf_tap
    btng = ui.Button(title='g')
    create_btn('g',btng,view.width*0.25,view.height*0.8,view.width*0.04)
    btng.action = btng_tap
    btnh = ui.Button(title='h')
    create_btn('h',btnh,view.width*0.3,view.height*0.8,view.width*0.04)
    btnh.action = btnh_tap
    btnj = ui.Button(title='j')
    create_btn('j',btnj,view.width*0.35,view.height*0.8,view.width*0.04)
    btnj.action = btnj_tap
    btnk = ui.Button(title='k')
    create_btn('k',btnk,view.width*0.4,view.height*0.8,view.width*0.04)
    btnk.action = btnk_tap
    btnl = ui.Button(title='l')
    create_btn('l',btnl,view.width*0.45,view.height*0.8,view.width*0.04)
    btnl.action = btnl_tap
    btnhf = ui.Button(title='๐Ÿ™‚')
    create_btn('๐Ÿ™‚',btnhf,view.width*0.5,view.height*0.8,view.width*0.04)
    btnhf.action = btnhf_tap
    btnz = ui.Button(title='z')
    create_btn('z',btnz,view.width*0.075,view.height*0.87,view.width*0.04)
    btnz.action = btnz_tap
    btnx = ui.Button(title='x')
    create_btn('x',btnx,view.width*0.125,view.height*0.87,view.width*0.04)
    btnx.action = btnx_tap
    btnc = ui.Button(title='c')
    create_btn('c',btnc,view.width*0.175,view.height*0.87,view.width*0.04)
    btnc.action = btnc_tap
    btnv = ui.Button(title='v')
    create_btn('v',btnv,view.width*0.225,view.height*0.87,view.width*0.04)
    btnv.action = btnv_tap
    btnb = ui.Button(title='b')
    create_btn('b',btnb,view.width*0.275,view.height*0.87,view.width*0.04)
    btnb.action = btnb_tap
    btnn = ui.Button(title='n')
    create_btn('n',btnn,view.width*0.325,view.height*0.87,view.width*0.04)
    btnn.action = btnn_tap
    btnm = ui.Button(title='m')
    create_btn('m',btnm,view.width*0.375,view.height*0.87,view.width*0.04)
    btnm.action = btnm_tap
    btnenter = ui.Button(title='enter')
    create_btn('enter',btnenter,view.width*0.425,view.height*0.87,view.width*0.09)
    btnenter.action = btnenter_tap
    
    # List of all button names
    all_btns=(btn1,btn2,btn3,btn4,btn5,btn6,btn7,btn8,btn9,btn0,btndel,
    btnq,btnw,btne,btnr,btnt,btny,btnu,btni,btno,btnp,btnsf,
    btna,btns,btnd,btnf,btng,btnh,btnj,btnk,btnl,btnhf,
    btnz,btnx,btnc,btnv,btnb,btnn,btnm,btnenter)
    
    # Include non-interactive box
    some_box = ui.Label(
      text='This is where you can ask some questions', # 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=(0, 0, view.width, 100)) # position of top box (0 in, 0 down, view.width wide, 100 high)
    some_box.font=('HoeflerText-BlackItalic', 40) # box font type and size
    view.add_subview(some_box) # create box
    
    txt_fld=ui.TextField(frame=(view.width*0.275, view.height*0.34,view.width*0.45, view.height*0.1)) # defines textfield dimensions
    txt_fld.alignment=ui.ALIGN_CENTER # places text in center of the box
    txt_fld.font = ('Chalkduster', 30) # change textfield font
    txt_fld.text_color='hotpink' # text colour
    txt_fld.enabled = False # cannot click in textfield
    view.add_subview(txt_fld) # create textfield
    
    

    posted in Pythonista read more
  • RoninSage

    @enceladus & @ellie_ff1493 thanks for the suggestions but it is not really where I wanted to go with this. Below is code that is starting to get there, however, I want all of the question boxes to move onto the next question whenever one of them is selected. I am sure how to do that. Also, I have included code at the bottom that will record the answers selected into a csv file for later use, I just need help with the code that records the selections into a list. Finally, to complete everything, I would like to start the test off with the participant entering Name, Surname, phone number and email, again something I havenโ€™t figured out yet but I am guessing will need access to the soft keyboard. The code probably needs some cleaning up as I just started working with the code that @cvp linked to earlier.

    
    import itertools, ui, uuid
    from objc_util import *
    
    # Generate list of all fonts
    def get_font_list():
      UIFont = ObjCClass('UIFont')
      return list(itertools.chain(*[UIFont.fontNamesForFamilyName_(str(x))
            for x in UIFont.familyNames()]))
    font_list = get_font_list()
    for i in range(len(font_list)):
      font_list[i]=str(font_list[i])
    
    UILayoutContainerView = ObjCClass('UILayoutContainerView')
    UISwipeGestureRecognizer = ObjCClass('UISwipeGestureRecognizer')
    
    def disable_swipe_to_close(view):
      v = view.objc_instance
      while not v.isKindOfClass_(UILayoutContainerView.ptr):
        v = v.superview()
      for gr in v.gestureRecognizers():
        if gr.isKindOfClass_(UISwipeGestureRecognizer.ptr):
          gr.setEnabled(False)
    
    class Gestures():
    
      TYPE_REGULAR = 0
      TYPE_FORCE = 1
      TYPE_STYLUS = 4
      TYPE_ANY = 8. 
    
      TAP = b'UITapGestureRecognizer'
      PINCH = b'UIPinchGestureRecognizer'
      ROTATION = b'UIRotationGestureRecognizer'
      SWIPE = b'UISwipeGestureRecognizer'
      PAN = b'UIPanGestureRecognizer'
      SCREEN_EDGE_PAN = b'UIScreenEdgePanGestureRecognizer'
      LONG_PRESS = b'UILongPressGestureRecognizer'
    
      CHANGED = 2
      ENDED = 3
    
      RIGHT = 1; LEFT = 2; UP = 4; DOWN = 8
    
      EDGE_NONE = 0; EDGE_TOP = 1; EDGE_LEFT = 2; EDGE_BOTTOM = 4; EDGE_RIGHT = 8; EDGE_ALL = 15
    
      def __init__(self, touch_type=TYPE_REGULAR, force_threshold=0.4, retain_global_reference = True):
        self.buttons = {}
        self.views = {}
        self.recognizers = {}
        self.actions = {}
        self.touches = {}
        self.touch_type = touch_type
        self.force_threshold = force_threshold
        if retain_global_reference:
          retain_global(self)
    
        # Friendly delegate functions
    
        def recognize_simultaneously_default(gr_name, other_gr_name):
          return False    
        self.recognize_simultaneously = recognize_simultaneously_default
        
        def fail_default(gr_name, other_gr_name):
          return False    
        self.fail = fail_default
        
        def fail_other_default(gr_name, other_gr_name):
          return False    
        self.fail_other = fail_other_default
    
        # ObjC delegate functions
        
        def simplify(func, gr, other_gr):
          gr_o = ObjCInstance(gr)
          other_gr_o = ObjCInstance(other_gr)
          if (gr_o.view() != other_gr_o.view()):
            return False
          gr_name = gr_o._get_objc_classname()
          other_gr_name = other_gr_o._get_objc_classname()
          return func(gr_name, other_gr_name)
        
        # Recognize simultaneously
    
        def gestureRecognizer_shouldRecognizeSimultaneouslyWithGestureRecognizer_(_self, _sel, gr, other_gr):
          return self.objc_should_recognize_simultaneously(self.recognize_simultaneously, gr, other_gr)
    
        def objc_should_recognize_simultaneously_default(func, gr, other_gr):
          return simplify(func, gr, other_gr)
          
        self.objc_should_recognize_simultaneously = objc_should_recognize_simultaneously_default
        
        # Fail other
        
        def gestureRecognizer_shouldRequireFailureOfGestureRecognizer_(_self, _sel, gr, other_gr):
          return self.objc_should_require_failure(self.fail_other, gr, other_gr)
    
        def objc_should_require_failure_default(func, gr, other_gr):
          return simplify(func, gr, other_gr)
          
        self.objc_should_require_failure = objc_should_require_failure_default
        
        # Fail
        
        def gestureRecognizer_shouldBeRequiredToFailByGestureRecognizer_(_self, _sel, gr, other_gr):
          return self.objc_should_fail(self.fail, gr, other_gr)
    
        def objc_should_fail_default(func, gr, other_gr):
          return simplify(func, gr, other_gr)
          
        self.objc_should_fail = objc_should_fail_default
        
        # Delegate
        
        try:
          PythonistaGestureDelegate = ObjCClass('PythonistaGestureDelegate')
        except:
          PythonistaGestureDelegate = create_objc_class('PythonistaGestureDelegate',
          superclass=NSObject,
          methods=[
            gestureRecognizer_shouldRecognizeSimultaneouslyWithGestureRecognizer_,
            gestureRecognizer_shouldRequireFailureOfGestureRecognizer_,
            gestureRecognizer_shouldBeRequiredToFailByGestureRecognizer_],
          classmethods=[],
          protocols=['UIGestureRecognizerDelegate'],
          debug=True)
        self._delegate = PythonistaGestureDelegate.new()
    
      @on_main_thread
      def add_tap(self, view, action, number_of_taps_required = None, number_of_touches_required = None):
        ''' Call `action` when a tap gesture is recognized for the `view`.
        
        Additional parameters:
          
        * `number_of_taps_required` - Set if more than one tap is required for the gesture to be recognized.
        * `number_of_touches_required` - Set if more than one finger is required for the gesture to be recognized.
        '''
        recog = self._get_recog('UITapGestureRecognizer', view, self._general_action, action)
    
        if number_of_taps_required:
          recog.numberOfTapsRequired = number_of_taps_required
        if number_of_touches_required:
          recog.numberOfTouchesRequired = number_of_touches_required
        return recog
    
      @on_main_thread
      def add_screen_edge_pan(self, view, action, edges):
        ''' Call `action` when a pan gesture starting from the edge is recognized for the `view`. This is a continuous gesture.
        
        `edges` must be set to one of `Gestures.EDGE_NONE/EDGE_TOP/EDGE_LEFT/EDGE_BOTTOM/EDGE_RIGHT/EDGE_ALL`. If you want to recognize pans from different edges, you have to set up separate recognizers with separate calls to this method.
        
        Handler `action` receives the same gesture-specific attributes in the `data` argument as pan gestures, see `add_pan`.
        '''
        recog = self._get_recog('UIScreenEdgePanGestureRecognizer', view, self._pan_action, action)
    
        recog.edges = edges
    
        return recog
    
      def _get_recog(self, recog_name, view, internal_action, final_handler):
        view.touch_enabled = True
        button = ui.Button()
        key = str(uuid.uuid4())
        button.name = key
        button.action = internal_action
        self.buttons[key] = button
        self.views[key] = view
        recognizer = ObjCClass(recog_name).alloc().initWithTarget_action_(button, sel('invokeAction:')).autorelease()
        self.recognizers[key] = recognizer
        self.actions[key] = final_handler
        ObjCInstance(view).addGestureRecognizer_(recognizer)
        recognizer.delegate = self._delegate
        return recognizer
    
      class Data():
        def __init__(self):
          self.recognizer = self.view = self.location = self.state = self.number_of_touches = self.scale = self.rotation = self.velocity = None
    
      def _context(self, button):
        key = button.name
        (view, recog, action) = (self.views[key], self.recognizers[key], self.actions[key])
        data = Gestures.Data()
        data.recognizer = recog
        data.view = view
        data.location = self._location(view, recog)
        data.state = recog.state()
        data.number_of_touches = recog.numberOfTouches()
        #data.additional_touch_data = self.touches[recog]
        return (data, action)
    
      def _location(self, view, recog):
        loc = recog.locationInView_(ObjCInstance(view))
        return ui.Point(loc.x, loc.y)
    
      def _general_action(self, sender):
        (data, action) = self._context(sender)
        action(data)
    
      def _pan_action(self, sender):
        (data, action) = self._context(sender)
        trans = data.recognizer.translationInView_(ObjCInstance(data.view))
        vel = data.recognizer.velocityInView_(ObjCInstance(data.view))
        data.translation = ui.Point(trans.x, trans.y)
        data.velocity = ui.Point(vel.x, vel.y)
    
        action(data)
    
        action(data)
    
    # TESTING AND DEMONSTRATION
    
    if __name__ == "__main__":
      
      import math, random
      
      g = Gestures()
      
      def random_background(view):
        colors = [(0.3,0.31,0.32), (0.25,0.26,0.27), (0.2,0.21,0.22), (0.15,0.16,0.17), (0.35,0.36,0.37), (0.4,0.41,0.42), (0.45,0.46,0.47), (0.5,0.51,0.52)]
        view.background_color = random.choice(colors)
        view.text_color = (0,0,0) if sum(view.background_color[:3]) > 1.5 else (1,1,1) # colour of font after press button
    
      def update_text(l, text):
        l.text = text
    
      q1_count=-1
      def generic_handler1(data):
        random_background(data.view)
        global q1_count
        q1_count+=1
        if q1_count<=len(Questions1)-1:
          update_text(data.view,Questions1[q1_count])
        else:
          update_text(data.view,'done')
    
      q2_count=-1
      def generic_handler2(data):
        random_background(data.view)
        global q2_count
        q2_count+=1
        if q2_count<=len(Questions2)-1:
          update_text(data.view,Questions2[q2_count])
        else:
          update_text(data.view,'done')
    
      q3_count=-1
      def generic_handler3(data):
        random_background(data.view)
        global q3_count
        q3_count+=1
        if q3_count<=len(Questions3)-1:
          update_text(data.view,Questions3[q3_count])
        else:
          update_text(data.view,'done')
    
      q4_count=-1
      def generic_handler4(data):
        random_background(data.view)
        global q4_count
        q4_count+=1
        if q4_count<=len(Questions4)-1:
          update_text(data.view,Questions4[q4_count])
        else:
          update_text(data.view,'done')
    
      def pan_handler(data):
        update_text(data.view, 'done')
        random_background(data.view)
        bg.close()
    
      Questions1=['What are my strengths?','What frustrates me?','What do I prefer to wear?','What does my desk look like?','When making a large purchase I prioritise:','Who inspires you;']
      Questions2=['ohW','nehW','erehW','yhW','tahw','woH']
      Questions3=['1st ?','2nd ?','3rd ?','4th ?','5th ?','6th ?']
      Questions4=['Question 1','Question 2','Question 3','Question 4','Question 5','Question 6']
    
      bg = ui.View()
      bg.present(style='default',hide_title_bar=True,title_bar_color=(198/255,50/255,108/255), title_color='Green')
      disable_swipe_to_close(bg) # Use to limit access to code
      bg.background_color=(198/255,50/255,108/255) # set background color to pink
      edge_l = ui.Label(
        text='Complete as quickly as possible', 
        background_color='grey',
        text_color='white',
        alignment=ui.ALIGN_CENTER,
        number_of_lines=0,
        frame=(
          0, 0, bg.width, 136 # position of top box (0 in, 0 down, bg.width wide, 136 high)
      ))
      edge_l.font=(font_list[71], 40) # font type and size
      bg.add_subview(edge_l)
      g.add_screen_edge_pan(edge_l, pan_handler, edges=Gestures.EDGE_RIGHT)
    
      v = ui.ScrollView(frame=(0, 95, bg.width, bg.height))  # where grid of boxes are placed 
      bg.add_subview(v)
      
      label_count = -1
      
      def create_label(title):
        global label_count
        label_count += 1
        label_w = 443
        label_h = 300
        gap = 120
        label_w_with_gap = label_w + gap
        label_h_with_gap = label_h + gap
        labels_per_line = math.floor((v.width-2*gap)/(label_w+gap))
        left_margin = (v.width - labels_per_line*label_w_with_gap + gap)/2
        line = math.floor(label_count/labels_per_line)
        column = label_count - line*labels_per_line
        
        l = ui.Label(
          text=title, 
          background_color=(95/255,96/255,98/255), # box colour
          text_color=(141/255,198/255,63/255), # text colour
          alignment=ui.ALIGN_CENTER,
          number_of_lines=0,
          frame=(
            left_margin+column * label_w_with_gap,
            gap+line * label_h_with_gap,
            label_w, label_h
        ))
        l.font=(font_list[32], 40) # font type and size
        v.add_subview(l)
        return l
    
      tap_1 = create_label("What is included in your perfect night in? \n \n Nailing a DYI project")
      tap_2 = create_label("What is included in your perfect night in? \n \n Bath, bed and a good book?")
      tap_3 = create_label("What is included in your perfect night in? \n \n Doonah, snacks, movie and someone to cuddle?")
      tap_4 = create_label("What is included in your perfect night in? \n \n It does'nt matter as long as the house is clean!")
      g.add_tap(tap_1, generic_handler1)
      g.add_tap(tap_2, generic_handler2)
      g.add_tap(tap_3, generic_handler3)
      g.add_tap(tap_4, generic_handler4)
    
    # code to export results to csv file once it is the same for as res given below
    import csv
    res = ['x', '2', 4.7]
    csvfile = 'data.csv'
    
    with open(csvfile, "w") as output:
        writer = csv.writer(output, lineterminator='\n')
        for val in res:
            writer.writerow([val])
    
    

    posted in Pythonista read more
  • RoninSage

    @mikael perfect, that does exactly what I wanted. Combined with guided access mode on the iPad, once the python program starts to run the user shouldnโ€™t be able to leave the view at all.

    But if anyone wants to use this code, I have edited the button function so it will eventually let you out, unfortunately I am not as elegant as @mikael

    Cheers

    #coding: utf-8
    import ui, random
    from ui import *
    from objc_util import *
    
    
    def button_tapped(sender):
      rn=random.random()
      if rn <0.8:
        sender.title = 'unlucky, click again to close'
        button.size_to_fit
      else:
        view.close()
    
    UILayoutContainerView = ObjCClass('UILayoutContainerView')
    UISwipeGestureRecognizer = ObjCClass('UISwipeGestureRecognizer')
    
    def disable_swipe_to_close(view):
      v = view.objc_instance
      while not v.isKindOfClass_(UILayoutContainerView.ptr):
        v = v.superview()
      for gr in v.gestureRecognizers():
        if gr.isKindOfClass_(UISwipeGestureRecognizer.ptr):
          gr.setEnabled(False)
    
    view = ui.View()
    view.background_color = (0.3,0.31,0.32)
    button = ui.Button(title='Click this button to close view')
    button.center = (view.width * 0.5, view.height * 0.5)
    button.flex = 'LRTB'
    button.action = button_tapped
    view.add_subview(button)
    view.present('fullscreen', hide_title_bar=True)
    disable_swipe_to_close(view)
    
    

    posted in Pythonista read more
  • RoninSage

    Is there a way to stop two-finger swipe down gesture from exiting a view with a hidden title bar?

    posted in Pythonista read more
  • RoninSage

    It seemed the best way to use the touch screen interface of the iPad. I am open to other suggestions.

    posted in Pythonista read more

Internal error.

Oops! Looks like something went wrong!