#!python3
import ui
from objc_util import ObjCClass, ObjCInstance, ns, create_objc_class, ObjCBlock, NSData
import ctypes
import editor
import os
import zipfile
import blackmamba.runtime as runtime
from blackmamba.uikit import UITableViewCellStyle
from blackmamba.key_event import (
register_key_event_handler, unregister_key_event_handler,
UIEventKeyCodeLeftSquareBracket, UIEventKeyCodeEscape
)
from blackmamba.key_command import UIKeyModifierControl
from blackmamba.log import error
import console
_TMP_DIR = os.environ.get('TMPDIR', os.environ.get('TMP'))
NSItemProvider = ObjCClass('NSItemProvider')
UIDragItem = ObjCClass('UIDragItem')
NSError = ObjCClass('NSError')
NSItemProviderRepresentationVisibilityAll = 0
_drag_items = []
_load_data_path = None
def _type_identifier(path):
if os.path.isdir(path):
return 'public.folder'
elif os.path.isfile(path):
return 'public.data'
return None
def _suggested_name(path):
name = os.path.basename(path)
if os.path.isdir(path):
name += '.zip'
return name
def _provide_file_data(path):
data = NSData.dataWithContentsOfFile_(path)
if not data:
error('Failed to read file: {}'.format(path))
return None
return data
def _provide_folder_data(path):
saved_dir = os.getcwd()
os.chdir(os.path.dirname(path))
folder_name = os.path.basename(path)
zip_file_path = os.path.join(_TMP_DIR, '{}.zip'.format(folder_name))
if os.path.exists(zip_file_path):
os.remove(zip_file_path)
ignore_folders = ['.git']
ignore_files = ['.DS_Store']
with zipfile.ZipFile(zip_file_path, 'w') as zip:
for root, subdirs, files in os.walk(folder_name, topdown=True):
if ignore_folders:
subdirs[:] = [d for d in subdirs if d not in ignore_folders]
for file in files:
if file not in ignore_files:
zip.write(os.path.join(root, file))
os.chdir(saved_dir)
return _provide_file_data(zip_file_path)
def _provide_data(path):
if os.path.isfile(path):
return _provide_file_data(path)
elif os.path.isdir(path):
return _provide_folder_data(path)
return None
def _load_data_imp(_cmd, _block_ptr):
global _load_data_path
handler = runtime.ObjCBlockPointer(_block_ptr,
argtypes=[ctypes.c_void_p, ctypes.c_void_p])
if _load_data_path:
data = _provide_data(_load_data_path)
_load_data_path = None
else:
data = None
if not data:
error = NSError.errorWithDomain_code_userInfo_('com.robertvojta.blackmamba', 1, None)
handler(None, error)
else:
handler(data, None)
_load_data = ObjCBlock(_load_data_imp, restype=ctypes.c_void_p,
argtypes=[ctypes.c_void_p, ctypes.c_void_p])
def tableView_itemsForBeginningDragSession_atIndexPath_(_self, _cmd, tv_ptr, session_ptr, index_path_ptr):
global _load_data_path
index = ObjCInstance(index_path_ptr).row()
if index >= 0 and index < len(_drag_items):
path = _drag_items[index]['path']
type_identifier = _type_identifier(path)
if not type_identifier:
error('Failed to provide data, file does not exists?')
return ns([]).ptr
suggested_name = _suggested_name(path)
provider = NSItemProvider.alloc().init()
args = [type_identifier, NSItemProviderRepresentationVisibilityAll, _load_data]
provider.registerDataRepresentationForTypeIdentifier_visibility_loadHandler_(*args)
if not provider:
error('Failed to create item provider.')
return ns([]).ptr
if suggested_name:
provider.setSuggestedName(suggested_name)
item = UIDragItem.alloc().initWithItemProvider_(provider)
if not item:
error('Failed to create drag item.')
return ns([]).ptr
_load_data_path = path
return ns([item]).ptr
return ns([]).ptr
class DragDataSource(ui.ListDataSource):
def __init__(self, items):
super().__init__(items)
def tableview_cell_for_row(self, tableview, section, row):
item = self.items[row]
cell = ui.TableViewCell(UITableViewCellStyle.subtitle.value)
cell.text_label.text = item['title']
cell.detail_text_label.text = item['subtitle']
cell.image_view.image = ui.Image(item['image'])
cell.detail_text_label.text_color = (0, 0, 0, 0.5)
return cell
class DragView(ui.View):
def __init__(self, path):
methods = [tableView_itemsForBeginningDragSession_atIndexPath_]
protocols = ['UITableViewDragDelegate']
DragDelegate = create_objc_class('DragDelegate', methods=methods, protocols=protocols)
self._drag_delegate = DragDelegate.alloc().init()
self.width = 540
self.height = 540
self.ds = DragDataSource(_drag_items)
self.ds.move_enabled = False
self.ds.delete_enabled = False
self.background_color = '#ffffff'
self.title_label = ui.Label()
self.title_label.width = self.bounds.width - 12
self.title_label.height = 32
self.title_label.x = self.bounds.x + 6
self.title_label.y = self.bounds.y + 6
self.title_label.text_color = '#000000'
self.title_label.text = 'Drag File or Folder'
self.title_label.background_color = '#ffffff'
self.title_label.alignment = ui.ALIGN_CENTER
self.title_label.font = ('<system-bold>', 18)
self.add_subview(self.title_label)
self.help_label = ui.Label()
self.help_label.width = self.bounds.width - 12
self.help_label.height = 32
self.help_label.x = self.bounds.x + 6
self.help_label.y = self.bounds.height - self.help_label.height - 3 + self.bounds.x
self.help_label.text_color = '#484848'
self.help_label.text = 'Esc - close • Ctrl [ - close with Apple smart keyboard'
self.help_label.background_color = '#ffffff'
self.help_label.alignment = ui.ALIGN_CENTER
self.help_label.font = ('<system>', 13)
self.add_subview(self.help_label)
self.tv = ui.TableView()
self.tv.allows_multiple_selection = False
self.tv.allows_selection = False
self.tv.allows_multiple_selection_during_editing = False
self.tv.allows_selection_during_editing = False
self.tv.data_source = self.ds
self.tv.delegate = self.ds
self.tv.frame = (self.title_label.x, self.title_label.y + self.title_label.height + 6,
self.title_label.width, self.bounds.height - 64 - 24)
self.add_subview(self.tv)
tv_objc = ObjCInstance(self.tv)
tv_objc.setDragDelegate_(self._drag_delegate)
def handle_escape():
self.close()
self._handlers = []
self._handlers.append(register_key_event_handler(UIEventKeyCodeEscape, handle_escape))
self._handlers.append(register_key_event_handler(UIEventKeyCodeLeftSquareBracket, handle_escape,
modifier_flags=UIKeyModifierControl))
def will_close(self):
for handler in self._handlers:
unregister_key_event_handler(handler)
def _drag_path_item(path, root):
is_folder = os.path.isdir(path)
breadcrumb = os.path.dirname(path)[len(root) + 1:]
breadcrumb = ' • '.join(breadcrumb.split(os.path.sep))
item = {
'title': os.path.basename(path),
'subtitle': breadcrumb,
'image': 'iob:folder_24' if is_folder else 'iob:document_24',
'folder': is_folder,
'accessory_type': 'none',
'path': path,
'drag_delegate': None
}
return item
def _drag_path_items(path):
docs_path = os.path.normpath(os.path.expanduser('~/Documents'))
root = os.path.dirname(docs_path)
items = [_drag_path_item(p
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
blackmamba-0.0.20.tar.gz (27个子文件)
blackmamba-0.0.20
setup.cfg 45B
README.rst 3KB
blackmamba
ide.py 4KB
runtime.py 5KB
key_event.py 2KB
log.py 1010B
dash.py 1KB
system.py 5KB
annotation.py 467B
config.py 1KB
analyzer.py 5KB
file_picker.py 3KB
picker.pyui 3KB
experimental
external_screen.py 6KB
__init__.py 0B
tester.py 3KB
__init__.py 5KB
update.py 3KB
key_command.py 4KB
outline.py 3KB
uikit.py 163B
drag_provider.py 8KB
picker.py 7KB
action_picker.py 3KB
comment.py 2KB
PKG-INFO 5KB
setup.py 885B
共 27 条
- 1
资源评论
挣扎的蓝藻
- 粉丝: 13w+
- 资源: 15万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功