PageRenderTime 46ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/Common/Product/ReplWindow/Repl/ZoomableInlineAdornment.cs

https://gitlab.com/SplatoonModdingHub/PTVS
C# | 173 lines | 132 code | 28 blank | 13 comment | 19 complexity | 05b788f6a5d006a008c88757cd614447 MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Apache License, Version 2.0, please send an email to
  8. * vspython@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Apache License, Version 2.0.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. * ***************************************************************************/
  14. using System;
  15. using System.Diagnostics;
  16. using System.Windows;
  17. using System.Windows.Controls;
  18. using System.Windows.Documents;
  19. using System.Windows.Input;
  20. using Microsoft.VisualStudio.Text.Editor;
  21. #if NTVS_FEATURE_INTERACTIVEWINDOW
  22. namespace Microsoft.NodejsTools.Repl {
  23. #else
  24. namespace Microsoft.VisualStudio.Repl {
  25. #endif
  26. internal class ZoomableInlineAdornment : ContentControl {
  27. private readonly ITextView _parent;
  28. private ResizingAdorner _adorner;
  29. private bool _isResizing;
  30. private double _zoom;
  31. private readonly double _minimizedZoom;
  32. private readonly double _zoomStep;
  33. private readonly double _widthRatio, _heightRatio;
  34. public ZoomableInlineAdornment(UIElement content, ITextView parent) {
  35. _parent = parent;
  36. Debug.Assert(parent is IInputElement);
  37. Content = new Border { BorderThickness = new Thickness(1), Child = content, Focusable = true };
  38. _zoom = 1.0; // config.GetConfig().Repl.InlineMedia.MaximizedZoom
  39. _zoomStep = 0.25; // config.GetConfig().Repl.InlineMedia.ZoomStep
  40. _minimizedZoom = 0.25; // config.GetConfig().Repl.InlineMedia.MinimizedZoom
  41. _widthRatio = 0.67; // config.GetConfig().Repl.InlineMedia.WidthRatio
  42. _heightRatio = 0.5; // config.GetConfig().Repl.InlineMedia.HeightRatio
  43. _isResizing = false;
  44. UpdateSize();
  45. GotFocus += OnGotFocus;
  46. LostFocus += OnLostFocus;
  47. ContextMenu = MakeContextMenu();
  48. var trigger = new Trigger { Property = Border.IsFocusedProperty, Value = true };
  49. var setter = new Setter { Property = Border.BorderBrushProperty, Value = SystemColors.ActiveBorderBrush };
  50. trigger.Setters.Add(setter);
  51. var style = new Style();
  52. style.Triggers.Add(trigger);
  53. MyContent.Style = style;
  54. }
  55. protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) {
  56. base.OnPreviewMouseLeftButtonDown(e);
  57. ((Border)Content).Focus();
  58. e.Handled = true;
  59. }
  60. private ContextMenu MakeContextMenu() {
  61. var result = new ContextMenu();
  62. AddMenuItem(result, "Zoom In", "Ctrl+OemPlus", (s, e) => OnZoomIn());
  63. AddMenuItem(result, "Zoom Out", "Ctrl+OemMinus", (s, e) => OnZoomOut());
  64. result.Items.Add(new Separator());
  65. AddMenuItem(result, "150%", null, (s, e) => Zoom(1.5));
  66. AddMenuItem(result, "100%", null, (s, e) => Zoom(1.0));
  67. AddMenuItem(result, "75%", null, (s, e) => Zoom(0.75));
  68. AddMenuItem(result, "50%", null, (s, e) => Zoom(0.50));
  69. AddMenuItem(result, "25%", null, (s, e) => Zoom(0.25));
  70. return result;
  71. }
  72. private static void AddMenuItem(ContextMenu menu, string text, string shortcut, EventHandler handler) {
  73. var item = new MenuItem();
  74. item.Header = text;
  75. item.Click += (s, e) => handler(s, e);
  76. menu.Items.Add(item);
  77. }
  78. private Border MyContent {
  79. get { return Content as Border; }
  80. }
  81. private void OnGotFocus(object sender, RoutedEventArgs args) {
  82. _adorner = new ResizingAdorner(MyContent);
  83. _adorner.ResizeStarted += OnResizeStarted;
  84. _adorner.ResizeCompleted += OnResizeCompleted;
  85. var adornerLayer = AdornerLayer.GetAdornerLayer(MyContent);
  86. if (adornerLayer != null) {
  87. adornerLayer.Add(_adorner);
  88. }
  89. }
  90. private void OnLostFocus(object sender, RoutedEventArgs args) {
  91. _adorner.ResizeStarted -= OnResizeStarted;
  92. _adorner.ResizeCompleted -= OnResizeCompleted;
  93. var adornerLayer = AdornerLayer.GetAdornerLayer(MyContent);
  94. if (adornerLayer != null) {
  95. adornerLayer.Remove(_adorner);
  96. _adorner = null;
  97. }
  98. }
  99. protected override void OnPreviewKeyDown(KeyEventArgs args) {
  100. var modifiers = args.KeyboardDevice.Modifiers & ModifierKeys.Control;
  101. if (modifiers == ModifierKeys.Control && (args.Key == Key.OemPlus || args.Key == Key.Add)) {
  102. OnZoomIn();
  103. args.Handled = true;
  104. } else if (modifiers == ModifierKeys.Control && (args.Key == Key.OemMinus || args.Key == Key.Subtract)) {
  105. OnZoomOut();
  106. args.Handled = true;
  107. }
  108. base.OnPreviewKeyDown(args);
  109. }
  110. private void OnResizeStarted(object sender, RoutedEventArgs args) {
  111. _isResizing = true;
  112. }
  113. private void OnResizeCompleted(object sender, RoutedEventArgs args) {
  114. _isResizing = false;
  115. _zoom = MyContent.DesiredSize.Width / (_parent.ViewportWidth * _widthRatio);
  116. }
  117. internal void Zoom(double zoomFactor) {
  118. _zoom = zoomFactor;
  119. UpdateSize();
  120. }
  121. private void OnZoomIn() {
  122. _zoom += _zoomStep;
  123. UpdateSize();
  124. }
  125. private void OnZoomOut() {
  126. if (_zoom - _zoomStep > 0.1) {
  127. _zoom -= _zoomStep;
  128. UpdateSize();
  129. }
  130. }
  131. internal void UpdateSize() {
  132. if (_isResizing) {
  133. return;
  134. }
  135. double width = _parent.ViewportWidth * _widthRatio * _zoom;
  136. double height = _parent.ViewportHeight * _heightRatio * _zoom;
  137. MyContent.MaxWidth = width;
  138. MyContent.MaxHeight = height;
  139. MyContent.Measure(new Size(width, height));
  140. }
  141. internal double MinimizedZoom {
  142. get { return _minimizedZoom; }
  143. }
  144. }
  145. }