Send View - BTC and Fiat currency inputs
ADD
WalletWasabi.Fluent/Controls/DualCurrencyEntryBox.axaml
+<Styles xmlns="https://github.com/avaloniaui"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:c="clr-namespace:WalletWasabi.Fluent.Controls;assembly=WalletWasabi.Fluent">
+ <Style Selector="c|DualCurrencyEntryBox">
+ <Setter Property="LeftColumn" Value="0"/>
+ <Setter Property="RightColumn" Value="2"/>
+
+ <Setter Property="Template">
+ <ControlTemplate>
+ <DockPanel>
+ <DataValidationErrors DockPanel.Dock="Bottom"/>
+
+ <Grid ColumnDefinitions="*,Auto,*">
+ <c:CurrencyEntryBox x:Name="PART_LeftEntryBox"
+ Text="{TemplateBinding Text, Mode=TwoWay}"
+ IsReadOnly="{TemplateBinding IsReadOnly}"
+ CurrencyCode="{TemplateBinding CurrencyCode}"
+ ConversionRate="{TemplateBinding ConversionRate}"
+ IsFiat="False"
+ Watermark="{TemplateBinding Watermark}"
+ IsApproximate="False"
+ Grid.Column="{TemplateBinding LeftColumn}"/>
+
+ <Button x:Name="PART_SwapButton" Focusable="False"
+ Cursor="Arrow" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Transparent"
+ BorderBrush="Transparent" BorderThickness="0" Padding="0" Margin="5"
+ Grid.Column="1">
+ <PathIcon Data="{StaticResource arrow_swap}" Width="16" />
+ </Button>
+
+ <c:CurrencyEntryBox x:Name="PART_RightEntryBox"
+ Text="{TemplateBinding ConversionText, Mode=TwoWay}"
+ IsReadOnly="{TemplateBinding IsReadOnly}"
+ CurrencyCode="{TemplateBinding ConversionCurrencyCode}"
+ ConversionRate="{TemplateBinding ConversionRate}"
+ IsFiat="True"
+ Watermark="{TemplateBinding ConversionWatermark}"
+ IsApproximate="{TemplateBinding IsConversionApproximate}"
+ Grid.Column="{TemplateBinding RightColumn}"/>
+ </Grid>
+ </DockPanel>
+ </ControlTemplate>
+ </Setter>
+ </Style>
+
+ <Style Selector="c|DualCurrencyEntryBox:noexchangerate Button#PART_SwapButton">
+ <Setter Property="IsVisible" Value="False" />
+ </Style>
+
+ <Style Selector="c|DualCurrencyEntryBox:reversed">
+ <Setter Property="LeftColumn" Value="2" />
+ <Setter Property="RightColumn" Value="0" />
+ </Style>
+
+ <!-- TODO: temporary fix to prevent layout issue when error occurs -->
+ <Style Selector="c|DualCurrencyEntryBox /template/ DataValidationErrors">
+ <Setter Property="MinHeight" Value="21" />
+ </Style>
+
+ <Style Selector="c|DualCurrencyEntryBox:error /template/ Border#PART_BorderElement">
+ <Setter Property="BorderBrush" Value="{DynamicResource SystemControlErrorTextForegroundBrush}" />
+ </Style>
+
+ <Style Selector="c|DualCurrencyEntryBox /template/ Button#PART_SwapButton">
+ <Setter Property="Opacity" Value="0.5" />
+ </Style>
+
+ <Style Selector="c|DualCurrencyEntryBox /template/ Button#PART_SwapButton:pointerover">
+ <Setter Property="Opacity" Value="1" />
+ </Style>
+
+ <Style
+ Selector="c|DualCurrencyEntryBox /template/ Button#PART_SwapButton:pointerover /template/ ContentPresenter#PART_ContentPresenter">
+ <Setter Property="Background" Value="Transparent" />
+ </Style>
+</Styles>

MODIFY
WalletWasabi.Fluent/Styles/Styles.axaml
WalletWasabi.Fluent/Styles/Styles.axaml
<StyleInclude Source="avares://WalletWasabi.Fluent/Styles/HyperlinkButton.axaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Controls/AnimatedButton.axaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Controls/CurrencyEntryBox.axaml" />
+ <StyleInclude Source="avares://WalletWasabi.Fluent/Controls/DualCurrencyEntryBox.axaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Controls/HistoryPlaceholderPanel.axaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Styles/TreeDataGrid.axaml" />
<StyleInclude Source="avares://WalletWasabi.Fluent/Styles/RadioButton.axaml" />

MODIFY
WalletWasabi.Fluent/UiConfig.cs
WalletWasabi.Fluent/UiConfig.cs
@@ -27,6 +27,7 @@ public class UiConfig : ConfigBase
private bool _hideOnClose;
private bool _autoPaste;
private int _feeTarget;
+ private bool _sendAmountConversionReversed;
public UiConfig() : base()
{
@@ -53,6 +54,12 @@ public class UiConfig : ConfigBase
.ObserveOn(RxApp.TaskpoolScheduler)
.Subscribe(_ => ToFile());
+ this.WhenAnyValue(x => x.SendAmountConversionReversed)
+ .Throttle(TimeSpan.FromMilliseconds(500))
+ .Skip(1) // Won't save on UiConfig creation.
+ .ObserveOn(RxApp.TaskpoolScheduler)
+ .Subscribe(_ => ToFile());
+
this.WhenAnyValue(
x => x.WindowState,
x => x.WindowX,
@@ -189,4 +196,12 @@ public class UiConfig : ConfigBase
get => _hideOnClose;
set => RaiseAndSetIfChanged(ref _hideOnClose, value);
}
+
+ [DefaultValue(false)]
+ [JsonProperty(PropertyName = "SendAmountConversionReversed", DefaultValueHandling = DefaultValueHandling.Populate)]
+ public bool SendAmountConversionReversed
+ {
+ get => _sendAmountConversionReversed;
+ internal set => RaiseAndSetIfChanged(ref _sendAmountConversionReversed, value);
+ }
}

MODIFY
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs
WalletWasabi.Fluent/ViewModels/Wallets/Send/SendViewModel.cs
@@ -59,6 +59,8 @@ public partial class SendViewModel : RoutableViewModel
_transactionInfo = new TransactionInfo(wallet.KeyManager.MinAnonScoreTarget);
_coinJoinManager = Services.HostedServices.GetOrDefault<CoinJoinManager>();
+ _conversionReversed = Services.UiConfig.SendAmountConversionReversed;
+
IsQrButtonVisible = WebcamQrReader.IsOsPlatformSupported;
ExchangeRate = _wallet.Synchronizer.UsdExchangeRate;
@@ -134,6 +136,10 @@ public partial class SendViewModel : RoutableViewModel
Navigate().To(new TransactionPreviewViewModel(wallet, _transactionInfo, address, _isFixedAmount));
}, nextCommandCanExecute);
+
+ this.WhenAnyValue(x => x.ConversionReversed)
+ .Skip(1)
+ .Subscribe(x => Services.UiConfig.SendAmountConversionReversed = x);
}
public bool IsQrButtonVisible { get; }

MODIFY
WalletWasabi.Fluent/Views/Wallets/Send/SendView.axaml
WalletWasabi.Fluent/Views/Wallets/Send/SendView.axaml
<DockPanel>
<Image Width="120" Source="avares://WalletWasabi.Fluent/Assets/TechnologyLogos/payjoin.png"
DockPanel.Dock="Right" IsVisible="{Binding IsPayJoin}" Margin="0 8 8 0" VerticalAlignment="Top" />
- <c:CurrencyEntryBox x:Name="amountTb"
+ <c:DualCurrencyEntryBox x:Name="amountTb"
KeyboardNavigation.IsTabStop="{Binding !IsFixedAmount}"
IsReadOnly="{Binding IsFixedAmount}"
AmountBtc="{Binding AmountBtc}"
ConversionRate="{Binding ExchangeRate}"
+ CurrencyCode="BTC"
ConversionCurrencyCode="USD"
IsConversionReversed="{Binding ConversionReversed, Mode=TwoWay}" />
</DockPanel>

MODIFY
WalletWasabi.Fluent/WalletWasabi.Fluent.csproj
WalletWasabi.Fluent/WalletWasabi.Fluent.csproj
<ItemGroup>
<RuntimeHostConfigurationOption Include="System.Globalization.Invariant" Value="true" />
</ItemGroup>
+
+ <ItemGroup>
+ <Compile Update="Controls\DualCurrencyEntryBox.axaml.cs">
+ <DependentUpon>DualCurrencyEntryBox.axaml</DependentUpon>
+ </Compile>
+ </ItemGroup>
</Project>

Send View - BTC and Fiat currency inputs