static void text_entry_delete_text(struct text_entry *entry, uint32_t index, uint32_t length) { uint32_t l; assert(index <= strlen(entry->text)); assert(index + length <= strlen(entry->text)); assert(index + length >= length); l = strlen(entry->text + index + length); memmove(entry->text + index, entry->text + index + length, l + 1); if (entry->cursor > (index + length)) entry->cursor -= length; else if (entry->cursor > index) entry->cursor = index; entry->anchor = entry->cursor; text_entry_update_layout(entry); widget_schedule_redraw(entry->widget); text_entry_update(entry); }
static void text_entry_insert_at_cursor(struct text_entry *entry, const char *text, int32_t cursor, int32_t anchor) { char *new_text = malloc(strlen(entry->text) + strlen(text) + 1); strncpy(new_text, entry->text, entry->cursor); strcpy(new_text + entry->cursor, text); strcpy(new_text + entry->cursor + strlen(text), entry->text + entry->cursor); free(entry->text); entry->text = new_text; if (anchor >= 0) entry->anchor = entry->cursor + strlen(text) + anchor; else entry->anchor = entry->cursor + 1 + anchor; if (cursor >= 0) entry->cursor += strlen(text) + cursor; else entry->cursor += 1 + cursor; text_entry_update_layout(entry); widget_schedule_redraw(entry->widget); text_entry_update(entry); }
static void text_entry_redraw_handler(struct widget *widget, void *data) { struct text_entry *entry = data; cairo_surface_t *surface; struct rectangle allocation; cairo_t *cr; surface = window_get_surface(entry->window); widget_get_allocation(entry->widget, &allocation); cr = cairo_create(surface); cairo_rectangle(cr, allocation.x, allocation.y, allocation.width, allocation.height); cairo_clip(cr); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_push_group(cr); cairo_translate(cr, allocation.x, allocation.y); cairo_set_source_rgba(cr, 1, 1, 1, 1); cairo_rectangle(cr, 0, 0, allocation.width, allocation.height); cairo_fill(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); if (entry->active) { cairo_rectangle(cr, 0, 0, allocation.width, allocation.height); cairo_set_line_width (cr, 3); cairo_set_source_rgba(cr, 0, 0, 1, 1.0); cairo_stroke(cr); } cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_translate(cr, text_offset_left, allocation.height / 2); if (!entry->layout) entry->layout = pango_cairo_create_layout(cr); else pango_cairo_update_layout(cr, entry->layout); text_entry_update_layout(entry); pango_cairo_show_layout(cr, entry->layout); text_entry_draw_cursor(entry, cr); cairo_pop_group_to_source(cr); cairo_paint(cr); cairo_destroy(cr); cairo_surface_destroy(surface); }
static void text_entry_delete_text(struct text_entry *entry, uint32_t index, uint32_t length) { if (entry->cursor > index) entry->cursor -= length; entry->anchor = entry->cursor; entry->text[index] = '\0'; strcat(entry->text, entry->text + index + length); text_entry_update_layout(entry); widget_schedule_redraw(entry->widget); }
static void text_entry_set_cursor_position(struct text_entry *entry, int32_t x, int32_t y) { entry->cursor = text_layout_xy_to_index(entry->layout, x, y); text_model_reset(entry->model); if (entry->cursor >= entry->preedit_cursor) { entry->cursor -= entry->preedit_cursor; } text_entry_update_layout(entry); widget_schedule_redraw(entry->widget); }
static void text_entry_set_preedit(struct text_entry *entry, const char *preedit_text, int preedit_cursor) { text_entry_reset_preedit(entry); if (!preedit_text) return; entry->preedit.text = strdup(preedit_text); entry->preedit.cursor = preedit_cursor; text_entry_update_layout(entry); widget_schedule_redraw(entry->widget); }
static void text_entry_insert_at_cursor(struct text_entry *entry, const char *text) { char *new_text = malloc(strlen(entry->text) + strlen(text) + 1); strncpy(new_text, entry->text, entry->cursor); strcpy(new_text + entry->cursor, text); strcpy(new_text + entry->cursor + strlen(text), entry->text + entry->cursor); free(entry->text); entry->text = new_text; entry->cursor += strlen(text); entry->anchor += strlen(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 text_entry_set_anchor_position(struct text_entry *entry, int32_t x, int32_t y) { int index, trailing; const char *text; pango_layout_xy_to_index(entry->layout, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing); text = pango_layout_get_text(entry->layout); entry->anchor = g_utf8_offset_to_pointer(text + index, trailing) - text; text_entry_update_layout(entry); widget_schedule_redraw(entry->widget); text_entry_update(entry); }
static void text_entry_set_cursor_position(struct text_entry *entry, int32_t x, int32_t y, bool move_anchor) { int index, trailing; const char *text; uint32_t cursor; pango_layout_xy_to_index(entry->layout, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing); text = pango_layout_get_text(entry->layout); cursor = g_utf8_offset_to_pointer(text + index, trailing) - text; if (move_anchor) entry->anchor = cursor; if (text_entry_has_preedit(entry)) { text_entry_commit_and_reset(entry); assert(!text_entry_has_preedit(entry)); } if (entry->cursor == cursor) return; entry->cursor = cursor; text_entry_update_layout(entry); widget_schedule_redraw(entry->widget); text_entry_update(entry); }