From 871ab502ec224d0e02de1d66382d8dbcfd92bfc5 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sun, 21 Feb 2021 12:24:19 +0000 Subject: [PATCH 1/2] Start fixing scrolling containing entries When setting up an entry do not expose a scroll container unless multiline or scrolling is specified. Fixes #1939 --- widget/entry.go | 31 ++++++++++++++----- widget/entry_test.go | 10 ++++-- widget/select_entry.go | 1 + .../disableable_disabled_custom_value.xml | 8 ++--- .../entry/disableable_disabled_empty.xml | 14 ++++----- .../disableable_disabled_placeholder.xml | 14 ++++----- .../disableable_enabled_custom_value.xml | 8 ++--- .../entry/disableable_enabled_empty.xml | 14 ++++----- .../entry/disableable_enabled_placeholder.xml | 14 ++++----- widget/testdata/entry/focus_gained.xml | 16 +++++----- widget/testdata/entry/focus_lost.xml | 14 ++++----- .../entry/focus_with_popup_dismissed.xml | 16 +++++----- .../entry/focus_with_popup_entry_selected.xml | 16 +++++----- .../entry/focus_with_popup_initial.xml | 16 +++++----- widget/testdata/entry/focused_disabled.xml | 14 ++++----- widget/testdata/entry/focused_enabled.xml | 16 +++++----- widget/testdata/entry/initial.xml | 14 ++++----- .../testdata/entry/placeholder_with_text.xml | 8 ++--- .../entry/placeholder_without_text.xml | 14 ++++----- .../testdata/entry/select_add_selection.xml | 12 +++---- widget/testdata/entry/select_initial.xml | 10 +++--- .../testdata/entry/select_move_wo_shift.xml | 10 +++--- widget/testdata/entry/select_select_left.xml | 12 +++---- widget/testdata/entry/select_selected.xml | 12 +++---- .../entry/select_single_line_pagedown.xml | 10 +++--- .../select_single_line_shift_pagedown.xml | 12 +++---- .../entry/select_single_line_shift_pageup.xml | 12 +++---- .../entry/set_placeholder_replaced.xml | 8 ++--- widget/testdata/entry/set_placeholder_set.xml | 14 ++++----- widget/testdata/entry/set_text_changed.xml | 8 ++--- widget/testdata/entry/set_text_style_bold.xml | 8 ++--- .../testdata/entry/set_text_style_italic.xml | 8 ++--- .../entry/set_text_style_monospace.xml | 8 ++--- .../entry/tapped_secondary_full_menu.xml | 16 +++++----- .../tapped_secondary_no_password_menu.xml | 14 ++++----- .../entry/tapped_secondary_password_menu.xml | 16 +++++----- .../entry/tapped_secondary_read_menu.xml | 14 ++++----- widget/testdata/entry/validate_initial.xml | 14 ++++----- widget/testdata/entry/validate_invalid.xml | 8 ++--- widget/testdata/entry/validate_valid.xml | 10 +++--- .../testdata/entry/wrap_single_line_off.xml | 10 +++--- 41 files changed, 224 insertions(+), 280 deletions(-) diff --git a/widget/entry.go b/widget/entry.go index cde5caadcc..d4440e1a4c 100644 --- a/widget/entry.go +++ b/widget/entry.go @@ -158,13 +158,21 @@ func (e *Entry) CreateRenderer() fyne.WidgetRenderer { // initialise e.textProvider() e.placeholderProvider() + scrolling := e.Wrapping != fyne.TextWrapOff box := canvas.NewRectangle(theme.InputBackgroundColor()) line := canvas.NewRectangle(theme.ShadowColor()) e.content = &entryContent{entry: e} - e.scroll = widget.NewScroll(e.content) - objects := []fyne.CanvasObject{box, line, e.scroll} + e.scroll = &widget.Scroll{} + objects := []fyne.CanvasObject{box, line} + if scrolling { + e.scroll.Content = e.content + objects = append(objects, e.scroll) + } else { + e.scroll.Hide() + objects = append(objects, e.content) + } e.content.scroll = e.scroll if e.Password && e.ActionItem == nil { @@ -1117,8 +1125,13 @@ func (r *entryRenderer) Layout(size fyne.Size) { entrySize := size.Subtract(fyne.NewSize(xInset, theme.InputBorderSize()*2)) entryPos := fyne.NewPos(0, theme.InputBorderSize()) - r.scroll.Resize(entrySize) - r.scroll.Move(entryPos) + if r.entry.Wrapping == fyne.TextWrapOff { + r.entry.content.Resize(entrySize) + r.entry.content.Move(entryPos) + } else { + r.scroll.Resize(entrySize) + r.scroll.Move(entryPos) + } } // MinSize calculates the minimum size of an entry widget. @@ -1126,7 +1139,7 @@ func (r *entryRenderer) Layout(size fyne.Size) { // If MultiLine is true then we will reserve space for at leasts 3 lines func (r *entryRenderer) MinSize() fyne.Size { if r.scroll.Direction == widget.ScrollNone { - return r.scroll.MinSize().Add(fyne.NewSize(0, theme.InputBorderSize()*2)) + return r.entry.content.MinSize().Add(fyne.NewSize(0, theme.InputBorderSize()*2)) } minSize := r.entry.placeholderProvider().charMinSize().Add(fyne.NewSize(theme.Padding()*2, theme.Padding()*2)) @@ -1193,7 +1206,7 @@ func (r *entryRenderer) Refresh() { r.entry.validationStatus.Hide() } - cache.Renderer(r.scroll.Content.(*entryContent)).Refresh() + cache.Renderer(r.entry.content).Refresh() canvas.Refresh(r.entry.super()) } @@ -1453,8 +1466,10 @@ func (r *entryContentRenderer) ensureCursorVisible() { } else if cy2 >= offset.X+size.Height { move.DY += cy2 - (offset.Y + size.Height) } - r.content.scroll.Offset = r.content.scroll.Offset.Add(move) - r.content.scroll.Refresh() + if r.content.scroll.Content != nil { + r.content.scroll.Offset = r.content.scroll.Offset.Add(move) + r.content.scroll.Refresh() + } } func (r *entryContentRenderer) moveCursor() { diff --git a/widget/entry_test.go b/widget/entry_test.go index 1981a9a1f7..f33b5b6296 100644 --- a/widget/entry_test.go +++ b/widget/entry_test.go @@ -1567,8 +1567,7 @@ func TestPasswordEntry_Reveal(t *testing.T) { // the Password field is set to true. // In this case the action item will be set when the renderer is created. t.Run("Entry with Password field", func(t *testing.T) { - entry := &widget.Entry{} - entry.Password = true + entry := &widget.Entry{Password: true, Wrapping: fyne.TextWrapWord} entry.Refresh() window := test.NewWindow(entry) defer window.Close() @@ -1657,7 +1656,12 @@ func checkNewlineIgnored(t *testing.T, entry *widget.Entry) { func setupImageTest(t *testing.T, multiLine bool) (*widget.Entry, fyne.Window) { test.NewApp() - entry := &widget.Entry{MultiLine: multiLine} + var entry *widget.Entry + if multiLine { + entry = &widget.Entry{MultiLine: true, Wrapping: fyne.TextWrapWord} + } else { + entry = &widget.Entry{Wrapping: fyne.TextWrapOff} + } w := test.NewWindow(entry) w.Resize(fyne.NewSize(150, 200)) diff --git a/widget/select_entry.go b/widget/select_entry.go index c9ad3891e0..92c878f93f 100644 --- a/widget/select_entry.go +++ b/widget/select_entry.go @@ -17,6 +17,7 @@ type SelectEntry struct { func NewSelectEntry(options []string) *SelectEntry { e := &SelectEntry{} e.ExtendBaseWidget(e) + e.Wrapping = fyne.TextTruncate e.options = options return e } diff --git a/widget/testdata/entry/disableable_disabled_custom_value.xml b/widget/testdata/entry/disableable_disabled_custom_value.xml index 2babf255c3..afe5585db2 100644 --- a/widget/testdata/entry/disableable_disabled_custom_value.xml +++ b/widget/testdata/entry/disableable_disabled_custom_value.xml @@ -3,11 +3,9 @@ - - - - Hello - + + + Hello diff --git a/widget/testdata/entry/disableable_disabled_empty.xml b/widget/testdata/entry/disableable_disabled_empty.xml index f5f7a0adea..6eefb3a03d 100644 --- a/widget/testdata/entry/disableable_disabled_empty.xml +++ b/widget/testdata/entry/disableable_disabled_empty.xml @@ -3,14 +3,12 @@ - - - - - - - - + + + + + + diff --git a/widget/testdata/entry/disableable_disabled_placeholder.xml b/widget/testdata/entry/disableable_disabled_placeholder.xml index 349e910d40..ab4bea56f0 100644 --- a/widget/testdata/entry/disableable_disabled_placeholder.xml +++ b/widget/testdata/entry/disableable_disabled_placeholder.xml @@ -3,14 +3,12 @@ - - - - Type! - - - - + + + Type! + + + diff --git a/widget/testdata/entry/disableable_enabled_custom_value.xml b/widget/testdata/entry/disableable_enabled_custom_value.xml index 4246b0bb02..e7a82232c4 100644 --- a/widget/testdata/entry/disableable_enabled_custom_value.xml +++ b/widget/testdata/entry/disableable_enabled_custom_value.xml @@ -3,11 +3,9 @@ - - - - Hello - + + + Hello diff --git a/widget/testdata/entry/disableable_enabled_empty.xml b/widget/testdata/entry/disableable_enabled_empty.xml index e11bd1d6e6..81c1ebd1cb 100644 --- a/widget/testdata/entry/disableable_enabled_empty.xml +++ b/widget/testdata/entry/disableable_enabled_empty.xml @@ -3,14 +3,12 @@ - - - - - - - - + + + + + + diff --git a/widget/testdata/entry/disableable_enabled_placeholder.xml b/widget/testdata/entry/disableable_enabled_placeholder.xml index 87953a6c18..fe8a3242e8 100644 --- a/widget/testdata/entry/disableable_enabled_placeholder.xml +++ b/widget/testdata/entry/disableable_enabled_placeholder.xml @@ -3,14 +3,12 @@ - - - - Type! - - - - + + + Type! + + + diff --git a/widget/testdata/entry/focus_gained.xml b/widget/testdata/entry/focus_gained.xml index fc9aa295da..1139d1a87d 100644 --- a/widget/testdata/entry/focus_gained.xml +++ b/widget/testdata/entry/focus_gained.xml @@ -3,16 +3,14 @@ - - - - - - - - - + + + + + + + diff --git a/widget/testdata/entry/focus_lost.xml b/widget/testdata/entry/focus_lost.xml index e11bd1d6e6..81c1ebd1cb 100644 --- a/widget/testdata/entry/focus_lost.xml +++ b/widget/testdata/entry/focus_lost.xml @@ -3,14 +3,12 @@ - - - - - - - - + + + + + + diff --git a/widget/testdata/entry/focus_with_popup_dismissed.xml b/widget/testdata/entry/focus_with_popup_dismissed.xml index fc9aa295da..1139d1a87d 100644 --- a/widget/testdata/entry/focus_with_popup_dismissed.xml +++ b/widget/testdata/entry/focus_with_popup_dismissed.xml @@ -3,16 +3,14 @@ - - - - - - - - - + + + + + + + diff --git a/widget/testdata/entry/focus_with_popup_entry_selected.xml b/widget/testdata/entry/focus_with_popup_entry_selected.xml index fc9aa295da..1139d1a87d 100644 --- a/widget/testdata/entry/focus_with_popup_entry_selected.xml +++ b/widget/testdata/entry/focus_with_popup_entry_selected.xml @@ -3,16 +3,14 @@ - - - - - - - - - + + + + + + + diff --git a/widget/testdata/entry/focus_with_popup_initial.xml b/widget/testdata/entry/focus_with_popup_initial.xml index e506f57665..a12ba795e4 100644 --- a/widget/testdata/entry/focus_with_popup_initial.xml +++ b/widget/testdata/entry/focus_with_popup_initial.xml @@ -3,16 +3,14 @@ - - - - - - - - - + + + + + + + diff --git a/widget/testdata/entry/focused_disabled.xml b/widget/testdata/entry/focused_disabled.xml index f5f7a0adea..6eefb3a03d 100644 --- a/widget/testdata/entry/focused_disabled.xml +++ b/widget/testdata/entry/focused_disabled.xml @@ -3,14 +3,12 @@ - - - - - - - - + + + + + + diff --git a/widget/testdata/entry/focused_enabled.xml b/widget/testdata/entry/focused_enabled.xml index fc9aa295da..1139d1a87d 100644 --- a/widget/testdata/entry/focused_enabled.xml +++ b/widget/testdata/entry/focused_enabled.xml @@ -3,16 +3,14 @@ - - - - - - - - - + + + + + + + diff --git a/widget/testdata/entry/initial.xml b/widget/testdata/entry/initial.xml index e11bd1d6e6..81c1ebd1cb 100644 --- a/widget/testdata/entry/initial.xml +++ b/widget/testdata/entry/initial.xml @@ -3,14 +3,12 @@ - - - - - - - - + + + + + + diff --git a/widget/testdata/entry/placeholder_with_text.xml b/widget/testdata/entry/placeholder_with_text.xml index 47208ccdae..f9be77abe8 100644 --- a/widget/testdata/entry/placeholder_with_text.xml +++ b/widget/testdata/entry/placeholder_with_text.xml @@ -3,11 +3,9 @@ - - - - Text - + + + Text diff --git a/widget/testdata/entry/placeholder_without_text.xml b/widget/testdata/entry/placeholder_without_text.xml index fa72a0bbdd..b06e54018c 100644 --- a/widget/testdata/entry/placeholder_without_text.xml +++ b/widget/testdata/entry/placeholder_without_text.xml @@ -3,14 +3,12 @@ - - - - Placehold - - - - + + + Placehold + + + diff --git a/widget/testdata/entry/select_add_selection.xml b/widget/testdata/entry/select_add_selection.xml index 0dc22ab066..a6d2197474 100644 --- a/widget/testdata/entry/select_add_selection.xml +++ b/widget/testdata/entry/select_add_selection.xml @@ -3,14 +3,12 @@ - - - - - Testing - - + + + + Testing + diff --git a/widget/testdata/entry/select_initial.xml b/widget/testdata/entry/select_initial.xml index 88d06bab3a..a77a2157b0 100644 --- a/widget/testdata/entry/select_initial.xml +++ b/widget/testdata/entry/select_initial.xml @@ -3,13 +3,11 @@ - - - - Testing - - + + + Testing + diff --git a/widget/testdata/entry/select_move_wo_shift.xml b/widget/testdata/entry/select_move_wo_shift.xml index 7e03ae3262..33f111450a 100644 --- a/widget/testdata/entry/select_move_wo_shift.xml +++ b/widget/testdata/entry/select_move_wo_shift.xml @@ -3,13 +3,11 @@ - - - - Testing - - + + + Testing + diff --git a/widget/testdata/entry/select_select_left.xml b/widget/testdata/entry/select_select_left.xml index 5c80331cec..fffd7d8c38 100644 --- a/widget/testdata/entry/select_select_left.xml +++ b/widget/testdata/entry/select_select_left.xml @@ -3,14 +3,12 @@ - - - - - Testing - - + + + + Testing + diff --git a/widget/testdata/entry/select_selected.xml b/widget/testdata/entry/select_selected.xml index 93bf488983..806c01bbdd 100644 --- a/widget/testdata/entry/select_selected.xml +++ b/widget/testdata/entry/select_selected.xml @@ -3,14 +3,12 @@ - - - - - Testing - - + + + + Testing + diff --git a/widget/testdata/entry/select_single_line_pagedown.xml b/widget/testdata/entry/select_single_line_pagedown.xml index ddaf0d08b3..f19036ec25 100644 --- a/widget/testdata/entry/select_single_line_pagedown.xml +++ b/widget/testdata/entry/select_single_line_pagedown.xml @@ -3,13 +3,11 @@ - - - - Testing - - + + + Testing + diff --git a/widget/testdata/entry/select_single_line_shift_pagedown.xml b/widget/testdata/entry/select_single_line_shift_pagedown.xml index afaafca133..31566b5021 100644 --- a/widget/testdata/entry/select_single_line_shift_pagedown.xml +++ b/widget/testdata/entry/select_single_line_shift_pagedown.xml @@ -3,14 +3,12 @@ - - - - - Testing - - + + + + Testing + diff --git a/widget/testdata/entry/select_single_line_shift_pageup.xml b/widget/testdata/entry/select_single_line_shift_pageup.xml index 81202bba56..6464b11bae 100644 --- a/widget/testdata/entry/select_single_line_shift_pageup.xml +++ b/widget/testdata/entry/select_single_line_shift_pageup.xml @@ -3,14 +3,12 @@ - - - - - Testing - - + + + + Testing + diff --git a/widget/testdata/entry/set_placeholder_replaced.xml b/widget/testdata/entry/set_placeholder_replaced.xml index 8598e25d9a..9ff8302639 100644 --- a/widget/testdata/entry/set_placeholder_replaced.xml +++ b/widget/testdata/entry/set_placeholder_replaced.xml @@ -3,11 +3,9 @@ - - - - Hi - + + + Hi diff --git a/widget/testdata/entry/set_placeholder_set.xml b/widget/testdata/entry/set_placeholder_set.xml index 4e7c3adae3..b9c9e3ef30 100644 --- a/widget/testdata/entry/set_placeholder_set.xml +++ b/widget/testdata/entry/set_placeholder_set.xml @@ -3,14 +3,12 @@ - - - - Test - - - - + + + Test + + + diff --git a/widget/testdata/entry/set_text_changed.xml b/widget/testdata/entry/set_text_changed.xml index b4b1a4c1ac..d57cc36583 100644 --- a/widget/testdata/entry/set_text_changed.xml +++ b/widget/testdata/entry/set_text_changed.xml @@ -3,11 +3,9 @@ - - - - Test - + + + Test diff --git a/widget/testdata/entry/set_text_style_bold.xml b/widget/testdata/entry/set_text_style_bold.xml index 9a6255936c..1f32faf7a1 100644 --- a/widget/testdata/entry/set_text_style_bold.xml +++ b/widget/testdata/entry/set_text_style_bold.xml @@ -3,11 +3,9 @@ - - - - Styled Text - + + + Styled Text diff --git a/widget/testdata/entry/set_text_style_italic.xml b/widget/testdata/entry/set_text_style_italic.xml index e9039eea6f..71cc881f0b 100644 --- a/widget/testdata/entry/set_text_style_italic.xml +++ b/widget/testdata/entry/set_text_style_italic.xml @@ -3,11 +3,9 @@ - - - - Styled Text - + + + Styled Text diff --git a/widget/testdata/entry/set_text_style_monospace.xml b/widget/testdata/entry/set_text_style_monospace.xml index 5df4141ba0..8b248fcecd 100644 --- a/widget/testdata/entry/set_text_style_monospace.xml +++ b/widget/testdata/entry/set_text_style_monospace.xml @@ -3,11 +3,9 @@ - - - - Styled Text - + + + Styled Text diff --git a/widget/testdata/entry/tapped_secondary_full_menu.xml b/widget/testdata/entry/tapped_secondary_full_menu.xml index 4c178cf416..ab6c9cc361 100644 --- a/widget/testdata/entry/tapped_secondary_full_menu.xml +++ b/widget/testdata/entry/tapped_secondary_full_menu.xml @@ -3,16 +3,14 @@ - - - - - - - - - + + + + + + + diff --git a/widget/testdata/entry/tapped_secondary_no_password_menu.xml b/widget/testdata/entry/tapped_secondary_no_password_menu.xml index f5f7a0adea..6eefb3a03d 100644 --- a/widget/testdata/entry/tapped_secondary_no_password_menu.xml +++ b/widget/testdata/entry/tapped_secondary_no_password_menu.xml @@ -3,14 +3,12 @@ - - - - - - - - + + + + + + diff --git a/widget/testdata/entry/tapped_secondary_password_menu.xml b/widget/testdata/entry/tapped_secondary_password_menu.xml index cc70974b55..8aad9fd8f7 100644 --- a/widget/testdata/entry/tapped_secondary_password_menu.xml +++ b/widget/testdata/entry/tapped_secondary_password_menu.xml @@ -3,16 +3,14 @@ - - - - - - - - - + + + + + + + diff --git a/widget/testdata/entry/tapped_secondary_read_menu.xml b/widget/testdata/entry/tapped_secondary_read_menu.xml index 11dafbe0b3..9c9744dc7e 100644 --- a/widget/testdata/entry/tapped_secondary_read_menu.xml +++ b/widget/testdata/entry/tapped_secondary_read_menu.xml @@ -3,14 +3,12 @@ - - - - - - - - + + + + + + diff --git a/widget/testdata/entry/validate_initial.xml b/widget/testdata/entry/validate_initial.xml index e11bd1d6e6..81c1ebd1cb 100644 --- a/widget/testdata/entry/validate_initial.xml +++ b/widget/testdata/entry/validate_initial.xml @@ -3,14 +3,12 @@ - - - - - - - - + + + + + + diff --git a/widget/testdata/entry/validate_invalid.xml b/widget/testdata/entry/validate_invalid.xml index f1ab8df5de..00eb13d7ea 100644 --- a/widget/testdata/entry/validate_invalid.xml +++ b/widget/testdata/entry/validate_invalid.xml @@ -3,11 +3,9 @@ - - - - 2020-02 - + + + 2020-02 diff --git a/widget/testdata/entry/validate_valid.xml b/widget/testdata/entry/validate_valid.xml index 6fc0c9ca6a..e711a60ad5 100644 --- a/widget/testdata/entry/validate_valid.xml +++ b/widget/testdata/entry/validate_valid.xml @@ -3,13 +3,11 @@ - - - - 2020-02-12 - - + + + 2020-02-12 + diff --git a/widget/testdata/entry/wrap_single_line_off.xml b/widget/testdata/entry/wrap_single_line_off.xml index fdf8adc0a8..8ac8b932ec 100644 --- a/widget/testdata/entry/wrap_single_line_off.xml +++ b/widget/testdata/entry/wrap_single_line_off.xml @@ -3,13 +3,11 @@ - - - - Testing Wrapping - - + + + Testing Wrapping + From b9f9f6e99a704a2463cfe2061c3052166d0c5aa9 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Thu, 25 Feb 2021 16:34:44 +0000 Subject: [PATCH 2/2] Fix the Entry/Scroll object hierarchy on Refresh if wrapping changes Required also fixing test masters for the off state which is now correct. --- widget/entry.go | 65 ++++++++++++++++--- widget/entry_test.go | 32 +++++++-- widget/testdata/entry/wrap_multi_line_off.xml | 10 ++- .../entry/wrap_multi_line_truncate.xml | 16 +++++ .../entry/wrap_single_line_truncate.xml | 16 +++++ 5 files changed, 116 insertions(+), 23 deletions(-) create mode 100644 widget/testdata/entry/wrap_multi_line_truncate.xml create mode 100644 widget/testdata/entry/wrap_single_line_truncate.xml diff --git a/widget/entry.go b/widget/entry.go index d4440e1a4c..6362d6f13f 100644 --- a/widget/entry.go +++ b/widget/entry.go @@ -158,7 +158,6 @@ func (e *Entry) CreateRenderer() fyne.WidgetRenderer { // initialise e.textProvider() e.placeholderProvider() - scrolling := e.Wrapping != fyne.TextWrapOff box := canvas.NewRectangle(theme.InputBackgroundColor()) line := canvas.NewRectangle(theme.ShadowColor()) @@ -166,7 +165,7 @@ func (e *Entry) CreateRenderer() fyne.WidgetRenderer { e.content = &entryContent{entry: e} e.scroll = &widget.Scroll{} objects := []fyne.CanvasObject{box, line} - if scrolling { + if e.Wrapping != fyne.TextWrapOff { e.scroll.Content = e.content objects = append(objects, e.scroll) } else { @@ -1091,6 +1090,24 @@ type entryRenderer struct { func (r *entryRenderer) Destroy() { } +func (r *entryRenderer) trailingInset() float32 { + xInset := float32(0) + + if r.entry.ActionItem != nil { + xInset = theme.IconInlineSize() + 2*theme.Padding() + } + + if r.entry.Validator != nil { + if r.entry.ActionItem == nil { + xInset = theme.IconInlineSize() + 2*theme.Padding() + } else { + xInset += theme.IconInlineSize() + theme.Padding() + } + } + + return xInset +} + func (r *entryRenderer) Layout(size fyne.Size) { r.line.Resize(fyne.NewSize(size.Width, theme.InputBorderSize())) r.line.Move(fyne.NewPos(0, size.Height-theme.InputBorderSize())) @@ -1098,10 +1115,8 @@ func (r *entryRenderer) Layout(size fyne.Size) { r.box.Move(fyne.NewPos(0, theme.InputBorderSize())) actionIconSize := fyne.NewSize(0, 0) - xInset := float32(0) if r.entry.ActionItem != nil { actionIconSize = fyne.NewSize(theme.IconInlineSize(), theme.IconInlineSize()) - xInset = theme.IconInlineSize() + 2*theme.Padding() r.entry.ActionItem.Resize(actionIconSize) r.entry.ActionItem.Move(fyne.NewPos(size.Width-actionIconSize.Width-2*theme.Padding(), theme.Padding()*2)) @@ -1116,14 +1131,12 @@ func (r *entryRenderer) Layout(size fyne.Size) { if r.entry.ActionItem == nil { r.entry.validationStatus.Move(fyne.NewPos(size.Width-validatorIconSize.Width-2*theme.Padding(), theme.Padding()*2)) - xInset = theme.IconInlineSize() + 2*theme.Padding() } else { r.entry.validationStatus.Move(fyne.NewPos(size.Width-validatorIconSize.Width-actionIconSize.Width-3*theme.Padding(), theme.Padding()*2)) - xInset += theme.IconInlineSize() + theme.Padding() } } - entrySize := size.Subtract(fyne.NewSize(xInset, theme.InputBorderSize()*2)) + entrySize := size.Subtract(fyne.NewSize(r.trailingInset(), theme.InputBorderSize()*2)) entryPos := fyne.NewPos(0, theme.InputBorderSize()) if r.entry.Wrapping == fyne.TextWrapOff { r.entry.content.Resize(entrySize) @@ -1163,12 +1176,44 @@ func (r *entryRenderer) Objects() []fyne.CanvasObject { func (r *entryRenderer) Refresh() { r.entry.propertyLock.RLock() provider := r.entry.textProvider() - content := r.entry.Text + text := r.entry.Text + content := r.entry.content focused := r.entry.focused + size := r.entry.size + wrapping := r.entry.Wrapping r.entry.propertyLock.RUnlock() - if content != string(provider.buffer) { - r.entry.SetText(content) + // correct our scroll wrappers if the wrap mode changed + entrySize := size.Subtract(fyne.NewSize(r.trailingInset(), theme.InputBorderSize()*2)) + if wrapping == fyne.TextWrapOff && r.scroll.Content != nil { + r.scroll.Hide() + r.scroll.Content = nil + content.Move(fyne.NewPos(0, theme.InputBorderSize())) + content.Resize(entrySize) + + for i, o := range r.objects { + if o == r.scroll { + r.objects[i] = content + break + } + } + } else if wrapping != fyne.TextWrapOff && r.scroll.Content == nil { + r.scroll.Content = content + content.Move(fyne.NewPos(0, 0)) + r.scroll.Move(fyne.NewPos(0, theme.InputBorderSize())) + r.scroll.Resize(entrySize) + r.scroll.Show() + + for i, o := range r.objects { + if o == content { + r.objects[i] = r.scroll + break + } + } + } + + if text != string(provider.buffer) { + r.entry.SetText(text) return } diff --git a/widget/entry_test.go b/widget/entry_test.go index f33b5b6296..96cfc0b52e 100644 --- a/widget/entry_test.go +++ b/widget/entry_test.go @@ -1392,20 +1392,19 @@ func TestEntry_TextWrap(t *testing.T) { "single line WrapOff": { want: "entry/wrap_single_line_off.xml", }, - // Disallowed - fallback to TextWrapOff "single line Truncate": { wrap: fyne.TextTruncate, - want: "entry/wrap_single_line_off.xml", + want: "entry/wrap_single_line_truncate.xml", }, - // Disallowed - fallback to TextWrapOff + // Disallowed - fallback to TextWrapTruncate (horizontal) "single line WrapBreak": { wrap: fyne.TextWrapBreak, - want: "entry/wrap_single_line_off.xml", + want: "entry/wrap_single_line_truncate.xml", }, - // Disallowed - fallback to TextWrapOff + // Disallowed - fallback to TextWrapTruncate (horizontal) "single line WrapWord": { wrap: fyne.TextWrapWord, - want: "entry/wrap_single_line_off.xml", + want: "entry/wrap_single_line_truncate.xml", }, "multi line WrapOff": { multiLine: true, @@ -1415,7 +1414,7 @@ func TestEntry_TextWrap(t *testing.T) { "multi line Truncate": { multiLine: true, wrap: fyne.TextTruncate, - want: "entry/wrap_multi_line_off.xml", + want: "entry/wrap_multi_line_truncate.xml", }, "multi line WrapBreak": { multiLine: true, @@ -1445,6 +1444,25 @@ func TestEntry_TextWrap(t *testing.T) { } } +func TestEntry_TextWrap_Changed(t *testing.T) { + e, window := setupImageTest(t, false) + defer teardownImageTest(window) + c := window.Canvas() + + c.Focus(e) + e.Wrapping = fyne.TextWrapOff + e.SetText("Testing Wrapping") + test.AssertRendersToMarkup(t, "entry/wrap_single_line_off.xml", c) + + e.Wrapping = fyne.TextTruncate + e.Refresh() + test.AssertRendersToMarkup(t, "entry/wrap_single_line_truncate.xml", c) + + e.Wrapping = fyne.TextWrapOff + e.Refresh() + test.AssertRendersToMarkup(t, "entry/wrap_single_line_off.xml", c) +} + func TestMultiLineEntry_MinSize(t *testing.T) { entry := widget.NewEntry() singleMin := entry.MinSize() diff --git a/widget/testdata/entry/wrap_multi_line_off.xml b/widget/testdata/entry/wrap_multi_line_off.xml index 72eacae2ea..e2cf97359f 100644 --- a/widget/testdata/entry/wrap_multi_line_off.xml +++ b/widget/testdata/entry/wrap_multi_line_off.xml @@ -3,13 +3,11 @@ - - - - A long text on short words w/o NLs or LFs. - - + + + A long text on short words w/o NLs or LFs. + diff --git a/widget/testdata/entry/wrap_multi_line_truncate.xml b/widget/testdata/entry/wrap_multi_line_truncate.xml new file mode 100644 index 0000000000..72eacae2ea --- /dev/null +++ b/widget/testdata/entry/wrap_multi_line_truncate.xml @@ -0,0 +1,16 @@ + + + + + + + + + A long text on short words w/o NLs or LFs. + + + + + + + diff --git a/widget/testdata/entry/wrap_single_line_truncate.xml b/widget/testdata/entry/wrap_single_line_truncate.xml new file mode 100644 index 0000000000..831bd83c0a --- /dev/null +++ b/widget/testdata/entry/wrap_single_line_truncate.xml @@ -0,0 +1,16 @@ + + + + + + + + + Testing Wrapping + + + + + + +