mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
fix project saving, resource management and media node properties change
This commit is contained in:
parent
308586d4b8
commit
83d8542002
9 changed files with 253 additions and 200 deletions
|
|
@ -191,6 +191,7 @@ public:
|
||||||
if (i.ID == pinId)
|
if (i.ID == pinId)
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
atIndex++;
|
atIndex++;
|
||||||
}
|
}
|
||||||
|
|
@ -206,6 +207,7 @@ public:
|
||||||
if (i.ID == pinId)
|
if (i.ID == pinId)
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
atIndex++;
|
atIndex++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -483,9 +483,28 @@ void LoadingIndicatorCircle(const char* label, const float indicator_radius,
|
||||||
}
|
}
|
||||||
} // namespace ImGui
|
} // namespace ImGui
|
||||||
|
|
||||||
|
void Gui::Image::Clear()
|
||||||
|
{
|
||||||
|
if (texture != nullptr)
|
||||||
|
{
|
||||||
|
SDL_DestroyTexture(static_cast<SDL_Texture*>(texture));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gui::Image::Load(const std::string &filename)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
Gui::LoadRawImage(filename, *this);
|
||||||
|
}
|
||||||
|
|
||||||
Gui::Image::Image()
|
Gui::Image::Image()
|
||||||
{
|
{
|
||||||
texture = nullptr;
|
texture = nullptr;
|
||||||
w = 0;
|
w = 0;
|
||||||
h = 0;
|
h = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Gui::Image::~Image()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,17 +14,22 @@ public:
|
||||||
struct Texture;
|
struct Texture;
|
||||||
|
|
||||||
struct Image {
|
struct Image {
|
||||||
void *texture; // Platform specific
|
void *texture{nullptr}; // Platform specific
|
||||||
int w;
|
int w;
|
||||||
int h;
|
int h;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
bool valid() const {
|
bool Valid() const {
|
||||||
return (w && h);
|
return (w && h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
void Load(const std::string &filename);
|
||||||
|
|
||||||
Image();
|
Image();
|
||||||
|
~Image();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ void MediaNode::Draw()
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
|
|
||||||
|
|
||||||
if (m_image.valid())
|
if (m_image.Valid())
|
||||||
{
|
{
|
||||||
ImGui::Image(m_image.texture, ImVec2(320, 240));
|
ImGui::Image(m_image.texture, ImVec2(320, 240));
|
||||||
}
|
}
|
||||||
|
|
@ -103,12 +103,8 @@ void MediaNode::Draw()
|
||||||
*/
|
*/
|
||||||
void MediaNode::FromJson(const nlohmann::json &j)
|
void MediaNode::FromJson(const nlohmann::json &j)
|
||||||
{
|
{
|
||||||
m_image.name = j["image"].get<std::string>();
|
SetImage(j["image"].get<std::string>());
|
||||||
|
SetSound(j["sound"].get<std::string>());
|
||||||
Gui::LoadRawImage(m_project.BuildFullAssetsPath(m_image.name), m_image);
|
|
||||||
|
|
||||||
m_soundName = j["sound"].get<std::string>();
|
|
||||||
m_soundPath = m_project.BuildFullAssetsPath(m_soundName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaNode::ToJson(nlohmann::json &j)
|
void MediaNode::ToJson(nlohmann::json &j)
|
||||||
|
|
@ -127,10 +123,10 @@ void MediaNode::DrawProperties()
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
std::string type = "sound";
|
static bool isImage = true;
|
||||||
if (ImGui::Button("Select...##image")) {
|
if (ImGui::Button("Select...##image")) {
|
||||||
type = "image";
|
|
||||||
ImGui::OpenPopup("popup_button");
|
ImGui::OpenPopup("popup_button");
|
||||||
|
isImage = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
ImGui::AlignTextToFramePadding();
|
||||||
|
|
@ -146,27 +142,187 @@ void MediaNode::DrawProperties()
|
||||||
m_project.PlaySoundFile(m_soundPath);
|
m_project.PlaySoundFile(m_soundPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
if (ImGui::Button("Select...##sound")) {
|
if (ImGui::Button("Select...##sound")) {
|
||||||
ImGui::OpenPopup("popup_button");
|
ImGui::OpenPopup("popup_button");
|
||||||
|
isImage = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This is the actual popup Gui drawing section.
|
// This is the actual popup Gui drawing section.
|
||||||
if (ImGui::BeginPopup("popup_button")) {
|
if (ImGui::BeginPopup("popup_button")) {
|
||||||
ImGui::SeparatorText("Sounds");
|
ImGui::SeparatorText(isImage ? "Images" : "Sounds");
|
||||||
|
|
||||||
static int item_current_idx = 0; // Here we store our selection data as an index.
|
auto [filtreDebut, filtreFin] = isImage ? m_project.Images() : m_project.Sounds();
|
||||||
|
|
||||||
|
|
||||||
auto [filtreDebut, filtreFin] = m_project.Sounds();
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (auto it = filtreDebut; it != filtreFin; ++it, n++)
|
for (auto it = filtreDebut; it != filtreFin; ++it, n++)
|
||||||
{
|
{
|
||||||
if (ImGui::Selectable((*it)->file.c_str()), n == item_current_idx)
|
if (ImGui::Selectable((*it)->file.c_str()))
|
||||||
item_current_idx = n;
|
{
|
||||||
|
if (isImage)
|
||||||
|
{
|
||||||
|
SetImage((*it)->file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetSound((*it)->file);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndPopup(); // Note this does not do anything to the popup open/close state. It just terminates the content declaration.
|
ImGui::EndPopup(); // Note this does not do anything to the popup open/close state. It just terminates the content declaration.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaNode::SetImage(const std::string &f)
|
||||||
|
{
|
||||||
|
m_image.name = f;
|
||||||
|
m_image.Load(m_project.BuildFullAssetsPath(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MediaNode::SetSound(const std::string &f)
|
||||||
|
{
|
||||||
|
m_soundName = f;
|
||||||
|
m_soundPath = m_project.BuildFullAssetsPath(m_soundName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
std::string NodeEditorWindow::ChoiceLabel() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "mediaChoice" << std::setw(4) << std::setfill('0') << GetId();
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string NodeEditorWindow::EntryLabel() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << ".mediaEntry" << std::setw(4) << std::setfill('0') << getNodeId();
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string NodeEditorWindow::GenerateConstants()
|
||||||
|
{
|
||||||
|
std::string s;
|
||||||
|
|
||||||
|
std::string image = m_mediaData["image"].get<std::string>();
|
||||||
|
std::string sound = m_mediaData["sound"].get<std::string>();
|
||||||
|
if (image.size() > 0)
|
||||||
|
{
|
||||||
|
s = StoryProject::FileToConstant(image, ".qoi"); // FIXME: Generate the extension setup in user option of output format
|
||||||
|
}
|
||||||
|
if (sound.size() > 0)
|
||||||
|
{
|
||||||
|
s += StoryProject::FileToConstant(sound, ".wav"); // FIXME: Generate the extension setup in user option of output format
|
||||||
|
}
|
||||||
|
|
||||||
|
int nb_out_conns = ComputeOutputConnections();
|
||||||
|
if (nb_out_conns > 1)
|
||||||
|
{
|
||||||
|
// Generate choice table if needed (out ports > 1)
|
||||||
|
std::stringstream ss;
|
||||||
|
std::string label = ChoiceLabel();
|
||||||
|
ss << "$" << label
|
||||||
|
<< " DC32, "
|
||||||
|
<< nb_out_conns << ", ";
|
||||||
|
|
||||||
|
std::unordered_set<ConnectionId> conns = m_model.allConnectionIds(getNodeId());
|
||||||
|
int i = 0;
|
||||||
|
for (auto & c : conns)
|
||||||
|
{
|
||||||
|
std::stringstream ssChoice;
|
||||||
|
|
||||||
|
// On va chercher le label d'entrée du noeud connecté à l'autre bout
|
||||||
|
ss << m_model.GetNodeEntryLabel(c.inNodeId);
|
||||||
|
if (i < (nb_out_conns - 1))
|
||||||
|
{
|
||||||
|
ss << ", ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss << "\n";
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
s += ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string NodeEditorWindow::Build()
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
int nb_out_conns = ComputeOutputConnections();
|
||||||
|
|
||||||
|
ss << R"(; ---------------------------- )"
|
||||||
|
<< GetNodeTitle()
|
||||||
|
<< " Type: "
|
||||||
|
<< (nb_out_conns == 0 ? "End" : nb_out_conns == 1 ? "Transition" : "Choice")
|
||||||
|
<< "\n";
|
||||||
|
std::string image = StoryProject::RemoveFileExtension(m_mediaData["image"].get<std::string>());
|
||||||
|
std::string sound = StoryProject::RemoveFileExtension(m_mediaData["sound"].get<std::string>());
|
||||||
|
|
||||||
|
// Le label de ce noeud est généré de la façon suivante :
|
||||||
|
// "media" + Node ID + id du noeud parent. Si pas de noeud parent, alors rien
|
||||||
|
ss << EntryLabel() << ":\n";
|
||||||
|
|
||||||
|
if (image.size() > 0)
|
||||||
|
{
|
||||||
|
ss << "lcons r0, $" << image << "\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss << "lcons r0, 0\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sound.size() > 0)
|
||||||
|
{
|
||||||
|
ss << "lcons r1, $" << sound << "\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss << "lcons r1, 0\n";
|
||||||
|
}
|
||||||
|
// Call the media executor (image, sound)
|
||||||
|
ss << "syscall 1\n";
|
||||||
|
|
||||||
|
// Check output connections number
|
||||||
|
// == 0: end node : generate halt
|
||||||
|
// == 1: transition node : image + sound on demand, jump directly to the other node when OK
|
||||||
|
// > 1 : choice node : call the node choice manager
|
||||||
|
|
||||||
|
if (nb_out_conns == 0) // End node
|
||||||
|
{
|
||||||
|
ss << "halt\n";
|
||||||
|
}
|
||||||
|
else if (nb_out_conns == 1) // Transition node
|
||||||
|
{
|
||||||
|
std::unordered_set<ConnectionId> conns = m_model.allConnectionIds(getNodeId());
|
||||||
|
|
||||||
|
|
||||||
|
for (auto c : conns)
|
||||||
|
{
|
||||||
|
if (c.outNodeId == getNodeId())
|
||||||
|
{
|
||||||
|
// On place dans R0 le prochain noeud à exécuter en cas de OK
|
||||||
|
ss << "lcons r0, "
|
||||||
|
<< m_model.GetNodeEntryLabel(c.inNodeId) << "\n"
|
||||||
|
<< "ret\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else // Choice node
|
||||||
|
{
|
||||||
|
ss << "lcons r0, $" << ChoiceLabel() << "\n"
|
||||||
|
<< "jump .media ; no return possible, so a jump is enough";
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
|
||||||
|
|
@ -32,4 +32,6 @@ private:
|
||||||
std::string m_id;
|
std::string m_id;
|
||||||
|
|
||||||
std::string m_buttonUniqueName;
|
std::string m_buttonUniqueName;
|
||||||
|
void SetImage(const std::string &f);
|
||||||
|
void SetSound(const std::string &f);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,7 @@ void NodeEditorWindow::Save(nlohmann::json &model)
|
||||||
|
|
||||||
node["position"] = position;
|
node["position"] = position;
|
||||||
node["internal-data"] = internalData;
|
node["internal-data"] = internalData;
|
||||||
|
nodes.push_back(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
model["nodes"] = nodes;
|
model["nodes"] = nodes;
|
||||||
|
|
@ -206,144 +207,6 @@ void NodeEditorWindow::Save(nlohmann::json &model)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
std::string NodeEditorWindow::ChoiceLabel() const
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "mediaChoice" << std::setw(4) << std::setfill('0') << GetId();
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string NodeEditorWindow::EntryLabel() const
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << ".mediaEntry" << std::setw(4) << std::setfill('0') << getNodeId();
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string NodeEditorWindow::GenerateConstants()
|
|
||||||
{
|
|
||||||
std::string s;
|
|
||||||
|
|
||||||
std::string image = m_mediaData["image"].get<std::string>();
|
|
||||||
std::string sound = m_mediaData["sound"].get<std::string>();
|
|
||||||
if (image.size() > 0)
|
|
||||||
{
|
|
||||||
s = StoryProject::FileToConstant(image, ".qoi"); // FIXME: Generate the extension setup in user option of output format
|
|
||||||
}
|
|
||||||
if (sound.size() > 0)
|
|
||||||
{
|
|
||||||
s += StoryProject::FileToConstant(sound, ".wav"); // FIXME: Generate the extension setup in user option of output format
|
|
||||||
}
|
|
||||||
|
|
||||||
int nb_out_conns = ComputeOutputConnections();
|
|
||||||
if (nb_out_conns > 1)
|
|
||||||
{
|
|
||||||
// Generate choice table if needed (out ports > 1)
|
|
||||||
std::stringstream ss;
|
|
||||||
std::string label = ChoiceLabel();
|
|
||||||
ss << "$" << label
|
|
||||||
<< " DC32, "
|
|
||||||
<< nb_out_conns << ", ";
|
|
||||||
|
|
||||||
std::unordered_set<ConnectionId> conns = m_model.allConnectionIds(getNodeId());
|
|
||||||
int i = 0;
|
|
||||||
for (auto & c : conns)
|
|
||||||
{
|
|
||||||
std::stringstream ssChoice;
|
|
||||||
|
|
||||||
// On va chercher le label d'entrée du noeud connecté à l'autre bout
|
|
||||||
ss << m_model.GetNodeEntryLabel(c.inNodeId);
|
|
||||||
if (i < (nb_out_conns - 1))
|
|
||||||
{
|
|
||||||
ss << ", ";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ss << "\n";
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
s += ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string NodeEditorWindow::Build()
|
|
||||||
{
|
|
||||||
std::stringstream ss;
|
|
||||||
int nb_out_conns = ComputeOutputConnections();
|
|
||||||
|
|
||||||
ss << R"(; ---------------------------- )"
|
|
||||||
<< GetNodeTitle()
|
|
||||||
<< " Type: "
|
|
||||||
<< (nb_out_conns == 0 ? "End" : nb_out_conns == 1 ? "Transition" : "Choice")
|
|
||||||
<< "\n";
|
|
||||||
std::string image = StoryProject::RemoveFileExtension(m_mediaData["image"].get<std::string>());
|
|
||||||
std::string sound = StoryProject::RemoveFileExtension(m_mediaData["sound"].get<std::string>());
|
|
||||||
|
|
||||||
// Le label de ce noeud est généré de la façon suivante :
|
|
||||||
// "media" + Node ID + id du noeud parent. Si pas de noeud parent, alors rien
|
|
||||||
ss << EntryLabel() << ":\n";
|
|
||||||
|
|
||||||
if (image.size() > 0)
|
|
||||||
{
|
|
||||||
ss << "lcons r0, $" << image << "\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ss << "lcons r0, 0\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sound.size() > 0)
|
|
||||||
{
|
|
||||||
ss << "lcons r1, $" << sound << "\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ss << "lcons r1, 0\n";
|
|
||||||
}
|
|
||||||
// Call the media executor (image, sound)
|
|
||||||
ss << "syscall 1\n";
|
|
||||||
|
|
||||||
// Check output connections number
|
|
||||||
// == 0: end node : generate halt
|
|
||||||
// == 1: transition node : image + sound on demand, jump directly to the other node when OK
|
|
||||||
// > 1 : choice node : call the node choice manager
|
|
||||||
|
|
||||||
if (nb_out_conns == 0) // End node
|
|
||||||
{
|
|
||||||
ss << "halt\n";
|
|
||||||
}
|
|
||||||
else if (nb_out_conns == 1) // Transition node
|
|
||||||
{
|
|
||||||
std::unordered_set<ConnectionId> conns = m_model.allConnectionIds(getNodeId());
|
|
||||||
|
|
||||||
|
|
||||||
for (auto c : conns)
|
|
||||||
{
|
|
||||||
if (c.outNodeId == getNodeId())
|
|
||||||
{
|
|
||||||
// On place dans R0 le prochain noeud à exécuter en cas de OK
|
|
||||||
ss << "lcons r0, "
|
|
||||||
<< m_model.GetNodeEntryLabel(c.inNodeId) << "\n"
|
|
||||||
<< "ret\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else // Choice node
|
|
||||||
{
|
|
||||||
ss << "lcons r0, $" << ChoiceLabel() << "\n"
|
|
||||||
<< "jump .media ; no return possible, so a jump is enough";
|
|
||||||
}
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
std::shared_ptr<BaseNode> NodeEditorWindow::GetSelectedNode()
|
std::shared_ptr<BaseNode> NodeEditorWindow::GetSelectedNode()
|
||||||
{
|
{
|
||||||
std::shared_ptr<BaseNode> selected;
|
std::shared_ptr<BaseNode> selected;
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,7 @@ private:
|
||||||
// Fonction pour trouver le prochain élément qui correspond au filtre
|
// Fonction pour trouver le prochain élément qui correspond au filtre
|
||||||
void searchNext() {
|
void searchNext() {
|
||||||
|
|
||||||
if (filterType == "") {
|
if (filterType != "")
|
||||||
++current;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
while (current != end && (*current)->type != filterType) {
|
while (current != end && (*current)->type != filterType) {
|
||||||
++current;
|
++current;
|
||||||
|
|
|
||||||
|
|
@ -60,38 +60,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
void StoryProject::AppendResource(const Resource &res)
|
|
||||||
{
|
|
||||||
m_resources.push_back(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StoryProject::GetResourceAt(int index, Resource &resOut)
|
|
||||||
{
|
|
||||||
bool success = false;
|
|
||||||
if ((index >= 0) && (index < m_resources.size()))
|
|
||||||
{
|
|
||||||
resOut = m_resources[index];
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StoryProject::ClearResources()
|
|
||||||
{
|
|
||||||
m_resources.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StoryProject::DeleteResourceAt(int index)
|
|
||||||
{
|
|
||||||
if ((index >= 0) && (index < m_resources.size()))
|
|
||||||
{
|
|
||||||
m_resources.erase(m_resources.begin() + index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::shared_ptr<Resource>> m_items;
|
std::vector<std::shared_ptr<Resource>> m_items;
|
||||||
std::pair<FilterIterator, FilterIterator> m_images;
|
std::pair<FilterIterator, FilterIterator> m_images;
|
||||||
|
|
|
||||||
|
|
@ -85,25 +85,31 @@ void ResourcesWindow::Draw()
|
||||||
|
|
||||||
ChooseFile();
|
ChooseFile();
|
||||||
|
|
||||||
ImGuiTableFlags tableFlags = ImGuiTableFlags_Borders |
|
static char description[260];
|
||||||
ImGuiTableFlags_RowBg |
|
|
||||||
ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY |
|
|
||||||
ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV |
|
|
||||||
ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable |
|
|
||||||
ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti;
|
|
||||||
|
|
||||||
if (ImGui::BeginTable("table1", 4, tableFlags))
|
static ImGuiTableFlags tableFlags =
|
||||||
|
ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable
|
||||||
|
| ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti
|
||||||
|
| ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_NoBordersInBody
|
||||||
|
| ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY
|
||||||
|
| ImGuiTableFlags_SizingFixedFit;
|
||||||
|
|
||||||
|
if (ImGui::BeginTable("table1", 5, tableFlags))
|
||||||
{
|
{
|
||||||
ImGui::TableSetupColumn("File", ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("File", ImGuiTableColumnFlags_WidthFixed);
|
||||||
ImGui::TableSetupColumn("Format", ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("Format", ImGuiTableColumnFlags_WidthFixed);
|
||||||
ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthFixed);
|
||||||
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
|
||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
|
|
||||||
auto [b, e] = m_project.Resources();
|
auto [b, e] = m_project.Resources();
|
||||||
|
|
||||||
|
int id = 1000;
|
||||||
for (auto it = b; it != e; ++it)
|
for (auto it = b; it != e; ++it)
|
||||||
{
|
{
|
||||||
|
ImGui::PushID(id);
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("%s", (*it)->file.c_str());
|
ImGui::Text("%s", (*it)->file.c_str());
|
||||||
|
|
||||||
|
|
@ -111,10 +117,45 @@ void ResourcesWindow::Draw()
|
||||||
ImGui::Text("%s", (*it)->format.c_str());
|
ImGui::Text("%s", (*it)->format.c_str());
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
static bool init = false;
|
||||||
|
|
||||||
|
if (ImGui::SmallButton(".."))
|
||||||
|
{
|
||||||
|
ImGui::OpenPopup("edit-comment-popup");
|
||||||
|
init = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (ImGui::BeginPopup("edit-comment-popup"))
|
||||||
|
{
|
||||||
|
if (init)
|
||||||
|
{
|
||||||
|
strncpy(description, (*it)->description.c_str(), sizeof(description));
|
||||||
|
init = false;
|
||||||
|
}
|
||||||
|
// ImGui::PushID(id);
|
||||||
|
ImGui::InputText("Description", description, sizeof(description));
|
||||||
|
if (ImGui::Button("Close"))
|
||||||
|
{
|
||||||
|
(*it)->description.assign(description);
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
// ImGui::PopID();
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
ImGui::Text("%s", (*it)->description.c_str());
|
ImGui::Text("%s", (*it)->description.c_str());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("%s", (*it)->type.c_str());
|
ImGui::Text("%s", (*it)->type.c_str());
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::SmallButton("Delete"))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue