From e6d32dc1c840402b49d020f7132de51e9e58ff5e Mon Sep 17 00:00:00 2001 From: Harsha Date: Fri, 20 Jun 2025 18:18:53 +0530 Subject: [PATCH 01/10] Added ImagePickerHelper class --- .../ChartGenerator/ChartGenerator.csproj | 1 + .../Helper/ImagePickerHelper.cs | 74 ++++++++ .../ChartGenerator/Models/ContextMenus.cs | 65 +++++++ .../ChartGenerator/View/ChartView.xaml | 45 +++-- .../ChartGenerator/View/ChartView.xaml.cs | 50 ++++++ .../ChartGenerator/View/DesktopUI.xaml | 68 +++++-- .../ChartGenerator/View/DesktopUI.xaml.cs | 24 +++ .../ViewModel/ChartViewModel.cs | 170 +++++++++++++++++- 8 files changed, 467 insertions(+), 30 deletions(-) create mode 100644 ChartGeneratorAISample/ChartGenerator/Helper/ImagePickerHelper.cs create mode 100644 ChartGeneratorAISample/ChartGenerator/Models/ContextMenus.cs diff --git a/ChartGeneratorAISample/ChartGenerator/ChartGenerator.csproj b/ChartGeneratorAISample/ChartGenerator/ChartGenerator.csproj index 753a6b3..07a6ff0 100644 --- a/ChartGeneratorAISample/ChartGenerator/ChartGenerator.csproj +++ b/ChartGeneratorAISample/ChartGenerator/ChartGenerator.csproj @@ -68,6 +68,7 @@ + diff --git a/ChartGeneratorAISample/ChartGenerator/Helper/ImagePickerHelper.cs b/ChartGeneratorAISample/ChartGenerator/Helper/ImagePickerHelper.cs new file mode 100644 index 0000000..7353edd --- /dev/null +++ b/ChartGeneratorAISample/ChartGenerator/Helper/ImagePickerHelper.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ChartGenerator +{ + public class ImagePickerHelper + { + internal async Task PickImageAsync() + { + try + { + var result = await MediaPicker.PickPhotoAsync(); + + if (result != null) + { + // Open the file stream + using (Stream stream = await result.OpenReadAsync()) + { + // Copy the stream into a memory stream to avoid object disposed exception. + using (MemoryStream memoryStream = new MemoryStream()) + { + await stream.CopyToAsync(memoryStream); + return memoryStream.ToArray(); + } + } + } + } + catch (Exception ex) + { + // Handle exceptions + Console.WriteLine($"Error picking image: {ex.Message}"); + } + + return null; + } + + internal async Task SaveImageAsync(string filePath) + { + try + { + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + } + catch (Exception ex) + { + Debug.WriteLine($"Error deleting image: {ex.Message}"); + } + + try + { + // Get the image from Gallery. + byte[] imageBytes = await PickImageAsync(); + + if (imageBytes != null) + { + // Save the image bytes to a file, database, etc. + File.WriteAllBytes(filePath, imageBytes); + } + } + catch (Exception ex) + { + Debug.WriteLine($"Error saving image: {ex.Message}"); + } + } + + + } +} diff --git a/ChartGeneratorAISample/ChartGenerator/Models/ContextMenus.cs b/ChartGeneratorAISample/ChartGenerator/Models/ContextMenus.cs new file mode 100644 index 0000000..7c994fb --- /dev/null +++ b/ChartGeneratorAISample/ChartGenerator/Models/ContextMenus.cs @@ -0,0 +1,65 @@ +using System.ComponentModel; + +namespace ChartGenerator +{ + public class Option : INotifyPropertyChanged + { + #region Private Fields + + private bool isEnabled; + private bool isOpen; + + #endregion + + #region Public APIs + + public string Name { get; set; } + public string Icon { get; set; } + public bool CanShowSeparator { get; set; } + + public bool IsEnabled + { + get { return isEnabled; } + set + { + isEnabled = value; + RaisePropertyChanged(nameof(IsEnabled)); + } + } + public bool IsOpen + { + get { return isOpen; } + set + { + isOpen = value; + RaisePropertyChanged(nameof(IsOpen)); + } + } + + #endregion + + #region Constructor + public Option() + { + IsEnabled = true; + } + + #endregion + + #region Property Changed + + public event PropertyChangedEventHandler? PropertyChanged; + /// + /// Occurs when property is changed. + /// + /// changed property name + public void RaisePropertyChanged(string propName) + { + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs(propName)); + } + } + #endregion + } +} diff --git a/ChartGeneratorAISample/ChartGenerator/View/ChartView.xaml b/ChartGeneratorAISample/ChartGenerator/View/ChartView.xaml index 403c16d..e56d560 100644 --- a/ChartGeneratorAISample/ChartGenerator/View/ChartView.xaml +++ b/ChartGeneratorAISample/ChartGenerator/View/ChartView.xaml @@ -192,22 +192,35 @@ Grid.Column="{OnPlatform Android='0',iOS='0', Default='1'}" VerticalOptions="Center" HorizontalOptions="Center"/> - - - + + + diff --git a/ChartGeneratorAISample/ChartGenerator/View/ChartView.xaml.cs b/ChartGeneratorAISample/ChartGenerator/View/ChartView.xaml.cs index 96f6713..7f390a1 100644 --- a/ChartGeneratorAISample/ChartGenerator/View/ChartView.xaml.cs +++ b/ChartGeneratorAISample/ChartGenerator/View/ChartView.xaml.cs @@ -1,9 +1,18 @@ +using Syncfusion.Maui.PdfViewer; +using Microsoft.Maui.Controls.Internals; +using Microsoft.Maui.Graphics; using Syncfusion.Maui.AIAssistView; +using System.Drawing; +using Syncfusion.Pdf; +using Syncfusion.Pdf.Graphics; +using Syncfusion.Maui.Core; +using Syncfusion.Maui.Core.Internals; namespace ChartGenerator; public partial class ChartView : ContentPage { + int count = 0; ChartViewModel ViewModel; public ChartView(ChartViewModel viewModel) { @@ -28,6 +37,47 @@ private void close_Clicked(object sender, EventArgs e) headerView.IsVisible = false; } } + + private async void Exportchartbutton_Clicked(object sender, EventArgs e) + { + PdfDocument document = new PdfDocument(); + PdfPage page = document.Pages.Add(); + PdfGraphics graphics = page.Graphics; + + float width = (float)templatedItemView.Width + 75; + float height = (float)templatedItemView.Height + 125; + + //To reduce the width and height of the Windows and MAC platform +#if !IOS && !ANDROID + width = (float)templatedItemView.Width / 2.5f; + height = (float)templatedItemView.Height / 1.5f; +#endif + + PdfImage img = new PdfBitmap((await templatedItemView.GetStreamAsync(ImageFileFormat.Png))); + graphics.DrawImage(img, 0, 0, width, height); + MemoryStream stream = new MemoryStream(); + document.Save(stream); + document.Close(true); + stream.Position = 0; + SavePDF("ChartAsPDF.pdf", stream); + stream.Flush(); + stream.Dispose(); + } + private async void SavePDF(string fileName, Stream stream) + { + fileName = Path.GetFileNameWithoutExtension(fileName) + ".pdf"; + +#if ANDROID + string path = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments).ToString(); +#else + string path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); +#endif + string filePath = Path.Combine(path, fileName); + using FileStream fileStream = new(filePath, FileMode.Create, FileAccess.ReadWrite); + await stream.CopyToAsync(fileStream); + fileStream.Flush(); + fileStream.Dispose(); + } } public class ChartTemplateSelector : DataTemplateSelector diff --git a/ChartGeneratorAISample/ChartGenerator/View/DesktopUI.xaml b/ChartGeneratorAISample/ChartGenerator/View/DesktopUI.xaml index 67cfb16..d8c82ea 100644 --- a/ChartGeneratorAISample/ChartGenerator/View/DesktopUI.xaml +++ b/ChartGeneratorAISample/ChartGenerator/View/DesktopUI.xaml @@ -33,24 +33,72 @@ - - + + - + FontSize="14" + TextColor="Black"> + + - + + + + + + + + + + + - + AnimationType="SingleCircle"/> + + imageSourceCollection; + private readonly ImagePickerHelper _imagePickerHelper; + private int imageNo; private string? entryText; private bool showAssistView; private bool showHeader = true; @@ -21,7 +27,43 @@ public class ChartViewModel : INotifyPropertyChanged private bool isLoading; private ObservableCollection messages = new(); + private bool isSendIconEnabled; + internal bool isResponseStreaming; + private double sendIconWidth; private ChartAIService openAIService = new(); + public double SendIconWidth + { + get { return sendIconWidth; } + set + { + sendIconWidth = value; + OnPropertyChanged(nameof(SendIconWidth)); + } + } + public bool IsSendIconEnabled + { + get + { + return isSendIconEnabled; + } + set + { + isSendIconEnabled = value; + OnPropertyChanged(nameof(IsSendIconEnabled)); + } + } + public string SendIconText + { + get + { + return sendIconText; + } + set + { + sendIconText = value; + OnPropertyChanged(nameof(SendIconText)); + } + } public string? EntryText { @@ -137,8 +179,36 @@ public ObservableCollection? ModelPrompts public ICommand AiButtonClicked { get; } public ICommand CloseButtonClicked { get; } public ICommand RefreshButtonClicked { get; } - public ICommand RequestCommand { get; } - + public ICommand RequestCommand { get; } + public Command EditorOptionsComamnd { get; set; } + public ObservableCollection