using System; using AppKit; using CoreGraphics; using Foundation; using System.Collections.Generic; namespace Cauldron.Macos.SourceWriter { public class SourceTextViewDelegate : NSTextViewDelegate { #region Computed Properties /// /// Gets or sets the text editor. /// /// The this delegate is attached to. public SourceTextView TextEditor { get; set; } #endregion #region Constructors /// /// Initializes a new instance of the class. /// /// Text editor. public SourceTextViewDelegate(SourceTextView textEditor) { this.TextEditor = textEditor; } #endregion #region Override Methods /// /// Based on the user preferences set on the parent , this /// method returns the available list of partial word completions. /// /// The list of word completions that will be presented to the user. /// The source . /// /// A list of default words automatically provided by OS X in the user's language. /// /// The cursor location where the partial word exists. /// /// The word that should be selected when the list is displayed (usually 0 meaning the first /// item in the list). Pass -1 for no selected items. /// public override string[] GetCompletions(NSTextView textView, string[] words, NSRange charRange, ref nint index) { List completions = new(); // Is auto complete enabled? if (TextEditor.AllowAutoComplete) { // Use keywords in auto complete? if (TextEditor.AutoCompleteKeywords) { // Yes, grab word being expanded NSRange range = TextEditor.Formatter.FindWordBoundries( TextEditor.TextStorage.Value, charRange); string word = TextEditor.TextStorage.Value.Substring( (int)range.Location, (int)range.Length); // Scan the keywords for the a possible match foreach (string keyword in TextEditor.Formatter.Language.Keywords.Keys) { // Found? if (keyword.Contains(word)) { completions.Add(keyword); } } } // Use default words? if (TextEditor.AutoCompleteDefaultWords) { // Only if keywords list is empty? if (TextEditor.DefaultWordsOnlyIfKeywordsEmpty) { if (completions.Count == 0) { // No keywords, add defaults completions.AddRange(words); } } else { // No, always include default words completions.AddRange(words); } } } // Return results return completions.ToArray(); } /// Called when the cell is clicked. /// The . /// The cell being acted upon. /// The onscreen frame of the cell. /// The index of the character clicked. /// /// Because a custom Delegate has been attached to the NSTextView, the normal /// events will not work so we are using this method to call custom /// events instead. /// public override void CellClicked(NSTextView textView, NSTextAttachmentCell cell, CGRect cellFrame, nuint charIndex) { // Pass through to Text Editor event TextEditor.RaiseSourceCellClicked(TextEditor, new NSTextViewClickedEventArgs(cell, cellFrame, charIndex)); } /// Called when the cell is double-clicked. /// The . /// The cell being acted upon. /// The onscreen frame of the cell. /// The index of the character clicked. /// /// Because a custom Delegate has been attached to the NSTextView, the normal /// events will not work so we are using this method to call custom /// events instead. /// public override void CellDoubleClicked(NSTextView textView, NSTextAttachmentCell cell, CGRect cellFrame, nuint charIndex) { // Pass through to Text Editor event TextEditor.RaiseSourceCellDoubleClicked(TextEditor, new NSTextViewDoubleClickEventArgs(cell, cellFrame, charIndex)); } /// Called when the cell is dragged. /// The . /// The cell being acted upon. /// The onscreen frame of the cell. /// An event defining the drag operation. /// /// Because a custom Delegate has been attached to the NSTextView, the normal /// events will not work so we are using this method to call custom /// events instead. /// //public override void DraggedCell(NSTextView view, NSTextAttachmentCell cell, CGRect rect, // NSEvent theevent) //{ // // Pass through to Text Editor event // TextEditor.RaiseSourceCellDragged(TextEditor, new NSTextViewDraggedCellEventArgs(cell, rect, theevent)); //} /// Called when the text selection has changed. /// A notification defining the change. /// /// Because a custom Delegate has been attached to the NSTextView, the normal /// events will not work so we are using this method to call custom /// events instead. /// public override void DidChangeSelection(NSNotification notification) { // Pass through to Text Editor event TextEditor.RaiseSourceSelectionChanged(TextEditor, EventArgs.Empty); } /// Called when the typing attributes has changed. /// A notification defining the change. /// /// Because a custom Delegate has been attached to the NSTextView, the normal /// events will not work so we are using this method to call custom /// events instead. /// public override void DidChangeTypingAttributes(NSNotification notification) { // Pass through to Text Editor event TextEditor.RaiseSourceTypingAttributesChanged(TextEditor, EventArgs.Empty); } #endregion } }