Exemplo n.º 1
0
	def presentPathList(self, pathList):
		def pathItem(index):
			def _onDelete(menuItem):
				del pathList[index]
				self._incr.onChanged()

			def buildContextMenu(element, menu):
				menu.add( MenuItem.menuItemWithLabel( 'Delete', _onDelete ) )
				return True

			return _itemHoverHighlightStyle.applyTo( Label( pathList[index] ) ).withContextMenuInteractor( buildContextMenu )


		def _onNew(hyperlink, event):
			component = hyperlink.getElement().getRootElement().getComponent()
			openDialog = JFileChooser()
			openDialog.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY )
			response = openDialog.showDialog( component, 'Choose path' )
			if response == JFileChooser.APPROVE_OPTION:
				sf = openDialog.getSelectedFile()
				if sf is not None:
					filename = sf.getPath()
					if filename is not None  and  os.path.isdir( filename ):
						pathList.append( filename )
						self._incr.onChanged()
		
		newLink = Hyperlink( 'NEW', _onNew )
		controls = newLink.pad( 10.0, 5.0 )

		pathPres = Column( [ pathItem( i )   for i in xrange( len( pathList ) ) ] )
		return Column( [ controls, pathPres.padX( 5.0 ) ] )
	def __present__(self, fragment, inheritedState):
		homeLink = Hyperlink( 'HOME PAGE', fragment.subject.rootSubject )
		configLink = Hyperlink( 'CONFIGURATION PAGE', fragment.subject.configSubject )
		linkHeader = SplitLinkHeaderBar( [ homeLink ], [ configLink ] )
		
		title = TitleBar( self.getTitleText() )

		head = _staticStyle.applyTo( Head( [ linkHeader, title ] ) )
		
		contents = self.__present_contents__( fragment, inheritedState )
		
		return self._configPageStyle.applyTo( Page( [ head, contents ] ) )
Exemplo n.º 3
0
	def __present__(self , fragment, inherited_state):
		title = TitleBarWithSubtitle('Mallard editor', 'development prototype - SAVE FUNCTIONALITY NOT IMPLEMENTED')
		path_heading = SectionHeading2(['Displaying contents of: ', _dir_style(RichSpan(self.__path))])

		links = [Hyperlink(p.filename, editor_page.EditorPageSubject(p, fragment.subject))   for p in self._pages]

		if self._example_pages is not None:
			examples_heading = SectionHeading2('Example mallard documents:')
			example_links = [Hyperlink(p.filename, editor_page.EditorPageSubject(p, fragment.subject))   for p in self._example_pages]
			examples_section = [Spacer(0.0, 20.0), examples_heading, Column(example_links)]
		else:
			examples_section = []

		return _page_style(Page([title, path_heading, Column(links)] + examples_section))
Exemplo n.º 4
0
    def AppConsole(self, fragment, state, node):
        index = node.getIndex()
        name = 'Console %d' % (index, )
        subject = node.subject(fragment.subject)
        consoleLink = Hyperlink(name, subject).padX(0.0, _appDocRightPadding)

        return GridRow([consoleLink])
    def __present_contents__(self, fragment, inheritedState):
        self._incr.onAccess()

        dirPres = self._presentDir()
        note = NotesText([
            'Note: please choose the location of the GraphViz ',
            EmphSpan('bin'), ' directory.'
        ])
        columnContents = [note, dirPres]
        if self._config is not None:
            columnContents.append(self._presentConfig())
        pathContents = Column(columnContents)
        pathSection = Section(SectionHeading2('GraphViz path'), pathContents)

        downloadText = ''
        if self.__isConfigured():
            downloadText = 'GraphViz appears to be installed on this machine and configured. If it does not work correctly, you may need to install it. You can download it from the '
        else:
            downloadText = 'If GraphViz is not installed on this machine, please install it. You can download it from the '

        downloadLink = Hyperlink('GraphViz homepage',
                                 URI('http://www.graphviz.org/'))
        download = NormalText([downloadText, downloadLink, '.'])
        downloadSec = Section(
            SectionHeading2('GraphViz download/installation'), download)

        return Body([pathSection, downloadSec])
    def __present__(self, fragment, inheritedState):
        configurationLink = Hyperlink(
            'CONFIGURATION PAGE',
            fragment.subject.world.configuration.subject())
        linkHeader = LinkHeaderBar([configurationLink])

        title = TitleBar('About')

        splash = Image.systemImage('SplashScreen.png')

        desc = NormalText(
            'The Larch Environment was designed and written by Geoffrey French'
        )

        jythonLink = Hyperlink('Jython', URI('http://www.jython.org/'))
        jerichoLink = Hyperlink('Jericho HTML parser',
                                URI('http://jericho.htmlparser.net'))
        salamanderLink = Hyperlink('SVG Salamander',
                                   URI('http://svgsalamander.java.net/'))
        googleFontsLink = Hyperlink('Google Fonts',
                                    URI('http://www.google.com/fonts'))

        jythonAcks = NormalText([
            'The Larch Environment incorporates the ', jythonLink,
            ' interpreter.'
        ])
        libraryAcks = NormalText([
            'Larch incorporates the ', jerichoLink, ', and ', salamanderLink,
            ' libraries.'
        ])
        fontAcks = NormalText([
            'Larch incorporates the following fonts (found at ',
            googleFontsLink, '): ',
            'Arimo (by Steve Matteson), Lora (by Cyreal), Nobile (by Vernon Adams), Noto Sans (by Google), ',
            'Open Sans (by Steve Matteson), PT Serif (by ParaType), and Source Sans Pro (by Paul D. Hunt)'
        ])

        copyright = NormalText('(C) copyright Geoffrey French 2008-2013')

        homePage = Hyperlink('The Larch Environment website',
                             URI('http://www.larchenvironment.com'))

        head = Head([linkHeader, title])
        body = Body([
            splash.padY(20.0).alignHCentre(),
            desc.padY(10.0).alignHCentre(),
            Spacer(0.0, 10.0),
            jythonAcks.pad(25.0, 5.0).alignHLeft(),
            libraryAcks.pad(25.0, 5.0).alignHLeft(),
            fontAcks.pad(25.0, 5.0).alignHLeft(),
            Spacer(0.0, 10.0),
            Row([copyright.alignHLeft(),
                 homePage.alignHRight()]).pad(10.0, 10.0).alignHExpand()
        ])
        return StyleSheet.style(Primitive.editable(False)).applyTo(
            Page([head, body]))
    def __present__(self, fragment, inheritedState):
        homeLink = Hyperlink('HOME PAGE', self.__world.rootSubject)
        linkHeader = SplitLinkHeaderBar([homeLink], []).alignHExpand()

        title = TitleBar('Configuration')

        head = Head([linkHeader, title])

        pageItemCmp = lambda itemA, itemB: cmp(itemA.getLinkText(),
                                               itemB.getLinkText())
        pages = self._pages[:]
        pages.sort(pageItemCmp)

        links = [
            Hyperlink(page.getLinkText(), page.subject(fragment.subject))
            for page in pages
        ]
        body = Body([Column(links)])

        return _staticStyle.applyTo(Page([head, body]))
def _documentContextMenuFactory(element, menu):
	region = element.getRegion()
	rootElement = element.getRootElement()
	
	def makeParagraphStyleFn(style):
		def setParagraphStyle(model):
			model.style = style
		
		def _onLink(link, event):
			caret = rootElement.getCaret()
			if caret is not None and caret.isValid():
				caretElement = caret.getElement()
				if caretElement.getRegion() is region:
					GUIRichTextController.instance.modifyParagraphAtMarker(caret.getMarker(), setParagraphStyle)
		return _onLink
	
	normalStyle = Hyperlink('Normal', makeParagraphStyleFn('normal'))
	h1Style = Hyperlink('H1', makeParagraphStyleFn('h1'))
	h2Style = Hyperlink('H2', makeParagraphStyleFn('h2'))
	h3Style = Hyperlink('H3', makeParagraphStyleFn('h3'))
	h4Style = Hyperlink('H4', makeParagraphStyleFn('h4'))
	h5Style = Hyperlink('H5', makeParagraphStyleFn('h5'))
	h6Style = Hyperlink('H6', makeParagraphStyleFn('h6'))
	titleStyle = Hyperlink('Title', makeParagraphStyleFn('title'))
	paraStyles = ControlsRow([normalStyle, h1Style, h2Style, h3Style, h4Style, h5Style, h6Style, titleStyle])
	menu.add(Section(SectionHeading2('Paragraph styles'), paraStyles))

	
	def makeStyleFn(attrName):
		def computeStyleValues(listOfSpanAttrs):
			value = bool(listOfSpanAttrs[0].getValue(attrName, 0))
			value = not value
			attrs = RichTextAttributes()
			attrs.putOverride(attrName, '1'   if value   else None)
			return attrs

		def onButton(button, event):
			selection = rootElement.getSelection()
			if isinstance(selection, TextSelection):
				if selection.getRegion() == region:
					GUIRichTextController.instance.applyStyleToSelection(selection, computeStyleValues)
		return onButton
	
	italicStyle = Button.buttonWithLabel('I', makeStyleFn('italic'))
	boldStyle = Button.buttonWithLabel('B', makeStyleFn('bold'))
	styles = ControlsRow([italicStyle, boldStyle]).alignHLeft()

	menu.add(Section(SectionHeading2('Selection styles'), styles))

	
	return True
Exemplo n.º 9
0
    def Worksheet(self, fragment, inheritedState, node):
        bodyView = Pres.coerce(node.getBody())

        try:
            editSubject = fragment.subject.editSubject
        except AttributeError:
            pageContents = []
        else:
            editLink = Hyperlink('Switch to developer mode', editSubject)
            linkHeader = LinkHeaderBar([editLink])
            pageContents = [linkHeader]

        tip = TipBox([
            NormalText([
                'To edit this worksheet or add content, click ',
                EmphSpan('Switch to developer mode'), ' at the top right'
            ])
        ], 'larchcore.worksheet.view.toedit')

        w = Page(pageContents + [bodyView, tip])
        w = w.withContextMenuInteractor(_worksheetContextMenuFactory)
        return StyleSheet.style(Primitive.editable(False)).applyTo(w)
    def _presentDir(self):
        def _onSet(hyperlink, event):
            component = hyperlink.getElement().getRootElement().getComponent()
            openDialog = JFileChooser()
            openDialog.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
            response = openDialog.showDialog(component, 'Choose path')
            if response == JFileChooser.APPROVE_OPTION:
                sf = openDialog.getSelectedFile()
                if sf is not None:
                    filename = sf.getPath()
                    if filename is not None and os.path.isdir(filename):
                        self._graphVizDir = filename
                        self._refreshConfig()
                        self._incr.onChanged()

        dirLabel = Label(
            self._graphVizDir
        ) if self._graphVizDir is not None else self._notSetStyle.applyTo(
            Label('<Not set>'))

        setLink = Hyperlink('CHANGE', _onSet)
        return self._dirBorderStyle.applyTo(
            Border(Row([dirLabel, Spacer(25.0, 0.0), setLink])))
Exemplo n.º 11
0
    def Page(self, fragment, inheritedState, page):
        root = page.rootNode
        if root is None:
            raise RuntimeError, 'No root node'
        isFrontPage = root.frontPage is page
        isStartupPage = root.startupPage is page

        class _RenameListener(TextEntry.TextEntryListener):
            def onAccept(self, textEntry, text):
                page.name = text

            def onCancel(self, textEntry, originalText):
                nameLive.setLiteralValue(nameBox)

        def _onRename(menuItem):
            textEntry = TextEntry(page.name, _RenameListener()).regexValidated(
                _nameRegex, 'Please enter a valid identifier')
            textEntry.grabCaretOnRealise()
            nameLive.setLiteralValue(textEntry)

        def _onDelete(menuItem):
            if page.parent is not None:
                page.parent.remove(page)

        def _onClearFrontPage(menuItem):
            root.frontPage = None

        def _onSetAsFrontPage(menuItem):
            root.frontPage = page

        def _onClearStartupPage(menuItem):
            root.startupPage = None

        def _onSetAsStartupPage(menuItem):
            root.startupPage = page

        def _pageContextMenuFactory(element, menu):
            menu.add(MenuItem.menuItemWithLabel('Rename', _onRename))
            menu.add(HSeparator())
            menu.add(MenuItem.menuItemWithLabel('Delete', _onDelete))
            menu.add(HSeparator())

            if isFrontPage:
                menu.add(
                    MenuItem.menuItemWithLabel('Clear front page',
                                               _onClearFrontPage))
            else:
                menu.add(
                    MenuItem.menuItemWithLabel('Set as front page',
                                               _onSetAsFrontPage))

            if isStartupPage:
                menu.add(
                    MenuItem.menuItemWithLabel('Clear startup page',
                                               _onClearStartupPage))
            else:
                menu.add(
                    MenuItem.menuItemWithLabel('Set as startup page',
                                               _onSetAsStartupPage))

            return True

        pageSubject = fragment.subject._pageSubject(page)

        link = Hyperlink(page.name, pageSubject)
        link = link.withContextMenuInteractor(_pageContextMenuFactory)
        nameBox = _itemHoverHighlightStyle.applyTo(Row([link]))
        nameBox = _ProjectTreeController.instance.item(page, nameBox)
        nameBox = nameBox.withDragSource(_linkDragSource)
        nameBox = AttachTooltip(
            nameBox,
            'Click to enter page.\nRight click to access context menu.', False)

        nameLive = LiveValue(nameBox)

        if isFrontPage or isStartupPage:
            notes = []
            if isFrontPage:
                notes.append(
                    _frontPageNoteBorder.surround(
                        _frontPageNoteStyle.applyTo(Label('Front page'))))
            if isStartupPage:
                notes.append(
                    _startupPageNoteBorder.surround(
                        _startupPageNoteStyle.applyTo(Label('Startup page'))))
            notesPres = _notesRowStyle.applyTo(Row(notes))
            pagePres = Row([nameLive, notesPres.padX(_notesGap, 0.0)])
        else:
            pagePres = nameLive

        return pagePres
Exemplo n.º 12
0
    def AppState(self, fragment, state, node):
        def _onNewDoc(link, event):
            def handleNewDocumentFn(document, firstPageSubjectFn):
                name = _newDocumentName(openDocuments)
                document.setDocumentName(name)

                node.registerOpenDocument(document)

                subject = document.newSubject(fragment.subject, None,
                                              document.getDocumentName())
                subject = firstPageSubjectFn(subject)

                pageController = link.element.rootElement.pageController
                pageController.openSubject(
                    subject, PageController.OpenOperation.OPEN_IN_CURRENT_TAB)

            element = link.getElement()
            openDocuments = node.getOpenDocuments()
            DocumentManagement.promptNewDocument(fragment.subject.world,
                                                 element, handleNewDocumentFn)

            return True

        def _onOpenDoc(link, event):
            def handleOpenedDocumentFn(fullPath, document):
                appDoc = node.registerOpenDocument(document)

            element = link.getElement()
            DocumentManagement.promptOpenDocument(
                fragment.subject.world,
                element.getRootElement().getComponent(),
                handleOpenedDocumentFn)

            return True

        def _onFileListDrop(element, targetPosition, data, action):
            world = fragment.subject.world
            for filename in data:
                filename = str(filename)

                document = Document.readFile(world, filename)
                node.registerOpenDocument(document)
            return True

        def _onNewConsole(link, event):
            consoles = node.getConsoles()
            index = _newConsoleIndex(consoles)
            appConsole = Application.AppConsole(index)
            node.addConsole(appConsole)

            subject = appConsole.subject(fragment.subject)

            pageController = link.element.rootElement.pageController
            pageController.openSubject(
                subject, PageController.OpenOperation.OPEN_IN_CURRENT_TAB)

            return True

        openDocViews = Pres.mapCoerce(node.getOpenDocuments())
        consoles = Pres.mapCoerce(node.getConsoles())

        systemLink = Hyperlink('TEST PAGES', TestsRootPage.instanceSubject)
        configurationLink = Hyperlink(
            'CONFIGURATION PAGE',
            fragment.subject.world.configuration.subject())
        aboutLink = Hyperlink('ABOUT', fragment.subject.aboutPageSubject)
        linkHeader = SplitLinkHeaderBar([aboutLink],
                                        [configurationLink, systemLink])

        title = TitleBar('The Larch Environment')

        newLink = Hyperlink('NEW', _onNewDoc)
        openLink = Hyperlink('OPEN', _onOpenDoc)
        openDocumentsBox = _contentsList([newLink, openLink], openDocViews,
                                         'Documents')
        openDocumentsBox = openDocumentsBox.withNonLocalDropDest(
            DataFlavor.javaFileListFlavor, _onFileListDrop)
        openDocumentsBox = AttachTooltip(
            openDocumentsBox,
            'Click NEW to create a new document. To open from a file, click OPEN, or drag files from a file explorer application.',
            False)

        newConsoleLink = Hyperlink('NEW', _onNewConsole)
        consolesBox = _contentsList([newConsoleLink], consoles,
                                    'Python consoles')


        tip = TipBox( [ NormalText( [ StrongSpan( 'Getting started: ' ), 'To get programming quickly, create a new Python console by pressing ', EmphSpan( 'new' ), ', beneath', EmphSpan( ' Python consoles' ), '.' ] ),
          NormalText( [ 'For something more easily modifiable and something you can save, press ', EmphSpan( 'new' ), ' beneath ', EmphSpan( 'Documents' ), ' and choose the ', EmphSpan( 'Quickstart: worksheet' ), ' option.' ] ),
          NormalText( [ StrongSpan( 'Tips: ' ), 'You can highlight items that have help tips by pressing F2. Hover the pointer over them to display the tips. ' + \
                   'Some items do not display their tips unless highlighting is enabled, in order to reduce clutter.' ] ),
          NormalText( [ StrongSpan( 'Command bar: ' ), 'The command bar can be invoked by pressing the ', EmphSpan( 'escape' ), ' key. From there you can type abbreviated commands to invoke them. '
            'Alternatively, type in part of the full name of a command and autocomplete will show a list of commands that match. '
            'Press ', EmphSpan( 'tab' ), ' to switch between the entries in the autocomplete list and press ', EmphSpan( 'enter' ), ' to execute the highlighted command. '
            'Bold letters shown within command names indicate abbreviations, e.g. ', EmphSpan( 's' ), ' for ', EmphSpan( 'save' ), ' and ', EmphSpan( 'sa' ), ' for ', EmphSpan( 'save as' ), '. '
            'You can type these to execute them quickly.' ] )],
               'larchcore.mainapp.tooltiphighlights' )

        head = Head([linkHeader, title])
        body = Body([
            openDocumentsBox.pad(0.0, 10.0).alignHLeft(),
            consolesBox.pad(0.0, 10.0).alignHLeft(), tip
        ])
        return StyleSheet.style(Primitive.editable(False)).applyTo(
            Page([head, body]))
Exemplo n.º 13
0
    def AppDocument(self, fragment, state, node):
        def _onSave(link, event):
            element = link.getElement()
            world = fragment.subject.world
            document = node.getDocument()

            if document.hasFilename():
                document.save()
            else:

                def handleSaveDocumentAsFn(filename):
                    document.saveAs(filename)

                DocumentManagement.promptSaveDocumentAs(
                    world,
                    element.getRootElement().getComponent(),
                    handleSaveDocumentAsFn)

        def _onSaveAs(link, event):
            element = link.getElement()
            world = fragment.subject.world
            document = node.getDocument()

            def handleSaveDocumentAsFn(filename):
                document.saveAs(filename)

            DocumentManagement.promptSaveDocumentAs(
                world,
                element.getRootElement().getComponent(),
                handleSaveDocumentAsFn, document.getFilename())

        def _onClose(link, event):
            element = link.getElement()
            world = fragment.subject.world
            document = node.getDocument()

            def _performClose():
                document.close()
                node.appState.unregisterDocument(document)

            if document.hasUnsavedData():
                response = JOptionPane.showOptionDialog(
                    element.rootElement.component,
                    'You have not saved your work. Close document anyway?',
                    'Unsaved data', JOptionPane.YES_NO_OPTION,
                    JOptionPane.WARNING_MESSAGE, None,
                    ['Close document', 'Cancel'], 'Cancel')
                if response == JOptionPane.YES_OPTION:
                    _performClose()
                else:
                    return
            else:
                _performClose()

        name = node.getName()

        document = node.getDocument()

        subject = node.getDocument().newSubject(fragment.subject, None,
                                                document.getDocumentName())
        docLink = Hyperlink(name, subject).padX(0.0, _appDocRightPadding)
        saveLink = Hyperlink('Save', _onSave)
        saveAsLink = Hyperlink('Save as', _onSaveAs)
        closeLink = Hyperlink('Close', _onClose)

        return GridRow([docLink, saveLink, saveAsLink, closeLink])
Exemplo n.º 14
0
 def Link(self, fragment, inheritedState, node):
     subject = node.getSubject(fragment.subject.documentSubject)
     return Hyperlink(node.text, subject)
Exemplo n.º 15
0
def _documentContextMenuFactory(element, menu):
	region = element.getRegion()
	rootElement = element.getRootElement()
	
	def makeParagraphStyleFn(style):
		def setStyle(model):
			model.setStyle(style)
		
		def _onLink(link, event):
			caret = rootElement.getCaret()
			if caret is not None and caret.isValid():
				caretElement = caret.getElement()
				if caretElement.getRegion() is region:
					_controller.modifyParagraphAtMarker(caret.getMarker(), setStyle)
		return _onLink
	
	def insertEmbedPara(link, event):
		def _newEmbedPara():
			img = _imageFileChooser(link.element, lambda f: _ParaImage(f))
			return embed.ParaEmbed(img)   if img is not None   else None
		
		caret = rootElement.getCaret()
		if caret is not None and caret.isValid():
			caretElement = caret.getElement()
			if caretElement.getRegion() is region:
				_controller.insertParagraphAtCaret(caret, _newEmbedPara)
	
	normalStyle = Hyperlink('Normal', makeParagraphStyleFn('normal'))
	h1Style = Hyperlink('H1', makeParagraphStyleFn('h1'))
	h2Style = Hyperlink('H2', makeParagraphStyleFn('h2'))
	h3Style = Hyperlink('H3', makeParagraphStyleFn('h3'))
	h4Style = Hyperlink('H4', makeParagraphStyleFn('h4'))
	h5Style = Hyperlink('H5', makeParagraphStyleFn('h5'))
	h6Style = Hyperlink('H6', makeParagraphStyleFn('h6'))
	titleStyle = Hyperlink('Title', makeParagraphStyleFn('title'))
	paraStyles = ControlsRow([normalStyle, h1Style, h2Style, h3Style, h4Style, h5Style, h6Style, titleStyle])
	embedPara = Hyperlink('Embed para', insertEmbedPara)
	paraEmbeds = ControlsRow([embedPara])
	menu.add(Section(SectionHeading2('Paragraph styles'), paraStyles))
	menu.add(Section(SectionHeading2('Paragraph embeds'), paraEmbeds))
	
	
	def makeStyleFn(attrName):
		def computeStyleValues(listOfSpanAttrs):
			value = listOfSpanAttrs[0].getValue(attrName, 0)
			value = not value
			attrs = RichTextAttributes()
			attrs.putOverride(attrName, value)
			return attrs
		
		def onButton(button, event):
			selection = rootElement.getSelection()
			if isinstance(selection, TextSelection):
				if selection.getRegion() == region:
					_controller.applyStyleToSelection(selection, computeStyleValues)
		return onButton
	
	def _onInsertInlineEmbed(button, event):
		def _newInlineEmbedValue():
			return _imageFileChooser(button.element, lambda f: _InlineImage(f))
		
		caret = rootElement.getCaret()
		if caret is not None and caret.isValid():
			caretElement = caret.getElement()
			if caretElement.getRegion() is region:
				_controller.insertInlineEmbedAtMarker(caret.getMarker(), _newInlineEmbedValue)
	
	def style_button(text, on_click, *style_values):
		sty = StyleSheet.instance.withValues(Primitive.fontFace(Primitive.monospacedFontName),
						     *style_values)
		return Button(sty.applyTo(Label(text)), on_click)

	italicStyle = style_button('I', makeStyleFn('i'), Primitive.fontItalic(True))
	boldStyle = style_button('B', makeStyleFn('b'), Primitive.fontBold(True))
	codeStyle = style_button('code', makeStyleFn('code'))
	cmdStyle = style_button('> cmd', makeStyleFn('cmd'))
	appStyle = style_button('app', makeStyleFn('app'))
	sysStyle = style_button('sys', makeStyleFn('sys'))
	styles = ControlsRow([italicStyle, boldStyle, codeStyle, cmdStyle, appStyle, sysStyle]).alignHLeft()
	insertInlineEmbed = Button.buttonWithLabel('Embed', _onInsertInlineEmbed)
	inlineEmbeds = ControlsRow([insertInlineEmbed]).alignHLeft()
	
	menu.add(Section(SectionHeading2('Selection styles'), styles))
	menu.add(Section(SectionHeading2('Inline embeds'), inlineEmbeds))
	
	
	return True