/* * Copyright (C) 2013 FooProject * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ using System; using System.Text; using System.ComponentModel; using System.Threading.Tasks; using Windows.ApplicationModel.Resources.Core; using Windows.Devices.Input; using Windows.System; using Windows.ApplicationModel.DataTransfer; using Windows.Foundation; using Windows.UI; using Windows.UI.Input; using Windows.UI.Core; using Windows.UI.Popups; using Windows.UI.Text; using Windows.UI.Xaml.Media; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Input; using DotNetTextStore; using DotNetTextStore.UnmanagedAPI.TSF; using DotNetTextStore.UnmanagedAPI.WinDef; // テンプレート コントロールのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=234235 を参照してください namespace FooEditEngine.Metro { /// /// テキストボックスコントロール /// public sealed class FooTextBox : Control,IDisposable { EditView View; Controller _Controller; D2DRender Render; ScrollBar horizontalScrollBar, verticalScrollBar; Windows.UI.Xaml.Shapes.Rectangle rectangle; GestureRecognizer gestureRecongnizer = new GestureRecognizer(); TextStore2 textStore; FooTextBoxAutomationPeer peer; bool nowCaretMove = false; Document _Document; DispatcherTimer timer = new DispatcherTimer(); /// /// コンストラクター /// public FooTextBox() { this.DefaultStyleKey = typeof(FooTextBox); this.textStore = new TextStore2(); this.textStore.IsLoading += textStore_IsLoading; this.textStore.IsReadOnly += textStore_IsReadOnly; this.textStore.GetStringLength += () => this.Document.Length; this.textStore.GetString += _textStore_GetString; this.textStore.GetSelectionIndex += _textStore_GetSelectionIndex; this.textStore.SetSelectionIndex += _textStore_SetSelectionIndex; this.textStore.InsertAtSelection += _textStore_InsertAtSelection; this.textStore.GetScreenExtent += _textStore_GetScreenExtent; this.textStore.GetStringExtent += _textStore_GetStringExtent; this.textStore.CompositionStarted += textStore_CompositionStarted; this.textStore.CompositionUpdated += textStore_CompositionUpdated; this.textStore.CompositionEnded += textStore_CompositionEnded; this.rectangle = new Windows.UI.Xaml.Shapes.Rectangle(); this.rectangle.Margin = this.Padding; this.Render = new D2DRender(this,this.rectangle,this.textStore); this.Document = new Document(); this.View = new EditView(this.Document, this.Render, new Padding(5, Gripper.HitAreaWidth, Gripper.HitAreaWidth / 2, Gripper.HitAreaWidth)); this.View.SrcChanged += View_SrcChanged; this.View.InsertMode = this.InsertMode; this.Document.DrawLineNumber = this.DrawLineNumber; this.View.HideCaret = !this.DrawCaret; this.View.HideLineMarker = !this.DrawCaretLine; this.Document.HideRuler = !this.DrawRuler; this.Document.UrlMark = this.MarkURL; this.Document.TabStops = this.TabChars; this._Controller = new Controller(this.Document, this.View); this.Document.SelectionChanged += Controller_SelectionChanged; this.gestureRecongnizer.GestureSettings = GestureSettings.Drag | GestureSettings.RightTap | GestureSettings.Tap | GestureSettings.DoubleTap | GestureSettings.ManipulationTranslateX | GestureSettings.ManipulationTranslateY | GestureSettings.ManipulationScale | GestureSettings.ManipulationTranslateInertia | GestureSettings.ManipulationScaleInertia; this.gestureRecongnizer.RightTapped += gestureRecongnizer_RightTapped; this.gestureRecongnizer.Tapped += gestureRecongnizer_Tapped; this.gestureRecongnizer.Dragging += gestureRecongnizer_Dragging; this.gestureRecongnizer.ManipulationInertiaStarting += GestureRecongnizer_ManipulationInertiaStarting; ; this.gestureRecongnizer.ManipulationStarted += gestureRecongnizer_ManipulationStarted; this.gestureRecongnizer.ManipulationUpdated += gestureRecongnizer_ManipulationUpdated; this.gestureRecongnizer.ManipulationCompleted += gestureRecongnizer_ManipulationCompleted; this.timer.Interval = new TimeSpan(0, 0, 0, 0, 500); this.timer.Tick += this.timer_Tick; this.timer.Start(); //Viewの初期化が終わった直後に置かないと例外が発生する this.Document.Update += Document_Update; Window.Current.CoreWindow.CharacterReceived += CoreWindow_CharacterReceived; this.SizeChanged += FooTextBox_SizeChanged; this.Loaded += FooTextBox_Loaded; } /// /// ファイナライザー /// ~FooTextBox() { this.Dispose(false); } /// /// アンマネージドリソースを解放する /// public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } bool Disposed = false; private void Dispose(bool disposing) { if (this.Disposed) return; if (disposing) { this.textStore.Dispose(); this.View.Dispose(); this.Render.Dispose(); } } /// /// ドキュメントを選択する /// /// 開始インデックス /// 長さ public void Select(int start, int length) { this.Document.Select(start, length); } /// /// キャレットを指定した行に移動させます /// /// インデックス /// このメソッドを呼び出すと選択状態は解除されます public void JumpCaret(int index) { this._Controller.JumpCaret(index); } /// /// キャレットを指定した行と桁に移動させます /// /// 行番号 /// 桁 /// このメソッドを呼び出すと選択状態は解除されます public void JumpCaret(int row, int col) { this._Controller.JumpCaret(row, col); } /// /// 選択中のテキストをクリップボードにコピーします /// public void Copy() { string text = this._Controller.SelectedText; if (text != null && text != string.Empty) { DataPackage dataPackage = new DataPackage(); dataPackage.RequestedOperation = DataPackageOperation.Copy; dataPackage.SetText(text); Clipboard.SetContent(dataPackage); } } /// /// 選択中のテキストをクリップボードに切り取ります /// public void Cut() { string text = this._Controller.SelectedText; if (text != null && text != string.Empty) { DataPackage dataPackage = new DataPackage(); dataPackage.RequestedOperation = DataPackageOperation.Copy; dataPackage.SetText(text); Clipboard.SetContent(dataPackage); this._Controller.SelectedText = ""; } } /// /// 選択中のテキストを貼り付けます /// public async Task PasteAsync() { var dataPackageView = Clipboard.GetContent(); if (dataPackageView.Contains(StandardDataFormats.Text)) { this._Controller.SelectedText = await dataPackageView.GetTextAsync(); } } /// /// すべて選択する /// public void SelectAll() { this.Document.Select(0, this.Document.Length); } /// /// 選択を解除する /// public void DeSelectAll() { this._Controller.DeSelectAll(); } /// /// 対応する座標を返します /// /// テキストポイント /// 座標 /// テキストポイントがクライアント領域の原点より外にある場合、返される値は原点に丸められます public Windows.Foundation.Point GetPostionFromTextPoint(TextPoint tp) { if (this.Document.FireUpdateEvent == false) throw new InvalidOperationException(""); return this.View.GetPostionFromTextPoint(tp); } /// /// 対応するテキストポイントを返します /// /// クライアント領域の原点を左上とする座標 /// テキストポイント public TextPoint GetTextPointFromPostion(Windows.Foundation.Point p) { if (this.Document.FireUpdateEvent == false) throw new InvalidOperationException(""); return this.View.GetTextPointFromPostion(p); } /// /// 行の高さを取得します /// /// レイアウト行 /// 行の高さ public double GetLineHeight(int row) { if (this.Document.FireUpdateEvent == false) throw new InvalidOperationException(""); return this.View.LayoutLines.GetLayout(row).Height; ; } /// /// インデックスに対応する座標を得ます /// /// インデックス /// 座標を返す public Windows.Foundation.Point GetPostionFromIndex(int index) { if (this.Document.FireUpdateEvent == false) throw new InvalidOperationException(""); TextPoint tp = this.View.GetLayoutLineFromIndex(index); return this.View.GetPostionFromTextPoint(tp); } /// /// 座標からインデックスに変換します /// /// 座標 /// インデックスを返す public int GetIndexFromPostion(Windows.Foundation.Point p) { if (this.Document.FireUpdateEvent == false) throw new InvalidOperationException(""); TextPoint tp = this.View.GetTextPointFromPostion(p); return this.View.GetIndexFromLayoutLine(tp); } /// /// 再描写する /// public void Refresh() { this.Refresh(this.View.PageBound); } /// /// レイアウト行をすべて破棄し、再度レイアウトを行う /// public void PerfomLayouts() { this.View.PerfomLayouts(); } /// /// 指定行までスクロールする /// /// 行 /// 指定行を画面上に置くなら真。そうでないなら偽 public void ScrollIntoView(int row, bool alignTop) { this.View.ScrollIntoView(row, alignTop); } /// /// ファイルからドキュメントを構築する /// /// StremReader /// Taskオブジェクト public async Task LoadFileAsync(System.IO.StreamReader sr, System.Threading.CancellationTokenSource token) { this.IsEnabled = false; this.View.LayoutLines.IsFrozneDirtyFlag = true; WinFileReader fs = new WinFileReader(sr); await this.Document.LoadAsync(fs, token); this.View.LayoutLines.IsFrozneDirtyFlag = false; TextStoreHelper.NotifyTextChanged(this.textStore, 0, 0, this.Document.Length); if (this.verticalScrollBar != null) this.verticalScrollBar.Maximum = this.View.LayoutLines.Count; this.View.CalculateLineCountOnScreen(); this.IsEnabled = true; } /// /// ドキュメントの内容をファイルに保存する /// /// StreamWriter /// エンコード /// Taskオブジェクト public async Task SaveFile(System.IO.StreamWriter sw, System.Threading.CancellationTokenSource token) { WinFileWriter fs = new WinFileWriter(sw); await this.Document.SaveAsync(fs, token); } #region command void CopyCommand() { this.Copy(); } void CutCommand() { this.Cut(); this.Refresh(); } async Task PasteCommand() { await this.PasteAsync(); this.Refresh(); } #endregion #region event /// protected override Windows.UI.Xaml.Automation.Peers.AutomationPeer OnCreateAutomationPeer() { this.peer = new FooTextBoxAutomationPeer(this); return this.peer; } /// protected override void OnApplyTemplate() { base.OnApplyTemplate(); Grid grid = this.GetTemplateChild("PART_Grid") as Grid; if (grid != null) { Grid.SetRow(this.rectangle, 0); Grid.SetColumn(this.rectangle, 0); grid.Children.Add(this.rectangle); } this.horizontalScrollBar = this.GetTemplateChild("PART_HorizontalScrollBar") as ScrollBar; if (this.horizontalScrollBar != null) { this.horizontalScrollBar.SmallChange = 10; this.horizontalScrollBar.LargeChange = 100; this.horizontalScrollBar.Maximum = this.horizontalScrollBar.LargeChange + 1; this.horizontalScrollBar.Scroll += new ScrollEventHandler(horizontalScrollBar_Scroll); } this.verticalScrollBar = this.GetTemplateChild("PART_VerticalScrollBar") as ScrollBar; if (this.verticalScrollBar != null) { this.verticalScrollBar.SmallChange = 1; this.verticalScrollBar.LargeChange = 10; this.verticalScrollBar.Maximum = this.View.LayoutLines.Count; this.verticalScrollBar.Scroll += new ScrollEventHandler(verticalScrollBar_Scroll); } } /// protected override void OnGotFocus(RoutedEventArgs e) { base.OnGotFocus(e); this.textStore.SetFocus(); this.View.IsFocused = true; this.Refresh(); } /// protected override void OnLostFocus(RoutedEventArgs e) { base.OnLostFocus(e); this.View.IsFocused = false; this.Refresh(); } /// protected override async void OnKeyDown(KeyRoutedEventArgs e) { bool isControlPressed = this.IsModiferKeyPressed(VirtualKey.Control); bool isShiftPressed = this.IsModiferKeyPressed(VirtualKey.Shift); bool isMovedCaret = false; switch (e.Key) { case VirtualKey.Up: this._Controller.MoveCaretVertical(-1, isShiftPressed); this.Refresh(); e.Handled = true; isMovedCaret = true; break; case VirtualKey.Down: this._Controller.MoveCaretVertical(+1, isShiftPressed); this.Refresh(); e.Handled = true; isMovedCaret = true; break; case VirtualKey.Left: this._Controller.MoveCaretHorizontical(-1, isShiftPressed, isControlPressed); this.Refresh(); e.Handled = true; isMovedCaret = true; break; case VirtualKey.Right: this._Controller.MoveCaretHorizontical(1, isShiftPressed, isControlPressed); this.Refresh(); e.Handled = true; isMovedCaret = true; break; case VirtualKey.PageUp: this._Controller.Scroll(ScrollDirection.Up, this.View.LineCountOnScreen, isShiftPressed, true); this.Refresh(); isMovedCaret = true; break; case VirtualKey.PageDown: this._Controller.Scroll(ScrollDirection.Down, this.View.LineCountOnScreen, isShiftPressed, true); this.Refresh(); isMovedCaret = true; break; case VirtualKey.Home: if (isControlPressed) this._Controller.JumpToHead(isShiftPressed); else this.Controller.JumpToLineHead(this.Document.CaretPostion.row,isShiftPressed); this.Refresh(); isMovedCaret = true; break; case VirtualKey.End: if (isControlPressed) this._Controller.JumpToEnd(isShiftPressed); else this.Controller.JumpToLineEnd(this.Document.CaretPostion.row,isShiftPressed); this.Refresh(); isMovedCaret = true; break; case VirtualKey.Tab: if (!isControlPressed) { if (this._Controller.SelectionLength == 0) this._Controller.DoInputChar('\t'); else if (isShiftPressed) this._Controller.DownIndent(); else this._Controller.UpIndent(); this.Refresh(); e.Handled = true; } break; case VirtualKey.Enter: this._Controller.DoEnterAction(); this.Refresh(); e.Handled = true; break; case VirtualKey.Insert: if(this.View.InsertMode) this.View.InsertMode = false; else this.View.InsertMode = true; this.Refresh(); e.Handled = true; break; case VirtualKey.A: if (isControlPressed) { this.SelectAll(); this.Refresh(); e.Handled = true; } break; case VirtualKey.B: if (isControlPressed) { if (this._Controller.RectSelection) this._Controller.RectSelection = false; else this._Controller.RectSelection = true; this.Refresh(); e.Handled = true; } break; case VirtualKey.C: if (isControlPressed) { this.CopyCommand(); e.Handled = true; } break; case VirtualKey.X: if (isControlPressed) { this.CutCommand(); e.Handled = true; } break; case VirtualKey.V: if (isControlPressed) { await this.PasteCommand(); e.Handled = true; } break; case VirtualKey.Y: if (isControlPressed) { this.Document.UndoManager.redo(); this.Refresh(); e.Handled = true; } break; case VirtualKey.Z: if (isControlPressed) { this.Document.UndoManager.undo(); this.Refresh(); e.Handled = true; } break; case VirtualKey.Back: this._Controller.DoBackSpaceAction(); this.Refresh(); e.Handled = true; break; case VirtualKey.Delete: this._Controller.DoDeleteAction(); this.Refresh(); e.Handled = true; break; } if (isMovedCaret && this.peer != null) this.peer.OnNotifyCaretChanged(); base.OnKeyDown(e); } /// protected override void OnPointerPressed(PointerRoutedEventArgs e) { this.CapturePointer(e.Pointer); this.gestureRecongnizer.ProcessDownEvent(e.GetCurrentPoint(this)); e.Handled = true; } /// protected override void OnPointerMoved(PointerRoutedEventArgs e) { this.gestureRecongnizer.ProcessMoveEvents(e.GetIntermediatePoints(this)); e.Handled = true; if (e.Pointer.PointerDeviceType == PointerDeviceType.Mouse) { Point p = e.GetCurrentPoint(this).Position; if (this.View.HitTextArea(p.X, p.Y)) { TextPoint tp = this.View.GetTextPointFromPostion(p); if (this._Controller.IsMarker(tp, HilightType.Url)) Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Hand, 101); else Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.IBeam, 101); } else { Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Arrow, 101); } } } /// protected override void OnPointerReleased(PointerRoutedEventArgs e) { this.gestureRecongnizer.ProcessUpEvent(e.GetCurrentPoint(this)); e.Handled = true; } /// protected override void OnPointerCanceled(PointerRoutedEventArgs e) { this.gestureRecongnizer.CompleteGesture(); e.Handled = true; } /// protected override void OnPointerWheelChanged(PointerRoutedEventArgs e) { bool shift = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Shift) == Windows.System.VirtualKeyModifiers.Shift; bool ctrl = (e.KeyModifiers & Windows.System.VirtualKeyModifiers.Control) == Windows.System.VirtualKeyModifiers.Control; this.gestureRecongnizer.ProcessMouseWheelEvent(e.GetCurrentPoint(this), shift, ctrl); e.Handled = true; } void CoreWindow_CharacterReceived(CoreWindow sender, CharacterReceivedEventArgs args) { if (this.FocusState == FocusState.Unfocused || !this.IsEnabled) return; if (args.KeyCode >= 00 && args.KeyCode <= 0x1f) return; this._Controller.DoInputString(Char.ConvertFromUtf32((int)args.KeyCode)); this.Refresh(); } bool textStore_IsReadOnly() { return false; } bool textStore_IsLoading() { return false; } void textStore_CompositionEnded() { TextStoreHelper.EndCompostion(this.Document); this.Refresh(); } void textStore_CompositionUpdated(int start, int end) { if (TextStoreHelper.ScrollToCompstionUpdated(this.textStore, this.View, start, end)) this.Refresh(); } bool textStore_CompositionStarted() { return TextStoreHelper.StartCompstion(this.Document); } string _textStore_GetString(int start, int length) { return this.Document.ToString(start, length); } void _textStore_GetStringExtent( int i_startIndex, int i_endIndex, out POINT o_topLeft, out POINT o_bottomRight ) { Point startPos, endPos; TextStoreHelper.GetStringExtent(this.Document, this.View, i_startIndex, i_endIndex, out startPos, out endPos); float dpi; this.Render.GetDpi(out dpi, out dpi); double scale = dpi / 96.0; var gt = this.TransformToVisual(Window.Current.Content); var screenStartPos = gt.TransformPoint(startPos.Scale(scale)); var screenEndPos = gt.TransformPoint(endPos.Scale(scale)); Rect win_rect = Window.Current.CoreWindow.Bounds; o_topLeft = new POINT((int)(screenStartPos.X + win_rect.X), (int)(screenStartPos.Y + win_rect.Y)); o_bottomRight = new POINT((int)(screenEndPos.X + win_rect.X), (int)(screenEndPos.Y + win_rect.Y)); } void _textStore_GetScreenExtent(out POINT o_topLeft, out POINT o_bottomRight) { var pointTopLeft = new Point(0, 0); var pointBottomRight = new Point(this.RenderSize.Width, this.RenderSize.Height); var gt = this.TransformToVisual(Window.Current.Content); pointTopLeft = gt.TransformPoint(pointTopLeft); pointBottomRight = gt.TransformPoint(pointBottomRight); o_topLeft = new POINT((int)pointTopLeft.X, (int)pointTopLeft.Y); o_bottomRight = new POINT((int)pointBottomRight.X, (int)pointBottomRight.Y); } void _textStore_GetSelectionIndex(int start_index, int max_count, out DotNetTextStore.TextSelection[] sels) { TextStoreHelper.GetSelection(this._Controller, this.View.Selections, out sels); } void _textStore_SetSelectionIndex(DotNetTextStore.TextSelection[] sels) { TextStoreHelper.SetSelectionIndex(this._Controller, this.View, sels); this.Refresh(); } void _textStore_InsertAtSelection(string i_value,ref int o_stratIndex,ref int o_endIndex) { TextStoreHelper.InsertTextAtSelection(this._Controller, i_value); this.Refresh(); } void Controller_SelectionChanged(object sender, EventArgs e) { //こうしないと選択できなくなってしまう this.nowCaretMove = true; SetValue(SelectedTextProperty, this._Controller.SelectedText); SetValue(CaretPostionPropertyKey, this.Document.CaretPostion); this.nowCaretMove = false; if (this.textStore.IsLocked() == false) this.textStore.NotifySelectionChanged(); } Gripper hittedGripper; void gestureRecongnizer_ManipulationStarted(GestureRecognizer sender, ManipulationStartedEventArgs e) { //Updateedの段階でヒットテストしてしまうとグリッパーを触ってもヒットしないことがある this.hittedGripper = this.View.HitGripperFromPoint(e.Position); } private void GestureRecongnizer_ManipulationInertiaStarting(GestureRecognizer sender, ManipulationInertiaStartingEventArgs args) { //sender.InertiaTranslationDeceleration = 0.001f; //sender.InertiaExpansionDeceleration = 100.0f * 96.0f / 1000.0f; //sender.InertiaRotationDeceleration = 720.0f / (1000.0f * 1000.0f); } void gestureRecongnizer_ManipulationUpdated(GestureRecognizer sender, ManipulationUpdatedEventArgs e) { if (this._Controller.MoveCaretAndGripper(e.Position, this.hittedGripper)) { if (this.peer != null) this.peer.OnNotifyCaretChanged(); this.Refresh(); return; } if (e.Delta.Scale < 1) { double newSize = this.Render.FontSize - 1; if (newSize < 1) newSize = 1; this.Render.FontSize = newSize; this.Refresh(); SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize); return; } if (e.Delta.Scale > 1) { double newSize = this.Render.FontSize + 1; if (newSize > 72) newSize = 72; this.Render.FontSize = newSize; this.Refresh(); SetValue(MagnificationPowerPropertyKey, this.Render.FontSize / this.FontSize); return; } Point translation = e.Delta.Translation; //Xの絶対値が大きければ横方向のスクロールで、そうでなければ縦方向らしい if (Math.Abs(e.Cumulative.Translation.X) < Math.Abs(e.Cumulative.Translation.Y)) { int deltay = (int)Math.Abs(Math.Ceiling(translation.Y)); if (translation.Y < 0) this._Controller.ScrollByPixel(ScrollDirection.Down, deltay, false, false); else this._Controller.ScrollByPixel(ScrollDirection.Up, deltay, false, false); this.Refresh(); return; } int deltax = (int)Math.Abs(Math.Ceiling(translation.X)); if (deltax != 0) { if (translation.X < 0) this._Controller.Scroll(ScrollDirection.Left, deltax, false, false); else this._Controller.Scroll(ScrollDirection.Right, deltax, false, false); this.Refresh(); } } void gestureRecongnizer_ManipulationCompleted(GestureRecognizer sender, ManipulationCompletedEventArgs e) { } async void gestureRecongnizer_RightTapped(GestureRecognizer sender, RightTappedEventArgs e) { ResourceMap map = ResourceManager.Current.MainResourceMap.GetSubtree("FooEditEngine.Metro/Resources"); ResourceContext context = ResourceContext.GetForCurrentView(); if (this.View.HitTextArea(e.Position.X, e.Position.Y)) { FooContextMenuEventArgs args = new FooContextMenuEventArgs(e.Position); if (this.ContextMenuOpening != null) this.ContextMenuOpening(this, args); if (!args.Handled) { PopupMenu ContextMenu = new PopupMenu(); ContextMenu.Commands.Add(new UICommand(map.GetValue("CopyMenuName", context).ValueAsString, (command) => { this.CopyCommand(); })); ContextMenu.Commands.Add(new UICommand(map.GetValue("CutMenuName", context).ValueAsString, (command) => { this.CutCommand(); })); ContextMenu.Commands.Add(new UICommand(map.GetValue("PasteMenuName", context).ValueAsString, async (command) => { await this.PasteCommand(); })); if (this._Controller.RectSelection) { ContextMenu.Commands.Add(new UICommand(map.GetValue("LineSelectMenuName", context).ValueAsString, (command) => { this._Controller.RectSelection = false; })); } else { ContextMenu.Commands.Add(new UICommand(map.GetValue("RectSelectMenuName", context).ValueAsString, (command) => { this._Controller.RectSelection = true; })); } await ContextMenu.ShowAsync(Util.GetScreentPoint(e.Position,this)); } } } void gestureRecongnizer_Tapped(GestureRecognizer sender, TappedEventArgs e) { bool touched = e.PointerDeviceType == PointerDeviceType.Touch; this.Document.SelectGrippers.BottomLeft.Enabled = false; this.Document.SelectGrippers.BottomRight.Enabled = touched; this.JumpCaret(e.Position); System.Diagnostics.Debug.WriteLine(e.TapCount); if (e.TapCount == 2) { this.Document.SelectGrippers.BottomLeft.Enabled = touched; //タッチスクリーンでダブルタップした場合、アンカーインデックスを単語の先頭にしないとバグる this.Document.SelectWord(this.Controller.SelectionStart, touched); this.Refresh(); } } void JumpCaret(Point p) { TextPoint tp = this.View.GetTextPointFromPostion(p); if (tp == TextPoint.Null) return; int index = this.View.LayoutLines.GetIndexFromTextPoint(tp); FoldingItem foldingData = this.View.HitFoldingData(p.X, tp.row); if (foldingData != null) { if (foldingData.Expand) this.View.LayoutLines.FoldingCollection.Collapse(foldingData); else this.View.LayoutLines.FoldingCollection.Expand(foldingData); this._Controller.JumpCaret(foldingData.Start, false); } else { this._Controller.JumpCaret(tp.row, tp.col, false); } if (this.peer != null) this.peer.OnNotifyCaretChanged(); this.View.IsFocused = true; this.Focus(FocusState.Programmatic); this.Refresh(); } void gestureRecongnizer_Dragging(GestureRecognizer sender, DraggingEventArgs e) { Point p = e.Position; TextPointSearchRange searchRange; if (this.View.HitTextArea(p.X, p.Y)) searchRange = TextPointSearchRange.TextAreaOnly; else if (this._Controller.SelectionLength > 0) searchRange = TextPointSearchRange.Full; else return; TextPoint tp = this.View.GetTextPointFromPostion(p, searchRange); this._Controller.MoveCaretAndSelect(tp); if (this.peer != null) this.peer.OnNotifyCaretChanged(); this.Refresh(); } bool IsModiferKeyPressed(VirtualKey key) { CoreVirtualKeyStates state = Window.Current.CoreWindow.GetKeyState(key); return (state & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down; } void Refresh(Rectangle updateRect) { if (this.rectangle.ActualWidth == 0 || this.rectangle.ActualHeight == 0 || this.Visibility == Windows.UI.Xaml.Visibility.Collapsed) return; this.Render.DrawContent(this.View, this.IsEnabled, updateRect); } bool Resize(double width, double height) { if (width == 0 || height == 0) throw new ArgumentOutOfRangeException(); if (this.Render.Resize(this.rectangle, width, height)) { this.View.PageBound = new Rectangle(0, 0, width, height); if (this.horizontalScrollBar != null) { this.horizontalScrollBar.LargeChange = this.View.PageBound.Width; this.horizontalScrollBar.Maximum = this.View.LongestWidth + this.horizontalScrollBar.LargeChange + 1; } if (this.verticalScrollBar != null) { this.verticalScrollBar.LargeChange = this.View.LineCountOnScreen; this.verticalScrollBar.Maximum = this.View.LayoutLines.Count + this.verticalScrollBar.LargeChange + 1; } return true; } return false; } void View_SrcChanged(object sender, EventArgs e) { if (this.horizontalScrollBar == null || this.verticalScrollBar == null) return; EditView view = this.View; if (view.Src.Row > this.verticalScrollBar.Maximum) this.verticalScrollBar.Maximum = view.Src.Row + view.LineCountOnScreen + 1; double absoulteX = Math.Abs(view.Src.X); if (absoulteX > this.horizontalScrollBar.Maximum) this.horizontalScrollBar.Maximum = absoulteX + view.PageBound.Width + 1; if (view.Src.Row != this.verticalScrollBar.Value) this.verticalScrollBar.Value = view.Src.Row; if (view.Src.X != this.horizontalScrollBar.Value) this.horizontalScrollBar.Value = Math.Abs(view.Src.X); } void FooTextBox_SizeChanged(object sender, SizeChangedEventArgs e) { if (this.Resize(this.rectangle.ActualWidth, this.rectangle.ActualHeight)) { this.Refresh(); return; } } void horizontalScrollBar_Scroll(object sender, ScrollEventArgs e) { if (this.horizontalScrollBar == null) return; double toX; if (this.FlowDirection == FlowDirection.LeftToRight) toX = this.horizontalScrollBar.Value; else toX = -this.horizontalScrollBar.Value; this._Controller.Scroll(toX, this.View.Src.Row, false, false); this.Refresh(); } void verticalScrollBar_Scroll(object sender, ScrollEventArgs e) { if (this.verticalScrollBar == null) return; int newRow = (int)this.verticalScrollBar.Value; if (newRow >= this.View.LayoutLines.Count) return; this._Controller.Scroll(this.View.Src.X, newRow, false, false); this.Refresh(); } void Document_Update(object sender, DocumentUpdateEventArgs e) { if (this.textStore.IsLocked()) return; if (e.type == UpdateType.Replace) TextStoreHelper.NotifyTextChanged(this.textStore, e.startIndex, e.removeLength, e.insertLength); if(this.peer != null) this.peer.OnNotifyTextChanged(); } void FooTextBox_Loaded(object sender, RoutedEventArgs e) { this.Focus(FocusState.Programmatic); } void timer_Tick(object sender, object e) { if (this.View.LayoutLines.HilightAll() || this.View.LayoutLines.GenerateFolding()) this.Refresh(this.View.PageBound); } /// public static void OnPropertyChanged(object sender, DependencyPropertyChangedEventArgs e) { FooTextBox source = (FooTextBox)sender; if(e.Property.Equals(SelectedTextProperty) && !source.nowCaretMove) source._Controller.SelectedText = source.SelectedText; if(e.Property.Equals(HilighterProperty)) source.View.Hilighter = source.Hilighter; if (e.Property.Equals(TextAntialiasModeProperty)) source.Render.TextAntialiasMode = source.TextAntialiasMode; if (e.Property.Equals(FoldingStrategyProperty)) source.View.LayoutLines.FoldingStrategy = source.FoldingStrategy; if (e.Property.Equals(IndentModeProperty)) source.Controller.IndentMode = source.IndentMode; if (e.Property.Equals(SelectionProperty) && !source.nowCaretMove) source.Document.Select(source.Selection.Index,source.Selection.Length); if (e.Property.Equals(CaretPostionPropertyKey) && !source.nowCaretMove) source.JumpCaret(source.CaretPostion.row, source.CaretPostion.col); if (e.Property.Equals(InsertModeProperty)) source.View.InsertMode = source.InsertMode; if (e.Property.Equals(TabCharsProperty)) source.Document.TabStops = source.TabChars; if (e.Property.Equals(RectSelectModeProperty)) source._Controller.RectSelection = source.RectSelectMode; if (e.Property.Equals(DrawCaretProperty)) source.View.HideCaret = !source.DrawCaret; if (e.Property.Equals(DrawCaretLineProperty)) source.View.HideLineMarker = !source.DrawCaretLine; if (e.Property.Equals(DrawLineNumberProperty)) source.Document.DrawLineNumber = source.DrawLineNumber; if(e.Property.Equals(MagnificationPowerPropertyKey)) source.Render.FontSize = source.FontSize * source.MagnificationPower; if (e.Property.Equals(FontFamilyProperty)) source.Render.FontFamily = source.FontFamily; if (e.Property.Equals(FontStyleProperty)) source.Render.FontStyle = source.FontStyle; if (e.Property.Equals(FontWeightProperty)) source.Render.FontWeigth = source.FontWeight; if (e.Property.Equals(FontSizeProperty)) source.Render.FontSize = source.FontSize; if (e.Property.Equals(ForegroundProperty)) source.Render.Foreground = D2DRenderBase.ToColor4(source.Foreground); if (e.Property.Equals(BackgroundProperty)) source.Render.Background = D2DRenderBase.ToColor4(source.Background); if (e.Property.Equals(ControlCharProperty)) source.Render.ControlChar = D2DRenderBase.ToColor4(source.ControlChar); if (e.Property.Equals(HilightProperty)) source.Render.Hilight = D2DRenderBase.ToColor4(source.Hilight); if (e.Property.Equals(Keyword1Property)) source.Render.Keyword1 = D2DRenderBase.ToColor4(source.Keyword1); if (e.Property.Equals(Keyword2Property)) source.Render.Keyword2 = D2DRenderBase.ToColor4(source.Keyword2); if (e.Property.Equals(CommentProperty)) source.Render.Comment = D2DRenderBase.ToColor4(source.Comment); if (e.Property.Equals(LiteralProperty)) source.Render.Literal = D2DRenderBase.ToColor4(source.Literal); if (e.Property.Equals(URLProperty)) source.Render.Url = D2DRenderBase.ToColor4(source.URL); if (e.Property.Equals(InsertCaretProperty)) source.Render.InsertCaret = D2DRenderBase.ToColor4(source.InsertCaret); if (e.Property.Equals(OverwriteCaretProperty)) source.Render.OverwriteCaret = D2DRenderBase.ToColor4(source.OverwriteCaret); if (e.Property.Equals(PaddingProperty)) source.View.Padding = new Padding((int)source.Padding.Left, (int)source.Padding.Top, (int)source.Padding.Right, (int)source.Padding.Bottom); if (e.Property.Equals(LineMarkerProperty)) source.Render.LineMarker = D2DRenderBase.ToColor4(source.LineMarker); if (e.Property.Equals(MarkURLProperty)) source.Document.UrlMark = source.MarkURL; if (e.Property.Equals(ShowFullSpaceProperty)) source.Render.ShowFullSpace = source.ShowFullSpace; if (e.Property.Equals(ShowHalfSpaceProperty)) source.Render.ShowHalfSpace = source.ShowHalfSpace; if (e.Property.Equals(ShowTabProperty)) source.Render.ShowTab = source.ShowTab; if (e.Property.Equals(ShowLineBreakProperty)) source.Render.ShowLineBreak = source.ShowLineBreak; if (e.Property.Equals(LineBreakProperty)) source.Document.LineBreak = source.LineBreakMethod; if (e.Property.Equals(LineBreakCharCountProperty)) source.Document.LineBreakCharCount = source.LineBreakCharCount; if (e.Property.Equals(UpdateAreaProperty)) source.Render.UpdateArea = D2DRenderBase.ToColor4(source.UpdateArea); if (e.Property.Equals(LineNumberProperty)) source.Render.LineNumber = D2DRenderBase.ToColor4(source.LineNumber); if (e.Property.Equals(FlowDirectionProperty)) { source.Document.RightToLeft = source.FlowDirection == Windows.UI.Xaml.FlowDirection.RightToLeft; if(source.horizontalScrollBar != null) source.horizontalScrollBar.FlowDirection = source.FlowDirection; } if (e.Property.Equals(DrawRulerProperty)) { source.Document.HideRuler = !source.DrawRuler; source._Controller.JumpCaret(source.Document.CaretPostion.row, source.Document.CaretPostion.col); } } #endregion #region event /// /// コンテキストメニューが表示されるときに呼び出されます /// public event EventHandler ContextMenuOpening; #endregion #region property internal Controller Controller { get { return this._Controller; } } /// /// 文字列の描写に使用されるアンチエイリアシング モードを表します /// public TextAntialiasMode TextAntialiasMode { get { return (TextAntialiasMode)GetValue(TextAntialiasModeProperty); } set { SetValue(TextAntialiasModeProperty, value); } } /// /// TextAntialiasModeの依存プロパティを表す /// public static readonly DependencyProperty TextAntialiasModeProperty = DependencyProperty.Register("TextAntialiasMode", typeof(TextAntialiasMode), typeof(FooTextBox), new PropertyMetadata(TextAntialiasMode.Default, OnPropertyChanged)); /// /// シンタックスハイライターを表す /// public IHilighter Hilighter { get { return (IHilighter)GetValue(HilighterProperty); } set { SetValue(HilighterProperty, value); } } /// /// Hilighterの依存プロパティを表す /// public static readonly DependencyProperty HilighterProperty = DependencyProperty.Register("Hilighter", typeof(IHilighter), typeof(FooTextBox), new PropertyMetadata(null, OnPropertyChanged)); /// /// フォールティングを作成するインターフェイスを表す /// public IFoldingStrategy FoldingStrategy { get { return (IFoldingStrategy)GetValue(FoldingStrategyProperty); } set { SetValue(FoldingStrategyProperty, value); } } /// /// FoldingStrategyの依存プロパティ /// public static readonly DependencyProperty FoldingStrategyProperty = DependencyProperty.Register("FoldingStrategy", typeof(IFoldingStrategy), typeof(FooTextBox), new PropertyMetadata(null,OnPropertyChanged)); /// /// マーカーパターンセットを表す /// public MarkerPatternSet MarkerPatternSet { get { return this.Document.MarkerPatternSet; } } /// /// ドキュメントを表す /// public Document Document { get { return this._Document; } set { Document old_doc = this._Document; int oldLength = 0; if (this._Document != null) { old_doc.Update -= new DocumentUpdateEventHandler(Document_Update); oldLength = old_doc.Length; } this._Document = value; this._Document.LayoutLines.Render = this.Render; this._Document.Update += new DocumentUpdateEventHandler(Document_Update); //初期化が終わっていればすべて存在する if (this.Controller != null && this.View != null && this.textStore != null) { this.Controller.Document = value; this.View.Document = value; this.Controller.AdjustCaret(); this.textStore.NotifyTextChanged(oldLength, value.Length); //依存プロパティとドキュメント内容が食い違っているので再設定する this.ShowFullSpace = value.ShowFullSpace; this.ShowHalfSpace = value.ShowHalfSpace; this.ShowLineBreak = value.ShowLineBreak; this.ShowTab = value.ShowTab; this.FlowDirection = value.RightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight; this.IndentMode = value.IndentMode; this.DrawCaretLine = !value.HideLineMarker; this.InsertMode = value.InsertMode; this.DrawRuler = !value.HideRuler; this.DrawLineNumber = value.DrawLineNumber; this.MarkURL = value.UrlMark; this.LineBreakMethod = value.LineBreak; this.LineBreakCharCount = value.LineBreakCharCount; this.TabChars = value.TabStops; this.Refresh(); } } } /// /// レイアウト行を表す /// public LineToIndexTable LayoutLineCollection { get { return this.View.LayoutLines; } } /// /// 選択中の文字列を表す /// public string SelectedText { get { return (string)GetValue(SelectedTextProperty); } set { SetValue(SelectedTextProperty, value); } } /// /// SelectedTextの依存プロパティを表す /// public static readonly DependencyProperty SelectedTextProperty = DependencyProperty.Register("SelectedText", typeof(string), typeof(FooTextBox), new PropertyMetadata(null, OnPropertyChanged)); /// /// インデントの方法を表す /// public IndentMode IndentMode { get { return (IndentMode)GetValue(IndentModeProperty); } set { SetValue(IndentModeProperty, value); } } /// /// IndentModeの依存プロパティを表す /// public static readonly DependencyProperty IndentModeProperty = DependencyProperty.Register("IndentMode", typeof(IndentMode), typeof(FooTextBox), new PropertyMetadata(IndentMode.Tab,OnPropertyChanged)); /// /// 選択範囲を表す /// /// /// Lengthが0の場合はキャレット位置を表します。 /// 矩形選択モードの場合、選択範囲の文字数ではなく、開始位置から終了位置までの長さとなります /// public TextRange Selection { get { return (TextRange)GetValue(SelectionProperty); } set { SetValue(SelectionProperty, value); } } /// /// Selectionの依存プロパティを表す /// public static readonly DependencyProperty SelectionProperty = DependencyProperty.Register("Selection", typeof(TextRange), typeof(FooTextBox), new PropertyMetadata(TextRange.Null, OnPropertyChanged)); /// /// 拡大率を表す /// public double MagnificationPower { get { return (double)GetValue(MagnificationPowerPropertyKey); } set { SetValue(MagnificationPowerPropertyKey, value); } } /// /// 拡大率を表す依存プロパティ /// public static readonly DependencyProperty MagnificationPowerPropertyKey = DependencyProperty.Register("MagnificationPower", typeof(double), typeof(FooTextBox), new PropertyMetadata(1.0, OnPropertyChanged)); /// /// キャレット位置を表す /// public TextPoint CaretPostion { get { return (TextPoint)GetValue(CaretPostionPropertyKey); } set { SetValue(CaretPostionPropertyKey, value); } } static readonly DependencyProperty CaretPostionPropertyKey = DependencyProperty.Register("CaretPostion", typeof(TextPoint), typeof(FooTextBox), new PropertyMetadata(new TextPoint(), OnPropertyChanged)); /// /// レタリング方向を表す /// public new FlowDirection FlowDirection { get { return (FlowDirection)GetValue(FlowDirectionProperty); } set { SetValue(FlowDirectionProperty, value); } } /// /// レタリング方向を表す。これは依存プロパティです /// public new static readonly DependencyProperty FlowDirectionProperty = DependencyProperty.Register("FlowDirection", typeof(FlowDirection), typeof(FooTextBox), new PropertyMetadata(FlowDirection.LeftToRight,OnPropertyChanged)); /// /// フォントファミリーを表す /// public new FontFamily FontFamily { get { return (FontFamily)GetValue(FontFamilyProperty); } set { SetValue(FontFamilyProperty, value); } } /// /// FontFamilyの依存プロパティを表す /// public new static readonly DependencyProperty FontFamilyProperty = DependencyProperty.Register("FontFamily", typeof(FontFamily), typeof(FooTextBox), new PropertyMetadata(new FontFamily("Cambria"), OnPropertyChanged)); /// /// フォントサイズを表す /// public new double FontSize { get { return (double)GetValue(FontSizeProperty); } set { SetValue(FontSizeProperty, value); } } /// /// FontSizeの依存プロパティを表す /// public new static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register("FontSize", typeof(double), typeof(FooTextBox), new PropertyMetadata(12.0,OnPropertyChanged)); /// /// フォントスタイルを表す /// public new FontStyle FontStyle { get { return (FontStyle)GetValue(FontStyleProperty); } set { SetValue(FontStyleProperty, value); } } /// /// FontStyleの依存プロパティを表す /// public new static readonly DependencyProperty FontStyleProperty = DependencyProperty.Register("FontStyle", typeof(FontStyle), typeof(FooTextBox), new PropertyMetadata(FontStyle.Normal,OnPropertyChanged)); /// /// フォントの幅を表す /// public new FontWeight FontWeight { get { return (FontWeight)GetValue(FontWeightProperty); } set { SetValue(FontWeightProperty, value); } } /// /// FontWeigthの依存プロパティを表す /// public new static readonly DependencyProperty FontWeightProperty = DependencyProperty.Register("FontWeigth", typeof(FontWeight), typeof(FooTextBox), new PropertyMetadata(FontWeights.Normal,OnPropertyChanged)); /// /// デフォルトの文字色を表す。これは依存プロパティです /// public new Windows.UI.Color Foreground { get { return (Windows.UI.Color)GetValue(ForegroundProperty); } set { SetValue(ForegroundProperty, value); } } /// /// Foregroundの依存プロパティを表す /// public new static readonly DependencyProperty ForegroundProperty = DependencyProperty.Register("Foreground", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged)); /// /// 背景色を表す。これは依存プロパティです /// public new Windows.UI.Color Background { get { return (Windows.UI.Color)GetValue(BackgroundProperty); } set { SetValue(BackgroundProperty, value); } } /// /// Backgroundの依存プロパティを表す /// public new static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register("Background", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.White, OnPropertyChanged)); /// /// コントロールコードの文字色を表す。これは依存プロパティです /// public Windows.UI.Color ControlChar { get { return (Windows.UI.Color)GetValue(ControlCharProperty); } set { SetValue(ControlCharProperty, value); } } /// /// ControlCharの依存プロパティを表す /// public static readonly DependencyProperty ControlCharProperty = DependencyProperty.Register("ControlChar", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Gray, OnPropertyChanged)); /// /// 選択時の背景色を表す。これは依存プロパティです /// public Windows.UI.Color Hilight { get { return (Windows.UI.Color)GetValue(HilightProperty); } set { SetValue(HilightProperty, value); } } /// /// Hilightの依存プロパティを表す /// public static readonly DependencyProperty HilightProperty = DependencyProperty.Register("Hilight", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DeepSkyBlue, OnPropertyChanged)); /// /// キーワード1の文字色を表す。これは依存プロパティです /// public Windows.UI.Color Keyword1 { get { return (Windows.UI.Color)GetValue(Keyword1Property); } set { SetValue(Keyword1Property, value); } } /// /// Keyword1の依存プロパティを表す /// public static readonly DependencyProperty Keyword1Property = DependencyProperty.Register("Keyword1", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Blue, OnPropertyChanged)); /// /// キーワード2の文字色を表す。これは依存プロパティです /// public Windows.UI.Color Keyword2 { get { return (Windows.UI.Color)GetValue(Keyword2Property); } set { SetValue(Keyword2Property, value); } } /// /// Keyword2の依存プロパティを表す /// public static readonly DependencyProperty Keyword2Property = DependencyProperty.Register("Keyword2", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DarkCyan, OnPropertyChanged)); /// /// コメントの文字色を表す。これは依存プロパティです /// public Windows.UI.Color Comment { get { return (Windows.UI.Color)GetValue(CommentProperty); } set { SetValue(CommentProperty, value); } } /// /// Commentの依存プロパティを表す /// public static readonly DependencyProperty CommentProperty = DependencyProperty.Register("Comment", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Green, OnPropertyChanged)); /// /// 文字リテラルの文字色を表す。これは依存プロパティです /// public Windows.UI.Color Literal { get { return (Windows.UI.Color)GetValue(LiteralProperty); } set { SetValue(LiteralProperty, value); } } /// /// Literalの依存プロパティを表す /// public static readonly DependencyProperty LiteralProperty = DependencyProperty.Register("Literal", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Brown, OnPropertyChanged)); /// /// URLの文字色を表す。これは依存プロパティです /// public Windows.UI.Color URL { get { return (Windows.UI.Color)GetValue(URLProperty); } set { SetValue(URLProperty, value); } } /// /// URLの依存プロパティを表す /// public static readonly DependencyProperty URLProperty = DependencyProperty.Register("URL", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Blue, OnPropertyChanged)); /// /// 行更新フラグの色を表す /// public Windows.UI.Color UpdateArea { get { return (Windows.UI.Color)GetValue(UpdateAreaProperty); } set { SetValue(UpdateAreaProperty, value); } } /// /// UpdateAreaの依存プロパティを表す /// public static readonly DependencyProperty UpdateAreaProperty = DependencyProperty.Register("UpdateArea", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.MediumSeaGreen, OnPropertyChanged)); /// /// ラインマーカーの色を表す /// public Windows.UI.Color LineMarker { get { return (Windows.UI.Color)GetValue(LineMarkerProperty); } set { SetValue(LineMarkerProperty, value); } } /// /// LineMarkerの依存プロパティを表す /// public static readonly DependencyProperty LineMarkerProperty = DependencyProperty.Register("LineMarker", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Gray, OnPropertyChanged)); /// /// 挿入モード時のキャレットの色を表す /// public Windows.UI.Color InsertCaret { get { return (Windows.UI.Color)GetValue(InsertCaretProperty); } set { SetValue(InsertCaretProperty, value); } } /// /// InsertCaretの依存プロパティを表す /// public static readonly DependencyProperty InsertCaretProperty = DependencyProperty.Register("InsertCaret", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged)); /// /// 上書きモード時のキャレット職を表す /// public Windows.UI.Color OverwriteCaret { get { return (Windows.UI.Color)GetValue(OverwriteCaretProperty); } set { SetValue(OverwriteCaretProperty, value); } } /// /// OverwriteCaretの依存プロパティを表す /// public static readonly DependencyProperty OverwriteCaretProperty = DependencyProperty.Register("OverwriteCaret", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.Black, OnPropertyChanged)); /// /// 行番号の色を表す /// public Windows.UI.Color LineNumber { get { return (Windows.UI.Color)GetValue(LineNumberProperty); } set { SetValue(LineNumberProperty, value); } } /// /// Using a DependencyProperty as the backing store for LineNumber. This enables animation, styling, binding, etc... /// public static readonly DependencyProperty LineNumberProperty = DependencyProperty.Register("LineNumber", typeof(Windows.UI.Color), typeof(FooTextBox), new PropertyMetadata(Colors.DimGray,OnPropertyChanged)); /// /// 余白を表す /// public new Thickness Padding { get { return (Thickness)GetValue(PaddingProperty); } set { SetValue(PaddingProperty, value); } } /// /// Paddingの依存プロパティを表す /// public new static readonly DependencyProperty PaddingProperty = DependencyProperty.Register("Padding", typeof(Thickness), typeof(FooTextBox), new PropertyMetadata(new Thickness(),OnPropertyChanged)); /// /// 挿入モードなら真を返し、そうでないなら、偽を返す。これは依存プロパティです /// public bool InsertMode { get { return (bool)GetValue(InsertModeProperty); } set { SetValue(InsertModeProperty, value); } } /// /// InsertModeの依存プロパティを表す /// public static readonly DependencyProperty InsertModeProperty = DependencyProperty.Register("InsertMode", typeof(bool), typeof(FooTextBox), new PropertyMetadata(true, OnPropertyChanged)); /// /// タブの文字数を表す。これは依存プロパティです /// public int TabChars { get { return (int)GetValue(TabCharsProperty); } set { SetValue(TabCharsProperty, value); } } /// /// TabCharsの依存プロパティを表す /// public static readonly DependencyProperty TabCharsProperty = DependencyProperty.Register("TabChars", typeof(int), typeof(FooTextBox), new PropertyMetadata(4, OnPropertyChanged)); /// /// 矩形選択モードなら真を返し、そうでないなら偽を返す。これは依存プロパティです /// public bool RectSelectMode { get { return (bool)GetValue(RectSelectModeProperty); } set { SetValue(RectSelectModeProperty, value); } } /// /// RectSelectModeの依存プロパティを表す /// public static readonly DependencyProperty RectSelectModeProperty = DependencyProperty.Register("RectSelectMode", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged)); /// /// 折り返しの方法を指定する /// /// /// 変更した場合、レイアウトの再構築を行う必要があります /// public LineBreakMethod LineBreakMethod { get { return (LineBreakMethod)GetValue(LineBreakProperty); } set { SetValue(LineBreakProperty, value); } } /// /// LineBreakMethodの依存プロパティを表す /// public static readonly DependencyProperty LineBreakProperty = DependencyProperty.Register("LineBreakMethod", typeof(LineBreakMethod), typeof(FooTextBox), new PropertyMetadata(LineBreakMethod.None, OnPropertyChanged)); /// /// 折り返しの幅を指定する。LineBreakMethod.CharUnit以外の時は無視されます /// /// /// 変更した場合、レイアウトの再構築を行う必要があります /// public int LineBreakCharCount { get { return (int)GetValue(LineBreakCharCountProperty); } set { SetValue(LineBreakCharCountProperty, value); } } /// /// LineBreakCharCountの依存プロパティを表す /// public static readonly DependencyProperty LineBreakCharCountProperty = DependencyProperty.Register("LineBreakCharCount", typeof(int), typeof(FooTextBox), new PropertyMetadata(80, OnPropertyChanged)); /// /// キャレットを描くなら真。そうでないなら偽を返す。これは依存プロパティです /// public bool DrawCaret { get { return (bool)GetValue(DrawCaretProperty); } set { SetValue(DrawCaretProperty, value); } } /// /// DrawCaretの依存プロパティを表す /// public static readonly DependencyProperty DrawCaretProperty = DependencyProperty.Register("DrawCaret", typeof(bool), typeof(FooTextBox), new PropertyMetadata(true, OnPropertyChanged)); /// /// キャレットラインを描くなら真。そうでないなら偽を返す。これは依存プロパティです /// public bool DrawCaretLine { get { return (bool)GetValue(DrawCaretLineProperty); } set { SetValue(DrawCaretLineProperty, value); } } /// /// DrawCaretLineの依存プロパティを表す /// public static readonly DependencyProperty DrawCaretLineProperty = DependencyProperty.Register("DrawCaretLine", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged)); /// /// 行番号を描くなら真。そうでなければ偽。これは依存プロパティです /// public bool DrawLineNumber { get { return (bool)GetValue(DrawLineNumberProperty); } set { SetValue(DrawLineNumberProperty, value); } } /// /// ルーラーを描くなら真。そうでなければ偽。これは依存プロパティです /// public bool DrawRuler { get { return (bool)GetValue(DrawRulerProperty); } set { SetValue(DrawRulerProperty, value); } } /// /// DrawRulerの依存プロパティを表す /// public static readonly DependencyProperty DrawRulerProperty = DependencyProperty.Register("DrawRuler", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged)); /// /// DrawLineNumberの依存プロパティを表す /// public static readonly DependencyProperty DrawLineNumberProperty = DependencyProperty.Register("DrawLineNumber", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged)); /// /// URLに下線を引くなら真。そうでないなら偽を表す。これは依存プロパティです /// public bool MarkURL { get { return (bool)GetValue(MarkURLProperty); } set { SetValue(MarkURLProperty, value); } } /// /// MarkURLの依存プロパティを表す /// public static readonly DependencyProperty MarkURLProperty = DependencyProperty.Register("MarkURL", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged)); /// /// 全角スペースを表示するなら真。そうでないなら偽 /// public bool ShowFullSpace { get { return (bool)GetValue(ShowFullSpaceProperty); } set { SetValue(ShowFullSpaceProperty, value); } } /// /// ShowFullSpaceの依存プロパティを表す /// public static readonly DependencyProperty ShowFullSpaceProperty = DependencyProperty.Register("ShowFullSpace", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged)); /// /// 半角スペースを表示するなら真。そうでないなら偽 /// public bool ShowHalfSpace { get { return (bool)GetValue(ShowHalfSpaceProperty); } set { SetValue(ShowHalfSpaceProperty, value); } } /// /// ShowHalfSpaceの依存プロパティを表す /// public static readonly DependencyProperty ShowHalfSpaceProperty = DependencyProperty.Register("ShowHalfSpace", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged)); /// /// タブを表示するなら真。そうでないなら偽 /// public bool ShowTab { get { return (bool)GetValue(ShowTabProperty); } set { SetValue(ShowTabProperty, value); } } /// /// ShowTabの依存プロパティを表す /// public static readonly DependencyProperty ShowTabProperty = DependencyProperty.Register("ShowTab", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false, OnPropertyChanged)); /// /// 改行マークを表示するなら真。そうでないなら偽 /// public bool ShowLineBreak { get { return (bool)GetValue(ShowLineBreakProperty); } set { SetValue(ShowLineBreakProperty, value); } } /// /// ShowLineBreakの依存プロパティを表す /// public static readonly DependencyProperty ShowLineBreakProperty = DependencyProperty.Register("ShowLineBreak", typeof(bool), typeof(FooTextBox), new PropertyMetadata(false,OnPropertyChanged)); #endregion } /// /// コンテキストメニューのイベントデーターを表す /// public class FooContextMenuEventArgs { /// /// 処理済みなら真。そうでないなら偽 /// public bool Handled = false; /// /// コンテキストメニューを表示すべき座標を表す /// public Windows.Foundation.Point Postion; /// /// コンストラクター /// /// public FooContextMenuEventArgs(Windows.Foundation.Point pos) { this.Postion = pos; } } }