Skip to content

Commit 1eba6e7

Browse files
committed
Editor now works
1 parent 7e70e7a commit 1eba6e7

File tree

9 files changed

+46
-66
lines changed

9 files changed

+46
-66
lines changed

CSharpMath.Maui.Example/CSharpMath.Maui.Example.csproj

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,4 @@
6767
<ProjectReference Include="..\CSharpMath.Maui\CSharpMath.Maui.csproj" />
6868
<ProjectReference Include="..\CSharpMath.Evaluation\CSharpMath.Evaluation.csproj" />
6969
</ItemGroup>
70-
71-
<ItemGroup>
72-
<Compile Update="EditorPage.xaml.cs">
73-
<DependentUpon>EditorPage.xaml</DependentUpon>
74-
</Compile>
75-
<Compile Update="TryPage.xaml.cs">
76-
<DependentUpon>TryPage.xaml</DependentUpon>
77-
</Compile>
78-
</ItemGroup>
79-
80-
<ItemGroup>
81-
<MauiXaml Update="EditorPage.xaml">
82-
<Generator>MSBuild:Compile</Generator>
83-
</MauiXaml>
84-
</ItemGroup>
8570
</Project>

CSharpMath.Maui.Example/EditorPage.xaml.cs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class EditorView : ContentView {
1414
MathKeyboard keyboard = new MathKeyboard(Rendering.FrontEnd.PainterConstants.LargerFontSize);
1515
public EditorView() {
1616
// Basic functionality
17-
var view = new GraphicsView { HeightRequest = 225 };
17+
var view = new GraphicsView();
1818
var viewModel = keyboard.Keyboard;
1919
viewModel.BindDisplay(view, OutputMathPainter, new Color(0, 0, 0, 153));
2020

@@ -26,7 +26,8 @@ public EditorView() {
2626
entry.TextChanged += (sender, e) => {
2727
entry.Text = "";
2828
foreach (var c in e.NewTextValue)
29-
// The (int) extra conversion seems to be required by Android or a crash occurs
29+
// The (int) extra conversion used to be required by Xamarin.Forms on Android or a crash occurs
30+
// Maybe this isn't required anymore in .NET MAUI
3031
viewModel.KeyPress((Editor.MathKeyboardInput)(int)c);
3132
};
3233

@@ -59,11 +60,12 @@ static View GridItem(int row, int col, View view) {
5960
// Assemble
6061
Content = new Grid {
6162
RowDefinitions = {
63+
new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) },
6264
new RowDefinition { Height = new GridLength(1, GridUnitType.Star) },
63-
new RowDefinition { Height = new GridLength(1.5, GridUnitType.Star) },
64-
new RowDefinition { Height = 1 },
65-
new RowDefinition { Height = new GridLength(1.5, GridUnitType.Star) },
66-
new RowDefinition { Height = new GridLength(2, GridUnitType.Star) },
65+
new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) },
66+
new RowDefinition { Height = new GridLength(1, GridUnitType.Star) },
67+
new RowDefinition { Height = new GridLength(1, GridUnitType.Star) },
68+
new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) },
6769
},
6870
Children = {
6971
GridItem(0, 0, new ScrollView {
@@ -74,19 +76,15 @@ static View GridItem(int row, int col, View view) {
7476
GridItem(1, 0, view),
7577
GridItem(2, 0, new BoxView { Color = Colors.Gray }),
7678
GridItem(3, 0, output),
77-
GridItem(4, 0, new StackLayout {
79+
GridItem(4, 0, keyboard),
80+
GridItem(5, 0, new StackLayout {
81+
Orientation = StackOrientation.Horizontal,
7882
Children = {
79-
keyboard,
80-
new StackLayout {
81-
Orientation = StackOrientation.Horizontal,
82-
Children = {
83-
new Button { Text = "Change appearance", Command = new Command(ChangeAppearance) },
84-
entry,
85-
new Button {
86-
Text = "Reset answer pan",
87-
Command = new Command(() => output.DisplacementX = output.DisplacementY = 0)
88-
}
89-
}
83+
new Button { Text = "Change appearance", Command = new Command(ChangeAppearance) },
84+
entry,
85+
new Button {
86+
Text = "Reset answer pan",
87+
Command = new Command(() => output.DisplacementX = output.DisplacementY = 0)
9088
}
9189
}
9290
})

CSharpMath.Maui/Controls/Buttons.cs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,46 +3,38 @@
33
using Microsoft.Maui.Graphics;
44
namespace CSharpMath.Maui {
55
using System;
6+
using System.Threading;
7+
68
public interface IButtonDraw { void ButtonDraw(); }
79
[ContentProperty(nameof(Content))]
810
public abstract class BaseButton<TView, TPainter, TContent> : ImageButton, IButtonDraw
911
where TView : BaseView<TPainter, TContent>
1012
where TPainter : Rendering.FrontEnd.Painter<(ICanvas, SizeF), TContent, Color>, new()
1113
where TContent : class {
12-
private readonly object lockObj = new object();
1314
public BaseButton() {
1415
Aspect = DefaultButtonStyle.AspectFit;
1516
BackgroundColor = DefaultButtonStyle.TransparentBackground;
16-
ButtonDraw();
17+
Content.PropertyChanged += (s, e) => ButtonDraw();
1718
}
18-
public virtual void ButtonDraw() => Source = ImageSource.FromStream(() => {
19+
public virtual void ButtonDraw() => Source = ImageSource.FromStream(async _ => {
1920
if (Content is { } c) {
20-
lock (lockObj) {
21-
var painter = c.Painter;
22-
var originalLatexString = painter.LaTeX;
23-
var modifiedLatexString = originalLatexString ?? "";
24-
25-
if (painter.FontSize is Rendering.FrontEnd.PainterConstants.DefaultFontSize)
26-
painter.FontSize = Rendering.FrontEnd.PainterConstants.LargerFontSize;
21+
var painter = c.Painter.ShallowClone();
2722

28-
modifiedLatexString = LatexHelper.SetColor(modifiedLatexString, TextColor);
23+
if (painter.FontSize is Rendering.FrontEnd.PainterConstants.DefaultFontSize)
24+
painter.FontSize = Rendering.FrontEnd.PainterConstants.LargerFontSize;
2925

30-
// Appropriate positioning for non-full characters, e.g. prime, degree
31-
// Also acts as spacing between MathButtons next to each other
32-
// TODO: Implement and use \phantom
33-
modifiedLatexString = LatexHelper.phantom + modifiedLatexString + LatexHelper.phantom;
26+
// Appropriate positioning for non-full characters, e.g. prime, degree
27+
// Also acts as spacing between MathButtons next to each other
28+
// TODO: Implement and use \phantom
29+
painter.LaTeX = LatexHelper.phantom + painter.LaTeX + LatexHelper.phantom;
3430

35-
var stream = new System.IO.MemoryStream();
36-
painter.DrawToStream(stream);
37-
painter.LaTeX = originalLatexString;
38-
stream.Position = 0;
39-
return stream;
40-
}
31+
var stream = new System.IO.MemoryStream();
32+
await painter.DrawToStreamAsync(stream);
33+
stream.Position = 0;
34+
return stream;
4135
}
4236
return null;
4337
});
44-
public Color TextColor { get => (Color)GetValue(TextColorProperty); set => SetValue(TextColorProperty, value); }
45-
public static readonly BindableProperty TextColorProperty = BindablePropertyWithButtonDraw<BaseButton<TView, TPainter, TContent>>(nameof(TextColor), typeof(Color), Colors.Black);
4638
public TView? Content { get => (TView?)GetValue(ContentProperty); set => SetValue(ContentProperty, value); }
4739
public static readonly BindableProperty ContentProperty = BindableProperty.Create(nameof(Content), typeof(TView), typeof(BaseButton<TView, TPainter, TContent>));
4840
protected static BindableProperty BindablePropertyWithButtonDraw<TButton>(string propertyName, Type propertyType, object? defaultValue = null) where TButton : IButtonDraw =>

CSharpMath.Maui/Controls/LatexHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
namespace CSharpMath.Maui {
77
public static class LatexHelper {
88
public static readonly string phantom = SetColor("|", Colors.Transparent);
9-
public static string SetColor(string latex, Color? color) => color != null ? @"\color{" + color.ToHex() + "}{" + latex + "}" : latex;
9+
public static string SetColor(string latex, Color? color) => color != null ? $@"\color{{{color.ToArgbHex(true)}}}{{{latex}}}" : latex;
1010
}
1111
}

CSharpMath.Maui/Extensions.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ internal static CSharpMathTextAlignment ToCSharpMathTextAlignment(this MauiTextA
2828
_ => CSharpMathTextAlignment.Left
2929
};
3030

31-
public static void DrawToStream<TContent>
31+
public static System.Threading.Tasks.Task DrawToStreamAsync<TContent>
3232
(this Rendering.FrontEnd.Painter<(MauiICanvas, SizeF), TContent, MauiColor> painter,
3333
System.IO.Stream target,
3434
float textPainterCanvasWidth = TextPainter.DefaultCanvasWidth,
3535
ImageFormat format = ImageFormat.Png,
3636
float quality = 1) where TContent : class {
37-
if (!(painter.Measure(textPainterCanvasWidth) is { } size)) return;
37+
if (!(painter.Measure(textPainterCanvasWidth) is { } size)) return System.Threading.Tasks.Task.CompletedTask;
3838
// In case there is no support for zero width/height - other frontends have this check
3939
// and I won't waste time checking each Maui platform to validate this.
4040
if (size.Width is 0) size.Width = 1;
@@ -44,8 +44,10 @@ public static void DrawToStream<TContent>
4444
using var canvas = new Microsoft.Maui.Graphics.Platform.PlatformCanvas();
4545
using var renderTarget = new Microsoft.Graphics.Canvas.CanvasRenderTarget(device, size.Width, size.Height, 96);
4646
canvas.CanvasSize = renderTarget.Size;
47-
canvas.Session = renderTarget.CreateDrawingSession();
48-
painter.Draw((canvas, new SizeF(size.Width, size.Height)), CSharpMathTextAlignment.TopLeft);
47+
using (canvas.Session = renderTarget.CreateDrawingSession()) {
48+
painter.Draw((canvas, new SizeF(size.Width, size.Height)), CSharpMathTextAlignment.TopLeft);
49+
}
50+
var bs = renderTarget.GetPixelBytes();
4951
var nativeFormat = format switch {
5052
ImageFormat.Jpeg => Microsoft.Graphics.Canvas.CanvasBitmapFileFormat.Jpeg,
5153
ImageFormat.Png => Microsoft.Graphics.Canvas.CanvasBitmapFileFormat.Png,
@@ -54,11 +56,11 @@ public static void DrawToStream<TContent>
5456
ImageFormat.Bmp => Microsoft.Graphics.Canvas.CanvasBitmapFileFormat.Bmp,
5557
_ => Microsoft.Graphics.Canvas.CanvasBitmapFileFormat.Png,
5658
};
57-
Microsoft.Maui.Graphics.Win2D.AsyncPump.Run(async () => await renderTarget.SaveAsync(target.AsRandomAccessStream(), nativeFormat, quality));
59+
return renderTarget.SaveAsync(target.AsRandomAccessStream(), nativeFormat, quality).AsTask();
5860
#else
5961
using var context = new Microsoft.Maui.Graphics.Platform.PlatformBitmapExportService().CreateContext((int)size.Width, (int)size.Height);
6062
painter.Draw((context.Canvas, new SizeF(size.Width, size.Height)), CSharpMathTextAlignment.TopLeft);
61-
context.Image.Save(target, format, quality);
63+
return context.Image.SaveAsync(target, format, quality);
6264
#endif
6365
}
6466
class KeyboardDrawable(MathKeyboard keyboard, MathPainter settings, Color caretColor, CaretShape caretShape) : IDrawable {

CSharpMath.Rendering/FrontEnd/MathPainter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,6 @@ public void DrawDisplay(IDisplay<Fonts, Glyph>? display, TCanvas canvas,
5656
Draw(canvas, textAlignment, padding, offsetX, offsetY);
5757
(Display, _displayChanged) = original;
5858
}
59+
public new MathPainter<TCanvas, TColor> ShallowClone() => (MathPainter<TCanvas, TColor>)MemberwiseClone();
5960
}
6061
}

CSharpMath.Rendering/FrontEnd/Painter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ GlyphBoxColor is var (glyph, textRun) ? Nullable((WrapColor(glyph), WrapColor(te
132132
canvas.Restore();
133133
}
134134
}
135+
public Painter<TCanvas, TContent, TColor> ShallowClone() => (Painter<TCanvas, TContent, TColor>)MemberwiseClone();
135136
#endregion Methods
136137
}
137138
}

CSharpMath.Rendering/FrontEnd/TextPainter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,5 +119,6 @@ public void DrawOneLine(TCanvas canvas, float x, float y) {
119119
);
120120
DrawCore(c, new ListDisplay<Fonts, Glyph>(array.Result));
121121
}
122+
public new TextPainter<TCanvas, TColor> ShallowClone() => (TextPainter<TCanvas, TColor>)MemberwiseClone();
122123
}
123124
}

CSharpMath.Xaml/Views.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public class BaseView<TPainter, TContent> : XInheritControl, ICSharpMathAPI<TCon
4747

4848
static BaseView() {
4949
// Initialize static property fields
50-
DisablePanningProperty = CreateProperty<BaseView<TPainter, TContent>, bool>(nameof(EnablePanning), false, _ => false, (_, __) => { });
50+
EnablePanningProperty = CreateProperty<BaseView<TPainter, TContent>, bool>(nameof(EnablePanning), false, _ => false, (_, __) => { });
5151
GlyphBoxColorProperty = CreateProperty<BaseView<TPainter, TContent>, (XColor glyph, XColor textRun)?>(nameof(GlyphBoxColor), false,
5252
p => p.GlyphBoxColor is var (glyph, textRun) ? Nullable((XCanvasColorToXColor(glyph), XCanvasColorToXColor(textRun))) : null,
5353
(p, v) => p.GlyphBoxColor = v is var (glyph, textRun) ? Nullable((XColorToXCanvasColor(glyph), XColorToXCanvasColor(textRun))) : null);
@@ -252,8 +252,8 @@ void Draw(XCanvas canvas) {
252252
Painter.Draw(canvas, TextAlignment, Padding, DisplacementX, DisplacementY);
253253
}
254254
/// <summary>Requires touch events to be enabled in SkiaSharp/Xamarin.Forms</summary>
255-
public bool EnablePanning { get => (bool)GetValue(DisablePanningProperty)!; set => SetValue(DisablePanningProperty, value); }
256-
public static readonly XProperty DisablePanningProperty;
255+
public bool EnablePanning { get => (bool)GetValue(EnablePanningProperty)!; set => SetValue(EnablePanningProperty, value); }
256+
public static readonly XProperty EnablePanningProperty;
257257

258258
static readonly System.Reflection.ParameterInfo[] drawMethodParams = typeof(TPainter)
259259
.GetMethod(nameof(Painter<XCanvas, TContent, XColor>.Draw),

0 commit comments

Comments
 (0)