omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular
    1. Home
    2. Enez Houad

    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.


    • Profile
    • Following 0
    • Followers 0
    • Topics 8
    • Posts 48
    • Best 4
    • Controversial 0
    • Groups 0

    Enez Houad

    @Enez Houad

    4
    Reputation
    1105
    Profile views
    48
    Posts
    0
    Followers
    0
    Following
    Joined Last Online
    Location Ile de Houat - FRANCE

    Enez Houad Unfollow Follow

    Best posts made by Enez Houad

    • RE: site-packages-3 in 3 3.4 (340006) beta

      @cvp Thanks a lot to you and to @omz for his unexpected but so wanted comeback !

      posted in Pythonista
      Enez Houad
      Enez Houad
    • RE: Anchor constraint updates

      @mikael Thanks for your reactivity !

      posted in Pythonista
      Enez Houad
      Enez Houad
    • RE: Pythonista special key row problems in IOS 14

      Here is my scrolling special key row to replace the standard one.
      This script is a mix between @cvpe's script AddButtonsToPythonistaKeyboard https://github.com/cvpe/Pythonista-scripts/blob/master/AddButtonsToPythonistaKeyboard.py
      and my own work.
      It uses module ui3.sfsymbol of @mikaelho https://github.com/mikaelho/ui3
      Thanks for all their work for Pythonista's community.
      It certainly contains errors as I am not an expert coder like the majority of you but it does work for me πŸ˜‰
      Feel free to improve and adapt it to your needs!

      # =================================================================
      # This script is a mix between @cvpe's script AddButtonsToPythonistaKeyboard 
      # https://github.com/cvpe/Pythonista-scripts/blob/master/AddButtonsToPythonistaKeyboard.py
      # and my own work.
      # It uses module ui3.sfsymbol of @mikaelho
      # https://github.com/mikaelho/ui3
      # 
      # enez.houad@free.fr
      # =================================================================
      
      import ui, editor, clipboard
      from objc_util import *
      from ui3.sfsymbol import *
      
      @on_main_thread
      def tv_find(tv):
      	import console, re
      	
      	tv.find = console.input_alert('Expression Γ  rechercher :', '', tv.find, hide_cancel_button=True)
      	txt = tv.find
      	
      	for sv in tv.subviews():
      		if 'SUIButton_PY3' in str(sv._get_objc_classname()):
      			sv.removeFromSuperview()
      	if txt == '':
      		return
      	t = str(tv.text())
      	
      	for m in re.finditer(txt, t):
      		st,en = m.span()
      		p1 = tv.positionFromPosition_offset_(tv.beginningOfDocument(), st)
      		p2 = tv.positionFromPosition_offset_(tv.beginningOfDocument(), en)
      		rge = tv.textRangeFromPosition_toPosition_(p1,p2)
      		rect = tv.firstRectForRange_(rge)
      		x,y = rect.origin.x,rect.origin.y
      		w,h = rect.size.width,rect.size.height
      		
      		l = ui.Button()
      		l.frame = (x,y,w,h)
      		if '|' not in txt:
      			l.background_color = (1,0,0,0.2)
      		else:
      			# search multiple strings
      			wrds = txt.split('|')
      			idx = wrds.index(t[st:en])
      			cols = [(1,0,0,0.2), (0,1,0,0.2), (0,0,1,0.2), (1,1,0,0.2), (1,0,1,0.2), (0,1,1,0.2)]
      			col = cols[idx % len(cols)]
      			l.background_color = col
      		l.corner_radius = 4
      		l.border_width = 1
      		tv.addSubview_(l)		
      	
      # β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
      
      def key_pressed(sender):
      	
      	tv = sender.objc_instance.firstResponder() # associated TextView  
      	
      	cursor = tv.offsetFromPosition_toPosition_(tv.beginningOfDocument(),     tv.selectedTextRange().start()) # get actual cursor position
      
      	if sender.name == 'tab':
      		tv.insertText_('\t')
      	
      	elif sender.name == 'paste':
      		tv.insertText_(clipboard.get())	
      		
      	elif sender.name == 'undo':
      		tv.undoManager().undo()
      		
      	elif sender.name == 'redo':
      		tv.undoManager().redo()
      	
      	elif sender.name == 'del_right':
      		# delete at right = delete at left of next
      		if cursor == (len(str(tv.text()))-1): # already after last character
      			return
      		cursor_position = tv.positionFromPosition_offset_(tv.beginningOfDocument(), cursor+1)
      		tv.selectedTextRange = tv.textRangeFromPosition_toPosition_(cursor_position, cursor_position)
      		tv.deleteBackward()		
      		
      	elif sender.name == 'find':
      		tv_find(tv)
      		
      	elif sender.name == 'line-':
      		tv.insertText_('# ' + 65 * 'β€”')
      	elif sender.name == 'line=':
      		tv.insertText_('# ' + 65 * '=')
      	elif sender.name == 'line#':
      		tv.insertText_(67 * '#')
      		
      	else: # all other keys > insert button title
      		tv.insertText_(sender.title)
      	
      # ===================================================================
      	
      class SpecialKeyRow(ui.View):
      	
      	def __init__(self, pad, *args, **kwargs):
      		
      		self.pad = pad
      	
      		sw, sh = ui.get_screen_size()	
      		self.uiStyle = ui.get_ui_style()
      		
      		self.buttonsList = []
      		self.buttonWidth = (sw - (2*8) - (24*4)) / 25
      		self.buttonHeight = 40
      		
      		# β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
      		# MAIN VIEW	
      	
      		self.width, self.height = sw, 50
      		self.alpha = 0.98
      		
      		# β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
      		# SCROLL VIEW
      		
      		sv = ui.ScrollView(name='scrollview')
      		sv.width, sv.height = (sw, 50)
      		sv.content_size = (2*sw, 50)
      		sv.bounces = False
      		sv.shows_horizontal_scroll_indicator = False
      		sv.paging_enabled = True
      		sv.x, sv.y = (0, 0)
      		colorDict = {'light':'#D6D8DD', 'dark':'#343639'}
      		sv.background_color = colorDict[self.uiStyle]
      		
      		self.add_subview(sv)
      		
      		# β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
      		# BUTTONS IN SCROLL VIEW
      		# β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
      
      		for pad_elem in self.pad:
      			if not 'style' in pad_elem: bStyle = 'light'
      			else: bStyle = pad_elem['style']
      			if 'title' in pad_elem:
      				b = self.add_text_button(name=pad_elem['key'], title=pad_elem['title'], style=bStyle)
      			elif 'symbol' in pad_elem:
      				b = self.add_symbol_button(name=pad_elem['key'], symbol_name=pad_elem['symbol'], style=bStyle)
      			self.add_scrollview_button(b)
      		
      	# ===================================================================
      		 
      	def add_scrollview_button(self, b):
      		b.y = 10
      		if self.buttonsList == []: b.x = 8 # 1er bouton
      		else:
      			lastButton = self.buttonsList[-1]
      			b.x = lastButton.x + lastButton.width + 4 # intervalle 4 px
      			if len(self.buttonsList) == 25: b.x += 12 # 2e page
      		b.action = key_pressed
      		retain_global(b)
      		self['scrollview'].add_subview(b)
      		self.buttonsList.append(b)
      			
      	# β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
      	
      	def add_text_button(self, name='', title='', width=40, style='light'):
      		b = self.add_button(name, style)
      		b.title = title
      		b.font = ('<system>', 18)
      		if width == None: b.width = ui.measure_string(b.title,font=b.font)[0] + 28
      		else: b.width = self.buttonWidth		
      		return b
      		
      	# β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
      	
      	def add_symbol_button(self, name='', symbol_name='', style='light'):
      		b = self.add_button(name, style)
      		symbol_image = SymbolImage(symbol_name, point_size=11, weight=LIGHT, scale=SMALL)
      		b.image = symbol_image	
      		b.width = self.buttonWidth	
      		return b
      		
      	# β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
      	
      	def add_button(self, name='', backgroundStyle='light'):
      		
      		b = ui.Button(name=name)
      		b.corner_radius = 8
      		
      		colorsDict = {	'light'	:({'light':'#FFFFFF', 'dark':'#B4B9C1'}, 'black'), 
      						'dark'	:({'light':'#717274', 'dark':'#4D4F50'}, 'white') }
      		b.background_color = colorsDict[self.uiStyle][0][backgroundStyle]
      		b.tint_color = colorsDict[self.uiStyle][1]
      		
      		b.alpha = self.alpha
      		
      		b.font = ('<system>', 18)
      		b.height = self.buttonHeight		
      		return b
      				
      # ===================================================================
      
      @on_main_thread
      def AddButtonsToPythonistaKeyboard(pad=None):
      	
      	def numeric_keys(): 
      		list = []
      		for i in range(1, 10):
      			list.append({'key':str(i), 'title':str(i)})
      		list.append({'key':'0', 'title':'0'})
      		return list
      		
      	if not pad:		
      		pad = [
      				{'key':'tab', 'symbol':'arrow.right.to.line.alt'},				
      			
      				{'key':'undo', 'symbol':'arrow.uturn.left', 'style':'dark'},
      				{'key':'redo','symbol':'arrow.uturn.right', 'style':'dark'},
      				
      				{'key':'paste', 'symbol':'doc.on.clipboard'},
      			
      				{'key':'#', 'title':'#'},
      				{'key':'_', 'title':'_'},
      			
      				{'key':"'", 'title':"'"},
      				{'key':'"', 'title':'"'},
      				{'key':"'''", 'title':"'''"},
      			
      				{'key':'(', 'title':'('},
      				{'key':')', 'title':')'},			
      				{'key':'[', 'title':'['},
      				{'key':']', 'title':']'},
      				{'key':'{', 'title':'{'},
      				{'key':'}', 'title':'}'},
      			
      				{'key':'+', 'title':'+'},
      				{'key':'-', 'title':'-'},
      				{'key':'*', 'title':'*'},
      				{'key':'/', 'title':'/'},
      				{'key':"\\", 'title':"\\"},
      			
      				{'key':'<', 'title':'<'},
      				{'key':'>', 'title':'>'},
      				{'key':'=', 'title':'='},
      				{'key':':', 'title':':'},
      			
      				{'key':'del_right', 'symbol':'delete.right', 'style':'dark'},
      			
      				{'key':'find', 'symbol':'magnifyingglass', 'style':'dark'}
      				]
      				
      		pad += numeric_keys() 
      		
      		pad += [
      				{'key':'+', 'title':'+'},
      				{'key':'-', 'title':'-'},
      				{'key':'*', 'title':'*'},
      				{'key':'/', 'title':'/'},
      				{'key':'<', 'title':'<'},
      				{'key':'>', 'title':'>'},
      				{'key':'=', 'title':'='},
      			
      				{'key':'line-', 'title':'---'},
      				{'key':'line=', 'title':'==='},
      				{'key':'line#', 'title':'###'}
      				]	
      		
      	ev = editor._get_editor_tab().editorView()
      	tv = ev.textView()
      	
      	v = SpecialKeyRow(pad)                        
      	vo = ObjCInstance(v)  
      
      	retain_global(v)
      	
      	tv.setInputAccessoryView_(vo)   # attach accessory to textview
      	tv.find = ''
      	
      # ===================================================================
      	
      if __name__ == '__main__':
      	AddButtonsToPythonistaKeyboard() ```
      posted in Pythonista
      Enez Houad
      Enez Houad
    • RE: ui.View Update

      @mikael, Perfect πŸ‘πŸ‘πŸ™πŸ‘
      Thank you very much, I would find it hard to do without Scripter!

      posted in Pythonista
      Enez Houad
      Enez Houad

    Latest posts made by Enez Houad

    • RE: site-packages-3 in 3 3.4 (340006) beta

      That's it, I did it! I just had forgotten to delete the original stash.launch !

      posted in Pythonista
      Enez Houad
      Enez Houad
    • RE: site-packages-3 in 3 3.4 (340006) beta

      I’ve go the obj exception :

      The app was terminated due to an Objective-C exception. Details below:

      2023-01-25 22:48:24.867065
      Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.

      But I don’t understand what it meens !

      posted in Pythonista
      Enez Houad
      Enez Houad
    • RE: site-packages-3 in 3 3.4 (340006) beta

      @cvp Yes, but on my iPad mini 4 running ipadOS 15.7.3, I get a crash when I run launch_stash.

      I’ve tried wrapping in_background as recommended with :

      import ui
      @ui.in_background()
      def launch(*args):
      _stash.launch(*args)

      launch(ns.command)

      but I still get a crash !

      posted in Pythonista
      Enez Houad
      Enez Houad
    • RE: site-packages-3 in 3 3.4 (340006) beta

      @cvp Exact, I’ve found it ! I’ve done a clean install of Pythonista 3.4 beta and at the moment I'm struggling to reinstall Slash and it's not easy ;-) but I will win !

      posted in Pythonista
      Enez Houad
      Enez Houad
    • RE: site-packages-3 in 3 3.4 (340006) beta

      @cvp Thanks a lot to you and to @omz for his unexpected but so wanted comeback !

      posted in Pythonista
      Enez Houad
      Enez Houad
    • RE: site-packages-3 in 3 3.4 (340006) beta

      @cvp So, now I need to put my own content of my old site-packages-3 in the site-packages, exact ?

      posted in Pythonista
      Enez Houad
      Enez Houad
    • site-packages-3 in 3 3.4 (340006) beta

      In 3 3.4 (340006) beta on my iPad mini 4 iPadOS 15.7.3 the folder site-packages-3 is not visible in Python Modules.

      posted in Pythonista
      Enez Houad
      Enez Houad
    • RE: Anchor constraint updates

      @mikael Thanks for your reactivity !

      posted in Pythonista
      Enez Houad
      Enez Houad
    • RE: Anchor constraint updates

      @mikael , I regularly use your modules and I thank you for it. Unfortunately, since the last version of ui3, I have an error when I want to use it.
      Here is the Traceback :

      Traceback (most recent call last):
        File "/private/var/mobile/Library/Mobile Documents/iCloud~com~omz-software~Pythonista3/Documents/ui3-master/sheet.py", line 7, in <module>
          from ui3.anchor import *
        File "/private/var/mobile/Library/Mobile Documents/iCloud~com~omz-software~Pythonista3/Documents/ui3-master/ui3/__init__.py", line 12, in <module>
          from ui3.anchor import *
        File "/private/var/mobile/Library/Mobile Documents/iCloud~com~omz-software~Pythonista3/Documents/ui3-master/ui3/anchor/__init__.py", line 821, in <module>
          via_screen,
      NameError: name 'via_screen' is not defined ```
      posted in Pythonista
      Enez Houad
      Enez Houad
    • RE: Pythonista special key row problems in IOS 14

      @cvp Thanks a lot ! I’m happy to see that I progress slowly…
      I had found textView().becomeFirstResponder() but couldn’t find to witch element it had to be applied. The _get_editor_tab is not documented ! To find it, do you open editor.py in the site-packages of Standard Library ?
      It's very instructive πŸ€“, I'm going to end up managing on my own. πŸ˜‰

      posted in Pythonista
      Enez Houad
      Enez Houad