Evas textblock: Implemented cursor_word_start/end
SVN revision: 66119
This commit is contained in:
parent
f147928c84
commit
4e29867a30
|
@ -544,3 +544,9 @@
|
|||
|
||||
* Fix rounding error in map clip bounds calculation
|
||||
|
||||
2011-12-12 Tom Hacohen (TAsn)
|
||||
|
||||
* Textblock: Added evas_textblock_cursor_word_start/end.
|
||||
Those functions let you jump to the start/end of the word under the
|
||||
cursor.
|
||||
|
||||
|
|
|
@ -8477,6 +8477,24 @@ EAPI Eina_Bool evas_textblock_cursor_char_next(Evas_Textblock
|
|||
*/
|
||||
EAPI Eina_Bool evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
|
||||
|
||||
/**
|
||||
* Moves the cursor to the start of the word under the cursor.
|
||||
*
|
||||
* @param cur the cursor to move.
|
||||
* @return #EINA_TRUE on success #EINA_FALSE otherwise.
|
||||
* @since 1.2.0
|
||||
*/
|
||||
EAPI Eina_Bool evas_textblock_cursor_word_start(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
|
||||
|
||||
/**
|
||||
* Moves the cursor to the end of the word under the cursor.
|
||||
*
|
||||
* @param cur the cursor to move.
|
||||
* @return #EINA_TRUE on success #EINA_FALSE otherwise.
|
||||
* @since 1.2.0
|
||||
*/
|
||||
EAPI Eina_Bool evas_textblock_cursor_word_end(Evas_Textblock_Cursor *cur) EINA_ARG_NONNULL(1);
|
||||
|
||||
/**
|
||||
* Go to the first char in the node the cursor is pointing on.
|
||||
*
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
|
||||
#ifdef HAVE_LINEBREAK
|
||||
#include "linebreak.h"
|
||||
#include "wordbreak.h"
|
||||
#endif
|
||||
|
||||
/* save typing */
|
||||
|
@ -5734,6 +5735,111 @@ evas_textblock_cursor_format_prev(Evas_Textblock_Cursor *cur)
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINEBREAK
|
||||
|
||||
/* BREAK_AFTER: true if we can break after the current char.
|
||||
* Both macros assume str[i] is not the terminating nul */
|
||||
#define BREAK_AFTER(i) \
|
||||
(breaks[i] == WORDBREAK_BREAK)
|
||||
|
||||
#else
|
||||
|
||||
#define BREAK_AFTER(i) \
|
||||
((!str[i + 1]) || \
|
||||
(_is_white(str[i]) && !_is_white(str[i + 1])) || \
|
||||
(!_is_white(str[i]) && _is_white(str[i + 1])))
|
||||
|
||||
#endif
|
||||
|
||||
EAPI Eina_Bool
|
||||
evas_textblock_cursor_word_start(Evas_Textblock_Cursor *cur)
|
||||
{
|
||||
const Eina_Unicode *text;
|
||||
size_t i;
|
||||
#ifdef HAVE_LINEBREAK
|
||||
char *breaks;
|
||||
#endif
|
||||
|
||||
if (!cur) return EINA_FALSE;
|
||||
if (!cur->node) return EINA_FALSE;
|
||||
|
||||
text = eina_ustrbuf_string_get(cur->node->unicode);
|
||||
|
||||
#ifdef HAVE_LINEBREAK
|
||||
{
|
||||
const char *lang = ""; /* FIXME: get lang */
|
||||
size_t len = eina_ustrbuf_length_get(cur->node->unicode);
|
||||
breaks = malloc(len);
|
||||
set_wordbreaks_utf32((const utf32_t *) text, len, lang, breaks);
|
||||
}
|
||||
#endif
|
||||
|
||||
i = cur->pos;
|
||||
|
||||
/* Skip the first one. This ensures we don't point to the nul, and also
|
||||
* we just don't care about it anyway. */
|
||||
if (i > 0) i--;
|
||||
|
||||
for ( ; i > 0 ; i--)
|
||||
{
|
||||
if (BREAK_AFTER(i))
|
||||
{
|
||||
/* Advance to the current char */
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cur->pos = i;
|
||||
|
||||
#ifdef HAVE_LINEBREAK
|
||||
free(breaks);
|
||||
#endif
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
evas_textblock_cursor_word_end(Evas_Textblock_Cursor *cur)
|
||||
{
|
||||
const Eina_Unicode *text;
|
||||
size_t i;
|
||||
#ifdef HAVE_LINEBREAK
|
||||
char *breaks;
|
||||
#endif
|
||||
|
||||
if (!cur) return EINA_FALSE;
|
||||
if (!cur->node) return EINA_FALSE;
|
||||
|
||||
text = eina_ustrbuf_string_get(cur->node->unicode);
|
||||
|
||||
#ifdef HAVE_LINEBREAK
|
||||
{
|
||||
const char *lang = ""; /* FIXME: get lang */
|
||||
size_t len = eina_ustrbuf_length_get(cur->node->unicode);
|
||||
breaks = malloc(len);
|
||||
set_wordbreaks_utf32((const utf32_t *) text, len, lang, breaks);
|
||||
}
|
||||
#endif
|
||||
|
||||
i = cur->pos;
|
||||
|
||||
for ( ; text[i] ; i++)
|
||||
{
|
||||
if (BREAK_AFTER(i))
|
||||
{
|
||||
/* This is the one to break after. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cur->pos = i;
|
||||
|
||||
#ifdef HAVE_LINEBREAK
|
||||
free(breaks);
|
||||
#endif
|
||||
return EINA_TRUE;;
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur)
|
||||
{
|
||||
|
@ -8828,6 +8934,7 @@ evas_object_textblock_init(Evas_Object *obj)
|
|||
{
|
||||
linebreak_init = EINA_TRUE;
|
||||
init_linebreak();
|
||||
init_wordbreak();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -568,6 +568,32 @@ START_TEST(evas_textblock_cursor)
|
|||
fail_if(evas_textblock_cursor_compare(main_cur, cur));
|
||||
}
|
||||
|
||||
{
|
||||
const char *buf_wb = "a This is_a t:e.s't a";
|
||||
evas_object_textblock_text_markup_set(tb, buf_wb);
|
||||
|
||||
/* Word start/end */
|
||||
evas_textblock_cursor_pos_set(cur, 3);
|
||||
evas_textblock_cursor_word_start(cur);
|
||||
fail_if(2 != evas_textblock_cursor_pos_get(cur));
|
||||
evas_textblock_cursor_word_end(cur);
|
||||
fail_if(5 != evas_textblock_cursor_pos_get(cur));
|
||||
|
||||
evas_textblock_cursor_pos_set(cur, 13);
|
||||
evas_textblock_cursor_word_end(cur);
|
||||
fail_if(18 != evas_textblock_cursor_pos_get(cur));
|
||||
evas_textblock_cursor_word_start(cur);
|
||||
fail_if(12 != evas_textblock_cursor_pos_get(cur));
|
||||
evas_textblock_cursor_word_start(cur);
|
||||
fail_if(12 != evas_textblock_cursor_pos_get(cur));
|
||||
evas_textblock_cursor_word_start(cur);
|
||||
fail_if(12 != evas_textblock_cursor_pos_get(cur));
|
||||
evas_textblock_cursor_word_end(cur);
|
||||
fail_if(18 != evas_textblock_cursor_pos_get(cur));
|
||||
evas_textblock_cursor_word_end(cur);
|
||||
fail_if(18 != evas_textblock_cursor_pos_get(cur));
|
||||
}
|
||||
|
||||
END_TB_TEST();
|
||||
}
|
||||
END_TEST
|
||||
|
|
Loading…
Reference in New Issue