Skip to content

Commit 34026b1

Browse files
committed
Made the cursor blink
1 parent 0f80ca6 commit 34026b1

2 files changed

Lines changed: 77 additions & 9 deletions

File tree

src/Engine/UI/textinput.cpp

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,55 @@ namespace pg
250250

251251
cursorUi->setVisible(isFocused);
252252
}
253+
254+
resetBlinkTimer();
255+
}
256+
257+
void TextInputSystem::onEvent(const TickEvent& event)
258+
{
259+
// Accumulate time (TickEvent::tick is in milliseconds)
260+
blinkTimer += event.tick / 1000.0f;
261+
262+
if (blinkTimer >= blinkInterval)
263+
{
264+
blinkTimer -= blinkInterval;
265+
cursorVisible = !cursorVisible;
266+
267+
for (const auto& entity : viewGroup<TextInputComponent, FocusableComponent>())
268+
{
269+
auto focus = entity->get<FocusableComponent>();
270+
auto text = entity->get<TextInputComponent>();
271+
272+
if (not focus->focused or not text->cursorEntity)
273+
continue;
274+
275+
auto cursorUi = text->cursorEntity->get<PositionComponent>();
276+
277+
if (cursorUi)
278+
cursorUi->setVisible(cursorVisible);
279+
}
280+
}
281+
}
282+
283+
void TextInputSystem::resetBlinkTimer()
284+
{
285+
blinkTimer = 0.0f;
286+
cursorVisible = true;
287+
288+
// Immediately make all focused cursors visible
289+
for (const auto& entity : viewGroup<TextInputComponent, FocusableComponent>())
290+
{
291+
auto focus = entity->get<FocusableComponent>();
292+
auto text = entity->get<TextInputComponent>();
293+
294+
if (not focus->focused or not text->cursorEntity)
295+
continue;
296+
297+
auto cursorUi = text->cursorEntity->get<PositionComponent>();
298+
299+
if (cursorUi)
300+
cursorUi->setVisible(true);
301+
}
253302
}
254303

255304
void TextInputSystem::updateCursorVisual(EntityRef entity, CompRef<TextInputComponent> textComp)
@@ -262,6 +311,9 @@ namespace pg
262311
if (not cursorAnchor)
263312
return;
264313

314+
// Reset the blink timer so cursor stays visible after any interaction
315+
resetBlinkTimer();
316+
265317
// Compute the X offset of the cursor by summing glyph advances up to cursorPos
266318
float cursorX = 0.0f;
267319

@@ -272,16 +324,20 @@ namespace pg
272324

273325
if (ttfSystem)
274326
{
275-
const auto& fontChars = ttfSystem->charactersMap[ttf->fontPath];
276-
float scale = ttf->scale;
277-
278-
for (size_t i = 0; i < textComp->cursorPos and i < textComp->text.size(); i++)
327+
auto mapIt = ttfSystem->charactersMap.find(ttf->fontPath);
328+
if (mapIt != ttfSystem->charactersMap.end())
279329
{
280-
char c = textComp->text[i];
281-
auto it = fontChars.find(c);
282-
if (it != fontChars.end())
330+
const auto& fontChars = mapIt->second;
331+
float scale = ttf->scale;
332+
333+
for (size_t i = 0; i < textComp->cursorPos and i < textComp->text.size(); i++)
283334
{
284-
cursorX += (it->second.advance >> 6) * scale;
335+
char c = textComp->text[i];
336+
auto it = fontChars.find(c);
337+
if (it != fontChars.end())
338+
{
339+
cursorX += (it->second.advance >> 6) * scale;
340+
}
285341
}
286342
}
287343
}

src/Engine/UI/textinput.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
#include "2D/simple2dobject.h"
88

9+
#include "Systems/coresystems.h"
10+
911
#include "sentencesystem.h"
1012
#include "ttftext.h"
1113
#include "focusable.h"
@@ -65,7 +67,7 @@ namespace pg
6567

6668
struct TextInputSystem: public System<Own<TextInputComponent>, Ref<FocusableComponent>,
6769
Listener<OnSDLTextInput>, Listener<OnSDLScanCode>,
68-
Listener<EntityChangedEvent>, Listener<OnFocus>,
70+
Listener<EntityChangedEvent>, Listener<OnFocus>, Listener<TickEvent>,
6971
QueuedListener<__InternalCurrentTextInputTextChanged>, InitSys>
7072
{
7173
TextInputSystem(Input* inputHandler) : inputHandler(inputHandler) { LOG_THIS_MEMBER("Text Input System"); }
@@ -83,6 +85,8 @@ namespace pg
8385

8486
virtual void onEvent(const OnFocus& event) override;
8587

88+
virtual void onEvent(const TickEvent& event) override;
89+
8690
virtual void onEvent(const EntityChangedEvent& event) override
8791
{
8892
auto ent = ecsRef->getEntity(event.id);
@@ -127,7 +131,15 @@ namespace pg
127131
/** Recomputes the cursor entity position based on the current text and cursor index. */
128132
void updateCursorVisual(EntityRef entity, CompRef<TextInputComponent> textComp);
129133

134+
/** Resets the blink timer so the cursor stays visible right after user interaction. */
135+
void resetBlinkTimer();
136+
130137
Input *inputHandler;
138+
139+
// Cursor blink state
140+
float blinkTimer = 0.0f;
141+
float blinkInterval = 0.5f; // seconds per on/off half-cycle
142+
bool cursorVisible = true;
131143
};
132144

133145
// template <typename Type>

0 commit comments

Comments
 (0)