Instantly share code, notes, and snippets.
-
Save anonymous/5e5cff66dbf585b70b901e3261b32555 to your computer and use it in GitHub Desktop.
StatusBarMenu for iPhone 5s.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' StatusBarMenu | |
A menu that lives in the status bar | |
A set of tools to add or delete custom buttons from the toolbar. This may not be super robust, but seems to work ok. Button objects and actions are saved so they survive global clearing, but thid has not been tested extensively. If a function relies on imports that occured outside of the function, these might dissappear -- user must make sure those modules are added to a module that is kept by pythonista, such as anything in site-packages, or name starting with __ | |
+by @JonB (Pythonista forum) | |
-slightly modified by @Matteo (Pythonista forum), with Label hint by @cvp (Pythonista forum) | |
Tested on iPhone 5s | |
''' | |
from objc_util import * | |
import ui,console,editor | |
import weakref | |
from functools import partial | |
try: | |
__s.teardown() | |
del __s | |
except NameError: | |
pass | |
class StatusBarOverlay(object): | |
def __init__(self): | |
app=UIApplication.sharedApplication() | |
self.bar=app.statusBar() | |
b=self.bar.bounds() | |
self.overlay1=ui.View(frame=(b.origin.x,b.origin.y,20,b.size.height+12)) | |
self.overlay2=ui.View(frame=(b.origin.x,b.origin.y,20,b.size.height+12)) | |
self.overlay1.flex='t' | |
self.overlay1.y=-self.overlay1.height | |
self.overlay2.flex='t' | |
self.overlay2.y=-self.overlay2.height | |
self.overlay1.border_width=1 | |
self.overlay1.corner_radius=5 | |
self.overlay2.border_width=1 | |
self.overlay2.corner_radius=5 | |
btn=ui.Button(frame=(0,0,50,20)) | |
btn.height=25+1 | |
btn.width=60-1 | |
btn.flex='l' | |
btn.alpha=.6 | |
btn.x=b.size.width-55 | |
btn.action=self.toggleBar | |
with ui.ImageContext(50,25) as ctx: | |
p=ui.Path() | |
p.move_to(0,0) | |
p.move_to(30,0) | |
p.line_to(52,20) | |
p.line_to(50,0) | |
p.line_width=4 | |
p.close() | |
ui.set_color((1,0,0,1)) | |
p.stroke() | |
p.fill() | |
btn.image=ctx.get_image() | |
self.btn=btn | |
self.overlay1.bg_color='white' | |
self.overlay2.bg_color='white' | |
self.expanded=False | |
self.bar.addSubview_(btn) | |
self.overlay1.x=self.btn.x+50 | |
self.overlay1.x0=11 | |
self.overlay1.bring_to_front | |
self.overlay2.x=self.btn.x+50 | |
self.overlay2.x0=11 | |
self.overlay2.bring_to_front | |
self.btn.bring_to_front | |
self.bar.superview().addSubview_(self.overlay2) | |
self.bar.superview().addSubview_(self.overlay1) | |
def toggleBar(self,sender): | |
''' display self.overlay''' | |
import ui | |
if self.expanded: #hide | |
def ani(): | |
self.overlay1.x=self.btn.x-self.overlay1.x0 | |
self.overlay1.y=-self.overlay1.height | |
self.overlay2.x=self.btn.x-self.overlay2.x0 | |
self.overlay2.y=-self.overlay2.height | |
else: #show | |
def ani(): | |
self.overlay1.x=self.btn.x-self.overlay1.x0+5 | |
self.overlay1.y=0 | |
self.overlay2.x=self.btn.x-self.overlay2.x0+5 | |
self.overlay2.y=32 | |
self.expanded=not (self.expanded) | |
ui.animate(ani,.25) | |
def add_action1(self,action,title=None,image=None): | |
'''adds a button to the overlay1, at next position''' | |
b=ui.Button(title=None,image=image,action=action) | |
b.size_to_fit() | |
self.overlay1.add_subview(b) | |
# Label hint by cvp: | |
lbl = ui.Label() | |
lbl.frame = (0,0,b.width,b.height) | |
lbl.font = ('<System-Bold>',10) | |
lbl.text = title | |
b.add_subview(lbl) | |
b.x=self.overlay1.x0 | |
self.overlay1.x0+=b.width+11 | |
self.overlay1.width=self.overlay1.x0 | |
self.overlay1.x=self.btn.x-self.overlay1.x0-11 | |
def add_action2(self,action,title=None,image=None): | |
'''adds a button to the overlay2, at next position''' | |
b=ui.Button(title=None,image=image,action=action) | |
b.size_to_fit() | |
self.overlay2.add_subview(b) | |
# Label hint by cvp: | |
lbl = ui.Label() | |
lbl.frame = (0,0,b.width,b.height) | |
lbl.font = ('<System-Bold>',10) | |
lbl.text = title | |
b.add_subview(lbl) | |
b.x=self.overlay2.x0 | |
self.overlay2.x0+=b.width+11 | |
self.overlay2.width=self.overlay2.x0 | |
self.overlay2.x=self.btn.x-self.overlay2.x0-11 | |
@on_main_thread | |
def teardown(self): | |
'''cleanup...''' | |
self.overlay1.objc_instance.removeFromSuperview() | |
self.overlay2.objc_instance.removeFromSuperview() | |
self.btn.objc_instance.removeFromSuperview() | |
def __del__(self): | |
self.teardown() | |
#for debug only: | |
app=UIApplication.sharedApplication() | |
bar=app.statusBar() | |
# BEGIN Actions: | |
def a(sender): | |
print('action from bar1') | |
def b(sender): | |
print('action from bar2') | |
# END Actions. | |
__s=StatusBarOverlay() #dunder retains in globals... | |
__s.add_action1(a,'xxxxx',ui.Image.named('iow:arrow_resize_32')) | |
__s.add_action1(a,'xxxxx',ui.Image.named('iow:arrow_up_a_32')) | |
__s.add_action1(a,'xxxxx',ui.Image.named('iow:beaker_32')) | |
__s.add_action1(a,'xxxxx',ui.Image.named('iow:arrow_swap_32')) | |
__s.add_action1(a,'xxxxx',ui.Image.named('iow:briefcase_32')) | |
__s.add_action1(a,'xxxxx',ui.Image.named('iow:code_working_32')) | |
__s.add_action2(b,'xxxxx',ui.Image.named('iow:alert_circled_32')) | |
__s.add_action2(b,'xxxxx',ui.Image.named('iow:arrow_down_a_32')) | |
__s.add_action2(b,'xxxxx',ui.Image.named('iow:arrow_down_b_32')) | |
__s.add_action2(b,'xxxxx',ui.Image.named('iow:arrow_expand_32')) | |
__s.add_action2(b,'xxxxx',ui.Image.named('iow:arrow_graph_up_left_32')) | |
__s.add_action2(b,'xxxxx',ui.Image.named('iow:arrow_left_b_32')) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment