def swizzle(cls_name, selector_name, fn): cls = ObjCClass(cls_name).ptr new_selector_name = SWIZZLED_SELECTOR_PREFIX + selector_name new_selector = sel(new_selector_name) if c.class_getInstanceMethod(cls, new_selector): error('Skipping swizzling, already responds to {} selector'.format( new_selector_name)) return selector = sel(selector_name) method = c.class_getInstanceMethod(cls, selector) if not method: error('Failed to get {} instance method'.format(selector_name)) return type_encoding = c.method_getTypeEncoding(method) parsed_types = parse_types(type_encoding) restype = parsed_types[0] argtypes = parsed_types[1] IMPTYPE = CFUNCTYPE(restype, *argtypes) imp = IMPTYPE(fn) retain_global(imp) did_add = c.class_addMethod(cls, new_selector, imp, type_encoding) if not did_add: error('Failed to add {} method'.format(new_selector_name)) return new_method = c.class_getInstanceMethod(cls, new_selector) method_exchangeImplementations(method, new_method)
def add_method(cls_name, selector_name, fn, type_encoding): cls = ObjCClass(cls_name).ptr selector = sel(selector_name) if c.class_getInstanceMethod(cls, selector): error( 'Failed to add method, class {} already provides method {}'.format( cls_name, selector_name)) return parsed_types = parse_types(type_encoding) restype = parsed_types[0] argtypes = parsed_types[1] IMPTYPE = CFUNCTYPE(restype, *argtypes) imp = IMPTYPE(fn) retain_global(imp) did_add = c.class_addMethod(cls, selector, imp, c_char_p(type_encoding.encode('utf-8'))) if not did_add: error('Failed to add class method') return did_add
def _register_key_command(input, modifier_flags, function, title=None): if not UIApplication.sharedApplication().respondsToSelector_( sel('originalkeyCommands')): swizzle('UIApplication', 'keyCommands', _blackmamba_keyCommands) selector_name = _key_command_selector_name(input, modifier_flags) selector = sel(selector_name) obj = UIApplication.sharedApplication() info('Registering key command "{}" ({})'.format( _shortcut_name(input, modifier_flags), title or 'No discoverability title')) if not callable(function): error('Skipping, provided function is not callable') return False if obj.respondsToSelector_(selector): error('Skipping, method {} already registered'.format(selector_name)) return False def key_command_action(_sel, _cmd, sender): function() IMPTYPE = CFUNCTYPE(None, c_void_p, c_void_p, c_void_p) imp = IMPTYPE(key_command_action) retain_global(imp) cls = c.object_getClass(obj.ptr) type_encoding = c_char_p('v@:@'.encode('utf-8')) did_add = c.class_addMethod(cls, selector, imp, type_encoding) if not did_add: error('Failed to add key command method {}'.format(selector_name)) return False if isinstance(modifier_flags, UIKeyModifier): modifier_flags = modifier_flags.value if title: kc = UIKeyCommand.keyCommandWithInput_modifierFlags_action_discoverabilityTitle_( ns(input), modifier_flags, selector, ns(title)) else: kc = UIKeyCommand.keyCommandWithInput_modifierFlags_action_( ns(input), modifier_flags, selector) _key_commands.append(kc) return True
def get_path(): tab = _get_selected_tab_view_controller() if not tab: return None return str(tab.filePath()) if tab.respondsToSelector_( sel('filePath')) else None
def register_key_event_handler(key_code, fn, *, modifier_flags=0): if not UIApplication.sharedApplication().respondsToSelector_( sel('originalhandleKeyUIEvent:')): swizzle('UIApplication', 'handleKeyUIEvent:', _blackmamba_handleKeyUIEvent) handler = KeyEventHandler(key_code, modifier_flags, fn) _key_event_handlers.append(handler) return handler
def get_paths(): tabs = _get_tabs_view_controller() if not tabs: return None return [ str(tab.filePath()) if tab.respondsToSelector_(sel('filePath')) else None for tab in tabs.tabViewControllers() ]
def create_button(label, func): button_width = 25 black = ObjCClass('UIColor').alloc().initWithWhite_alpha_(0.0, 1.0) action_button = ui.Button() action_button.action = func accessory_button = ObjCClass( 'UIBarButtonItem').alloc().initWithTitle_style_target_action_( label, 0, action_button, sel('invokeAction:')) accessory_button.width = button_width accessory_button.tintColor = black return (action_button, accessory_button)
def create_button(label, func): button_width = 25 black = ObjCClass("UIColor").alloc().initWithWhite_alpha_(0.0, 1.0) action_button = ui.Button() action_button.action = func accessory_button = ( ObjCClass("UIBarButtonItem") .alloc() .initWithTitle_style_target_action_(label, 0, action_button, sel("invokeAction:")) ) accessory_button.width = button_width accessory_button.tintColor = black return (action_button, accessory_button)
def save(all=False): tabs = _get_tabs_view_controller() if not tabs: return if all: tabs_to_save = tabs.tabViewControllers() else: tabs_to_save = [tabs.tabViewControllers()[_get_selected_tab_index()]] for tab in tabs_to_save: if tab.respondsToSelector(sel('saveData')): tab.saveData()
def _start_notification_listener(): global _listener if _listener is not None: _logger.debug( 'External screen notification listener is already running') return methods = [screenDidConnectNotification_, screenDidDisconnectNotification_] listener_class = objc_util.create_objc_class('ExternalScreenListener', methods=methods) _listener = listener_class.alloc().init() NSNotificationCenter = objc_util.ObjCClass('NSNotificationCenter') default_center = NSNotificationCenter.defaultCenter() default_center.addObserver_selector_name_object_( _listener, objc_util.sel('screenDidConnectNotification:'), 'UIScreenDidConnectNotification', None) default_center.addObserver_selector_name_object_( _listener, objc_util.sel('screenDidDisconnectNotification:'), 'UIScreenDidDisconnectNotification', None) _logger.debug('External screen notification listener started')
def _register_key_event_handler(key_code, func, *, modifier=UIKeyModifier.NONE): if not UIApplication.sharedApplication().respondsToSelector_( sel('originalhandleKeyUIEvent:')): swizzle('UIApplication', 'handleKeyUIEvent:', _blackmamba_handleKeyUIEvent) @system.catch_exceptions def invoke_func(): func() handler = KeyEventHandler(key_code, modifier, invoke_func) _key_event_handlers.append(handler) return handler
def _add_method(cls, func): # void, object, selector type_encoding = "v@:" sel_name = str(uuid.uuid4()) sel = objc_util.sel(sel_name) class_ptr = objc_util.object_getClass(cls.ptr) # ----------------- Modified from objc_util.add_method ------------------ # parsed_types = objc_util.parse_types(type_encoding) restype, argtypes, _ = parsed_types imp = ctypes.CFUNCTYPE(restype, *argtypes)(func) objc_util.retain_global(imp) if isinstance(type_encoding, str): type_encoding = type_encoding.encode('ascii') objc_util.class_addMethod(class_ptr, sel, imp, type_encoding) # ----------------------------------------------------------------------- # return sel
def add_method(method, cls): guard_objc_util() import ctypes import objc_util import uuid encoding = "v@:" # this code is borrowed from `objc_util._add_method` parsed_types = objc_util.parse_types(encoding) restype = parsed_types[0] argtypes = parsed_types[1] IMPTYPE = ctypes.CFUNCTYPE(restype, *argtypes) imp = IMPTYPE(method) objc_util.retain_global(imp) selector = objc_util.sel(str(uuid.uuid1()).replace("-", "")) objc_util.class_addMethod(objc_util.object_getClass(cls.ptr), selector, imp, encoding.encode("ascii")) return selector
def present(view): '''Presents view (ui.View) on external screen. Returns True if view was presented or False if external screen is not available. ''' window = _configure_window() if window is None: _logger.debug( 'Unable to present view, external screen is not available') return False view.flex = 'WH' view_objc = objc_util.ObjCInstance(view) view_objc.setFrame(window.bounds()) window.subviews().makeObjectsPerformSelector( objc_util.sel('removeFromSuperview')) window.addSubview(view_objc) _logger.debug('View presented on external screen') return True
def create_accessory_toolbar(self): from objc_util import ObjCClass, ObjCInstance, sel def create_button(label, func): button_width = 25 black = ObjCClass("UIColor").alloc().initWithWhite_alpha_(0.0, 1.0) action_button = ui.Button() action_button.action = func accessory_button = ( ObjCClass("UIBarButtonItem") .alloc() .initWithTitle_style_target_action_(label, 0, action_button, sel("invokeAction:")) ) accessory_button.width = button_width accessory_button.tintColor = black return (action_button, accessory_button) vobj = ObjCInstance(self.markup) keyboardToolbar = ObjCClass("UIToolbar").alloc().init() keyboardToolbar.sizeToFit() button_width = 25 black = ObjCClass("UIColor").alloc().initWithWhite_alpha_(0.0, 1.0) # Create the buttons # Need to retain references to the buttons used # to handle clicks (self.indentButton, indentBarButton) = create_button(u"\u21E5", self.indent) (self.outdentButton, outdentBarButton) = create_button(u"\u21E4", self.outdent) (self.quoteButton, quoteBarButton) = create_button(">", self.block_quote) (self.linkButton, linkBarButton) = create_button("[]", self.link) # (self.anchorButton, anchorBarButton) = create_button('<>', self.anchor) (self.hashButton, hashBarButton) = create_button("#", self.heading) (self.numberedButton, numberedBarButton) = create_button("1.", self.numbered_list) (self.listButton, listBarButton) = create_button("•", self.unordered_list) (self.underscoreButton, underscoreBarButton) = create_button("_", self.insert_underscore) (self.backtickButton, backtickBarButton) = create_button("`", self.insert_backtick) # Flex between buttons f = ObjCClass("UIBarButtonItem").alloc().initWithBarButtonSystemItem_target_action_(5, None, None) doneBarButton = ( ObjCClass("UIBarButtonItem").alloc().initWithBarButtonSystemItem_target_action_(0, vobj, sel("endEditing:")) ) keyboardToolbar.items = [ indentBarButton, f, outdentBarButton, f, quoteBarButton, f, linkBarButton, f, hashBarButton, f, numberedBarButton, f, listBarButton, f, underscoreBarButton, f, backtickBarButton, f, doneBarButton, ] vobj.inputAccessoryView = keyboardToolbar
def create_accessory_toolbar(self): from objc_util import ObjCClass, ObjCInstance, sel def create_button(label, func): button_width = 25 black = ObjCClass('UIColor').alloc().initWithWhite_alpha_(0.0, 1.0) action_button = ui.Button() action_button.action = func accessory_button = ObjCClass('UIBarButtonItem').alloc().initWithTitle_style_target_action_(label, 0, action_button, sel('invokeAction:')) accessory_button.width = button_width accessory_button.tintColor = black return (action_button, accessory_button) vobj = ObjCInstance(self.markup) keyboardToolbar = ObjCClass('UIToolbar').alloc().init() keyboardToolbar.sizeToFit() button_width = 25 black = ObjCClass('UIColor').alloc().initWithWhite_alpha_(0.0, 1.0) # Create the buttons # Need to retain references to the buttons used # to handle clicks (self.indentButton, indentBarButton) = create_button('\u21E5', self.indent) (self.outdentButton, outdentBarButton) = create_button('\u21E4', self.outdent) (self.quoteButton, quoteBarButton) = create_button('>', self.block_quote) (self.linkButton, linkBarButton) = create_button('[]', self.link) #(self.anchorButton, anchorBarButton) = create_button('<>', self.anchor) (self.hashButton, hashBarButton) = create_button('#', self.heading) (self.numberedButton, numberedBarButton) = create_button('1.', self.numbered_list) (self.listButton, listBarButton) = create_button('•', self.unordered_list) (self.underscoreButton, underscoreBarButton) = create_button('_', self.insert_underscore) (self.backtickButton, backtickBarButton) = create_button('`', self.insert_backtick) # Flex between buttons f = ObjCClass('UIBarButtonItem').alloc().initWithBarButtonSystemItem_target_action_(5, None, None) doneBarButton = ObjCClass('UIBarButtonItem').alloc().initWithBarButtonSystemItem_target_action_(0, vobj, sel('endEditing:')) keyboardToolbar.items = [indentBarButton, f, outdentBarButton, f, quoteBarButton, f, linkBarButton, f, hashBarButton, f, numberedBarButton, f, listBarButton, f, underscoreBarButton, f, backtickBarButton, f, doneBarButton] vobj.inputAccessoryView = keyboardToolbar
def registerAllObservers(self): for k, v in self._method_table.items(): self._ndc.addObserver_selector_name_object_( self._mp4p_nc, sel(v.__name__), k, None)
def ButtonItem(s, image, action): return (UIBarButtonItem.alloc().initWithImage_style_target_action_( UIImage.imageNamed_(image), 0, s.newVC, sel(action)))
def ButtonItem(s, image, action): return ( UIBarButtonItem.alloc() .initWithImage_style_target_action_(UIImage.imageNamed_(image), 0, s.newVC, sel(action)) )