Exemple #1
0
class TextSpanAbstractView(_TextAbstractView):
    def __init__(self, worksheet, model):
        super(TextSpanAbstractView, self).__init__(worksheet, model)
        self._styleMapLive = LiveFunction(self.__compute_style_map)

    def getStyleAttrs(self):
        return self._styleMapLive.getValue()[0]

    def getStyleSheet(self):
        return self._styleMapLive.getValue()[1]

    _styleMap = {}
    _styleMap['italic'] = lambda value: Primitive.fontItalic(bool(value))
    _styleMap['bold'] = lambda value: Primitive.fontBold(bool(value))
    _styleMap['underline'] = lambda value: Primitive.fontUnderline(bool(value))
    _styleMap['strikethrough'] = lambda value: Primitive.fontStrikethrough(
        bool(value))

    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)
Exemple #2
0
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),
            ]).pad(5.0, 5.0)))


class _ChoiceInteractor(PushElementInteractor):
    def __init__(self, choiceValue, fontName):
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()
Exemple #4
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'
from BritefuryJ.Controls import Button, RealSpinEntry

from BritefuryJ.Pres import Pres
from BritefuryJ.Pres.Primitive import Primitive, Label, Bin, Row, Column, Table

from BritefuryJ.StyleSheet import StyleSheet

from LarchCore.Languages.Python2 import Schema as Py

from LarchTools.PythonTools.GUIEditor.DataModel import GUIObject, TypedEvalField



_uniformStyle = StyleSheet.style(Primitive.foreground(Color(0.2, 0.25, 0.3)), Primitive.fontSize(11))
_boxStyle = StyleSheet.style(Primitive.background(FilledOutlinePainter(Color(0.7, 0.75, 0.8), Color(0.6, 0.65, 0.7))), Primitive.fontSize(11), Primitive.foreground(Color(0.0, 0.0, 0.0, 0.5)), Primitive.fontItalic(True))
_tableStyle = StyleSheet.style(Primitive.tableColumnSpacing(2.0), Primitive.tableRowSpacing(2.0))
_liveLabelStyle = StyleSheet.style(Primitive.foreground(Color(0.4, 0.45, 0.5)))



class AbstractPadding (GUIObject):
	def apply(self, p):
		raise NotImplementedError, 'abstract'

	def __apply_py_evalmodel__(self, codeGen, py_p):
		raise NotImplementedError, 'abstract'



def _liveLabel(live):
Exemple #6
0
_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(
    Primitive.foreground(Color(0.2, 0.2, 0.2)), Primitive.fontItalic(True))

_frontPageNoteBorder = SolidBorder(1.0, 1.0, 3.0, 3.0, Color(0.0, 1.0, 0.0),
                                   Color(0.85, 0.95, 0.85))
_frontPageNoteStyle = StyleSheet.style(
    Primitive.foreground(Color(0.0, 0.5, 0.0)), Primitive.fontSize(10))
_startupPageNoteBorder = SolidBorder(1.0, 1.0, 3.0, 3.0, Color(0.75, 0.5, 1.0),
                                     Color(0.925, 0.9, 0.95))
_startupPageNoteStyle = StyleSheet.style(
    Primitive.foreground(Color(0.25, 0.0, 0.5)), Primitive.fontSize(10))
_notesRowStyle = StyleSheet.style(Primitive.rowSpacing(10.0))
_notesGap = 15.0

_packageContentsIndentation = 20.0

_packageIcon = Image(
Exemple #7
0
    def make_xml_element(self, rich_text_attributes, child):
        value = rich_text_attributes.getValue(self.tag_name, 0)
        if value:
            e = xmlmodel.XmlElem(self.tag_name)
            if child is not None:
                e.append(child)
            return e
        else:
            return child

    def store_value_from_element(self, rich_text_attributes, element):
        rich_text_attributes.putOverride(self.tag_name, True)


_italic_style = StyleSheet.instance.withValues(Primitive.fontItalic(True))
_bold_style = StyleSheet.instance.withValues(Primitive.fontBold(True))
_code_style = StyleSheet.instance.withValues(
    Primitive.fontFace(Primitive.monospacedFontName),
    Primitive.background(
        FilledOutlinePainter(Color(0.9, 0.9, 0.9), Color(0.75, 0.75, 0.75))))
_cmd_style = StyleSheet.instance.withValues(
    Primitive.fontFace(Primitive.monospacedFontName),
    Primitive.background(
        FilledOutlinePainter(Color(0.9, 0.9, 0.9), Color(0.75, 0.75, 0.75))),
    Primitive.foreground(Color(0.0, 0.5, 0.0)))
_cmd_prompt_style = StyleSheet.instance.withValues(
    Primitive.foreground(Color(0.0, 0.6, 0.5)))
_app_style = StyleSheet.instance.withValues(
    Primitive.fontItalic(True), Primitive.foreground(Color(0.5, 0.0, 0.0)))
_sys_style = StyleSheet.instance.withValues(
class MonitoredExpression (object):
	_currentSuite = None

	def __init__(self):
		self._name = 'value'
		self._expr = EmbeddedPython2Expr()
		self._suite = None
		self._code = None
		self._incr = IncrementalValueMonitor()
		self.__change_history__ = None


	def __getstate__(self):
		return { 'name' : self._name,  'expr' : self._expr }

	def __setstate__(self, state):
		self._name = state['name']
		self._expr = state['expr']
		self._suite = None
		self._code = None
		self._incr = IncrementalValueMonitor()
		self.__change_history__ = None


	def __get_trackable_contents__(self):
		return [ self._name, self._expr ]


	def __py_compile_visit__(self, codeGen):
		self._code = codeGen.compileForEvaluation( self._expr.model )
		self._suite = self._currentSuite
		if self._suite is not None:
			self._suite._registerMonitoredExpression( self )


	def __py_eval__(self, _globals, _locals, codeGen):
		value = eval( self._code, _globals, _locals )
		if self._suite is not None:
			self._suite._logValue( self, value )
		return value

	def __py_replacement__(self):
		return deepcopy( self._expr.model['expr'] )


	def __present__(self, fragment, inheritedState):
		self._incr.onAccess()

		def _setName(editableLabel, text):
			self._name = text
			self._incr.onChanged()


		namePres = EditableLabel( self._name, self._nameNotSetStyle( Label( '<not set>' ) ), _setName ).regexValidated( Pattern.compile( '[a-zA-Z_][a-zA-Z0-9_]*' ), 'Please enter a valid identifier' )

		exprPres = self._expr

		contents = Row( [ namePres, Label( ': ' ), exprPres ] )
		return ObjectBox( 'Monitored exp.', contents )

	_nameNotSetStyle = StyleSheet.style( Primitive.foreground( Color( 0.5, 0.0, 0.0 ) ), Primitive.fontItalic( True ) )
class GraphVizConfigurationPage(ConfigurationPage):
    def __init__(self):
        super(GraphVizConfigurationPage, self).__init__()
        self._graphVizDir = None
        self._config = None
        self._incr = IncrementalValueMonitor()

    def initPage(self, config):
        super(GraphVizConfigurationPage, self).initPage(config)
        GraphVizConfiguration.setConfigurationPageSubject(self.subject())

    def __getstate__(self):
        state = super(GraphVizConfigurationPage, self).__getstate__()
        state['graphVizDir'] = self._graphVizDir
        return state

    def __setstate__(self, state):
        super(GraphVizConfigurationPage, self).__setstate__(state)
        self._graphVizDir = state['graphVizDir']
        self._config = None
        self._incr = IncrementalValueMonitor()

        self._refreshConfig()

    def _checkedToolPath(self, name):
        path = os.path.join(self._graphVizDir, name + _exeExtension)
        if os.path.exists(path):
            return path
        else:
            return None

    def _setGraphVizDir(self, dir):
        self._graphVizDir = dir
        self._refreshConfig()
        self._incr.onChanged()

    def __isConfigured(self):
        if self._graphVizDir is not None and os.path.isdir(self._graphVizDir):
            dotPath = self._checkedToolPath('dot')
            neatoPath = self._checkedToolPath('neato')
            twopiPath = self._checkedToolPath('twopi')
            circoPath = self._checkedToolPath('circo')
            fdpPath = self._checkedToolPath('fdp')
            sfdpPath = self._checkedToolPath('sfdp')
            osagePath = self._checkedToolPath('osage')
            return dotPath is not None and neatoPath is not None and twopiPath is not None and circoPath is not None and fdpPath is not None and sfdpPath is not None and osagePath is not None
        return False

    def _refreshConfig(self):
        if self._graphVizDir is not None and os.path.isdir(self._graphVizDir):
            dotPath = self._checkedToolPath('dot')
            neatoPath = self._checkedToolPath('neato')
            twopiPath = self._checkedToolPath('twopi')
            circoPath = self._checkedToolPath('circo')
            fdpPath = self._checkedToolPath('fdp')
            sfdpPath = self._checkedToolPath('sfdp')
            osagePath = self._checkedToolPath('osage')
            self._config = GraphVizConfiguration(dotPath, neatoPath, twopiPath,
                                                 circoPath, fdpPath, sfdpPath,
                                                 osagePath)
            GraphVizConfiguration.setInstance(self._config)
        else:
            self._config = None
            GraphVizConfiguration.setInstance(None)
        self._incr.onChanged()

    def getSubjectTitle(self):
        return '[CFG] GraphViz'

    def getTitleText(self):
        return 'GraphViz Configuration'

    def getLinkText(self):
        return 'GraphViz'

    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])))

    def _toolLabel(self, name):
        return self._configTableToolNameStyle.applyTo(Label(name))

    def _presentConfig(self):
        if self._config is not None:
            rows = []
            rows.append([SectionHeading3('Tool'), SectionHeading3('Path')])
            rows.append(
                [self._toolLabel('dot'),
                 Label(self._config.getDotPath())])
            rows.append(
                [self._toolLabel('neato'),
                 Label(self._config.getNeatoPath())])
            rows.append(
                [self._toolLabel('twopi'),
                 Label(self._config.getTwopiPath())])
            rows.append(
                [self._toolLabel('circo'),
                 Label(self._config.getCircoPath())])
            rows.append(
                [self._toolLabel('fdp'),
                 Label(self._config.getFdpPath())])
            rows.append(
                [self._toolLabel('sfdp'),
                 Label(self._config.getSfdpPath())])
            rows.append(
                [self._toolLabel('osage'),
                 Label(self._config.getOsagePath())])
            return self._configTableStyle.applyTo(Table(rows)).pad(15.0, 5.0)

    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])

    _dirBorderStyle = StyleSheet.style(
        Primitive.border(
            SolidBorder(1.0, 3.0, 10.0, 10.0, Color(1.0, 0.85, 0.0),
                        Color(1.0, 1.0, 0.85))))
    _notSetStyle = StyleSheet.style(Primitive.fontItalic(True))
    _configTableStyle = StyleSheet.style(Primitive.tableColumnSpacing(10.0))
    _configTableToolNameStyle = StyleSheet.style(
        Primitive.foreground(Color(0.25, 0.0, 0.5)))
	@expected.setter
	def expected(self, x):
		if x is None:
			self._expected.setLiteralValue( None )




AbstractInlineTestTableRow._resultColumn = AttributeColumn( 'Result', 'result' )
AbstractInlineTestTableRow._expectedColumn = AttributeColumn( 'Expected', 'expected', None, None )



_nameBorder = SolidBorder( 1.0, 2.0, 5.0, 5.0, Color( 0.6, 0.6, 0.6 ), Color( 0.95, 0.95, 0.95 ) )
_notSet = StyleSheet.style( Primitive.fontItalic( True ) )( Label( 'not set' ) )
_inlineTestTableBorder = SolidBorder( 1.5, 3.0, 5.0, 5.0, Color( 0.4, 0.4, 0.5 ), None )


class AbstractInlineTestTable (AbstractInlineTest):
	_tableEditor = NotImplemented


	def __init__(self, name='test'):
		super( AbstractInlineTestTable, self ).__init__()
		self._name = TrackedLiveValue( name )
		self._tests = LiveList()
		self.__change_history__ = None

		self.__methodNames = UniqueNameTable()
Exemple #11
0
##-*************************
from java.util.regex import Pattern

from javax.swing import JOptionPane, JFileChooser
from javax.swing.filechooser import FileNameExtensionFilter

from BritefuryJ.Controls import Button, EditableLabel
from BritefuryJ.Pres.Primitive import Primitive, Label, Spacer, Row
from BritefuryJ.StyleSheet import StyleSheet

from Britefury.Util.Abstract import abstractmethod

from LarchTools.EmbeddedData.Model import Model
from LarchTools.EmbeddedData.Editor import Editor

_notSetStyle = StyleSheet.style(Primitive.fontItalic(True))

_filenamePattern = Pattern.compile('.+')


class _PathEditorTextEntry(Editor):
    def _newModel(self, value):
        if not isinstance(value, str) and not isinstance(value, unicode):
            value = None
        return Model(value)

    @abstractmethod
    def _initFileChooser(self, fileChooser):
        pass

    def buildEditorPres(self, fragment, inheritedState):
Exemple #12
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

from LarchCore.Languages.Python2 import Python2
from LarchCore.Languages.Python2.Execution.ExecutionPresCombinators import execStdout, execStderr, execException, execResult
from LarchCore.Languages.Python2.Execution import Execution




_executeShortcut = Shortcut( KeyEvent.VK_ENTER, Modifier.CTRL )
_executeNoEvalShortcut = Shortcut( KeyEvent.VK_ENTER, Modifier.CTRL | Modifier.SHIFT )
_historyPreviousShortcut = Shortcut( KeyEvent.VK_UP, Modifier.ALT )
_historyNextShortcut = Shortcut( KeyEvent.VK_DOWN, Modifier.ALT )

_bannerTextStyle = StyleSheet.style( Primitive.fontFace( 'Serif' ), Primitive.fontSmallCaps( True ), Primitive.editable( False ) )
_bannerHelpKeyTextStyle = StyleSheet.style( Primitive.fontFace( 'Serif' ), Primitive.fontSmallCaps( True ), Primitive.fontItalic( True ), Primitive.foreground( Color( 0.25, 0.25, 0.25 ) ) )
_bannerHelpTextStyle = StyleSheet.style( Primitive.fontFace( 'Serif' ), Primitive.fontItalic( True ), Primitive.foreground( Color( 0.25, 0.25, 0.25 ) ) )
_bannerBorder = SolidBorder( 2.0, 5.0, 8.0, 8.0, Color( 0.3, 0.5, 0.3 ), Color( 0.875, 0.9, 0.875 ) )


_labelStyle = StyleSheet.style( Primitive.fontSize( 10 ) )

#_blockStyle = StyleSheet.style( Primitive.columnSpacing( 2.0 ), Primitive.border( SolidBorder( 1.0, 5.0, 15.0, 15.0, Color( 0.25, 0.25, 0.25 ), Color( 0.8, 0.8, 0.8 ) ) ) )
_blockStyle = StyleSheet.style( Primitive.columnSpacing( 3.0 ), Primitive.border( SolidBorder( 1.0, 3.0, 13.0, 13.0, Color( 0.6, 0.6, 0.6 ), Color( 0.9, 0.9, 0.9 ) ) ) )
_blockOutputStyle = StyleSheet.style( Primitive.columnSpacing( 2.0 ) )

_pythonModuleBorderStyle = StyleSheet.style( Primitive.border( SolidBorder( 1.5, 5.0, 10.0, 10.0, Color( 0.65, 0.65, 0.65 ), Color.WHITE ) ) )
_dropPromptStyle = StyleSheet.style( Primitive.border( SolidBorder( 1.0, 3.0, 10.0, 10.0, Color( 0.0, 0.8, 0.0 ), None ) ) )

_varAssignVarNameStyle = StyleSheet.style( Primitive.fontItalic( True ), Primitive.foreground( Color( 0.0, 0.0, 0.5 ) ) )
_varAssignTypeNameStyle = StyleSheet.style( Primitive.foreground( Color( 0.3, 0.0, 0.3 ) ) )
class EvalFieldInstance(FieldInstance):
    """
	A field that contains a value, which can alternatively have an expression that generates the required value
	"""
    def __init__(self, field, object_instance, wrapped_source_value):
        super(EvalFieldInstance, self).__init__(field, object_instance,
                                                wrapped_source_value)

        self.__change_history__ = None

        if wrapped_source_value is not None:
            source_value = wrapped_source_value[0]
            if isinstance(source_value, _EvalFieldState):
                constantValue = source_value.constantValue
                expr = source_value.expr
            else:
                constantValue = source_value
                expr = None
        else:
            constantValue = field._getDefaultValue()
            expr = None

        self._live = TrackedLiveValue(constantValue)
        self._expr = expr
        self.__incr = IncrementalValueMonitor()

    def isConstant(self):
        return self._expr is None

    @property
    def constantValue(self):
        return self._live.getValue()

    @constantValue.setter
    def constantValue(self, x):
        self._live.setLiteralValue(x)

    @property
    def constantValueLive(self):
        return self._live

    @property
    def expr(self):
        return self._expr

    @expr.setter
    def expr(self, exp):
        oldExpr = self._expr
        self._expr = exp

        if self.__change_history__ is not None:
            if oldExpr is not None:
                self.__change_history__.stopTracking(oldExpr)

            def setExpression():
                self.expr = exp

            def revertExpression():
                self.expr = oldExpr

            self.__change_history__.addChange(setExpression, revertExpression,
                                              'Set expression')
            if exp is not None:
                self.__change_history__.track(exp)

        self.__incr.onChanged()

    def _addTrackableContentsTo(self, contents):
        contents.append(self)

    def __field_getstate__(self):
        return _EvalFieldState(self._live.getValue(), self._expr)

    def __field_getstate_for_clipboard_copy__(self, memo):
        return _EvalFieldState(memo.copy(self._live.getValue()),
                               memo.copy(self._expr))

    def getValueForEditor(self):
        return self._live.getValue()

    def __py_evalmodel__(self, codeGen):
        self.__incr.onAccess()
        if self._expr is None:
            return self.__fixedvalue_py_evalmodel__(self._live.getValue(),
                                                    codeGen)
        else:
            return self._expr.model

    def __fixedvalue_py_evalmodel__(self, value, codeGen):
        return Py.coerceToModel(value)

    def __get_trackable_contents__(self):
        if self._expr is not None:
            return [self._live, self._expr]
        else:
            return [self._live]

    def editUI(self, controlFactoryFn):
        self.__incr.onAccess()
        valueControl = controlFactoryFn(self._live)

        if self._expr is None:

            def _onAdd(button, event):
                self.expr = EmbeddedPython2Expr()

            addButton = Button(self._addButtonContents, _onAdd).alignHPack()

            return Row([valueControl, Spacer(10.0, 0.0), addButton])
        else:

            def _onRemove(button, event):
                self.expr = None

            removeButton = Button(self._removeButtonContents,
                                  _onRemove).alignHPack()

            return Column([
                valueControl,
                Row([
                    removeButton,
                    Spacer(10.0, 0.0),
                    exprBorder.surround(self._expr)
                ])
            ])

    _addStyle = StyleSheet.style(Primitive.foreground(Color(0.0, 0.5, 0.0)),
                                 Primitive.fontBold(True),
                                 Primitive.fontSize(11))
    _removeStyle = StyleSheet.style(Primitive.foreground(Color(0.5, 0.0, 0.0)),
                                    Primitive.fontBold(True),
                                    Primitive.fontSize(11))
    _fStyle = StyleSheet.style(Primitive.foreground(Color(0.0, 0.25, 0.5)),
                               Primitive.fontItalic(True),
                               Primitive.fontSize(11))
    _parenStyle = StyleSheet.style(Primitive.foreground(Color(0.3, 0.3, 0.3)),
                                   Primitive.fontSize(11))

    _addButtonContents = Row([
        _addStyle(Label('+ ')),
        _fStyle(Label('f')),
        _parenStyle(Label('()'))
    ])
    _removeButtonContents = Row([
        _removeStyle(Label('- ')),
        _fStyle(Label('f')),
        _parenStyle(Label('()'))
    ])
from BritefuryJ.Pres.UI import Form

from BritefuryJ.StyleSheet import StyleSheet

from LarchCore.Languages.Python2 import Schema as Py

from LarchTools.PythonTools.GUIEditor.DataModel import GUIObject, TypedEvalField
from LarchTools.PythonTools.GUIEditor.FieldEditor import optionalTypedEditor

_uniformStyle = StyleSheet.style(Primitive.foreground(Color(0.2, 0.25, 0.3)),
                                 Primitive.fontSize(11))
_boxStyle = StyleSheet.style(
    Primitive.background(
        FilledOutlinePainter(Color(0.7, 0.75, 0.8), Color(0.6, 0.65, 0.7))),
    Primitive.fontSize(11), Primitive.foreground(Color(0.0, 0.0, 0.0, 0.5)),
    Primitive.fontItalic(True))
_tableStyle = StyleSheet.style(Primitive.tableColumnSpacing(2.0),
                               Primitive.tableRowSpacing(2.0))
_liveLabelStyle = StyleSheet.style(Primitive.foreground(Color(0.4, 0.45, 0.5)))


class AbstractGUIBorder(GUIObject):
    def formSections(self):
        raise NotImplementedError, 'abstract'

    def makeBorder(self):
        raise NotImplementedError, 'abstract'

    def apply(self, p):
        return self.makeBorder().surround(p)