Пример #1
0
	def __setstate__(self, state):
		super(NotebookBlockCode, self).__setstate__(state)
		self.__code = state.get('code')
		if self.__code is None:
			self.__code = source_code.PythonCode()
		self.__result = None
		self.__incr = IncrementalValueMonitor()
Пример #2
0
class LiveValue (AbstractLive):
	def __init__(self, value=None):
		self.__incr = IncrementalValueMonitor(self)
		self.__value = value



	@property
	def incremental_monitor(self):
		return self.__incr


	@property
	def value(self):
		self.__incr.on_access()
		return self.__value

	@value.setter
	def value(self, v):
		self.__value = v
		self.__incr.on_changed()

	@property
	def static_value(self):
		return self.__value
Пример #3
0
	def __init__(self, blocks=None):
		if blocks is None:
			blocks = [NotebookBlockCode(self)]
		self.__blocks = blocks
		self.__incr = IncrementalValueMonitor()
		self._module = None
		self.__execution_state = LiveValue()
		self.__exec_state_init()
Пример #4
0
	def __setstate__(self, state):
		self.__blocks = state.get('blocks')
		if self.__blocks is None:
			self.__blocks = []
		self.__incr = IncrementalValueMonitor()
		self._module = None
		self.__execution_state = LiveValue()
		self.__exec_state_init()
Пример #5
0
	def __init__(self, notebook, language, var_name='src'):
		super(NotebookBlockSource, self).__init__(notebook)
		try:
			code_type = self.__language_to_type_map[language]
		except KeyError:
			raise ValueError, 'Invalid language {0}'.format(language)

		self.__code = code_type()
		self.__var_name = LiveValue(var_name)
		self.__incr = IncrementalValueMonitor()
Пример #6
0
	def __init__(self, xs=None):
		self._items = []
		if xs is not None:
			self._items[:] = xs[:]
		self.__change_history__ = None
		self._incr = IncrementalValueMonitor()
		self.__change_listener = None
Пример #7
0
	def __init__(self, app, category, path, loc_prefix, app_context, on_docs_loaded):
		self.__incr = IncrementalValueMonitor()

		self.category = category
		self.__app_context = app_context

		self.__imported_module_registry = ImportedModuleRegistry()

		self._app = app
		self.__path = path
		self.__loc_prefix = loc_prefix

		self.__documents = []
		self.__docs_by_location = {}
		self.__docs_by_filename = {}

		self.__load_documents(on_docs_loaded)
Пример #8
0
class AbstractConsole(object):
    def __init__(self, code=''):
        self.__blocks = []
        self.__current_block = CurrentBlock(
            self._source_text_to_code_object(code), self)
        self.__incr = IncrementalValueMonitor()

    def _execute_current_block(self, block):
        result = self._get_result_of_executing_code(block.code)

        block.code.editable = False
        self.__blocks.append(ConsoleBlock(block.code, result))
        self.__current_block = CurrentBlock(
            self._source_text_to_code_object(''), self)
        self.__incr.on_changed()

    def __present__(self, fragment):
        self.__incr.on_access()

        preamble = self._get_console_preamble_text(
        ) + '\n' + 'Press Control+Enter to execute.'
        contents = [
            '<div class="python_console_header">{0}</div>'.format(
                preamble.replace('\n', '<br>'))
        ]
        notifications = self._get_console_notifications()
        if notifications is not None:
            contents.append('<div class="console_notifications">')
            contents.append(notifications)
            contents.append('</div>')
        for block in self.__blocks + [self.__current_block]:
            contents.extend(['<div>', block, '</div>'])

        return Html(*contents).use_css('/static/larch/console.css')

    def _source_text_to_code_object(self, source_text):
        raise NotImplementedError, 'abstract'

    def _get_result_of_executing_code(self, code):
        raise NotImplementedError, 'abstract'

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

    def _get_console_notifications(self):
        return None
Пример #9
0
class NotebookBlockCode (NotebookBlock):
	def __init__(self, notebook, code=None):
		super(NotebookBlockCode, self).__init__(notebook)
		self.__code = source_code.PythonCode(code=code)
		self.__result = None
		self.__incr = IncrementalValueMonitor()


	def __getstate__(self):
		state = super(NotebookBlockCode, self).__getstate__()
		state['code'] = self.__code
		return state

	def __setstate__(self, state):
		super(NotebookBlockCode, self).__setstate__(state)
		self.__code = state.get('code')
		if self.__code is None:
			self.__code = source_code.PythonCode()
		self.__result = None
		self.__incr = IncrementalValueMonitor()



	def execute(self, module):
		self.__result = self.__code.execute_in_module(module)
		self.__incr.on_changed()


	def __present__(self, fragment):
		self.__incr.on_access()
		header = Html('<div class="notebook_python_code_header">Python code (executable)</div>')
		code = Html('<div class="notebook_python_code_container notebook_code_container">', self.__code, '</div>')
		res = ['<div class="notebook_result_container">', self.__result, '</div>']   if self.__result is not None  else []
		p = Html(*(['<div class="notebook_code_block">', header, '<div class="notebook_code_block_body">', code] + res + ['</div></div>']))
		p = focusable.focusable(p)
		return p
Пример #10
0
class ToolList (object):
	def __init__(self):
		self.contents = []
		self.__incr = IncrementalValueMonitor()


	def add(self, box):
		box._tool_list = self
		self.contents.append(box)
		self.__incr.on_changed()


	def close(self, box):
		self.contents.remove(box)
		self.__incr.on_changed()


	def __present__(self, fragment):
		self.__incr.on_access()
		return Html(*self.contents)
Пример #11
0
	def __init__(self, value=None):
		self.__incr = IncrementalValueMonitor(self)
		self.__value = value
Пример #12
0
	def __init__(self, notebook, code=None):
		super(NotebookBlockCode, self).__init__(notebook)
		self.__code = source_code.PythonCode(code=code)
		self.__result = None
		self.__incr = IncrementalValueMonitor()
Пример #13
0
class DocumentList (object):
	def __init__(self, app, category, path, loc_prefix, app_context, on_docs_loaded):
		self.__incr = IncrementalValueMonitor()

		self.category = category
		self.__app_context = app_context

		self.__imported_module_registry = ImportedModuleRegistry()

		self._app = app
		self.__path = path
		self.__loc_prefix = loc_prefix

		self.__documents = []
		self.__docs_by_location = {}
		self.__docs_by_filename = {}

		self.__load_documents(on_docs_loaded)



	@property
	def path(self):
		return self.__path

	@property
	def loc_prefix(self):
		return self.__loc_prefix


	def __iter__(self):
		return iter(self.__documents)


	def doc_for_location(self, location):
		return self.__docs_by_location.get(location)

	def doc_for_filename(self, filename):
		return self.__docs_by_filename.get(filename)

	def unused_filename(self, filename):
		if filename not in self.__docs_by_filename:
			return filename

		index = 0
		while True:
			name = filename + '_' + str(index)
			if name not in self.__docs_by_filename:
				return name
			index += 1


	def __add_document(self, doc):
		self.__documents.append(doc)
		self.__docs_by_location[doc.location] = doc
		self.__docs_by_filename[doc.filename] = doc
		self.__incr.on_changed()

	def new_document_for_content(self, name, content_factory):
		if name in self.__docs_by_filename:
			raise DocumentNameInUseError, name
		# Document file names do NOT include the extension
		filename = _sanitise_filename(name)
		file_path = os.path.join(self.__path, filename + '.ularch')

		def on_doc_created(doc):
			doc.save()
			self.__add_document(doc)

		Document.for_content(on_doc_created, self, name, filename, file_path, content_factory, self.__app_context, self.__imported_module_registry)


	def reload(self):
		self.__documents = []
		self.__docs_by_location = {}
		self.__docs_by_filename = {}

		self.__load_documents(None)

		self.__incr.on_changed()



	def __load_documents(self, on_all_docs_loaded):
		file_paths = glob.glob(os.path.join(self.__path, '*' + _EXTENSION))
		num_docs_to_load = len(file_paths)
		docs_loaded = [0]

		def on_doc_loaded(doc):
			self.__add_document(doc)
			docs_loaded[0] += 1
			if docs_loaded[0] == num_docs_to_load  and  on_all_docs_loaded is not None:
				on_all_docs_loaded()

		for p in sorted(file_paths):
			Document.load(on_doc_loaded, self._app, self, p, self.__app_context, self.__imported_module_registry)




	def __doc_table_row(self, doc, page):
		def on_save(event):
			doc.save_and_display_notification(page)

		save_button = button.button('Save', on_save)
		doc_title = '<a href="/pages/{0}/{1}" class="larch_app_doc_title">{2}</a>'.format(self.loc_prefix, doc.location, doc.name)
		doc_filename = '<span class="larch_app_doc_filename">{0}</span><span class="larch_app_doc_extension">.ularch</span>'.format(doc.filename)
		controls = Html('<div class="larch_app_doc_controls">', save_button, '</div>')
		return Html('<tr class="larch_app_doc">	<td>', doc_title, '</td><td>', doc_filename, '</td><td>', controls, '</td></tr>')




	def __present__(self, fragment):
		self.__incr.on_access()
		contents = ['<table class="larch_app_doc_list">']
		contents.append('<thead class="larch_app_doc_list_header"><td>Title</td><td>Filename</td><td>Save</td></thead>')
		contents.append('<tbody>')
		contents.extend([self.__doc_table_row(doc, fragment.page)   for doc in self.__documents])
		contents.append('</tbody></table>')
		return Html(*contents)
Пример #14
0
	def __setstate__(self, state):
		super(NotebookBlockSource, self).__setstate__(state)
		self.__code = state.get('code')
		self.__var_name = LiveValue(state.get('var_name'))
		self.__incr = IncrementalValueMonitor()
Пример #15
0
class Notebook (object):
	def __init__(self, blocks=None):
		if blocks is None:
			blocks = [NotebookBlockCode(self)]
		self.__blocks = blocks
		self.__incr = IncrementalValueMonitor()
		self._module = None
		self.__execution_state = LiveValue()
		self.__exec_state_init()


	def __exec_state_init(self):
		self.__execution_state.value = Html('<span class="notebook_exec_state_init">CODE NOT EXECUTED</span>')

	def __exec_state_executed(self):
		self.__execution_state.value = Html('')


	def __getstate__(self):
		return {'blocks': self.__blocks}


	def __setstate__(self, state):
		self.__blocks = state.get('blocks')
		if self.__blocks is None:
			self.__blocks = []
		self.__incr = IncrementalValueMonitor()
		self._module = None
		self.__execution_state = LiveValue()
		self.__exec_state_init()



	def append(self, block):
		self.__blocks.append(block)
		self.__incr.on_changed()


	def execute(self):
		self._module = imp.new_module('<Notebook>')
		larch_builtins.init_module(self._module)
		self.__execute_in_module(self._module)
		self.__exec_state_executed()


	def __execute_in_module(self, module):
		for block in self.__blocks:
			block.execute(module)



	def _insert_block(self, block_to_insert, below, focus_block):
		index = len(self.__blocks)
		if focus_block is not None  and  focus_block in self.__blocks:
			index = self.__blocks.index(focus_block)
			if below:
				index += 1
		self.__blocks.insert(index, block_to_insert)
		self.__incr.on_changed()

	def _delete_block(self, focus_block):
		if focus_block is not None  and  focus_block in self.__blocks:
			self.__blocks.remove(focus_block)
			self.__incr.on_changed()



	def __load_module__(self, document, fullname):
		try:
			return sys.modules[fullname]
		except KeyError:
			pass

		mod = document.new_module(fullname, self)

		self.__execute_in_module(mod)

		return mod



	def _save_containing_document_and_display_notification(self, fragment):
		subject = fragment.subject
		try:
			save_and_display_notification = subject.document.save_and_display_notification
		except AttributeError:
			print 'WARNING: Could not save; method unavailable'
			raise
		else:
			save_and_display_notification(fragment)


	def _unload_from_containing_document_and_display_notification(self, fragment):
		subject = fragment.subject
		try:
			unload_modules_and_display_notification = subject.document.unload_modules_and_display_notification
		except AttributeError:
			print 'WARNING: Could not unload_modules_and_display_notification; method unavailable'
			raise
		else:
			unload_modules_and_display_notification(fragment)


	def __focused_block(self, page):
		seg = page.focused_segment
		if seg is not None:
			frag = seg.fragment
			return frag.find_enclosing_model(NotebookBlock)
		else:
			return None


	def __commands__(self, page):
		return [
			command.Command([command.Key(ord('R'))], 'Insert rich text below', lambda page: self._insert_block(NotebookBlockText(self), True, self.__focused_block(page))),
			command.Command([command.Key(ord('P'))], 'Insert Python code below', lambda page: self._insert_block(NotebookBlockCode(self), True, self.__focused_block(page))),
			command.Command([command.Key(ord('J'))], 'Insert Javascript source below', lambda page: self._insert_block(NotebookBlockSource(self, 'js', 'js'), True, self.__focused_block(page))),
			command.Command([command.Key(ord('C'))], 'Insert CSS source below', lambda page: self._insert_block(NotebookBlockSource(self, 'css', 'css'), True, self.__focused_block(page))),
			command.Command([command.Key(ord('T'))], 'Insert HTML source below', lambda page: self._insert_block(NotebookBlockSource(self, 'html', 'html'), True, self.__focused_block(page))),
			command.Command([command.Key(ord('G'))], 'Insert GLSL source below', lambda page: self._insert_block(NotebookBlockSource(self, 'glsl', 'glsl'), True, self.__focused_block(page))),

			command.Command([command.Key(ord('A')), command.Key(ord('R'))], 'Insert rich text below', lambda page: self._insert_block(NotebookBlockText(self), False, self.__focused_block(page))),
			command.Command([command.Key(ord('A')), command.Key(ord('P'))], 'Insert Python code below', lambda page: self._insert_block(NotebookBlockCode(self), False, self.__focused_block(page))),
			command.Command([command.Key(ord('A')), command.Key(ord('J'))], 'Insert Javascript source below', lambda page: self._insert_block(NotebookBlockSource(self, 'js', 'js'), False, self.__focused_block(page))),
			command.Command([command.Key(ord('A')), command.Key(ord('C'))], 'Insert CSS source below', lambda page: self._insert_block(NotebookBlockSource(self, 'css', 'css'), False, self.__focused_block(page))),
			command.Command([command.Key(ord('A')), command.Key(ord('T'))], 'Insert HTML source below', lambda page: self._insert_block(NotebookBlockSource(self, 'html', 'html'), False, self.__focused_block(page))),
			command.Command([command.Key(ord('A')), command.Key(ord('G'))], 'Insert GLSL source below', lambda page: self._insert_block(NotebookBlockSource(self, 'glsl', 'glsl'), False, self.__focused_block(page))),

			command.Command([command.Key(ord('X'))], 'Remove block', lambda page: self._delete_block(self.__focused_block(page))),
		]

	def __menu_bar_contents__(self, page, fragment):
		#
		# File menu
		#

		def on_save():
			self._save_containing_document_and_display_notification(fragment)

		def on_unload():
			self._unload_from_containing_document_and_display_notification(fragment)


		save_item = menu.item('Save (Ctrl+S)', lambda event: on_save())
		unload_modules_item = menu.item('Unload modules', lambda event: on_unload())
		file_menu_contents = menu.sub_menu('File', [save_item, menu.separator(), unload_modules_item])
		file_menu = menu.menu([file_menu_contents], drop_down=True)



		#
		# Edit menu
		#

		def _insert_rich_text(below):
			self._insert_block(NotebookBlockText(self), below, self.__focused_block(fragment.page))

		def _insert_code(below):
			self._insert_block(NotebookBlockCode(self), below, self.__focused_block(fragment.page))

		def _insert_js(below):
			self._insert_block(NotebookBlockSource(self, 'js', 'js'), below, self.__focused_block(fragment.page))

		def _insert_css(below):
			self._insert_block(NotebookBlockSource(self, 'css', 'css'), below, self.__focused_block(fragment.page))

		def _insert_glsl(below):
			self._insert_block(NotebookBlockSource(self, 'glsl', 'glsl'), below, self.__focused_block(fragment.page))

		def _insert_html(below):
			self._insert_block(NotebookBlockSource(self, 'html', 'html'), below, self.__focused_block(fragment.page))

		insert_rich_text_above = menu.item('Insert rich text above', lambda event: _insert_rich_text(False))
		insert_code_above = menu.item('Insert executable Python code above', lambda event: _insert_code(False))
		insert_js_above = menu.item('Insert JS source above', lambda event: _insert_js(False))
		insert_css_above = menu.item('Insert CSS source above', lambda event: _insert_css(False))
		insert_html_above = menu.item('Insert HTML source above', lambda event: _insert_html(False))
		insert_glsl_above = menu.item('Insert GLSL source above', lambda event: _insert_glsl(False))

		insert_rich_text_below = menu.item('Insert rich text below', lambda event: _insert_rich_text(True))
		insert_code_below = menu.item('Insert executable Python code below', lambda event: _insert_code(True))
		insert_js_below = menu.item('Insert JS source below', lambda event: _insert_js(True))
		insert_css_below = menu.item('Insert CSS source below', lambda event: _insert_css(True))
		insert_html_below = menu.item('Insert HTML source below', lambda event: _insert_html(True))
		insert_glsl_below = menu.item('Insert GLSL source below', lambda event: _insert_glsl(True))

		remove_block = menu.item('Remove block', lambda event: self._delete_block(self.__focused_block(fragment.page)))
		edit_menu_contents = menu.sub_menu('Edit', [
			insert_rich_text_above,
			insert_code_above,
			insert_js_above,
			insert_css_above,
			insert_html_above,
			insert_glsl_above,

			menu.separator(),

			insert_rich_text_below,
			insert_code_below,
			insert_js_below,
			insert_css_below,
			insert_html_below,
			insert_glsl_below,

			menu.separator(),

			remove_block])

		edit_menu = menu.menu([edit_menu_contents], drop_down=True)

		exec_button = button.button('Execute (Ctrl-Enter)', lambda event: self.execute())

		return [file_menu, edit_menu, exec_button, self.__execution_state]



	def __present__(self, fragment):
		def on_execute_key(event, key):
			self.execute()
			return True

		def on_save_key(event, key):
			self._save_containing_document_and_display_notification(fragment)



		self.__incr.on_access()



		contents = []

		for block in self.__blocks:
			contents.extend(['<div>', block, '</div>'])


		p = Html(*contents)
		p = p.with_key_handler([KeyAction(KeyAction.KEY_DOWN, 13, ctrl=True)], on_execute_key)
		p = p.with_key_handler([KeyAction(KeyAction.KEY_DOWN, ord('S'), ctrl=True, prevent_default=True)], on_save_key)
		return p.use_css('/static/larch/notebook.css')
Пример #16
0
	def __init__(self):
		self.contents = []
		self.__incr = IncrementalValueMonitor()
Пример #17
0
 def __init__(self, code=''):
     self.__blocks = []
     self.__current_block = CurrentBlock(
         self._source_text_to_code_object(code), self)
     self.__incr = IncrementalValueMonitor()
Пример #18
0
	def __init__(self):
		self._incr = IncrementalValueMonitor()
		self.__change_history__ = None
		self._parent = None
Пример #19
0
class TrackedLiveList (object):
	__slots__ = [ '__change_history__', '_items', '_incr', '__change_listener']

	def __init__(self, xs=None):
		self._items = []
		if xs is not None:
			self._items[:] = xs[:]
		self.__change_history__ = None
		self._incr = IncrementalValueMonitor()
		self.__change_listener = None


	@property
	def change_listener(self):
		return self.__change_listener

	@change_listener.setter
	def change_listener(self, x):
		self.__change_listener = x


	def __getstate__(self):
		self._incr.on_access()
		return { 'items' : self._items }

	def __setstate__(self, state):
		self._items = state['items']
		self.__change_history__ = None
		self._incr = IncrementalValueMonitor()
		self.__change_listener = None

	def __copy__(self):
		self._incr.on_access()
		t = type( self )
		return t( self._items )

	def __deepcopy__(self, memo):
		self._incr.on_access()
		t = type( self )
		return t( deepcopy( self._items, memo ) )


	def __eq__(self, other):
		if isinstance( other, TrackedLiveList ):
			other = other._items
		return self._items == other

	def __ne__(self, other):
		if isinstance( other, TrackedLiveList ):
			other = other._items
		return self._items != other


	def __str__(self):
		return str( self._items )

	def __repr__(self):
		return 'LiveList( {0} )'.format( repr( self._items ) )


	def __trackable_contents__(self):
		return self._items


	def __clipboard_copy__(self, memo):
		self._incr.on_access()
		t = type( self )
		return t( [ memo.copy( x )   for x in self ] )



	def __iter__(self):
		self._incr.on_access()
		return _LiveListIter( iter( self._items ), self._incr )

	def __contains__(self, x):
		self._incr.on_access()
		return x in self._items

	def __add__(self, xs):
		self._incr.on_access()
		return self._items + xs

	def __mul__(self, x):
		self._incr.on_access()
		return self._items * x

	def __rmul__(self, x):
		self._incr.on_access()
		return x * self._items

	def __getitem__(self, index):
		self._incr.on_access()
		return self._items[index]

	def __len__(self):
		self._incr.on_access()
		return len( self._items )

	def index(self, x, i=None, j=None):
		self._incr.on_access()
		if i is None:
			return self._items.index( x )
		elif j is None:
			return self._items.index( x, i )
		else:
			return self._items.index( x, i, j )

	def count(self, x):
		self._incr.on_access()
		return self._items.count( x )

	def __setitem__(self, index, x):
		if isinstance( index, int )  or  isinstance( index, long ):
			oldX = self._items[index]
			if self.__change_listener is not None:
				old_contents = self._items[:]
			self._items[index] = x
			_on_tracked_list_set_item( self.__change_history__, self, index, oldX, x, 'Live list set item' )
			if self.__change_listener is not None:
				self.__change_listener( old_contents, self._items[:] )
		else:
			old_contents = self._items[:]
			self._items[index] = x
			newContents = self._items[:]
			_on_tracked_list_set_contents( self.__change_history__, self, old_contents, newContents, 'Live list set item' )
			if self.__change_listener is not None:
				self.__change_listener( old_contents, newContents )
		self._incr.on_changed()

	def __delitem__(self, index):
		oldContents = self._items[:]
		del self._items[index]
		newContents = self._items[:]
		_on_tracked_list_set_contents( self.__change_history__, self, oldContents, newContents, 'Live list del item' )
		if self.__change_listener is not None:
			self.__change_listener( oldContents, newContents )
		self._incr.on_changed()

	def append(self, x):
		if self.__change_listener is not None:
			old_contents = self._items[:]
		self._items.append( x )
		_on_tracked_list_append( self.__change_history__, self, x, 'Live list append' )
		if self.__change_listener is not None:
			self.__change_listener( old_contents, self._items[:] )
		self._incr.on_changed()

	def extend(self, xs):
		if self.__change_listener is not None:
			old_contents = self._items[:]
		self._items.extend( xs )
		_on_tracked_list_extend( self.__change_history__, self, xs, 'Live list extend' )
		if self.__change_listener is not None:
			self.__change_listener( old_contents, self._items[:] )
		self._incr.on_changed()

	def insert(self, i, x):
		if self.__change_listener is not None:
			old_contents = self._items[:]
		self._items.insert( i, x )
		_on_tracked_list_insert( self.__change_history__, self, i, x, 'Live list insert' )
		if self.__change_listener is not None:
			self.__change_listener( old_contents, self._items[:] )
		self._incr.on_changed()

	def pop(self):
		if self.__change_listener is not None:
			old_contents = self._items[:]
		x = self._items.pop()
		_on_tracked_list_pop( self.__change_history__, self, x, 'Live list pop' )
		if self.__change_listener is not None:
			self.__change_listener( old_contents, self._items[:] )
		self._incr.on_changed()
		return x

	def remove(self, x):
		if self.__change_listener is not None:
			old_contents = self._items[:]
		i = self._items.index( x )
		xFromList = self._items[i]
		del self._items[i]
		_on_tracked_list_remove( self.__change_history__, self, i, xFromList, 'Live list remove' )
		if self.__change_listener is not None:
			self.__change_listener( old_contents, self._items[:] )
		self._incr.on_changed()

	def reverse(self):
		if self.__change_listener is not None:
			old_contents = self._items[:]
		self._items.reverse()
		_on_tracked_list_reverse( self.__change_history__, self, 'Live list reverse' )
		if self.__change_listener is not None:
			self.__change_listener( old_contents, self._items[:] )
		self._incr.on_changed()

	def sort(self, cmp_fn=None, key=None, reverse=False):
		old_contents = self._items[:]
		self._items.sort( cmp=cmp_fn, key=key, reverse=reverse )
		newContents = self._items[:]
		_on_tracked_list_set_contents( self.__change_history__, self, old_contents, newContents, 'Live list sort' )
		if self.__change_listener is not None:
			self.__change_listener( old_contents, newContents )
		self._incr.on_changed()

	def _set_contents(self, xs):
		old_contents = self._items[:]
		self._items[:] = xs
		_on_tracked_list_set_contents( self.__change_history__, self, old_contents, xs, 'Live list set contents' )
		if self.__change_listener is not None:
			self.__change_listener( old_contents, self._items[:] )
		self._incr.on_changed()
Пример #20
0
	def __setstate__(self, state):
		self._items = state['items']
		self.__change_history__ = None
		self._incr = IncrementalValueMonitor()
		self.__change_listener = None
Пример #21
0
	def __setstate__(self, state):
		self._incr = IncrementalValueMonitor()
		self.__change_history__ = None
		self._parent = None
Пример #22
0
class NotebookBlockSource (NotebookBlock):
	__language_to_type_map = {
		'html': source_code.HtmlCode,
		'css': source_code.CSSCode,
		'js': source_code.JSCode,
		'glsl': source_code.GLSLCode,
	}

	__type_to_language_map = {
		source_code.HtmlCode: 'html',
		source_code.CSSCode: 'css',
		source_code.JSCode: 'js',
		source_code.GLSLCode: 'glsl',
	}

	__language_to_human_name = {
		'html': 'HTML',
		'css': 'CSS',
		'js': 'Javascript',
		'glsl': 'GLSL',
	}

	def __init__(self, notebook, language, var_name='src'):
		super(NotebookBlockSource, self).__init__(notebook)
		try:
			code_type = self.__language_to_type_map[language]
		except KeyError:
			raise ValueError, 'Invalid language {0}'.format(language)

		self.__code = code_type()
		self.__var_name = LiveValue(var_name)
		self.__incr = IncrementalValueMonitor()


	def __getstate__(self):
		state = super(NotebookBlockSource, self).__getstate__()
		state['code'] = self.__code
		state['var_name'] = self.__var_name.static_value
		return state

	def __setstate__(self, state):
		super(NotebookBlockSource, self).__setstate__(state)
		self.__code = state.get('code')
		self.__var_name = LiveValue(state.get('var_name'))
		self.__incr = IncrementalValueMonitor()


	@property
	def language(self):
		return self.__type_to_language_map[type(self.__code)]

	@language.setter
	def language(self, lang):
		try:
			code_type = self.__language_to_type_map[lang]
		except KeyError:
			raise ValueError, 'Invalid language {0}'.format(lang)
		src_text = self.__code.source_text
		self.__code = code_type(code=src_text)
		self.__incr.on_changed()



	def execute(self, module):
		module.__dict__[self.__var_name.static_value] = self.__code.source_text


	def __present__(self, fragment):
		self.__incr.on_access()

		def _on_change_language(lang):
			self.language = lang

		language = self.language


		var_name = text_entry.live_text_entry(self.__var_name)


		js_item = menu.item('Javascript', lambda event: _on_change_language('js'))
		css_item = menu.item('CSS', lambda event: _on_change_language('css'))
		glsl_item = menu.item('GLSL', lambda event: _on_change_language('glsl'))
		html_item = menu.item('HTML', lambda event: _on_change_language('html'))

		lang_menu = menu.sub_menu('Change language', [
			js_item,
			css_item,
			glsl_item,
			html_item
		])
		lang_menu_button = menu.menu([lang_menu], drop_down=True)


		human_lang_name = self.__language_to_human_name[language]

		header = Html('<div class="notebook_{0}_code_header">'.format(language),
			      '<table class="notebook_src_language_select_table"><tr>',
			      '<td>{0}</td>'.format(human_lang_name),
			      '<td>', lang_menu_button, '</td>',
			      '</tr></table>',
			      '<table><tr>',
			      '<td>Variable name:</td>',
			      '<td>', var_name, '</td>',
			      '</tr></table>',
			      '</div>')
		code = Html('<div class="notebook_{0}_code_container notebook_code_container">'.format(language), self.__code, '</div>')
		p = Html('<div class="notebook_code_block">', header, '<div class="notebook_code_block_body">', code, '</div></div>')
		p = focusable.focusable(p)
		return p