gui2/ttext_: Add a blinking cursor to textbox widgets

This is used by all widgets that inherit from the textbox abstract
class, ttext_. The cursor is updated every 750 ms by toggling the
cursor alpha every time. When the cursor position is set by a method
(e.g. in reaction to a keyboard event), the cursor is reset to full
alpha, and the blink timer restarted.
This commit is contained in:
Ignacio R. Morelle 2016-10-12 01:53:29 -03:00
parent b3cf75196c
commit f1d89ba4a3
3 changed files with 63 additions and 0 deletions

View file

@ -66,6 +66,7 @@
x2 = "(cursor_offset + {X_OFFSET})"
y2 = "(text_y_offset + text_font_height - 2)"
color = "255, 255, 255, 255"
alpha = "(cursor_alpha)"
thickness = 1
[/line]
#enddef

View file

@ -18,6 +18,7 @@
#include "desktop/clipboard.hpp"
#include "gui/core/log.hpp"
#include "gui/core/timer.hpp"
#include "serialization/string_utils.hpp"
#include "serialization/unicode.hpp"
@ -37,6 +38,9 @@ ttext_::ttext_()
, text_()
, selection_start_(0)
, selection_length_(0)
, cursor_timer_(0)
, cursor_alpha_(0)
, cursor_blink_rate_ms_(750)
, text_changed_callback_()
{
#ifdef __unix__
@ -53,6 +57,15 @@ ttext_::ttext_()
&ttext_::signal_handler_receive_keyboard_focus, this, _2));
connect_signal<event::LOSE_KEYBOARD_FOCUS>(
std::bind(&ttext_::signal_handler_lose_keyboard_focus, this, _2));
cursor_timer_ = add_timer(cursor_blink_rate_ms_, std::bind(&ttext_::cursor_timer_callback, this), true);
}
ttext_::~ttext_()
{
if(cursor_timer_) {
remove_timer(cursor_timer_);
}
}
void ttext_::set_active(const bool active)
@ -109,6 +122,8 @@ void ttext_::set_value(const std::string& text)
void ttext_::set_cursor(const size_t offset, const bool select)
{
reset_cursor_state();
if(select) {
if(selection_start_ == offset) {
@ -239,6 +254,41 @@ void ttext_::set_state(const tstate state)
}
}
void ttext_::cursor_timer_callback()
{
switch(state_) {
case DISABLED:
cursor_alpha_ = 0;
return;
case ENABLED:
cursor_alpha_ = 255;
return;
default:
cursor_alpha_ = (~cursor_alpha_) & 0xFF;
}
for(auto& tmp : canvas()) {
tmp.set_variable("cursor_alpha", variant(cursor_alpha_));
}
set_is_dirty(true);
}
void ttext_::reset_cursor_state()
{
cursor_alpha_ = 255;
for(auto& tmp : canvas()) {
tmp.set_variable("cursor_alpha", variant(cursor_alpha_));
}
// Restart the blink timer.
if(cursor_timer_) {
remove_timer(cursor_timer_);
}
cursor_timer_ = add_timer(cursor_blink_rate_ms_, std::bind(&ttext_::cursor_timer_callback, this), true);
}
void ttext_::handle_key_left_arrow(SDL_Keymod modifier, bool& handled)
{
/** @todo implement the ctrl key. */

View file

@ -46,6 +46,8 @@ class ttext_ : public tcontrol
public:
ttext_();
~ttext_();
/** See @ref tcontrol::set_active. */
virtual void set_active(const bool active) override;
@ -262,6 +264,11 @@ private:
void set_state(const tstate state);
/** Implements blinking cursor functionality. */
virtual void cursor_timer_callback();
virtual void reset_cursor_state();
/**
* Current state of the widget.
*
@ -285,6 +292,11 @@ private:
*/
int selection_length_;
size_t cursor_timer_;
unsigned short cursor_alpha_;
unsigned short cursor_blink_rate_ms_;
/****** handling of special keys first the pure virtuals *****/
/**