Skip to content

Commit

Permalink
CollectionView
Browse files Browse the repository at this point in the history
  • Loading branch information
danzuep committed Nov 30, 2023
1 parent 9fc23b4 commit b6c224a
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 191 deletions.
52 changes: 32 additions & 20 deletions Bible.App/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@
<Picker
x:Name="bibleBookPicker"
ItemDisplayBinding="{Binding Name, Mode=OneWay}"
ItemsSource="{Binding Bible.Books, Mode=OneWay}"
ItemsSource="{Binding Bible, Mode=OneWay}"
SelectedIndex="{Binding BookIndex, Mode=TwoWay}"
SelectedItem="{Binding SelectedBook, Mode=TwoWay}"
WidthRequest="160">
<Picker.Behaviors>
<mct:EventToCommandBehavior Command="{Binding BookSelectedCommand}" EventName="SelectedIndexChanged" />
</Picker.Behaviors>
</Picker>
SelectedIndexChanged="OnBookSelectionChanged"
WidthRequest="160" />
<Picker
x:Name="bibleChapterPicker"
ItemsSource="{Binding SelectedBook.ChapterNumbers, Mode=OneWay}"
ItemDisplayBinding="{Binding Id, Mode=OneWay}"
ItemsSource="{Binding Source={x:Reference bibleBookPicker}, Path=SelectedItem, Mode=OneWay}"
SelectedIndex="{Binding ChapterIndex, Mode=TwoWay}"
WidthRequest="70">
<Picker.Behaviors>
<mct:EventToCommandBehavior Command="{Binding ChapterSelectedCommand}" EventName="SelectedIndexChanged" />
</Picker.Behaviors>
</Picker>
SelectedIndexChanged="OnChapterSelectionChanged"
WidthRequest="70" />
<Picker
x:Name="bibleVersePicker"
ItemDisplayBinding="{Binding Id, Mode=OneWay}"
ItemsSource="{Binding Source={x:Reference bibleChapterPicker}, Path=SelectedItem, Mode=OneWay}"
SelectedIndexChanged="OnVerseSelectionChanged"
WidthRequest="70" />
<Picker
x:Name="bibleTranslationPicker"
ItemsSource="{Binding Translations, Mode=OneTime}"
Expand All @@ -55,21 +55,28 @@
<CollectionView
x:Name="collectionView"
IsGrouped="true"
ItemsSource="{Binding SelectedBook, Mode=OneWay}">
ItemsSource="{Binding Source={x:Reference bibleBookPicker}, Path=SelectedItem, Mode=OneWay}"
Scrolled="OnCollectionViewScrolled">
<CollectionView.GroupHeaderTemplate>
<DataTemplate x:DataType="m:ChapterUiModel">
<Label
FontAttributes="Bold"
FontSize="18"
Text="{Binding Path=Id, StringFormat='Chapter {0}'}"
TextColor="LightGray" />
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<CollectionView.ItemsLayout>
<LinearItemsLayout
ItemSpacing="5"
Orientation="Vertical"
SnapPointsAlignment="Start"
SnapPointsType="MandatorySingle" />
<LinearItemsLayout ItemSpacing="5" Orientation="Vertical" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="m:VerseUiModel">
<Grid ColumnDefinitions="15,*">
<Label
FontSize="8"
HorizontalTextAlignment="End"
Text="{Binding Id, Mode=OneWay}" />
Text="{Binding Id, Mode=OneWay}"
TextColor="LightGray" />
<!-- TODO - Hanzi jyutping ruby characters, like furigana -->
<Label
x:Name="VerseTextLabel"
Expand All @@ -80,6 +87,11 @@
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.GroupFooterTemplate>
<DataTemplate x:DataType="m:ChapterUiModel">
<Label Text="{Binding Path=Copyright, StringFormat='© {0}'}" TextColor="Gray" />
</DataTemplate>
</CollectionView.GroupFooterTemplate>
</CollectionView>
<Grid.GestureRecognizers>
<SwipeGestureRecognizer Direction="Left" Swiped="OnSwipeLeft" />
Expand Down
28 changes: 26 additions & 2 deletions Bible.App/MainPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using BibleApp.ViewModels;
using BibleApp.Models;
using BibleApp.ViewModels;
using CommunityToolkit.Mvvm.DependencyInjection;

namespace BibleApp
Expand All @@ -20,9 +21,32 @@ protected override void OnAppearing()
bibleChapterPicker.Focus();
}

private void OnBookSelectionChanged(object sender, EventArgs e)
{
_viewModel.ChapterIndex = 0;
}

private void OnChapterSelectionChanged(object sender, EventArgs e)
{
if (sender is Picker picker && picker.SelectedItem is ChapterUiModel chapter && chapter.Id > 0 && _viewModel.ChapterIndex >= 0)
collectionView.ScrollTo(0, chapter.Id - 1, position: ScrollToPosition.Start, animate: true);
}

private void OnVerseSelectionChanged(object sender, EventArgs e)
{
if (sender is Picker picker && picker.SelectedItem is VerseUiModel verse)
collectionView.ScrollTo(verse.Id - 1, _viewModel.ChapterIndex, position: ScrollToPosition.Center, animate: true);
}

private void OnCollectionViewScrolled(object sender, ItemsViewScrolledEventArgs e)
{
if (e.FirstVisibleItemIndex != 0)
_viewModel.ChapterIndex = -1;
}

private void OnSwipeLeft(object sender, SwipedEventArgs e)
{
if (_viewModel.SelectedBook?.Count > bibleChapterPicker.SelectedIndex + 1)
if (_viewModel.Bible?[_viewModel.BookIndex]?.Count > bibleChapterPicker.SelectedIndex + 1)
bibleChapterPicker.SelectedIndex++;
}

Expand Down
23 changes: 11 additions & 12 deletions Bible.App/Models/BibleUiModel.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.ObjectModel;

namespace BibleApp.Models
{
public sealed partial class BibleUiModel : ObservableObject
public sealed partial class BibleUiModel : List<BookUiModel>
{
//[ObservableProperty]
//private string translation = default!;

//[ObservableProperty]
//private IList<BookUiModel> books = new List<BookUiModel>();
public string Translation { get; } = default!;

public string Translation { get; set; } = default!;
public BibleUiModel(string translation) : base(new List<BookUiModel>())
{
Translation = translation;
}

public ObservableCollection<BookUiModel> Books { get; set; } = new();
public BibleUiModel(List<BookUiModel> books, string translation) : base(books)
{
Translation = translation;
}

public override string ToString() =>
$"Bible: {Translation} ({Books.Count} books)";
$"Bible: {Translation} ({this.Count} books)";
}
}
49 changes: 18 additions & 31 deletions Bible.App/Models/BookUiModel.cs
Original file line number Diff line number Diff line change
@@ -1,46 +1,33 @@
using Bible.Reader.Models;
using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.ObjectModel;

namespace BibleApp.Models
{
public sealed partial class BookUiModel : ObservableObject
[ObservableObject]
public sealed partial class BookUiModel : List<ChapterUiModel>
{
//[ObservableProperty]
//private int id;
public int Id { get; }

//[ObservableProperty]
//private string name = default!;
public string Name { get; } = default!;

//[ObservableProperty]
//private IList<ChapterUiModel> chapters = new List<ChapterUiModel>();
public ObservableCollection<int> ChapterNumbers { get; }

public int Id { get; set; }

public string Name { get; set; } = default!;

public ObservableCollection<ChapterUiModel> Chapters { get; set; } = new();


private int _chapterCount = 1;
public int ChapterCount
public BookUiModel(int id, string name, int chapterCount) : base(new List<ChapterUiModel>())
{
get => _chapterCount;
init
{
if (SetProperty(ref _chapterCount, value))
{
_chapterNumbers = new(ParallelEnumerable.Range(1, _chapterCount));
OnPropertyChanged(nameof(ChapterNumbers));
}
}
Id = id;
Name = name;
ChapterNumbers = new(Enumerable.Range(1, chapterCount));
}

Lazy<IEnumerable<int>>? _chapterNumbers;

public ObservableCollection<int> ChapterNumbers =>
new(_chapterNumbers?.Value ?? [1]);

public BookUiModel(List<ChapterUiModel> chapters, int id, string name) : base(chapters)
{
Id = id;
Name = name;
ChapterNumbers = new(Enumerable.Range(1, chapters.Count));
}

public override string ToString() =>
$"Book #{Id}, {Name} ({ChapterCount} chapters)";
$"Book #{Id}, {Name} ({this.Count} chapters)";
}
}
23 changes: 12 additions & 11 deletions Bible.App/Models/ChapterUiModel.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
using CommunityToolkit.Mvvm.ComponentModel;
using System.Collections.ObjectModel;

namespace BibleApp.Models
{
public sealed partial class ChapterUiModel : ObservableObject
public sealed partial class ChapterUiModel : List<VerseUiModel>
{
//[ObservableProperty]
//private int id;
public int Id { get; }

//[ObservableProperty]
//private IList<VerseUiModel> verses = new List<VerseUiModel>();
public string? Copyright { get; set; }

public int Id { get; set; }
public ChapterUiModel(int id) : base(new List<VerseUiModel>())
{
Id = id;
}

public ObservableCollection<VerseUiModel> Verses { get; set; } = new();
public ChapterUiModel(List<VerseUiModel> verses, int id) : base(verses)
{
Id = id;
}

public override string ToString() =>
$"Chapter {Id} ({Verses.Count} verses)";
$"Chapter {Id} ({this.Count} verses)";
}
}
21 changes: 8 additions & 13 deletions Bible.App/Models/VerseUiModel.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
using CommunityToolkit.Mvvm.ComponentModel;

namespace BibleApp.Models
{
public sealed partial class VerseUiModel : ObservableObject
public sealed partial class VerseUiModel
{
//[ObservableProperty]
//private bool isSelected;

//[ObservableProperty]
//private int id;

//[ObservableProperty]
//private string text = default!;
public int Id { get; }

public int Id { get; set; }
public string Text { get; }

public string Text { get; set; } = default!;
public VerseUiModel(int id, string text)
{
Id = id;
Text = text;
}

public override string ToString() =>
$"{Id} {Text}";
Expand Down
58 changes: 7 additions & 51 deletions Bible.App/Services/BibleUiData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,72 +15,28 @@ public BibleUiModel Load(string fileName, string suffix = ".xml")
return GetBible(_bible, translation);
}

public BibleUiModel LoadMock(BibleModel bible, string translation)
{
var bibleModel = new BibleUiModel() { Translation = translation };
if (bible != null)
{
foreach (var book in bible.Books)
{
var bibleBook = new BookUiModel
{
Id = book.Id,
Name = book.Reference.BookName,
ChapterCount = book.ChapterCount
};
bibleModel.Books.Add(bibleBook);
}
}
return bibleModel;
}

private static ChapterUiModel GetChapter(BibleModel? bible, byte bookIndex, byte chapterIndex)
{
var bibleChapter = new ChapterUiModel { Id = chapterIndex + 1 };
if (bible != null)
{
foreach (var verse in bible.Books[bookIndex].Chapters[chapterIndex].Verses)
{
var bibleVerse = new VerseUiModel { Id = verse.Id, Text = verse.Text };
bibleChapter.Verses.Add(bibleVerse);
}
}
return bibleChapter;
}

public static ChapterUiModel? GetChapter(BibleUiModel? bible, byte bookIndex, byte chapterIndex) =>
bible?.Books[bookIndex].Chapters[chapterIndex];

public ChapterUiModel? GetChapter(byte bookIndex, byte chapterIndex) =>
GetChapter(_bible, bookIndex, chapterIndex);

public static BibleUiModel GetBible(BibleModel? bible, string translation, bool addChapters = true)
{
var bibleModel = new BibleUiModel() { Translation = translation };
var bibleModel = new BibleUiModel(translation);
if (bible != null)
{
foreach (var book in bible.Books)
{
var bibleBook = new BookUiModel
{
Id = book.Id,
Name = book.Reference.BookName,
ChapterCount = book.ChapterCount
};
var bibleBook = new BookUiModel(book.Id, book.Reference.BookName, book.ChapterCount);
if (addChapters)
{
foreach (var chapter in book.Chapters)
{
var bibleChapter = new ChapterUiModel { Id = chapter.Id };
var bibleChapter = new ChapterUiModel(chapter.Id) { Copyright = translation };
foreach (var verse in chapter.Verses)
{
var bibleVerse = new VerseUiModel { Id = verse.Id, Text = verse.Text };
bibleChapter.Verses.Add(bibleVerse);
var bibleVerse = new VerseUiModel(verse.Id, verse.Text);
bibleChapter.Add(bibleVerse);
}
bibleBook.Chapters.Add(bibleChapter);
bibleBook.Add(bibleChapter);
}
}
bibleModel.Books.Add(bibleBook);
bibleModel.Add(bibleBook);
}
}
return bibleModel;
Expand Down
Loading

0 comments on commit b6c224a

Please sign in to comment.