@Zoot (not so) quick and (as usual) dirty script to allow a split screen with local documentation and console REPL mode, thus without needing split view of Pythonista and Safari.
top right buttons = navigation in doc
main view is presented as sheet to allow transparency
as console command and output area is overriden by main view,
their buttons are actionned by user buttons at bottom left
1) edit button to put cursor in command textfield
2) previous and next history
y-position of user buttons change when keyboard (dis)appears
program automatically sets console in partial screen
Please, try and give me some feedback.
Thanks
And, one more time, this app is marvelous, you can (almost) do anything
import console
import editor
from objc_util import *
import ui
@on_main_thread
def setConsolePartialScreen():
global next_OMTextView_is_console
win = ObjCClass('UIApplication').sharedApplication().keyWindow()
main_view = win.rootViewController().view()
ret = ''
next_OMTextView_is_console = False
def analyze(v,indent):
global next_OMTextView_is_console, console_width,console_view, b_prev, b_next
ret = None
for sv in v.subviews():
#print(indent,sv._get_objc_classname())
if 'UILabel' in str(sv._get_objc_classname()):
next_OMTextView_is_console = str(sv.text()) == '>'
elif 'OMTextView' in str(sv._get_objc_classname()):
if next_OMTextView_is_console:
# this sv is the console TextView
console_view = sv
console_width = sv.size().width
elif 'UIImageView' in str(sv._get_objc_classname()):
# <UIImage:0x281108240 named(main: DockAccessoryPanel) {28, 28}>
#print(sv.image())
if 'DockAccessoryPanel' in str(sv.image()):
b = sv.superview() # button of ImageView
if console_width >= (ui.get_screen_size()[0]/3):
# simulate tap the partial/full console button
UIControlEventTouchUpInside = 255
b.sendActionsForControlEvents_(UIControlEventTouchUpInside)
return True
elif 'HistoryPrev' in str(sv.image()):
b_prev = sv.superview() # button of ImageView
elif 'HistoryNext' in str(sv.image()):
b_next = sv.superview() # button of ImageView
ret = analyze(sv,indent+' ')
if ret:
return ret
ret = analyze(main_view,'')
return ret
class my_View(ui.View):
global console_view, b_prev, b_next
def __init__(self):
# set Console in mode partial screen
setConsolePartialScreen()
#print(dir(console_view))
# build a transparent view
self.border_color = 'red'
self.border_width = 2
w,h = ui.get_screen_size()
self.background_color = (1,1,1,0)
self.frame = (0,0,w,h)
self.name = 'split-screen: Console REPL and doc viewer'
# webview with local doc in left part of screen
evw = editor._get_editor_tab().editorView().size().width
self.b_y = h-130
wv = ui.WebView(name='wv')
wv.frame =(0,0,evw,self.b_y)
wv.load_url('zip:///private/var/containers/Bundle/Application/34BAEE1A-BC33-4D6F-A0C1-B733E4991F31/Pythonista3.app/Documentation.zip/py3/index.html')
self.add_subview(wv)
bi_back = ui.ButtonItem(image=ui.Image.named('iob:ios7_arrow_back_32'))
bi_back.action = self.go_back
bi_forward = ui.ButtonItem(image=ui.Image.named('iob:ios7_arrow_forward_32'))
bi_forward.action = self.go_forward
self.right_button_items = [bi_forward, bi_back]
# I don't know why but console history buttons are not accessible, thus I create user buttons with action = tapping real buttons
b_bg = ui.View()
b_bg.frame = (0,self.b_y,evw,h-self.b_y)
b_bg.background_color = 'white'
self.add_subview(b_bg)
b_command = ui.Button(name='b_command')
b_command.frame = (evw-150,self.b_y,24,24)
b_command.image = ui.Image.named('iob:compose_32')
b_command.action = self.b_command_action
self.add_subview(b_command)
b_prev_hist = ui.Button(name='b_prev_hist')
b_prev_hist.frame = (evw-70,self.b_y,24,24)
b_prev_hist.image = ui.Image.named('iob:chevron_down_32')
b_prev_hist.action = self.b_prev_hist_action
self.add_subview(b_prev_hist)
b_next_hist = ui.Button(name='b_next_hist')
b_next_hist.frame = (evw-30,self.b_y,24,24)
b_next_hist.image = ui.Image.named('iob:chevron_up_32')
b_next_hist.action = self.b_next_hist_action
self.add_subview(b_next_hist)
# advance one line because first is hidden
print('')
def go_back(self,sender):
self['wv'].go_back()
def go_forward(self,sender):
self['wv'].go_forward()
def b_command_action(self,sender):
# edit command textfield
console_view.becomeFirstResponder()
def b_prev_hist_action(self,sender):
# simulate tap the previous console history button
UIControlEventTouchUpInside = 255
b_prev.sendActionsForControlEvents_(UIControlEventTouchUpInside)
def b_next_hist_action(self,sender):
# simulate tap the next console history button
UIControlEventTouchUpInside = 255
b_next.sendActionsForControlEvents_(UIControlEventTouchUpInside)
def keyboard_frame_did_change(self, frame):
# Called when the on-screen keyboard appears/disappears
# Note: The frame is in screen coordinates.
kbd_height = frame[3]
self['b_command'].y = self.b_y - kbd_height
self['b_prev_hist'].y = self.b_y - kbd_height
self['b_next_hist'].y = self.b_y - kbd_height
#print('keyboard_frame_did_change',frame)
def main():
global console_view, b_prev, b_next
v = my_View()
v.present('sheet')
if __name__ == "__main__":
main()
