ui: Make pattern editor console use another text editor
This commit is contained in:
parent
5c31b5cf0d
commit
dd832bfa7e
5
lib/external/imgui/include/TextEditor.h
vendored
5
lib/external/imgui/include/TextEditor.h
vendored
@ -212,6 +212,9 @@ public:
|
||||
bool IsTextChanged() const { return mTextChanged; }
|
||||
bool IsCursorPositionChanged() const { return mCursorPositionChanged; }
|
||||
|
||||
void SetShowCursor(bool aValue) { mShowCursor = aValue; }
|
||||
void SetShowLineNumbers(bool aValue) { mShowLineNumbers = aValue; }
|
||||
|
||||
bool IsColorizerEnabled() const { return mColorizerEnabled; }
|
||||
void SetColorizerEnable(bool aValue);
|
||||
|
||||
@ -386,6 +389,8 @@ private:
|
||||
uint64_t mStartTime;
|
||||
|
||||
float mLastClick;
|
||||
bool mShowCursor;
|
||||
bool mShowLineNumbers;
|
||||
};
|
||||
|
||||
bool TokenizeCStyleString(const char * in_begin, const char * in_end, const char *& out_begin, const char *& out_end);
|
||||
|
10
lib/external/imgui/source/TextEditor.cpp
vendored
10
lib/external/imgui/source/TextEditor.cpp
vendored
@ -24,7 +24,7 @@ bool equals(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Bi
|
||||
TextEditor::Palette TextEditor::sPaletteBase = TextEditor::GetDarkPalette();
|
||||
|
||||
TextEditor::TextEditor()
|
||||
: mLineSpacing(1.0f), mUndoIndex(0), mTabSize(4), mOverwrite(false), mReadOnly(false), mWithinRender(false), mScrollToCursor(false), mScrollToTop(false), mTextChanged(false), mColorizerEnabled(true), mTextStart(20.0f), mLeftMargin(10), mCursorPositionChanged(false), mColorRangeMin(0), mColorRangeMax(0), mSelectionMode(SelectionMode::Normal), mCheckComments(true), mLastClick(-1.0f), mHandleKeyboardInputs(true), mHandleMouseInputs(true), mIgnoreImGuiChild(false), mShowWhitespaces(true), mStartTime(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count()) {
|
||||
: mLineSpacing(1.0f), mUndoIndex(0), mTabSize(4), mOverwrite(false), mReadOnly(false), mWithinRender(false), mScrollToCursor(false), mScrollToTop(false), mTextChanged(false), mColorizerEnabled(true), mTextStart(20.0f), mLeftMargin(10), mCursorPositionChanged(false), mColorRangeMin(0), mColorRangeMax(0), mSelectionMode(SelectionMode::Normal), mCheckComments(true), mLastClick(-1.0f), mHandleKeyboardInputs(true), mHandleMouseInputs(true), mIgnoreImGuiChild(false), mShowWhitespaces(true), mShowCursor(true), mShowLineNumbers(true), mStartTime(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count()) {
|
||||
SetLanguageDefinition(LanguageDefinition::HLSL());
|
||||
mLines.push_back(Line());
|
||||
}
|
||||
@ -788,7 +788,11 @@ void TextEditor::Render() {
|
||||
|
||||
// Deduce mTextStart by evaluating mLines size (global lineMax) plus two spaces as text width
|
||||
char buf[16];
|
||||
snprintf(buf, 16, " %d ", globalLineMax);
|
||||
|
||||
if (mShowLineNumbers)
|
||||
snprintf(buf, 16, " %d ", globalLineMax);
|
||||
else
|
||||
buf[0] = '\0';
|
||||
mTextStart = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize(), FLT_MAX, -1.0f, buf, nullptr, nullptr).x + mLeftMargin;
|
||||
|
||||
if (!mLines.empty()) {
|
||||
@ -859,7 +863,7 @@ void TextEditor::Render() {
|
||||
drawList->AddCircle(start + ImVec2(0, mCharAdvance.y) / 2, mCharAdvance.y / 3, mPalette[(int)PaletteIndex::Default]);
|
||||
}
|
||||
|
||||
if (mState.mCursorPosition.mLine == lineNo) {
|
||||
if (mState.mCursorPosition.mLine == lineNo && mShowCursor) {
|
||||
auto focused = ImGui::IsWindowFocused();
|
||||
|
||||
// Highlight the current line (where the cursor is)
|
||||
|
@ -139,7 +139,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
bool m_hasUnevaluatedChanges = false;
|
||||
|
||||
TextEditor m_textEditor;
|
||||
TextEditor m_textEditor, m_consoleEditor;
|
||||
|
||||
std::atomic<bool> m_dangerousFunctionCalled = false;
|
||||
std::atomic<DangerousFunctionPerms> m_dangerousFunctionsAllowed = DangerousFunctionPerms::Ask;
|
||||
@ -152,7 +152,7 @@ namespace hex::plugin::builtin {
|
||||
ui::HexEditor m_sectionHexEditor;
|
||||
|
||||
PerProvider<std::string> m_sourceCode;
|
||||
PerProvider<std::vector<std::pair<pl::core::LogConsole::Level, std::string>>> m_console;
|
||||
PerProvider<std::vector<std::string>> m_console;
|
||||
PerProvider<bool> m_executionDone = true;
|
||||
|
||||
std::mutex m_logMutex;
|
||||
@ -170,7 +170,7 @@ namespace hex::plugin::builtin {
|
||||
std::atomic<bool> m_resetDebuggerVariables;
|
||||
|
||||
private:
|
||||
void drawConsole(ImVec2 size, const std::vector<std::pair<pl::core::LogConsole::Level, std::string>> &console);
|
||||
void drawConsole(ImVec2 size);
|
||||
void drawEnvVars(ImVec2 size, std::list<EnvVar> &envVars);
|
||||
void drawVariableSettings(ImVec2 size, std::map<std::string, PatternVariable> &patternVariables);
|
||||
void drawSectionSelector(ImVec2 size, std::map<u64, pl::api::Section> §ions);
|
||||
|
@ -83,6 +83,41 @@ namespace hex::plugin::builtin {
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return langDef;
|
||||
}
|
||||
|
||||
static const TextEditor::LanguageDefinition &ConsoleLog() {
|
||||
static bool initialized = false;
|
||||
static TextEditor::LanguageDefinition langDef;
|
||||
if (!initialized) {
|
||||
langDef.mTokenize = [](const char *inBegin, const char *inEnd, const char *&outBegin, const char *&outEnd, TextEditor::PaletteIndex &paletteIndex) -> bool {
|
||||
if (std::string_view(inBegin).starts_with("D: "))
|
||||
paletteIndex = TextEditor::PaletteIndex::Comment;
|
||||
else if (std::string_view(inBegin).starts_with("I: "))
|
||||
paletteIndex = TextEditor::PaletteIndex::Default;
|
||||
else if (std::string_view(inBegin).starts_with("W: "))
|
||||
paletteIndex = TextEditor::PaletteIndex::Preprocessor;
|
||||
else if (std::string_view(inBegin).starts_with("E: "))
|
||||
paletteIndex = TextEditor::PaletteIndex::ErrorMarker;
|
||||
else
|
||||
paletteIndex = TextEditor::PaletteIndex::Max;
|
||||
|
||||
outBegin = inBegin;
|
||||
outEnd = inEnd;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
langDef.mName = "Console Log";
|
||||
langDef.mCaseSensitive = false;
|
||||
langDef.mAutoIndentation = false;
|
||||
langDef.mCommentStart = "\x01";
|
||||
langDef.mCommentEnd = "\x01";
|
||||
langDef.mSingleLineComment = "\x01";
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
return langDef;
|
||||
}
|
||||
|
||||
@ -93,6 +128,12 @@ namespace hex::plugin::builtin {
|
||||
this->m_textEditor.SetLanguageDefinition(PatternLanguage());
|
||||
this->m_textEditor.SetShowWhitespaces(false);
|
||||
|
||||
this->m_consoleEditor.SetLanguageDefinition(ConsoleLog());
|
||||
this->m_consoleEditor.SetShowWhitespaces(false);
|
||||
this->m_consoleEditor.SetReadOnly(true);
|
||||
this->m_consoleEditor.SetShowCursor(false);
|
||||
this->m_consoleEditor.SetShowLineNumbers(false);
|
||||
|
||||
this->registerEvents();
|
||||
this->registerMenuItems();
|
||||
this->registerHandlers();
|
||||
@ -101,7 +142,6 @@ namespace hex::plugin::builtin {
|
||||
ViewPatternEditor::~ViewPatternEditor() {
|
||||
EventManager::unsubscribe<RequestSetPatternLanguageCode>(this);
|
||||
EventManager::unsubscribe<EventFileLoaded>(this);
|
||||
EventManager::unsubscribe<RequestChangeTheme>(this);
|
||||
EventManager::unsubscribe<EventProviderChanged>(this);
|
||||
EventManager::unsubscribe<EventProviderClosed>(this);
|
||||
}
|
||||
@ -135,7 +175,7 @@ namespace hex::plugin::builtin {
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
|
||||
}
|
||||
|
||||
|
||||
if (dragging) {
|
||||
height += ImGui::GetMouseDragDelta(ImGuiMouseButton_Left, 0).y;
|
||||
ImGui::ResetMouseDragDelta(ImGuiMouseButton_Left);
|
||||
@ -146,7 +186,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if (ImGui::BeginTabBar("##settings")) {
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.console"_lang)) {
|
||||
this->drawConsole(settingsSize, *this->m_console);
|
||||
this->drawConsole(settingsSize);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.env_vars"_lang)) {
|
||||
@ -257,47 +297,9 @@ namespace hex::plugin::builtin {
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void ViewPatternEditor::drawConsole(ImVec2 size, const std::vector<std::pair<pl::core::LogConsole::Level, std::string>> &console) {
|
||||
const auto &palette = TextEditor::GetPalette();
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, palette[u32(TextEditor::PaletteIndex::Background)]);
|
||||
if (ImGui::BeginChild("##console", size, true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_HorizontalScrollbar)) {
|
||||
ImGuiListClipper clipper;
|
||||
|
||||
std::scoped_lock lock(this->m_logMutex);
|
||||
clipper.Begin(console.size());
|
||||
|
||||
while (clipper.Step())
|
||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
||||
auto [level, message] = console[i];
|
||||
std::replace_if(message.begin(), message.end(), [](char c) { return c == 0x00; }, ' ');
|
||||
|
||||
switch (level) {
|
||||
using enum pl::core::LogConsole::Level;
|
||||
|
||||
case Debug:
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, palette[u32(TextEditor::PaletteIndex::Comment)]);
|
||||
break;
|
||||
case Info:
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, palette[u32(TextEditor::PaletteIndex::Default)]);
|
||||
break;
|
||||
case Warning:
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, palette[u32(TextEditor::PaletteIndex::Preprocessor)]);
|
||||
break;
|
||||
case Error:
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, palette[u32(TextEditor::PaletteIndex::ErrorMarker)]);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ImGui::Selectable(hex::format("{}##ConsoleLine", message).c_str()))
|
||||
ImGui::SetClipboardText(message.c_str());
|
||||
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleColor(1);
|
||||
void ViewPatternEditor::drawConsole(ImVec2 size) {
|
||||
this->m_consoleEditor.Render("##console", size, true);
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + ImGui::GetStyle().FramePadding.y + 1_scaled);
|
||||
}
|
||||
|
||||
void ViewPatternEditor::drawEnvVars(ImVec2 size, std::list<EnvVar> &envVars) {
|
||||
@ -898,7 +900,21 @@ namespace hex::plugin::builtin {
|
||||
|
||||
runtime.setLogCallback([this](auto level, auto message) {
|
||||
std::scoped_lock lock(this->m_logMutex);
|
||||
this->m_console->emplace_back(level, message);
|
||||
|
||||
for (auto line : wolv::util::splitString(message, "\n")) {
|
||||
switch (level) {
|
||||
using enum pl::core::LogConsole::Level;
|
||||
|
||||
case Debug: line = hex::format("D: {}", line); break;
|
||||
case Info: line = hex::format("I: {}", line); break;
|
||||
case Warning: line = hex::format("W: {}", line); break;
|
||||
case Error: line = hex::format("E: {}", line); break;
|
||||
}
|
||||
|
||||
this->m_console->emplace_back(line);
|
||||
}
|
||||
|
||||
this->m_consoleEditor.SetTextLines(this->m_console.get());
|
||||
});
|
||||
|
||||
ON_SCOPE_EXIT {
|
||||
@ -911,9 +927,9 @@ namespace hex::plugin::builtin {
|
||||
|
||||
std::scoped_lock lock(this->m_logMutex);
|
||||
this->m_console->emplace_back(
|
||||
pl::core::LogConsole::Level::Info,
|
||||
hex::format("Evaluation took {}", runtime.getLastRunningTime())
|
||||
hex::format("I: Evaluation took {}", runtime.getLastRunningTime())
|
||||
);
|
||||
this->m_consoleEditor.SetTextLines(this->m_console.get());
|
||||
};
|
||||
|
||||
|
||||
@ -958,8 +974,10 @@ namespace hex::plugin::builtin {
|
||||
if (oldProvider != nullptr)
|
||||
this->m_sourceCode.get(oldProvider) = this->m_textEditor.GetText();
|
||||
|
||||
if (newProvider != nullptr)
|
||||
if (newProvider != nullptr) {
|
||||
this->m_consoleEditor.SetTextLines(this->m_console.get(newProvider));
|
||||
this->m_textEditor.SetText(wolv::util::trim(this->m_sourceCode.get(newProvider)));
|
||||
}
|
||||
else
|
||||
this->m_textEditor.SetText("");
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user