|
"""Modified version of my file picker to work with unextracted zip files. Modified |
|
to show both files and directories, as well as executing an action every time a |
|
file is tapped instead of selecting one and then finishing.""" |
|
|
|
import ui, os, console |
|
from zipfile import ZipFile |
|
from FileListOps import * |
|
|
|
class DropDown(ui.View): |
|
def __init__(self,p,level,filelist,parent=None,frame=None,width=None,x=None,y=None): |
|
self.path = p |
|
self.fl = filelist |
|
|
|
self.subDirs = getSubDirs(self.fl,self.path) |
|
self.subFiles = getSubFiles(self.fl,self.path) |
|
|
|
self.open = False |
|
|
|
self.level=level |
|
|
|
self.arrowClosed = ui.Image.named('iob:ios7_arrow_right_32') |
|
self.arrowOpened = ui.Image.named('iob:ios7_arrow_down_32') |
|
self.folderIcon = ui.Image.named('iob:ios7_folder_outline_32') |
|
|
|
self.children = [] |
|
self.ydent = 0 |
|
|
|
self.above = [] |
|
self.below = [] |
|
|
|
self.selected = 0 |
|
|
|
indent=32*self.level |
|
|
|
self.arrow=ui.ImageView(frame=(indent,4,32,32)) |
|
self.arrow.image = self.arrowOpened if self.open else self.arrowClosed |
|
self.add_subview(self.arrow) |
|
|
|
self.folder=ui.ImageView(frame=(indent+32,4,32,32)) |
|
self.folder.image = self.folderIcon |
|
self.add_subview(self.folder) |
|
|
|
self.text=ui.Label(frame=(indent+75,4,300,32)) |
|
self.text.text = str(os.path.abspath(self.path)).split('/')[-1] |
|
self.text.font=('AvenirNext-Light',20) |
|
self.add_subview(self.text) |
|
|
|
|
|
def draw(self): |
|
|
|
self.height = 40 |
|
self.y = 40*len(self.superview.subviews[:self.superview.subviews.index(self)])+self.ydent*40 |
|
self.x = 0 |
|
self.width = self.superview.width |
|
|
|
|
|
maxscroll = max(x.y+40 for x in self.superview.subviews) |
|
self.superview.content_size = (0, maxscroll) |
|
|
|
def should_open(self): |
|
self.arrow.image = self.arrowOpened |
|
self.open = not self.open |
|
|
|
self.above = [x for x in self.superview.subviews if x.y < self.y] |
|
self.below = [x for x in self.superview.subviews if x.y > self.y] |
|
|
|
for sd in self.subDirs: |
|
self.children.append(DropDown(sd, self.level+1, self.fl)) |
|
self.superview.add_subview(self.children[-1]) |
|
self.children[-1].ydent -= len(self.below) |
|
|
|
for sd in self.subFiles: |
|
self.children.append(File(sd, self.level+1)) |
|
self.superview.add_subview(self.children[-1]) |
|
self.children[-1].ydent -= len(self.below) |
|
|
|
|
|
for b in self.below: |
|
b.ydent += len(self.children) |
|
b.draw() |
|
|
|
def should_collapse(self): |
|
self.arrow.image = self.arrowClosed |
|
self.open = not self.open |
|
|
|
for sd in self.children: |
|
if sd.selected: |
|
self.superview.superview.deselect() |
|
sd.should_collapse() |
|
self.superview.remove_subview(sd) |
|
|
|
self.above = [x for x in self.superview.subviews if x.y < self.y] |
|
self.below = [x for x in self.superview.subviews if x.y > self.y] |
|
|
|
for b in set(self.below)-set(self.children): |
|
|
|
b.ydent -= len(self.children) |
|
b.draw() |
|
|
|
self.children = [] |
|
|
|
def select(self): |
|
self.superview.superview.select(self) |
|
|
|
def touch_began(self, touch): |
|
if not self.selected: |
|
self.background_color = .88, .88, .88 |
|
self.selectCanditate=False |
|
x, y = touch.location |
|
|
|
a=self.arrow |
|
arrowBounds = list(a.frame[:2]) + [a.x+a.width,a.y+a.height] |
|
if x > arrowBounds[0]-20 and x < arrowBounds[2]+20: |
|
if self.open: |
|
self.should_collapse() |
|
else: |
|
self.should_open() |
|
else: |
|
self.selectCanditate=True |
|
self.initialTouch = touch.location |
|
|
|
def touch_ended(self, touch): |
|
if not self.selected: |
|
self.background_color = 1.0, 1.0, 1.0 |
|
x, y = touch.location |
|
px, py = self.initialTouch |
|
if self.selectCanditate and abs(x-px) < 5 and abs(y-py) < 5: |
|
self.select() |
|
|
|
class File(ui.View): |
|
def __init__(self, name, level): |
|
self.selected=False |
|
self.path = name |
|
self.level=level |
|
self.ydent=0 |
|
self.docIcon = ui.Image.named('iob:document_32') |
|
indent=32*self.level |
|
|
|
self.file=ui.ImageView(frame=(indent+32,4,32,32)) |
|
self.file.image = self.docIcon |
|
self.add_subview(self.file) |
|
|
|
self.text=ui.Label(frame=(indent+75,4,300,32)) |
|
self.text.text = name.split("/")[-1] |
|
self.text.font=('AvenirNext-Light',20) |
|
self.add_subview(self.text) |
|
|
|
def draw(self): |
|
self.height = 40 |
|
self.y = 40*len(self.superview.subviews[:self.superview.subviews.index(self)])+self.ydent*40 |
|
self.x = 0 |
|
self.width = self.superview.width |
|
maxscroll = max(x.y+40 for x in self.superview.subviews) |
|
self.superview.content_size = (0, maxscroll) |
|
|
|
def should_collapse(self): |
|
pass |
|
|
|
def touch_began(self, touch): |
|
if not self.selected: |
|
self.background_color = .88, .88, .88 |
|
self.initialTouch = touch.location |
|
|
|
def touch_ended(self, touch): |
|
if not self.selected: |
|
self.background_color = 1.0, 1.0, 1.0 |
|
x, y = touch.location |
|
px, py = self.initialTouch |
|
if abs(x-px) < 5 and abs(y-py) < 5: |
|
self.select() |
|
|
|
|
|
def select(self): |
|
self.superview.superview.select(self) |
|
|
|
|
|
class SVDelegate: |
|
def scrollview_did_scroll(self, sv): |
|
for sub in sv.subviews: |
|
if not sub.selected: |
|
sub.background_color = 1.0, 1.0, 1.0 |
|
yscroll=sv.content_offset[1] |
|
|
|
class FilePicker(ui.View): |
|
def __init__(self,path,handle,frame=(0,0,500,500),background_color=(1.0, 1.0, 1.0)): |
|
self.files = ZipFile(path).namelist() |
|
for i,f in enumerate(self.files): |
|
self.files[i]=path+"/"+f |
|
self.background_color=background_color |
|
self.frame=frame |
|
self.scroll=ui.ScrollView(frame=(0,0,self.width,self.height)) |
|
self.scroll.delegate = SVDelegate() |
|
self.scroll.add_subview(DropDown(path,0,self.files)) |
|
self.add_subview(self.scroll) |
|
|
|
self.handle=handle |
|
|
|
def select(self,view): |
|
self.handle(view.path) |
|
|
|
|
|
def getFileName(dir,title=''): |
|
"""Example function that displays a file picker and returns the result""" |
|
global selected |
|
selected = None |
|
|
|
def handle(result): |
|
print result |
|
|
|
fp=FilePicker(dir,handle,frame=(0,0,500,500)) |
|
fp.name = title |
|
fp.right_button_items=[ui.ButtonItem(title='Done', action=lambda sender:fp.close())] |
|
fp.present('sheet') |
|
|
|
if __name__ == '__main__': |
|
getFileName('example.zip') |