diff --git a/Resources/CharacterGroupIcon.png b/Resources/CharacterGroupIcon.png new file mode 100644 index 0000000..8ffb1ba Binary files /dev/null and b/Resources/CharacterGroupIcon.png differ diff --git a/Resources/Max.png b/Resources/Max.png index 16f8df5..412cb09 100644 Binary files a/Resources/Max.png and b/Resources/Max.png differ diff --git a/Source/Cut5/MainHUD.cpp b/Source/Cut5/MainHUD.cpp index 1802464..25e7332 100644 --- a/Source/Cut5/MainHUD.cpp +++ b/Source/Cut5/MainHUD.cpp @@ -31,5 +31,5 @@ AMainHUD::AMainHUD() AMainHUD::~AMainHUD() { - FCutButtonStyle::Shutdown(); + // FCutButtonStyle::Shutdown(); } diff --git a/Source/Cut5/Utils/Utils.cpp b/Source/Cut5/Utils/Utils.cpp index 2a02661..aca9954 100644 --- a/Source/Cut5/Utils/Utils.cpp +++ b/Source/Cut5/Utils/Utils.cpp @@ -87,68 +87,38 @@ void FUtils::CreateDefaultTimelineSave(const FString& SavedPath, const FTimeline void FUtils::TrackEncodeVideo(const FTrackData& TrackData, const FString& ExportPath) { - if (TrackData.ClipData.Num() == 0) - return; - - AVFormatContext *outctx = NULL; - AVStream *outstream = NULL; - AVCodecContext *outcodecctx = NULL; - AVCodec *outcodec = NULL; - - avformat_alloc_output_context2(&outctx, NULL, NULL, "output.mp4"); - outcodec = avcodec_find_encoder(AV_CODEC_ID_H264); - outstream = avformat_new_stream(outctx, outcodec); - outcodecctx = avcodec_alloc_context3(outcodec); - TArray ClipData = TrackData.ClipData; ClipData.Sort([](const FClipData& A, const FClipData& B) {return A.ClipStartFrame < B.ClipStartFrame; }); - // 对于每个AVFrame - AVFrame *frame = NULL; - - - - + int32 i = 0; for (FClipData& TempClipData : ClipData) { - // 先从 ClipData 中读取这个 Clip 的视频数据。 if (TempClipData.ResourcePropertyDataPtr->Context) { FTimespan EndTimespan = FTimespan::FromSeconds(TempClipData.VideoEndFrame / FGlobalData::GlobalFPS); FTimespan StartTimespan = FTimespan::FromSeconds(TempClipData.VideoStartFrame / FGlobalData::GlobalFPS); - FString StartTime = FString::Printf(TEXT("%02d:%02d:%02d"), StartTimespan.GetHours(), StartTimespan.GetMinutes(), StartTimespan.GetSeconds()); FString EndTime = FString::Printf(TEXT("%02d:%02d:%02d"), EndTimespan.GetHours(), EndTimespan.GetMinutes(), EndTimespan.GetSeconds()); FString InputFile = TempClipData.ResourcePropertyDataPtr->MoviePath; - FString OutputFile = FPaths::ConvertRelativePathToFull((FPaths::Combine(FPaths::ProjectDir(), TEXT("output.mp4")))); + // 给定一个路径,创建所有不存在的文件夹 + FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*(ExportPath / FString::FromInt(i))); + + FString OutputFile = FPaths::ConvertRelativePathToFull(ExportPath / FString::FromInt(i) + TEXT(".mp4")); + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, OutputFile); int32 StartFrame = (TempClipData.VideoStartFrame) % static_cast(FGlobalData::GlobalFPS);; int32 EndFrame = (TempClipData.VideoEndFrame) % static_cast(FGlobalData::GlobalFPS); - // - // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("StartFrame: %d, EndFrame: %d"), StartFrame, EndFrame)); - // //输出文件名字 - // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("OutputFile: %s"), *OutputFile)); - // //输入文件名字 - // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("InputFile: %s"), *InputFile)); - // //开始时间 - // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("StartTime: %s"), *StartTime)); - // //结束时间 - // GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FString::Printf(TEXT("EndTime: %s"), *EndTime)); - // 构造FFmpeg命令 + FString Command = FString::Printf(TEXT("-y -i %s -ss %s -to %s -c copy %s"), *InputFile, *StartTime, *EndTime, *OutputFile); - FString FFmpegPath = FPaths::ConvertRelativePathToFull(FPaths::ProjectDir() / TEXT("Binaries") / TEXT("Win64") / TEXT("ffmpeg.exe")); - GEngine->AddOnScreenDebugMessage(-1, 10.0f, FColor::Red, FFmpegPath + " " + FString::Printf(TEXT("%s"), *Command)); - // FFmpeg的路径,需要根据实际情况修改 - - // 创建进程 - FPlatformProcess::CreateProc(*FFmpegPath, *Command, true, false, false, nullptr, 0, nullptr, nullptr); + FPlatformProcess::CreateProc(*GetFfmepg(), *Command, true, false, false, nullptr, 0, nullptr, nullptr); } + i++; } @@ -169,6 +139,11 @@ void FUtils::TrackEncodeVideo(const FTrackData& TrackData, const FString& Export } +FString FUtils::GetFfmepg() +{ + return FPaths::ConvertRelativePathToFull(FPaths::ProjectDir() / TEXT("Binaries") / TEXT("Win64") / TEXT("ffmpeg.exe")); +} + FSaveModifier::FSaveModifier(const FString& FullSavedPath) { diff --git a/Source/Cut5/Utils/Utils.h b/Source/Cut5/Utils/Utils.h index d071920..74fbc5b 100644 --- a/Source/Cut5/Utils/Utils.h +++ b/Source/Cut5/Utils/Utils.h @@ -56,6 +56,12 @@ public: .SetNormal(FSlateImageBrush(*FUtils::GetResourcesPath("CurtainNormal.png", true), FVector2D(257, 32), FLinearColor(42.0f /255, 42.0f /255, 42.0f /255, 1.0f))) .SetHovered(FSlateBoxBrush(*FUtils::GetResourcesPath("CurtainHover.png", true), FMargin(1.0), FLinearColor(46.0 /255,48.0/255,54.0/255,1.0f))) .SetPressed(FSlateBoxBrush(*FUtils::GetResourcesPath("CurtainSelected.png", true), FMargin(1.0), FLinearColor(88.0/255,96.0/255,121.0/255,1.0f))); + + + static FString GetFfmepg(); + + + }; class FSaveModifier diff --git a/Source/Cut5/Widgets/FX/SEffectCardGroup.cpp b/Source/Cut5/Widgets/FX/SEffectCardGroup.cpp index ec45928..2fd349c 100644 --- a/Source/Cut5/Widgets/FX/SEffectCardGroup.cpp +++ b/Source/Cut5/Widgets/FX/SEffectCardGroup.cpp @@ -361,8 +361,8 @@ void SEffectCardGroup::CallRender() }) ] + SOverlay::Slot() - .HAlign(HAlign_Fill) - .VAlign(VAlign_Fill) + .HAlign(HAlign_Center) + .VAlign(VAlign_Center) [ SNew(SBox) .WidthOverride(32) diff --git a/Source/Cut5/Widgets/Presets/SEffectPreset.cpp b/Source/Cut5/Widgets/Presets/SEffectPreset.cpp index fa7a26d..f9339e2 100644 --- a/Source/Cut5/Widgets/Presets/SEffectPreset.cpp +++ b/Source/Cut5/Widgets/Presets/SEffectPreset.cpp @@ -5,6 +5,7 @@ #include "SlateOptMacros.h" #include "Cut5/Utils/Utils.h" +#include "Cut5/Widgets/Style/CutButtonWidgetStyle.h" #include "Widgets/Input/SComboBox.h" BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION @@ -33,8 +34,8 @@ void SEffectPreset::Construct(const FArguments& InArgs) ChildSlot [ SNew(SBox) - .WidthOverride(76) - .HeightOverride(76) + .WidthOverride(80) + .HeightOverride(80) .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) .Padding(2) @@ -45,6 +46,7 @@ void SEffectPreset::Construct(const FArguments& InArgs) .VAlign(VAlign_Fill) [ SNew(SButton) + .ButtonStyle(FCutButtonStyle::Get(), "Preset.PresetButton") .ClickMethod(EButtonClickMethod::MouseDown) .OnClicked_Lambda([this]() { diff --git a/Source/Cut5/Widgets/SCustomInputPanel.cpp b/Source/Cut5/Widgets/SCustomInputPanel.cpp index b2d1799..82a65b2 100644 --- a/Source/Cut5/Widgets/SCustomInputPanel.cpp +++ b/Source/Cut5/Widgets/SCustomInputPanel.cpp @@ -172,9 +172,13 @@ void SCustomInputPanel::Construct(const FArguments& InArgs) + SWidgetSwitcher::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Fill) - .Padding(16, 0, 0, 0) + .Padding(8, 13, 0, 0) [ - SAssignNew(EffectGridPanel, SGridPanel) + SNew(SScrollBox) + + SScrollBox::Slot() + [ + SAssignNew(EffectGridPanel, SGridPanel) + ] ] + SWidgetSwitcher::Slot() .HAlign(HAlign_Fill) diff --git a/Source/Cut5/Widgets/SCutMainWindow.cpp b/Source/Cut5/Widgets/SCutMainWindow.cpp index 7e216a1..1b058c5 100644 --- a/Source/Cut5/Widgets/SCutMainWindow.cpp +++ b/Source/Cut5/Widgets/SCutMainWindow.cpp @@ -28,6 +28,7 @@ #include "StatePanel/SStatePanel.h" #include "Widgets/Layout/SConstraintCanvas.h" #include "Widgets/Layout/SScaleBox.h" +#include "Widgets/Layout/SSpacer.h" #include "Widgets/Layout/SWidgetSwitcher.h" #include "Widgets/Views/STreeView.h" #include "Windows/AllowWindowsPlatformTypes.h" @@ -43,9 +44,9 @@ void SCutMainWindow::Construct(const FArguments& InArgs) FTextBlockStyle MainBarTextStyle = FAppStyle::GetWidgetStyle("NormalText"); - MainBarTextStyle.SetFontSize(17); + MainBarTextStyle.SetFontSize(14); FTextBlockStyle TitleBarTextStyle = FAppStyle::GetWidgetStyle("NormalText"); - MainBarTextStyle.SetFontSize(15); + TitleBarTextStyle.SetFontSize(15); ChildSlot @@ -83,8 +84,7 @@ void SCutMainWindow::Construct(const FArguments& InArgs) ] ] + SHorizontalBox::Slot() - .Padding(32, 0, -32, 0) - .HAlign(HAlign_Fill) + .HAlign(HAlign_Left) .VAlign(VAlign_Center) .SizeParam(FAuto()) [ @@ -117,6 +117,12 @@ void SCutMainWindow::Construct(const FArguments& InArgs) ] ] + SHorizontalBox::Slot() + .SizeParam(FStretch(1.0)) + [ + SNew(SSpacer) + ] + + SHorizontalBox::Slot() + .SizeParam(FAuto()) .VAlign(VAlign_Center) .HAlign(HAlign_Right) [ @@ -129,6 +135,7 @@ void SCutMainWindow::Construct(const FArguments& InArgs) ] ] + SHorizontalBox::Slot() + .SizeParam(FAuto()) .VAlign(VAlign_Center) .HAlign(HAlign_Right) [ @@ -141,6 +148,7 @@ void SCutMainWindow::Construct(const FArguments& InArgs) ] ] + SHorizontalBox::Slot() + .SizeParam(FAuto()) .VAlign(VAlign_Center) .HAlign(HAlign_Right) [ @@ -651,19 +659,18 @@ void SCutMainWindow::OpenProject(const FString& Project) void SCutMainWindow::ExportProject(const FString& ExportPath) { - + // 先读取所有保存下来的轨道 for (FTrackGroup& TrackGroup : CutTimeline->TrackGroups) { for (FTrackData& TrackData : TrackGroup.TrackDataArray) { - - FUtils::TrackEncodeVideo(TrackData, {}); + // FUtils::TrackEncodeVideo(TrackData, FPaths::Combine(ExportPath, TEXT("Video"))); } } for (int32 i = 0; i < CutTimeline->TrackGroupInstances.Num(); i++) { - FUtils::TrackEncodeVideo(StaticCastSharedPtr(CutTimeline->TrackGroupInstances[i].Head)->TrackData, TEXT("D:\\Project\\Cut5\\Movie.mp4")); + FUtils::TrackEncodeVideo(StaticCastSharedPtr(CutTimeline->TrackGroupInstances[i].Head)->TrackData, FPaths::Combine(ExportPath, TEXT("Video"))); } if (ExportPath.IsEmpty()) @@ -733,17 +740,31 @@ void SCutMainWindow::ExportProject(const FString& ExportPath) tinyxml2::XMLElement* CardList = RootElement->InsertNewChildElement("CardList"); for (int32 i = 0; i < EffectCardsPanel->EffectCardGroups.Num(); i ++) { - for (int32 j = 0; j < EffectCardsPanel->EffectCardGroups[i].Cards.Num(); j++) + if (EffectCardsPanel->EffectCardGroups[i].bIsDedicated) + { + for (int32 j = 0; j < EffectCardsPanel->EffectCardGroups[i].Cards.Num(); j++) + { + tinyxml2::XMLElement* Card = CardList->InsertNewChildElement("Card"); + Card->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].Cards[j].ID))); + Card->InsertNewChildElement("Type")->InsertNewText(EffectCardsPanel->EffectCardGroups[0].bIsDedicated ? "0" : "2"); + Card->InsertNewChildElement("Times"); + Card->InsertNewChildElement("Step"); + Card->InsertNewChildElement("SpecialEffectID"); + Card->InsertNewChildElement("SerialNumberList"); + + } + } + else { tinyxml2::XMLElement* Card = CardList->InsertNewChildElement("Card"); - Card->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(ID))); - Card->InsertNewChildElement("Type")->InsertNewText(EffectCardsPanel->EffectCardGroups[0].bIsDedicated ? "0" : "1"); + Card->InsertNewChildElement("ID")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(EffectCardsPanel->EffectCardGroups[i].ID))); + Card->InsertNewChildElement("Type")->InsertNewText(EffectCardsPanel->EffectCardGroups[0].bIsDedicated ? "0" : "2"); Card->InsertNewChildElement("Times"); Card->InsertNewChildElement("Step"); Card->InsertNewChildElement("SpecialEffectID"); Card->InsertNewChildElement("SerialNumberList"); - ID++; } + } // KeyBoard @@ -761,30 +782,67 @@ void SCutMainWindow::ExportProject(const FString& ExportPath) tinyxml2::XMLElement* TimeLength = ProcessB->InsertNewChildElement("TimeLength"); tinyxml2::XMLElement* SoundList = ProcessB->InsertNewChildElement("SoundList"); { - tinyxml2::XMLElement* Sound = SoundList->InsertNewChildElement("Sound"); - tinyxml2::XMLElement* URL = Sound->InsertNewChildElement("URL"); - tinyxml2::XMLElement* Loop = Sound->InsertNewChildElement("Loop"); - tinyxml2::XMLElement* Mode = Sound->InsertNewChildElement("Mode"); - tinyxml2::XMLElement* Round = Sound->InsertNewChildElement("Round"); - tinyxml2::XMLElement* Timecode = Sound->InsertNewChildElement("Timecode"); - tinyxml2::XMLElement* VolumeEventList = Sound->InsertNewChildElement("VolumeEventList"); - { - tinyxml2::XMLElement* VolumeEvent = VolumeEventList->InsertNewChildElement("VolumeEvent"); - tinyxml2::XMLElement* VolumeEventTimeCode = VolumeEvent->InsertNewChildElement("TimeCode"); - tinyxml2::XMLElement* VolumeEventValue = VolumeEvent->InsertNewChildElement("Value"); - } + GetSoundElement(SoundList); } + ProcessB->InsertEndChild(GetDeviceElement(ProcessB)); + tinyxml2::XMLElement* VideoList = ProcessB->InsertNewChildElement("VideoList"); + { + // for video + GetVideoElement(VideoList); + } + // 非必须项 + tinyxml2::XMLElement* Identity_SpecialEffects = ProcessB->InsertNewChildElement("Identity_SpecialEffects"); + { + + } + tinyxml2::XMLElement* IsGlobal = ProcessB->InsertNewChildElement("IsGlobal"); + { + + } + tinyxml2::XMLElement* State = ProcessB->InsertNewChildElement("State"); + { + + } } } + // Effect Lists + for (int32 i = 0; i < EffectCardsPanel->EffectCardGroups.Num(); i++) + { + for (int32 j = 0; j < EffectCardsPanel->EffectCardGroups[i].Cards.Num(); j++) + { + + } + } + tinyxml2::XMLElement* SpecialEffect = RootElement->InsertNewChildElement("SpecialEffect"); + { + tinyxml2::XMLElement* Test = SpecialEffect->InsertNewChildElement("Test"); + { + Test->InsertNewChildElement("ID"); + Test->InsertNewChildElement("AutoNext"); + Test->InsertNewChildElement("TimeLength"); + + GetSoundElement(Test); + GetDeviceElement(Test); + GetVideoElement(Test); + + Test->InsertNewChildElement("IsGlobal"); + Test->InsertNewChildElement("State"); + } + } - - Document.SaveFile(TCHAR_TO_UTF8(*(ExportPath + "/" + FGlobalData::CurrentProjectName + "/" + FGlobalData::CurrentProjectName + TEXT(".xml")))); + + FString XMLExportPath = FPaths::ConvertRelativePathToFull(FPaths::Combine(ExportPath, FGlobalData::CurrentProjectName, FGlobalData::CurrentProjectName + TEXT(".xml"))); + TArray Data; + FFileHelper::SaveArrayToFile(Data, *XMLExportPath); + // FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*XMLExportPath); + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, XMLExportPath); + Document.SaveFile(TCHAR_TO_UTF8(*XMLExportPath)); } void SCutMainWindow::ImportProject(const FString& ImportPath) @@ -969,5 +1027,81 @@ void SCutMainWindow::PreSettingBeforeSeek() OnUpdateVideo(FGuid::NewGuid(), 1920, 1080, nullptr); } +tinyxml2::XMLElement* SCutMainWindow::GetDeviceElement(tinyxml2::XMLElement* Parent) +{ + tinyxml2::XMLElement* Device = Parent->InsertNewChildElement("Device"); + { + tinyxml2::XMLElement* Light = Device->InsertNewChildElement("Light"); + { + // DMLightList + tinyxml2::XMLElement* DMLightList = Light->InsertNewChildElement("DMLightList"); + { + + } + tinyxml2::XMLElement* PlayerLightList = Light->InsertNewChildElement("PlayerLightList"); + { + + } + tinyxml2::XMLElement* GuangZhenList = Light->InsertNewChildElement("GuangZhenList"); + { + + } + tinyxml2::XMLElement* RoomLight = Light->InsertNewChildElement("RoomLight"); + { + + } + tinyxml2::XMLElement* JLight = Light->InsertNewChildElement("JLight"); + { + + } + tinyxml2::XMLElement* Incense_Machine = Light->InsertNewChildElement("Incense_Machine"); + { + + } + } + } + return Device; +} + +tinyxml2::XMLElement* SCutMainWindow::GetVideoElement(tinyxml2::XMLElement* Parent) +{ + tinyxml2::XMLElement* Video = Parent->InsertNewChildElement("Video"); + tinyxml2::XMLElement* URL = Video->InsertNewChildElement("URL"); + tinyxml2::XMLElement* Timecode = Video->InsertNewChildElement("Timecode"); + tinyxml2::XMLElement* Loop = Video->InsertNewChildElement("Loop"); + tinyxml2::XMLElement* Mode = Video->InsertNewChildElement("Mode"); + tinyxml2::XMLElement* ProjectorID = Video->InsertNewChildElement("ProjectorID"); + + tinyxml2::XMLElement* ProjectorEventList = Video->InsertNewChildElement("ProjectorEventList"); + { + tinyxml2::XMLElement* ProjectorEvent = ProjectorEventList->InsertNewChildElement("ProjectorEvent"); + { + tinyxml2::XMLElement* TimeCode = ProjectorEvent->InsertNewChildElement("TimeCode"); + tinyxml2::XMLElement* Value = ProjectorEvent->InsertNewChildElement("Value"); + } + } + return Parent; +} + +tinyxml2::XMLElement* SCutMainWindow::GetSoundElement(tinyxml2::XMLElement* Parent) +{ + tinyxml2::XMLElement* Sound = Parent->InsertNewChildElement("Sound"); + tinyxml2::XMLElement* URL = Sound->InsertNewChildElement("URL"); + tinyxml2::XMLElement* Loop = Sound->InsertNewChildElement("Loop"); + tinyxml2::XMLElement* Mode = Sound->InsertNewChildElement("Mode"); + tinyxml2::XMLElement* Round = Sound->InsertNewChildElement("Round"); + tinyxml2::XMLElement* Timecode = Sound->InsertNewChildElement("Timecode"); + tinyxml2::XMLElement* VolumeEventList = Sound->InsertNewChildElement("VolumeEventList"); + { + tinyxml2::XMLElement* VolumeEvent = VolumeEventList->InsertNewChildElement("VolumeEvent"); + { + tinyxml2::XMLElement* VolumeEventTimeCode = VolumeEvent->InsertNewChildElement("TimeCode"); + tinyxml2::XMLElement* VolumeEventValue = VolumeEvent->InsertNewChildElement("Value"); + } + + } + return Parent; +} + END_SLATE_FUNCTION_BUILD_OPTIMIZATION diff --git a/Source/Cut5/Widgets/SCutMainWindow.h b/Source/Cut5/Widgets/SCutMainWindow.h index f106bae..5fecc20 100644 --- a/Source/Cut5/Widgets/SCutMainWindow.h +++ b/Source/Cut5/Widgets/SCutMainWindow.h @@ -2,6 +2,8 @@ #pragma once +#include + #include "CoreMinimal.h" #include "Curtain/SCurtainPanel.h" @@ -75,4 +77,8 @@ public: virtual void DeleteAllAssetsInTimeline() override; virtual SCutTimeline* GetCutTimeline() override { return CutTimeline.Get(); }; virtual void PreSettingBeforeSeek() override; + + static tinyxml2::XMLElement* GetDeviceElement(tinyxml2::XMLElement* Parent); + static tinyxml2::XMLElement* GetVideoElement(tinyxml2::XMLElement* Parent); + static tinyxml2::XMLElement* GetSoundElement(tinyxml2::XMLElement* Parent); }; diff --git a/Source/Cut5/Widgets/SCutTimeline.cpp b/Source/Cut5/Widgets/SCutTimeline.cpp index 458cad2..4266db0 100644 --- a/Source/Cut5/Widgets/SCutTimeline.cpp +++ b/Source/Cut5/Widgets/SCutTimeline.cpp @@ -115,6 +115,7 @@ void SCutTimeline::Construct(const FArguments& InArgs) [ SNew(SVerticalBox) + SVerticalBox::Slot() + .SizeParam(FAuto()) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() @@ -143,6 +144,7 @@ void SCutTimeline::Construct(const FArguments& InArgs) .AutoWidth() .VAlign(VAlign_Center) .HAlign(HAlign_Center) + .SizeParam(FAuto()) [ SNew(SImage) .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("PlayButton.png"), {})) diff --git a/Source/Cut5/Widgets/STimelineProperty.cpp b/Source/Cut5/Widgets/STimelineProperty.cpp index 82aba7f..4eb8166 100644 --- a/Source/Cut5/Widgets/STimelineProperty.cpp +++ b/Source/Cut5/Widgets/STimelineProperty.cpp @@ -18,7 +18,7 @@ void STimelineProperty::Construct(const FArguments& InArgs) SNew(SBox) .WidthOverride(80) .HeightOverride(80) - .Padding(5) + .Padding(4) [ SNew(SOverlay) + SOverlay::Slot() diff --git a/Source/Cut5/Widgets/STimelinePropertyPanel.cpp b/Source/Cut5/Widgets/STimelinePropertyPanel.cpp index b24a9be..c215251 100644 --- a/Source/Cut5/Widgets/STimelinePropertyPanel.cpp +++ b/Source/Cut5/Widgets/STimelinePropertyPanel.cpp @@ -36,6 +36,7 @@ void STimelinePropertyPanel::Construct(const FArguments& InArgs) .SizeParam(FAuto()) [ SNew(SBox) + .Padding(0, 0 , 0, 14) [ SNew(SOverlay) + SOverlay::Slot() @@ -90,15 +91,44 @@ void STimelinePropertyPanel::Construct(const FArguments& InArgs) .Visibility(EVisibility::HitTestInvisible) ] + SOverlay::Slot() + .VAlign(VAlign_Center) + .HAlign(HAlign_Center) + .Padding(0, 0 , 0, 10) + [ + SNew(SBox) + .WidthOverride(16) + .HeightOverride(21) + [ + SNew(SImage) + .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("CharacterGroupIcon.png"), {16, 21})) + .Visibility(EVisibility::HitTestInvisible) + ] + ] + + SOverlay::Slot() + .Padding(0, 0, 9, 9) + .VAlign(VAlign_Bottom) + .HAlign(HAlign_Right) + [ + SNew(SBox) + .WidthOverride(24) + .HeightOverride(24) + [ + SNew(SImage) + .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("add-circle-fill.png"), {24, 24})) + .Visibility(EVisibility::HitTestInvisible) + ] + ] + + SOverlay::Slot() .VAlign(VAlign_Bottom) .HAlign(HAlign_Fill) - .Padding(0, 0, 0, 3) + .Padding(0, 0, 0, 9) [ SNew(STextBlock) .Text(FText::FromString(TEXT("角色组"))) .Justification(ETextJustify::Center) .Visibility(EVisibility::HitTestInvisible) ] + ] diff --git a/Source/Cut5/Widgets/StatePanel/SStatePanel.cpp b/Source/Cut5/Widgets/StatePanel/SStatePanel.cpp index bf4b90e..f803cf1 100644 --- a/Source/Cut5/Widgets/StatePanel/SStatePanel.cpp +++ b/Source/Cut5/Widgets/StatePanel/SStatePanel.cpp @@ -134,26 +134,52 @@ void SStatePanel::Construct(const FArguments& InArgs) + SOverlay::Slot() .HAlign(HAlign_Left) .VAlign(VAlign_Center) + .Padding(50, 0, 0, 0) [ - SNew(SBox) - .WidthOverride(100) - .HeightOverride(100) + SNew(SVerticalBox) + + SVerticalBox::Slot() + .SizeParam(FAuto()) [ - SAssignNew(Projector, SImage) - .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("Projector.png")), FVector2D(0, 0))) + SNew(SBox) + .WidthOverride(32) + .HeightOverride(32) + [ + SAssignNew(Projector, SImage) + .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("Projector.png")), FVector2D(0, 0))) + ] ] + + SVerticalBox::Slot() + .SizeParam(FAuto()) + [ + SNew(STextBlock) + .Text(FText::FromString(TEXT("投影仪"))) + ] + ] + SOverlay::Slot() + .Padding(0, 0, 50, 0) .HAlign(HAlign_Right) .VAlign(VAlign_Center) [ - SNew(SBox) - .WidthOverride(100) - .HeightOverride(100) + SNew(SVerticalBox) + + SVerticalBox::Slot() + .SizeParam(FAuto()) [ - SAssignNew(SpotLight, SImage) - .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("SpotLight.png")), FVector2D(0, 0))) + SNew(SBox) + .WidthOverride(59) + .HeightOverride(49) + [ + SAssignNew(SpotLight, SImage) + .Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("SpotLight.png")), FVector2D(0, 0))) + ] ] + + SVerticalBox::Slot() + .SizeParam(FAuto()) + [ + SNew(STextBlock) + .Text(FText::FromString(TEXT("投射灯"))) + ] + ] + SOverlay::Slot() .HAlign(HAlign_Right) diff --git a/Source/Cut5/Widgets/Style/CutButtonWidgetStyle.cpp b/Source/Cut5/Widgets/Style/CutButtonWidgetStyle.cpp index 4eb42cf..09be853 100644 --- a/Source/Cut5/Widgets/Style/CutButtonWidgetStyle.cpp +++ b/Source/Cut5/Widgets/Style/CutButtonWidgetStyle.cpp @@ -83,6 +83,13 @@ TSharedPtr< FSlateStyleSet > FCutButtonStyle::Create() .SetNormal( BOX_BRUSH( "CurtainSelected", FVector2D(240,32), 0.25) ) ); + + Style->Set("Preset.PresetButton", FButtonStyle(Button) + .SetNormal( BOX_BRUSH( "PresetButtonNormal", FVector2D(76,76), 0.25) ) + .SetHovered( BOX_BRUSH( "PresetButtonHover", FVector2D(76,76), 0.25) ) + .SetPressed( BOX_BRUSH( "PresetButtonSelected", FVector2D(76,76), 0.25) ) + ); + return Style; } diff --git a/output.mp4 b/output.mp4 index bc4bc40..35bc233 100644 Binary files a/output.mp4 and b/output.mp4 differ