def startup(self): # We want the web canvas to be 1024x768; # 22 pixels is the window header size. self.main_window = toga.MainWindow(self.name, size=(1024, 768 + 22)) self.main_window.app = self webview = toga.WebView() self.main_window.content = webview files = [] filenames = [ os.path.join(self.root, 'css', self.path, f) for f in os.listdir(os.path.join(self.root, 'css', self.path)) if f.endswith('.xht') or f.endswith('.htm') or f.endswith('.html') ] loader = Loader.alloc().init() loader.webview = webview loader.filenames = iter(filenames) loader.path = self.path loader.output = self.output NSTimer.scheduledTimerWithTimeInterval(0.5, target=loader, selector=SEL('run:'), userInfo=None, repeats=False) # Show the main window self.main_window.show()
def toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_( self, toolbar, identifier, insert: bool): "Create the requested toolbar button" native = NSToolbarItem.alloc().initWithItemIdentifier_(identifier) try: item = self.impl._toolbar_items[str(identifier)] if item.label: native.setLabel(item.label) native.setPaletteLabel(item.label) if item.tooltip: native.setToolTip(item.tooltip) if item.icon: native.setImage(item.icon._impl.native) item._impl.native.append(native) native.setTarget_(self) native.setAction_(SEL('onToolbarButtonPress:')) except KeyError: pass # Prevent the toolbar item from being deallocated when # no Python references remain native.retain() native.autorelease() return native
def create(self): self.native = TogaPopupButton.alloc().init() self.native.interface = self.interface self.native.target = self.native self.native.action = SEL('onSelect:') self.add_constraints()
def create(self): self.native = TogaSlider.alloc().init() self.native.interface = self.interface self.native.target = self.native self.native.action = SEL('onSlide:') self.set_tick_count(self.interface.tick_count) self.add_constraints()
def create(self): self.native = TogaButton.alloc().init() self.native.interface = self.interface self.native.bezelStyle = NSRoundedBezelStyle self.native.buttonType = NSMomentaryPushInButton self.native.target = self.native self.native.action = SEL('onPress:') # Add the layout constraints self.add_constraints()
def create(self): self.native = TogaSwitch.alloc().init() self.native.interface = self.interface self.native.bezelStyle = NSRoundedBezelStyle self.native.setButtonType(NSSwitchButton) self.native.target = self.native self.native.action = SEL('onPress:') # Add the layout constraints self.add_constraints()
def create(self): # Create a tree view, and put it in a scroll view. # The scroll view is the _impl, because it's the outer container. self.native = NSScrollView.alloc().init() self.native.hasVerticalScroller = True self.native.hasHorizontalScroller = False self.native.autohidesScrollers = False self.native.borderType = NSBezelBorder # Create the Tree widget self.tree = TogaTree.alloc().init() self.tree.interface = self.interface self.tree._impl = self self.tree.columnAutoresizingStyle = NSTableViewColumnAutoresizingStyle.Uniform self.tree.usesAlternatingRowBackgroundColors = True self.tree.allowsMultipleSelection = self.interface.multiple_select # Create columns for the tree self.columns = [] # Cocoa identifies columns by an accessor; to avoid repeated # conversion from ObjC string to Python String, create the # ObjC string once and cache it. self.column_identifiers = {} for i, (heading, accessor) in enumerate( zip(self.interface.headings, self.interface._accessors)): column_identifier = at(accessor) self.column_identifiers[id(column_identifier)] = accessor column = NSTableColumn.alloc().initWithIdentifier( column_identifier) # column.editable = False column.minWidth = 16 # if self.interface.sorting: # sort_descriptor = NSSortDescriptor.sortDescriptorWithKey(column_identifier, ascending=True) # column.sortDescriptorPrototype = sort_descriptor self.tree.addTableColumn(column) self.columns.append(column) column.headerCell.stringValue = heading # Put the tree arrows in the first column. self.tree.outlineTableColumn = self.columns[0] self.tree.delegate = self.tree self.tree.dataSource = self.tree self.tree.target = self.tree self.tree.doubleAction = SEL('onDoubleClick:') # Embed the tree view in the scroll view self.native.documentView = self.tree # Add the layout constraints self.add_constraints()
def create(self): self.native = TogaCanvas.alloc().init() self.native.interface = self.interface self.native._impl = self NSNotificationCenter.defaultCenter.addObserver( self.native, selector=SEL("frameChanged:"), name=NSViewFrameDidChangeNotification, object=self.native) # Add the layout constraints self.add_constraints()
def menuForEvent_(self, event): if self.interface.on_delete: mousePoint = self.convertPoint(event.locationInWindow, fromView=None) row = self.rowAtPoint(mousePoint) popup = NSMenu.alloc().initWithTitle("popup") delete_item = popup.addItemWithTitle( "Delete", action=SEL('actionDeleteRow:'), keyEquivalent="") delete_item.tag = row # action_item = popup.addItemWithTitle("???", action=SEL('actionRow:'), keyEquivalent="") # action_item.tag = row return popup
def run_(self, info) -> None: try: print("Cleaning {}...".format(self.filename)) self.webview.evaluate(CLEANSE) evaluator = Evaluator.alloc().init() evaluator.loader = self.loader evaluator.webview = self.webview evaluator.filename = self.filename evaluator.output = self.output evaluator.path = self.path NSTimer.scheduledTimerWithTimeInterval(0.1, target=evaluator, selector=SEL('run:'), userInfo=None, repeats=False) except StopIteration: sys.exit(1)
def toolbar_itemForItemIdentifier_willBeInsertedIntoToolbar_(self, toolbar, identifier, insert: bool): "Create the requested toolbar button" native = NSToolbarItem.alloc().initWithItemIdentifier_(identifier) try: item = self.interface._impl._toolbar_items[str(identifier)] if item.label: native.setLabel(item.label) native.setPaletteLabel(item.label) if item.tooltip: native.setToolTip(item.tooltip) if item.icon: native.setImage(item.icon._impl.native) item._impl.native.append(native) native.setTarget_(self) native.setAction_(SEL('onToolbarButtonPress:')) except KeyError: pass return native
def run_(self, info) -> None: try: filename = os.path.abspath(next(self.filenames)) self.webview.url = 'file://' + filename print("Inspecting {}...".format(filename)) cleaner = Cleaner.alloc().init() cleaner.loader = self cleaner.webview = self.webview cleaner.filename = filename cleaner.output = self.output cleaner.path = self.path NSTimer.scheduledTimerWithTimeInterval(0.1, target=cleaner, selector=SEL('run:'), userInfo=None, repeats=False) except StopIteration: sys.exit(1)
def create(self): self._view_for_row = dict() # Create a table view, and put it in a scroll view. # The scroll view is the native, because it's the outer container. self.native = NSScrollView.alloc().init() self.native.hasVerticalScroller = True self.native.hasHorizontalScroller = False self.native.autohidesScrollers = False self.native.borderType = NSBezelBorder self.table = TogaTable.alloc().init() self.table.interface = self.interface self.table._impl = self self.table.columnAutoresizingStyle = NSTableViewColumnAutoresizingStyle.Uniform self.table.usesAlternatingRowBackgroundColors = True self.table.allowsMultipleSelection = self.interface.multiple_select # Create columns for the table self.columns = [] # Cocoa identifies columns by an accessor; to avoid repeated # conversion from ObjC string to Python String, create the # ObjC string once and cache it. self.column_identifiers = {} for heading, accessor in zip(self.interface.headings, self.interface._accessors): self._add_column(heading, accessor) self.table.delegate = self.table self.table.dataSource = self.table self.table.target = self.table self.table.doubleAction = SEL('onDoubleClick:') # Embed the table view in the scroll view self.native.documentView = self.table # Add the layout constraints self.add_constraints()
def createRefreshView(self) -> None: # delete old stuff if any if self.refreshView: self.refreshView.removeFromSuperview() self.refreshView.release() self.refreshView = None self.verticalScrollElasticity = NSScrollElasticityAllowed # create new content view self.createContentView() self.contentView.postsFrameChangedNotifications = True self.contentView.postsBoundsChangedNotifications = True NSNotificationCenter.defaultCenter.addObserver( self, selector=SEL('viewBoundsChanged:'), name=NSViewBoundsDidChangeNotification, object=self.contentView, ) # Create view to hold the refresh widgets refreshview contentRect = self.contentView.documentView.frame self.refreshView = NSView.alloc().init() self.refreshView.translatesAutoresizingMaskIntoConstraints = False # Create spinner self.refreshIndicator = NSProgressIndicator.alloc().init() self.refreshIndicator.style = NSProgressIndicatorSpinningStyle self.refreshIndicator.translatesAutoresizingMaskIntoConstraints = False self.refreshIndicator.displayedWhenStopped = True self.refreshIndicator.usesThreadedAnimation = True self.refreshIndicator.indeterminate = True self.refreshIndicator.bezeled = False self.refreshIndicator.sizeToFit() # Center the spinner in the header self.refreshIndicator.setFrame( NSMakeRect( self.refreshView.bounds.size.width / 2 - self.refreshIndicator.frame.size.width / 2, self.refreshView.bounds.size.height / 2 - self.refreshIndicator.frame.size.height / 2, self.refreshIndicator.frame.size.width, self.refreshIndicator.frame.size.height)) # Put everything in place self.refreshView.addSubview(self.refreshIndicator) # self.refreshView.addSubview(self.refreshArrow) self.contentView.addSubview(self.refreshView) # set layout constraints indicatorHCenter = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_( # noqa: E501 self.refreshIndicator, NSLayoutAttributeCenterX, NSLayoutRelationEqual, self.refreshView, NSLayoutAttributeCenterX, 1.0, 0, ) self.refreshView.addConstraint(indicatorHCenter) indicatorVCenter = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_( # noqa: E501 self.refreshIndicator, NSLayoutAttributeCenterY, NSLayoutRelationEqual, self.refreshView, NSLayoutAttributeCenterY, 1.0, 0, ) self.refreshView.addConstraint(indicatorVCenter) refreshWidth = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_( # noqa: E501 self.refreshView, NSLayoutAttributeWidth, NSLayoutRelationEqual, self.contentView, NSLayoutAttributeWidth, 1.0, 0, ) self.contentView.addConstraint(refreshWidth) refreshHeight = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_( # noqa: E501 self.refreshView, NSLayoutAttributeHeight, NSLayoutRelationEqual, None, NSLayoutAttributeNotAnAttribute, 1.0, HEADER_HEIGHT, ) self.contentView.addConstraint(refreshHeight) refreshHeight = NSLayoutConstraint.constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_( # noqa: E501 self.refreshView, NSLayoutAttributeTop, NSLayoutRelationEqual, self.contentView, NSLayoutAttributeTop, 1.0, -HEADER_HEIGHT, ) self.contentView.addConstraint(refreshHeight) # Scroll to top self.contentView.scrollToPoint(NSMakePoint(contentRect.origin.x, 0)) self.reflectScrolledClipView(self.contentView)
def create(self): self.native = TogaView.alloc().init() self.input = NSTextField.new() self.input.interface = self.interface self.input.bezeled = True self.input.bezelStyle = NSTextFieldSquareBezel self.input.translatesAutoresizingMaskIntoConstraints = False self.stepper = TogaStepper.alloc().init() self.stepper.interface = self.interface self.stepper._impl = self self.stepper.translatesAutoresizingMaskIntoConstraints = False self.stepper.target = self.stepper self.stepper.action = SEL('onChange:') self.stepper.controller = self.input self.input.delegate = self.stepper # Add the input and stepper to the constraining box. self.native.addSubview(self.input) self.native.addSubview(self.stepper) # Add constraints to lay out the input and stepper. # Stepper is always top right corner. self.native.addConstraint( NSLayoutConstraint. constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_( self.native, NSLayoutAttributeTop, NSLayoutRelationEqual, self.stepper, NSLayoutAttributeTop, 1.0, 0)) self.native.addConstraint( NSLayoutConstraint. constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_( self.native, NSLayoutAttributeRight, NSLayoutRelationEqual, self.stepper, NSLayoutAttributeRight, 1.0, 0)) # Stepper height matches container box height self.native.addConstraint( NSLayoutConstraint. constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_( self.native, NSLayoutAttributeBottom, NSLayoutRelationEqual, self.stepper, NSLayoutAttributeBottom, 1.0, 0)) # Input is always left, centred vertically on the stepper self.native.addConstraint( NSLayoutConstraint. constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_( self.stepper, NSLayoutAttributeCenterY, NSLayoutRelationEqual, self.input, NSLayoutAttributeCenterY, 1.0, 0)) self.native.addConstraint( NSLayoutConstraint. constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_( self.native, NSLayoutAttributeLeft, NSLayoutRelationEqual, self.input, NSLayoutAttributeLeft, 1.0, 0)) # Stepper and input meet in the middle with a small gap self.native.addConstraint( NSLayoutConstraint. constraintWithItem_attribute_relatedBy_toItem_attribute_multiplier_constant_( self.stepper, NSLayoutAttributeLeft, NSLayoutRelationEqual, self.input, NSLayoutAttributeRight, 1.0, 2)) # Add the layout constraints for the main box self.add_constraints()
def run_(self, info) -> None: try: print("Inspecting {}...".format(self.filename)) result = self.webview.evaluate(INSPECT) # print(result) result = json.loads(result) example = os.path.splitext(os.path.basename(self.filename))[0] test_dir = os.path.join(self.output, self.path.replace('-', '_')) # If a document has "matches" or "assert" metadata, # it's a test document; otherwise, it's a reference. # We can ignore reference files. They often don't have # the same document structure as the base document, # so they're not helpful for a DOM comparison. if 'matches' in result or 'assert' in result: newdirs = [] dirname = test_dir while not os.path.exists(dirname): newdirs.append(dirname) dirname = os.path.dirname(dirname) newdirs.reverse() for newdir in newdirs: print("Creating directory {}...".format(newdir)) os.mkdir(newdir) with open(os.path.join(newdir, '__init__.py'), 'w'): pass # Output the test case data # If the last part of the filename is of the pattern # -001 or -001a, then the group name drops that part. parts = example.rsplit('-') if parts[-1].isdigit() or parts[-1][:-1].isdigit(): parts.pop() suffix = '-' else: suffix = '' group = '-'.join(parts) group_class = 'Test' + ''.join(p.title() for p in parts) group_file = 'test_' + '_'.join(parts) + '.py' test_filename = os.path.join(test_dir, group_file) print("Writing unittest file {}".format(test_filename)) with open(os.path.join(test_filename), 'w') as f: f.write( TEST_CLASS_TEMPLATE.format( group=group + suffix, classname=group_class, )) test_datadir = os.path.join(test_dir, 'data') # Create data/ref directory try: os.mkdir(test_datadir) except FileExistsError: pass test_datafile = os.path.join(test_datadir, example + '.json') # If this is a new test, automatically add it to the not_implemented file. if not os.path.exists(test_datafile): print('New test - adding to not_implemented list...') with open(os.path.join(test_dir, 'not_implemented'), 'a') as nif: nif.write('{}\n'.format(example.replace('-', '_'))) # Output JSON content with open(test_datafile, 'w') as f: print("Writing data file {}".format(test_datafile)) f.write( json.dumps( { 'test_case': result['test_case'], 'assert': result.get('assert', None), 'help': result['help'], 'matches': result.get('matches', None), }, indent=4)) # Output reference rendering data test_refdir = os.path.join(test_dir, 'ref') # Create data/ref directory try: os.mkdir(test_refdir) except FileExistsError: pass # Output JSON content test_reffile = os.path.join(test_refdir, example + '.json') with open(test_reffile, 'w') as f: print("Writing reference file {}".format(test_reffile)) f.write(json.dumps(result['reference'], indent=4)) NSTimer.scheduledTimerWithTimeInterval(0.05, target=self.loader, selector=SEL('run:'), userInfo=None, repeats=False) except StopIteration: sys.exit(1)