Skip to content

Commit

Permalink
channelist ui overhaul
Browse files Browse the repository at this point in the history
now categories cant be clicked and look like categories
  • Loading branch information
exp111 committed Nov 24, 2023
1 parent 0b93a72 commit dbb54e9
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 49 deletions.
28 changes: 15 additions & 13 deletions Turbulence.Core/ViewModels/Design/DesignChannelListViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,15 @@ public class DesignChannelListViewModel : ChannelListViewModel
{
public DesignChannelListViewModel()
{
var text = new Channel()
{
Id = new(1),
Type = ChannelType.GUILD_TEXT,
Name = "Text"
};
Channels.AddRange(new List<Channel>()
{
new()
{
Id = new(0),
Type = ChannelType.GUILD_CATEGORY,
Name = "Category"
},
new()
{
Id = new(1),
Type = ChannelType.GUILD_TEXT,
Name = "Text"
},
text,
new()
{
Id = new(2),
Expand All @@ -34,10 +29,17 @@ public DesignChannelListViewModel()
},
new()
{
Id = new(3),
Id = new(0),
Type = ChannelType.GUILD_CATEGORY,
Name = "Category"
},
new()
{
Id = new(4),
Type = ChannelType.GUILD_ANNOUNCEMENT,
Name = "Announcement"
},
});
SelectedChannel = text;
}
}
26 changes: 26 additions & 0 deletions Turbulence.Desktop/Converters/ObjectEqualsConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Avalonia.Data.Converters;
using System.Globalization;

namespace Turbulence.Desktop.Converters;

public class ObjectEqualsMultiConverter : IMultiValueConverter
{
public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
{
if (values.Count == 0)
return true;

var val = values[0];
foreach (var item in values.Skip(1))
{
if (val != item)
return false;
}
return true;
}

public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
6 changes: 4 additions & 2 deletions Turbulence.Desktop/DataTemplates/ChannelTemplateSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ namespace Turbulence.Desktop.DataTemplates;

public class ChannelTemplateSelector : IDataTemplate
{
public bool SupportsRecycling => false;
[Content]
public Dictionary<string, IDataTemplate> Templates { get; } = new Dictionary<string, IDataTemplate>();

Expand All @@ -16,7 +15,10 @@ public class ChannelTemplateSelector : IDataTemplate
Control? ITemplate<object?, Control?>.Build(object? param)
{
var channel = (Channel)param!;
if (!Templates.TryGetValue(channel.Type.ToString(), out var template))
var type = "channel";
if (channel.Type == ChannelType.GUILD_CATEGORY)
type = "category";
if (!Templates.TryGetValue(type, out var template))
return Templates["unknown"].Build(param);
return template.Build(param);
}
Expand Down
22 changes: 22 additions & 0 deletions Turbulence.Desktop/DataTemplates/ChannelTypeTemplateSelector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Avalonia.Controls.Templates;
using Avalonia.Controls;
using Avalonia.Metadata;
using Turbulence.Discord.Models.DiscordChannel;

namespace Turbulence.Desktop.DataTemplates;

public class ChannelTypeTemplateSelector : IDataTemplate
{
[Content]
public Dictionary<string, IDataTemplate> Templates { get; } = new Dictionary<string, IDataTemplate>();

public bool Match(object? data) => data is Channel;

Control? ITemplate<object?, Control?>.Build(object? param)
{
var channel = (Channel)param!;
if (!Templates.TryGetValue(channel.Type.ToString(), out var template))
return Templates["unknown"].Build(param);
return template.Build(param);
}
}
102 changes: 68 additions & 34 deletions Turbulence.Desktop/Views/Main/ChannelListView.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:Turbulence.Core.ViewModels;assembly=Turbulence.Core"
xmlns:converters="using:Turbulence.Desktop.Converters"
xmlns:dataTemplates="using:Turbulence.Desktop.DataTemplates"
xmlns:channel="clr-namespace:Turbulence.Discord.Models.DiscordChannel;assembly=Turbulence.Discord"
x:Class="Turbulence.Desktop.Views.Main.ChannelListView"
Expand All @@ -11,45 +12,78 @@
<UserControl.DataContext>
<vm:ChannelListViewModel />
</UserControl.DataContext>
<ListBox ItemsSource="{Binding Channels}"
Background="#2B2D31"
SelectedValue="{Binding SelectedChannel}">
<ListBox.DataTemplates>
<UserControl.Resources>
<converters:ObjectEqualsMultiConverter x:Key="EqualsConverter" />
</UserControl.Resources>
<UserControl.Styles>
<Style Selector="ToggleButton">
<Setter Property="Background" Value="Transparent" />
</Style>
<Style Selector="ToggleButton:checked /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="#404249" />
</Style>
<Style Selector="TextBlock.Category">
<Setter Property="Margin" Value="0,10,0,0" />
<Setter Property="FontSize" Value="12" />
</Style>
</UserControl.Styles>
<ItemsControl ItemsSource="{Binding Channels}"
Background="#2B2D31">
<ItemsControl.DataTemplates>
<dataTemplates:ChannelTemplateSelector>
<DataTemplate x:Key="GUILD_TEXT" x:DataType="channel:Channel">
<Grid ColumnDefinitions="20,*">
<TextBlock Text="#" HorizontalAlignment="Center" />
<TextBlock Text="{Binding Name}" Grid.Column="1" Margin="5,0" />
</Grid>
<!--Channels that can be clicked-->
<DataTemplate x:Key="channel" x:DataType="channel:Channel">
<ToggleButton Click="ChannelSelected"
HorizontalAlignment="Stretch" Margin="4,1">
<ToggleButton.IsChecked>
<MultiBinding Converter="{StaticResource EqualsConverter}">
<Binding Path="$parent[ItemsControl].((vm:ChannelListViewModel)DataContext).SelectedChannel" />
<Binding Path="."/>
</MultiBinding>
</ToggleButton.IsChecked>
<Grid ColumnDefinitions="20,*">
<!--The icon-->
<ContentControl Content="{Binding}">
<ContentControl.DataTemplates>
<dataTemplates:ChannelTypeTemplateSelector>
<DataTemplate x:Key="GUILD_TEXT" x:DataType="channel:Channel">
<TextBlock Text="#" HorizontalAlignment="Center" />
</DataTemplate>
<DataTemplate x:Key="GUILD_VOICE" x:DataType="channel:Channel">
<TextBlock Text="&#x1F50A;" HorizontalAlignment="Center" />
</DataTemplate>
<DataTemplate x:Key="GUILD_ANNOUNCEMENT" x:DataType="channel:Channel">
<TextBlock Text="&#x1F4E3;" HorizontalAlignment="Center" />
</DataTemplate>
<DataTemplate x:Key="GUILD_STAGE_VOICE" x:DataType="channel:Channel">
<TextBlock Text="&#x1F399;" HorizontalAlignment="Center" />
</DataTemplate>
<DataTemplate x:Key="unknown" x:DataType="channel:Channel">
<TextBlock Text="#" Background="Red" HorizontalAlignment="Center" />
</DataTemplate>
</dataTemplates:ChannelTypeTemplateSelector>
</ContentControl.DataTemplates>
</ContentControl>
<!--Channel Name-->
<TextBlock Text="{Binding Name}" Grid.Column="1" Margin="5,0" />
</Grid>
</ToggleButton>
</DataTemplate>
<DataTemplate x:Key="GUILD_VOICE" x:DataType="channel:Channel">
<Grid ColumnDefinitions="20,*">
<TextBlock Text="&#x1F50A;" HorizontalAlignment="Center" />
<TextBlock Text="{Binding Name}" Grid.Column="1" Margin="5,0" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="GUILD_CATEGORY" x:DataType="channel:Channel">
<Grid ColumnDefinitions="20,*">
<TextBlock Text="&#x23F7;" HorizontalAlignment="Center" />
<TextBlock Text="{Binding Name}" Grid.Column="1" Margin="5,0" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="GUILD_ANNOUNCEMENT" x:DataType="channel:Channel">
<Grid ColumnDefinitions="20,*">
<TextBlock Text="&#x1F4E3;" HorizontalAlignment="Center" />
<TextBlock Text="{Binding Name}" Grid.Column="1" Margin="5,0" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="GUILD_STAGE_VOICE" x:DataType="channel:Channel">
<Grid ColumnDefinitions="20,*">
<TextBlock Text="&#x1F399;" HorizontalAlignment="Center" />
<TextBlock Text="{Binding Name}" Grid.Column="1" Margin="5,0" />
<!--Category-->
<DataTemplate x:Key="category" x:DataType="channel:Channel">
<Grid ColumnDefinitions="15,*">
<TextBlock Text="&#x23F7;" FontSize="11" VerticalAlignment="Bottom" />
<TextBlock Classes="Category" Text="{Binding Name}" Grid.Column="1" />
</Grid>
</DataTemplate>
<!--Default case-->
<DataTemplate x:Key="unknown" x:DataType="channel:Channel">
<TextBlock Background="Red" Text="{Binding Name, StringFormat='Unknown: {0}'}" />
<Grid ColumnDefinitions="20,*" Background="Red">
<TextBlock Text="UNKNOWN" HorizontalAlignment="Center" />
<TextBlock Text="{Binding Name}" Grid.Column="1" Margin="5,0" />
</Grid>
</DataTemplate>
</dataTemplates:ChannelTemplateSelector>
</ListBox.DataTemplates>
</ListBox>
</ItemsControl.DataTemplates>
</ItemsControl>
</UserControl>
22 changes: 22 additions & 0 deletions Turbulence.Desktop/Views/Main/ChannelListView.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using Turbulence.Core.ViewModels;
using Turbulence.Core.ViewModels.Design;
using Turbulence.Discord.Models.DiscordChannel;

namespace Turbulence.Desktop.Views.Main;

public partial class ChannelListView : UserControl
{
private ChannelListViewModel _vm;
public ChannelListView()
{
InitializeComponent();
Expand All @@ -13,5 +18,22 @@ public ChannelListView()
// Workaround to fix design data context getting overwritten
DataContext = new DesignChannelListViewModel();
}
_vm = (ChannelListViewModel)DataContext!;
}

//TODO: use a button with a "checked" class + command to do this
public void ChannelSelected(object sender, RoutedEventArgs e)
{
if (e.Source is ToggleButton control)
{
var dataContext = control.DataContext;
if (dataContext is Channel)
{
if (_vm.SelectedChannel != (Channel)dataContext)
_vm.SelectedChannel = (Channel)dataContext;
else
control.IsChecked = true;
}
}
}
}

0 comments on commit dbb54e9

Please sign in to comment.