Skip to content

Commit e6d32dc

Browse files
committed
Added ImagePickerHelper class
1 parent 5fff03b commit e6d32dc

File tree

8 files changed

+467
-30
lines changed

8 files changed

+467
-30
lines changed

ChartGeneratorAISample/ChartGenerator/ChartGenerator.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
6969
<PackageReference Include="SampleBrowser.Maui.Base" Version="*" />
7070
<PackageReference Include="Syncfusion.Maui.AIAssistView" Version="*" />
71+
<PackageReference Include="Syncfusion.Maui.PdfViewer" Version="*" />
7172
<PackageReference Include="Syncfusion.Maui.Toolkit" Version="*" />
7273
</ItemGroup>
7374

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace ChartGenerator
9+
{
10+
public class ImagePickerHelper
11+
{
12+
internal async Task<byte[]> PickImageAsync()
13+
{
14+
try
15+
{
16+
var result = await MediaPicker.PickPhotoAsync();
17+
18+
if (result != null)
19+
{
20+
// Open the file stream
21+
using (Stream stream = await result.OpenReadAsync())
22+
{
23+
// Copy the stream into a memory stream to avoid object disposed exception.
24+
using (MemoryStream memoryStream = new MemoryStream())
25+
{
26+
await stream.CopyToAsync(memoryStream);
27+
return memoryStream.ToArray();
28+
}
29+
}
30+
}
31+
}
32+
catch (Exception ex)
33+
{
34+
// Handle exceptions
35+
Console.WriteLine($"Error picking image: {ex.Message}");
36+
}
37+
38+
return null;
39+
}
40+
41+
internal async Task SaveImageAsync(string filePath)
42+
{
43+
try
44+
{
45+
if (File.Exists(filePath))
46+
{
47+
File.Delete(filePath);
48+
}
49+
}
50+
catch (Exception ex)
51+
{
52+
Debug.WriteLine($"Error deleting image: {ex.Message}");
53+
}
54+
55+
try
56+
{
57+
// Get the image from Gallery.
58+
byte[] imageBytes = await PickImageAsync();
59+
60+
if (imageBytes != null)
61+
{
62+
// Save the image bytes to a file, database, etc.
63+
File.WriteAllBytes(filePath, imageBytes);
64+
}
65+
}
66+
catch (Exception ex)
67+
{
68+
Debug.WriteLine($"Error saving image: {ex.Message}");
69+
}
70+
}
71+
72+
73+
}
74+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System.ComponentModel;
2+
3+
namespace ChartGenerator
4+
{
5+
public class Option : INotifyPropertyChanged
6+
{
7+
#region Private Fields
8+
9+
private bool isEnabled;
10+
private bool isOpen;
11+
12+
#endregion
13+
14+
#region Public APIs
15+
16+
public string Name { get; set; }
17+
public string Icon { get; set; }
18+
public bool CanShowSeparator { get; set; }
19+
20+
public bool IsEnabled
21+
{
22+
get { return isEnabled; }
23+
set
24+
{
25+
isEnabled = value;
26+
RaisePropertyChanged(nameof(IsEnabled));
27+
}
28+
}
29+
public bool IsOpen
30+
{
31+
get { return isOpen; }
32+
set
33+
{
34+
isOpen = value;
35+
RaisePropertyChanged(nameof(IsOpen));
36+
}
37+
}
38+
39+
#endregion
40+
41+
#region Constructor
42+
public Option()
43+
{
44+
IsEnabled = true;
45+
}
46+
47+
#endregion
48+
49+
#region Property Changed
50+
51+
public event PropertyChangedEventHandler? PropertyChanged;
52+
/// <summary>
53+
/// Occurs when property is changed.
54+
/// </summary>
55+
/// <param name="propName">changed property name</param>
56+
public void RaisePropertyChanged(string propName)
57+
{
58+
if (PropertyChanged != null)
59+
{
60+
PropertyChanged(this, new PropertyChangedEventArgs(propName));
61+
}
62+
}
63+
#endregion
64+
}
65+
}

ChartGeneratorAISample/ChartGenerator/View/ChartView.xaml

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -192,22 +192,35 @@
192192
Grid.Column="{OnPlatform Android='0',iOS='0', Default='1'}"
193193
VerticalOptions="Center"
194194
HorizontalOptions="Center"/>
195-
196-
<buttons:SfButton
197-
Grid.Row="0"
198-
Margin="0,0,20,0"
199-
Grid.Column="{OnPlatform Android='0',iOS='0', Default='1'}"
200-
x:Name="aibutton"
201-
Text="&#xe7e1;"
202-
FontFamily="MauiSampleFontIcon"
203-
CornerRadius="5"
204-
BackgroundColor="#CAC4D0"
205-
FontSize="{OnPlatform WinUI=20, Android=15, MacCatalyst=20, iOS=20}" WidthRequest="30" HeightRequest="30"
206-
ToolTipProperties.Text="Click to open AI assistant"
207-
FontAttributes="Bold"
208-
VerticalOptions="Start"
209-
HorizontalOptions="End"/>
210-
</Grid>
195+
<buttons:SfButton Grid.Row="0"
196+
Margin="0,0,60,0"
197+
Grid.Column="{OnPlatform Android='0',iOS='0', Default='1'}"
198+
x:Name="exportchartbutton"
199+
Text="Export Chart"
200+
Clicked="Exportchartbutton_Clicked"
201+
FontFamily="MauiSampleFontIcon"
202+
CornerRadius="5"
203+
TextColor="White"
204+
BackgroundColor="#6750a4"
205+
FontSize="{OnPlatform WinUI=17, Android=15, MacCatalyst=17, iOS=17}" WidthRequest="120" HeightRequest="30"
206+
ToolTipProperties.Text="Click to Export the Chart"
207+
FontAttributes="Bold" VerticalOptions="Start"
208+
HorizontalOptions="End"/>
209+
<buttons:SfButton
210+
Grid.Row="0"
211+
Margin="0,0,20,0"
212+
Grid.Column="{OnPlatform Android='0',iOS='0', Default='1'}"
213+
x:Name="aibutton"
214+
Text="&#xe7e1;"
215+
FontFamily="MauiSampleFontIcon"
216+
CornerRadius="5"
217+
BackgroundColor="#CAC4D0"
218+
FontSize="{OnPlatform WinUI=20, Android=15, MacCatalyst=20, iOS=20}" WidthRequest="30" HeightRequest="30"
219+
ToolTipProperties.Text="Click to open AI assistant"
220+
FontAttributes="Bold"
221+
VerticalOptions="Start"
222+
HorizontalOptions="End"/>
223+
</Grid>
211224
</Grid>
212225
</ContentPage.Content>
213226

ChartGeneratorAISample/ChartGenerator/View/ChartView.xaml.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1+
using Syncfusion.Maui.PdfViewer;
2+
using Microsoft.Maui.Controls.Internals;
3+
using Microsoft.Maui.Graphics;
14
using Syncfusion.Maui.AIAssistView;
5+
using System.Drawing;
6+
using Syncfusion.Pdf;
7+
using Syncfusion.Pdf.Graphics;
8+
using Syncfusion.Maui.Core;
9+
using Syncfusion.Maui.Core.Internals;
210

311
namespace ChartGenerator;
412

513
public partial class ChartView : ContentPage
614
{
15+
int count = 0;
716
ChartViewModel ViewModel;
817
public ChartView(ChartViewModel viewModel)
918
{
@@ -28,6 +37,47 @@ private void close_Clicked(object sender, EventArgs e)
2837
headerView.IsVisible = false;
2938
}
3039
}
40+
41+
private async void Exportchartbutton_Clicked(object sender, EventArgs e)
42+
{
43+
PdfDocument document = new PdfDocument();
44+
PdfPage page = document.Pages.Add();
45+
PdfGraphics graphics = page.Graphics;
46+
47+
float width = (float)templatedItemView.Width + 75;
48+
float height = (float)templatedItemView.Height + 125;
49+
50+
//To reduce the width and height of the Windows and MAC platform
51+
#if !IOS && !ANDROID
52+
width = (float)templatedItemView.Width / 2.5f;
53+
height = (float)templatedItemView.Height / 1.5f;
54+
#endif
55+
56+
PdfImage img = new PdfBitmap((await templatedItemView.GetStreamAsync(ImageFileFormat.Png)));
57+
graphics.DrawImage(img, 0, 0, width, height);
58+
MemoryStream stream = new MemoryStream();
59+
document.Save(stream);
60+
document.Close(true);
61+
stream.Position = 0;
62+
SavePDF("ChartAsPDF.pdf", stream);
63+
stream.Flush();
64+
stream.Dispose();
65+
}
66+
private async void SavePDF(string fileName, Stream stream)
67+
{
68+
fileName = Path.GetFileNameWithoutExtension(fileName) + ".pdf";
69+
70+
#if ANDROID
71+
string path = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments).ToString();
72+
#else
73+
string path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
74+
#endif
75+
string filePath = Path.Combine(path, fileName);
76+
using FileStream fileStream = new(filePath, FileMode.Create, FileAccess.ReadWrite);
77+
await stream.CopyToAsync(fileStream);
78+
fileStream.Flush();
79+
fileStream.Dispose();
80+
}
3181
}
3282

3383
public class ChartTemplateSelector : DataTemplateSelector

ChartGeneratorAISample/ChartGenerator/View/DesktopUI.xaml

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,72 @@
3333

3434
<Grid ColumnDefinitions="500,auto" HorizontalOptions="Center" ColumnSpacing="5" Padding="5">
3535

36-
<Grid ColumnDefinitions="*" HorizontalOptions="FillAndExpand" Grid.Column="0">
37-
<Editor Grid.Column="1" IsEnabled="{Binding IsDisable}"
36+
<Grid RowDefinitions="Auto,*,Auto" HorizontalOptions="FillAndExpand" Grid.Column="0">
37+
<core:SfChip
38+
Text="&#xe7CD;"
39+
FontFamily="MauiSampleFontIcon"
40+
VerticalOptions="Start"
41+
HorizontalOptions="Center"
42+
VerticalTextAlignment="Center"
43+
HorizontalTextAlignment="Center"
44+
CornerRadius="20"
45+
Stroke="Transparent"
46+
StrokeThickness="0"
47+
HeightRequest="30"
48+
WidthRequest="30"
49+
Margin="10"
50+
Grid.Row="1"
51+
Command="{Binding EditorExpandCollapseCommand}"
52+
CommandParameter="{x:Reference editor}"
53+
/>
54+
<Editor Grid.Row="2" IsEnabled="{Binding IsDisable}" x:Name="editor"
3855
BackgroundColor="Transparent"
3956
HeightRequest="100"
4057
PlaceholderColor="Gray"
4158
Text="{Binding EntryText}"
4259
Placeholder="Describe what you want to create.."
4360
HorizontalOptions="FillAndExpand"
44-
FontSize="14"
45-
TextColor="Black"
46-
>
47-
</Editor>
61+
FontSize="14"
62+
TextColor="Black">
63+
64+
</Editor>
4865

49-
<core:SfBusyIndicator IsRunning="{Binding IsLoading}"
66+
<core:SfChipGroup ItemHeight="40" Margin="5,50,5,5"
67+
ChipCornerRadius="20"
68+
ChipBackground="Transparent"
69+
ChipStrokeThickness="0"
70+
Grid.Row="3"
71+
ChipPadding="0"
72+
ChipClicked="OnChipClicked"
73+
ItemsSource="{Binding Path=EditorOptions}">
74+
<core:SfChipGroup.ItemTemplate>
75+
<DataTemplate>
76+
<Grid x:Name="editorOptionGrid" ColumnDefinitions="Auto,Auto">
77+
<Label x:Name="editorOptions"
78+
Text="{Binding Icon}"
79+
VerticalTextAlignment="Center"
80+
HorizontalTextAlignment="Center"
81+
HorizontalOptions="Center"
82+
FontFamily="MauiSampleFontIcon"
83+
TextColor="#611C1B1F"
84+
FontSize="20"
85+
WidthRequest="40" >
86+
<Label.GestureRecognizers>
87+
<TapGestureRecognizer Command="{Binding Source={x:Reference editor}, Path=BindingContext.AttachmentContextMenuCommand}" CommandParameter="{Binding .}" />
88+
</Label.GestureRecognizers>
89+
90+
</Label>
91+
92+
93+
</Grid>
94+
</DataTemplate>
95+
</core:SfChipGroup.ItemTemplate>
96+
</core:SfChipGroup>
97+
<core:SfBusyIndicator IsRunning="{Binding IsLoading}"
5098
IsVisible="{Binding IsLoading}"
51-
AnimationType="SingleCircle"
52-
/>
53-
</Grid>
99+
AnimationType="SingleCircle"/>
100+
101+
</Grid>
54102

55103
<buttons:SfButton Text="&#xe76f;"
56104
FontFamily="MauiSampleFontIcon"

ChartGeneratorAISample/ChartGenerator/View/DesktopUI.xaml.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using Syncfusion.Maui.Core;
2+
13
namespace ChartGenerator;
24

35
public partial class DesktopUI : ContentPage
@@ -6,4 +8,26 @@ public DesktopUI()
68
{
79
InitializeComponent();
810
}
11+
private void OnChipClicked(object sender, EventArgs e)
12+
{
13+
var viewmodel = this.BindingContext as ChartViewModel;
14+
var chip = (sender as SfChip);
15+
var layout = chip.Children[0] as HorizontalStackLayout;
16+
17+
Option option;
18+
if (layout != null)
19+
{
20+
option = layout.BindingContext as Option;
21+
}
22+
else
23+
{
24+
var label = chip.Children[0] as Grid;
25+
option = label.BindingContext as Option;
26+
}
27+
28+
if (string.IsNullOrEmpty(option.Name) || !option.IsEnabled)
29+
return;
30+
31+
viewmodel.EditorOptionsComamnd.Execute(option);
32+
}
933
}

0 commit comments

Comments
 (0)