From 5ce841cac93fe66aad803d160212374368734f19 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 27 Aug 2021 21:05:09 +0100 Subject: [PATCH] Support newline in buttons Fixes #2378 --- .../doctabs/desktop/single_custom_theme.png | Bin 2297 -> 2293 bytes widget/button.go | 23 ++++++++++-------- widget/button_internal_test.go | 8 +++--- widget/button_test.go | 4 +++ .../layout_multiple_open_multiple_items.xml | 8 ++++-- ...ut_multiple_open_multiple_items_opened.xml | 8 ++++-- .../layout_multiple_open_one_item.xml | 4 ++- .../layout_multiple_open_one_item_opened.xml | 4 ++- .../layout_single_open_multiple_items.xml | 8 ++++-- ...yout_single_open_multiple_items_opened.xml | 8 ++++-- .../accordion/layout_single_open_one_item.xml | 4 ++- .../layout_single_open_one_item_opened.xml | 4 ++- .../layout_text_icon_center_leading.xml | 4 ++- .../layout_text_icon_center_trailing.xml | 4 ++- .../layout_text_icon_leading_leading.xml | 4 ++- .../layout_text_icon_leading_trailing.xml | 4 ++- .../layout_text_icon_trailing_leading.xml | 4 ++- .../layout_text_icon_trailing_trailing.xml | 4 ++- .../layout_text_only_center_leading.xml | 4 ++- .../layout_text_only_center_trailing.xml | 4 ++- .../layout_text_only_leading_leading.xml | 4 ++- .../layout_text_only_leading_trailing.xml | 4 ++- .../button/layout_text_only_multiline.xml | 22 +++++++++++++++++ .../layout_text_only_trailing_leading.xml | 4 ++- .../layout_text_only_trailing_trailing.xml | 4 ++- widget/testdata/form/layout.xml | 8 ++++-- 26 files changed, 122 insertions(+), 39 deletions(-) create mode 100644 widget/testdata/button/layout_text_only_multiline.xml diff --git a/container/testdata/doctabs/desktop/single_custom_theme.png b/container/testdata/doctabs/desktop/single_custom_theme.png index 63bc14ad294e9882942f0370ccc0a15fbe0e77ca..d5ac152b8b12637b6b9b1dc662f5e119e6c9472c 100644 GIT binary patch literal 2293 zcmcImdpHve7hm352-Um7%i{Hxj*3jH?nHWCbzu)tG|GnQI=bYy`&vSm~`JLxEzjIO@?V*z5a^e60KoWMz z+IcTx|6`&ed!FF`y#)Xe?SxrdxW<(5nTH%*87F#|*^osWa}NdL=su53Icq!c;JFY# zJ7=45Ida|baI=`W)BYAeXb8Hn8DVgeK62_)Rp#xg8zotXfu)`i1=e05oksU6;PE3^ zNm2E~2becU=fUe8rfFi-h3i}F9W%ldc!Bi>%p(dG+6@Ui<>Y8@D~kRgQQ?_FNzGC(&LIGE`O%bx~Hh>{#*`%4Ncr?NqR_li-c{`qtn$w-UUDYhjuu{Qcp z@{DabZ>ipaX*;5j-1;!utoc)^Kl{7KRyagVKG5%9?Y&vE+Du!62(wLn*c9h}^Tjla zIined8n6ymR`92zw#aUY67c%NvI`a25$covM9RC_4-VBBhp>d!%>fgdS;|CVZH%b& z@n*M}yDG@$-^3rS^4A=fr3{MDr!^~%XeoN71t*D;L;55nv*gv-<8S_c7ro$37-f!(6ciPW2{ad6V&;rSzL#Hgqj7EuzKsub7ajFn z3L6orywjC7oDyV7S9@T3#kfTeL}0ypT>jT{G>r5^p-d zoZ}=MIRz<0m23Te&9d4g(J03?`BgymEs#oWH$*Q0pR|lr^&K;cSxRB9Y)|r|whqg- zIjkR=eetMbE$cS zg`;~^bGI!Gd7)pV7Pplv@djVu5>hnE;?602GG)9@-i)2W*By#gSqwWo-HYk?x0tks`r`3Z|43Y#!_j2O4Lwe+=RBElfnxJ0w@wNsS1<>A2 z;k<7Hr}GmNteBlfZ_Y!7qhQU2QL`8e4PTLZj*nybjUIT-M2|u@OWDt{)6*Crj51}9 zv8OY=wmKz*v3~$dfBdR^Ufv|{Z%Y2A?N^V>i#5n|CXwO3R&qTL)ZPeFOA7=*VMn#1 zo5#6tO)>#jl6&2&6MX~GrL%>96*7rE3ZO}(rbY@F?dnJ{+ zR;;g|pBLljr*8xCJW@fASuc1?!DHeXVSLZMDwJzpOT$2?Ka@907?_`Qd4@Ty+`?zG z5#KXH1B3lxsWnaK?@o57zi zXuuoFw0jSMp4qHp9s?5t*5-Ny>|N*QMkaTdB%owR6u$u3kIi{}(x!WCY_7gO2ZI^O zhfBw)AG2z`;|2u!oR#IfhfaOPtE|SxL7`jAQ!1;QpxAhukUA#lG;|$P4x5U)6f*AvKUwi_w)>M zc8)_JMyg@@C~m?&zXS4$i(}3$x2}#*QmtO!Uh%+rtR|>h2P3qRhmETVY|7Jyr0bc+j^I5TvU5qN5SnKBby!d31$&FRKA! zV{X3sw{njRJTKDS^dbx6o=auXj~d^v{edKT6!G~fv!6r1);nd&)x_=m`Z_d(gJyj& zJO}@4@otYVL3eMqU`4ZVRwr@3%GNGp{8c5so?nbc&y|32)cd=S6gQI|5u;v3-`{{j z`wbn2gwk;{=DwiQ)^?>K5VZ~;r-&cxp5YjQs#Wz%j66>w_hK%u|;yc9ehoV zWEkm0?vvr4%e_~|TldxawBN<}px{2Ncm#q$D>Xv&J7W=RxWqg%`JrKHH;s19gE7I{ ziH9p3lgGKf&=?+G_hMLNkhZA@mr%d{>+*N*?gs#NcXI~&mUW)Ec<;S40GN%vb%W&% G^uGbZc$K&S literal 2297 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 diff --git a/widget/button.go b/widget/button.go index 69cda5a16b..5d58884af0 100644 --- a/widget/button.go +++ b/widget/button.go @@ -97,8 +97,10 @@ func NewButtonWithIcon(label string, icon fyne.Resource, tapped func()) *Button // CreateRenderer is a private method to Fyne which links this widget to its renderer func (b *Button) CreateRenderer() fyne.WidgetRenderer { b.ExtendBaseWidget(b) - text := canvas.NewText(b.Text, theme.ForegroundColor()) - text.TextStyle.Bold = true + seg := &TextSegment{Text: b.Text, Style: RichTextStyleStrong} + seg.Style.Alignment = fyne.TextAlignCenter + text := NewRichText(seg) + text.inset = fyne.NewSize(theme.Padding()*2, theme.Padding()*2) background := canvas.NewRectangle(theme.ButtonColor()) tapBG := canvas.NewRectangle(color.Transparent) @@ -216,7 +218,7 @@ type buttonRenderer struct { *widget.ShadowingRenderer icon *canvas.Image - label *canvas.Text + label *RichText background *canvas.Rectangle tapBG *canvas.Rectangle button *Button @@ -237,7 +239,7 @@ func (r *buttonRenderer) Layout(size fyne.Size) { r.background.Resize(bgSize) hasIcon := r.icon != nil - hasLabel := r.label.Text != "" + hasLabel := r.label.Segments[0].(*TextSegment).Text != "" if !hasIcon && !hasLabel { // Nothing to layout return @@ -277,7 +279,7 @@ func (r *buttonRenderer) Layout(size fyne.Size) { // amount of padding added. func (r *buttonRenderer) MinSize() (size fyne.Size) { hasIcon := r.icon != nil - hasLabel := r.label.Text != "" + hasLabel := r.label.Segments[0].(*TextSegment).Text != "" iconSize := fyne.NewSize(theme.IconInlineSize(), theme.IconInlineSize()) labelSize := r.label.MinSize() if hasLabel { @@ -295,7 +297,8 @@ func (r *buttonRenderer) MinSize() (size fyne.Size) { } func (r *buttonRenderer) Refresh() { - r.label.Text = r.button.Text + r.label.inset = fyne.NewSize(theme.Padding()*2, theme.Padding()*2) + r.label.Segments[0].(*TextSegment).Text = r.button.Text r.updateIconAndText() r.applyTheme() r.background.Refresh() @@ -306,14 +309,14 @@ func (r *buttonRenderer) Refresh() { // applyTheme updates this button to match the current theme func (r *buttonRenderer) applyTheme() { r.background.FillColor = r.buttonColor() - r.label.TextSize = theme.TextSize() - r.label.Color = theme.ForegroundColor() + r.label.Segments[0].(*TextSegment).Style.ColorName = theme.ColorNameForeground switch { case r.button.disabled: - r.label.Color = theme.DisabledColor() + r.label.Segments[0].(*TextSegment).Style.ColorName = theme.ColorNameDisabled case r.button.Importance == HighImportance: - r.label.Color = theme.BackgroundColor() + r.label.Segments[0].(*TextSegment).Style.ColorName = theme.ColorNameBackground } + r.label.Refresh() if r.icon != nil && r.icon.Resource != nil { switch res := r.icon.Resource.(type) { case *theme.ThemedResource: diff --git a/widget/button_internal_test.go b/widget/button_internal_test.go index 26f977a08e..2964947dfa 100644 --- a/widget/button_internal_test.go +++ b/widget/button_internal_test.go @@ -6,6 +6,7 @@ import ( "testing" "fyne.io/fyne/v2" + "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/internal/cache" col "fyne.io/fyne/v2/internal/color" "fyne.io/fyne/v2/internal/widget" @@ -208,12 +209,13 @@ func TestButton_Shadow(t *testing.T) { func TestButtonRenderer_ApplyTheme(t *testing.T) { button := &Button{} render := test.WidgetRenderer(button).(*buttonRenderer) + textRender := test.WidgetRenderer(render.label).(*textRenderer) - textSize := render.label.TextSize + textSize := textRender.Objects()[0].(*canvas.Text).TextSize customTextSize := textSize test.WithTestTheme(t, func() { - render.applyTheme() - customTextSize = render.label.TextSize + button.Refresh() + customTextSize = textRender.Objects()[0].(*canvas.Text).TextSize }) assert.NotEqual(t, textSize, customTextSize) diff --git a/widget/button_test.go b/widget/button_test.go index 302fda0711..aa787aec7b 100644 --- a/widget/button_test.go +++ b/widget/button_test.go @@ -190,6 +190,10 @@ func TestButton_Layout(t *testing.T) { alignment: widget.ButtonAlignTrailing, placement: widget.ButtonIconTrailingText, }, + "text_only_multiline": { + text: "Test\nLine2", + alignment: widget.ButtonAlignCenter, + }, "icon_only_center_leading": { icon: theme.CancelIcon(), alignment: widget.ButtonAlignCenter, diff --git a/widget/testdata/accordion/layout_multiple_open_multiple_items.xml b/widget/testdata/accordion/layout_multiple_open_multiple_items.xml index e4e410a193..ae41b1725d 100644 --- a/widget/testdata/accordion/layout_multiple_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_multiple_open_multiple_items.xml @@ -5,13 +5,17 @@ - A + + A + - B + + B + diff --git a/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml index 4fa3b215f8..fe99e23443 100644 --- a/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml @@ -5,13 +5,17 @@ - A + + A + - B + + B + diff --git a/widget/testdata/accordion/layout_multiple_open_one_item.xml b/widget/testdata/accordion/layout_multiple_open_one_item.xml index 3385f2393f..0e002cc886 100644 --- a/widget/testdata/accordion/layout_multiple_open_one_item.xml +++ b/widget/testdata/accordion/layout_multiple_open_one_item.xml @@ -5,7 +5,9 @@ - A + + A + diff --git a/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml b/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml index 0da8d246e2..91000a052b 100644 --- a/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml @@ -5,7 +5,9 @@ - A + + A + diff --git a/widget/testdata/accordion/layout_single_open_multiple_items.xml b/widget/testdata/accordion/layout_single_open_multiple_items.xml index e4e410a193..ae41b1725d 100644 --- a/widget/testdata/accordion/layout_single_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_single_open_multiple_items.xml @@ -5,13 +5,17 @@ - A + + A + - B + + B + diff --git a/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml index 51d5c5583b..61a5424731 100644 --- a/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml @@ -5,13 +5,17 @@ - A + + A + - B + + B + diff --git a/widget/testdata/accordion/layout_single_open_one_item.xml b/widget/testdata/accordion/layout_single_open_one_item.xml index 3385f2393f..0e002cc886 100644 --- a/widget/testdata/accordion/layout_single_open_one_item.xml +++ b/widget/testdata/accordion/layout_single_open_one_item.xml @@ -5,7 +5,9 @@ - A + + A + diff --git a/widget/testdata/accordion/layout_single_open_one_item_opened.xml b/widget/testdata/accordion/layout_single_open_one_item_opened.xml index 0da8d246e2..91000a052b 100644 --- a/widget/testdata/accordion/layout_single_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_single_open_one_item_opened.xml @@ -5,7 +5,9 @@ - A + + A + diff --git a/widget/testdata/button/layout_text_icon_center_leading.xml b/widget/testdata/button/layout_text_icon_center_leading.xml index 56920504d4..82cc0f85db 100644 --- a/widget/testdata/button/layout_text_icon_center_leading.xml +++ b/widget/testdata/button/layout_text_icon_center_leading.xml @@ -13,7 +13,9 @@ - Test + + Test + diff --git a/widget/testdata/button/layout_text_icon_center_trailing.xml b/widget/testdata/button/layout_text_icon_center_trailing.xml index 84e9424729..392b53311b 100644 --- a/widget/testdata/button/layout_text_icon_center_trailing.xml +++ b/widget/testdata/button/layout_text_icon_center_trailing.xml @@ -13,7 +13,9 @@ - Test + + Test + diff --git a/widget/testdata/button/layout_text_icon_leading_leading.xml b/widget/testdata/button/layout_text_icon_leading_leading.xml index 1bc8547b49..2be99cabd9 100644 --- a/widget/testdata/button/layout_text_icon_leading_leading.xml +++ b/widget/testdata/button/layout_text_icon_leading_leading.xml @@ -13,7 +13,9 @@ - Test + + Test + diff --git a/widget/testdata/button/layout_text_icon_leading_trailing.xml b/widget/testdata/button/layout_text_icon_leading_trailing.xml index e6017ad872..fb930d4ff6 100644 --- a/widget/testdata/button/layout_text_icon_leading_trailing.xml +++ b/widget/testdata/button/layout_text_icon_leading_trailing.xml @@ -13,7 +13,9 @@ - Test + + Test + diff --git a/widget/testdata/button/layout_text_icon_trailing_leading.xml b/widget/testdata/button/layout_text_icon_trailing_leading.xml index be7acf67de..a14e5c611c 100644 --- a/widget/testdata/button/layout_text_icon_trailing_leading.xml +++ b/widget/testdata/button/layout_text_icon_trailing_leading.xml @@ -13,7 +13,9 @@ - Test + + Test + diff --git a/widget/testdata/button/layout_text_icon_trailing_trailing.xml b/widget/testdata/button/layout_text_icon_trailing_trailing.xml index d9be60bcf6..ede8d11d3f 100644 --- a/widget/testdata/button/layout_text_icon_trailing_trailing.xml +++ b/widget/testdata/button/layout_text_icon_trailing_trailing.xml @@ -13,7 +13,9 @@ - Test + + Test + diff --git a/widget/testdata/button/layout_text_only_center_leading.xml b/widget/testdata/button/layout_text_only_center_leading.xml index 2577bd1ae4..1f400c95d1 100644 --- a/widget/testdata/button/layout_text_only_center_leading.xml +++ b/widget/testdata/button/layout_text_only_center_leading.xml @@ -13,7 +13,9 @@ - Test + + Test + diff --git a/widget/testdata/button/layout_text_only_center_trailing.xml b/widget/testdata/button/layout_text_only_center_trailing.xml index 2577bd1ae4..1f400c95d1 100644 --- a/widget/testdata/button/layout_text_only_center_trailing.xml +++ b/widget/testdata/button/layout_text_only_center_trailing.xml @@ -13,7 +13,9 @@ - Test + + Test + diff --git a/widget/testdata/button/layout_text_only_leading_leading.xml b/widget/testdata/button/layout_text_only_leading_leading.xml index 89bc1d7fec..7f63b321a8 100644 --- a/widget/testdata/button/layout_text_only_leading_leading.xml +++ b/widget/testdata/button/layout_text_only_leading_leading.xml @@ -13,7 +13,9 @@ - Test + + Test + diff --git a/widget/testdata/button/layout_text_only_leading_trailing.xml b/widget/testdata/button/layout_text_only_leading_trailing.xml index 89bc1d7fec..7f63b321a8 100644 --- a/widget/testdata/button/layout_text_only_leading_trailing.xml +++ b/widget/testdata/button/layout_text_only_leading_trailing.xml @@ -13,7 +13,9 @@ - Test + + Test + diff --git a/widget/testdata/button/layout_text_only_multiline.xml b/widget/testdata/button/layout_text_only_multiline.xml new file mode 100644 index 0000000000..d0cd7db937 --- /dev/null +++ b/widget/testdata/button/layout_text_only_multiline.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + Test + Line2 + + + + diff --git a/widget/testdata/button/layout_text_only_trailing_leading.xml b/widget/testdata/button/layout_text_only_trailing_leading.xml index 9c74be654b..24347356f2 100644 --- a/widget/testdata/button/layout_text_only_trailing_leading.xml +++ b/widget/testdata/button/layout_text_only_trailing_leading.xml @@ -13,7 +13,9 @@ - Test + + Test + diff --git a/widget/testdata/button/layout_text_only_trailing_trailing.xml b/widget/testdata/button/layout_text_only_trailing_trailing.xml index 9c74be654b..24347356f2 100644 --- a/widget/testdata/button/layout_text_only_trailing_trailing.xml +++ b/widget/testdata/button/layout_text_only_trailing_trailing.xml @@ -13,7 +13,9 @@ - Test + + Test + diff --git a/widget/testdata/form/layout.xml b/widget/testdata/form/layout.xml index 1cb5f9e9ff..a4e57306b4 100644 --- a/widget/testdata/form/layout.xml +++ b/widget/testdata/form/layout.xml @@ -49,7 +49,9 @@ - Cancel + + Cancel + @@ -65,7 +67,9 @@ - Submit + + Submit +