def InlinePythonCode(self, fragment, inheritedState, node): assert isinstance(node, ViewSchema.InlinePythonCodeView) if node.isCodeVisible(): exprView = Python2.python2EditorPerspective.applyTo( Pres.coerce(node.getExpr())) if node.isCodeEditable(): exprView = StyleSheet.style( Primitive.editable(True)).applyTo(exprView) else: exprView = None executionResultView = None executionResult = node.getResult() if executionResult is not None: if node.isResultMinimal(): executionResultView = executionResult.minimalView() else: executionResultView = executionResult.view() if node.isCodeVisible(): boxContents = [ _pythonCodeBorderStyle.applyTo( Border(exprView.alignHExpand()).alignHExpand()) ] if executionResultView is not None: boxContents.append(executionResultView.alignHExpand()) box = StyleSheet.style(Primitive.rowSpacing(5.0)).applyTo( Row(boxContents)) return _pythonCodeEditorBorderStyle.applyTo( Border(box.alignHExpand()).alignHExpand()) else: return executionResultView.alignHPack( ) if executionResultView is not None else Proxy()
class XmlElemSpan(abstract_text.MRTAbstractText): contents_query = elem_query.children()\ .map(abstract_text.remove_whitespace, elem.identity)\ .project_to_objects(mappings.text_mapping) def __init__(self, projection_table, elem, contents=None): super(XmlElemSpan, self).__init__(projection_table, elem, contents) elem_tag_and_attrs = XmlElemTagAndAttrs.from_xml_elem(elem) self._elem_tag_and_attrs = elem_tag_and_attrs self._editorModel = controller.MallardRichTextController.instance.editorModelSpan( [], self._span_attrs(elem_tag_and_attrs)) def node_init(self): self._editorModel.setModelContents( controller.MallardRichTextController.instance, list(self.contents_query)) def setElementTagAndAttrs(self, elem_tag_and_attrs): self._elem_tag_and_attrs = elem_tag_and_attrs self._editorModel.setSpanAttrs(self._span_attrs(elem_tag_and_attrs)) self._incr.onChanged() def getElementTagAndAttrs(self): self._incr.onAccess() return self._elem_tag_and_attrs def __present__(self, fragment, inheritedState): self._incr.onAccess() open_tag = self._tag_border.surround( self._open_tag_style(Label(self._elem_tag_and_attrs.tag))) close_tag = self._tag_border.surround( self._close_tag_style(Label('/' + self._elem_tag_and_attrs.tag))) x = RichSpan([open_tag] + list(self.contents_query) + [close_tag]) x = controller.MallardRichTextController.instance.editableSpan(self, x) return x @staticmethod def _span_attrs(elem_tag_and_attrs): return RichTextAttributes.fromValues(None, {XML_ELEM: [elem_tag_and_attrs]}) @staticmethod def new_span(mapping, contents, elem_tag_and_attrs): return XmlElemSpan(mapping, elem_tag_and_attrs.create_xml_elem(), contents) _tag_border = SolidBorder(1.0, 1.0, 4.0, 4.0, Color(0.4, 0.42, 0.45), Color(0.95, 0.975, 1.0)) _open_tag_style = StyleSheet.style( Primitive.fontSize(10), Primitive.foreground(Color(0.0, 0.3, 0.8)), Primitive.fontFace('Monospaced')) _close_tag_style = StyleSheet.style( Primitive.fontSize(10), Primitive.foreground(Color(0.3, 0.35, 0.4)), Primitive.fontFace('Monospaced'))
def _createStyleSheet(self): def suffix(fontName, defaultFont): if defaultFont in [f.strip() for f in fontName.split(';')]: return fontName elif fontName.strip() == '': return defaultFont else: return fontName + '; ' + defaultFont style = StyleSheet.style( Primitive.fontFace(suffix(self._generic.getValue(), 'SansSerif')), RichText.titleTextAttrs( RichText.titleTextAttrs.defaultValue.withValues( Primitive.fontFace(suffix(self._title.getValue(), 'Serif')))), RichText.headingTextAttrs( RichText.headingTextAttrs.defaultValue.withValues( Primitive.fontFace( suffix(self._heading.getValue(), 'Serif')))), RichText.normalTextAttrs( RichText.normalTextAttrs.defaultValue.withValues( Primitive.fontFace( suffix(self._normal.getValue(), 'SansSerif')))), UI.uiTextAttrs( UI.uiTextAttrs.defaultValue.withValues( Primitive.fontFace( suffix(self._uiHeading.getValue(), 'SansSerif'))))) return style
def headingSample(fontName, text='The quick brown fox jumps over the lazy dog'): style = StyleSheet.style( RichText.headingTextAttrs( RichText.headingTextAttrs.defaultValue.withValues( Primitive.fontFace(fontName)))) return style(Heading1(text))
def normalSample(fontName, text='The quick brown fox jumps over the lazy dog'): style = StyleSheet.style( RichText.normalTextAttrs( RichText.normalTextAttrs.defaultValue.withValues( Primitive.fontFace(fontName)))) return style(NormalText(text))
def __present__(self, fragment, inheritedState): pythonModule = self.getPythonModule() executionResult = self.getExecResult() caughtException = executionResult.getCaughtException() result = executionResult.getResult() streams = executionResult.getStreams() moduleView = StyleSheet.style( Primitive.editable( False ) ).applyTo( Python2.python2EditorPerspective.applyTo( pythonModule ) ) caughtExceptionView = ApplyPerspective.defaultPerspective( caughtException ) if caughtException is not None else None resultView = ApplyPerspective.defaultPerspective( result[0] ) if result is not None else None code = _pythonModuleBorderStyle.applyTo( Border( moduleView.alignHExpand() ).alignHExpand() ) outputContents = [] for stream in streams: if stream.name == 'out': outputContents.append( execStdout( stream.richString, True ) ) elif stream.name == 'err': outputContents.append( execStderr( stream.richString, True ) ) else: raise ValueError, 'Unreckognised stream \'{0}\''.format( stream.name ) if caughtExceptionView is not None: outputContents.append( execException( caughtExceptionView ) ) if resultView is not None: outputContents.append( execResult( resultView ) ) outputColumn = _blockOutputStyle.applyTo( Column( outputContents ).alignHExpand() ) return _blockStyle.applyTo( Border( Column( [ code, outputColumn ] ) ) ).alignHExpand()
class _FrameBox (object): def __init__(self, frame, valuesLive): self._frame = frame self._valuesLive = valuesLive def __present__(self, fragment, inheritedState): interactor = _FrameInteractor( self._frame, self._valuesLive ) box = Box( 15.0, 5.0 ).withElementInteractor( interactor ) if self._valuesLive.getValue() is self._frame.values: return self._selectedTabFrameStyle.applyTo( box ) else: return self._tabFrameStyle.applyTo( box ) _tabFrameStyle = StyleSheet.style( Primitive.shapePainter( FilledOutlinePainter( Color( 0.85, 0.9, 0.85 ), Color( 0.6, 0.8, 0.6 ) ) ), Primitive.hoverShapePainter( FilledOutlinePainter( Color( 0.6, 0.8, 0.6 ), Color( 0.0, 0.5, 0.0 ) ) ) ) _selectedTabFrameStyle = StyleSheet.style( Primitive.shapePainter( FilledOutlinePainter( Color( 1.0, 1.0, 0.85 ), Color( 1.0, 0.8, 0.0 ) ) ), Primitive.hoverShapePainter( FilledOutlinePainter( Color( 1.0, 1.0, 0.6 ), Color( 1.0, 0.5, 0.0 ) ) ) )
def uiHeadingSample(fontName, text='The quick brown fox jumps over the lazy dog' ): style = StyleSheet.style( UI.uiTextAttrs( UI.uiTextAttrs.defaultValue.withValues( Primitive.fontFace(fontName)))) return style(SectionHeading1(text))
class GUIArrow(GUILeafComponent): componentName = 'Arrow' size = TypedEvalField(float, 12.0) direction = TypedEvalField(Arrow.Direction, Arrow.Direction.RIGHT) def _presentLeafContents(self, fragment, inheritedState): return Arrow(self.direction.getValueForEditor(), self.size.getValueForEditor()) _offStyle = StyleSheet.style( Primitive.shapePainter(FillPainter(Color(0.4, 0.4, 0.4)))) _onStyle = StyleSheet.style( Primitive.shapePainter(FillPainter(Color(0.2, 0.2, 0.2)))) @staticmethod def _arrowDirectionEditor(live): offOptions = [ GUIArrow._offStyle(Arrow(dir, 14.0).alignVCentre()) for dir in Arrow.Direction.values() ] onOptions = [ GUIArrow._onStyle(Arrow(dir, 14.0).alignVCentre()) for dir in Arrow.Direction.values() ] return enumSwitchButtonEditor(live, Arrow.Direction, offOptions, onOptions) def _editUIFormSections(self): direction = Form.SmallSection( 'Direction', None, self.direction.editUI(self._arrowDirectionEditor)) size = Form.SmallSection( 'Size', None, self.size.editUI( lambda live: RealSpinEntry(live, 0.0, 1048576.0, 1.0, 10.0))) superSections = super(GUIArrow, self)._editUIFormSections() return [direction, size] + superSections def __component_py_evalmodel__(self, codeGen): arrow = codeGen.embeddedValue(Arrow) direction = self.direction.__py_evalmodel__(codeGen) size = self.size.__py_evalmodel__(codeGen) return Py.Call(target=arrow, args=[direction, size])
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 PythonCode(self, fragment, inheritedState, node): if node.isVisible(): if node.isCodeVisible(): codeView = Python2.python2EditorPerspective.applyTo( Pres.coerce(node.getCode())) if node.isCodeEditable(): codeView = StyleSheet.style( Primitive.editable(True)).applyTo(codeView) else: codeView = None executionResultView = None executionResult = node.getResult() if executionResult is not None: if not node.isResultVisible(): executionResult = executionResult.suppressStdOut( ).suppressResult() if node.isMinimal(): executionResultView = executionResult.minimalView() else: executionResultView = executionResult.view() if node.isMinimal(): return executionResultView.alignHExpand( ) if executionResultView is not None else Blank() else: boxContents = [] if node.isCodeVisible(): boxContents.append( _pythonCodeBorderStyle.applyTo( Border(codeView.alignHExpand()).alignHExpand())) if node.isResultVisible() and executionResultView is not None: boxContents.append(executionResultView.alignHExpand()) box = StyleSheet.style(Primitive.columnSpacing(5.0)).applyTo( Column(boxContents)) return _pythonCodeEditorBorderStyle.applyTo( Border(box.alignHExpand()).alignHExpand()) else: return Blank()
def __compute_style_map(self): attrs = self._model['styleAttrs'] m = {} styles = [] for a in attrs: key = a['name'] value = a['value'] m[key] = value styles.append(self._styleMap[key](value)) return m, StyleSheet.style(*styles)
class LiterateExpression(object): def __init__(self, expr=None): if expr is None: expr = EmbeddedPython2Expr() self._expr = expr self._incr = IncrementalValueMonitor() self.__change_history__ = None def __getstate__(self): return {'expr': self._expr} def __setstate__(self, state): self._expr = state['expr'] self._incr = IncrementalValueMonitor() self.__change_history__ = None def __get_trackable_contents__(self): return [self._expr] def __py_evalmodel__(self, codeGen): return self._expr.model def __py_replacement__(self): return deepcopy(self._expr.model['expr']) def _new_reference(self): return LiterateExpression(self._expr) def __present__(self, fragment, inheritedState): self._incr.onAccess() exprPres = self._expr header = Row([ self._angleQuoteStyle(Label(u'\u00ab')), self._angleQuoteStyle(Label(u'\u00bb')), Spacer(9.0, 0.0) ]).withDragSource(_dragSource) return ObjectBorder(Row([header.alignVCentre(), exprPres])) _angleQuoteStyle = StyleSheet.style( Primitive.foreground(Color(0.15, 0.15, 0.45)), Primitive.fontBold(True), Primitive.fontSize(12))
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 embeddedObjectMacro(ctx, style, valueView, modelView): modelView = StyleSheet.style(Primitive.editable(False)).applyTo(modelView) embeddedObjectBorderStyle = style.get( PythonEditorStyle.embeddedObjectBorderStyle) embeddedObjectLineStyle = style.get( PythonEditorStyle.embeddedObjectLineStyle) embeddedObjectExpansionLabelStyle = style.get( PythonEditorStyle.embeddedObjectExpansionLabelStyle) hLine = embeddedObjectLineStyle.applyTo(Box(1, 1).alignHExpand()).pad( 8.0, 2.0).alignHExpand() expansionLabel = embeddedObjectExpansionLabelStyle.applyTo( Label('Expansion')) expander = DropDownExpander(expansionLabel, modelView) view = embeddedObjectBorderStyle.applyTo( Border(Column([valueView, expander]))) segment = Segment(view) return segment.present(ctx, style)
class ExecutionStyle(object): pythonExecution = AttributeNamespace('pythonExecution') labelStyle = InheritedAttributeNonNull( pythonExecution, 'labelStyle', StyleSheet, StyleSheet.style(Primitive.fontSize(10))) stdOutStyle = InheritedAttributeNonNull( pythonExecution, 'stdOutStyle', StyleSheet, StyleSheet.style( Primitive.border( SolidBorder(1.0, 3.0, 7.0, 7.0, Color(0.5, 1.0, 0.5), Color(0.9, 1.0, 0.9))), Primitive.foreground(Color(0.0, 0.5, 0.0)))) stdErrStyle = InheritedAttributeNonNull( pythonExecution, 'stdErrStyle', StyleSheet, StyleSheet.style( Primitive.border( SolidBorder(1.0, 3.0, 7.0, 7.0, Color(1.0, 0.75, 0.5), Color(1.0, 0.95, 0.9))), Primitive.foreground(Color(0.75, 0.375, 0.0)))) exceptionBorderStyle = InheritedAttributeNonNull( pythonExecution, 'exceptionBorderStyle', StyleSheet, StyleSheet.style( Primitive.border( SolidBorder(1.0, 3.0, 7.0, 7.0, Color(0.8, 0.0, 0.0), Color(1.0, 0.9, 0.9))))) resultBorderStyle = InheritedAttributeNonNull( pythonExecution, 'resultBorderStyle', StyleSheet, StyleSheet.style( Primitive.border( SolidBorder(1.0, 3.0, 10.0, 10.0, Color(0.0, 0.0, 0.8), Color.WHITE)))) resultBoxStyle = InheritedAttributeNonNull( pythonExecution, 'resultSpacing', StyleSheet, StyleSheet.style(Primitive.columnSpacing(5.0))) @PyDerivedValueTable(pythonExecution) def _resultBoxStyle(style): resultSpacing = style.get(ExecutionStyle.resultSpacing) return style.withValues(Primitive.columnSpacing(resultSpacing))
def titleSample(fontName, text='The quick brown fox'): style = StyleSheet.style( RichText.titleTextAttrs( RichText.titleTextAttrs.defaultValue.withValues( Primitive.fontFace(fontName)))) return style(TitleBar(text))
from BritefuryJ.StyleSheet import StyleSheet, StyleValues from BritefuryJ.LSpace.Interactor import PushElementInteractor from BritefuryJ.LSpace.Input import Modifier from BritefuryJ.Live import LiveValue, LiveFunction from Britefury.Config.UserConfig import loadUserConfig, saveUserConfig from Britefury.Config import Configuration from Britefury.Config.ConfigurationPage import ConfigurationPage # Font chooser _ge = GraphicsEnvironment.getLocalGraphicsEnvironment() _fontNames = sorted([font.name for font in _ge.allFonts]) _nameStyle = StyleSheet.style(Primitive.fontSize(10), Primitive.foreground(Color(0.45, 0.45, 0.45))) _hoverStyle = StyleSheet.style( Primitive.hoverBackground( FilledOutlinePainter(Color(0.95, 0.95, 0.95), Color(0.65, 0.65, 0.65)))) _headerNameStyle = StyleSheet.style(Primitive.fontItalic(True)) def _fontSample(fontName, sampleFn): sample = sampleFn(fontName) name = Label(fontName) return _hoverStyle( Bin( Column([ sample, _nameStyle(name).padX(10.0, 0.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]))
##-* licensed under the MIT license, a copy of which can be found in ##-* the file 'COPYING'. ##-************************* from BritefuryJ.Controls import Hyperlink from BritefuryJ.Pres.Primitive import Primitive from BritefuryJ.Pres.RichText import SplitLinkHeaderBar, TitleBar, Page, Head, Body from BritefuryJ.StyleSheet import StyleSheet from BritefuryJ.Projection import TransientSubject from Britefury.Util.Abstract import abstractmethod _staticStyle = StyleSheet.style( Primitive.editable( False ) ) class ConfigurationPage (object): class _ConfigPageSubject (TransientSubject): def __init__(self, enclosingSubject, page): super( ConfigurationPage._ConfigPageSubject, self ).__init__( enclosingSubject ) self._page = page def getFocus(self): return self._page def getTitle(self): return self._page.getSubjectTitle()
class ConfigurationPage (object): class _ConfigPageSubject (TransientSubject): def __init__(self, enclosingSubject, page): super( ConfigurationPage._ConfigPageSubject, self ).__init__( enclosingSubject ) self._page = page def getFocus(self): return self._page def getTitle(self): return self._page.getSubjectTitle() def __init__(self): self.__config = None def __getstate__(self): return {} def __setstate__(self, state): pass def initPage(self, config): self.__config = config def subject(self, enclosingSubject=None): if enclosingSubject is None: enclosingSubject = self.__config.subject() return self._ConfigPageSubject( enclosingSubject, self ) @abstractmethod def getSubjectTitle(self): pass @abstractmethod def getTitleText(self): pass @abstractmethod def getLinkText(self): pass @abstractmethod def __present_contents__(self, fragment, inheritedState): pass 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 ] ) ) _configPageStyle = StyleSheet.style( Primitive.editable( False ) )
if not isinstance(model, ProjectPage): raise TypeError, 'model is not a project page, it is a %s' % type( model) fragment = element.fragmentContext pageSubject = fragment.subject._pageSubject(model) return pageSubject def _dragSourceCreateLink(element, aspect): return LinkSubjectDrag(_getSubjectOfPageNameElement(element)) _linkDragSource = ObjectDndHandler.DragSource(LinkSubjectDrag, _dragSourceCreateLink) _controlsStyle = StyleSheet.style(Controls.bClosePopupOnActivate(True)) _projectIndexNameStyle = StyleSheet.style( Primitive.foreground(Color(0.25, 0.35, 0.5)), Primitive.fontSize(16), Primitive.fontFace(Primitive.lightFontName)) _packageNameStyle = StyleSheet.style( Primitive.foreground(Color(0.0, 0.0, 0.5)), Primitive.fontSize(14), Primitive.fontFace(Primitive.lightFontName)) _itemHoverHighlightStyle = StyleSheet.style( Primitive.hoverBackground( FilledOutlinePainter(Color(0.8, 0.825, 0.9), Color(0.125, 0.341, 0.574), BasicStroke(1.0)))) _pythonPackageNameStyle = StyleSheet.style( Primitive.foreground(Color(0.0, 0.0, 0.5))) _pythonPackageNameNotSetStyle = StyleSheet.style( Primitive.foreground(Color(0.5, 0.0, 0.0))) _pythonPackageNameNotSetCommentStyle = StyleSheet.style(
from BritefuryJ.StyleSheet import StyleSheet from BritefuryJ.DefaultPerspective import DefaultPerspective from BritefuryJ.Projection import TransientSubject from Britefury.Kernel.Document import Document from LarchCore.MainApp.MainAppViewer.View import perspective from LarchCore.MainApp.MainAppViewer.AboutPage import AboutPage from Britefury import app_in_jar from main_app import editor_page _page_style = StyleSheet.style(Primitive.selectable(False), Primitive.editable(False)) _dir_style = StyleSheet.style(Primitive.foreground(Color(0.0, 0.2, 0.4))) def _get_examples(): names_and_bytes = None # z is the zip file containing the examples z = None if app_in_jar.startedFromJar(): # App started from JAR; attempt to acquire through java.lang.Class.getResourceAsStream() stream = Column.getResourceAsStream('/mallard_examples.zip') if stream is not None: # Convert to cStringIO; FileUtil.wrap does not seem to work well with ZipFile
def ProjectRoot(self, fragment, inheritedState, project): # Save and Save As def _onSave(control, buttonEvent): if document.hasFilename(): document.save() else: def handleSaveDocumentAsFn(filename): document.saveAs(filename) DocumentManagement.promptSaveDocumentAs( world, control.getElement().getRootElement().getComponent(), handleSaveDocumentAsFn) def _onSaveAs(control, buttonEvent): def handleSaveDocumentAsFn(filename): document.saveAs(filename) DocumentManagement.promptSaveDocumentAs( world, control.getElement().getRootElement().getComponent(), handleSaveDocumentAsFn, document.getFilename()) def _onReload(control, buttonEvent): if document.hasFilename(): document.save() document.reload() project.reset() else: def handleSaveDocumentAsFn(filename): document.saveAs(filename) document.reload() project.reset() DocumentManagement.promptSaveDocumentAs( world, control.getElement().getRootElement().getComponent(), handleSaveDocumentAsFn) def _onExport(control, event): component = control.getElement().getRootElement().getComponent() openDialog = JFileChooser() openDialog.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY) response = openDialog.showDialog(component, 'Export') 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): response = JOptionPane.showOptionDialog( component, 'Existing content will be overwritten. Proceed?', 'Overwrite existing content', JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, None, ['Overwrite', 'Cancel'], 'Cancel') if response == JFileChooser.APPROVE_OPTION: exc = None try: project.export(filename) except: exc = JythonException.getCurrentException() if exc is not None: BubblePopup.popupInBubbleAdjacentTo( DefaultPerspective.instance(exc), control.getElement(), Anchor.BOTTOM, True, True) # Python package name class _PythonPackageNameListener(EditableLabel.EditableLabelListener): def onTextChanged(self, editableLabel, text): if text != '': project.pythonPackageName = text else: project.pythonPackageName = None # Project index def _addPackage(menuItem): project.append(ProjectPackage('NewPackage')) def _addPage(page): project.append(page) def _projectIndexContextMenuFactory(element, menu): menu.add(MenuItem.menuItemWithLabel('New package', _addPackage)) newPageMenu = PageData.newPageMenu(_addPage) importPageMenu = PageData.importPageMenu( element.getRootElement().getComponent(), _addPage) menu.add( MenuItem.menuItemWithLabel( 'New page', newPageMenu, MenuItem.SubmenuPopupDirection.RIGHT)) menu.add( MenuItem.menuItemWithLabel( 'Import page', importPageMenu, MenuItem.SubmenuPopupDirection.RIGHT)) return True # Get some initial variables document = fragment.subject.document world = fragment.subject.world # Title title = TitleBar(document.getDocumentName()) # Controls for 'save' and 'save as' saveExportHeader = SectionHeading1('Save/export') saveButton = Button.buttonWithLabel('Save', _onSave) saveAsButton = Button.buttonWithLabel('Save as', _onSaveAs) reloadButton = Button.buttonWithLabel('Save and reload', _onReload) reloadButton = AttachTooltip( reloadButton, 'Saves and reloads the project from scratch\nCauses all embedded objects to be re-created.' ) exportButton = Button.buttonWithLabel('Export', _onExport) exportButton = AttachTooltip( exportButton, 'Exports project contents to text files where possible.') saveBox = Row([ saveButton.padX(10.0), Spacer(30.0, 0.0), saveAsButton.padX(10.0), Spacer(30.0, 0.0), reloadButton.padX(10.0), Spacer(50.0, 0.0), exportButton.padX(10.0) ]).alignHLeft() saveExportSection = Section(saveExportHeader, saveBox) # # Project Section # # Python package name notSet = _pythonPackageNameNotSetStyle.applyTo(Label('<not set>')) pythonPackageNameLabel = EditableLabel( project.pythonPackageName, notSet, _PythonPackageNameListener()).regexValidated( _pythonPackageNameRegex, 'Please enter a valid dotted identifier') pythonPackageNameLabel = AttachTooltip( pythonPackageNameLabel, 'The root python package name is the name under which the contents of the project can be imported using import statements within the project.\n' + \ 'If this is not set, pages from this project cannot be imported.', False ) pythonPackageNameRow = Form.Section( 'Root Python package name', 'Pages will not be importable unless this is set', pythonPackageNameLabel) # Clear imported modules def _onReset(button, event): project.reset() modules = document.unloadAllImportedModules() heading = SectionHeading2('Unloaded modules:') modules = Column([Label(module) for module in modules]) report = Section(heading, modules) BubblePopup.popupInBubbleAdjacentTo(report, button.getElement(), Anchor.BOTTOM, True, True) resetButton = Button.buttonWithLabel('Reset', _onReset) resetButton = AttachTooltip( resetButton, 'Unloads all modules that were imported from this project from the Python module cache. This way they can be re-imported, allowing modifications to take effect.' ) resetRow = Form.Section('Reset', 'Unload project modules', resetButton) projectSection = Form('Project', [pythonPackageNameRow, resetRow]) # Project index indexHeader = SectionHeading1('Index') nameElement = _projectIndexNameStyle.applyTo(Label('Project root')) nameBox = _itemHoverHighlightStyle.applyTo(nameElement.alignVCentre()) nameBox = nameBox.withContextMenuInteractor( _projectIndexContextMenuFactory) nameBox = _ProjectTreeController.instance.item(project, nameBox) nameBox = AttachTooltip( nameBox, 'Right click to access context menu, from which new pages and packages can be created.\n' + \ 'A page called index at the root will appear instead of the project page. A page called __startup__ will be executed at start time.', False ) itemsBox = Column(project[:]).alignHExpand() itemsBox = _ProjectTreeController.instance.editableList( project, itemsBox) contentsView = Column([ nameBox.alignHExpand(), itemsBox.padX(_packageContentsIndentation, 0.0).alignHExpand() ]) indexSection = Section(indexHeader, contentsView) def _onBuildJar(button, event): _buildProjectJar(button.element, document) buildJarButton = Button.buttonWithLabel('Build JAR', _onBuildJar) jarRow = Form.Section('Build executable app', 'Export the project as an executable JAR', buildJarButton) packagingSection = Form('Packaging', [jarRow]) indexTip = TipBox([ NormalText([ StrongSpan('Index: '), 'Larch projects act like Python programs. Packages act as directories/packages and pages act as Python source files. Pages can import code from one another as if they are modules.' ]), NormalText([ 'New pages and packages can be created by right clicking on the entries in the index or on ', EmphSpan('Project root'), ' (they will highlight as you hover over them).' ]), NormalText([ StrongSpan('Front and startup pages: '), 'If a page is set as the front page it will appear instead of the project page. In these cases, the project page can still be reached using the links in the location bar at the top of the window.' ]), 'If a page is set as the startup page, code within it will be executed before all other pages. This can be used for registering editor extensions.', 'To set a page as the front page or the startup page, right-click on it to show its context menu and choose the appropriate option.' ], 'larchcore.worksheet.worksheeteditor') # The page head = Head([title]) body = Body([ saveExportSection, projectSection, indexSection, packagingSection, indexTip ]).alignHPack() return StyleSheet.style(Primitive.editable(False)).applyTo( Page([head, body]))
class FontConfiguration(object): def __init__(self, generic=Primitive.genericFontName, normal=Primitive.normalTextFontName, heading=Primitive.headingFontName, title=Primitive.titleFontName, uiHeading=Primitive.lightFontName): self._generic = LiveValue(generic) self._normal = LiveValue(normal) self._heading = LiveValue(heading) self._title = LiveValue(title) self._uiHeading = LiveValue(uiHeading) def __getstate__(self): state = {} state['generic'] = self._generic.getStaticValue() state['normal'] = self._normal.getStaticValue() state['heading'] = self._heading.getStaticValue() state['title'] = self._title.getStaticValue() state['uiHeading'] = self._uiHeading.getStaticValue() return state def __setstate__(self, state): self._generic = LiveValue(state.get('generic', 'SansSerif')) self._normal = LiveValue(state.get('normal', 'SansSerif')) self._heading = LiveValue(state.get('heading', 'Serif')) self._title = LiveValue(state.get('title', 'Serif')) self._uiHeading = LiveValue(state.get('uiHeading', 'SansSerif')) def copyFrom(self, config): self._generic.setLiteralValue(config._generic.getStaticValue()) self._normal.setLiteralValue(config._normal.getStaticValue()) self._heading.setLiteralValue(config._heading.getStaticValue()) self._title.setLiteralValue(config._title.getStaticValue()) self._uiHeading.setLiteralValue(config._uiHeading.getStaticValue()) def _createStyleSheet(self): def suffix(fontName, defaultFont): if defaultFont in [f.strip() for f in fontName.split(';')]: return fontName elif fontName.strip() == '': return defaultFont else: return fontName + '; ' + defaultFont style = StyleSheet.style( Primitive.fontFace(suffix(self._generic.getValue(), 'SansSerif')), RichText.titleTextAttrs( RichText.titleTextAttrs.defaultValue.withValues( Primitive.fontFace(suffix(self._title.getValue(), 'Serif')))), RichText.headingTextAttrs( RichText.headingTextAttrs.defaultValue.withValues( Primitive.fontFace( suffix(self._heading.getValue(), 'Serif')))), RichText.normalTextAttrs( RichText.normalTextAttrs.defaultValue.withValues( Primitive.fontFace( suffix(self._normal.getValue(), 'SansSerif')))), UI.uiTextAttrs( UI.uiTextAttrs.defaultValue.withValues( Primitive.fontFace( suffix(self._uiHeading.getValue(), 'SansSerif'))))) return style def apply(self): StyleValues.setRootStyleSheet(self._createStyleSheet()) def __present__(self, fragment, inheritedState): helpText = NormalText( 'Click to open the font choosers. Click on a font sample to choose it. Ctrl-click to select additional fonts.' ) def titleSample(fontName, text='The quick brown fox'): style = StyleSheet.style( RichText.titleTextAttrs( RichText.titleTextAttrs.defaultValue.withValues( Primitive.fontFace(fontName)))) return style(TitleBar(text)) titleChooser = _collapsibleFontChooser('Titles', self._title, titleSample) def headingSample(fontName, text='The quick brown fox jumps over the lazy dog'): style = StyleSheet.style( RichText.headingTextAttrs( RichText.headingTextAttrs.defaultValue.withValues( Primitive.fontFace(fontName)))) return style(Heading1(text)) headingChooser = _collapsibleFontChooser('Headings', self._heading, headingSample) def normalSample(fontName, text='The quick brown fox jumps over the lazy dog'): style = StyleSheet.style( RichText.normalTextAttrs( RichText.normalTextAttrs.defaultValue.withValues( Primitive.fontFace(fontName)))) return style(NormalText(text)) normalChooser = _collapsibleFontChooser('Normal text', self._normal, normalSample) def uiHeadingSample(fontName, text='The quick brown fox jumps over the lazy dog' ): style = StyleSheet.style( UI.uiTextAttrs( UI.uiTextAttrs.defaultValue.withValues( Primitive.fontFace(fontName)))) return style(SectionHeading1(text)) uiHeadingChooser = _collapsibleFontChooser('UI Headings', self._uiHeading, uiHeadingSample) def genericSample(fontName, text='The quick brown fox jumps over the lazy dog'): style = StyleSheet.style(Primitive.fontFace(fontName)) return style(Label(text)) genericChooser = _collapsibleFontChooser('Generic text', self._generic, genericSample) chooserColumn = self._chooserColumnStyle( Column([ titleChooser, headingChooser, normalChooser, uiHeadingChooser, genericChooser ])) # Sample page @LiveFunction def samplePage(): label = Label('Sample page:') title = titleSample(self._title.getValue(), 'Example Page Title') heading = headingSample(self._heading.getValue(), 'Main heading') normal1 = normalSample(self._normal.getValue(), 'Normal text will appear like this.') normal2 = normalSample( self._normal.getValue(), 'Paragraphs of normal text are used for standard content.') ui1 = uiHeadingSample(self._uiHeading.getValue(), 'UI heading') genericLabel = Label( 'Generic text (within controls, code, etc) will appear like this.' ) buttons = self._buttonRowStyle( Row([ Button.buttonWithLabel('Button %d' % (i, ), None) for i in xrange(0, 5) ])) ui = Section(ui1, Column([genericLabel, Spacer(0.0, 7.0), buttons])) page = Page([title, Body([heading, normal1, normal2, ui])]) return Column([label, Spacer(0.0, 15.0), page]) return self._mainColumnStyle( Column([helpText, chooserColumn, samplePage])) _mainColumnStyle = StyleSheet.style(Primitive.columnSpacing(30.0)) _chooserColumnStyle = StyleSheet.style(Primitive.columnSpacing(5.0)) _buttonRowStyle = StyleSheet.style(Primitive.rowSpacing(10.0))
def genericSample(fontName, text='The quick brown fox jumps over the lazy dog'): style = StyleSheet.style(Primitive.fontFace(fontName)) return style(Label(text))
class FontConfigurationPage(ConfigurationPage): def __init__(self): super(FontConfigurationPage, self).__init__() self._config = None self._userConfig = LiveValue(self._config) def __getstate__(self): state = super(FontConfigurationPage, self).__getstate__() state['config'] = self._config return state def __setstate__(self, state): super(FontConfigurationPage, self).__setstate__(state) self._config = state.get('config') self._userConfig = LiveValue(self._config) def getSubjectTitle(self): return '[CFG] Fonts' def getTitleText(self): return 'Font Configuration' def getLinkText(self): return 'Fonts' def apply(self): config = _fontConfigForName(self._config) config.apply() def __present_contents__(self, fragment, inheritedState): def _onApply(button, event): self._config = self._userConfig.getStaticValue() self.apply() def _onRevert(button, event): self._userConfig.setLiteralValue(self._config) choices = [Label(c[1]) for c in _fontConfigChoices] choices.append(Label('Custom')) @LiveFunction def indexOfChoice(): config = self._userConfig.getValue() if isinstance(config, FontConfiguration): return len(choices) - 1 else: try: return [c[0] for c in _fontConfigChoices ].index(self._userConfig.getValue()) except ValueError: return 0 @LiveFunction def footer(): config = self._userConfig.getValue() if isinstance(config, FontConfiguration): return config else: return Blank() def _onChoice(menu, prevChoice, choice): if choice == len(choices) - 1: # Custom if prevChoice != choice: prevConfig = _fontConfigChoices[prevChoice][0] prevConfig = _fontConfigForName(prevConfig) config = FontConfiguration() config.copyFrom(prevConfig) self._userConfig.setLiteralValue(config) else: self._userConfig.setLiteralValue(_fontConfigChoices[choice][0]) applyButton = Button.buttonWithLabel('Apply', _onApply) revertButton = Button.buttonWithLabel('Revert', _onRevert) buttons = Row([applyButton, Spacer(15.0, 0.0), revertButton]).alignHPack() configMenu = OptionMenu(choices, indexOfChoice, _onChoice) chooserHeader = Row([ Label('Choose a font configuration:'), Spacer(25.0, 0.0), configMenu ]).alignHPack() return self._pageColumnStyle(Column([buttons, chooserHeader, footer])) _pageColumnStyle = StyleSheet.style(Primitive.columnSpacing(25.0))
from BritefuryJ.Live import TrackedLiveValue from BritefuryJ.Editor.List import EditableListController from Britefury.Util.LiveList import LiveList from LarchCore.Languages.Python2 import Schema as Py from LarchTools.PythonTools.GUIEditor.DataModel import ChildField, ChildListField from LarchTools.PythonTools.GUIEditor.Component import GUIComponent from LarchTools.PythonTools.GUIEditor.ComponentPalette import PaletteComponentDrag # #Sequential components: _emptyStyle = StyleSheet.style(Primitive.fontItalic(True), Primitive.fontSize(10), Primitive.foreground(Color(0.4, 0.4, 0.4))) emptyLabel = _emptyStyle(Label('<empty>')) class GUIBranchComponent(GUIComponent): def removeChild(self, child): raise NotImplementedError, 'abstract' def getNextSiblingOf(self, child): raise NotImplementedError, 'abstract' class GUIUnaryBranchComponent(GUIBranchComponent): child = ChildField()
from BritefuryJ.Editor.SyntaxRecognizing import SREInnerFragment from BritefuryJ.Editor.SyntaxRecognizing.SyntaxRecognizingController import EditMode from LarchTools.PythonTools.VisualRegex import Schema from LarchTools.PythonTools.VisualRegex.Parser import VisualRegexGrammar from LarchTools.PythonTools.VisualRegex.SRController import VisualRegexSyntaxRecognizingController PRECEDENCE_NONE = -1 _unparsedTextStyle = StyleSheet.style( Primitive.textSquiggleUnderlinePaint( Color.RED ) ) _controlCharStyle = StyleSheet.style( Primitive.foreground( Color( 0.0, 0.0, 0.0, 0.5 ) ) ) _invertControlCharStyle = StyleSheet.style( Primitive.foreground( Color( 1.0, 0.0, 0.0, 0.5 ) ) ) _specialCharStyle = StyleSheet.style( Primitive.foreground( Color( 0.25, 0.25, 0.35 ) ), Primitive.fontSize( 10 ) ) _specialBorder = SolidBorder( 1.0, 1.0, 4.0, 4.0, Color( 0.6, 0.6, 0.7 ), Color( 0.75, 0.75, 0.85 ) ) _charClassStyle = StyleSheet.style( Primitive.foreground( Color( 0.2, 0.3, 0.4 ) ), Primitive.fontSize( 10 ) ) _charClassBorder = SolidBorder( 1.0, 1.0, 4.0, 4.0, Color( 0.6, 0.65, 0.7 ), Color( 0.8, 0.85, 0.9 ) ) #_charClassStyle = StyleSheet.style( Primitive.foreground( Color( 0.0, 0.25, 0.5 ) ) ) #_charClassEscapeStyle = StyleSheet.style( Primitive.foreground( Color( 0.0, 0.25, 0.5, 0.5 ) ) ) #_charClassBorder = SolidBorder( 1.0, 2.0, 4.0, 4.0, Color( 0.0, 0.25, 0.5 ), Color( 0.8, 0.9, 1.0 ) ) _groupNameStyle = StyleSheet.style( Primitive.foreground( Color( 0.0, 0.65, 0.0 ) ) )
from BritefuryJ.Controls import TextEntry from BritefuryJ.Pres.Primitive import Primitive, Label, Row from BritefuryJ.Pres.UI import Form from BritefuryJ.StyleSheet import StyleSheet from LarchCore.Languages.Python2 import Schema as Py from LarchCore.Languages.Python2.Embedded import EmbeddedPython2Expr from LarchTools.PythonTools.GUIEditor.DataModel import ExprField, TypedField from LarchTools.PythonTools.GUIEditor.LeafComponent import GUILeafComponent from LarchTools.PythonTools.GUIEditor.ComponentPalette import paletteItem, registerPaletteSubsection _evalLabelStyle = StyleSheet.style(Primitive.fontItalic(True), Primitive.fontSize(11), Primitive.foreground(Color(0.3, 0.4, 0.5))) _liveEvalLabelStyle = StyleSheet.style( Primitive.fontItalic(True), Primitive.fontSize(11), Primitive.foreground(Color(0.4, 0.3, 0.5))) _evalItemStyleF = StyleSheet.style(Primitive.fontItalic(True), Primitive.foreground(Color(0.2, 0.4, 0.6))) _evalItemStyleParens = StyleSheet.style( Primitive.foreground(Color(0.4, 0.4, 0.4))) class GUIEval(GUILeafComponent): componentName = 'Eval' expr = ExprField()