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.


    Braille application.

    Pythonista
    6
    334
    212715
    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

      I am thinking of an application to input text using Braille.

      I'm thinking about Braille in Japanese.

      Is it possible for Pythonisa?

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

        Have you looked at the built in braile input?

        https://support.apple.com/guide/iphone/type-onscreen-braille-using-voiceover-iph10366cc30/ios

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

          @shinya.ta Does the iOS standard Braille also support Japanese Braille like Wikipedia?

          If not, do you want to entirely write yourself a script to allow Japanese Braille input in Pythonista? If this is the case, could you describe how you imagine that?

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

            @shinya.ta Please, try this, with these remarks:

            • I really don't know nor Japonese, nor Braille, thus...
            • this script is obviously quick and dirty, only to show what is possible
            • positions of the 6 buttons could be parametrized for each user
              1 4
              2 5
              3 6
            • standard keyboard could be removed or replaced by some keys (left delete...)
            • I only can test on iPad, sorry if not works on iPhone
            • the script needs Gestures of @mikael, our Ukko Ylijumala from Finland 😀
            • use of 3 fingers needs you disable Settings/General/Accessibilty/Zoom
            • it only supports a few points combinations for testing
              but you can easily add other ones
            	Japanese_Braille = {
            		'1':'あ',
            		'12':'い',
            		'14':'う',
            		'124':'え',
            		'24':'お',
            		'16':'か',
            		'1246':'け'
            		}
            
            • I'm ready do continue the script development, with your requests, but at my speed and availability
            import ui
            from objc_util import *
            from Gestures import Gestures
            
            def SetTextFieldPad(tf, pad=None, clearButtonMode=False, undo_redo_pasteBarButtons=False, textfield_did_change=None):
            	if not pad:
            		pad = [
            		{'key':'1','x':2,'y':1},
            		{'key':'2','x':2,'y':2},
            		{'key':'3','x':2,'y':3},
            		{'key':'4','x':5,'y':1},
            		{'key':'5','x':5,'y':2},
            		{'key':'6','x':5,'y':3},
            
            		]
            	Japanese_Braille = {
            		'1':'あ',
            		'12':'い',
            		'14':'う',
            		'124':'え',
            		'24':'お',
            		'16':'か',
            		'1246':'け'
            		}
            	tfo = ObjCInstance(tf).textField() # UITextField is subview of ui.TextField
            	
            	def key_pressed(key):
            			if key not in Japanese_Braille:
            				return
            			ch = Japanese_Braille[key]
            			cursor = tfo.offsetFromPosition_toPosition_(tfo.beginningOfDocument(), tfo.selectedTextRange().start())
            			tf.text = tf.text[:cursor] + ch + tf.text[cursor:]
            			cursor = cursor + 1
            				
            			if textfield_did_change:
            				textfield_did_change(tfb)
            				
            			# set cursor
            			cursor_position = tfo.positionFromPosition_offset_(tfo.beginningOfDocument(), cursor)
            			tfo.selectedTextRange = tfo.textRangeFromPosition_toPosition_(cursor_position, cursor_position)
            			
            	def tapped(data):
            		#print('tapped',data.number_of_touches)
            		#print(len(data.recognizer.touches()))
            		bs = []
            		for t in data.recognizer.touches():
            			pt = t.locationInView_(ObjCInstance(v))
            			for b in v.subviews:
            				r = b.width/2
            				x = b.x + r
            				y = b.y + r
            				if ((pt.x-x)**2+(pt.y-y)**2) <= r**2:
            					# touch in circle of button
            					if b.name not in bs:
            						# avoid two times same button
            						bs.append(b.name)
            		if len(bs) != data.number_of_touches:
            			# at least one touch outside buttons, no way to recognize
            			return
            		seq = ''
            		for b in sorted(bs):
            			seq = seq + b
            		key_pressed(seq)
            
            	# design your keyboard
            
            	v = ui.View()
            	v.border_color = 'red'
            	v.border_width = 4
            	w,h = ui.get_screen_size()
            	h = h - 350
            	db = w/6 
            	dd = (h-3*db)/4
            	y_max = 0
            
            	for pad_elem in pad:
            		b = ui.Button()
            		b.name = pad_elem['key']
            		b.background_color = (1,0,0,0.5)
            		b.tint_color = 'red'
            		b.font = ('Academy Engraved LET',36)
            		b.corner_radius = db/2
            		b.title = b.name
            		x = (pad_elem['x']-1)*db
            		y = dd + (pad_elem['y']-1)*(db+dd)
            		b.frame = (x,y,db,db)
            		b.TextField = tf # store tf as key attribute  needed when pressed
            		b.enabled = False
            		v.add_subview(b)
            		y_max = max(y_max,y+db+dd)
            
            	v.width = ui.get_screen_size()[0]
            	v.height = h
            	g = Gestures()
            	for n in range(1,7):
            		g.add_tap(v, tapped,number_of_touches_required=n)
            
            	# view of keyboard
            	retain_global(v) # see https://forum.omz-software.com/topic/4653/button-action-not-called-when-view-is-added-to-native-view
            	tfo.setInputAccessoryView_(ObjCInstance(v))	# attach accessory to textview
            	#print(dir(tfo))
            
            if __name__ == '__main__':		
            	import ui 
            	tf = ui.TextField()
            	SetTextFieldPad(tf)
            	tf.text = ''
            	tf.width = 200
            	tf.name = 'Japanese Braille'
            	tf.present('sheet')
            	tf.begin_editing()
            	tf.wait_modal()
            

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

              Special gestures can also be added like in standard IOS Braille.
              For example, here-after:

              • swipe from right to left to back space, delete at left
              • swipe from left to right to add a space
              • swipe from bottom to top with 3 fingers to return and dismiss the keyboard

              Sorry to post two similar scripts so, next time, if any, I would post it on GitHub

              import ui
              from objc_util import *
              from Gestures import Gestures
              
              def SetTextFieldPad(tf, pad=None, clearButtonMode=False, undo_redo_pasteBarButtons=False, textfield_did_change=None):
              	if not pad:
              		pad = [
              		{'key':'1','x':2,'y':1},
              		{'key':'2','x':2,'y':2},
              		{'key':'3','x':2,'y':3},
              		{'key':'4','x':5,'y':1},
              		{'key':'5','x':5,'y':2},
              		{'key':'6','x':5,'y':3},
              
              		]
              	Japanese_Braille = {
              		'1':'あ',
              		'12':'い',
              		'14':'う',
              		'124':'え',
              		'24':'お',
              		'16':'か',
              		'1246':'け'
              		}
              	tfo = ObjCInstance(tf).textField() # UITextField is subview of ui.TextField
              	
              	def key_pressed(key):
              			cursor = tfo.offsetFromPosition_toPosition_(tfo.beginningOfDocument(), tfo.selectedTextRange().start())
              			if key == 'back space':
              				if cursor > 0:
              					#if tfb.text != '':
              					tf.text = tf.text[:cursor-1] + tf.text[cursor:]
              					cursor = cursor - 1
              			elif key == 'return':
              				tf.end_editing()
              				return
              			elif key == ' ':
              				ch = ' '
              				tf.text = tf.text[:cursor] + ch + tf.text[cursor:]
              				cursor = cursor + 1
              			elif key not in Japanese_Braille:
              				return
              			else:
              				ch = Japanese_Braille[key]
              				tf.text = tf.text[:cursor] + ch + tf.text[cursor:]
              				cursor = cursor + 1
              				
              			if textfield_did_change:
              				textfield_did_change(tfb)
              				
              			# set cursor
              			cursor_position = tfo.positionFromPosition_offset_(tfo.beginningOfDocument(), cursor)
              			tfo.selectedTextRange = tfo.textRangeFromPosition_toPosition_(cursor_position, cursor_position)
              			
              	def tapped(data):
              		#print('tapped',data.number_of_touches)
              		#print(len(data.recognizer.touches()))
              		bs = []
              		for t in data.recognizer.touches():
              			pt = t.locationInView_(ObjCInstance(v))
              			for b in v.subviews:
              				r = b.width/2
              				x = b.x + r
              				y = b.y + r
              				if ((pt.x-x)**2+(pt.y-y)**2) <= r**2:
              					# touch in circle of button
              					if b.name not in bs:
              						# avoid two times same button
              						bs.append(b.name)
              		if len(bs) != data.number_of_touches:
              			# at least one touch outside buttons, no way to recognize
              			return
              		seq = ''
              		for b in sorted(bs):
              			seq = seq + b
              		key_pressed(seq)
              
              	# like IOS left swipe: delete at left		
              	def left_swipe_handler(data):
              		key_pressed('back space')
              		
              	# like IOS right swipe: space		
              	def right_swipe_handler(data):
              		key_pressed(' ')
              		
              	# like IOS up swipe with 3 fingers: return
              	def up_swipe_handler(data):
              		key_pressed('return')
              
              	# design your keyboard
              
              	v = ui.View()
              	v.border_color = 'red'
              	v.border_width = 4
              	w,h = ui.get_screen_size()
              	h = h - 350
              	db = w/6 
              	dd = (h-3*db)/4
              	y_max = 0
              
              	for pad_elem in pad:
              		b = ui.Button()
              		b.name = pad_elem['key']
              		b.background_color = (1,0,0,0.5)
              		b.tint_color = 'red'
              		b.font = ('Academy Engraved LET',36)
              		b.corner_radius = db/2
              		b.title = b.name
              		x = (pad_elem['x']-1)*db
              		y = dd + (pad_elem['y']-1)*(db+dd)
              		b.frame = (x,y,db,db)
              		b.TextField = tf # store tf as key attribute  needed when pressed
              		b.enabled = False
              		v.add_subview(b)
              		y_max = max(y_max,y+db+dd)
              
              	v.width = ui.get_screen_size()[0]
              	v.height = h
              	g = Gestures()
              	for n in range(1,7):
              		g.add_tap(v, tapped,number_of_touches_required=n)
              	g.add_swipe(v, left_swipe_handler, direction = Gestures.LEFT)
              	g.add_swipe(v, right_swipe_handler, direction = Gestures.RIGHT)
              	g.add_swipe(v, up_swipe_handler, direction = Gestures.UP, number_of_touches_required=3)
              
              	# view of keyboard
              	retain_global(v) # see https://forum.omz-software.com/topic/4653/button-action-not-called-when-view-is-added-to-native-view
              	tfo.setInputAccessoryView_(ObjCInstance(v))	# attach accessory to textview
              	#print(dir(tfo))
              
              if __name__ == '__main__':		
              	import ui 
              	tf = ui.TextField()
              	SetTextFieldPad(tf)
              	tf.text = ''
              	tf.width = 200
              	tf.name = 'Japanese Braille'
              	tf.present('sheet')
              	tf.begin_editing()
              	tf.wait_modal()
              
              1 Reply Last reply Reply Quote 0
              • cvp
                cvp last edited by cvp

                Version without standard keyboard is Braille_Input.py

                Don't forget to swipe with 3 fingers from bottom to top to dismiss the (Braille) keyboard

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

                  @JonB

                  My wife is having trouble using the rotor function, so I've been thinking about a special application.

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

                    @cvp

                    Dear.cvp

                    I tried on my iPhone, but the third line of the ModuleNotFoundError comes out.

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

                      @shinya.ta It uses a module that you have to import and copy in your site-packages folder: Gestures

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

                        @shinya.ta Other version here

                        • version without Gestures module (see here-after for the reason)

                        • while at least one finger stays on screen, another one may "arrive"

                        • move of fingers allowed, not only a tap

                        • character only added when all fingers leave the screen

                        • speech of added character could be programmed but does not work actually

                        • special sound could be played when a finger arrives or leave a circle

                        • position of circles could be changed and stored per device and orientation

                        • ... waiting for your requests

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

                          @shinya.ta The GitHub BrailleInput2.py now supports

                          • put 6 fingers on the screen and move them to position the circles where you want.
                            • you may move until all fingers leave the screen
                          • the positions will be automatically saved in keychain memory of your device, for the current orientation, either portrait, either landscape.
                          • the saved positions will be reused at next run

                          That will say that, actually, the character using the 6 dots is not supported. In a close future, I'll try to distinguish between this operation and the 6 dots character.

                          I'm still waiting for some feedback from you, even very negative if I didn't understand how your wife could use it.

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

                            @shinya.ta Six dots character (め) also supported now.
                            Setting of the circles positions needs to put six fingers on the screen, where you want, during at least 3 seconds.
                            The six dots character needs 6 fingers in the circles, during less than 3 seconds.

                            Of course, if this way to process is unusable, let me know how to do.

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

                              @cvp

                              Dear.cvp

                              I tried a new version.
                              Another problem has come up.
                              The application cannot be shut down.

                              That's why you can't open any other Pythonisa apps.

                              What should I do?

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

                                @shinya.ta As I said previously, you have to swipe 3 fingers up to close the keyboard.
                                And after, the x button is available to close the script.

                                But, first, use of 3 fingers needs you disable Settings/General/Accessibilty/Zoom.

                                Edit: if you prefer another gesture, let me know, but this is the standard IOS Braille gesture to simulate a return key, thus dismiss the keyboard.

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

                                  @cvp

                                  My wife is used to closing buttons.

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

                                    @shinya.ta Yes, but in the Braille keyboard with only 6 circles, where do you want to put a close button, and you want that this button dismisses the keyboard, please confirm!

                                    And, please, don't forget that this script is only a starting point to show what could be done.
                                    You have to do your job also 😀, that will say explain your requests.
                                    My little script creates a code for any TextField. I don't know how or where you want to use this kind of Braille keyboard.

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

                                      @shinya.ta Just added a "close keyboard button" in the GitHub version BrailleInput2.py

                                      Don't hesitate to ask any change but don't hope a quick answer today.
                                      Easter Monday is a bank holiday in Belgium and all my children and grandchildren come for the lunch 🍾

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

                                        @cvp

                                        Dear.cvp

                                        I'll ask my wife to use it on the weekend.

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

                                          @shinya.ta new version:

                                          • rename module into BrailleKeyboardForTextField.py
                                          • rename some functions and classes
                                          • define all characters in Japanese Braille dictionnary with comment showing dots, like:
                                          		'156':'さ',		# ⠱
                                          		'1256':'し',		# ⠳
                                          		'1456':'す',		# ⠹
                                          		'12456':'せ',	# ⠻
                                          		'2456':'そ',		# ⠺
                                          
                                          • displaying tapped dots, dots symbol and character outside TextField name
                                          1 Reply Last reply Reply Quote 1
                                          • cvp
                                            cvp @shinya.ta last edited by

                                            @shinya.ta No news, good news?

                                            shinya.ta 4 Replies Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Powered by NodeBB Forums | Contributors