345 lines
11 KiB
C++

#include "DeerStudio/EditorEngine/API/UI.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "DeerStudio/EditorEngine/DockPanelObject.h"
#include "DeerStudio/EditorEngine.h"
#include "Deer/Log.h"
#include "imgui.h"
#include "angelscript.h"
#include "scriptany.h"
#include "DeerStudio/Fonts.h"
#include <string>
namespace Deer {
namespace EditorEngine {
namespace DragDropPayload{
CScriptAny* payload;
}
void separator() {
ImGui::Separator();
}
void title(std::string& txt) {
ImGui::PushFont(titleText);
ImGui::Text("%s", txt.c_str());
ImGui::PopFont();
}
void titleEnd(std::string& txt) {
ImGui::PushFont(titleText);
textEnd(txt);
ImGui::PopFont();
}
void titleCenter(std::string& txt) {
ImGui::PushFont(titleText);
textCenter(txt);
ImGui::PopFont();
}
void sameLine() {
ImGui::SameLine();
}
bool button(std::string& txt) {
return ImGui::Button(txt.c_str());
}
bool buttonCenter(std::string& txt) {
float sizeX;
if (ImGui::GetColumnsCount() > 1)
sizeX = ImGui::GetColumnWidth(-1);
else
sizeX = ImGui::GetContentRegionAvail().x;
float textWidth = ImGui::CalcTextSize(txt.c_str(), nullptr, false).x;
float padding = (sizeX - textWidth - ImGui::GetStyle().FramePadding.x * 2) * 0.5f;
if (padding > 0.0f)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + padding);
return ImGui::Button(txt.c_str());
}
bool buttonEnd(std::string& txt) {
float sizeX;
if (ImGui::GetColumnsCount() > 1)
sizeX = ImGui::GetColumnWidth(-1);
else
sizeX = ImGui::GetContentRegionAvail().x;
float textWidth = ImGui::CalcTextSize(txt.c_str(), nullptr, false).x;
float padding = (sizeX - textWidth - ImGui::GetStyle().FramePadding.x * 2);
if (padding > 0.0f)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + padding);
return ImGui::Button(txt.c_str());
}
void textColor(float r, float g, float b, std::string& msg) {
ImGui::TextColored(ImVec4(r, g, b, 1.0f), "%s", msg.c_str());
}
void text(std::string& msg) {
ImGui::Text("%s", msg.c_str());
}
void textEnd(std::string& msg) {
float sizeX;
if (ImGui::GetColumnsCount() > 1)
sizeX = ImGui::GetColumnWidth(-1);
else
sizeX = ImGui::GetContentRegionAvail().x;
float textWidth = ImGui::CalcTextSize(msg.c_str(), nullptr, false).x;
float padding = (sizeX - textWidth);
if (padding > 0.0f)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + padding);
ImGui::Text("%s", msg.c_str());
}
void textCenter(std::string& msg) {
float sizeX;
if (ImGui::GetColumnsCount() > 1)
sizeX = ImGui::GetColumnWidth(-1);
else
sizeX = ImGui::GetContentRegionAvail().x;
float textWidth = ImGui::CalcTextSize(msg.c_str(), nullptr, false).x;
float padding = (sizeX - textWidth) * 0.5f;
if (padding > 0.0f)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + padding);
ImGui::Text("%s", msg.c_str());
}
void drawIcon(std::string& name, int size) {
int iconId = DataStore::getIconId(name);
if (iconId < 0) {
DEER_UI_ENGINE_ERROR("Invalid icon name {0}", name.c_str());
if (currentDockPanelExecution) {
currentDockPanelExecution->invalidate();
}
return;
}
ImGui::Image((void*)(uint64_t)iconId,
ImVec2(size, size), ImVec2(0, 1),
ImVec2(1, 0));
}
void drawIconCentered(std::string& name, int size) {
int iconId = DataStore::getIconId(name);
if (iconId < 0) {
DEER_UI_ENGINE_ERROR("Invalid icon name {0}", name.c_str());
if (currentDockPanelExecution) {
currentDockPanelExecution->invalidate();
}
return;
}
float sizeX;
if (ImGui::GetColumnsCount() > 1)
sizeX = ImGui::GetColumnWidth(-1);
else
sizeX = ImGui::GetContentRegionAvail().x;
float iconWidth = size;
float padding = (sizeX - iconWidth) * 0.5f;
if (padding > 0.0f)
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + padding);
drawIcon(name, size);
}
bool isItemClicked(int mouse) {
return ImGui::IsItemClicked(mouse);
}
bool isMouseDoubleClicked(int mouse) {
return ImGui::IsMouseDoubleClicked(mouse);
}
bool menuItem(std::string& txt) {
return ImGui::MenuItem(txt.c_str());
}
void dragDropSource(std::string& id, CScriptAny* data, std::string& debugText) {
if (DragDropPayload::payload && !ImGui::GetDragDropPayload()) {
DragDropPayload::payload->Release();
DragDropPayload::payload = nullptr;
}
data->AddRef();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginDragDropSource()) {
if (DragDropPayload::payload)
DragDropPayload::payload->Release();
DragDropPayload::payload = data;
ImGui::SetDragDropPayload(id.c_str(), nullptr, 0);
ImGui::Text("%s", debugText.c_str());
ImGui::EndDragDropSource();
}
ImGui::PopStyleVar();
}
void dragDropTarget(std::string& id, CScriptAny* data, asIScriptFunction* func) {
if (ImGui::BeginDragDropTarget()) {
if (ImGui::AcceptDragDropPayload(id.c_str()) && DragDropPayload::payload) {
if (scriptContext && scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->SetArgObject(0, data));
AS_CHECK(scriptContext->SetArgObject(1, DragDropPayload::payload));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
}
DragDropPayload::payload->Release();
DragDropPayload::payload = nullptr;
}
ImGui::EndDragDropTarget();
}
}
bool inputText(std::string& id, std::string& in, std::string& text) {
static char buffer[256];
strncpy(buffer, in.c_str(), sizeof(buffer));
buffer[sizeof(buffer) - 1] = '\0';
bool edited = ImGui::InputText(id.c_str(), buffer, sizeof(buffer));
if (edited) {
text = buffer;
}
return edited;
}
#include "imgui.h"
float magicSlider(std::string& txt, float value, float speed) {
ImGui::PushID(txt.c_str());
static ImGuiID id = 0;
float tmp = value;
bool value_changed = false;
ImGui::Text("%s", txt.c_str());
ImGui::SameLine();
if (id == ImGui::GetID(txt.c_str()))
{
// — Input mode —
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputFloat("##input", &tmp, 0.0f, 0.0f, "%.2f",
ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll))
{
value_changed = true;
id = 0;
}
// Cancel if click away or Esc
if (!ImGui::IsItemActive() && !ImGui::IsItemHovered()){
value_changed = true;
id = 0;
}
}
else
{
// — Drag mode (unbounded) —
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
ImGui::DragFloat("##input", &tmp, speed, 0.0f, 0.0f, "%.2f");
if (ImGui::IsItemActive())
value_changed = true;
// Click to enter edit mode
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
id = ImGui::GetID(txt.c_str());
ImGui::SetKeyboardFocusHere(0);
}
}
if (value_changed)
value = tmp;
ImGui::PopID();
return value;
}
glm::vec3 magicSlider3(std::string& txt, glm::vec3 value, float speed) {
static ImGuiID id = 0;
glm::vec3 tmp = value;
bool value_changed = false;
ImGui::Columns(4, nullptr, false);
ImGui::PushID(txt.c_str());
ImGui::Text("%s", txt.c_str());
ImGui::NextColumn();
for (int i = 0; i < 3; i++) {
ImGui::PushID(i);
if (id == ImGui::GetID("##input"))
{
// — Input mode —
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputFloat("##input", &tmp[i], 0.0f, 0.0f, "%.2f",
ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll))
{
value_changed = true;
id = 0;
}
// Cancel if click away or Esc
if (!ImGui::IsItemActive() && !ImGui::IsItemHovered()){
value_changed = true;
id = 0;
}
}
else
{
// — Drag mode (unbounded) —
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
ImGui::DragFloat("##input", &tmp[i], speed, 0.0f, 0.0f, "%.2f");
if (ImGui::IsItemActive())
value_changed = true;
// Click to enter edit mode
if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
id = ImGui::GetID("##input");
ImGui::SetKeyboardFocusHere(-1);
}
}
ImGui::PopID();
ImGui::NextColumn();
}
ImGui::Columns();
ImGui::PopID();
if (value_changed)
value = tmp;
return value;
}
}
}