From 09431a45ec16ea64464615a5f73d27fe9e817d3b Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sun, 23 Apr 2023 19:45:16 +0100 Subject: [PATCH] Address alignment issues by not mixing SVG and and solid canvas items Fixes #3792 --- theme/bundled-icons.go | 16 +++++++++++++--- theme/gen.go | 2 ++ theme/icons.go | 2 ++ theme/icons/check-box-fill.svg | 8 ++++++++ theme/icons/radio-button-fill.svg | 9 +++++++++ widget/check.go | 22 ++++++++++++---------- widget/radio_item.go | 24 ++++++++++-------------- 7 files changed, 56 insertions(+), 27 deletions(-) create mode 100644 theme/icons/check-box-fill.svg create mode 100644 theme/icons/radio-button-fill.svg diff --git a/theme/bundled-icons.go b/theme/bundled-icons.go index 0383a5c477..680e85f2aa 100644 --- a/theme/bundled-icons.go +++ b/theme/bundled-icons.go @@ -50,9 +50,14 @@ var checkboxIconRes = &fyne.StaticResource{ StaticContent: []byte("\n\n \n\n"), } -var checkboxblankIconRes = &fyne.StaticResource{ - StaticName: "check-box-blank.svg", - StaticContent: []byte("\n\n \n \n \n image/svg+xml\n \n \n \n \n \n \n \n \n \n\n"), +var checkboxcheckedIconRes = &fyne.StaticResource{ + StaticName: "check-box-checked.svg", + StaticContent: []byte("\n\n \n\n"), +} + +var checkboxfillIconRes = &fyne.StaticResource{ + StaticName: "check-box-fill.svg", + StaticContent: []byte("\n\n \n\n"), } var radiobuttonIconRes = &fyne.StaticResource{ @@ -65,6 +70,11 @@ var radiobuttoncheckedIconRes = &fyne.StaticResource{ StaticContent: []byte("\n\n \n\n"), } +var radiobuttonfillIconRes = &fyne.StaticResource{ + StaticName: "radio-button-fill.svg", + StaticContent: []byte("\n\n \n\n"), +} + var contentaddIconRes = &fyne.StaticResource{ StaticName: "content-add.svg", StaticContent: []byte(""), diff --git a/theme/gen.go b/theme/gen.go index ea227a87db..422b658219 100644 --- a/theme/gen.go +++ b/theme/gen.go @@ -89,8 +89,10 @@ func main() { bundleIcon("check-box", f) bundleIcon("check-box-checked", f) + bundleIcon("check-box-fill", f) bundleIcon("radio-button", f) bundleIcon("radio-button-checked", f) + bundleIcon("radio-button-fill", f) bundleIcon("content-add", f) bundleIcon("content-remove", f) diff --git a/theme/icons.go b/theme/icons.go index fe1fabb803..cb8f43f381 100644 --- a/theme/icons.go +++ b/theme/icons.go @@ -464,8 +464,10 @@ var ( IconNameCheckButton: NewThemedResource(checkboxIconRes), IconNameCheckButtonChecked: NewThemedResource(checkboxcheckedIconRes), + "iconNameCheckButtonFill": NewThemedResource(checkboxfillIconRes), IconNameRadioButton: NewThemedResource(radiobuttonIconRes), IconNameRadioButtonChecked: NewThemedResource(radiobuttoncheckedIconRes), + "iconNameRadioButtonFill": NewThemedResource(radiobuttonfillIconRes), IconNameContentAdd: NewThemedResource(contentaddIconRes), IconNameContentClear: NewThemedResource(cancelIconRes), diff --git a/theme/icons/check-box-fill.svg b/theme/icons/check-box-fill.svg new file mode 100644 index 0000000000..e4a1e4322e --- /dev/null +++ b/theme/icons/check-box-fill.svg @@ -0,0 +1,8 @@ + + + + diff --git a/theme/icons/radio-button-fill.svg b/theme/icons/radio-button-fill.svg new file mode 100644 index 0000000000..bb647521b9 --- /dev/null +++ b/theme/icons/radio-button-fill.svg @@ -0,0 +1,9 @@ + + + + diff --git a/widget/check.go b/widget/check.go index 4ffbb809f1..d110ad5d0e 100644 --- a/widget/check.go +++ b/widget/check.go @@ -14,8 +14,7 @@ import ( type checkRenderer struct { widget.BaseRenderer - bg *canvas.Rectangle - icon *canvas.Image + bg, icon *canvas.Image label *canvas.Text focusIndicator *canvas.Circle check *Check @@ -46,19 +45,17 @@ func (c *checkRenderer) Layout(size fyne.Size) { iconPos := fyne.NewPos(theme.InnerPadding()/2+theme.InputBorderSize(), (size.Height-theme.IconInlineSize())/2) iconSize := fyne.NewSize(theme.IconInlineSize(), theme.IconInlineSize()) - c.bg.Move(iconPos.AddXY(4, 4)) // absolute numbers to move relative to SVG details - c.bg.Resize(iconSize.SubtractWidthHeight(8, 8)) + c.bg.Move(iconPos) + c.bg.Resize(iconSize) c.icon.Resize(iconSize) c.icon.Move(iconPos) } // applyTheme updates this Check to the current theme func (c *checkRenderer) applyTheme() { - c.bg.FillColor = color.Transparent c.label.Color = theme.ForegroundColor() c.label.TextSize = theme.TextSize() if c.check.disabled { - c.bg.FillColor = theme.InputBackgroundColor() c.label.Color = theme.DisabledColor() } } @@ -80,20 +77,24 @@ func (c *checkRenderer) updateLabel() { func (c *checkRenderer) updateResource() { res := theme.NewThemedResource(theme.CheckButtonIcon()) res.ColorName = theme.ColorNameInputBorder - c.bg.FillColor = theme.InputBackgroundColor() + // TODO move to `theme.CheckButtonFillIcon()` when we add it in 2.4 + bgRes := theme.NewThemedResource(fyne.CurrentApp().Settings().Theme().Icon("iconNameCheckButtonFill")) + bgRes.ColorName = theme.ColorNameInputBackground + if c.check.Checked { res = theme.NewThemedResource(theme.CheckButtonCheckedIcon()) res.ColorName = theme.ColorNamePrimary - c.bg.FillColor = theme.BackgroundColor() + bgRes.ColorName = theme.ColorNameBackground } if c.check.disabled { if c.check.Checked { res = theme.NewThemedResource(theme.CheckButtonCheckedIcon()) } res.ColorName = theme.ColorNameDisabled - c.bg.FillColor = color.Transparent + bgRes.ColorName = theme.ColorNameBackground } c.icon.Resource = res + c.bg.Resource = bgRes } func (c *checkRenderer) updateFocusIndicator() { @@ -209,7 +210,8 @@ func (c *Check) CreateRenderer() fyne.WidgetRenderer { c.ExtendBaseWidget(c) c.propertyLock.RLock() defer c.propertyLock.RUnlock() - bg := canvas.NewRectangle(theme.InputBackgroundColor()) + // TODO move to `theme.CheckButtonFillIcon()` when we add it in 2.4 + bg := canvas.NewImageFromResource(fyne.CurrentApp().Settings().Theme().Icon("iconNameCheckButtonFill")) icon := canvas.NewImageFromResource(theme.CheckButtonIcon()) text := canvas.NewText(c.Text, theme.ForegroundColor()) diff --git a/widget/radio_item.go b/widget/radio_item.go index bc7b881871..ca09212850 100644 --- a/widget/radio_item.go +++ b/widget/radio_item.go @@ -39,14 +39,14 @@ type radioItem struct { func (i *radioItem) CreateRenderer() fyne.WidgetRenderer { focusIndicator := canvas.NewCircle(color.Transparent) bg := canvas.NewCircle(theme.InputBackgroundColor()) - icon := canvas.NewImageFromResource(theme.NewPrimaryThemedResource(theme.RadioButtonCheckedIcon())) + // TODO move to `theme.RadioButtonFillIcon()` when we add it in 2.4 + icon := canvas.NewImageFromResource(fyne.CurrentApp().Settings().Theme().Icon("iconNameRadioButtonFill")) over := canvas.NewImageFromResource(theme.NewThemedResource(theme.RadioButtonIcon())) label := canvas.NewText(i.Label, theme.ForegroundColor()) label.Alignment = fyne.TextAlignLeading r := &radioItemRenderer{ BaseRenderer: widget.NewBaseRenderer([]fyne.CanvasObject{focusIndicator, bg, icon, over, label}), focusIndicator: focusIndicator, - bg: bg, icon: icon, over: over, item: i, @@ -152,10 +152,10 @@ func (i *radioItem) toggle() { type radioItemRenderer struct { widget.BaseRenderer - bg, focusIndicator *canvas.Circle - icon, over *canvas.Image - item *radioItem - label *canvas.Text + focusIndicator *canvas.Circle + icon, over *canvas.Image + item *radioItem + label *canvas.Text } func (r *radioItemRenderer) Layout(size fyne.Size) { @@ -169,8 +169,6 @@ func (r *radioItemRenderer) Layout(size fyne.Size) { iconPos := fyne.NewPos(theme.InnerPadding()/2+theme.InputBorderSize(), (size.Height-theme.IconInlineSize())/2) iconSize := fyne.NewSize(theme.IconInlineSize(), theme.IconInlineSize()) - r.bg.Move(iconPos.AddXY(3, 3)) // absolute numbers to move relative to SVG details - r.bg.Resize(iconSize.SubtractWidthHeight(6, 6)) r.icon.Resize(iconSize) r.icon.Move(iconPos) r.over.Resize(iconSize) @@ -200,17 +198,15 @@ func (r *radioItemRenderer) update() { out := theme.NewThemedResource(theme.RadioButtonIcon()) out.ColorName = theme.ColorNameInputBorder - in := theme.NewThemedResource(theme.RadioButtonCheckedIcon()) - r.icon.Hidden = true - r.bg.FillColor = theme.InputBackgroundColor() + // TODO move to `theme.RadioButtonFillIcon()` when we add it in 2.4 + in := theme.NewThemedResource(fyne.CurrentApp().Settings().Theme().Icon("iconNameRadioButtonFill")) + in.ColorName = theme.ColorNameInputBackground if r.item.Selected { in.ColorName = theme.ColorNamePrimary - r.icon.Hidden = false out.ColorName = theme.ColorNameForeground } if r.item.Disabled() { - r.bg.FillColor = theme.BackgroundColor() - in.ColorName = theme.ColorNameDisabled + in.ColorName = theme.ColorNameBackground out.ColorName = theme.ColorNameDisabled } r.icon.Resource = in