|
|
Quellcode |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
using System;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
using System.Windows.Input;
namespace RPG.Editor.Framework {
public class AutoScrollViewer : ScrollViewer {
readonly VisualCollection _visuals;
const double ScrollBaseSize = 2.5,
InvisibleCursorRadius = 12,
FourWayCursorRadius = 60;
Point _scrollBasePosition;
Vector _vector;
readonly Timer _ht,
_vt;
readonly DrawingVisual _scrollBase;
public AutoScrollViewer()
: base() {
_visuals = new VisualCollection(this);
_ht = new Timer {Interval = 80};
_ht.Elapsed += new ElapsedEventHandler(ScrollTickX);
_vt = new Timer {Interval = 80};
_vt.Elapsed += new ElapsedEventHandler(ScrollTickY);
_scrollBase = new DrawingVisual();
using (DrawingContext dc = _scrollBase.RenderOpen()) {
dc.DrawEllipse(Brushes.Black, new Pen(Brushes.White, 1), new Point(ScrollBaseSize, ScrollBaseSize), ScrollBaseSize, ScrollBaseSize);
}
_scrollBase.Opacity = 0;
_visuals.Add(_scrollBase);
}
private Timer HorizontalTimer {
get { return _ht; }
}
private Timer VerticalTimer {
get { return _vt; }
}
private DrawingVisual ScrollBase {
get { return _scrollBase; }
}
protected override Visual GetVisualChild(int index) {
if(index >= base.VisualChildrenCount)
return _visuals[index - base.VisualChildrenCount];
return base.GetVisualChild(index);
}
protected override int VisualChildrenCount {
get { return _visuals.Count + base.VisualChildrenCount; }
}
protected override void OnMouseDown(MouseButtonEventArgs e) {
base.OnMouseDown(e);
if (e.MouseDevice.MiddleButton == MouseButtonState.Pressed) {
_scrollBasePosition = e.MouseDevice.GetPosition(this);
ScrollBase.Opacity = 1;
ScrollBase.Offset = new Vector(_scrollBasePosition.X, _scrollBasePosition.Y);
Cursor = Cursors.None;
if (HorizontalScrollBarVisibility == ScrollBarVisibility.Visible)
HorizontalTimer.Enabled = true;
if (VerticalScrollBarVisibility == ScrollBarVisibility.Visible)
VerticalTimer.Enabled = true;
}
}
protected override void OnMouseUp(MouseButtonEventArgs e) {
base.OnMouseUp(e);
if (e.MouseDevice.MiddleButton == MouseButtonState.Released) {
ScrollBase.Opacity = 0;
HorizontalTimer.Stop();
VerticalTimer.Stop();
Cursor = Cursors.Arrow;
}
}
protected override void OnMouseMove(MouseEventArgs e) {
base.OnMouseMove(e);
if (e.MiddleButton == MouseButtonState.Pressed) {
_vector = _scrollBasePosition - e.MouseDevice.GetPosition(this);
if (_vector.Length < InvisibleCursorRadius) {
Cursor = Cursors.None;
return;
}
if (HorizontalTimer.Enabled && VerticalTimer.Enabled) {
double absX = Math.Abs(_vector.X),
absY = Math.Abs(_vector.Y);
if (_vector.X > 0 && absX > absY) Cursor = Cursors.ScrollW;
if (_vector.X < 0 && absX > absY) Cursor = Cursors.ScrollE;
if (_vector.Y > 0 && absY > absX) Cursor = Cursors.ScrollN;
if (_vector.Y < 0 && absY > absX) Cursor = Cursors.ScrollS;
if (_vector.Length > FourWayCursorRadius && Math.Abs(absX - absY) < _vector.Length / 2 && Math.Abs(absY - absX) < _vector.Length / 2) {
if (_vector.X > 0 && _vector.Y > 0) Cursor = Cursors.ScrollNW;
if (_vector.X < 0 && _vector.Y > 0) Cursor = Cursors.ScrollNE;
if (_vector.X > 0 && _vector.Y < 0) Cursor = Cursors.ScrollSW;
if (_vector.X < 0 && _vector.Y < 0) Cursor = Cursors.ScrollSE;
}
} else {
if (HorizontalTimer.Enabled) {
if (_vector.X > 0) Cursor = Cursors.ScrollW;
if (_vector.X < 0) Cursor = Cursors.ScrollE;
}
if (VerticalTimer.Enabled) {
if (_vector.Y > 0) Cursor = Cursors.ScrollN;
if (_vector.Y < 0) Cursor = Cursors.ScrollS;
}
}
}
}
void ScrollTickX(object sender, ElapsedEventArgs e) {
Dispatcher.Invoke((Action)(() => ScrollToHorizontalOffset(HorizontalOffset - _vector.X)));
}
void ScrollTickY(object sender, ElapsedEventArgs e) {
Dispatcher.Invoke((Action)(() => ScrollToVerticalOffset(VerticalOffset - _vector.Y)));
}
}
}
|
Forensoftware: Burning Board® 3.1.7, entwickelt von WoltLab® GmbH
