Skip to content

Commit be06fb4

Browse files
committed
Merge branch 'develop'
2 parents e68c9d9 + 720fd89 commit be06fb4

File tree

6 files changed

+183
-27
lines changed

6 files changed

+183
-27
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System.Linq;
2+
using System.Windows;
3+
using Microsoft.Xaml.Behaviors;
4+
5+
namespace PdfiumViewer.Demo.Converters
6+
{
7+
/// <summary>
8+
/// Wrapper to allow a behavior to be included in a style definition
9+
/// </summary>
10+
/// <typeparam name="TTarget"></typeparam>
11+
/// <typeparam name="TBehavior"></typeparam>
12+
public class BehaviorForStyle<TTarget, TBehavior> : Behavior<TTarget>
13+
where TTarget : DependencyObject
14+
where TBehavior : BehaviorForStyle<TTarget, TBehavior>, new()
15+
{
16+
public static readonly DependencyProperty IsEnabledForStyleProperty =
17+
DependencyProperty.RegisterAttached("IsEnabledForStyle",
18+
typeof(bool),
19+
typeof(BehaviorForStyle<TTarget, TBehavior>),
20+
new FrameworkPropertyMetadata(false, OnIsEnabledForStyleChanged));
21+
22+
public bool IsEnabledForStyle
23+
{
24+
get => (bool)GetValue(IsEnabledForStyleProperty);
25+
set => SetValue(IsEnabledForStyleProperty, value);
26+
}
27+
28+
private static void OnIsEnabledForStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
29+
{
30+
if (!(e.NewValue is bool))
31+
return;
32+
33+
var newValue = (bool)e.NewValue;
34+
35+
var behaviors = Interaction.GetBehaviors(d);
36+
var existingBehavior = behaviors.FirstOrDefault(b => b.GetType() == typeof(TBehavior)) as TBehavior;
37+
38+
if (!newValue && existingBehavior != null)
39+
behaviors.Remove(existingBehavior);
40+
else if (newValue && existingBehavior == null)
41+
behaviors.Add(new TBehavior());
42+
}
43+
}
44+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System.Windows;
2+
using System.Windows.Controls;
3+
4+
namespace PdfiumViewer.Demo.Converters
5+
{
6+
public class BindSelectedItemBehavior : BehaviorForStyle<TreeView, BindSelectedItemBehavior>
7+
{
8+
#region SelectedItem Property
9+
10+
public object SelectedItem
11+
{
12+
get => GetValue(SelectedItemProperty);
13+
set => SetValue(SelectedItemProperty, value);
14+
}
15+
16+
public static readonly DependencyProperty SelectedItemProperty =
17+
DependencyProperty.Register(nameof(SelectedItem), typeof(object),
18+
typeof(BindSelectedItemBehavior), new UIPropertyMetadata(null, OnSelectedItemChanged));
19+
20+
private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
21+
{
22+
if (e.NewValue is TreeViewItem item)
23+
{
24+
item.SetValue(TreeViewItem.IsSelectedProperty, true);
25+
}
26+
}
27+
28+
#endregion
29+
30+
protected override void OnAttached()
31+
{
32+
base.OnAttached();
33+
AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
34+
}
35+
36+
protected override void OnDetaching()
37+
{
38+
base.OnDetaching();
39+
40+
if (AssociatedObject != null)
41+
{
42+
AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
43+
}
44+
}
45+
46+
private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
47+
{
48+
SelectedItem = e.NewValue;
49+
}
50+
}
51+
}

src/PdfiumViewer.Demo/MainWindow.xaml

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
xmlns:pdfiumViewer="clr-namespace:PdfiumViewer;assembly=PdfiumViewer"
77
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
88
xmlns:converters="clr-namespace:PdfiumViewer.Demo.Converters"
9+
xmlns:core="clr-namespace:PdfiumViewer.Core;assembly=PdfiumViewer"
910
mc:Ignorable="d"
1011
Title="PDFium Viewer WPF Demo" Height="450" Width="1118" Background="LightGray">
1112
<Grid >
@@ -24,6 +25,45 @@
2425
<Button ToolTip="Render all pages" Click="RenderToMemory">
2526
<Image Source="Resources/render_all_pages.png" />
2627
</Button>
28+
<Button Name="BtnShowBookmarks" ToolTip="Show Bookmarks" Click="OnDisplayBookmarks">
29+
<Image Source="Resources/show_bookmarks.png" />
30+
</Button>
31+
<Popup IsOpen="{Binding ShowBookmarks}"
32+
Placement="Bottom"
33+
PlacementRectangle="0,20,0,20"
34+
ScrollViewer.VerticalScrollBarVisibility="Auto"
35+
PlacementTarget = "{Binding ElementName=BtnShowBookmarks}"
36+
PopupAnimation="Slide">
37+
38+
<Border Background="WhiteSmoke" Height="Auto" MaxHeight="600"
39+
HorizontalAlignment="Center"
40+
BorderBrush="AntiqueWhite"
41+
BorderThickness="2">
42+
<TreeView x:Name="TocTree"
43+
MaxHeight="500"
44+
Foreground="{DynamicResource Brushes.ThemeForeground}"
45+
FlowDirection="{Binding IsRtl, Mode=OneWay}"
46+
ItemsSource="{Binding Bookmarks, Mode=OneWay}"
47+
HorizontalContentAlignment="Stretch"
48+
HorizontalAlignment="Stretch">
49+
<TreeView.ItemTemplate>
50+
<HierarchicalDataTemplate ItemsSource="{Binding Children, Mode=OneWay}" DataType="{x:Type core:PdfBookmarkCollection}">
51+
<Grid>
52+
<Grid.ColumnDefinitions>
53+
<ColumnDefinition Width="*"/>
54+
<ColumnDefinition Width="*"/>
55+
</Grid.ColumnDefinitions>
56+
<TextBlock Grid.Column="0" Text="{Binding Title, Mode=OneWay}" />
57+
<TextBlock Grid.Column="1" Text="{Binding PageIndex, Mode=OneWay}" HorizontalAlignment="Right" Margin="10,0"/>
58+
</Grid>
59+
</HierarchicalDataTemplate>
60+
</TreeView.ItemTemplate>
61+
<b:Interaction.Behaviors>
62+
<converters:BindSelectedItemBehavior SelectedItem="{Binding SelectedBookIndex, Mode=OneWayToSource}" />
63+
</b:Interaction.Behaviors>
64+
</TreeView>
65+
</Border>
66+
</Popup>
2767
<Button x:Name="BtnSearch" ToolTip="Search term" Click="OpenCloseSearch">
2868
<Image Source="Resources/find.png" />
2969
</Button>
@@ -156,9 +196,6 @@
156196
<Button ToolTip="Transparent Page" Click="OnTransparent">
157197
<Image Source="Resources/transparent.png" />
158198
</Button>
159-
<Button ToolTip="Show Bookmarks" Click="OnDisplayBookmarks">
160-
<Image Source="Resources/show_bookmarks.png" />
161-
</Button>
162199
<Button ToolTip="Get Page Text" Click="OnGetText">
163200
<Image Source="Resources/show_text.png" />
164201
</Button>

src/PdfiumViewer.Demo/MainWindow.xaml.cs

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ public partial class MainWindow : Window, INotifyPropertyChanged
2828

2929
public string InfoText { get; set; }
3030
public string SearchTerm { get; set; }
31-
31+
public PdfBookmarkCollection Bookmarks { get; set; }
32+
public bool ShowBookmarks { get; set; }
33+
public PdfBookmark SelectedBookIndex { get; set; }
34+
3235
public double ZoomPercent
3336
{
3437
get => Renderer.Zoom * 100;
@@ -42,6 +45,11 @@ public int Page
4245
get => Renderer.PageNo + 1;
4346
set => Renderer.GotoPage(Math.Min(Math.Max(value - 1, 0), Renderer.PageCount - 1));
4447
}
48+
public FlowDirection IsRtl
49+
{
50+
get => Renderer.IsRightToLeft ? FlowDirection.RightToLeft : FlowDirection.LeftToRight;
51+
set => Renderer.IsRightToLeft = value == FlowDirection.RightToLeft ? true : false;
52+
}
4553

4654

4755
public MainWindow()
@@ -160,31 +168,36 @@ private void OnRotateRightClick(object sender, RoutedEventArgs e)
160168
private void OnInfo(object sender, RoutedEventArgs e)
161169
{
162170
var info = Renderer.GetInformation();
163-
var sb = new StringBuilder();
164-
sb.AppendLine($"Author: {info.Author}");
165-
sb.AppendLine($"Creator: {info.Creator}");
166-
sb.AppendLine($"Keywords: {info.Keywords}");
167-
sb.AppendLine($"Producer: {info.Producer}");
168-
sb.AppendLine($"Subject: {info.Subject}");
169-
sb.AppendLine($"Title: {info.Title}");
170-
sb.AppendLine($"Create Date: {info.CreationDate}");
171-
sb.AppendLine($"Modified Date: {info.ModificationDate}");
172-
173-
MessageBox.Show(sb.ToString(), "Information", MessageBoxButton.OK, MessageBoxImage.Information);
171+
if (info != null)
172+
{
173+
var sb = new StringBuilder();
174+
sb.AppendLine($"Author: {info.Author}");
175+
sb.AppendLine($"Creator: {info.Creator}");
176+
sb.AppendLine($"Keywords: {info.Keywords}");
177+
sb.AppendLine($"Producer: {info.Producer}");
178+
sb.AppendLine($"Subject: {info.Subject}");
179+
sb.AppendLine($"Title: {info.Title}");
180+
sb.AppendLine($"Create Date: {info.CreationDate}");
181+
sb.AppendLine($"Modified Date: {info.ModificationDate}");
182+
183+
MessageBox.Show(sb.ToString(), "Information", MessageBoxButton.OK, MessageBoxImage.Information);
184+
}
174185
}
175186

176187
private void OnGetText(object sender, RoutedEventArgs e)
177188
{
178189
var txtViewer = new TextViewer();
179190
var page = Renderer.PageNo;
180191
txtViewer.Body = Renderer.GetPdfText(page);
181-
txtViewer.Caption = $"Page {page + 1} contains {txtViewer.Body.Length} character(s):";
192+
txtViewer.Caption = $"Page {page + 1} contains {txtViewer.Body?.Length} character(s):";
182193
txtViewer.ShowDialog();
183194
}
184195

185196
private void OnDisplayBookmarks(object sender, RoutedEventArgs e)
186197
{
187-
throw new NotImplementedException();
198+
Bookmarks = Renderer.Bookmarks;
199+
if(Bookmarks?.Count > 0)
200+
ShowBookmarks = !ShowBookmarks;
188201
}
189202

190203
private void OnContinuousModeClick(object sender, RoutedEventArgs e)
@@ -335,11 +348,13 @@ private void OnPrevFoundClick(object sender, RoutedEventArgs e)
335348
private void ToRtlClick(object sender, RoutedEventArgs e)
336349
{
337350
Renderer.IsRightToLeft = true;
351+
OnPropertyChanged(nameof(IsRtl));
338352
}
339353

340354
private void ToLtrClick(object sender, RoutedEventArgs e)
341355
{
342356
Renderer.IsRightToLeft = false;
357+
OnPropertyChanged(nameof(IsRtl));
343358
}
344359

345360
private async void OnClosePdf(object sender, RoutedEventArgs e)
@@ -356,5 +371,13 @@ private async void OnClosePdf(object sender, RoutedEventArgs e)
356371
Console.WriteLine(exception);
357372
}
358373
}
374+
375+
/// <summary>
376+
/// Call when SelectedBookIndex changed.
377+
/// </summary>
378+
private void OnSelectedBookIndexChanged()
379+
{
380+
Renderer.GotoPage(SelectedBookIndex.PageIndex);
381+
}
359382
}
360383
}

src/PdfiumViewer/ScrollPanel.Paning.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace PdfiumViewer
77
{
88
public partial class ScrollPanel
99
{
10-
private const double DefaultFriction = 0.94;
10+
private const double DefaultFriction = 0.95;
1111
private Point ScrollStartPoint { get; set; }
1212
private Point ScrollStartOffset { get; set; }
1313
private Point PreviousPoint { get; set; }
@@ -22,7 +22,7 @@ public partial class ScrollPanel
2222
/// <summary>
2323
/// Friction Attached Dependency Property
2424
/// </summary>
25-
public static readonly DependencyProperty FrictionProperty =
25+
public static readonly DependencyProperty FrictionProperty =
2626
DependencyProperty.RegisterAttached(nameof(Friction), typeof(double), typeof(ScrollPanel), new FrameworkPropertyMetadata(DefaultFriction));
2727

2828
public double Friction
@@ -43,6 +43,7 @@ protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
4343
Cursor = Cursors.ScrollAll;
4444
// Save starting point, used later when
4545
// determining how much to scroll.
46+
Velocity = new Vector();
4647
ScrollStartPoint = e.GetPosition(this);
4748
ScrollStartOffset = new Point(HorizontalOffset, VerticalOffset);
4849
IsMouseDown = true;
@@ -103,7 +104,7 @@ private async void InertiaHandleMouseUp()
103104
{
104105
for (var i = 0; i < InertiaMaxAnimationTime / InertiaHandlerInterval; i++)
105106
{
106-
if (IsMouseDown || Velocity.Length <= 1 || Environment.TickCount64 - MouseWheelUpdateTime < InertiaHandlerInterval)
107+
if (IsMouseDown || Velocity.Length <= 1 || Environment.TickCount64 - MouseWheelUpdateTime < InertiaHandlerInterval * 2)
107108
break;
108109

109110
ScrollToHorizontalOffset(_scrollTarget.X);

src/PdfiumViewer/ScrollPanel.PdfDocument.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,17 @@ public void Save(Stream stream)
5959

6060
public PdfMatches Search(string text, bool matchCase, bool wholeWord)
6161
{
62-
return Document.Search(text, matchCase, wholeWord);
62+
return Document?.Search(text, matchCase, wholeWord);
6363
}
6464

6565
public PdfMatches Search(string text, bool matchCase, bool wholeWord, int page)
6666
{
67-
return Document.Search(text, matchCase, wholeWord, page);
67+
return Document?.Search(text, matchCase, wholeWord, page);
6868
}
6969

7070
public PdfMatches Search(string text, bool matchCase, bool wholeWord, int startPage, int endPage)
7171
{
72-
return Document.Search(text, matchCase, wholeWord, startPage, endPage);
72+
return Document?.Search(text, matchCase, wholeWord, startPage, endPage);
7373
}
7474

7575
public PrintDocument CreatePrintDocument()
@@ -105,22 +105,22 @@ public void RotatePage(int page, PdfRotation rotate)
105105

106106
public PdfInformation GetInformation()
107107
{
108-
return Document.GetInformation();
108+
return Document?.GetInformation();
109109
}
110110

111111
public string GetPdfText(int page)
112112
{
113-
return Document.GetPdfText(page);
113+
return Document?.GetPdfText(page);
114114
}
115115

116116
public string GetPdfText(PdfTextSpan textSpan)
117117
{
118-
return Document.GetPdfText(textSpan);
118+
return Document?.GetPdfText(textSpan);
119119
}
120120

121121
public IList<PdfRectangle> GetTextBounds(PdfTextSpan textSpan)
122122
{
123-
return Document.GetTextBounds(textSpan);
123+
return Document?.GetTextBounds(textSpan);
124124
}
125125

126126
public PointF PointToPdf(int page, Point point)

0 commit comments

Comments
 (0)