mirror of
https://github.com/maker-community/ElectronBot.DotNet.git
synced 2026-10-29 05:10:45 +08:00
添加表情编辑添加的功能
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 529 KiB |
@@ -10,6 +10,10 @@
|
||||
|
||||

|
||||
|
||||
表情编辑页包含表情视频的上传,表情的播放。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
目前的一些表盘如下图:
|
||||
|
||||
@@ -20,4 +20,19 @@ public class EmoticonAction
|
||||
{
|
||||
get; set;
|
||||
} = "";
|
||||
|
||||
public string EmojisVideoPath
|
||||
{
|
||||
get; set;
|
||||
} = "";
|
||||
public EmojisType EmojisType
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
public enum EmojisType
|
||||
{
|
||||
Default = 1,
|
||||
Custom = 2
|
||||
}
|
||||
@@ -54,35 +54,40 @@ public class Constants
|
||||
Name ="AngerName".GetLocalized(),
|
||||
NameId="anger",
|
||||
Avatar = "ms-appx:///Assets/Emoji/anger.png",
|
||||
Desc ="AngerName".GetLocalized()
|
||||
Desc ="AngerName".GetLocalized(),
|
||||
EmojisType = EmojisType.Default
|
||||
},
|
||||
new EmoticonAction()
|
||||
{
|
||||
Name ="DisdainName".GetLocalized(),
|
||||
NameId="disdain",
|
||||
Avatar = "ms-appx:///Assets/Emoji/disdain.png",
|
||||
Desc ="DisdainName".GetLocalized()
|
||||
Desc ="DisdainName".GetLocalized(),
|
||||
EmojisType = EmojisType.Default
|
||||
},
|
||||
new EmoticonAction()
|
||||
{
|
||||
Name ="ExcitedName".GetLocalized(),
|
||||
NameId="excited",
|
||||
Avatar = "ms-appx:///Assets/Emoji/excited.png",
|
||||
Desc ="ExcitedName".GetLocalized()
|
||||
Desc ="ExcitedName".GetLocalized(),
|
||||
EmojisType = EmojisType.Default
|
||||
},
|
||||
new EmoticonAction()
|
||||
{
|
||||
Name ="FearName".GetLocalized(),
|
||||
NameId="fear",
|
||||
Avatar = "ms-appx:///Assets/Emoji/fear.png",
|
||||
Desc ="FearName".GetLocalized()
|
||||
Desc ="FearName".GetLocalized(),
|
||||
EmojisType = EmojisType.Default
|
||||
},
|
||||
new EmoticonAction()
|
||||
{
|
||||
Name ="SadName".GetLocalized(),
|
||||
NameId="sad",
|
||||
Avatar = "ms-appx:///Assets/Emoji/sad.png",
|
||||
Desc ="SadName".GetLocalized()
|
||||
Desc ="SadName".GetLocalized(),
|
||||
EmojisType = EmojisType.Default
|
||||
}
|
||||
};
|
||||
public static readonly string TwitterConsumerKey = "";
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ElectronBot.BraincasePreview.Models;
|
||||
using Verdure.ElectronBot.Core.Models;
|
||||
|
||||
namespace ElectronBot.BraincasePreview.Contracts.Services;
|
||||
public interface IActionExpressionProvider
|
||||
@@ -13,5 +14,7 @@ public interface IActionExpressionProvider
|
||||
}
|
||||
Task PlayActionExpressionAsync(string actionName);
|
||||
|
||||
Task PlayActionExpressionAsync(EmoticonAction emoticonAction);
|
||||
|
||||
Task PlayActionExpressionAsync(string actionName, List<ElectronBotAction> actions);
|
||||
}
|
||||
|
||||
@@ -50,10 +50,15 @@
|
||||
<TextBox
|
||||
Width="280"
|
||||
Margin="4"
|
||||
Text="{x:Bind ViewModel.EmojisAvatar, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
IsReadOnly="True"
|
||||
Text="{x:Bind ViewModel.EmojisAvatar, Mode=OneWay}"
|
||||
TextWrapping="NoWrap" />
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button x:Uid="EmojisAvatarAddBtn" Command="{x:Bind ViewModel.AddEmojisAvatarCommand}">
|
||||
<FontIcon FontFamily="/Assets/Fonts/Segoe Fluent Icons.ttf#Segoe Fluent Icons" Glyph="" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock
|
||||
x:Uid="EmojisDesc"
|
||||
@@ -73,7 +78,7 @@
|
||||
Width="280"
|
||||
Margin="4"
|
||||
IsReadOnly="True"
|
||||
Text="{x:Bind ViewModel.EmojisVideoUrl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
Text="{x:Bind ViewModel.EmojisVideoUrl, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button x:Uid="EmojisVideoAddBtn" Command="{x:Bind ViewModel.AddEmojisVideoCommand}">
|
||||
|
||||
@@ -29,6 +29,9 @@ public sealed partial class AddEmojisContentDialog : ContentDialog
|
||||
public AddEmojisContentDialog()
|
||||
{
|
||||
ViewModel = App.GetService<AddEmojisDialogViewModel>();
|
||||
|
||||
DataContext = ViewModel;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
||||
+37
-2
@@ -1,10 +1,10 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using ElectronBot.BraincasePreview.Contracts.Services;
|
||||
using Verdure.ElectronBot.Core.Models;
|
||||
using ElectronBot.BraincasePreview.Helpers;
|
||||
using ElectronBot.BraincasePreview.Models;
|
||||
using ElectronBot.BraincasePreview.Services.EbotGrpcService;
|
||||
using OpenCvSharp;
|
||||
using Verdure.ElectronBot.Core.Models;
|
||||
using Windows.ApplicationModel;
|
||||
|
||||
namespace ElectronBot.BraincasePreview.Services;
|
||||
@@ -18,7 +18,6 @@ public class DefaultActionExpressionProvider : IActionExpressionProvider
|
||||
|
||||
var capture = new VideoCapture(Package.Current.InstalledLocation.Path + $"\\Assets\\Emoji\\{actionName}.mp4");
|
||||
|
||||
var frameCount = capture.FrameCount;
|
||||
while (true)
|
||||
{
|
||||
capture.Read(image);
|
||||
@@ -117,4 +116,40 @@ public class DefaultActionExpressionProvider : IActionExpressionProvider
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Task PlayActionExpressionAsync(EmoticonAction emoticonAction)
|
||||
{
|
||||
Mat image = new();
|
||||
|
||||
var capture = new VideoCapture(emoticonAction.EmojisVideoPath);
|
||||
|
||||
while (true)
|
||||
{
|
||||
capture.Read(image);
|
||||
|
||||
capture.Set(OpenCvSharp.VideoCaptureProperties.PosFrames,
|
||||
capture.Get(OpenCvSharp.VideoCaptureProperties.PosFrames) + 1);
|
||||
|
||||
if (image.Empty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//var mat1 = image.Resize(new OpenCvSharp.Size(240, 240), 0, 0, OpenCvSharp.InterpolationFlags.Lanczos4);
|
||||
|
||||
//var mat2 = mat1.CvtColor(OpenCvSharp.ColorConversionCodes.RGBA2BGR);
|
||||
|
||||
var dataMeta = image.Data;
|
||||
|
||||
var data = new byte[240 * 240 * 3];
|
||||
|
||||
Marshal.Copy(dataMeta, data, 0, 240 * 240 * 3);
|
||||
|
||||
EmojiPlayHelper.Current.Enqueue(new EmoticonActionFrame(data));
|
||||
}
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,6 +381,9 @@
|
||||
<data name="FearName" xml:space="preserve">
|
||||
<value>惊恐</value>
|
||||
</data>
|
||||
<data name="PlayEmojis.Text" xml:space="preserve">
|
||||
<value>播放表情</value>
|
||||
</data>
|
||||
<data name="SadName" xml:space="preserve">
|
||||
<value>难过</value>
|
||||
</data>
|
||||
|
||||
@@ -20,6 +20,9 @@ public class AddEmojisDialogViewModel : ObservableRecipient
|
||||
private ICommand _addEmojisVideoCommand;
|
||||
public ICommand AddEmojisVideoCommand => _addEmojisVideoCommand ??= new RelayCommand(AddEmojisVideo);
|
||||
|
||||
private ICommand _addEmojisAvatarCommand;
|
||||
public ICommand AddEmojisAvatarCommand => _addEmojisAvatarCommand ??= new RelayCommand(AddEmojisAvatar);
|
||||
|
||||
|
||||
private ICommand _openEmojisEditDialogCommand;
|
||||
public ICommand OpenEmojisEditDialogCommand => _openEmojisEditDialogCommand ??= new RelayCommand(EmojisEditDialogEmojis);
|
||||
@@ -27,15 +30,25 @@ public class AddEmojisDialogViewModel : ObservableRecipient
|
||||
private ICommand _saveEmojisCommand;
|
||||
public ICommand SaveEmojisCommand => _saveEmojisCommand ??= new RelayCommand(SaveEmojis);
|
||||
|
||||
public AddEmojisDialogViewModel()
|
||||
{
|
||||
}
|
||||
|
||||
public EmoticonAction EmoticonAction
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
private void SaveEmojis()
|
||||
{
|
||||
Actions.Add(new EmoticonAction()
|
||||
EmoticonAction = new EmoticonAction()
|
||||
{
|
||||
Avatar = EmojisAvatar,
|
||||
Desc = EmojisDesc,
|
||||
Name = EmojisName,
|
||||
NameId = EmojisNameId
|
||||
});
|
||||
NameId = EmojisNameId,
|
||||
EmojisVideoPath = EmojisVideoUrl,
|
||||
EmojisType = EmojisType.Custom
|
||||
};
|
||||
}
|
||||
|
||||
private async void EmojisEditDialogEmojis()
|
||||
@@ -52,7 +65,7 @@ public class AddEmojisDialogViewModel : ObservableRecipient
|
||||
};
|
||||
|
||||
addEmojisContentDialog.DataContextChanged += AddEmojisContentDialog_DataContextChanged;
|
||||
|
||||
|
||||
await addEmojisContentDialog.ShowAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
@@ -71,10 +84,6 @@ public class AddEmojisDialogViewModel : ObservableRecipient
|
||||
private string _emojisDesc;
|
||||
private string _mojisAvatar;
|
||||
private string _emojisVideoUrl;
|
||||
public AddEmojisDialogViewModel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private async void AddEmojisVideo()
|
||||
{
|
||||
@@ -110,6 +119,42 @@ public class AddEmojisDialogViewModel : ObservableRecipient
|
||||
EmojisVideoUrl = storageFile.Path;
|
||||
}
|
||||
|
||||
private async void AddEmojisAvatar()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(EmojisNameId))
|
||||
{
|
||||
ToastHelper.SendToast("请设置表情id", TimeSpan.FromSeconds(3));
|
||||
return;
|
||||
}
|
||||
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
|
||||
|
||||
var picker = new Windows.Storage.Pickers.FileOpenPicker
|
||||
{
|
||||
ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail,
|
||||
|
||||
SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary
|
||||
};
|
||||
|
||||
picker.FileTypeFilter.Add(".png");
|
||||
picker.FileTypeFilter.Add(".jpg");
|
||||
picker.FileTypeFilter.Add(".jpeg");
|
||||
|
||||
WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);
|
||||
|
||||
var file = await picker.PickSingleFileAsync();
|
||||
|
||||
var folder = ApplicationData.Current.LocalFolder;
|
||||
|
||||
var storageFolder = await folder.CreateFolderAsync(Constants.EmojisFolder, CreationCollisionOption.OpenIfExists);
|
||||
|
||||
var storageFile = await storageFolder
|
||||
.CreateFileAsync($"{EmojisNameId}.{file.FileType}", CreationCollisionOption.ReplaceExisting);
|
||||
|
||||
await FileIO.WriteBytesAsync(storageFile, await file.ReadBytesAsync());
|
||||
|
||||
EmojisAvatar = storageFile.Path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表情名称
|
||||
/// </summary>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Windows.Input;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using ElectronBot.BraincasePreview.Contracts.Services;
|
||||
using ElectronBot.BraincasePreview.Controls;
|
||||
using ElectronBot.BraincasePreview.Helpers;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
@@ -14,6 +15,8 @@ public class EmojisEditViewModel : ObservableRecipient
|
||||
{
|
||||
private ObservableCollection<EmoticonAction> _actions = new();
|
||||
|
||||
private readonly IActionExpressionProvider _actionExpressionProvider;
|
||||
|
||||
private ICommand _loadedCommand;
|
||||
public ICommand LoadedCommand => _loadedCommand ??= new RelayCommand(OnLoaded);
|
||||
|
||||
@@ -27,6 +30,48 @@ public class EmojisEditViewModel : ObservableRecipient
|
||||
private ICommand _saveEmojisCommand;
|
||||
public ICommand SaveEmojisCommand => _saveEmojisCommand ??= new RelayCommand(SaveEmojis);
|
||||
|
||||
private ICommand _playEmojisCommand;
|
||||
public ICommand PlayEmojisCommand => _playEmojisCommand ??= new RelayCommand<object>(PlayEmojis);
|
||||
|
||||
private string _mojisName;
|
||||
private string _mojisNameId;
|
||||
private string _emojisDesc;
|
||||
private string _mojisAvatar;
|
||||
private string _emojisVideoUrl;
|
||||
|
||||
|
||||
public EmojisEditViewModel(IActionExpressionProvider actionExpressionProvider)
|
||||
{
|
||||
_actionExpressionProvider = actionExpressionProvider;
|
||||
}
|
||||
|
||||
private void PlayEmojis(object? obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
ToastHelper.SendToast("请选中一个表情播放", TimeSpan.FromSeconds(3));
|
||||
return;
|
||||
}
|
||||
if (obj is EmoticonAction emojis)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (emojis.EmojisType == EmojisType.Default)
|
||||
{
|
||||
_actionExpressionProvider.PlayActionExpressionAsync(emojis.NameId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_actionExpressionProvider.PlayActionExpressionAsync(emojis);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveEmojis()
|
||||
{
|
||||
Actions.Add(new EmoticonAction()
|
||||
@@ -34,7 +79,8 @@ public class EmojisEditViewModel : ObservableRecipient
|
||||
Avatar = EmojisAvatar,
|
||||
Desc = EmojisDesc,
|
||||
Name = EmojisName,
|
||||
NameId = EmojisNameId
|
||||
NameId = EmojisNameId,
|
||||
EmojisType = EmojisType.Custom
|
||||
});
|
||||
}
|
||||
|
||||
@@ -51,8 +97,8 @@ public class EmojisEditViewModel : ObservableRecipient
|
||||
XamlRoot = App.MainWindow.Content.XamlRoot
|
||||
};
|
||||
|
||||
addEmojisContentDialog.DataContextChanged += AddEmojisContentDialog_DataContextChanged;
|
||||
|
||||
addEmojisContentDialog.Closed += AddEmojisContentDialog_Closed;
|
||||
|
||||
await addEmojisContentDialog.ShowAsync();
|
||||
}
|
||||
catch (Exception)
|
||||
@@ -61,18 +107,20 @@ public class EmojisEditViewModel : ObservableRecipient
|
||||
}
|
||||
}
|
||||
|
||||
private void AddEmojisContentDialog_DataContextChanged(Microsoft.UI.Xaml.FrameworkElement sender, Microsoft.UI.Xaml.DataContextChangedEventArgs args)
|
||||
private void AddEmojisContentDialog_Closed(ContentDialog sender, ContentDialogClosedEventArgs args)
|
||||
{
|
||||
var value = args.NewValue;
|
||||
}
|
||||
if (sender.DataContext is AddEmojisDialogViewModel viewModel)
|
||||
{
|
||||
if (viewModel is not null)
|
||||
{
|
||||
var emotion = viewModel.EmoticonAction;
|
||||
|
||||
private string _mojisName;
|
||||
private string _mojisNameId;
|
||||
private string _emojisDesc;
|
||||
private string _mojisAvatar;
|
||||
private string _emojisVideoUrl;
|
||||
public EmojisEditViewModel()
|
||||
{
|
||||
if (emotion is not null)
|
||||
{
|
||||
Actions.Add(emotion);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -60,11 +60,24 @@
|
||||
Grid.Row="1"
|
||||
CornerRadius="8"
|
||||
DesiredWidth="200"
|
||||
IsEnabled="True"
|
||||
IsItemClickEnabled="True"
|
||||
ItemTemplate="{StaticResource PhotosTemplate}"
|
||||
ItemsSource="{x:Bind ViewModel.Actions, Mode=OneWay}"
|
||||
OneRowModeEnabled="False"
|
||||
SelectionMode="Single"
|
||||
StretchContentForSingleRow="False" />
|
||||
StretchContentForSingleRow="False">
|
||||
<controls:AdaptiveGridView.ContextFlyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem x:Name="AddPic" x:Uid="PlayEmojis">
|
||||
<i:Interaction.Behaviors>
|
||||
<ic:EventTriggerBehavior EventName="Click">
|
||||
<ic:InvokeCommandAction Command="{x:Bind ViewModel.PlayEmojisCommand}" CommandParameter="{x:Bind AdaptiveGridViewControl.SelectedItem, Mode=TwoWay}" />
|
||||
</ic:EventTriggerBehavior>
|
||||
</i:Interaction.Behaviors>
|
||||
</MenuFlyoutItem>
|
||||
</MenuFlyout>
|
||||
</controls:AdaptiveGridView.ContextFlyout>
|
||||
</controls:AdaptiveGridView>
|
||||
</Grid>
|
||||
</Page>
|
||||
|
||||
Reference in New Issue
Block a user