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.

Best posts made by 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() ```
-
RE: ui.View Update
@mikael, Perfect ππππ
Thank you very much, I would find it hard to do without Scripter!
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 !
-
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 !
-
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 !
-
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 !
-
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 ?
-
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.
-
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 ```
-
RE: Pythonista special key row problems in IOS 14
@cvp Thanks a lot ! Iβm happy to see that I progress slowlyβ¦
I had foundtextView().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 openeditor.py
in thesite-packages
ofStandard Library
?
It's very instructive π€, I'm going to end up managing on my own. π