Notes and Profile Pictures are now working, and Mother and Father selections are no longer just Ids
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.IO;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Data.Core;
|
||||
@@ -37,6 +38,8 @@ public partial class App : Application
|
||||
}
|
||||
|
||||
// Other init stuff here
|
||||
Directory.CreateDirectory(Sys.UserDataPath);
|
||||
Directory.CreateDirectory(Path.Combine(Sys.UserDataPath, "ImageCache"));
|
||||
|
||||
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
VerticalContentAlignment="Center"
|
||||
x:Name="MainButton">
|
||||
<Grid ColumnDefinitions="Auto, *, Auto">
|
||||
<Image x:Name="ProfileImage" Grid.Column="0" Width="80" Height="80" Stretch="UniformToFill" Source="avares://CritterFolio/Assets/Icon.png" />
|
||||
<Image x:Name="ProfileImage" Grid.Column="0" Width="75" Height="75" Stretch="UniformToFill" Source="avares://CritterFolio/Assets/Icon.png" />
|
||||
<Label x:Name="ProfileNameLabel" Grid.Column="1" VerticalAlignment="Center" FontSize="18" Margin="20, 0" />
|
||||
</Grid>
|
||||
</Button>
|
||||
|
||||
@@ -7,6 +7,7 @@ public class Document
|
||||
{
|
||||
[PrimaryKey, AutoIncrement]
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
public int CritterId { get; set; }
|
||||
public string Name { get; set; } = "Document";
|
||||
public string Description { get; set; } = "A Document";
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
<ScrollViewer HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<StackPanel Spacing="10">
|
||||
<Label Classes="heading1">Info</Label>
|
||||
<Image x:Name="ProfImage" Width="150" Height="150" Stretch="UniformToFill" Source="avares://CritterFolio/Assets/Icon.png" />
|
||||
<StackPanel HorizontalAlignment="Stretch">
|
||||
<Label VerticalAlignment="Center">Name: </Label>
|
||||
<TextBox x:Name="NameBox" />
|
||||
@@ -27,6 +28,13 @@
|
||||
<Label VerticalAlignment="Center">Father: </Label>
|
||||
<ComboBox x:Name="FatherPicker" />
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Stretch">
|
||||
<Label VerticalAlignment="Center">Notes: </Label>
|
||||
<TextBox x:Name="NotesBox" MinHeight="100" AcceptsReturn="True" TextWrapping="Wrap" />
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<Button x:Name="PfpButton">Choose Profile Picture</Button>
|
||||
</StackPanel>
|
||||
<!-- <Button x:Name="AddButton" Classes="icon" HorizontalAlignment="Stretch"></Button> -->
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Avalonia;
|
||||
@@ -7,6 +8,8 @@ using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Avalonia.Platform.Storage;
|
||||
using Avalonia.Threading;
|
||||
using CritterFolio.DataModels;
|
||||
using CritterFolio.Services;
|
||||
@@ -16,6 +19,7 @@ namespace CritterFolio.Pages;
|
||||
public partial class CritterPage : Page
|
||||
{
|
||||
private Critter? _critter;
|
||||
private List<CritterComboBoxDisplay> _critterDisplays = [];
|
||||
|
||||
public CritterPage()
|
||||
{
|
||||
@@ -26,31 +30,37 @@ public partial class CritterPage : Page
|
||||
{
|
||||
_critter = critter;
|
||||
|
||||
UpdateInfo();
|
||||
PfpButton.Click += OpenFileButton_Clicked;
|
||||
}
|
||||
|
||||
public override void Refresh()
|
||||
public override async void Refresh()
|
||||
{
|
||||
base.Refresh();
|
||||
CreateHeaderButtons();
|
||||
GenderOption.ItemsSource = Enum.GetNames(typeof(Gender));
|
||||
|
||||
LoadComboItemsAsync();
|
||||
await UpdateInfo();
|
||||
}
|
||||
|
||||
private async void LoadComboItemsAsync()
|
||||
private async Task LoadComboItemsAsync()
|
||||
{
|
||||
_critterDisplays.Clear();
|
||||
_critterDisplays.Add(new CritterComboBoxDisplay(0, "Not set"));
|
||||
|
||||
try
|
||||
{
|
||||
var allCritters = await DatabaseService.GetAllCritters();
|
||||
var allCritterIds = allCritters.Select(c => c.Id).ToList();
|
||||
|
||||
foreach (var critter in allCritters)
|
||||
{
|
||||
if (critter.Id == _critter?.Id) continue;
|
||||
_critterDisplays.Add(new CritterComboBoxDisplay(critter.Id, critter.Name));
|
||||
}
|
||||
|
||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
FatherPicker.ItemsSource = allCritterIds;
|
||||
MotherPicker.ItemsSource = allCritterIds;
|
||||
|
||||
UpdateInfo();
|
||||
FatherPicker.ItemsSource = _critterDisplays;
|
||||
MotherPicker.ItemsSource = _critterDisplays;
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -59,15 +69,64 @@ public partial class CritterPage : Page
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateInfo()
|
||||
private async Task UpdateInfo()
|
||||
{
|
||||
if (_critter is null) return;
|
||||
|
||||
Sys.Navigation?.SetTitle(_critter.Name);
|
||||
|
||||
await LoadComboItemsAsync();
|
||||
|
||||
NameBox.Text = _critter.Name;
|
||||
GenderOption.SelectedItem = Enum.GetName(typeof(Gender), _critter.Gender);
|
||||
BirthdayPicker.SelectedDate = _critter.DateOfBirth;
|
||||
MotherPicker.SelectedItem = _critter.FatherId;
|
||||
FatherPicker.SelectedItem = _critter.FatherId;
|
||||
|
||||
if (_critter.FatherId != 0)
|
||||
{
|
||||
var father = _critterDisplays.FirstOrDefault(c => c.Id == _critter.FatherId);
|
||||
if (father is null)
|
||||
{
|
||||
Logger.LogToFile($"Couldn't find father id: {_critter.FatherId}");
|
||||
await DialogHelper.ShowMessage($"ERROR: Couldn't find FatherID: {_critter.FatherId}");
|
||||
return;
|
||||
}
|
||||
FatherPicker.SelectedItem = father;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatherPicker.SelectedItem = _critterDisplays.FirstOrDefault(c => c.Id == 0);
|
||||
}
|
||||
|
||||
if (_critter.MotherId != 0)
|
||||
{
|
||||
var mother = _critterDisplays.FirstOrDefault(c => c.Id == _critter.MotherId);
|
||||
if (mother is null)
|
||||
{
|
||||
Logger.LogToFile($"[ERROR] Couldn't find MotherId: {_critter.MotherId}");
|
||||
await DialogHelper.ShowMessage($"ERROR: Couldn't find MotherId: {_critter.MotherId}");
|
||||
return;
|
||||
}
|
||||
MotherPicker.SelectedItem = mother;
|
||||
}
|
||||
else
|
||||
{
|
||||
MotherPicker.SelectedItem = _critterDisplays.FirstOrDefault(c => c.Id == 0);
|
||||
}
|
||||
|
||||
NotesBox.Text = _critter.Notes;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_critter.ProfileImagePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
var bmp = new Bitmap(_critter.ProfileImagePath);
|
||||
ProfImage.Source = bmp;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine($"Pfp image for {_critter.Id} was moved, deleted, or is corrupt.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateHeaderButtons()
|
||||
@@ -86,14 +145,13 @@ public partial class CritterPage : Page
|
||||
Classes = { "headerBttn" },
|
||||
Content = "\ue4a6"
|
||||
};
|
||||
delBttn.Foreground = new SolidColorBrush(Colors.DarkRed);
|
||||
delBttn.Foreground = new SolidColorBrush(Colors.Red);
|
||||
delBttn.Click += DeleteButtonClicked;
|
||||
Sys.Navigation?.AddHeaderButton(delBttn);
|
||||
}
|
||||
|
||||
private async void DeleteButtonClicked(object? sender, RoutedEventArgs args)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
var result = await DialogHelper.ShowConfirmationDialog("Are you sure you want to delete this critter?");
|
||||
@@ -125,7 +183,7 @@ public partial class CritterPage : Page
|
||||
}
|
||||
|
||||
await DatabaseService.UpdateCritter(_critter);
|
||||
UpdateInfo();
|
||||
await UpdateInfo();
|
||||
|
||||
await DialogHelper.ShowMessage($"Critter '{_critter.Name}' saved!");
|
||||
}
|
||||
@@ -164,28 +222,81 @@ public partial class CritterPage : Page
|
||||
errString += "Birthday is invalid somehow. Please report this to the developer\n";
|
||||
}
|
||||
|
||||
// Dont need to validate these yet, as they are not required
|
||||
// // Father ID validation
|
||||
// if (FatherPicker.SelectedItem is int fatherId)
|
||||
// {
|
||||
// _critter.FatherId = fatherId;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// errString += "FatherId is null or invalid somehow. Please report this to the developer\n";
|
||||
// }
|
||||
//
|
||||
// // Mother ID validation
|
||||
// if (MotherPicker.SelectedItem is int motherId)
|
||||
// {
|
||||
// _critter.MotherId = motherId;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// errString += "MotherId is null or invalid somehow. Please report this to the developer\n";
|
||||
// }
|
||||
// TODO: Change the way that fatherid and motherid work, it should show names, not the ids, but still link back to the id
|
||||
// Father ID validation
|
||||
if (FatherPicker.SelectedItem is CritterComboBoxDisplay father)
|
||||
{
|
||||
var id = _critterDisplays.FirstOrDefault(d => d.Id == father.Id);
|
||||
_critter.FatherId = id?.Id ?? 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_critter.FatherId = 0;
|
||||
}
|
||||
|
||||
// Mother ID validation
|
||||
if (MotherPicker.SelectedItem is CritterComboBoxDisplay mother)
|
||||
{
|
||||
var id = _critterDisplays.FirstOrDefault(d => d.Id == mother.Id);
|
||||
_critter.MotherId = id?.Id ?? 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_critter.MotherId = 0;
|
||||
}
|
||||
|
||||
if (_critter.MotherId == _critter.FatherId && _critter.MotherId > 0 && _critter.FatherId > 0)
|
||||
{
|
||||
errString += "Mother and Father cannot be the same";
|
||||
}
|
||||
|
||||
_critter.Notes = NotesBox.Text ?? "";
|
||||
|
||||
return errString != "" ? (false, errString) : (true, "No errors");
|
||||
}
|
||||
|
||||
private class CritterComboBoxDisplay(int id, string name)
|
||||
{
|
||||
public int Id { get; set; } = id;
|
||||
public string Name { get; set; } = name;
|
||||
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
|
||||
private async void OpenFileButton_Clicked(object? sender, RoutedEventArgs args)
|
||||
{
|
||||
var topLevel = TopLevel.GetTopLevel(this);
|
||||
|
||||
var files = await topLevel.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
|
||||
{
|
||||
Title = "Open Image File",
|
||||
AllowMultiple = false,
|
||||
FileTypeFilter = [new FilePickerFileType("image"){Patterns = ["*.png", "*.jpg", "*.jpeg"]}]
|
||||
});
|
||||
|
||||
if (files.Count == 0) return;
|
||||
|
||||
var file = files[0];
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
await using var stream = await file.OpenReadAsync();
|
||||
// using var streamReader = new StreamReader(stream);
|
||||
// var fileContent = await streamReader.ReadToEndAsync();
|
||||
|
||||
var bmp = new Bitmap(stream);
|
||||
var path = Path.Combine(Sys.UserDataPath, "ImageCache", $"{_critter.Id}-{_critter.Name}.jpg");
|
||||
bmp.Save(path);
|
||||
_critter.ProfileImagePath = path;
|
||||
await UpdateInfo();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await DialogHelper.ShowMessage(e.ToString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user