impr: Moved pattern editor shortcuts to the Shortcut manager (#1892)
### Problem description There are some recent issues about Mac keys not configured properly for the pattern editor. This PR moves all the shortcuts to the shortcut manager, so they can be edited at will. Even if the key is not identified correctly it should be possible to use preferred keys for any action. --------- Co-authored-by: Nik <werwolv98@gmail.com>
This commit is contained in:
parent
187d90e8f2
commit
4b3bbb4a97
@ -215,6 +215,7 @@ public:
|
||||
FindReplaceHandler *GetFindReplaceHandler() { return &mFindReplaceHandler; }
|
||||
int GetTotalLines() const { return (int)mLines.size(); }
|
||||
bool IsOverwrite() const { return mOverwrite; }
|
||||
void SetOverwrite(bool aValue) { mOverwrite = aValue; }
|
||||
|
||||
void SetReadOnly(bool aValue);
|
||||
bool IsReadOnly() const { return mReadOnly; }
|
||||
@ -268,6 +269,7 @@ public:
|
||||
void Cut();
|
||||
void Paste();
|
||||
void Delete();
|
||||
int32_t GetPageSize() const;
|
||||
|
||||
ImVec2 &GetCharAdvance() { return mCharAdvance; }
|
||||
|
||||
@ -276,6 +278,10 @@ public:
|
||||
void Undo(int aSteps = 1);
|
||||
void Redo(int aSteps = 1);
|
||||
|
||||
void DeleteWordLeft();
|
||||
void DeleteWordRight();
|
||||
void Backspace();
|
||||
|
||||
static const Palette& GetDarkPalette();
|
||||
static const Palette& GetLightPalette();
|
||||
static const Palette& GetRetroBluePalette();
|
||||
@ -400,7 +406,6 @@ private:
|
||||
void ColorizeInternal();
|
||||
float TextDistanceToLineStart(const Coordinates& aFrom) const;
|
||||
void EnsureCursorVisible();
|
||||
int GetPageSize() const;
|
||||
std::string GetText(const Coordinates& aStart, const Coordinates& aEnd) const;
|
||||
Coordinates GetActualCursorCoordinates() const;
|
||||
Coordinates SanitizeCoordinates(const Coordinates& aValue) const;
|
||||
@ -425,7 +430,6 @@ private:
|
||||
void RemoveLine(int aIndex);
|
||||
Line& InsertLine(int aIndex);
|
||||
void EnterCharacter(ImWchar aChar, bool aShift);
|
||||
void Backspace();
|
||||
void DeleteSelection();
|
||||
std::string GetWordUnderCursor() const;
|
||||
std::string GetWordAt(const Coordinates& aCoords) const;
|
||||
|
@ -304,6 +304,22 @@ TextEditor::Coordinates TextEditor::ScreenPosToCoordinates(const ImVec2 &aPositi
|
||||
return SanitizeCoordinates(Coordinates(lineNo, columnCoord));
|
||||
}
|
||||
|
||||
void TextEditor::DeleteWordLeft() {
|
||||
const auto wordEnd = GetCursorPosition();
|
||||
MoveLeft();
|
||||
const auto wordStart = FindWordStart(GetCursorPosition());
|
||||
SetSelection(wordStart, wordEnd);
|
||||
Backspace();
|
||||
}
|
||||
|
||||
void TextEditor::DeleteWordRight() {
|
||||
const auto wordStart = GetCursorPosition();
|
||||
MoveRight();
|
||||
const auto wordEnd = FindWordEnd(GetCursorPosition());
|
||||
SetSelection(wordStart, wordEnd);
|
||||
Backspace();
|
||||
}
|
||||
|
||||
bool isWordChar(char c) {
|
||||
auto asUChar = static_cast<unsigned char>(c);
|
||||
return std::isalnum(asUChar) || c == '_' || asUChar > 0x7F;
|
||||
@ -640,21 +656,21 @@ void TextEditor::HandleKeyboardInputs() {
|
||||
// command => Ctrl
|
||||
// control => Super
|
||||
// option => Alt
|
||||
|
||||
auto ctrl = io.KeyCtrl;
|
||||
auto alt = io.KeyAlt;
|
||||
auto shift = io.KeyShift;
|
||||
auto left = ImGui::IsKeyPressed(ImGuiKey_LeftArrow);
|
||||
/* auto left = ImGui::IsKeyPressed(ImGuiKey_LeftArrow);
|
||||
auto right = ImGui::IsKeyPressed(ImGuiKey_RightArrow);
|
||||
auto up = ImGui::IsKeyPressed(ImGuiKey_UpArrow);
|
||||
auto down = ImGui::IsKeyPressed(ImGuiKey_DownArrow);
|
||||
auto ctrl = io.KeyCtrl;
|
||||
auto alt = io.KeyAlt;
|
||||
|
||||
auto home = io.ConfigMacOSXBehaviors ? io.KeySuper && left : ImGui::IsKeyPressed(ImGuiKey_Home);
|
||||
auto end = io.ConfigMacOSXBehaviors ? io.KeySuper && right : ImGui::IsKeyPressed(ImGuiKey_End);
|
||||
auto top = io.ConfigMacOSXBehaviors ? io.KeySuper && up : ctrl && ImGui::IsKeyPressed(ImGuiKey_Home);
|
||||
auto bottom = io.ConfigMacOSXBehaviors ? io.KeySuper && down : ctrl && ImGui::IsKeyPressed(ImGuiKey_End);
|
||||
auto pageUp = io.ConfigMacOSXBehaviors ? ctrl && up : ImGui::IsKeyPressed(ImGuiKey_PageUp);
|
||||
auto pageDown = io.ConfigMacOSXBehaviors ? ctrl && down : ImGui::IsKeyPressed(ImGuiKey_PageDown);
|
||||
|
||||
*/
|
||||
if (ImGui::IsWindowFocused()) {
|
||||
if (ImGui::IsWindowHovered())
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_TextInput);
|
||||
@ -663,87 +679,10 @@ void TextEditor::HandleKeyboardInputs() {
|
||||
io.WantCaptureKeyboard = true;
|
||||
io.WantTextInput = true;
|
||||
|
||||
bool handledKeyEvent = true;
|
||||
|
||||
if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Z))
|
||||
Undo();
|
||||
else if (!IsReadOnly() && !ctrl && !shift && alt && ImGui::IsKeyPressed(ImGuiKey_Backspace))
|
||||
Undo();
|
||||
else if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Y))
|
||||
Redo();
|
||||
else if (!ctrl && !alt && up)
|
||||
MoveUp(1, shift);
|
||||
else if (!ctrl && !alt && down)
|
||||
MoveDown(1, shift);
|
||||
else if (!alt && left)
|
||||
MoveLeft(1, shift, ctrl);
|
||||
else if (!alt && right)
|
||||
MoveRight(1, shift, ctrl);
|
||||
else if (!alt && pageUp)
|
||||
MoveUp(GetPageSize() - 4, shift);
|
||||
else if (!alt && pageDown)
|
||||
MoveDown(GetPageSize() - 4, shift);
|
||||
else if (!alt && top)
|
||||
MoveTop(shift);
|
||||
else if (!alt && bottom)
|
||||
MoveBottom(shift);
|
||||
else if (!ctrl && !alt && home)
|
||||
MoveHome(shift);
|
||||
else if (!ctrl && !alt && end)
|
||||
MoveEnd(shift);
|
||||
else if (!IsReadOnly() && !ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Delete))
|
||||
Delete();
|
||||
else if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Delete)) {
|
||||
auto wordStart = GetCursorPosition();
|
||||
MoveRight();
|
||||
auto wordEnd = FindWordEnd(GetCursorPosition());
|
||||
SetSelection(wordStart, wordEnd);
|
||||
Backspace();
|
||||
}
|
||||
else if (!IsReadOnly() && !ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_Backspace))
|
||||
Backspace();
|
||||
else if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Backspace)) {
|
||||
auto wordEnd = GetCursorPosition();
|
||||
MoveLeft();
|
||||
auto wordStart = FindWordStart(GetCursorPosition());
|
||||
SetSelection(wordStart, wordEnd);
|
||||
Backspace();
|
||||
}
|
||||
else if (!ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Insert))
|
||||
mOverwrite = !mOverwrite;
|
||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Insert))
|
||||
Copy();
|
||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_C))
|
||||
Copy();
|
||||
else if (!IsReadOnly() && !ctrl && shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Insert))
|
||||
Paste();
|
||||
else if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_V))
|
||||
Paste();
|
||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_X))
|
||||
Cut();
|
||||
else if (!ctrl && shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Delete))
|
||||
Cut();
|
||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_A))
|
||||
SelectAll();
|
||||
else if (!IsReadOnly() && !ctrl && !shift && !alt && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter)))
|
||||
if (!IsReadOnly() && !ctrl && !shift && !alt && (ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter)))
|
||||
EnterCharacter('\n', false);
|
||||
else if (!IsReadOnly() && !ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_Tab))
|
||||
EnterCharacter('\t', shift);
|
||||
else if (!ctrl && !alt && !shift && ImGui::IsKeyPressed(ImGuiKey_F3))
|
||||
mFindReplaceHandler.FindMatch(this, true);
|
||||
else if (!ctrl && !alt && shift && ImGui::IsKeyPressed(ImGuiKey_F3))
|
||||
mFindReplaceHandler.FindMatch(this, false);
|
||||
else if (!ctrl && alt && !shift && ImGui::IsKeyPressed(ImGuiKey_C))
|
||||
mFindReplaceHandler.SetMatchCase(this,!mFindReplaceHandler.GetMatchCase());
|
||||
else if (!ctrl && alt && !shift && ImGui::IsKeyPressed(ImGuiKey_R))
|
||||
mFindReplaceHandler.SetFindRegEx(this,!mFindReplaceHandler.GetFindRegEx());
|
||||
else if (!ctrl && alt && !shift && ImGui::IsKeyPressed(ImGuiKey_W))
|
||||
mFindReplaceHandler.SetWholeWord(this,!mFindReplaceHandler.GetWholeWord());
|
||||
else
|
||||
handledKeyEvent = false;
|
||||
|
||||
if (handledKeyEvent)
|
||||
ResetCursorBlinkTime();
|
||||
|
||||
if (!IsReadOnly() && !io.InputQueueCharacters.empty()) {
|
||||
for (int i = 0; i < io.InputQueueCharacters.Size; i++) {
|
||||
|
@ -635,12 +635,12 @@ namespace hex {
|
||||
EventViewOpened::post(view.get());
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
// Pass on currently pressed keys to the shortcut handler
|
||||
for (const auto &key : m_pressedKeys) {
|
||||
ShortcutManager::process(view.get(), io.KeyCtrl, io.KeyAlt, io.KeyShift, io.KeySuper, focused, key);
|
||||
}
|
||||
|
||||
// Pass on currently pressed keys to the shortcut handler
|
||||
for (const auto &key : m_pressedKeys) {
|
||||
ShortcutManager::process(view.get(), io.KeyCtrl, io.KeyAlt, io.KeyShift, io.KeySuper, focused, key);
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,15 @@ namespace pl::ptrn { class Pattern; }
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
|
||||
constexpr static auto textEditorView = "/Pattern editor_";
|
||||
constexpr static auto consoleView = "/##console_";
|
||||
constexpr static auto variablesView = "/##env_vars_";
|
||||
constexpr static auto settingsView = "/##settings_";
|
||||
constexpr static auto sectionsView = "/##sections_table_";
|
||||
constexpr static auto virtualFilesView = "/Virtual File Tree_";
|
||||
constexpr static auto debuggerView = "/##debugger_";
|
||||
|
||||
class PatternSourceCode {
|
||||
public:
|
||||
const std::string& get(prv::Provider *provider) {
|
||||
@ -260,9 +269,13 @@ namespace hex::plugin::builtin {
|
||||
u32 m_accessHistoryIndex = 0;
|
||||
bool m_parentHighlightingEnabled = true;
|
||||
bool m_replaceMode = false;
|
||||
bool m_openFindReplacePopUp = false;
|
||||
|
||||
std::map<std::fs::path, std::string> m_patternNames;
|
||||
|
||||
ImRect m_textEditorHoverBox;
|
||||
ImRect m_consoleHoverBox;
|
||||
std::string m_focusedSubWindowName;
|
||||
|
||||
static inline std::array<std::string,256> m_findHistory;
|
||||
static inline u32 m_findHistorySize = 0;
|
||||
@ -281,7 +294,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
void drawPatternTooltip(pl::ptrn::Pattern *pattern);
|
||||
|
||||
void drawFindReplaceDialog(std::string &findWord, bool &requestFocus, u64 &position, u64 &count, bool &updateCount);
|
||||
void drawFindReplaceDialog(TextEditor *textEditor, std::string &findWord, bool &requestFocus, u64 &position, u64 &count, bool &updateCount, bool canReplace);
|
||||
|
||||
void historyInsert(std::array<std::string, 256> &history, u32 &size, u32 &index, const std::string &value);
|
||||
|
||||
@ -290,6 +303,9 @@ namespace hex::plugin::builtin {
|
||||
void parsePattern(const std::string &code, prv::Provider *provider);
|
||||
void evaluatePattern(const std::string &code, prv::Provider *provider);
|
||||
|
||||
TextEditor *getEditorFromFocusedWindow();
|
||||
void setupFindReplace(TextEditor *editor);
|
||||
|
||||
void registerEvents();
|
||||
void registerMenuItems();
|
||||
void registerHandlers();
|
||||
|
@ -920,6 +920,7 @@
|
||||
"hex.builtin.view.pattern_editor.auto": "Auto evaluate",
|
||||
"hex.builtin.view.pattern_editor.breakpoint_hit": "Halted at line {0}",
|
||||
"hex.builtin.view.pattern_editor.console": "Console",
|
||||
"hex.builtin.view.pattern_editor.console.shortcut.copy": "Copy",
|
||||
"hex.builtin.view.pattern_editor.dangerous_function.desc": "This pattern tried to call a dangerous function.\nAre you sure you want to trust this pattern?",
|
||||
"hex.builtin.view.pattern_editor.dangerous_function.name": "Allow dangerous function?",
|
||||
"hex.builtin.view.pattern_editor.debugger": "Debugger",
|
||||
@ -958,6 +959,51 @@
|
||||
"hex.builtin.view.pattern_editor.sections.view": "View content",
|
||||
"hex.builtin.view.pattern_editor.sections.export": "Export content",
|
||||
"hex.builtin.view.pattern_editor.settings": "Settings",
|
||||
"hex.builtin.view.pattern_editor.shortcut.find": "Search ...",
|
||||
"hex.builtin.view.pattern_editor.shortcut.replace": "Replace ...",
|
||||
"hex.builtin.view.pattern_editor.shortcut.find_next": "Find Next",
|
||||
"hex.builtin.view.pattern_editor.shortcut.find_previous": "Find Previous",
|
||||
"hex.builtin.view.pattern_editor.shortcut.match_case_toggle": "Toggle Case Sensitive Search",
|
||||
"hex.builtin.view.pattern_editor.shortcut.regex_toggle": "Toggle Regular Expression Search/Replace",
|
||||
"hex.builtin.view.pattern_editor.shortcut.whole_word_toggle": "Toggle Whole Word Search",
|
||||
"hex.builtin.view.pattern_editor.shortcut.save_project": "Save Project",
|
||||
"hex.builtin.view.pattern_editor.shortcut.open_project": "Open Project ...",
|
||||
"hex.builtin.view.pattern_editor.shortcut.save_project_as": "Save Project As ...",
|
||||
"hex.builtin.view.pattern_editor.shortcut.copy": "Copy Selection to the Clipboard",
|
||||
"hex.builtin.view.pattern_editor.shortcut.cut": "Copy Selection to the Clipboard and Delete it",
|
||||
"hex.builtin.view.pattern_editor.shortcut.paste": "Paste Clipboard Contents at the Cursor Position",
|
||||
"hex.builtin.view.pattern_editor.shortcut.undo": "Undo",
|
||||
"hex.builtin.view.pattern_editor.shortcut.redo": "Redo",
|
||||
"hex.builtin.view.pattern_editor.shortcut.toggle_insert": "Toggle Write Over",
|
||||
"hex.builtin.view.pattern_editor.shortcut.delete": "Delete One Character at the Cursor Position",
|
||||
"hex.builtin.view.pattern_editor.shortcut.backspace": "Delete One Character to the Left of Cursor",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_all": "Select Entire File",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_left": "Extend Selection One Character to the Left of the Cursor",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_right": "Extend Selection One Character to the Right of the Cursor",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_word_left": "Extend Selection One Word to the Left of the Cursor",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_word_right": "Extend Selection One Word to the Right of the Cursor",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_up": "Extend Selection One Line Up from the Cursor",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_down": "Extend Selection One Line Down from the Cursor",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_page_up": "Extend Selection One Page Up from the Cursor",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_page_down": "Extend Selection One Page Down from the Cursor",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_home": "Extend Selection to the Start of the Line",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_end": "Extend Selection to the End of the Line",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_top": "Extend Selection to the Start of the File",
|
||||
"hex.builtin.view.pattern_editor.shortcut.select_bottom": "Extend Selection to the End of the File",
|
||||
"hex.builtin.view.pattern_editor.shortcut.move_left": "Move Cursor One Character to the Left",
|
||||
"hex.builtin.view.pattern_editor.shortcut.move_right": "Move Cursor One Character to the Right",
|
||||
"hex.builtin.view.pattern_editor.shortcut.move_word_left": "Move Cursor One Word to the Left",
|
||||
"hex.builtin.view.pattern_editor.shortcut.move_word_right": "Move Cursor One Word to the Right",
|
||||
"hex.builtin.view.pattern_editor.shortcut.move_up": "Move Cursor One Line Up",
|
||||
"hex.builtin.view.pattern_editor.shortcut.move_down": "Move Cursor One Line Down",
|
||||
"hex.builtin.view.pattern_editor.shortcut.move_page_up": "Move Cursor One Page Up",
|
||||
"hex.builtin.view.pattern_editor.shortcut.move_page_down": "Move Cursor One Page Down",
|
||||
"hex.builtin.view.pattern_editor.shortcut.move_home": "Move Cursor to the Start of the Line",
|
||||
"hex.builtin.view.pattern_editor.shortcut.move_end": "Move Cursor to the End of the Line",
|
||||
"hex.builtin.view.pattern_editor.shortcut.move_top": "Move Cursor to the Start of the File",
|
||||
"hex.builtin.view.pattern_editor.shortcut.move_bottom": "Move Cursor to the End of the File",
|
||||
"hex.builtin.view.pattern_editor.shortcut.delete_word_left": "Delete One Word to the Left of the Cursor",
|
||||
"hex.builtin.view.pattern_editor.shortcut.delete_word_right": "Delete One Word to the Right of the Cursor",
|
||||
"hex.builtin.view.pattern_editor.shortcut.run_pattern": "Run Pattern",
|
||||
"hex.builtin.view.pattern_editor.shortcut.step_debugger": "Step Debugger",
|
||||
"hex.builtin.view.pattern_editor.shortcut.continue_debugger": "Continue Debugger",
|
||||
|
@ -134,6 +134,12 @@ namespace hex::plugin::builtin {
|
||||
return langDef;
|
||||
}
|
||||
|
||||
int levelId;
|
||||
|
||||
static void loadPatternAsMemoryProvider(const ViewPatternEditor::VirtualFile *file) {
|
||||
ImHexApi::Provider::add<prv::MemoryProvider>(file->data, wolv::util::toUTF8String(file->path.filename()));
|
||||
}
|
||||
|
||||
static void drawVirtualFileTree(const std::vector<const ViewPatternEditor::VirtualFile*> &virtualFiles, u32 level = 0) {
|
||||
ImGui::PushID(level + 1);
|
||||
ON_SCOPE_EXIT { ImGui::PopID(); };
|
||||
@ -148,13 +154,24 @@ namespace hex::plugin::builtin {
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::TextUnformatted(ICON_VS_FILE);
|
||||
ImGui::PushID(levelId);
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::TreeNodeEx(currSegment.c_str(), ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen);
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && ImGui::IsItemHovered()) {
|
||||
ImHexApi::Provider::add<prv::MemoryProvider>(file->data, wolv::util::toUTF8String(file->path.filename()));
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Right) && ImGui::IsItemHovered() && !ImGui::IsMouseDragging(ImGuiMouseButton_Right)) {
|
||||
ImGui::OpenPopup("##virtual_files_context_menu");
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopup("##virtual_files_context_menu")) {
|
||||
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.open_in_new_provider"_lang, nullptr, false)) {
|
||||
loadPatternAsMemoryProvider(file);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) && ImGui::IsItemHovered()) {
|
||||
loadPatternAsMemoryProvider(file);
|
||||
}
|
||||
ImGui::PopID();
|
||||
levelId +=1;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -213,6 +230,101 @@ namespace hex::plugin::builtin {
|
||||
RequestAddVirtualFile::unsubscribe(this);
|
||||
}
|
||||
|
||||
void ViewPatternEditor::setupFindReplace(TextEditor *editor) {
|
||||
|
||||
// Context menu entries that open the find/replace popup
|
||||
ImGui::PushID(editor);
|
||||
static std::string findWord;
|
||||
static bool requestFocus = false;
|
||||
static u64 position = 0;
|
||||
static u64 count = 0;
|
||||
static bool updateCount = false;
|
||||
TextEditor::FindReplaceHandler *findReplaceHandler = editor->GetFindReplaceHandler();
|
||||
static bool canReplace = true;
|
||||
if (m_openFindReplacePopUp) {
|
||||
m_openFindReplacePopUp = false;
|
||||
// Place the popup at the top right of the window
|
||||
auto windowSize = ImGui::GetWindowSize();
|
||||
auto style = ImGui::GetStyle();
|
||||
|
||||
// Set the scrollbar size only if it is visible
|
||||
float scrollbarSize = 0;
|
||||
|
||||
// Calculate the number of lines to display in the text editor
|
||||
auto totalTextHeight = editor->GetTotalLines() * editor->GetCharAdvance().y;
|
||||
|
||||
// Compare it to the window height
|
||||
if (totalTextHeight > windowSize.y)
|
||||
scrollbarSize = style.ScrollbarSize;
|
||||
|
||||
auto labelSize = ImGui::CalcTextSize(ICON_VS_WHOLE_WORD);
|
||||
|
||||
// Six icon buttons
|
||||
auto popupSize = ImVec2({(labelSize.x + style.FramePadding.x * 2.0F) * 6.0F,
|
||||
labelSize.y + style.FramePadding.y * 2.0F + style.WindowPadding.y + 3 });
|
||||
|
||||
// 2 * 11 spacings in between elements
|
||||
popupSize.x += style.FramePadding.x * 22.0F;
|
||||
|
||||
// Text input fields are set to 12 characters wide
|
||||
popupSize.x += ImGui::GetFontSize() * 12.0F;
|
||||
|
||||
// IndexOfCount text
|
||||
popupSize.x += ImGui::CalcTextSize("2000 of 2000").x + 2.0F;
|
||||
popupSize.x += scrollbarSize;
|
||||
|
||||
// Position of popup relative to parent window
|
||||
ImVec2 windowPosForPopup = ImGui::GetWindowPos();
|
||||
|
||||
// Not the window height but the content height
|
||||
windowPosForPopup.y += popupSize.y;
|
||||
|
||||
// Add remaining window height
|
||||
popupSize.y += style.WindowPadding.y + 1;
|
||||
|
||||
// Move to the right so as not to overlap the scrollbar
|
||||
windowPosForPopup.x += windowSize.x - popupSize.x;
|
||||
findReplaceHandler->SetFindWindowPos(windowPosForPopup);
|
||||
|
||||
if (m_replaceMode) {
|
||||
// Remove one window padding
|
||||
popupSize.y -= style.WindowPadding.y;
|
||||
// Add the replace window height
|
||||
popupSize.y *= 2;
|
||||
}
|
||||
|
||||
if (m_focusedSubWindowName.contains(consoleView)) {
|
||||
windowPosForPopup.y = m_consoleHoverBox.Min.y;
|
||||
canReplace = false;
|
||||
} else if (m_focusedSubWindowName.contains(textEditorView))
|
||||
canReplace = true;
|
||||
|
||||
ImGui::SetNextWindowPos(windowPosForPopup);
|
||||
ImGui::SetNextWindowSize(popupSize);
|
||||
ImGui::OpenPopup("##pattern_editor_find_replace");
|
||||
|
||||
findReplaceHandler->resetMatches();
|
||||
|
||||
// Use selection as find word if there is one, otherwise use the word under the cursor
|
||||
if (!editor->HasSelection())
|
||||
editor->SelectWordUnderCursor();
|
||||
|
||||
findWord = editor->GetSelectedText();
|
||||
|
||||
// Find all matches to findWord
|
||||
findReplaceHandler->FindAllMatches(editor,findWord);
|
||||
position = findReplaceHandler->FindPosition(editor,editor->GetCursorPosition(), true);
|
||||
count = findReplaceHandler->GetMatches().size();
|
||||
findReplaceHandler->SetFindWord(editor,findWord);
|
||||
requestFocus = true;
|
||||
updateCount = true;
|
||||
}
|
||||
|
||||
drawFindReplaceDialog(editor, findWord, requestFocus, position, count, updateCount, canReplace);
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void ViewPatternEditor::drawContent() {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
|
||||
@ -221,6 +333,7 @@ namespace hex::plugin::builtin {
|
||||
static bool dragging = false;
|
||||
|
||||
const auto availableSize = ImGui::GetContentRegionAvail();
|
||||
const auto windowPosition = ImGui::GetCursorScreenPos();
|
||||
auto textEditorSize = availableSize;
|
||||
textEditorSize.y *= 3.5 / 5.0;
|
||||
textEditorSize.y -= ImGui::GetTextLineHeightWithSpacing();
|
||||
@ -228,15 +341,20 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if (availableSize.y > 1)
|
||||
textEditorSize.y = std::clamp(textEditorSize.y, 1.0F, std::max(1.0F, availableSize.y - ImGui::GetTextLineHeightWithSpacing() * 3));
|
||||
|
||||
const ImGuiContext& g = *GImGui;
|
||||
if (g.NavWindow != nullptr) {
|
||||
std::string name = g.NavWindow->Name;
|
||||
if (name.contains(textEditorView) || name.contains(consoleView))
|
||||
m_focusedSubWindowName = name;
|
||||
}
|
||||
m_textEditor.Render("hex.builtin.view.pattern_editor.name"_lang, textEditorSize, true);
|
||||
m_textEditorHoverBox = ImRect(windowPosition,windowPosition+textEditorSize);
|
||||
m_consoleHoverBox = ImRect(ImVec2(windowPosition.x,windowPosition.y+textEditorSize.y),windowPosition+availableSize);
|
||||
TextEditor::FindReplaceHandler *findReplaceHandler = m_textEditor.GetFindReplaceHandler();
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Right) && ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows) && !ImGui::IsMouseDragging(ImGuiMouseButton_Right)) {
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Right) && ImGui::IsMouseHoveringRect(m_textEditorHoverBox.Min,m_textEditorHoverBox.Max) && !ImGui::IsMouseDragging(ImGuiMouseButton_Right)) {
|
||||
ImGui::OpenPopup("##pattern_editor_context_menu");
|
||||
}
|
||||
|
||||
bool clickedMenuFind = false;
|
||||
bool clickedMenuReplace = false;
|
||||
if (ImGui::BeginPopup("##pattern_editor_context_menu")) {
|
||||
// no shortcut for this
|
||||
if (ImGui::MenuItem("hex.builtin.menu.file.import.pattern_file"_lang, nullptr, false))
|
||||
@ -268,8 +386,11 @@ namespace hex::plugin::builtin {
|
||||
|
||||
ImGui::Separator();
|
||||
// Search and replace entries
|
||||
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.find"_lang, Shortcut(CTRLCMD + Keys::F).toString().c_str(),false,this->m_textEditor.HasSelection()))
|
||||
clickedMenuFind = true;
|
||||
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.find"_lang, Shortcut(CTRLCMD + Keys::F).toString().c_str(),false, m_textEditor.HasSelection())){
|
||||
m_replaceMode = false;
|
||||
m_openFindReplacePopUp = true;
|
||||
}
|
||||
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.find_next"_lang, Shortcut(Keys::F3).toString().c_str(),false,!findReplaceHandler->GetFindWord().empty()))
|
||||
findReplaceHandler->FindMatch(&m_textEditor,true);
|
||||
@ -277,8 +398,10 @@ namespace hex::plugin::builtin {
|
||||
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.find_previous"_lang, Shortcut(SHIFT + Keys::F3).toString().c_str(),false,!findReplaceHandler->GetFindWord().empty()))
|
||||
findReplaceHandler->FindMatch(&m_textEditor,false);
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.replace"_lang, Shortcut(CTRLCMD + Keys::H).toString().c_str(),false,!findReplaceHandler->GetReplaceWord().empty()))
|
||||
clickedMenuReplace = true;
|
||||
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.replace"_lang, Shortcut(CTRLCMD + Keys::H).toString().c_str(),false,!findReplaceHandler->GetReplaceWord().empty())) {
|
||||
m_replaceMode = true;
|
||||
m_openFindReplacePopUp = true;
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.replace_next"_lang,"",false,!findReplaceHandler->GetReplaceWord().empty()))
|
||||
findReplaceHandler->Replace(&m_textEditor,true);
|
||||
@ -292,119 +415,8 @@ namespace hex::plugin::builtin {
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// Context menu entries that open the find/replace popup
|
||||
bool openFindPopup = false;
|
||||
ImGui::PushID(&this->m_textEditor);
|
||||
if (clickedMenuFind) {
|
||||
m_replaceMode = false;
|
||||
openFindPopup = true;
|
||||
}
|
||||
|
||||
if (clickedMenuReplace) {
|
||||
m_replaceMode = true;
|
||||
openFindPopup = true;
|
||||
}
|
||||
|
||||
// shortcuts to open the find/replace popup
|
||||
if (ImGui::IsItemHovered()) {
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_F, false) && ImGui::GetIO().KeyCtrl) {
|
||||
m_replaceMode = false;
|
||||
openFindPopup = true;
|
||||
}
|
||||
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_H, false) && ImGui::GetIO().KeyCtrl) {
|
||||
m_replaceMode = true;
|
||||
openFindPopup = true;
|
||||
}
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_S, false) && ImGui::GetIO().KeyAlt)
|
||||
hex::plugin::builtin::saveProject();
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_O, false) && ImGui::GetIO().KeyAlt)
|
||||
hex::plugin::builtin::openProject();
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_S, false) && ImGui::GetIO().KeyAlt && ImGui::GetIO().KeyShift)
|
||||
hex::plugin::builtin::saveProjectAs();
|
||||
}
|
||||
|
||||
static std::string findWord;
|
||||
static bool requestFocus = false;
|
||||
static u64 position = 0;
|
||||
static u64 count = 0;
|
||||
static bool updateCount = false;
|
||||
|
||||
if (openFindPopup) {
|
||||
// Place the popup at the top right of the window
|
||||
auto windowSize = ImGui::GetWindowSize();
|
||||
auto style = ImGui::GetStyle();
|
||||
|
||||
// Set the scrollbar size only if it is visible
|
||||
float scrollbarSize = 0;
|
||||
|
||||
// Calculate the number of lines to display in the text editor
|
||||
auto totalTextHeight = m_textEditor.GetTotalLines() * m_textEditor.GetCharAdvance().y;
|
||||
|
||||
// Compare it to the window height
|
||||
if (totalTextHeight > windowSize.y)
|
||||
scrollbarSize = style.ScrollbarSize;
|
||||
|
||||
auto labelSize = ImGui::CalcTextSize(ICON_VS_WHOLE_WORD);
|
||||
|
||||
// Six icon buttons
|
||||
auto popupSize = ImVec2({(labelSize.x + style.FramePadding.x * 2.0F) * 6.0F,
|
||||
labelSize.y + style.FramePadding.y * 2.0F + style.WindowPadding.y + 3 });
|
||||
|
||||
// 2 * 11 spacings in between elements
|
||||
popupSize.x += style.FramePadding.x * 22.0F;
|
||||
|
||||
// Text input fields are set to 12 characters wide
|
||||
popupSize.x += ImGui::GetFontSize() * 12.0F;
|
||||
|
||||
// IndexOfCount text
|
||||
popupSize.x += ImGui::CalcTextSize("2000 of 2000").x + 2.0F;
|
||||
popupSize.x += scrollbarSize;
|
||||
|
||||
// Position of popup relative to parent window
|
||||
ImVec2 windowPosForPopup = ImGui::GetWindowPos();
|
||||
|
||||
// Not the window height but the content height
|
||||
windowPosForPopup.y += popupSize.y;
|
||||
|
||||
// Add remaining window height
|
||||
popupSize.y += style.WindowPadding.y + 1;
|
||||
|
||||
// Move to the right so as not to overlap the scrollbar
|
||||
windowPosForPopup.x += windowSize.x - popupSize.x;
|
||||
findReplaceHandler->SetFindWindowPos(windowPosForPopup);
|
||||
|
||||
if (m_replaceMode) {
|
||||
// Remove one window padding
|
||||
popupSize.y -= style.WindowPadding.y;
|
||||
// Add the replace window height
|
||||
popupSize.y *= 2;
|
||||
}
|
||||
|
||||
ImGui::SetNextWindowPos(windowPosForPopup);
|
||||
ImGui::SetNextWindowSize(popupSize);
|
||||
ImGui::OpenPopup("##pattern_editor_find_replace");
|
||||
|
||||
findReplaceHandler->resetMatches();
|
||||
|
||||
// Use selection as find word if there is one, otherwise use the word under the cursor
|
||||
if (!this->m_textEditor.HasSelection())
|
||||
this->m_textEditor.SelectWordUnderCursor();
|
||||
|
||||
findWord = this->m_textEditor.GetSelectedText();
|
||||
|
||||
// Find all matches to findWord
|
||||
findReplaceHandler->FindAllMatches(&m_textEditor,findWord);
|
||||
position = findReplaceHandler->FindPosition(&m_textEditor,m_textEditor.GetCursorPosition(), true);
|
||||
count = findReplaceHandler->GetMatches().size();
|
||||
findReplaceHandler->SetFindWord(&m_textEditor,findWord);
|
||||
requestFocus = true;
|
||||
updateCount = true;
|
||||
}
|
||||
|
||||
drawFindReplaceDialog(findWord, requestFocus, position, count, updateCount);
|
||||
|
||||
ImGui::PopID();
|
||||
setupFindReplace(getEditorFromFocusedWindow());
|
||||
|
||||
ImGui::Button("##settings_drag_bar", ImVec2(ImGui::GetContentRegionAvail().x, 2_scaled));
|
||||
if (ImGui::IsMouseDragging(ImGuiMouseButton_Left, 0)) {
|
||||
@ -605,18 +617,9 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
}
|
||||
|
||||
void ViewPatternEditor::drawFindReplaceDialog(std::string &findWord, bool &requestFocus, u64 &position, u64 &count, bool &updateCount) {
|
||||
static std::string replaceWord;
|
||||
void ViewPatternEditor::drawFindReplaceDialog(TextEditor *textEditor, std::string &findWord, bool &requestFocus, u64 &position, u64 &count, bool &updateCount, bool canReplace) {
|
||||
|
||||
TextEditor::FindReplaceHandler *findReplaceHandler = m_textEditor.GetFindReplaceHandler();
|
||||
static bool requestFocusReplace = false;
|
||||
static bool requestFocusFind = false;
|
||||
|
||||
static bool downArrowFind = false;
|
||||
static bool upArrowFind = false;
|
||||
static bool downArrowReplace = false;
|
||||
static bool upArrowReplace = false;
|
||||
static bool enterPressedFind = false;
|
||||
TextEditor::FindReplaceHandler *findReplaceHandler = textEditor->GetFindReplaceHandler();
|
||||
|
||||
bool enter = ImGui::IsKeyPressed(ImGuiKey_Enter, false) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter, false);
|
||||
bool upArrow = ImGui::IsKeyPressed(ImGuiKey_UpArrow, false) || ImGui::IsKeyPressed(ImGuiKey_Keypad8, false);
|
||||
@ -630,9 +633,14 @@ namespace hex::plugin::builtin {
|
||||
ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_BordersInnerH)) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
static bool requestFocusFind = false;
|
||||
static bool requestFocusReplace = false;
|
||||
bool oldReplace = m_replaceMode;
|
||||
ImGuiExt::DimmedIconToggle(ICON_VS_TRIANGLE_DOWN, ICON_VS_TRIANGLE_RIGHT, &m_replaceMode);
|
||||
|
||||
if (canReplace)
|
||||
ImGuiExt::DimmedIconToggle(ICON_VS_TRIANGLE_DOWN, ICON_VS_TRIANGLE_RIGHT, &m_replaceMode);
|
||||
else
|
||||
m_replaceMode = false;
|
||||
if (oldReplace != m_replaceMode) {
|
||||
if (m_replaceMode)
|
||||
requestFocusReplace = true;
|
||||
@ -659,16 +667,15 @@ namespace hex::plugin::builtin {
|
||||
hint += ICON_BI_DATA_TRANSFER_BOTH;
|
||||
hint += "hex.builtin.view.pattern_editor.find_hint_history"_lang.operator std::string();
|
||||
}
|
||||
|
||||
static bool enterPressedFind = false;
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 12);
|
||||
if (ImGui::InputTextWithHint("###findInputTextWidget", hint.c_str(), findWord, findFlags) || enter ) {
|
||||
if (enter) {
|
||||
if (enter)
|
||||
enterPressedFind = true;
|
||||
enter = false;
|
||||
}
|
||||
|
||||
updateCount = true;
|
||||
requestFocusFind = true;
|
||||
findReplaceHandler->SetFindWord(&m_textEditor,findWord);
|
||||
findReplaceHandler->SetFindWord(textEditor,findWord);
|
||||
}
|
||||
|
||||
if ((!m_replaceMode && requestFocus) || requestFocusFind) {
|
||||
@ -686,8 +693,8 @@ namespace hex::plugin::builtin {
|
||||
m_findHistoryIndex = (m_findHistoryIndex + 1) % m_findHistorySize;
|
||||
|
||||
findWord = m_findHistory[m_findHistoryIndex];
|
||||
findReplaceHandler->SetFindWord(&m_textEditor,findWord);
|
||||
position = findReplaceHandler->FindPosition(&m_textEditor,m_textEditor.GetCursorPosition(), true);
|
||||
findReplaceHandler->SetFindWord(textEditor,findWord);
|
||||
position = findReplaceHandler->FindPosition(textEditor,textEditor->GetCursorPosition(), true);
|
||||
count = findReplaceHandler->GetMatches().size();
|
||||
updateCount = true;
|
||||
requestFocusFind = true;
|
||||
@ -703,8 +710,8 @@ namespace hex::plugin::builtin {
|
||||
if (altCPressed || ImGuiExt::DimmedIconToggle(ICON_VS_CASE_SENSITIVE, &matchCase)) {
|
||||
if (altCPressed)
|
||||
matchCase = !matchCase;
|
||||
findReplaceHandler->SetMatchCase(&m_textEditor,matchCase);
|
||||
position = findReplaceHandler->FindPosition(&m_textEditor,m_textEditor.GetCursorPosition(), true);
|
||||
findReplaceHandler->SetMatchCase(textEditor,matchCase);
|
||||
position = findReplaceHandler->FindPosition(textEditor,textEditor->GetCursorPosition(), true);
|
||||
count = findReplaceHandler->GetMatches().size();
|
||||
updateCount = true;
|
||||
requestFocusFind = true;
|
||||
@ -719,8 +726,8 @@ namespace hex::plugin::builtin {
|
||||
if (altWPressed || ImGuiExt::DimmedIconToggle(ICON_VS_WHOLE_WORD, &matchWholeWord)) {
|
||||
if (altWPressed)
|
||||
matchWholeWord = !matchWholeWord;
|
||||
findReplaceHandler->SetWholeWord(&m_textEditor,matchWholeWord);
|
||||
position = findReplaceHandler->FindPosition(&m_textEditor,m_textEditor.GetCursorPosition(), true);
|
||||
findReplaceHandler->SetWholeWord(textEditor,matchWholeWord);
|
||||
position = findReplaceHandler->FindPosition(textEditor,textEditor->GetCursorPosition(), true);
|
||||
count = findReplaceHandler->GetMatches().size();
|
||||
updateCount = true;
|
||||
requestFocusFind = true;
|
||||
@ -735,8 +742,8 @@ namespace hex::plugin::builtin {
|
||||
if (altRPressed || ImGuiExt::DimmedIconToggle(ICON_VS_REGEX, &useRegex)) {
|
||||
if (altRPressed)
|
||||
useRegex = !useRegex;
|
||||
findReplaceHandler->SetFindRegEx(&m_textEditor,useRegex);
|
||||
position = findReplaceHandler->FindPosition(&m_textEditor,m_textEditor.GetCursorPosition(), true);
|
||||
findReplaceHandler->SetFindRegEx(textEditor,useRegex);
|
||||
position = findReplaceHandler->FindPosition(textEditor,textEditor->GetCursorPosition(), true);
|
||||
count = findReplaceHandler->GetMatches().size();
|
||||
updateCount = true;
|
||||
requestFocusFind = true;
|
||||
@ -777,10 +784,12 @@ namespace hex::plugin::builtin {
|
||||
ImGui::InvisibleButton("##find_result_padding", buttonSize);
|
||||
|
||||
ImGui::SameLine();
|
||||
static bool downArrowFind = false;
|
||||
if (ImGuiExt::IconButton(ICON_VS_ARROW_DOWN, ImVec4(1, 1, 1, 1)))
|
||||
downArrowFind = true;
|
||||
|
||||
ImGui::SameLine();
|
||||
static bool upArrowFind = false;
|
||||
if (ImGuiExt::IconButton(ICON_VS_ARROW_UP, ImVec4(1, 1, 1, 1)))
|
||||
upArrowFind = true;
|
||||
|
||||
@ -803,11 +812,14 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 12);
|
||||
static std::string replaceWord;
|
||||
static bool downArrowReplace = false;
|
||||
static bool upArrowReplace = false;
|
||||
if (ImGui::InputTextWithHint("##replaceInputTextWidget", hint.c_str(), replaceWord, replaceFlags) || downArrowReplace || upArrowReplace) {
|
||||
findReplaceHandler->SetReplaceWord(replaceWord);
|
||||
historyInsert(m_replaceHistory, m_replaceHistorySize, m_replaceHistoryIndex, replaceWord);
|
||||
|
||||
bool textReplaced = findReplaceHandler->Replace(&m_textEditor,!shift && !upArrowReplace);
|
||||
bool textReplaced = findReplaceHandler->Replace(textEditor,!shift && !upArrowReplace);
|
||||
if (textReplaced) {
|
||||
if (count > 0) {
|
||||
if (position == count)
|
||||
@ -863,7 +875,7 @@ namespace hex::plugin::builtin {
|
||||
if (ImGuiExt::IconButton(ICON_VS_REPLACE_ALL, ImVec4(1, 1, 1, 1))) {
|
||||
findReplaceHandler->SetReplaceWord(replaceWord);
|
||||
historyInsert(m_replaceHistory,m_replaceHistorySize, m_replaceHistoryIndex, replaceWord);
|
||||
findReplaceHandler->ReplaceAll(&m_textEditor);
|
||||
findReplaceHandler->ReplaceAll(textEditor);
|
||||
count = 0;
|
||||
position = 0;
|
||||
requestFocusFind = true;
|
||||
@ -875,7 +887,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if ((ImGui::IsKeyPressed(ImGuiKey_F3, false)) || downArrowFind || upArrowFind || enterPressedFind) {
|
||||
historyInsert(m_findHistory, m_findHistorySize, m_findHistoryIndex, findWord);
|
||||
position = findReplaceHandler->FindMatch(&m_textEditor,!shift && !upArrowFind);
|
||||
position = findReplaceHandler->FindMatch(textEditor,!shift && !upArrowFind);
|
||||
count = findReplaceHandler->GetMatches().size();
|
||||
updateCount = true;
|
||||
downArrowFind = false;
|
||||
@ -895,6 +907,32 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void ViewPatternEditor::drawConsole(ImVec2 size) {
|
||||
auto findReplaceHandler = m_consoleEditor.GetFindReplaceHandler();
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Right) && ImGui::IsMouseHoveringRect(m_consoleHoverBox.Min,m_consoleHoverBox.Max) && !ImGui::IsMouseDragging(ImGuiMouseButton_Right)) {
|
||||
ImGui::OpenPopup("##console_context_menu");
|
||||
}
|
||||
const bool hasSelection = m_consoleEditor.HasSelection();
|
||||
if (ImGui::BeginPopup("##console_context_menu")) {
|
||||
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.copy"_lang, Shortcut(CTRLCMD + Keys::C).toString().c_str(), false, hasSelection)) {
|
||||
m_consoleEditor.Copy();
|
||||
}
|
||||
if (ImGui::MenuItem("hex.builtin.view.hex_editor.menu.edit.select_all"_lang, Shortcut(CTRLCMD + Keys::A).toString().c_str())) {
|
||||
m_consoleEditor.SelectAll();
|
||||
}
|
||||
ImGui::Separator();
|
||||
// Search and replace entries
|
||||
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.find"_lang, Shortcut(CTRLCMD + Keys::F).toString().c_str(),false, hasSelection)) {
|
||||
m_openFindReplacePopUp = true;
|
||||
m_replaceMode = false;
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.find_next"_lang, Shortcut(Keys::F3).toString().c_str(),false,!findReplaceHandler->GetFindWord().empty()))
|
||||
findReplaceHandler->FindMatch(&m_consoleEditor,true);
|
||||
|
||||
if (ImGui::MenuItem("hex.builtin.view.pattern_editor.menu.find_previous"_lang, Shortcut(SHIFT + Keys::F3).toString().c_str(),false,!findReplaceHandler->GetFindWord().empty()))
|
||||
findReplaceHandler->FindMatch(&m_consoleEditor,false);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
if (m_consoleNeedsUpdate) {
|
||||
std::scoped_lock lock(m_logMutex);
|
||||
|
||||
@ -1175,7 +1213,7 @@ namespace hex::plugin::builtin {
|
||||
file.writeVector(runtime.getSection(id));
|
||||
});
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", (const char*)"hex.builtin.view.pattern_editor.sections.export"_lang.get());
|
||||
ImGui::SetItemTooltip("%s", "hex.builtin.view.pattern_editor.sections.export"_lang.get());
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
@ -1193,7 +1231,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
if (ImGui::BeginTable("Virtual File Tree", 1, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, size)) {
|
||||
ImGui::TableSetupColumn("##path", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
levelId = 1;
|
||||
drawVirtualFileTree(virtualFilePointers);
|
||||
|
||||
ImGui::EndTable();
|
||||
@ -1203,9 +1241,10 @@ namespace hex::plugin::builtin {
|
||||
|
||||
void ViewPatternEditor::drawDebugger(ImVec2 size) {
|
||||
const auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
|
||||
auto &evaluator = runtime.getInternals().evaluator;
|
||||
|
||||
|
||||
if (ImGui::BeginChild("##debugger", size, true)) {
|
||||
auto &evaluator = runtime.getInternals().evaluator;
|
||||
const auto &breakpoints = evaluator->getBreakpoints();
|
||||
const auto line = m_textEditor.GetCursorPosition().mLine + 1;
|
||||
|
||||
@ -1372,8 +1411,8 @@ namespace hex::plugin::builtin {
|
||||
const auto end = value.find(']');
|
||||
if (end == std::string::npos)
|
||||
return std::nullopt;
|
||||
|
||||
value = value.substr(0, end);
|
||||
value.resize(end);
|
||||
//value = value.substr(0, end);
|
||||
value = wolv::util::trim(value);
|
||||
|
||||
return BinaryPattern(value);
|
||||
@ -1851,6 +1890,16 @@ namespace hex::plugin::builtin {
|
||||
appendEditorText(hex::format("{0} {0}_array_at_0x{1:02X}[0x{2:02X}] @ 0x{1:02X};", type, selection->getStartAddress(), (selection->getSize() + (size - 1)) / size));
|
||||
}
|
||||
|
||||
TextEditor *ViewPatternEditor::getEditorFromFocusedWindow() {
|
||||
if (m_focusedSubWindowName.contains(consoleView)) {
|
||||
return &m_consoleEditor;
|
||||
}
|
||||
if (m_focusedSubWindowName.contains(textEditorView)) {
|
||||
return &m_textEditor;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ViewPatternEditor::registerMenuItems() {
|
||||
/* Import Pattern */
|
||||
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.pattern" }, ICON_VS_FILE_CODE, 4050, Shortcut::None,
|
||||
@ -2037,6 +2086,257 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::F + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.find", [this] {
|
||||
m_openFindReplacePopUp = true;
|
||||
m_replaceMode = false;
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::H + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.replace", [this] {
|
||||
if (m_focusedSubWindowName.contains(textEditorView)) {
|
||||
m_openFindReplacePopUp = true;
|
||||
m_replaceMode = true;
|
||||
}
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::F3 + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.find_next", [this] {
|
||||
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr) {
|
||||
TextEditor::FindReplaceHandler *findReplaceHandler = editor->GetFindReplaceHandler();
|
||||
findReplaceHandler->FindMatch(editor, true);
|
||||
}
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::F3 + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.find_previous", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr) {
|
||||
TextEditor::FindReplaceHandler *findReplaceHandler = editor->GetFindReplaceHandler();
|
||||
findReplaceHandler->FindMatch(editor, false);
|
||||
}
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, ALT + Keys::C + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.match_case_toggle", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr) {
|
||||
TextEditor::FindReplaceHandler *findReplaceHandler = editor->GetFindReplaceHandler();
|
||||
findReplaceHandler->SetMatchCase(editor, !findReplaceHandler->GetMatchCase());
|
||||
}
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, ALT + Keys::R + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.regex_toggle", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr) {
|
||||
TextEditor::FindReplaceHandler *findReplaceHandler = editor->GetFindReplaceHandler();
|
||||
findReplaceHandler->SetFindRegEx(editor, !findReplaceHandler->GetFindRegEx());
|
||||
}
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, ALT + Keys::W + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.whole_word_toggle", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr) {
|
||||
TextEditor::FindReplaceHandler *findReplaceHandler = editor->GetFindReplaceHandler();
|
||||
findReplaceHandler->SetWholeWord(editor, !findReplaceHandler->GetWholeWord());
|
||||
}
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, ALT + Keys::S + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.save_project", [] {
|
||||
hex::plugin::builtin::saveProject();
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, ALT + Keys::O + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.open_project", [] {
|
||||
hex::plugin::builtin::openProject();
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, ALT + SHIFT + Keys::S + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.save_project_as", [] {
|
||||
hex::plugin::builtin::saveProjectAs();
|
||||
});
|
||||
|
||||
// ShortcutManager::addShortcut(this, CTRL + Keys::Insert + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.copy", [this] {
|
||||
// m_textEditor.Copy();
|
||||
// });
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::C + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.copy", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->Copy();
|
||||
});
|
||||
|
||||
// ShortcutManager::addShortcut(this, SHIFT + Keys::Insert + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.paste", [this] {
|
||||
// m_textEditor.Paste();
|
||||
// });
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::V + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.paste", [this] {
|
||||
if (m_focusedSubWindowName.contains(textEditorView))
|
||||
m_textEditor.Paste();
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::X + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.cut", [this] {
|
||||
if (m_focusedSubWindowName.contains(textEditorView))
|
||||
m_textEditor.Cut();
|
||||
});
|
||||
|
||||
// ShortcutManager::addShortcut(this, SHIFT + Keys::Delete + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.cut", [this] {
|
||||
// m_textEditor.Cut();
|
||||
// });
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::Z + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.undo", [this] {
|
||||
if (m_focusedSubWindowName.contains(textEditorView))
|
||||
m_textEditor.Undo();
|
||||
});
|
||||
|
||||
// ShortcutManager::addShortcut(this, ALT + Keys::Backspace + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.undo", [this] {
|
||||
// m_textEditor.Undo();
|
||||
// });
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::Delete + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.delete", [this] {
|
||||
if (m_focusedSubWindowName.contains(textEditorView))
|
||||
m_textEditor.Delete();
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::Y + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.redo", [this] {
|
||||
if (m_focusedSubWindowName.contains(textEditorView))
|
||||
m_textEditor.Redo();
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::A + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_all", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->SelectAll();
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::Right + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_right", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveRight(1, true, false);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + SHIFT + Keys::Right + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_word_right", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveRight(1, true, true);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::Left + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_left", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveLeft(1, true, false);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + SHIFT + Keys::Left + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_word_left", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveLeft(1, true, true);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::Up + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_up", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveUp(1, true);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, SHIFT +Keys::PageUp + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_page_up", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveUp(editor->GetPageSize()-4, true);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::Down + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_down", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveDown(1, true);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, SHIFT +Keys::PageDown + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_page_down", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveDown(editor->GetPageSize()-4, true);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + SHIFT + Keys::Home + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_top", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveTop(true);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + SHIFT + Keys::End + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_bottom", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveBottom(true);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::Home + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_home", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveHome(true);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, SHIFT + Keys::End + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.select_end", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveEnd(true);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::Delete + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.delete_word_right", [this] {
|
||||
if (m_focusedSubWindowName.contains(textEditorView))
|
||||
m_textEditor.DeleteWordRight();
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::Backspace + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.delete_word_left", [this] {
|
||||
if (m_focusedSubWindowName.contains(textEditorView))
|
||||
m_textEditor.DeleteWordLeft();
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::Backspace + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.backspace", [this] {
|
||||
if (m_focusedSubWindowName.contains(textEditorView))
|
||||
m_textEditor.Backspace();
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::Insert + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.toggle_insert", [this] {
|
||||
if (m_focusedSubWindowName.contains(textEditorView))
|
||||
m_textEditor.SetOverwrite(!m_textEditor.IsOverwrite());
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::Right + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.move_word_right", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveRight(1, false, true);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::Right + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.move_right", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveRight(1, false, false);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::Left + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.move_word_left", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveLeft(1, false, true);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::Left + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.move_left", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveLeft(1, false, false);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::Up + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.move_up", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveUp(1, false);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::PageUp + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.move_page_up", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveUp(editor->GetPageSize()-4, false);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::Down + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.move_down", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveDown(1, false);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::PageDown + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.move_page_down", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveDown(editor->GetPageSize()-4, false);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::Home + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.move_top", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveTop(false);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, CTRL + Keys::End + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.move_bottom", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveBottom(false);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::Home + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.move_home", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveHome(false);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::End + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.move_end", [this] {
|
||||
if (auto editor = getEditorFromFocusedWindow(); editor != nullptr)
|
||||
editor->MoveEnd(false);
|
||||
});
|
||||
|
||||
ShortcutManager::addShortcut(this, Keys::F8 + AllowWhileTyping, "hex.builtin.view.pattern_editor.shortcut.add_breakpoint", [this] {
|
||||
const auto line = m_textEditor.GetCursorPosition().mLine + 1;
|
||||
const auto &runtime = ContentRegistry::PatternLanguage::getRuntime();
|
||||
|
Loading…
x
Reference in New Issue
Block a user