aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Controls/MdiContainerControl.xaml
blob: 50c2aaf46dc11907f1207fd677480115c4537fde (plain)
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
<UserControl x:Class="Tango.MachineStudio.Common.Controls.MdiContainerControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
             xmlns:local="clr-namespace:Tango.MachineStudio.Common.Controls"
             xmlns:converters="clr-namespace:Tango.MachineStudio.Common.Converters"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">

    <UserControl.Resources>
        <converters:PointToMarginConverter x:Key="PointToMarginConverter"></converters:PointToMarginConverter>
    </UserControl.Resources>
    
    <Grid>
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=UserControl,Mode=FindAncestor},Path=ItemsSource}" x:Name="itemsControl">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas x:Name="canvas"  HorizontalAlignment="Left" VerticalAlignment="Top"></Canvas>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemContainerStyle>
                    <Style TargetType="FrameworkElement">
                        <Setter Property="Canvas.Left" Value="{Binding Location.X}"></Setter>
                        <Setter Property="Canvas.Top" Value="{Binding Location.Y}"></Setter>
                        <EventSetter Event="PreviewMouseDown" Handler="OnControlMouseDown"></EventSetter>
                    </Style>
                </ItemsControl.ItemContainerStyle>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="25"/>
                                    <RowDefinition Height="277*"/>
                                </Grid.RowDefinitions>

                                <Grid Background="{StaticResource AccentColorBrush}">
                                    <Thumb Opacity="0" DragDelta="OnControlDragging" Tag="{Binding}"></Thumb>
                                    <DockPanel LastChildFill="False">
                                        <StackPanel IsHitTestVisible="False" DockPanel.Dock="Left" VerticalAlignment="Center" Orientation="Horizontal" Margin="5 0 0 0">
                                            <materialDesign:PackIcon Kind="{Binding Icon}" Foreground="White"></materialDesign:PackIcon>
                                            <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Foreground="White" Text="{Binding Header}"></TextBlock>
                                        </StackPanel>

                                        <StackPanel DockPanel.Dock="Right" VerticalAlignment="Center" Orientation="Horizontal">
                                            <Button Foreground="White" Style="{StaticResource MaterialDesignFlatButton}" ToolTip="Close" Width="24" Height="24" Padding="0" Click="OnControlClosed" Tag="{Binding}">
                                                <materialDesign:PackIcon Kind="WindowClose" />
                                            </Button>
                                        </StackPanel>
                                    </DockPanel>
                                </Grid>

                                <Grid Grid.Row="1" MinWidth="100" MinHeight="100">
                                    <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
                                        <ContentPresenter Content="{Binding View}"></ContentPresenter>
                                    </ScrollViewer>

                                    <Thumb HorizontalAlignment="Right" VerticalAlignment="Stretch" Opacity="0" Width="5" Cursor="SizeWE" DragDelta="OnControlSizeRight" Tag="{Binding}"></Thumb>
                                    <Thumb HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Opacity="0" Height="5" Cursor="SizeNS" DragDelta="OnControlSizeBottom" Tag="{Binding}"></Thumb>
                                    <Thumb HorizontalAlignment="Right" VerticalAlignment="Bottom" Opacity="0" Height="10" Width="10" Cursor="SizeNWSE" DragDelta="OnControlResize" Tag="{Binding}"></Thumb>
                                </Grid>
                            </Grid>
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>    
    </Grid>
</UserControl>
">; using System.Windows.Media; using System.Windows.Media.TextFormatting; using Tango.Scripting.Editors.Document; using Tango.Scripting.Editors.Rendering; using Tango.Scripting.Editors.Utils; namespace Tango.Scripting.Editors.Editing { /// <summary> /// Margin showing line numbers. /// </summary> public class LineNumberMargin : AbstractMargin, IWeakEventListener { public Brush Foreground { get { return (Brush)GetValue(ForegroundProperty); } set { SetValue(ForegroundProperty, value); } } public static readonly DependencyProperty ForegroundProperty = DependencyProperty.Register("Foreground", typeof(Brush), typeof(LineNumberMargin), new PropertyMetadata(Brushes.Gray)); static LineNumberMargin() { DefaultStyleKeyProperty.OverrideMetadata(typeof(LineNumberMargin), new FrameworkPropertyMetadata(typeof(LineNumberMargin))); } TextArea textArea; Typeface typeface; double emSize; /// <inheritdoc/> protected override Size MeasureOverride(Size availableSize) { typeface = this.CreateTypeface(); emSize = (double)GetValue(TextBlock.FontSizeProperty); FormattedText text = TextFormatterFactory.CreateFormattedText( this, new string('9', maxLineNumberLength), typeface, emSize, Foreground ); return new Size(text.Width, 0); } /// <inheritdoc/> protected override void OnRender(DrawingContext drawingContext) { TextView textView = this.TextView; Size renderSize = this.RenderSize; if (textView != null && textView.VisualLinesValid) { var foreground = Foreground; foreach (VisualLine line in textView.VisualLines) { int lineNumber = line.FirstDocumentLine.LineNumber; FormattedText text = TextFormatterFactory.CreateFormattedText( this, lineNumber.ToString(CultureInfo.CurrentCulture), typeface, emSize, foreground ); double y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.TextTop); drawingContext.DrawText(text, new Point((renderSize.Width / 2) - text.Width + 5, y - textView.VerticalOffset)); } } } /// <inheritdoc/> protected override void OnTextViewChanged(TextView oldTextView, TextView newTextView) { if (oldTextView != null) { oldTextView.VisualLinesChanged -= TextViewVisualLinesChanged; } base.OnTextViewChanged(oldTextView, newTextView); if (newTextView != null) { newTextView.VisualLinesChanged += TextViewVisualLinesChanged; // find the text area belonging to the new text view textArea = newTextView.Services.GetService(typeof(TextArea)) as TextArea; } else { textArea = null; } InvalidateVisual(); } /// <inheritdoc/> protected override void OnDocumentChanged(TextDocument oldDocument, TextDocument newDocument) { if (oldDocument != null) { PropertyChangedEventManager.RemoveListener(oldDocument, this, "LineCount"); } base.OnDocumentChanged(oldDocument, newDocument); if (newDocument != null) { PropertyChangedEventManager.AddListener(newDocument, this, "LineCount"); } OnDocumentLineCountChanged(); } /// <inheritdoc cref="IWeakEventListener.ReceiveWeakEvent"/> protected virtual bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e) { if (managerType == typeof(PropertyChangedEventManager)) { OnDocumentLineCountChanged(); return true; } return false; } bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e) { return ReceiveWeakEvent(managerType, sender, e); } int maxLineNumberLength = 1; void OnDocumentLineCountChanged() { int documentLineCount = Document != null ? Document.LineCount : 1; int newLength = documentLineCount.ToString(CultureInfo.CurrentCulture).Length; // The margin looks too small when there is only one digit, so always reserve space for // at least two digits if (newLength < 2) newLength = 2; if (newLength != maxLineNumberLength) { maxLineNumberLength = newLength; InvalidateMeasure(); } } void TextViewVisualLinesChanged(object sender, EventArgs e) { InvalidateVisual(); } AnchorSegment selectionStart; bool selecting; /// <inheritdoc/> protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); if (!e.Handled && TextView != null && textArea != null) { e.Handled = true; textArea.Focus(); SimpleSegment currentSeg = GetTextLineSegment(e); if (currentSeg == SimpleSegment.Invalid) return; textArea.Caret.Offset = currentSeg.Offset + currentSeg.Length; if (CaptureMouse()) { selecting = true; selectionStart = new AnchorSegment(Document, currentSeg.Offset, currentSeg.Length); if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) { SimpleSelection simpleSelection = textArea.Selection as SimpleSelection; if (simpleSelection != null) selectionStart = new AnchorSegment(Document, simpleSelection.SurroundingSegment); } textArea.Selection = Selection.Create(textArea, selectionStart); if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) { ExtendSelection(currentSeg); } } } } SimpleSegment GetTextLineSegment(MouseEventArgs e) { Point pos = e.GetPosition(TextView); pos.X = 0; pos.Y += TextView.VerticalOffset; VisualLine vl = TextView.GetVisualLineFromVisualTop(pos.Y); if (vl == null) return SimpleSegment.Invalid; TextLine tl = vl.GetTextLineByVisualYPosition(pos.Y); int visualStartColumn = vl.GetTextLineVisualStartColumn(tl); int visualEndColumn = visualStartColumn + tl.Length; int relStart = vl.FirstDocumentLine.Offset; int startOffset = vl.GetRelativeOffset(visualStartColumn) + relStart; int endOffset = vl.GetRelativeOffset(visualEndColumn) + relStart; if (endOffset == vl.LastDocumentLine.Offset + vl.LastDocumentLine.Length) endOffset += vl.LastDocumentLine.DelimiterLength; return new SimpleSegment(startOffset, endOffset - startOffset); } void ExtendSelection(SimpleSegment currentSeg) { if (currentSeg.Offset < selectionStart.Offset) { textArea.Caret.Offset = currentSeg.Offset; textArea.Selection = Selection.Create(textArea, currentSeg.Offset, selectionStart.Offset + selectionStart.Length); } else { textArea.Caret.Offset = currentSeg.Offset + currentSeg.Length; textArea.Selection = Selection.Create(textArea, selectionStart.Offset, currentSeg.Offset + currentSeg.Length); } } /// <inheritdoc/> protected override void OnMouseMove(MouseEventArgs e) { if (selecting && textArea != null && TextView != null) { e.Handled = true; SimpleSegment currentSeg = GetTextLineSegment(e); if (currentSeg == SimpleSegment.Invalid) return; ExtendSelection(currentSeg); } base.OnMouseMove(e); } /// <inheritdoc/> protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) { if (selecting) { selecting = false; selectionStart = null; ReleaseMouseCapture(); e.Handled = true; } base.OnMouseLeftButtonUp(e); } /// <inheritdoc/> protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) { // accept clicks even when clicking on the background return new PointHitTestResult(this, hitTestParameters.HitPoint); } } }