Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MapUiTools/WPF/MapUiTools.WPF.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<Copyright>Copyright © 2023 Clemens Fischer</Copyright>
<SignAssembly>true</SignAssembly>
<Platforms>x64</Platforms>
<AppendPlatformToOutputPath>false</AppendPlatformToOutputPath>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<UserControl x:Class="PhotoLocator.Helpers.ColorToneControl"
<UserControl x:Class="PhotoLocator.Controls.ColorToneControl"
x:ClassModifier="internal"
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:local="clr-namespace:PhotoLocator.Helpers"
xmlns:local="clr-namespace:PhotoLocator.Controls"
mc:Ignorable="d"
d:DesignHeight="256" d:DesignWidth="256" SizeChanged="HandleSizeChanged"
PreviewMouseMove="HandleMouseMove" PreviewMouseDown="HandleMouseDown">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using PhotoLocator.BitmapOperations;
using PhotoLocator.Helpers;
using System;
using System.ComponentModel;
using System.Threading.Tasks;
Expand All @@ -8,7 +9,7 @@
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace PhotoLocator.Helpers
namespace PhotoLocator.Controls
{
/// <summary>
/// Interaction logic for ColorToneControl.xaml
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<UserControl x:Class="PhotoLocator.Helpers.CropControl"
<UserControl x:Class="PhotoLocator.Controls.CropControl"
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:local="clr-namespace:PhotoLocator.Helpers"
xmlns:local="clr-namespace:PhotoLocator.Controls"
mc:Ignorable="d"
PreviewMouseDown="HandleMouseDown" PreviewMouseUp="HandleMouseUp" PreviewMouseMove="HandleMouseMove"
d:DataContext="{d:DesignInstance Type=local:CropControl, IsDesignTimeCreatable=True}"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using System;
using PhotoLocator.Helpers;
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace PhotoLocator.Helpers
namespace PhotoLocator.Controls
{
public interface ICropControl
{
Expand Down
36 changes: 36 additions & 0 deletions PhotoLocator/Controls/DropDownSlider.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<UserControl x:Class="PhotoLocator.Controls.DropDownSlider"
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"
mc:Ignorable="d" d:DesignHeight="30" d:DesignWidth="200">
<Grid Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="22" />
</Grid.ColumnDefinitions>

<TextBox Text="{Binding Text, RelativeSource={RelativeSource AncestorType=UserControl}, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
IsEnabled="{Binding IsEnabled, RelativeSource={RelativeSource AncestorType=UserControl}}"
VerticalContentAlignment="Center" />

<ToggleButton x:Name="DropToggle" Grid.Column="1" Width="20" Margin="2,0,0,0" FontFamily="Segoe UI Symbol" FontSize="12" Content="&#x23F7;"
IsEnabled="{Binding IsEnabled, RelativeSource={RelativeSource AncestorType=UserControl}}"/>

<Popup IsOpen="{Binding IsChecked, ElementName=DropToggle}" PlacementTarget="{Binding ElementName=DropToggle}"
StaysOpen="False" AllowsTransparency="True" PopupAnimation="Fade">
<Border Background="#FF222222" BorderBrush="Gray" BorderThickness="1" Padding="8" CornerRadius="4">
<StackPanel Width="260">
<Slider Minimum="{Binding Minimum, RelativeSource={RelativeSource AncestorType=UserControl}}"
Maximum="{Binding Maximum, RelativeSource={RelativeSource AncestorType=UserControl}}"
Value="{Binding NumericValue, RelativeSource={RelativeSource AncestorType=UserControl}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
TickPlacement="BottomRight"
TickFrequency="{Binding TickFrequency, RelativeSource={RelativeSource AncestorType=UserControl}}" IsSnapToTickEnabled="False" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,6,0,0">
<TextBlock Foreground="#FFEEEEEE" Margin="0,0,6,0" Text="{Binding FormattedNumericValue, RelativeSource={RelativeSource AncestorType=UserControl}}" />
</StackPanel>
</StackPanel>
</Border>
</Popup>
</Grid>
</UserControl>
87 changes: 87 additions & 0 deletions PhotoLocator/Controls/DropDownSlider.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;

namespace PhotoLocator.Controls;

public partial class DropDownSlider : UserControl
{
bool _onTextChangedRunning, _onNumericValueChangedRunning;

public DropDownSlider()
{
InitializeComponent();
}

public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
nameof(Text), typeof(string), typeof(DropDownSlider), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnTextChanged));

public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}

static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not DropDownSlider control || control._onNumericValueChangedRunning)
return;
if (double.TryParse(control.Text, NumberStyles.Float, CultureInfo.InvariantCulture, out var v))
{
control._onTextChangedRunning = true;
control.NumericValue = Math.Clamp(v, control.Minimum, control.Maximum);
control._onTextChangedRunning = false;
}
}

public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register(
nameof(Minimum), typeof(double), typeof(DropDownSlider), new PropertyMetadata(0.0));
public double Minimum { get => (double)GetValue(MinimumProperty); set => SetValue(MinimumProperty, value); }

public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register(
nameof(Maximum), typeof(double), typeof(DropDownSlider), new PropertyMetadata(100.0));
public double Maximum { get => (double)GetValue(MaximumProperty); set => SetValue(MaximumProperty, value); }

public static readonly DependencyProperty TickFrequencyProperty = DependencyProperty.Register(
nameof(TickFrequency), typeof(double), typeof(DropDownSlider), new PropertyMetadata(1.0));
public double TickFrequency { get => (double)GetValue(TickFrequencyProperty); set => SetValue(TickFrequencyProperty, value); }

public static readonly DependencyProperty NumericValueProperty = DependencyProperty.Register(
nameof(NumericValue), typeof(double), typeof(DropDownSlider), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnNumericValueChanged));
public double NumericValue { get => (double)GetValue(NumericValueProperty); set => SetValue(NumericValueProperty, value); }

public static readonly DependencyProperty DecimalsProperty = DependencyProperty.Register(
nameof(Decimals), typeof(int), typeof(DropDownSlider), new PropertyMetadata(1, OnFormatChanged));
public int Decimals { get => (int)GetValue(DecimalsProperty); set => SetValue(DecimalsProperty, value); }

public static readonly DependencyProperty SliderValueUnitsProperty = DependencyProperty.Register(
nameof(SliderValueUnits), typeof(string), typeof(DropDownSlider), new PropertyMetadata(string.Empty, OnFormatChanged));
public string SliderValueUnits { get => (string)GetValue(SliderValueUnitsProperty); set => SetValue(SliderValueUnitsProperty, value); }

static void OnFormatChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is DropDownSlider control)
control.UpdateFormattedValue();
}

public static readonly DependencyProperty FormattedNumericValueProperty = DependencyProperty.Register(
nameof(FormattedNumericValue), typeof(string), typeof(DropDownSlider), new PropertyMetadata(string.Empty));
public string FormattedNumericValue { get => (string)GetValue(FormattedNumericValueProperty); private set => SetValue(FormattedNumericValueProperty, value); }

static void OnNumericValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not DropDownSlider control)
return;
control._onNumericValueChangedRunning = true;
if (!control._onTextChangedRunning)
control.Text = control.NumericValue.ToString("F" + control.Decimals.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
control.UpdateFormattedValue();
control._onNumericValueChangedRunning = false;
}

void UpdateFormattedValue()
{
FormattedNumericValue = NumericValue.ToString("F" + Decimals.ToString(CultureInfo.InvariantCulture), CultureInfo.CurrentCulture) + SliderValueUnits;
}
}
3 changes: 3 additions & 0 deletions PhotoLocator/Helpers/IntMath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ public static int Round(double a)
return (int)Math.Round(a);
}

/// <summary>
/// Clamp without min/max check, for better performance when the caller can guarantee the value is within range.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Clamp(int value, int min, int max)
{
Expand Down
7 changes: 6 additions & 1 deletion PhotoLocator/Helpers/RealMath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ namespace PhotoLocator.Helpers
{
public static class RealMath
{
/// <summary>
/// Clamp without min/max sanity check, for better performance when the caller can guarantee that max>min
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Clamp(float value, float min, float max)
{
Expand All @@ -15,6 +18,9 @@ public static float Clamp(float value, float min, float max)
return value;
}

/// <summary>
/// Clamp without min/max sanity check, for better performance when the caller can guarantee that max>min
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Clamp(double value, double min, double max)
{
Expand Down Expand Up @@ -53,7 +59,6 @@ public static float SmoothStep(float x)
return (3.0f - 2.0f * x) * x * x;
}


/// <summary>
/// Smooth step edge between min and max
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions PhotoLocator/Helpers/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,10 @@ public static string TrimPath(this string path)
{
return path.Trim(' ', '"');
}

public static string TrimInvariantValue(this string str)
{
return str.Trim().Replace(',', '.');
}
}
}
4 changes: 2 additions & 2 deletions PhotoLocator/LocalContrastView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:PhotoLocator" xmlns:helpers="clr-namespace:PhotoLocator.Helpers"
xmlns:local="clr-namespace:PhotoLocator" xmlns:controls="clr-namespace:PhotoLocator.Controls"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=local:LocalContrastViewModel, IsDesignTimeCreatable=True}"
Background="Black"
Expand Down Expand Up @@ -181,7 +181,7 @@
</DockPanel>
<Slider Value="{Binding ToneRotation}" Minimum="-0.2" Maximum="0.2" SmallChange="0.01" LargeChange="0.05"/>

<helpers:ColorToneControl x:Name="ColorToneControl" Margin="0,8,0,0"/>
<controls:ColorToneControl x:Name="ColorToneControl" Margin="0,8,0,0"/>

<Grid Margin="0,20,0,0">
<Button Content="Original" Width="90" HorizontalAlignment="Left"
Expand Down
1 change: 1 addition & 0 deletions PhotoLocator/MainViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using MapControl;
using Peter;
using PhotoLocator.Controls;
using PhotoLocator.Gps;
using PhotoLocator.Helpers;
using PhotoLocator.MapDisplay;
Expand Down
4 changes: 2 additions & 2 deletions PhotoLocator/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
xmlns:map="clr-namespace:MapControl;assembly=MapControl.WPF"
xmlns:local="clr-namespace:PhotoLocator"
xmlns:mapDisplay="clr-namespace:PhotoLocator.MapDisplay"
xmlns:helpers="clr-namespace:PhotoLocator.Helpers"
xmlns:controls="clr-namespace:PhotoLocator.Controls"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=local:MainViewModel, IsDesignTimeCreatable=True}"
Loaded="HandleWindowLoaded" Closed="HandleWindowClosed"
Expand Down Expand Up @@ -329,7 +329,7 @@
<TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="10" FontSize="18" FontWeight="Bold" Foreground="White"
TextWrapping="Wrap" Text="{Binding PreviewPictureTitle}"/>

<helpers:CropControl x:Name="CropGrid" HorizontalAlignment="Center" VerticalAlignment="Center"
<controls:CropControl x:Name="CropGrid" HorizontalAlignment="Center" VerticalAlignment="Center"
Visibility="{Binding Parent.DataContext.IsCropControlVisible, Converter={StaticResource BooleanToVisibility}}"/>

<Grid.ContextMenu>
Expand Down
1 change: 1 addition & 0 deletions PhotoLocator/Metadata/ExifHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ public static void SetGeotag(BitmapMetadata metadata, Location location)
?? metadata.GetQuery(FileTimeStampQuery1) ?? metadata.GetQuery(FileTimeStampQuery2)) as string;

if (!DateTime.TryParseExact(timestampStr, "yyyy:MM:dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out var timeStamp) &&
!DateTime.TryParseExact(timestampStr, "yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out timeStamp) &&
!DateTime.TryParse(metadata.DateTaken, out timeStamp))
return null;

Expand Down
4 changes: 2 additions & 2 deletions PhotoLocator/Metadata/MaskBasedNaming.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ private void AppendMetadata(StringBuilder result, string query1, string query2)
var value = (metadata?.GetQuery(query1) ?? metadata?.GetQuery(query2))?.ToString();
if (value is null)
return;
foreach (var ch in Path.GetInvalidFileNameChars())
value = value.Replace(ch, '_');
foreach (var ch in _invalidFileNameChars)
value = value.Replace(ch, '-');
result.Append(value);
}

Expand Down
1 change: 1 addition & 0 deletions PhotoLocator/PhotoLocator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<NoWarn>CA1014,CA1309,CA1515,CA1814,CA1819,IDE0017</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Platforms>x64</Platforms>
<AppendPlatformToOutputPath>false</AppendPlatformToOutputPath>
<IsPackable>false</IsPackable>
</PropertyGroup>

Expand Down
Loading
Loading