|
31 | 31 | #include "Widgets/Notifications/SNotificationList.h" |
32 | 32 |
|
33 | 33 | #include "HAL/PlatformApplicationMisc.h" |
| 34 | +#include "DragAndDrop/AssetDragDropOp.h" |
| 35 | +#include "Input/DragAndDrop.h" // FExternalDragOperation (SlateCore) |
| 36 | +#include "AssetRegistry/AssetData.h" |
34 | 37 | #include "Json.h" |
35 | 38 | #include "JsonUtilities.h" |
36 | 39 | #include "Editor.h" |
@@ -478,6 +481,78 @@ FReply SHaybaMCPChatPanel::OnPromptCardClicked(FString Prompt) |
478 | 481 | return FReply::Handled(); |
479 | 482 | } |
480 | 483 |
|
| 484 | +// ── Drag-and-drop into the input (assets + external files) ──────────────── |
| 485 | + |
| 486 | +bool SHaybaMCPChatPanel::AppendToInput(const FString& Addition) |
| 487 | +{ |
| 488 | + if (!InputBox.IsValid() || Addition.IsEmpty()) return false; |
| 489 | + |
| 490 | + FString Existing = InputBox->GetText().ToString(); |
| 491 | + // Space-separate from prior content; if the box already ends in whitespace |
| 492 | + // (or is empty) don't inject a redundant leading space. |
| 493 | + if (!Existing.IsEmpty() && !FChar::IsWhitespace(Existing[Existing.Len() - 1])) |
| 494 | + { |
| 495 | + Existing += TEXT(" "); |
| 496 | + } |
| 497 | + Existing += Addition; |
| 498 | + |
| 499 | + InputBox->SetText(FText::FromString(Existing)); |
| 500 | + if (FSlateApplication::IsInitialized()) |
| 501 | + { |
| 502 | + FSlateApplication::Get().SetKeyboardFocus(InputBox); |
| 503 | + } |
| 504 | + return true; |
| 505 | +} |
| 506 | + |
| 507 | +FReply SHaybaMCPChatPanel::OnDragOver(const FGeometry& /*MyGeometry*/, const FDragDropEvent& DragDropEvent) |
| 508 | +{ |
| 509 | + // Show the droppable cursor for payloads we know how to consume. |
| 510 | + if (DragDropEvent.GetOperationAs<FAssetDragDropOp>().IsValid() || |
| 511 | + DragDropEvent.GetOperationAs<FExternalDragOperation>().IsValid()) |
| 512 | + { |
| 513 | + return FReply::Handled(); |
| 514 | + } |
| 515 | + return FReply::Unhandled(); |
| 516 | +} |
| 517 | + |
| 518 | +FReply SHaybaMCPChatPanel::OnDrop(const FGeometry& /*MyGeometry*/, const FDragDropEvent& DragDropEvent) |
| 519 | +{ |
| 520 | + TArray<FString> Refs; |
| 521 | + |
| 522 | + // 1) Content Browser assets — append each asset's object path |
| 523 | + // (e.g. /Game/Path/Asset.Asset) so the reference is unambiguous. |
| 524 | + if (TSharedPtr<FAssetDragDropOp> AssetOp = DragDropEvent.GetOperationAs<FAssetDragDropOp>()) |
| 525 | + { |
| 526 | + for (const FAssetData& Asset : AssetOp->GetAssets()) |
| 527 | + { |
| 528 | + const FString ObjectPath = Asset.GetObjectPathString(); |
| 529 | + if (!ObjectPath.IsEmpty()) Refs.Add(ObjectPath); |
| 530 | + } |
| 531 | + } |
| 532 | + // 2) External files dragged from the OS file explorer. |
| 533 | + else if (TSharedPtr<FExternalDragOperation> ExtOp = DragDropEvent.GetOperationAs<FExternalDragOperation>()) |
| 534 | + { |
| 535 | + if (ExtOp->HasFiles()) |
| 536 | + { |
| 537 | + for (const FString& File : ExtOp->GetFiles()) |
| 538 | + { |
| 539 | + if (!File.IsEmpty()) Refs.Add(File); |
| 540 | + } |
| 541 | + } |
| 542 | + } |
| 543 | + |
| 544 | + if (Refs.Num() == 0) return FReply::Unhandled(); |
| 545 | + |
| 546 | + const bool bAppended = AppendToInput(FString::Join(Refs, TEXT(" "))); |
| 547 | + if (bAppended) |
| 548 | + { |
| 549 | + Toast(FText::Format( |
| 550 | + LOCTEXT("DropAppended", "Added {0} reference(s) to the message."), |
| 551 | + FText::AsNumber(Refs.Num()))); |
| 552 | + } |
| 553 | + return FReply::Handled(); |
| 554 | +} |
| 555 | + |
481 | 556 | // ── Message row (Q5-a flat + Q12-c copy on hover + right-click) ────────── |
482 | 557 |
|
483 | 558 | TSharedRef<SWidget> SHaybaMCPChatPanel::BuildMessageRow(const FHaybaMCPChatMessage& Msg, int32 MessageIndex) |
|
0 commit comments