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.


    Keyboard switch.

    Pythonista
    5
    116
    46943
    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.
    • shinya.ta
      shinya.ta last edited by

      If you use this script to switch the keyboard, the existing keyboard will be hidden.
      How can I change the beta version to use with the existing keyboard?

      import ui
      from objc_util import *
      import clipboard
      import speech
      
      v = ui.View()
      v.frame = (0,0,500,320)
      v.name = 'Move cursor in TextView'
      
      tv = ui.TextView()
      tv.name = 'TextView'
      tv.frame = (0,10,380,250)
      tv.font = ('Arial Rounded MT Bold',20)
      tv.text = 'aรฉ๐Ÿ˜ข๐Ÿ‡ฏ๐Ÿ‡ต๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง'
      v.add_subview(tv)
      
      def say_char(tv):
          # test speech character at cursor
          idxtopos = IndexToPos('')       # list index to position
          i = tv.selected_range[0]
          #print(i,idxtopos)  
          i = idxtopos[i]                                 # used to check if same base character
          if i < len(tv.text):
              c = tv.text[i]
              if c == ' ':
                  c ='space'
              speech.say(c,'jp-JP')
      
      
      def selected_range(i):
          tvo = ObjCInstance(tv)
          p1 = tvo.positionFromPosition_offset_(tvo.beginningOfDocument(), i)
          p2 = p1
          tvo.selectedTextRange = tvo.textRangeFromPosition_toPosition_(p1, p2)
          say_char(tv)
          return 
      
      # some emoji like flags count as 2 for len but as 4 for selected_range
      def IndexToPos(type):
          tvo = ObjCInstance(tv)
          # build array index -> position in range
          idxtopos = []
          pre_x = -1
          #print(tv.text)
          for c in tv.text:
            # nbr characters used e=1 รฉ=1 ๐Ÿ˜‚=1 ๐Ÿ‡ฏ๐Ÿ‡ต=2 ๐Ÿ‘จโ€๐Ÿ‘จโ€๐Ÿ‘งโ€๐Ÿ‘ง=7
            # some emoji generate more than one character, 
            # sometimes counted for more than one in range
            # 1,2,3->1  4->2
            nb = 1 + int(len(c.encode('utf-8'))/4)
            for j in range(0,nb):
              p1 = tvo.positionFromPosition_offset_(tvo.beginningOfDocument(), len(idxtopos))
              p2 = p1
              rge = tvo.textRangeFromPosition_toPosition_(p1, p2)
              rect = tvo.firstRectForRange_(rge)  # CGRect
              x = rect.origin.x
              if x == float('inf') or x == pre_x:
                # same x as previous one, composed character
                pass
              else:
                pre_x = x
                i = len(idxtopos)
              idxtopos.append(i)                      # start position of c
            #print(c,nb,len(idxtopos)-1,i,x)
          idxtopos.append(i+1)                            # end position of last c
          #print(idxtopos)
          # get index of actual cursor
          i = tv.selected_range[0]                # actual position of cursor
          # often p is one of sub_chars, not always the first one
          p = idxtopos[i]                                 # used to check if same base character
          #print(p,i,idxtopos)
          if type == 'left':
            if i == 0:
              return                                              # already before character
            while True:
              i = i - 1
              if idxtopos[i] != p:
                q = idxtopos[i]
                # seach first sub-character
                while i > 0:
                  if idxtopos[i-1] != q:
                    break
                  i = i - 1
              break
          elif type == 'right':
            if i == (len(idxtopos)-1):
              return                                              # already after last character
            while True:
              i = i + 1
              if idxtopos[i] != p:
                break
          elif type == 'end':
            i = len(idxtopos)-1
          else:
            return idxtopos
          r = idxtopos[i]
          selected_range(i)
          return idxtopos
      
      b_top = ui.Button()
      b_top.frame = (285,302,94,41)
      b_top.title = 'ๆ–‡้ ญ'
      b_top.background_color = 'white'
      b_top.border_width = 1
      def b_top_action(sender):
          tv = sender.superview['TextView']
          tv.selected_range = (0,0)
      b_top.action = b_top_action
      v.add_subview(b_top)
      
      b_left = ui.Button()
      b_left.frame = (190,262,94,41)
      b_left.title = 'โฌ…๏ธŽ'
      b_left.background_color = 'white'
      b_left.border_width = 1
      def b_left_action(sender):
          idxtopos = IndexToPos('left')       # list index to position
      b_left.action = b_left_action
      v.add_subview(b_left)
      
      b_right = ui.Button()
      b_right.frame = (285,262,94,41)
      b_right.title = 'โžก๏ธŽ'
      b_right.background_color = 'white'
      b_right.border_width = 1
      def b_right_action(sender):
          idxtopos = IndexToPos('right')      # list index to position
      b_right.action = b_right_action
      v.add_subview(b_right)
      
      b_bottom = ui.Button()
      b_bottom.frame = (190,302,94,41)
      b_bottom.title = 'ๆ–‡ๆœซ'
      b_bottom.background_color = 'white'
      b_bottom.border_width = 1
      def b_bottom_action(sender):
          idxtopos = IndexToPos('end')        # list index to position
      b_bottom.action = b_bottom_action
      v.add_subview(b_bottom)
      
      def get_xy(tv):
          idxtopos = IndexToPos('')       # list index to position
          tvo = ObjCInstance(tv)
          x_y = []
          for i in range(0,len(idxtopos)+1):  # x,y of each character
            p1 = tvo.positionFromPosition_offset_(tvo.beginningOfDocument(), i)
            rge = tvo.textRangeFromPosition_toPosition_(p1,p1)
            rect = tvo.firstRectForRange_(rge)    # CGRect
            x,y = rect.origin.x,rect.origin.y
            if i == len(idxtopos):
              if i > 0:
                x,y = x_y[i-1]
              else:
                # text is empty
                x,y = 0,0
            if x == float('inf'):
              x,y = x_prec+15,y_prec
            x_prec,y_prec = x,y
            x_y.append((x,y))
          return x_y
          
      b_up = ui.Button()
      b_up.frame = (0,262,94,41)
      b_up.title = 'โฌ†๏ธŽ'
      b_up.background_color = 'white'
      b_up.border_width = 1
      def b_up_action(sender):
          tv = sender.superview['TextView']
          x_y = get_xy(tv)
          c = tv.selected_range[0] 
          xc,yc = x_y[c]
          i = c - 1
          while i >=  0:
            x,y = x_y[i]
            if y < yc:
              # previous row
              if x <= xc:
                selected_range(i)
                return
            i = i - 1
      b_up.action = b_up_action
      v.add_subview(b_up)
      
      b_down = ui.Button()
      b_down.frame = (95,262,94,41)
      b_down.title = 'โฌ‡๏ธŽ'
      b_down.background_color = 'white'
      b_down.border_width = 1
      def b_down_action(sender):
          tv = sender.superview['TextView']
          idxtopos = IndexToPos('')       # list index to position
          x_y = get_xy(tv)
          c = tv.selected_range[0] 
          #print(x_y,c)
          xc,yc = x_y[c]
          i = c# - 1          # I don't remember why this "- 1"
          while i < len(idxtopos):
            x,y = x_y[i]
            if y > yc:
              # next row
              if x >= xc:
                selected_range(i)
                return
              else:
                if (i+1) < len(idxtopos):
                  if x_y[i+1][1] > y: # i = last character of row under cursor
                    selected_range(i)
                    return
                  else:
                    pass  # try next x
                else:
                  # last character of last row
                  selected_range(i)
                  return
            i = i + 1
      b_down.action = b_down_action
      v.add_subview(b_down)
      
      b_copy = ui.Button()
      b_copy.frame = (95,302,94,41)
      b_copy.title = 'copy'
      b_copy.background_color = 'white'
      b_copy.border_width = 1
      def b_copy_action(sender):
          tv = sender.superview['TextView']
          clipboard.set(tv.text)
      b_copy.action = b_copy_action
      v.add_subview(b_copy)
      
      b_clear = ui.Button()
      b_clear.frame = (0,302,94,41)
      b_clear.title = 'clear'
      b_clear.background_color = 'white'
      b_clear.border_width = 1
      def b_clear_action(sender):
          tv = sender.superview['TextView']
          tv.text = ''
      b_clear.action = b_clear_action
      v.add_subview(b_clear)
      
      #็ตตๆ–‡ๅญ—ใ‚ฟใ‚นใ‚ฏใƒใƒผ
      
      def typeChar(sender):
          '''finds active textinput, and types the button's title'''
          tf=sender.objc_instance.firstResponder()
          tf.insertText_(sender.title)
      
      def nextSet(sender):
          i_set = sender.i_set + 1
          if i_set == sender.n_sets:
              i_set = 0
          #attach our accessory to the textfield, and textview
          ww = vv_array[i_set]
          tvo = tv.objc_instance
          #print(dir(tvo))
          tvo.setInputAccessoryView_(ObjCInstance(ww))
          tvo.reloadInputViews()
      
      #create normal keys
      d = 32
      dd = 4
      emojis = '๐Ÿ˜Š๐Ÿ˜œ๐Ÿ˜ฑ๐Ÿ’ฆโ˜”๏ธ(็ฌ‘)โ˜€๏ธโ˜๏ธโ˜ƒ๏ธโ„๏ธ๐Ÿ™๐Ÿ”๐Ÿš—๐ŸŒˆโญ๏ธ๐Ÿ˜€๐Ÿ˜ƒ๐Ÿ˜„๐Ÿ˜๐Ÿ˜†๐Ÿ˜…๐Ÿ˜‚๐Ÿคฃโ˜บ๏ธ๐Ÿ˜Š๐Ÿ˜‡๐Ÿ™‚๐Ÿ™ƒ๐Ÿ˜‰๐Ÿ˜Œ๐Ÿ˜๐Ÿฅฐ๐Ÿ˜˜๐Ÿ˜—๐Ÿ˜™๐Ÿ˜š๐Ÿ˜‹๐Ÿ˜›๐Ÿ˜๐Ÿ˜œ๐Ÿคช๐Ÿคจ๐Ÿง๐Ÿค“๐Ÿ˜Ž๐Ÿคฉ๐Ÿฅณ๐Ÿ˜๐Ÿ˜’๐Ÿ˜ž๐Ÿ˜”๐Ÿ˜Ÿ๐Ÿ˜•๐Ÿ™โ˜น๏ธ๐Ÿ˜ฃ๐Ÿ˜–๐Ÿ˜ซ๐Ÿ˜ฉ๐Ÿฅบ๐Ÿ˜ข๐Ÿ˜ญ๐Ÿ˜ค๐Ÿ˜ ๐Ÿ˜ก๐Ÿคฌ๐Ÿคฏ๐Ÿ˜ณ๐Ÿฅต๐Ÿฅถ๐Ÿ˜จ๐Ÿ˜ฐ๐Ÿ˜ฅ๐Ÿ˜“๐Ÿค—๐Ÿค”๐Ÿคญ๐Ÿคซ๐Ÿคฅ๐Ÿ˜ถ๐Ÿ˜๐Ÿ˜‘๐Ÿ˜ฌ๐Ÿ˜ฆ๐Ÿ˜ง๐Ÿ˜ฎ๐Ÿ˜ฒ๐Ÿ˜ด'
      n_emojis_in_set = 10
      n_sets = 1 + int((len(emojis)-1)/n_emojis_in_set)
      vv_array = []
      for i_set in range(0,n_sets):
          l = int(len(emojis)/n_sets)
          i = i_set * l
          set_emojis = emojis[i:i+l] + 'โฉ'
          w, h = ui.get_screen_size() 
          vv = ui.View(name='set'+str(i_set))
          vv.background_color = 'lightgray'
          h = 0
          x = dd
          y = dd
          for button_title in set_emojis:
              b = ui.Button(title=button_title)
              if button_title == 'โฉ':
                  b_action = nextSet
                  b.i_set = i_set
                  b.n_sets = n_sets
                  b.name = 'nextSet'
              else:
                  b_action = typeChar
              b.action=b_action
              b.frame = (x,y,d,d)
              b.font = ('.SFUIText', d)
              if (y+d+dd) > h:
                  h = y + d + dd
              vv.add_subview(b)
              x = x + d + dd
              if (x+d+dd) > w:
                  x = dd
                  y = y + d + dd
          vv.frame = (0,0,w,h)
          vv_array.append(vv)
      
      i_set = 0
      nextSet(vv_array[n_sets-1]['nextSet'])  # display 1st setet)
      
      v.present('sheet')
      tv.selected_range = (0,0)
      tv.begin_editing()
      
      cvp 1 Reply Last reply Reply Quote 0
      • cvp
        cvp @shinya.ta last edited by

        @shinya.ta Hello, hoping you're ok

        Try to comment this line by putting a # in front of it

        #nextSet(vv_array[n_sets-1]['nextSet'])  # display 1st setet)
        
        shinya.ta 1 Reply Last reply Reply Quote 0
        • shinya.ta
          shinya.ta @cvp last edited by

          @cvp

          Dear.@cvp

          #nextSet(vv_array[n_sets-1]['nextSet']) # display 1st setet)

          I don't know where I insert this.

          cvp 1 Reply Last reply Reply Quote 0
          • cvp
            cvp @shinya.ta last edited by

            @shinya.ta You have only to put a # at the line which is the 4th before the end of your script

            shinya.ta 1 Reply Last reply Reply Quote 0
            • shinya.ta
              shinya.ta @cvp last edited by

              @cvp

              I put the #, but there is no change.

              The window is displayed instead of the keyboard.

              cvp 1 Reply Last reply Reply Quote 0
              • cvp
                cvp @shinya.ta last edited by cvp

                @shinya.ta Please, could you post here your 10 last lines, thanks

                shinya.ta 1 Reply Last reply Reply Quote 0
                • shinya.ta
                  shinya.ta @cvp last edited by

                  @cvp

                          if (x+d+dd) > w:
                              x = dd
                              y = y + d + dd
                      vv.frame = (0,0,w,h)
                      vv_array.append(vv)
                  
                  i_set = 0
                  nextSet(vv_array[n_sets-1]['nextSet'])  # display 1st setet)
                  
                  v.present('sheet')
                  tv.selected_range = (0,0)
                  tv.begin_editing()
                  
                  cvp 1 Reply Last reply Reply Quote 0
                  • cvp
                    cvp @shinya.ta last edited by

                    @shinya.ta put a # before the line nextSet... as here-after

                    if (x+d+dd) > w:
                                x = dd
                                y = y + d + dd
                        vv.frame = (0,0,w,h)
                        vv_array.append(vv)
                    
                    i_set = 0
                    #nextSet(vv_array[n_sets-1]['nextSet'])  # display 1st setet)
                    
                    v.present('sheet')
                    tv.selected_range = (0,0)
                    tv.begin_editing()```
                    shinya.ta 1 Reply Last reply Reply Quote 0
                    • shinya.ta
                      shinya.ta @cvp last edited by

                      @cvp

                      vv.frame = (0,0,w,h)...
                      
                      

                      There is an error here.

                      cvp 1 Reply Last reply Reply Quote 0
                      • cvp
                        cvp @shinya.ta last edited by

                        @shinya.ta Sorry but without the code, no help possible

                        shinya.ta 2 Replies Last reply Reply Quote 0
                        • cvp
                          cvp last edited by

                          Please post your new 10 last lines

                          shinya.ta 1 Reply Last reply Reply Quote 0
                          • shinya.ta
                            shinya.ta @cvp last edited by

                            @cvp

                            if (x+d+dd) > w:
                                        x = dd
                                        y = y + d + dd
                                vv.frame = (0,0,w,h)
                                vv_array.append(vv)
                            
                            i_set = 0
                            #nextSet(vv_array[n_sets-1]['nextSet'])  # display 1st setet)
                            
                            v.present('sheet')
                            tv.selected_range = (0,0)
                            tv.begin_editing()```
                            
                            
                            
                                if (y+d+dd) > h:
                                    h = y + d + dd
                                vv.add_subview(b)
                                x = x + d + dd
                                if (x+d+dd) > w:
                                    x = dd
                                    y = y + d + dd
                            vv.frame = (0,0,w,h)
                            vv_array.append(vv)
                            

                            i_set = 0
                            nextSet(vv_array[n_sets-1]['nextSet']) # display 1st setet)

                            v.present('sheet')
                            tv.selected_range = (0,0)
                            tv.begin_editing()

                            Insert Code Here
                            
                            1 Reply Last reply Reply Quote 0
                            • shinya.ta
                              shinya.ta @cvp last edited by

                              @cvp

                              The "indentation error" will appear.

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

                                The error results from your lines not being well-aligned
                                Unindenting the x=... and y=... lines should fix it

                                shinya.ta 1 Reply Last reply Reply Quote 0
                                • shinya.ta
                                  shinya.ta @cvp last edited by

                                  @cvp

                                  I'm sorry. The second code is wrong.

                                  1 Reply Last reply Reply Quote 0
                                  • shinya.ta
                                    shinya.ta @Olaf last edited by

                                    @Olaf

                                    I'm a beginner, so I don't know which line I should go.

                                    cvp 1 Reply Last reply Reply Quote 0
                                    • cvp
                                      cvp @shinya.ta last edited by

                                      @shinya.ta your modified code is here

                                      shinya.ta 1 Reply Last reply Reply Quote 0
                                      • shinya.ta
                                        shinya.ta @cvp last edited by

                                        @cvp

                                        I can't use the existing keyboard because it is hidden.
                                        There is no change between the beginning and the change.

                                        cvp 1 Reply Last reply Reply Quote 0
                                        • cvp
                                          cvp @shinya.ta last edited by cvp

                                          @shinya.ta It's sure that there is a modification between beginning and this last script...
                                          The 4th one before end of script is commented to use the standard keyboard

                                          Or I don't understand your request, in this case, sorry

                                          shinya.ta 1 Reply Last reply Reply Quote 0
                                          • shinya.ta
                                            shinya.ta @cvp last edited by

                                            @cvp

                                            Can I use this script only in the frame of the keyboard?
                                            Do I need to change my size?

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