allow Node/Ref to accept drag&drop

This commit is contained in:
2022-06-16 10:29:35 +09:00
parent 9ff6339fe4
commit 6eaab065aa
8 changed files with 177 additions and 46 deletions

View File

@@ -10,10 +10,11 @@ namespace nf7 {
class DirItem : public File::Interface {
public:
enum Flag : uint8_t {
kNone = 0,
kTree = 1 << 0,
kMenu = 1 << 1,
kTooltip = 1 << 2,
kNone = 0,
kTree = 1 << 0,
kMenu = 1 << 1,
kTooltip = 1 << 2,
kDragDropTarget = 1 << 3,
};
using Flags = uint8_t;
@@ -28,6 +29,7 @@ class DirItem : public File::Interface {
virtual void UpdateTree() noexcept { }
virtual void UpdateMenu() noexcept { }
virtual void UpdateTooltip() noexcept { }
virtual void UpdateDragDropTarget() noexcept { }
Flags flags() const noexcept { return flags_; }

69
common/gui_dnd.hh Normal file
View File

@@ -0,0 +1,69 @@
#pragma once
#include <cstring>
#include <optional>
#include <string>
#include <string_view>
#include <imgui.h>
#include "nf7.hh"
namespace nf7::gui::dnd {
// data entity is char[] of file path
constexpr const char* kFilePath = "nf7::File::Path";
template <typename T>
bool Send(const char* type, const T&) noexcept;
template <>
inline bool Send<std::string>(const char* type, const std::string& v) noexcept {
return ImGui::SetDragDropPayload(type, v.data(), v.size());
}
template <>
inline bool Send<std::string_view>(const char* type, const std::string_view& v) noexcept {
return ImGui::SetDragDropPayload(type, v.data(), v.size());
}
template <>
inline bool Send<File::Path>(const char* type, const File::Path& p) noexcept {
return Send(type, p.Stringify());
}
template <typename T>
T To(const ImGuiPayload&) noexcept;
template <>
inline std::string To<std::string>(const ImGuiPayload& pay) noexcept {
std::string ret;
ret.resize(static_cast<size_t>(pay.DataSize));
std::memcpy(ret.data(), pay.Data, ret.size());
return ret;
}
template <>
inline File::Path To<File::Path>(const ImGuiPayload& pay) noexcept {
return File::Path::Parse(To<std::string>(pay));
}
template <typename T>
std::optional<T> Accept(const char* type, ImGuiDragDropFlags flags = 0) noexcept {
if (auto pay = ImGui::AcceptDragDropPayload(type, flags)) {
return To<T>(*pay);
}
return std::nullopt;
}
template <typename T>
const ImGuiPayload* Peek(const char* type, auto& v, ImGuiDragDropFlags flags = 0) noexcept {
flags |= ImGuiDragDropFlags_AcceptBeforeDelivery;
if (auto pay = ImGui::AcceptDragDropPayload(type, flags)) {
if (pay->IsDelivery()) v = To<T>(*pay);
return pay;
}
return nullptr;
}
} // namespace nf7::gui::dnd

View File

@@ -7,6 +7,8 @@
#include "nf7.hh"
#include "common/gui_dnd.hh"
namespace nf7::gui {
@@ -128,4 +130,18 @@ struct FileCreatePopup final {
std::string type_filter_;
};
} // namespace nf7
inline bool InputFilePath(const char* id, std::string* path) noexcept {
bool ret = ImGui::InputText(id, path, ImGuiInputTextFlags_EnterReturnsTrue);
if (ImGui::BeginDragDropTarget()) {
if (auto str = gui::dnd::Accept<std::string>(gui::dnd::kFilePath)) {
*path = *str;
ret = true;
}
ImGui::EndDragDropTarget();
}
return ret;
}
} // namespace nf7::gui