1
0
mirror of synced 2025-01-18 09:04:52 +01:00

ui: Make pattern editor console use another text editor

This commit is contained in:
WerWolv 2023-06-13 22:58:57 +02:00
parent 5c31b5cf0d
commit dd832bfa7e
4 changed files with 81 additions and 54 deletions

View File

@ -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);

View File

@ -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)

View File

@ -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> &sections);

View File

@ -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 {