some progress on settings layout.
MODIFY
WalletWasabi.Fluent.Desktop/WalletWasabi.Fluent.Desktop.csproj
WalletWasabi.Fluent.Desktop/WalletWasabi.Fluent.Desktop.csproj
<AvaloniaResource Include="Assets\**" />
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Avalonia.Desktop" Version="0.10.999-cibuild0012021-beta" />
- <PackageReference Include="Avalonia.ReactiveUI" Version="0.10.999-cibuild0012021-beta" />
+ <PackageReference Include="Avalonia.Desktop" Version="0.10.999-cibuild0012042-beta" />
+ <PackageReference Include="Avalonia.ReactiveUI" Version="0.10.999-cibuild0012042-beta" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WalletWasabi.Fluent\WalletWasabi.Fluent.csproj" />

MODIFY
WalletWasabi.Fluent/App.xaml
WalletWasabi.Fluent/App.xaml
<local:ViewLocator/>
</Application.DataTemplates>
+ <Application.Resources>
+ <x:Double x:Key="ToggleSwitchThemeMinWidth">0</x:Double>
+ </Application.Resources>
+
<Application.Styles>
<StyleInclude Source="avares://WalletWasabi.Fluent/Styles/Themes/BaseDark.xaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Icons/Icons.xaml" />

MODIFY
WalletWasabi.Fluent/Controls/ConcatenatingWrapPanel.cs
WalletWasabi.Fluent/Controls/ConcatenatingWrapPanel.cs
using System;
+using System.Collections.Generic;
using System.Linq;
using Avalonia;
using Avalonia.Controls;
@@ -8,8 +9,306 @@ using Avalonia.Utilities;
namespace WalletWasabi.Fluent.Controls
{
- // Note: Most of this class is a copy paste from Avalonia. So the code style and standard should
- // be kept as is to allow for future maintenance.
+ /// <summary>
+ /// Works like a wrap panel.. but concatenates the Items in ConcatenatedChildren.
+ /// Also the very last child in ConcatenatedChildren will fill the remaining space.
+ /// </summary>
+ public class FillingWrapPanel : Panel, INavigableContainer
+ {
+ /// <summary>
+ /// Defines the <see cref="Orientation"/> property.
+ /// </summary>
+ public static readonly StyledProperty<Orientation> OrientationProperty =
+ AvaloniaProperty.Register<ConcatenatingWrapPanel, Orientation>(nameof(Orientation), defaultValue: Orientation.Horizontal);
+
+ /// <summary>
+ /// Defines the <see cref="ItemWidth"/> property.
+ /// </summary>
+ public static readonly StyledProperty<double> ItemWidthProperty =
+ AvaloniaProperty.Register<ConcatenatingWrapPanel, double>(nameof(ItemWidth), double.NaN);
+
+ /// <summary>
+ /// Defines the <see cref="ItemHeight"/> property.
+ /// </summary>
+ public static readonly StyledProperty<double> ItemHeightProperty =
+ AvaloniaProperty.Register<ConcatenatingWrapPanel, double>(nameof(ItemHeight), double.NaN);
+
+ /// <summary>
+ /// Initializes static members of the <see cref="ConcatenatingWrapPanel"/> class.
+ /// </summary>
+ static FillingWrapPanel()
+ {
+ AffectsMeasure<ConcatenatingWrapPanel>(OrientationProperty, ItemWidthProperty, ItemHeightProperty);
+ }
+
+ /// <summary>
+ /// Gets or sets the orientation in which child controls will be layed out.
+ /// </summary>
+ public Orientation Orientation
+ {
+ get { return GetValue(OrientationProperty); }
+ set { SetValue(OrientationProperty, value); }
+ }
+
+ /// <summary>
+ /// Gets or sets the width of all items in the WrapPanel.
+ /// </summary>
+ public double ItemWidth
+ {
+ get { return GetValue(ItemWidthProperty); }
+ set { SetValue(ItemWidthProperty, value); }
+ }
+
+ /// <summary>
+ /// Gets or sets the height of all items in the WrapPanel.
+ /// </summary>
+ public double ItemHeight
+ {
+ get { return GetValue(ItemHeightProperty); }
+ set { SetValue(ItemHeightProperty, value); }
+ }
+
+ /// <summary>
+ /// Gets the next control in the specified direction.
+ /// </summary>
+ /// <param name="direction">The movement direction.</param>
+ /// <param name="from">The control from which movement begins.</param>
+ /// <param name="wrap">Whether to wrap around when the first or last item is reached.</param>
+ /// <returns>The control.</returns>
+ IInputElement INavigableContainer.GetControl(NavigationDirection direction, IInputElement from, bool wrap)
+ {
+ var orientation = Orientation;
+ var children = Children;
+ bool horiz = orientation == Orientation.Horizontal;
+ int index = Children.IndexOf((IControl)from);
+
+ switch (direction)
+ {
+ case NavigationDirection.First:
+ index = 0;
+ break;
+ case NavigationDirection.Last:
+ index = children.Count - 1;
+ break;
+ case NavigationDirection.Next:
+ ++index;
+ break;
+ case NavigationDirection.Previous:
+ --index;
+ break;
+ case NavigationDirection.Left:
+ index = horiz ? index - 1 : -1;
+ break;
+ case NavigationDirection.Right:
+ index = horiz ? index + 1 : -1;
+ break;
+ case NavigationDirection.Up:
+ index = horiz ? -1 : index - 1;
+ break;
+ case NavigationDirection.Down:
+ index = horiz ? -1 : index + 1;
+ break;
+ }
+
+ if (index >= 0 && index < children.Count)
+ {
+ return children[index];
+ }
+ else
+ {
+ return null!;
+ }
+ }
+
+ /// <inheritdoc/>
+ protected override Size MeasureOverride(Size constraint)
+ {
+ double itemWidth = ItemWidth;
+ double itemHeight = ItemHeight;
+ var orientation = Orientation;
+ var children = Children;
+ var curLineSize = new UVSize(orientation);
+ var panelSize = new UVSize(orientation);
+ var uvConstraint = new UVSize(orientation, constraint.Width, constraint.Height);
+ bool itemWidthSet = !double.IsNaN(itemWidth);
+ bool itemHeightSet = !double.IsNaN(itemHeight);
+
+ var childConstraint = new Size(
+ itemWidthSet ? itemWidth : constraint.Width,
+ itemHeightSet ? itemHeight : constraint.Height);
+
+ for (int i = 0, count = children.Count; i < count; i++)
+ {
+ var child = children[i];
+ if (child != null)
+ {
+ // Flow passes its own constraint to children
+ child.Measure(childConstraint);
+
+ // This is the size of the child in UV space
+ var sz = new UVSize(orientation,
+ itemWidthSet ? itemWidth : child.DesiredSize.Width,
+ itemHeightSet ? itemHeight : child.DesiredSize.Height);
+
+ if (MathUtilities.GreaterThan(curLineSize.U + sz.U, uvConstraint.U)) // Need to switch to another line
+ {
+ panelSize.U = Math.Max(curLineSize.U, panelSize.U);
+ panelSize.V += curLineSize.V;
+ curLineSize = sz;
+
+ if (MathUtilities.GreaterThan(sz.U, uvConstraint.U)) // The element is wider then the constraint - give it a separate line
+ {
+ panelSize.U = Math.Max(sz.U, panelSize.U);
+ panelSize.V += sz.V;
+ curLineSize = new UVSize(orientation);
+ }
+ }
+ else // Continue to accumulate a line
+ {
+ curLineSize.U += sz.U;
+ curLineSize.V = Math.Max(sz.V, curLineSize.V);
+ }
+ }
+ }
+
+ // The last line size, if any should be added
+ panelSize.U = Math.Max(curLineSize.U, panelSize.U);
+ panelSize.V += curLineSize.V;
+
+ // Go from UV space to W/H space
+ return new Size(panelSize.Width, panelSize.Height);
+ }
+
+ /// <inheritdoc/>
+ protected override Size ArrangeOverride(Size finalSize)
+ {
+ double itemWidth = ItemWidth;
+ double itemHeight = ItemHeight;
+ var orientation = Orientation;
+ var children = Children;
+ int firstInLine = 0;
+ double accumulatedV = 0;
+ double itemU = orientation == Orientation.Horizontal ? itemWidth : itemHeight;
+ var curLineSize = new UVSize(orientation);
+ var uvFinalSize = new UVSize(orientation, finalSize.Width, finalSize.Height);
+ bool itemWidthSet = !double.IsNaN(itemWidth);
+ bool itemHeightSet = !double.IsNaN(itemHeight);
+ bool useItemU = orientation == Orientation.Horizontal ? itemWidthSet : itemHeightSet;
+
+ for (int i = 0; i < children.Count; i++)
+ {
+ var child = children[i];
+ if (child != null)
+ {
+ var sz = new UVSize(orientation,
+ itemWidthSet ? itemWidth : child.DesiredSize.Width,
+ itemHeightSet ? itemHeight : child.DesiredSize.Height);
+
+ if (MathUtilities.GreaterThan(curLineSize.U + sz.U, uvFinalSize.U)) // Need to switch to another line
+ {
+ ArrangeLine(accumulatedV, curLineSize.V, firstInLine, i, useItemU, itemU, uvFinalSize);
+
+ accumulatedV += curLineSize.V;
+ curLineSize = sz;
+
+ if (MathUtilities.GreaterThan(sz.U, uvFinalSize.U)) // The element is wider then the constraint - give it a separate line
+ {
+ // Switch to next line which only contain one element
+ ArrangeLine(accumulatedV, sz.V, i, ++i, useItemU, itemU, uvFinalSize);
+
+ accumulatedV += sz.V;
+ curLineSize = new UVSize(orientation);
+ }
+ firstInLine = i;
+ }
+ else // Continue to accumulate a line
+ {
+ curLineSize.U += sz.U;
+ curLineSize.V = Math.Max(sz.V, curLineSize.V);
+ }
+ }
+ }
+
+ // Arrange the last line, if any
+ if (firstInLine < children.Count)
+ {
+ ArrangeLine(accumulatedV, curLineSize.V, firstInLine, children.Count, useItemU, itemU, uvFinalSize);
+ }
+
+ return finalSize;
+ }
+
+ private void ArrangeLine(double v, double lineV, int start, int end, bool useItemU, double itemU, UVSize uvFinalSize)
+ {
+ var orientation = Orientation;
+ var children = Children;
+ double u = 0;
+ bool isHorizontal = orientation == Orientation.Horizontal;
+
+ for (int i = start; i < end; i++)
+ {
+ var child = children[i];
+ if (child != null)
+ {
+ if (i == children.Count - 1)
+ {
+ var childSize = new UVSize(orientation, uvFinalSize.Width - u, uvFinalSize.Height - u);
+ double layoutSlotU = useItemU ? itemU : childSize.U;
+ child.Arrange(new Rect(
+ isHorizontal ? u : v,
+ isHorizontal ? v : u,
+ isHorizontal ? layoutSlotU : lineV,
+ isHorizontal ? lineV : layoutSlotU));
+ u += layoutSlotU;
+ }
+ else
+ {
+ var childSize = new UVSize(orientation, child.DesiredSize.Width, child.DesiredSize.Height);
+ double layoutSlotU = useItemU ? itemU : childSize.U;
+ child.Arrange(new Rect(
+ isHorizontal ? u : v,
+ isHorizontal ? v : u,
+ isHorizontal ? layoutSlotU : lineV,
+ isHorizontal ? lineV : layoutSlotU));
+ u += layoutSlotU;
+ }
+ }
+ }
+ }
+
+ private struct UVSize
+ {
+ internal UVSize(Orientation orientation, double width, double height)
+ {
+ U = V = 0d;
+ _orientation = orientation;
+ Width = width;
+ Height = height;
+ }
+
+ internal UVSize(Orientation orientation)
+ {
+ U = V = 0d;
+ _orientation = orientation;
+ }
+
+ internal double U;
+ internal double V;
+ private Orientation _orientation;
+
+ internal double Width
+ {
+ get { return _orientation == Orientation.Horizontal ? U : V; }
+ set { if (_orientation == Orientation.Horizontal) U = value; else V = value; }
+ }
+ internal double Height
+ {
+ get { return _orientation == Orientation.Horizontal ? V : U; }
+ set { if (_orientation == Orientation.Horizontal) V = value; else U = value; }
+ }
+ }
+ }
+
/// <summary>
/// Works like a wrap panel.. but concatenates the Items in ConcatenatedChildren.

MODIFY
WalletWasabi.Fluent/Controls/ContentArea.axaml
WalletWasabi.Fluent/Controls/ContentArea.axaml
<Style Selector="c|ContentArea">
<Setter Property="Template">
<ControlTemplate>
- <DockPanel Margin="40,0,40,0">
- <StackPanel DockPanel.Dock="Top" Spacing="10" Margin="0 0 0 40">
+ <DockPanel Margin="20,0,20,0">
+ <StackPanel DockPanel.Dock="Top" Spacing="10" Margin="0 0 0 20">
<DockPanel>
- <Button Margin="-40,0,0,0" Classes="plain" Command="{Binding BackCommand}" IsVisible="{TemplateBinding EnableBack}">
+ <Button Margin="-20,0,0,0" Classes="plain" Command="{Binding BackCommand}" IsVisible="{TemplateBinding EnableBack}">
<PathIcon Data="{StaticResource arrow_left_regular}" Width="16" />
</Button>
<ContentPresenter Name="PART_TitlePresenter" Content="{TemplateBinding Title}" />

DELETE
WalletWasabi.Fluent/Views/SettingsPageView.axaml
-<UserControl xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:c="using:WalletWasabi.Fluent.Controls"
- xmlns:vm="using:WalletWasabi.Fluent.ViewModels"
- mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
- x:DataType="vm:SettingsPageViewModel"
- x:Class="WalletWasabi.Fluent.Views.SettingsPageView">
- <UserControl.Styles>
- <Style Selector="TabItem">
- <Setter Property="FontSize" Value="12" />
- <Setter Property="MinHeight" Value="28" />
- <Setter Property="Padding" Value="0 0 24 24" />
- </Style>
- <Style Selector="TabControl">
- <Setter Property="Padding" Value="0" />
- </Style>
- </UserControl.Styles>
- <c:ContentArea Title="Settings" Caption="Manage appearance, privacy and other settings">
- <TabControl>
- <TabItem Header="General">
- <StackPanel Orientation="Vertical" Spacing="5">
- <Grid ColumnDefinitions="Auto, *" RowDefinitions="*,*,*,*">
- <Grid.Styles>
- <Style Selector="TextBlock">
- <Setter Property="Margin" Value="0 0 50 0" />
- <Setter Property="FontSize" Value="14" />
- </Style>
- <Style Selector="ToggleSwitch">
- <Setter Property="Margin" Value="0 0 10 20" />
- </Style>
- </Grid.Styles>
- <TextBlock>Dark Mode</TextBlock>
- <ToggleSwitch Grid.Column="1" IsChecked="{Binding DarkModeEnabled}" />
-
- <TextBlock Grid.Row="1">Auto Copy/Paste Bitcoin addresses</TextBlock>
- <ToggleSwitch Grid.Row="1" Grid.Column="1" IsChecked="{Binding Autocopy}" />
-
- <TextBlock Grid.Row="2">Manual fee entry.</TextBlock>
- <ToggleSwitch Grid.Row="2" Grid.Column="1" IsChecked="{Binding CustomFee}" />
-
- <TextBlock Grid.Row="3">Custom change address.</TextBlock>
- <ToggleSwitch Grid.Row="3" Grid.Column="1" IsChecked="{Binding CustomChangeAddress}" />
- </Grid>
-
- <StackPanel Margin="0 10" Orientation="Vertical" Spacing="5">
- <TextBlock>Fee Display Format</TextBlock>
- <DropDown Items="{Binding FeeDisplayFormats}" SelectedItem="{Binding SelectedFeeDisplayFormat}">
- <!--<DropDown.ItemTemplate>
- <DataTemplate>
- <TextBlock Text="{Binding Converter={StaticResource FeeDisplayFormatStringConverter}}" />
- </DataTemplate>
- </DropDown.ItemTemplate>-->
- </DropDown>
- </StackPanel>
-
- <StackPanel Orientation="Vertical" Spacing="5">
- <StackPanel Margin="0 10" Spacing="5">
- <TextBlock ToolTip.Tip="Coins under the dust threshold won't appear in the coin lists.">Dust Threshold (BTC)</TextBlock>
- <TextBox Text="{Binding DustThreshold}" />
- </StackPanel>
- </StackPanel>
- </StackPanel>
- </TabItem>
-
- <TabItem Header="Privacy">
- <StackPanel Orientation="Vertical" Spacing="5">
- <Grid Margin="0 10" ColumnDefinitions="30, *">
- <DrawingPresenter Height="24" Width="24" Grid.Column="0" Margin="0 0 10 10" VerticalAlignment="Center" HorizontalAlignment="Center" Drawing="{DynamicResource PrivacySome}" />
- <TextBox Text="{Binding SomePrivacyLevel}" Grid.Column="1" />
- </Grid>
- <Grid Margin="0 10" ColumnDefinitions="30, *">
- <DrawingPresenter Height="24" Width="24" Grid.Column="0" Margin="0 0 10 10" VerticalAlignment="Center" HorizontalAlignment="Center" Drawing="{DynamicResource PrivacyFine}" />
- <TextBox Text="{Binding FinePrivacyLevel}" Grid.Column="1" />
- </Grid>
- <Grid Margin="0 10" ColumnDefinitions="30, *">
- <DrawingPresenter Height="24" Width="24" Grid.Column="0" Margin="0 0 10 10" VerticalAlignment="Center" HorizontalAlignment="Center" Drawing="{DynamicResource PrivacyStrong}" />
- <TextBox Text="{Binding StrongPrivacyLevel}" Grid.Column="1" />
- </Grid>
- </StackPanel>
- </TabItem>
-
- <TabItem Header="Network">
- <StackPanel Orientation="Vertical" Spacing="5">
- <StackPanel Margin="0 10" Orientation="Horizontal" Spacing="5">
- <ToggleSwitch IsChecked="{Binding UseTor}" Margin="0 0 10 0" />
- <TextBlock VerticalAlignment="Center">Tor can be turned off for debugging.</TextBlock>
- </StackPanel>
- <StackPanel Margin="0 10" Spacing="5" IsVisible="{Binding UseTor}">
- <TextBlock>Tor SOCKS5 Endpoint</TextBlock>
- <TextBox Text="{Binding TorSocks5EndPoint}" />
- </StackPanel>
- <StackPanel Margin="0 10" Orientation="Horizontal" Spacing="5" IsVisible="{Binding UseTor}">
- <ToggleSwitch IsChecked="{Binding TerminateTorOnExit}" Margin="0 0 10 0" />
- <TextBlock VerticalAlignment="Center">Terminate Tor process on exit.</TextBlock>
- </StackPanel>
- </StackPanel>
- </TabItem>
-
- <TabItem Header="Node">
- <StackPanel Orientation="Vertical" Spacing="5">
- <StackPanel Margin="0 10" Spacing="5">
- <TextBlock>Network</TextBlock>
- <ComboBox Items="{Binding Networks}" SelectedItem="{Binding Network}">
- <!--<ComboBox.ItemTemplate>
- <DataTemplate>
- <TextBlock Text="{Binding Converter={StaticResource NetworkStringConverter}}" />
- </DataTemplate>
- </ComboBox.ItemTemplate>-->
- </ComboBox>
- </StackPanel>
- <Panel>
- <StackPanel Orientation="Vertical" Spacing="5">
- <TextBlock Classes="warningMessage">Work in progress...</TextBlock>
- <TextBlock>Use your own Bitcoin Core or Wasabi's built-in Bitcoin Knots.</TextBlock>
- <TextBlock>Expect high CPU, network usage and 300+ GB disk space requirement.</TextBlock>
- <StackPanel Margin="0 10" Orientation="Horizontal" Spacing="5">
- <ToggleSwitch IsChecked="{Binding StartLocalBitcoinCoreOnStartup}" Margin="0 0 10 0" />
- <TextBlock VerticalAlignment="Center">Run Bitcoin Knots at Wasabi's startup.</TextBlock>
- </StackPanel>
- <StackPanel Margin="0 10" Spacing="5" IsVisible="{Binding StartLocalBitcoinCoreOnStartup}">
- <TextBlock>Bitcoin Core or Bitcoin Knots Data Folder</TextBlock>
- <TextBox Text="{Binding LocalBitcoinCoreDataDir}" />
- </StackPanel>
- <StackPanel Margin="0 10" Orientation="Horizontal" Spacing="5" IsVisible="{Binding StartLocalBitcoinCoreOnStartup}">
- <ToggleSwitch IsChecked="{Binding StopLocalBitcoinCoreOnShutdown}" Margin="0 0 10 0" />
- <TextBlock VerticalAlignment="Center">Stop Bitcoin Knots when Wasabi is shut down.</TextBlock>
- </StackPanel>
- </StackPanel>
- </Panel>
- <Panel IsVisible="{Binding !StartLocalBitcoinCoreOnStartup}">
- <StackPanel Orientation="Vertical" Spacing="5">
- <TextBlock>Set Wasabi to download blocks from a full node you control.</TextBlock>
- <StackPanel Margin="0 10" Spacing="5">
- <TextBlock>Bitcoin P2P Endpoint</TextBlock>
- <TextBox Text="{Binding BitcoinP2pEndPoint}" />
- </StackPanel>
- </StackPanel>
- </Panel>
- </StackPanel>
- </TabItem>
- </TabControl>
- </c:ContentArea>
-</UserControl>

ADD
WalletWasabi.Fluent/Views/SettingsPageView.xaml
+<UserControl xmlns="https://github.com/avaloniaui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:c="using:WalletWasabi.Fluent.Controls"
+ xmlns:vm="using:WalletWasabi.Fluent.ViewModels"
+ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+ x:DataType="vm:SettingsPageViewModel"
+ x:Class="WalletWasabi.Fluent.Views.SettingsPageView">
+ <UserControl.Styles>
+ <Style Selector="TabItem">
+ <Setter Property="FontSize" Value="12" />
+ <Setter Property="MinHeight" Value="28" />
+ <Setter Property="Padding" Value="0 0 24 24" />
+ </Style>
+ <Style Selector="TabControl">
+ <Setter Property="Padding" Value="0" />
+ </Style>
+ </UserControl.Styles>
+ <c:ContentArea Title="Settings" Caption="Manage appearance, privacy and other settings">
+ <TabControl>
+ <TabItem Header="General">
+ <StackPanel Spacing="20" MaxWidth="650" HorizontalAlignment="Left" Orientation="Vertical">
+ <StackPanel.Styles>
+ <Style Selector="WrapPanel > TextBlock">
+ <Setter Property="MinWidth" Value="300" />
+ <Setter Property="VerticalAlignment" Value="Center" />
+ </Style>
+ </StackPanel.Styles>
+
+ <WrapPanel>
+ <Panel Background="Green" Width="300">
+ <TextBlock>Dark Mode</TextBlock>
+ </Panel>
+ <Panel Background="Blue" Height="20" Width="72.66">
+ </Panel>
+ <!--<ToggleSwitch IsChecked="{Binding DarkModeEnabled}" />-->
+ </WrapPanel>
+
+ <WrapPanel>
+ <TextBlock>Auto Copy/Paste Bitcoin addresses</TextBlock>
+ <ToggleSwitch IsChecked="{Binding Autocopy}" />
+ </WrapPanel>
+
+ <WrapPanel>
+ <TextBlock>Manual fee entry.</TextBlock>
+ <ToggleSwitch IsChecked="{Binding CustomFee}" />
+ </WrapPanel>
+
+ <WrapPanel>
+ <TextBlock DockPanel.Dock="Left" VerticalAlignment="Center">Custom change address.</TextBlock>
+ <ToggleSwitch IsChecked="{Binding CustomChangeAddress}" />
+ </WrapPanel>
+
+ <WrapPanel>
+ <TextBlock MinWidth="200" DockPanel.Dock="Left">Fee Display Format</TextBlock>
+ <Panel Width="200" HorizontalAlignment="Stretch" Background="Red">
+ <Button Content="Testing 123 ABC 123" />
+ </Panel>
+
+ </WrapPanel>
+
+ <StackPanel>
+ <TextBlock ToolTip.Tip="Coins under the dust threshold won't appear in the coin lists.">Dust Threshold (BTC)</TextBlock>
+ <TextBox Text="{Binding DustThreshold}" />
+ </StackPanel>
+ </StackPanel>
+ </TabItem>
+
+ <TabItem Header="Privacy">
+ <StackPanel Orientation="Vertical" Spacing="5">
+ <Grid Margin="0 10" ColumnDefinitions="30, *">
+ <DrawingPresenter Height="24" Width="24" Grid.Column="0" Margin="0 0 10 10" VerticalAlignment="Center" HorizontalAlignment="Center" Drawing="{DynamicResource PrivacySome}" />
+ <TextBox Text="{Binding SomePrivacyLevel}" Grid.Column="1" />
+ </Grid>
+ <Grid Margin="0 10" ColumnDefinitions="30, *">
+ <DrawingPresenter Height="24" Width="24" Grid.Column="0" Margin="0 0 10 10" VerticalAlignment="Center" HorizontalAlignment="Center" Drawing="{DynamicResource PrivacyFine}" />
+ <TextBox Text="{Binding FinePrivacyLevel}" Grid.Column="1" />
+ </Grid>
+ <Grid Margin="0 10" ColumnDefinitions="30, *">
+ <DrawingPresenter Height="24" Width="24" Grid.Column="0" Margin="0 0 10 10" VerticalAlignment="Center" HorizontalAlignment="Center" Drawing="{DynamicResource PrivacyStrong}" />
+ <TextBox Text="{Binding StrongPrivacyLevel}" Grid.Column="1" />
+ </Grid>
+ </StackPanel>
+ </TabItem>
+
+ <TabItem Header="Network">
+ <StackPanel Orientation="Vertical" Spacing="5">
+ <StackPanel Margin="0 10" Orientation="Horizontal" Spacing="5">
+ <ToggleSwitch IsChecked="{Binding UseTor}" Margin="0 0 10 0" />
+ <TextBlock VerticalAlignment="Center">Tor can be turned off for debugging.</TextBlock>
+ </StackPanel>
+ <StackPanel Margin="0 10" Spacing="5" IsVisible="{Binding UseTor}">
+ <TextBlock>Tor SOCKS5 Endpoint</TextBlock>
+ <TextBox Text="{Binding TorSocks5EndPoint}" />
+ </StackPanel>
+ <StackPanel Margin="0 10" Orientation="Horizontal" Spacing="5" IsVisible="{Binding UseTor}">
+ <ToggleSwitch IsChecked="{Binding TerminateTorOnExit}" Margin="0 0 10 0" />
+ <TextBlock VerticalAlignment="Center">Terminate Tor process on exit.</TextBlock>
+ </StackPanel>
+ </StackPanel>
+ </TabItem>
+
+ <TabItem Header="Node">
+ <StackPanel Orientation="Vertical" Spacing="5">
+ <StackPanel Margin="0 10" Spacing="5">
+ <TextBlock>Network</TextBlock>
+ <ComboBox Items="{Binding Networks}" SelectedItem="{Binding Network}">
+ <!--<ComboBox.ItemTemplate>
+ <DataTemplate>
+ <TextBlock Text="{Binding Converter={StaticResource NetworkStringConverter}}" />
+ </DataTemplate>
+ </ComboBox.ItemTemplate>-->
+ </ComboBox>
+ </StackPanel>
+ <Panel>
+ <StackPanel Orientation="Vertical" Spacing="5">
+ <TextBlock Classes="warningMessage">Work in progress...</TextBlock>
+ <TextBlock>Use your own Bitcoin Core or Wasabi's built-in Bitcoin Knots.</TextBlock>
+ <TextBlock>Expect high CPU, network usage and 300+ GB disk space requirement.</TextBlock>
+ <StackPanel Margin="0 10" Orientation="Horizontal" Spacing="5">
+ <ToggleSwitch IsChecked="{Binding StartLocalBitcoinCoreOnStartup}" Margin="0 0 10 0" />
+ <TextBlock VerticalAlignment="Center">Run Bitcoin Knots at Wasabi's startup.</TextBlock>
+ </StackPanel>
+ <StackPanel Margin="0 10" Spacing="5" IsVisible="{Binding StartLocalBitcoinCoreOnStartup}">
+ <TextBlock>Bitcoin Core or Bitcoin Knots Data Folder</TextBlock>
+ <TextBox Text="{Binding LocalBitcoinCoreDataDir}" />
+ </StackPanel>
+ <StackPanel Margin="0 10" Orientation="Horizontal" Spacing="5" IsVisible="{Binding StartLocalBitcoinCoreOnStartup}">
+ <ToggleSwitch IsChecked="{Binding StopLocalBitcoinCoreOnShutdown}" Margin="0 0 10 0" />
+ <TextBlock VerticalAlignment="Center">Stop Bitcoin Knots when Wasabi is shut down.</TextBlock>
+ </StackPanel>
+ </StackPanel>
+ </Panel>
+ <Panel IsVisible="{Binding !StartLocalBitcoinCoreOnStartup}">
+ <StackPanel Orientation="Vertical" Spacing="5">
+ <TextBlock>Set Wasabi to download blocks from a full node you control.</TextBlock>
+ <StackPanel Margin="0 10" Spacing="5">
+ <TextBlock>Bitcoin P2P Endpoint</TextBlock>
+ <TextBox Text="{Binding BitcoinP2pEndPoint}" />
+ </StackPanel>
+ </StackPanel>
+ </Panel>
+ </StackPanel>
+ </TabItem>
+ </TabControl>
+ </c:ContentArea>
+</UserControl>
\ No newline at end of file

RENAME
WalletWasabi.Fluent/Views/SettingsPageView.axaml.cs
WalletWasabi.Fluent/Views/SettingsPageView.xaml.cs
MODIFY
WalletWasabi.Fluent/WalletWasabi.Fluent.csproj
WalletWasabi.Fluent/WalletWasabi.Fluent.csproj
<SubType>Designer</SubType>
</AvaloniaResource>
<AvaloniaResource Include="Assets\**" />
- <Compile Update="Controls\ProgressRingArc.xaml.cs">
- <DependentUpon>ProgressRingArc.xaml</DependentUpon>
- </Compile>
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Avalonia.ReactiveUI" Version="0.10.999-cibuild0012021-beta" />
- <PackageReference Include="Avalonia.Diagnostics" Version="0.10.999-cibuild0012021-beta" />
+ <PackageReference Include="Avalonia.ReactiveUI" Version="0.10.999-cibuild0012042-beta" />
+ <PackageReference Include="Avalonia.Diagnostics" Version="0.10.999-cibuild0012042-beta" />
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="0.10.0-preview6" />
<PackageReference Include="Avalonia.Xaml.Interactions.Custom" Version="0.10.0-preview6" />
<PackageReference Include="Avalonia.Xaml.Interactivity" Version="0.10.0-preview6" />

some progress on settings layout.