-
Notifications
You must be signed in to change notification settings - Fork 262
Code Editor Programming Discussion
The ATF Code Editor Sample shows how to interface third party software to an ATF application: the ActiproSoftware SyntaxEditor, which is provided in a set of DLLs. CodeEditor uses this software to access an editing control with language syntax sensitive editing for plain text, C#, Lua, Python, XML, and other format files with appropriate extensions. CodeEditor handles text files in these formats, so it does not store application data using a data model. Its data model could be considered to be the formats for the file types, and these are specified in proprietary XML files, such as CSharpDefinition.xml
.
CodeEditor uses only a fraction of the capabilities ActiproSoftware SyntaxEditor provides.
CodeEditor uses interfaces and classes in the Sce.Atf.Controls.SyntaxEditorControl
namespace, which comprises the Atf.SyntaxEditorControl
assembly. The items in this namespace provide a layer between CodeEditor and SyntaxEditor.
The CodeEditor application is basically a container for the ActiproSoftware SyntaxEditor editing control. CodeEditor itself uses some standard ATF facilities for handling documents in its CodeDocument
class and Editor
component. CodeEditor also provides source control with its own simple SourceControlContext
component, but mainly with the ATF components SourceControlCommands
and PerforceService
.
The Sce.Atf.Controls.SyntaxEditorControl
namespace contains interfaces and classes CodeEditor uses to communicate with the editing control. The most important is the ISyntaxEditorControl
interface, which describes a framework for a syntax editor and could be used for syntax editors other than ActiproSoftware's. SyntaxEditorControl
implements ISyntaxEditorControl
by using ActiproSoftware's SyntaxEditor
class. Other items in Sce.Atf.Controls.SyntaxEditorControl
play a minor supporting role.
CodeEditor handles documents in a similar way as other samples by implementing IDocument
and IDocumentClient
. For a description of the general process, see Implementing a Document and Its Client in the section Documents in ATF.
CodeDocument
is the document class, implementing IDocument
. Its constructor sheds light on interfacing with the editing control:
public CodeDocument(Uri uri)
{
if (uri == null)
throw new ArgumentNullException("uri");
m_uri = uri;
string filePath = uri.LocalPath;
string fileName = Path.GetFileName(filePath);
m_type = GetDocumentType(fileName);
m_editor = TextEditorFactory.CreateSyntaxHighlightingEditor();
Languages lang = GetDocumentLanguage(fileName);
m_editor.SetLanguage(lang);
Control ctrl = (Control)m_editor;
ctrl.Tag = this;
m_editor.EditorTextChanged += editor_EditorTextChanged;
m_controlInfo = new ControlInfo(fileName, filePath, StandardControlGroup.Center);
// tell ControlHostService this control should be considered a document in the menu,
// and using the full path of the document for menu text to avoid adding a number in the end
// in control header, which is not desirable for documents that have the same name
// but located at different directories.
m_controlInfo.IsDocument = true;
}
This constructor does some initial housekeeping with the give URI. Next, the constructor gets an editing control object using the factory method TextEditorFactory.CreateSyntaxHighlightingEditor()
and saves it in the field m_editor
. This editing control implements ISyntaxEditorControl
, which is the interface to access an editing control's capabilities. For information on this interface, see ISyntaxEditorControl Interface. The constructor sets the editing control's language, gleaned from the URI file's extension by the GetDocumentLanguage()
method. The constructor finishes up by setting the Tag
property in the control, subscribing to the EditorTextChanged
event and setting up a new ControlInfo
.
CodeDocument
provides a few simple properties, such as Control
, which gets the editing control. It also provides Read()
and Write()
methods, which are straightforward, because CodeEditor only works with text files. Here's Read()
, for example:
public void Read()
{
string filePath = m_uri.LocalPath;
if (File.Exists(filePath))
{
using (StreamReader stream = new StreamReader(filePath, Encoding.UTF8))
{
m_editor.Text = stream.ReadToEnd();
m_editor.Dirty = false;
}
}
}
The editing control's Text
property is set to the text read from the file.
CodeDocument
also implements IDocument
and IResource
. These simple interfaces handle the Dirty
and Uri
properties and their related events, such as DirtyChanged
and UriChanged
.
CodeDocument
also contains a couple of utility methods GetDocumentType()
and GetDocumentLanguage()
that provide their information by examining the file's extension, which indicates the document type.
The Editor
component provides CodeEditor's document client. It is also the control host client and command client for the main editing control, so it implements both IControlHostClient
and ICommandClient
. It implements ICommandClient
for the standard editing commands:
public class Editor : IControlHostClient, IInitializable, ICommandClient
For information about how ATF handles controls and control host clients, see Using Controls in ATF in the section Controls in ATF. To learn about commands and their clients, see Using Commands in ATF in Commands in ATF.
Editor
contains the simple class DocumentClient
that is the document client for CodeEditor:
private class DocumentClient : IDocumentClient
Its constructor takes an instance of Editor
:
public DocumentClient(Editor editor, string extension)
{
m_editor = editor;
string fileType = CodeDocument.GetDocumentType(extension);
m_info = new DocumentClientInfo(fileType, extension, null, null);
}
The constructor saves the Editor
instance in the field m_editor
. Do not confuse this with the m_editor
field in the CodeDocument
class, which holds an instance of the ActiproSoftware SyntaxEditor editing control.
This constructor also creates a DocumentClientInfo
based on the document's type, indicated by its extension.
The document client uses the IControlHostService
object passed to the Editor
constructor to do some of its work. For example, Open()
creates a CodeDocument
object, reads the document, and then registers the ActiproSoftware SyntaxEditor editing control held in the CodeDocument.Control
property with the Control Host Service:
public IDocument Open(Uri uri)
{
CodeDocument doc = new CodeDocument(uri);
doc.Read();
m_editor.m_controlHostService.RegisterControl(
doc.Control,
doc.ControlInfo,
m_editor);
return doc;
}
The other IDocumentClient
methods are even simpler that Open()
.
Editor
's constructor creates a DocumentClient
object for every file type that CodeEditor supports for later use:
// create a document client for each file type
m_txtDocumentClient = new DocumentClient(this, ".txt");
...
m_cgDocumentClient = new DocumentClient(this, ".cg");
It is typical for an ATF application to create a document client for each document type it handles.
This client handles the editing control. The Activate()
method, called when the control becomes active, informs the Document Registry and Command Service of the active document and control host client:
public void Activate(Control control)
{
if (control.Tag is CodeDocument)
{
IDocument doc = (IDocument)control.Tag;
m_documentRegistry.ActiveDocument = doc;
m_commandService.SetActiveClient(this);
}
}
Close()
gets the active document, if any, and asks the Document Service to close it, which prompts the user to save the document if it was modified:
public bool Close(Control control)
{
CodeDocument document = control.Tag as CodeDocument;
if (document != null)
return m_documentService.Close(document);
return true;
}
The Editor
component's IInitializable.Initialize()
is called after Editor
is constructed and finishes initialization that can't be done in the constructor. In this case, it uses the Command Service component to register the Edit commands:
// register commands
m_commandService.RegisterCommand(CommandInfo.EditUndo, this);
...
m_commandService.RegisterCommand(CommandInfo.EditDelete, this);
m_commandService.RegisterCommand(
Command.FindReplace,
StandardMenu.Edit,
StandardCommandGroup.EditOther,
"Find and Replace...",
"Find and replace text",
Keys.None,
Resources.FindImage,
CommandVisibility.Menu,
this);
m_commandService.RegisterCommand(
Command.Goto,
StandardMenu.Edit,
StandardCommandGroup.EditOther,
"Go to...",
"Go to line",
Keys.None,
null,
CommandVisibility.Menu,
this);
In addition to standard Edit commands, it registers a couple of commands for search and going to a line in the file.
CodeEditor imports the StandardFileCommands
component to create the actual Edit menu items for the edit commands.
The command client relies on the editing control to actually perform editing commands. Here's what ICommandClient.DoCommand()
does:
public void DoCommand(object commandTag)
{
CodeDocument activeDocument = m_documentRegistry.ActiveDocument as CodeDocument;
if (commandTag is StandardCommand)
{
switch ((StandardCommand)commandTag)
{
case StandardCommand.EditUndo:
activeDocument.Editor.Undo();
break;
...
case StandardCommand.EditDelete:
activeDocument.Editor.Delete();
break;
}
}
else if (commandTag is Command)
{
switch ((Command)commandTag)
{
case Command.FindReplace:
activeDocument.Editor.ShowFindReplaceForm();
break;
case Command.Goto:
activeDocument.Editor.ShowGoToLineForm();
break;
}
}
}
The variable activeDocument
is adapted to a CodeDocument
object, so the value activeDocument.Editor
is the editing control. The editing control methods invoked here, such as Undo()
, are in the ISyntaxEditorControl
interface, which the editing control implements. For details on this interface, see ISyntaxEditorControl Interface.
SourceControlContext
implements ISourceControlContext
, which gets an enumeration of the IResource
s under source control with its Resources
property. A source control facility can examine the URIs in this property and adapt the IResource
to IDocument
to track a document's dirty flag.
CodeEditor also imports the SourceControlCommands
and PerforceService
components, which actually do the source control management work.
SourceControlCommands
registers the commands for source control and also provides the command client to perform them. In addition, it implements IContextMenuCommandProvider
to provide a context menu with the source control commands. Its command client relies on a SourceControlService
component to do the actual source control, which allows using different source control providers.
SourceControlService
is an abstract component that implements ISourceControlService
, the interface for source control services. PerforceService
derives from SourceControlService
and uses the Perforce Client for its source control provider.
The interfaces and classes in Sce.Atf.Controls.SyntaxEditorControl
comprise the layer between CodeEditor and the ActiproSoftware SyntaxEditor. The most important are ISyntaxEditorControl
and its implementer, SyntaxEditorControl
.
ISyntaxEditorControl
is an interface for syntax aware editing controls in general, not just the ActiproSoftware SyntaxEditor. This interface contains properties, methods, and events to do various things:
- Get the actual text editing control.
- Get or set text in the control.
- Get or set information about the text, such as the number of lines.
- Get or set user interface information, such as splitter locations.
- Notify when key press and change events occur.
- Determine if editing commands are doable and do them.
- Enable facilities, such as word wrapping.
- Perform selection operations.
- Do search and replace operations.
ISyntaxEditorFindReplaceOptions
, ISyntaxEditorFindReplaceResult
, and ISyntaxEditorFindReplaceResultSet
.
SyntaxEditorControl
derives from SyntaxEditor
, the actual ActiproSoftware SyntaxEditor editing control, defined in the ActiproSoftware DLLs. SyntaxEditorControl
implements ISyntaxEditorControl
by using the properties and methods of SyntaxEditor
. CodeEditor also uses some ATF facilities; for more information, see ATF Facilities. CodeEditor could use another editing control package by implementing ISyntaxEditorControl
for that editing control's API.
SyntaxEditorControl
's constructor sets default values for various ISyntaxEditorControl
properties and subscribes to the events in ISyntaxEditorControl
.
The SetLanguage()
method sets the control to one of the built-in languages. This is where the XML language definition files, such as PythonDefinition.xml
and LuaDefinition.xml
, are used to set SyntaxEditor
's language. These files have a proprietary format.
SyntaxEditorControl
also contains classes to implement ISyntaxEditorFindReplaceOptions
, ISyntaxEditorFindReplaceResult
, and ISyntaxEditorFindReplaceResultSet
.
SyntaxEditorControl
is an internal class to abide by SyntaxEditor's licensing terms.
The namespace Sce.Atf.Controls.SyntaxEditorControl
contains other ATF facilities that are primarily used in SyntaxEditorControl
.
CodeEditor provides breakpoint facilities, as would be expected. An interface and classes provide breakpoint support:
-
IBreakpoint
: Properties describing a breakpoint, such asEnabled
andLineNumber
. -
BreakpointEventArgs
: Breakpoint event argument information for theBreakpointChanging
event, providing a constructor and properties, such asIsSet
andLineNumber
. TheBreakpointChanging
event is not implemented in CodeEditor. -
BreakpointIndicator
: Breakpoint indicator, implementingIBreakpoint
. ItsDrawGlyph()
method draws the indicator.
Several classes besides BreakpointEventArgs
provide event arguments for events defined in ISourceControlContext
.
-
EditorTextChangedEventArgs
: Event arguments for theEditorTextChanged
event, describing the nature of the text change. -
MouseHoverOverTokenEventArgs
: Event arguments for theMouseHoveringOverToken
event. TheMouseHoveringOverToken
event is not implemented in CodeEditor. -
ShowContextMenuEventArg
: Event arguments for theShowContextMenu
event. The event is raised when the context menu should be displayed by right-clicking theSyntaxEditor
control.
These provide support for languages in CodeEditor:
-
Languages
: Enumeration of languages supported in CodeEditor. -
LuaDynamicSyntaxLanguage
: Adds folding for code blocks in the Lua language.
These miscellaneous items generally support the CodeEditor:
-
SyntaxEditorRegions
: Enumeration of regions in theSyntaxEditorControl
user interface for hit testing. These include items such as splitters, scroll bars, and margins. -
Token
: Astruct
for a text token representing a word in a document. Besides the constructor, it holds token properties, such as the lexeme, the base unit of meaning of some word that can have a variety of forms (run with the forms runs, ran, running, etc.). -
TextEditorFactory
: Factory with methods to produce editing objects:-
CreateSyntaxHighlightingEditor()
: Provide aSyntaxEditorControl
object. Used by theCodeDocument
constructor. -
CreateSyntaxEditorFindReplaceOptions()
: Get aSyntaxEditorFindReplaceOptions
object.
-
- Circuit Editor Programming Discussion: Learn how ATF handles graphs, and provides editors for kinds of graphs, such as circuits.
- Code Editor Programming Discussion: Shows how to interface third party software to an ATF application: the ActiproSoftware SyntaxEditor.
- Diagram Editor Programming Discussion: Very simply combines components from the CircuitEditor, FsmEditor, and StateChartEditor samples into one application, with the abilities of all three, showing the power of components.
-
DOM Property Editor Programming Discussion: Shows how to use the ATF DOM with an XML Schema to define application data with a large variety of attribute types, whose values can be viewed and edited using the ATF
PropertyEditor
component, using various value editors to view and edit attributes. - DOM Tree Editor Programming Discussion: Shows how to edit DOM data using a tree control and display properties in a variety of value editors.
- File Explorer Programming Discussion: Discusses the ATF File Explorer Sample using list and tree controls with adapters.
- FSM Editor Programming Discussion: Tells you about how the ATF FSM Editor Sample edits simple graphs for state machines, using DOM adapters for contexts and validation.
-
Model Viewer Programming Discussion: Shows how the ATF Model Viewer Sample is written, discussing how ATGI and Collada model data is handled, using rendering components, and using a
DesignControl
as a canvas for rendering. -
Simple DOM Editor Programming Discussion: Programming the ATF Simple DOM Editor Sample, creating a palette, using DOM adapters and contexts, editing application data, and searching
DomNode
s. - Simple DOM Editor WPF Programming Discussion: Programming the ATF Simple DOM Editor WPF Sample, which is similar to ATF Simple DOM Editor Sample, but implemented using ATF's WPF framework.
- Simple DOM No XML Editor Programming Discussion: Programming the ATF Simple DOM No XML Editor Sample, which is very similar to ATF Simple DOM Editor Sample, except that it doesn't use XML for either its data model or persisting application data.
- State Chart Editor Programming Discussion: Shows using ATF graph and other classes to create a statechart editor, using DOM adapters, documents, contexts, and validators.
- Target Manager Programming Discussion: Description of how a target manager is implemented using ATF components to manage target devices, such as PlayStation®Vita or PS3™ consoles. A target manager is used in other tools, such as the StateMachine tool.
- Timeline Editor Programming Discussion: Discusses how to create a fairly full-featured timeline editor using the ATF timeline facilities, such as the timeline renderer and the timeline control and its manipulators.
-
Tree List Control Programming Discussion: Demonstrates using the
TreeListControl
andTreeListItemRenderer
classes to display and edit hierarchical data in a tree view with details in columns. -
Tree List Editor Programming Discussion: Demonstrates how to use the ATF tree controls
TreeListView
and its enhancement,TreeListViewEditor
.TreeListView
usesTreeListViewAdapter
, which adaptsTreeListView
to display data in a tree. - Using Dom Programming Discussion: Shows how to use the various parts of the ATF DOM: an XML Schema, a schema metadata class file generated by DomGen, DOM adapters for the data types, a schema loader, and saving application data to an XML file.
- Home
- Getting Started
- Features & Benefits
- Requirements & Dependencies
- Gallery
- Technology & Samples
- Adoption
- News
- Release Notes
- ATF Community
- Searching Documentation
- Using Documentation
- Videos
- Tutorials
- How To
- Programmer's Guide
- Reference
- Code Samples
- Documentation Files
© 2014-2015, Sony Computer Entertainment America LLC