editor: Add support for setting a preedit
Add support for setting a preedit text to the editor example. Signed-off-by: Jan Arne Petersen <jpetersen@openismus.com>
This commit is contained in:
committed by
Kristian Høgsberg
parent
0e5bd45100
commit
c1fbcb7c38
+89
-2
@@ -51,6 +51,8 @@ struct text_entry {
|
|||||||
int active;
|
int active;
|
||||||
uint32_t cursor;
|
uint32_t cursor;
|
||||||
uint32_t anchor;
|
uint32_t anchor;
|
||||||
|
char *preedit_text;
|
||||||
|
uint32_t preedit_cursor;
|
||||||
struct text_model *model;
|
struct text_model *model;
|
||||||
struct text_layout *layout;
|
struct text_layout *layout;
|
||||||
};
|
};
|
||||||
@@ -311,6 +313,8 @@ text_entry_create(struct editor *editor, const char *text)
|
|||||||
entry->active = 0;
|
entry->active = 0;
|
||||||
entry->cursor = strlen(text);
|
entry->cursor = strlen(text);
|
||||||
entry->anchor = entry->cursor;
|
entry->anchor = entry->cursor;
|
||||||
|
entry->preedit_text = NULL;
|
||||||
|
entry->preedit_cursor = 0;
|
||||||
entry->model = text_model_factory_create_text_model(editor->text_model_factory);
|
entry->model = text_model_factory_create_text_model(editor->text_model_factory);
|
||||||
text_model_add_listener(entry->model, &text_model_listener, entry);
|
text_model_add_listener(entry->model, &text_model_listener, entry);
|
||||||
|
|
||||||
@@ -407,6 +411,30 @@ text_entry_deactivate(struct text_entry *entry,
|
|||||||
seat);
|
seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
text_entry_update_layout(struct text_entry *entry)
|
||||||
|
{
|
||||||
|
char *text;
|
||||||
|
|
||||||
|
assert(((unsigned int)entry->cursor) <= strlen(entry->text));
|
||||||
|
|
||||||
|
if (!entry->preedit_text) {
|
||||||
|
text_layout_set_text(entry->layout, entry->text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
text = malloc(strlen(entry->text) + strlen(entry->preedit_text) + 1);
|
||||||
|
strncpy(text, entry->text, entry->cursor);
|
||||||
|
strcpy(text + entry->cursor, entry->preedit_text);
|
||||||
|
strcpy(text + entry->cursor + strlen(entry->preedit_text),
|
||||||
|
entry->text + entry->cursor);
|
||||||
|
|
||||||
|
text_layout_set_text(entry->layout, text);
|
||||||
|
free(text);
|
||||||
|
|
||||||
|
widget_schedule_redraw(entry->widget);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
text_entry_insert_at_cursor(struct text_entry *entry, const char *text)
|
text_entry_insert_at_cursor(struct text_entry *entry, const char *text)
|
||||||
{
|
{
|
||||||
@@ -422,7 +450,27 @@ text_entry_insert_at_cursor(struct text_entry *entry, const char *text)
|
|||||||
entry->cursor += strlen(text);
|
entry->cursor += strlen(text);
|
||||||
entry->anchor += strlen(text);
|
entry->anchor += strlen(text);
|
||||||
|
|
||||||
text_layout_set_text(entry->layout, entry->text);
|
text_entry_update_layout(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
text_entry_set_preedit(struct text_entry *entry,
|
||||||
|
const char *preedit_text,
|
||||||
|
int preedit_cursor)
|
||||||
|
{
|
||||||
|
if (entry->preedit_text) {
|
||||||
|
free(entry->preedit_text);
|
||||||
|
entry->preedit_text = NULL;
|
||||||
|
entry->preedit_cursor = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preedit_text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
entry->preedit_text = strdup(preedit_text);
|
||||||
|
entry->preedit_cursor = preedit_cursor;
|
||||||
|
|
||||||
|
text_entry_update_layout(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -431,6 +479,12 @@ text_entry_set_cursor_position(struct text_entry *entry,
|
|||||||
{
|
{
|
||||||
entry->cursor = text_layout_xy_to_index(entry->layout, x, y);
|
entry->cursor = text_layout_xy_to_index(entry->layout, x, y);
|
||||||
|
|
||||||
|
if (entry->cursor >= entry->preedit_cursor) {
|
||||||
|
entry->cursor -= entry->preedit_cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
text_entry_update_layout(entry);
|
||||||
|
|
||||||
widget_schedule_redraw(entry->widget);
|
widget_schedule_redraw(entry->widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,7 +539,9 @@ text_entry_draw_cursor(struct text_entry *entry, cairo_t *cr)
|
|||||||
cairo_rectangle_t cursor_pos;
|
cairo_rectangle_t cursor_pos;
|
||||||
|
|
||||||
text_layout_extents(entry->layout, &extents);
|
text_layout_extents(entry->layout, &extents);
|
||||||
text_layout_get_cursor_pos(entry->layout, entry->cursor, &cursor_pos);
|
text_layout_get_cursor_pos(entry->layout,
|
||||||
|
entry->cursor + entry->preedit_cursor,
|
||||||
|
&cursor_pos);
|
||||||
|
|
||||||
cairo_set_line_width(cr, 1.0);
|
cairo_set_line_width(cr, 1.0);
|
||||||
cairo_move_to(cr, cursor_pos.x, extents.y_bearing + extents.height + 2);
|
cairo_move_to(cr, cursor_pos.x, extents.y_bearing + extents.height + 2);
|
||||||
@@ -493,6 +549,34 @@ text_entry_draw_cursor(struct text_entry *entry, cairo_t *cr)
|
|||||||
cairo_stroke(cr);
|
cairo_stroke(cr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
text_entry_draw_preedit(struct text_entry *entry, cairo_t *cr)
|
||||||
|
{
|
||||||
|
cairo_text_extents_t extents;
|
||||||
|
cairo_rectangle_t start;
|
||||||
|
cairo_rectangle_t end;
|
||||||
|
|
||||||
|
if (!entry->preedit_text)
|
||||||
|
return;
|
||||||
|
|
||||||
|
text_layout_extents(entry->layout, &extents);
|
||||||
|
|
||||||
|
text_layout_index_to_pos(entry->layout, entry->cursor, &start);
|
||||||
|
text_layout_index_to_pos(entry->layout,
|
||||||
|
entry->cursor + strlen(entry->preedit_text),
|
||||||
|
&end);
|
||||||
|
|
||||||
|
cairo_save (cr);
|
||||||
|
|
||||||
|
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0);
|
||||||
|
cairo_rectangle(cr,
|
||||||
|
start.x, 0,
|
||||||
|
end.x - start.x, 1);
|
||||||
|
cairo_fill(cr);
|
||||||
|
|
||||||
|
cairo_restore (cr);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
text_entry_redraw_handler(struct widget *widget, void *data)
|
text_entry_redraw_handler(struct widget *widget, void *data)
|
||||||
{
|
{
|
||||||
@@ -535,6 +619,8 @@ text_entry_redraw_handler(struct widget *widget, void *data)
|
|||||||
|
|
||||||
text_entry_draw_cursor(entry, cr);
|
text_entry_draw_cursor(entry, cr);
|
||||||
|
|
||||||
|
text_entry_draw_preedit(entry, cr);
|
||||||
|
|
||||||
cairo_pop_group_to_source(cr);
|
cairo_pop_group_to_source(cr);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
|
|
||||||
@@ -646,6 +732,7 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
editor.entry = text_entry_create(&editor, "Entry");
|
editor.entry = text_entry_create(&editor, "Entry");
|
||||||
editor.editor = text_entry_create(&editor, "Editor");
|
editor.editor = text_entry_create(&editor, "Editor");
|
||||||
|
text_entry_set_preedit(editor.editor, "preedit", strlen("preedit"));
|
||||||
|
|
||||||
window_set_title(editor.window, "Text Editor");
|
window_set_title(editor.window, "Text Editor");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user