1
0
mirror of synced 2025-01-29 19:17:28 +01:00

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:
SparkyTD 2024-05-11 06:58:55 -07:00 committed by GitHub
parent 09bffb6745
commit 62aea46c61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 4 deletions

View File

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

View File

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