impr: Ensure that Text Editor's cursor blink state is never invisible after a keyboard event (#1664)
### Problem description By default, the cursor's blinking cycle is independent from user actions, which feels unconventional while editing pattern code. This change ensures that the blinking cycle is reset, and the cursor is made visible every time the editor receives a keyboard event like character entry, or arrow navigation. ### Implementation description I moved the hard-coded blink timing numbers to their dedicated static constant fields since now they are referenced from multiple different places. I added the function `void ResetCursorBlinkTime()` to `TextEditor.cpp` that will reset the blink cycle to `currentMillis() - sCursorBlinkOnTime`, ensuring that the cursor is visible. This function is called for every keyboard and mouse click event. ### Screenshots Before: https://github.com/WerWolv/ImHex/assets/45818400/668c6802-79a3-450b-80d3-d6abf2ce27be After: https://github.com/WerWolv/ImHex/assets/45818400/ee7f60e0-a75f-416d-b86d-8d12b5cdadf2 --------- Co-authored-by: Nik <werwolv98@gmail.com>
This commit is contained in:
parent
09bffb6745
commit
62aea46c61
@ -428,6 +428,7 @@ private:
|
||||
std::string GetWordUnderCursor() const;
|
||||
std::string GetWordAt(const Coordinates& aCoords) const;
|
||||
ImU32 GetGlyphColor(const Glyph& aGlyph) const;
|
||||
void ResetCursorBlinkTime();
|
||||
|
||||
void HandleKeyboardInputs();
|
||||
void HandleMouseInputs();
|
||||
@ -475,6 +476,9 @@ private:
|
||||
float mLastClick;
|
||||
bool mShowCursor;
|
||||
bool mShowLineNumbers;
|
||||
|
||||
static const int sCursorBlinkInterval;
|
||||
static const int sCursorBlinkOnTime;
|
||||
};
|
||||
|
||||
bool TokenizeCStyleString(const char * in_begin, const char * in_end, const char *& out_begin, const char *& out_end);
|
||||
|
@ -22,12 +22,15 @@ bool equals(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Bi
|
||||
return first1 == last1 && first2 == last2;
|
||||
}
|
||||
|
||||
const int TextEditor::sCursorBlinkInterval = 1200;
|
||||
const int TextEditor::sCursorBlinkOnTime = 800;
|
||||
|
||||
TextEditor::Palette TextEditor::sPaletteBase = TextEditor::GetDarkPalette();
|
||||
|
||||
TextEditor::FindReplaceHandler::FindReplaceHandler() : mWholeWord(false),mFindRegEx(false),mMatchCase(false) {}
|
||||
|
||||
TextEditor::TextEditor()
|
||||
: mLineSpacing(1.0f), mUndoIndex(0), mTabSize(4), mOverwrite(false), mReadOnly(false), mWithinRender(false), mScrollToCursor(false), mScrollToTop(false), mScrollToBottom(false), mTextChanged(false), mColorizerEnabled(true), mTextStart(20.0f), mLeftMargin(10), mTopMargin(0), 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()) {
|
||||
: mLineSpacing(1.0f), mUndoIndex(0), mTabSize(4), mOverwrite(false), mReadOnly(false), mWithinRender(false), mScrollToCursor(false), mScrollToTop(false), mScrollToBottom(false), mTextChanged(false), mColorizerEnabled(true), mTextStart(20.0f), mLeftMargin(10), mTopMargin(0), 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(ImGui::GetTime() * 1000) {
|
||||
SetLanguageDefinition(LanguageDefinition::HLSL());
|
||||
mLines.push_back(Line());
|
||||
}
|
||||
@ -642,6 +645,8 @@ 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))
|
||||
@ -716,6 +721,11 @@ void TextEditor::HandleKeyboardInputs() {
|
||||
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++) {
|
||||
@ -754,6 +764,7 @@ void TextEditor::HandleMouseInputs() {
|
||||
}
|
||||
|
||||
mLastClick = -1.0f;
|
||||
ResetCursorBlinkTime();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -771,6 +782,7 @@ void TextEditor::HandleMouseInputs() {
|
||||
}
|
||||
|
||||
mLastClick = (float)ImGui::GetTime();
|
||||
ResetCursorBlinkTime();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -788,6 +800,7 @@ void TextEditor::HandleMouseInputs() {
|
||||
mSelectionMode = SelectionMode::Normal;
|
||||
}
|
||||
SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
|
||||
ResetCursorBlinkTime();
|
||||
|
||||
mLastClick = (float)ImGui::GetTime();
|
||||
}
|
||||
@ -796,6 +809,7 @@ void TextEditor::HandleMouseInputs() {
|
||||
io.WantCaptureMouse = true;
|
||||
mState.mCursorPosition = mInteractiveEnd = ScreenPosToCoordinates(ImGui::GetMousePos());
|
||||
SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode);
|
||||
ResetCursorBlinkTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -927,9 +941,9 @@ void TextEditor::Render() {
|
||||
|
||||
// Render the cursor
|
||||
if (focused) {
|
||||
auto timeEnd = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
auto timeEnd = ImGui::GetTime() * 1000;
|
||||
auto elapsed = timeEnd - mStartTime;
|
||||
if (elapsed > 400) {
|
||||
if (elapsed > sCursorBlinkOnTime) {
|
||||
float width = 1.0f;
|
||||
auto cindex = GetCharacterIndex(mState.mCursorPosition);
|
||||
float cx = TextDistanceToLineStart(mState.mCursorPosition);
|
||||
@ -949,7 +963,7 @@ void TextEditor::Render() {
|
||||
ImVec2 cstart(textScreenPos.x + cx, lineStartScreenPos.y);
|
||||
ImVec2 cend(textScreenPos.x + cx + width, lineStartScreenPos.y + mCharAdvance.y);
|
||||
drawList->AddRectFilled(cstart, cend, mPalette[(int)PaletteIndex::Cursor]);
|
||||
if (elapsed > 800)
|
||||
if (elapsed > sCursorBlinkInterval)
|
||||
mStartTime = timeEnd;
|
||||
}
|
||||
}
|
||||
@ -1219,6 +1233,8 @@ void TextEditor::EnterCharacter(ImWchar aChar, bool aShift) {
|
||||
|
||||
u.mBefore = mState;
|
||||
|
||||
ResetCursorBlinkTime();
|
||||
|
||||
if (HasSelection()) {
|
||||
if (aChar == '\t' && mState.mSelectionStart.mLine != mState.mSelectionEnd.mLine) {
|
||||
|
||||
@ -2780,6 +2796,10 @@ int TextEditor::GetPageSize() const {
|
||||
return (int)floor(height / mCharAdvance.y);
|
||||
}
|
||||
|
||||
void TextEditor::ResetCursorBlinkTime() {
|
||||
mStartTime = ImGui::GetTime() * 1000 - sCursorBlinkOnTime;
|
||||
}
|
||||
|
||||
TextEditor::UndoRecord::UndoRecord(
|
||||
const std::string &aAdded,
|
||||
const TextEditor::Coordinates aAddedStart,
|
||||
|
Loading…
x
Reference in New Issue
Block a user