Skip to content

Commit

Permalink
fix(gui): TextEdit should reset the caret position after blur
Browse files Browse the repository at this point in the history
  • Loading branch information
lc-soft committed Mar 9, 2019
1 parent 51eef68 commit 8de4e71
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 26 deletions.
4 changes: 2 additions & 2 deletions include/LCUI/font/textlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ LCUI_API void TextLayer_AddUpdateTypeset(LCUI_TextLayer layer, int start_row);
LCUI_API void TextLayer_SetTextAlign(LCUI_TextLayer layer, int align);

/** 设置坐标偏移量 */
LCUI_API void TextLayer_SetOffset(LCUI_TextLayer layer, int offset_x,
int offset_y);
LCUI_API LCUI_BOOL TextLayer_SetOffset(LCUI_TextLayer layer, int offset_x,
int offset_y);

LCUI_API LCUI_TextLayer TextLayer_New(void);

Expand Down
10 changes: 7 additions & 3 deletions src/font/textlayer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1427,8 +1427,12 @@ void TextLayer_SetLineHeight(LCUI_TextLayer layer, int height)
layer->task.typeset_start_row = 0;
}

void TextLayer_SetOffset(LCUI_TextLayer layer, int offset_x, int offset_y)
LCUI_BOOL TextLayer_SetOffset(LCUI_TextLayer layer, int offset_x, int offset_y)
{
layer->new_offset_x = offset_x;
layer->new_offset_y = offset_y;
if (layer->new_offset_x != offset_x || layer->new_offset_y != offset_y) {
layer->new_offset_x = offset_x;
layer->new_offset_y = offset_y;
return TRUE;
}
return FALSE;
}
58 changes: 37 additions & 21 deletions src/gui/widget/textedit.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* textedit.c -- textedit widget, used to allow user edit text.
*
* Copyright (c) 2018, Liu chao <[email protected]> All rights reserved.
* Copyright (c) 2018-2019, Liu chao <[email protected]> All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
Expand Down Expand Up @@ -145,9 +145,10 @@ static void TextEdit_UpdateCaret(LCUI_Widget widget)
LCUI_TextEdit edit = GetData(widget);

int row = edit->layer->insert_y;
int offset_x, offset_y;
float height, width;
float scale = LCUIMetrics_GetScale();
float x, y, caret_x = 0, caret_y = 0;
float height, offset_x, offset_y;

if (!edit->is_placeholder_shown) {
LCUI_Pos pos;
Expand All @@ -157,33 +158,37 @@ static void TextEdit_UpdateCaret(LCUI_Widget widget)
caret_x = pos.x / scale;
caret_y = pos.y / scale;
}
offset_x = edit->layer->offset_x / scale;
offset_y = edit->layer->offset_y / scale;
offset_x = iround(edit->layer->offset_x / scale);
offset_y = iround(edit->layer->offset_y / scale);
x = caret_x + offset_x;
y = caret_y + offset_y;
width = edit->layer->width / scale;
height = TextLayer_GetRowHeight(edit->layer, row) / scale;
Widget_SetStyle(edit->caret, key_height, height, px);
/* 如果光标超出可见区域,则重新计算文本偏移距离 */
/* Keep the caret in the visible area */
if (x < 0) {
x = 0;
update_offset = TRUE;
}
if (y < 0) {
y = 0;
update_offset = TRUE;
}
if (x + edit->caret->width > widget->box.content.width) {
x = widget->box.content.width - edit->caret->width;
update_offset = TRUE;
}
if (y + edit->caret->height > widget->box.content.height) {
y = widget->box.content.height - edit->caret->height;
update_offset = TRUE;
}
if (update_offset) {
int ix = iround((x - caret_x) * scale);
int iy = iround((y - caret_y) * scale);
TextLayer_SetOffset(edit->layer, ix, iy);
/* Keep current line text in the visible area */
if (width < widget->box.content.width) {
x = caret_x;
} else if (edit->caret->width + offset_x + width <
widget->box.content.width) {
x = caret_x + widget->box.content.width -
(edit->layer->width / scale);
}
offset_x = iround((x - caret_x) * scale);
offset_y = iround((y - caret_y) * scale);
if (TextLayer_SetOffset(edit->layer, offset_x, offset_y)) {
edit->tasks[TASK_UPDATE] = TRUE;
Widget_AddTask(widget, LCUI_WTASK_USER);
}
Expand Down Expand Up @@ -235,7 +240,7 @@ static void TextBlock_OnDestroy(void *arg)
}

static int TextEdit_AddTextBlock(LCUI_Widget widget, const wchar_t *wtext,
TextBlockAction action, TextBlockOwner owner)
TextBlockAction action, TextBlockOwner owner)
{
const wchar_t *p;
LCUI_TextEdit edit;
Expand All @@ -253,7 +258,7 @@ static int TextEdit_AddTextBlock(LCUI_Widget widget, const wchar_t *wtext,
return -ENOMEM;
}
block->owner = owner;
block->type = action;
block->action = action;
size = edit->text_block_size;
if (i == 0) {
block->type = TEXT_BLOCK_BEGIN;
Expand Down Expand Up @@ -368,6 +373,7 @@ static void TextEdit_UpdateTextLayer(LCUI_Widget w)
LCUI_TextEdit edit;
LCUI_TextStyleRec style;
LinkedListNode *node;

LinkedList_Init(&rects);
scale = LCUIMetrics_GetScale();
edit = Widget_GetData(w, self.prototype);
Expand Down Expand Up @@ -525,7 +531,7 @@ int TextEdit_SetTextW(LCUI_Widget w, const wchar_t *wstr)
{
TextEdit_ClearText(w);
return TextEdit_AddTextBlock(w, wstr, TEXT_BLOCK_ACTION_APPEND,
TEXT_BLOCK_OWNER_SOURCE);
TEXT_BLOCK_OWNER_SOURCE);
}

int TextEdit_SetText(LCUI_Widget widget, const char *utf8_str)
Expand Down Expand Up @@ -553,13 +559,13 @@ void TextEdit_SetPasswordChar(LCUI_Widget w, wchar_t ch)
int TextEdit_AppendTextW(LCUI_Widget w, const wchar_t *wstr)
{
return TextEdit_AddTextBlock(w, wstr, TEXT_BLOCK_ACTION_APPEND,
TEXT_BLOCK_OWNER_SOURCE);
TEXT_BLOCK_OWNER_SOURCE);
}

int TextEdit_InsertTextW(LCUI_Widget w, const wchar_t *wstr)
{
return TextEdit_AddTextBlock(w, wstr, TEXT_BLOCK_ACTION_INSERT,
TEXT_BLOCK_OWNER_SOURCE);
TEXT_BLOCK_OWNER_SOURCE);
}

int TextEdit_SetPlaceHolderW(LCUI_Widget w, const wchar_t *wstr)
Expand All @@ -572,7 +578,7 @@ int TextEdit_SetPlaceHolderW(LCUI_Widget w, const wchar_t *wstr)
Widget_InvalidateArea(w, NULL, SV_PADDING_BOX);
}
return TextEdit_AddTextBlock(w, wstr, TEXT_BLOCK_ACTION_INSERT,
TEXT_BLOCK_OWNER_PLACEHOLDER);
TEXT_BLOCK_OWNER_PLACEHOLDER);
}

int TextEdit_SetPlaceHolder(LCUI_Widget w, const char *str)
Expand Down Expand Up @@ -603,16 +609,26 @@ static void TextEdit_OnParseText(LCUI_Widget w, const char *text)

static void TextEdit_OnFocus(LCUI_Widget widget, LCUI_WidgetEvent e, void *arg)
{
LCUI_TextEdit edit = Widget_GetData(widget, self.prototype);
LCUI_TextEdit edit;

edit = Widget_GetData(widget, self.prototype);
TextCaret_SetVisible(edit->caret, TRUE);
edit->tasks[TASK_UPDATE_CARET] = TRUE;
Widget_AddTask(widget, LCUI_WTASK_USER);
}

static void TextEdit_OnBlur(LCUI_Widget widget, LCUI_WidgetEvent e, void *arg)
{
LCUI_TextEdit edit = Widget_GetData(widget, self.prototype);
LCUI_TextEdit edit;

edit = Widget_GetData(widget, self.prototype);
TextCaret_SetVisible(edit->caret, FALSE);
/* In single-line editing mode, we should reset the caret position to
* the head, otherwise it will mistakenly think that only the last part
* is entered after inputting long text. */
if (!edit->is_multiline_mode) {
TextEdit_MoveCaret(widget, 0, 0);
}
}

static void TextEdit_TextBackspace(LCUI_Widget widget, int n_ch)
Expand Down

0 comments on commit 8de4e71

Please sign in to comment.