diff --git a/src/AdvancedCalculator.Android/Styles/Android.axaml b/src/AdvancedCalculator.Android/Styles/Android.axaml
new file mode 100644
index 0000000..30f7e04
--- /dev/null
+++ b/src/AdvancedCalculator.Android/Styles/Android.axaml
@@ -0,0 +1,17 @@
+
+
+ 16
+ 18
+ 24
+ 1.35
+
+
+
+
+
+
diff --git a/src/AdvancedCalculator.Browser/Styles/Browser.axaml b/src/AdvancedCalculator.Browser/Styles/Browser.axaml
new file mode 100644
index 0000000..3842c71
--- /dev/null
+++ b/src/AdvancedCalculator.Browser/Styles/Browser.axaml
@@ -0,0 +1,16 @@
+
+
+ 15
+ 22
+ 1.3
+
+
+
+
+
+
diff --git a/src/AdvancedCalculator.Desktop/Styles/Desktop.axaml b/src/AdvancedCalculator.Desktop/Styles/Desktop.axaml
new file mode 100644
index 0000000..7a951d8
--- /dev/null
+++ b/src/AdvancedCalculator.Desktop/Styles/Desktop.axaml
@@ -0,0 +1,16 @@
+
+
+ 13
+ 1.2
+ 20
+
+
+
+
+
+
diff --git a/src/AdvancedCalculator/App.axaml b/src/AdvancedCalculator/App.axaml
index 5e686cd..8d7bed3 100644
--- a/src/AdvancedCalculator/App.axaml
+++ b/src/AdvancedCalculator/App.axaml
@@ -6,6 +6,8 @@
+
+
diff --git a/src/AdvancedCalculator/App.axaml.cs b/src/AdvancedCalculator/App.axaml.cs
index e967b3b..32716eb 100644
--- a/src/AdvancedCalculator/App.axaml.cs
+++ b/src/AdvancedCalculator/App.axaml.cs
@@ -5,6 +5,8 @@ using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Data.Core.Plugins;
using Avalonia.Markup.Xaml;
+using Avalonia.Styling;
+using System;
namespace AdvancedCalculator;
@@ -21,6 +23,40 @@ public partial class App : Application
// Without this line you will get duplicate validations from both Avalonia and CT
BindingPlugins.DataValidators.RemoveAt(0);
+ // Load platform-specific styles (typography, scrollbars overrides)
+ try
+ {
+ var styles = Current?.Styles;
+ if (styles is not null)
+ {
+ if (OperatingSystem.IsAndroid())
+ {
+ styles.Add(new StyleInclude(new Uri("avares://AdvancedCalculator/"))
+ {
+ Source = new Uri("avares://AdvancedCalculator.Android/Styles/Android.axaml")
+ });
+ }
+ else if (OperatingSystem.IsBrowser())
+ {
+ styles.Add(new StyleInclude(new Uri("avares://AdvancedCalculator/"))
+ {
+ Source = new Uri("avares://AdvancedCalculator.Browser/Styles/Browser.axaml")
+ });
+ }
+ else
+ {
+ styles.Add(new StyleInclude(new Uri("avares://AdvancedCalculator/"))
+ {
+ Source = new Uri("avares://AdvancedCalculator.Desktop/Styles/Desktop.axaml")
+ });
+ }
+ }
+ }
+ catch
+ {
+ // If a platform-specific style dictionary is missing, continue without failing.
+ }
+
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow
diff --git a/src/AdvancedCalculator/Converters/WidthToBooleanConverter.cs b/src/AdvancedCalculator/Converters/WidthToBooleanConverter.cs
new file mode 100644
index 0000000..6efa5f6
--- /dev/null
+++ b/src/AdvancedCalculator/Converters/WidthToBooleanConverter.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Globalization;
+using Avalonia.Data.Converters;
+
+namespace AdvancedCalculator.Converters;
+
+// Returns true if width (double) is less than the provided threshold (parameter),
+// otherwise false. Default threshold is 640 when parameter is null or invalid.
+public class WidthToBooleanConverter : IValueConverter
+{
+ public static readonly WidthToBooleanConverter Instance = new();
+
+ public object? Convert(object? value, Type targetType, object? parameter, CultureInfo? culture)
+ {
+ if (value is double width)
+ {
+ double threshold = 640;
+ if (parameter is double p)
+ threshold = p;
+ else if (parameter is string s && double.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out var parsed))
+ threshold = parsed;
+
+ return width < threshold;
+ }
+ return false;
+ }
+
+ public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo? culture)
+ => throw new NotSupportedException();
+}
+
diff --git a/src/AdvancedCalculator/Styles/Scroll.axaml b/src/AdvancedCalculator/Styles/Scroll.axaml
new file mode 100644
index 0000000..ea9284d
--- /dev/null
+++ b/src/AdvancedCalculator/Styles/Scroll.axaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AdvancedCalculator/Styles/Typography.axaml b/src/AdvancedCalculator/Styles/Typography.axaml
new file mode 100644
index 0000000..eb80272
--- /dev/null
+++ b/src/AdvancedCalculator/Styles/Typography.axaml
@@ -0,0 +1,30 @@
+
+
+ 12
+ 14
+ 16
+ 20
+
+ 18
+ 22
+ 26
+
+ 1.1
+ 1.25
+ 1.4
+
+
+
+
+
+
+
+
diff --git a/src/AdvancedCalculator/ViewModels/MainViewModel.cs b/src/AdvancedCalculator/ViewModels/MainViewModel.cs
index 1611402..7be1cf6 100644
--- a/src/AdvancedCalculator/ViewModels/MainViewModel.cs
+++ b/src/AdvancedCalculator/ViewModels/MainViewModel.cs
@@ -41,6 +41,37 @@ public partial class MainViewModel : ViewModelBase
IsFunctionsPanelOpen = !IsFunctionsPanelOpen;
}
+ // Insert helpers for touch: appends tokens to the input box
+ [RelayCommand]
+ private void InsertVariable(string? variableName)
+ {
+ if (string.IsNullOrWhiteSpace(variableName))
+ return;
+ InsertToken(variableName);
+ }
+
+ [RelayCommand]
+ private void InsertFunction(string? functionName)
+ {
+ if (string.IsNullOrWhiteSpace(functionName))
+ return;
+ InsertToken(functionName + "()");
+ }
+
+ private void InsertToken(string token)
+ {
+ if (string.IsNullOrEmpty(InputText))
+ {
+ InputText = token;
+ return;
+ }
+
+ if (!char.IsWhiteSpace(InputText[^1]))
+ InputText += " ";
+
+ InputText += token;
+ }
+
[RelayCommand(AllowConcurrentExecutions = false)]
private async Task Submit()
{
diff --git a/src/AdvancedCalculator/Views/MainView.axaml b/src/AdvancedCalculator/Views/MainView.axaml
index 71ffac9..d5fc5e7 100644
--- a/src/AdvancedCalculator/Views/MainView.axaml
+++ b/src/AdvancedCalculator/Views/MainView.axaml
@@ -10,92 +10,184 @@
x:DataType="vm:MainViewModel">
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+