LumixEngine/src/editor/log_ui.cpp

247 lines
5 KiB
C++
Raw Normal View History

2015-09-14 18:03:45 +02:00
#include "log_ui.h"
2016-06-05 20:25:09 +02:00
#include "editor/platform_interface.h"
2016-05-10 08:24:31 +02:00
#include "engine/log.h"
2015-12-23 19:52:09 +01:00
#include "imgui/imgui.h"
2015-09-14 18:03:45 +02:00
2017-05-23 19:57:11 +02:00
namespace Lumix
{
LogUI::LogUI(IAllocator& allocator)
2015-09-14 18:03:45 +02:00
: m_allocator(allocator)
, m_messages(allocator)
2016-08-22 21:27:11 +02:00
, m_current_tab(Error)
2015-09-14 18:03:45 +02:00
, m_notifications(allocator)
, m_last_uid(1)
, m_guard(false)
2017-08-20 00:16:42 +02:00
, m_is_open(false)
2016-06-15 15:28:07 +02:00
, m_are_notifications_hovered(false)
, m_move_notifications_to_front(false)
2015-09-14 18:03:45 +02:00
{
2017-05-23 19:57:11 +02:00
g_log_info.getCallback().bind<LogUI, &LogUI::onInfo>(this);
g_log_error.getCallback().bind<LogUI, &LogUI::onError>(this);
g_log_warning.getCallback().bind<LogUI, &LogUI::onWarning>(this);
2015-09-14 18:03:45 +02:00
for (int i = 0; i < Count; ++i)
{
m_new_message_count[i] = 0;
m_messages.emplace(allocator);
}
}
LogUI::~LogUI()
{
2017-05-23 19:57:11 +02:00
g_log_info.getCallback().unbind<LogUI, &LogUI::onInfo>(this);
g_log_error.getCallback().unbind<LogUI, &LogUI::onError>(this);
g_log_warning.getCallback().unbind<LogUI, &LogUI::onWarning>(this);
2015-09-14 18:03:45 +02:00
}
void LogUI::setNotificationTime(int uid, float time)
{
for (auto& notif : m_notifications)
{
if (notif.uid == uid)
{
notif.time = time;
break;
}
}
}
int LogUI::addNotification(const char* text)
{
m_move_notifications_to_front = true;
if (!m_notifications.empty() && m_notifications.back().message == text) return -1;
auto& notif = m_notifications.emplace(m_allocator);
notif.time = 10.0f;
notif.message = text;
notif.uid = ++m_last_uid;
return notif.uid;
}
2015-09-14 18:03:45 +02:00
void LogUI::push(Type type, const char* message)
{
2017-05-23 19:57:11 +02:00
MT::SpinLock lock(m_guard);
2015-09-14 18:03:45 +02:00
++m_new_message_count[type];
2017-05-23 19:57:11 +02:00
m_messages[type].push(string(message, m_allocator));
2015-09-14 18:03:45 +02:00
if (type == Error)
2015-09-14 18:03:45 +02:00
{
addNotification(message);
2015-09-14 18:03:45 +02:00
}
}
void LogUI::onInfo(const char* system, const char* message)
{
2016-02-14 16:49:37 +01:00
push(Info, message);
2015-09-14 18:03:45 +02:00
}
void LogUI::onWarning(const char* system, const char* message)
{
2016-02-14 16:49:37 +01:00
push(Warning, message);
2015-09-14 18:03:45 +02:00
}
void LogUI::onError(const char* system, const char* message)
{
2016-02-14 16:49:37 +01:00
push(Error, message);
2015-09-14 18:03:45 +02:00
}
void fillLabel(char* output, int max_size, const char* label, int count)
{
2017-05-23 19:57:11 +02:00
copyString(output, max_size, label);
catString(output, max_size, "(");
int len = stringLength(output);
toCString(count, output + len, max_size - len);
catString(output, max_size, ")###");
catString(output, max_size, label);
2015-09-14 18:03:45 +02:00
}
void LogUI::showNotifications()
{
m_are_notifications_hovered = false;
2015-09-14 18:03:45 +02:00
if (m_notifications.empty()) return;
ImGui::SetNextWindowPos(ImVec2(10, 30));
2017-09-28 14:45:20 +02:00
bool open;
if (!ImGui::Begin("Notifications",
2017-09-28 14:45:20 +02:00
&open,
2016-01-28 14:17:22 +01:00
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings |
ImGuiWindowFlags_ShowBorders))
2015-09-14 18:03:45 +02:00
{
ImGui::End();
2015-09-14 18:03:45 +02:00
return;
}
m_are_notifications_hovered = ImGui::IsWindowHovered();
if (ImGui::Button("Close")) m_notifications.clear();
if (m_move_notifications_to_front) ImGui::BringToFront();
m_move_notifications_to_front = false;
2015-09-14 18:03:45 +02:00
for (int i = 0; i < m_notifications.size(); ++i)
{
if (i > 0) ImGui::Separator();
ImGui::Text("%s", m_notifications[i].message.c_str());
2015-09-14 18:03:45 +02:00
}
ImGui::End();
2015-09-14 18:03:45 +02:00
}
void LogUI::update(float time_delta)
{
if (m_are_notifications_hovered) return;
2015-09-14 18:03:45 +02:00
for (int i = 0; i < m_notifications.size(); ++i)
{
m_notifications[i].time -= time_delta;
if (m_notifications[i].time < 0)
{
m_notifications.erase(i);
--i;
}
}
}
2016-02-12 22:31:05 +01:00
int LogUI::getUnreadErrorCount() const
{
return m_new_message_count[Error];
}
2015-10-03 01:14:38 +02:00
void LogUI::onGUI()
2015-09-14 18:03:45 +02:00
{
2017-05-23 19:57:11 +02:00
MT::SpinLock lock(m_guard);
2015-09-25 23:03:10 +02:00
showNotifications();
2017-08-20 00:16:42 +02:00
if (ImGui::BeginDock("Log", &m_is_open))
2015-09-14 18:03:45 +02:00
{
2016-02-14 16:49:37 +01:00
const char* labels[] = { "Info", "Warning", "Error" };
2017-05-23 19:57:11 +02:00
for (int i = 0; i < lengthOf(labels); ++i)
2015-09-14 18:03:45 +02:00
{
char label[40];
2015-09-14 18:03:45 +02:00
fillLabel(label, sizeof(label), labels[i], m_new_message_count[i]);
if(i > 0) ImGui::SameLine();
if (ImGui::Button(label))
2015-09-14 18:03:45 +02:00
{
m_current_tab = i;
m_new_message_count[i] = 0;
}
}
2015-09-14 18:03:45 +02:00
auto* messages = &m_messages[m_current_tab];
if (ImGui::Button("Clear"))
2015-09-14 18:03:45 +02:00
{
for (int i = 0; i < m_messages.size(); ++i)
{
m_messages[m_current_tab].clear();
m_new_message_count[m_current_tab] = 0;
2015-09-14 18:03:45 +02:00
}
}
ImGui::SameLine();
2015-09-14 18:03:45 +02:00
char filter[128] = "";
2017-10-19 17:48:53 +02:00
ImGui::LabellessInputText("Filter", filter, sizeof(filter));
2016-06-05 20:25:09 +02:00
int len = 0;
if (ImGui::Button("Copy to clipboard"))
{
for (int i = 0; i < messages->size(); ++i)
{
const char* msg = (*messages)[i].c_str();
if (filter[0] == '\0' || strstr(msg, filter) != nullptr)
{
2017-05-23 19:57:11 +02:00
len += stringLength(msg);
2016-06-05 20:25:09 +02:00
}
}
if (len > 0)
2016-06-05 20:25:09 +02:00
{
char* mem = (char*)m_allocator.allocate(len);
mem[0] = '\0';
for (int i = 0; i < messages->size(); ++i)
2016-06-05 20:25:09 +02:00
{
const char* msg = (*messages)[i].c_str();
if (filter[0] == '\0' || strstr(msg, filter) != nullptr)
{
2017-05-23 19:57:11 +02:00
catString(mem, len, msg);
catString(mem, len, "\n");
}
2016-06-05 20:25:09 +02:00
}
PlatformInterface::copyToClipboard(mem);
m_allocator.deallocate(mem);
}
2016-06-05 20:25:09 +02:00
}
2015-09-14 18:03:45 +02:00
if (ImGui::BeginChild("log_messages"))
2015-09-14 18:03:45 +02:00
{
2015-10-15 20:53:13 +02:00
for (int i = 0; i < messages->size(); ++i)
2015-09-14 18:03:45 +02:00
{
2015-10-15 20:53:13 +02:00
const char* msg = (*messages)[i].c_str();
if (filter[0] == '\0' || strstr(msg, filter) != nullptr)
{
2016-08-12 15:20:02 +02:00
ImGui::TextUnformatted(msg);
2015-10-15 20:53:13 +02:00
}
2015-09-14 18:03:45 +02:00
}
}
ImGui::EndChild();
2015-09-14 18:03:45 +02:00
}
2016-01-01 20:31:34 +01:00
ImGui::EndDock();
2015-09-14 18:03:45 +02:00
}
2017-05-23 19:57:11 +02:00
} // namespace Lumix