Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure Popups are resized in newly created window and when window is resized, fixes #1692 #1932

Merged
merged 9 commits into from Feb 26, 2021
16 changes: 1 addition & 15 deletions dialog/base.go
Expand Up @@ -126,21 +126,7 @@ func (d *dialog) Refresh() {
// Resize dialog, call this function after dialog show
func (d *dialog) Resize(size fyne.Size) {
d.desiredSize = size
maxSize := d.win.Size()
minSize := d.win.MinSize()
newWidth := size.Width
if size.Width > maxSize.Width {
newWidth = maxSize.Width
} else if size.Width < minSize.Width {
newWidth = minSize.Width
}
newHeight := size.Height
if size.Height > maxSize.Height {
newHeight = maxSize.Height
} else if size.Height < minSize.Height {
newHeight = minSize.Height
}
d.win.Resize(fyne.NewSize(newWidth, newHeight))
d.win.Resize(size)
}

// SetDismissText allows custom text to be set in the confirmation button
Expand Down
16 changes: 1 addition & 15 deletions dialog/file.go
Expand Up @@ -483,21 +483,7 @@ func (f *FileDialog) Resize(size fyne.Size) {
if f.dialog == nil {
return
}
maxSize := f.dialog.win.Size()
minSize := f.dialog.win.MinSize()
newWidth := size.Width
if size.Width > maxSize.Width {
newWidth = maxSize.Width
} else if size.Width < minSize.Width {
newWidth = minSize.Width
}
newHeight := size.Height
if size.Height > maxSize.Height {
newHeight = maxSize.Height
} else if size.Height < minSize.Height {
newHeight = minSize.Height
}
f.dialog.win.Resize(fyne.NewSize(newWidth, newHeight))
f.dialog.win.Resize(size)
}

// Hide hides the file dialog.
Expand Down
2 changes: 1 addition & 1 deletion internal/driver/glfw/canvas.go
Expand Up @@ -182,7 +182,7 @@ func (c *glCanvas) Resize(size fyne.Size) {
if p, ok := overlay.(*widget.PopUp); ok {
// TODO: remove this when #707 is being addressed.
// “Notifies” the PopUp of the canvas size change.
p.Resize(p.Content.Size().Add(fyne.NewSize(theme.Padding()*2, theme.Padding()*2)))
p.Refresh()
} else {
overlay.Resize(size)
}
Expand Down
34 changes: 26 additions & 8 deletions internal/driver/glfw/canvas_test.go
Expand Up @@ -422,14 +422,8 @@ func TestGlCanvas_ResizeWithOverlays(t *testing.T) {
o3 := widget.NewLabel("o3")
w.SetContent(content)
w.Canvas().Overlays().Add(o1)
// TODO: address #707; overlays should always be canvas size
o1.Resize(w.Canvas().Size())
w.Canvas().Overlays().Add(o2)
// TODO: address #707; overlays should always be canvas size
o2.Resize(w.Canvas().Size())
w.Canvas().Overlays().Add(o3)
// TODO: address #707; overlays should always be canvas size
o3.Resize(w.Canvas().Size())

size := fyne.NewSize(200, 100)
assert.NotEqual(t, size, content.Size())
Expand All @@ -451,12 +445,12 @@ func TestGlCanvas_ResizeWithPopUpOverlay(t *testing.T) {

content := widget.NewLabel("Content")
over := widget.NewPopUp(widget.NewLabel("Over"), w.Canvas())
over.Show() // to ensure popup content size is not zero
w.SetContent(content)
w.Canvas().Overlays().Add(over)
over.Show()

size := fyne.NewSize(200, 100)
overContentSize := over.Content.Size()
assert.NotZero(t, overContentSize)
assert.NotEqual(t, size, content.Size())
assert.NotEqual(t, size, over.Size())
assert.NotEqual(t, size, overContentSize)
Expand All @@ -467,6 +461,30 @@ func TestGlCanvas_ResizeWithPopUpOverlay(t *testing.T) {
assert.Equal(t, overContentSize, over.Content.Size(), "canvas overlay content is _not_ resized")
}

func TestGlCanvas_ResizeWithModalPopUpOverlay(t *testing.T) {
w := createWindow("Test")
w.SetPadded(false)

content := widget.NewLabel("Content")
w.SetContent(content)

popup := widget.NewModalPopUp(widget.NewLabel("PopUp"), w.Canvas())
popupBgSize := fyne.NewSize(975, 575)
popup.Show()
popup.Resize(popupBgSize)

winSize := fyne.NewSize(1000, 600)
w.Resize(winSize)
w.Show()
defer w.Close()

// get popup content padding dynamically
popupContentPadding := popup.MinSize().Subtract(popup.Content.MinSize())

assert.Equal(t, popupBgSize.Subtract(popupContentPadding), popup.Content.Size())
assert.Equal(t, winSize, popup.Size())
}

func TestGlCanvas_Scale(t *testing.T) {
w := createWindow("Test").(*window)
c := w.Canvas().(*glCanvas)
Expand Down
3 changes: 1 addition & 2 deletions internal/driver/gomobile/canvas.go
Expand Up @@ -340,8 +340,7 @@ func (c *mobileCanvas) sizeContent(size fyne.Size) {
if p, ok := overlay.(*widget.PopUp); ok {
// TODO: remove this when #707 is being addressed.
// “Notifies” the PopUp of the canvas size change.
size := p.Content.Size().Add(fyne.NewSize(theme.Padding()*2, theme.Padding()*2)).Min(areaSize)
p.Resize(size)
p.Refresh()
} else {
overlay.Resize(areaSize)
overlay.Move(topLeft)
Expand Down
20 changes: 20 additions & 0 deletions internal/driver/gomobile/canvas_test.go
Expand Up @@ -227,6 +227,26 @@ func TestWindow_TappedAndDoubleTapped(t *testing.T) {
assert.Equal(t, 2, tapped)
}

func TestGlCanvas_ResizeWithModalPopUpOverlay(t *testing.T) {
c := NewCanvas().(*mobileCanvas)

c.SetContent(widget.NewLabel("Content"))

popup := widget.NewModalPopUp(widget.NewLabel("PopUp"), c)
popupBgSize := fyne.NewSize(200, 200)
popup.Show()
popup.Resize(popupBgSize)

canvasSize := fyne.NewSize(600, 700)
c.resize(canvasSize)

// get popup content padding dynamically
popupContentPadding := popup.MinSize().Subtract(popup.Content.MinSize())

assert.Equal(t, popupBgSize.Subtract(popupContentPadding), popup.Content.Size())
assert.Equal(t, canvasSize, popup.Size())
}

func TestCanvas_Focusable(t *testing.T) {
content := newFocusableEntry()
c := NewCanvas().(*mobileCanvas)
Expand Down
13 changes: 12 additions & 1 deletion test/testcanvas.go
Expand Up @@ -160,8 +160,19 @@ func (c *testCanvas) Resize(size fyne.Size) {
return
}

// Ensure testcanvas mimics real canvas.Resize behavior
for _, overlay := range overlays.List() {
overlay.Resize(size)
type popupWidget interface {
fyne.CanvasObject
ShowAtPosition(fyne.Position)
}
if p, ok := overlay.(popupWidget); ok {
// TODO: remove this when #707 is being addressed.
fpabl0 marked this conversation as resolved.
Show resolved Hide resolved
// “Notifies” the PopUp of the canvas size change.
p.Refresh()
} else {
overlay.Resize(size)
}
}

if padded {
Expand Down
4 changes: 0 additions & 4 deletions widget/popup.go
Expand Up @@ -48,7 +48,6 @@ func (p *PopUp) Move(pos fyne.Position) {
// Implements: fyne.Widget
func (p *PopUp) Resize(size fyne.Size) {
p.innerSize = size
p.BaseWidget.Resize(p.Canvas.Size())
// The canvas size might not have changed and therefore the Resize won't trigger a layout.
// Until we have a widget.Relayout() or similar, the renderer's refresh will do the re-layout.
p.Refresh()
Expand All @@ -57,9 +56,6 @@ func (p *PopUp) Resize(size fyne.Size) {
// Show this pop-up as overlay if not already shown.
func (p *PopUp) Show() {
if !p.overlayShown {
if p.Size().IsZero() {
p.Resize(p.MinSize())
}
p.Canvas.Overlays().Add(p)
p.overlayShown = true
}
Expand Down
54 changes: 54 additions & 0 deletions widget/popup_test.go
Expand Up @@ -350,6 +350,33 @@ func TestPopUp_ResizeOnShow(t *testing.T) {
pop.Hide()
}

func TestPopUp_ResizeBeforeShow_CanvasSizeZero(t *testing.T) {
test.NewApp()
defer test.NewApp()

// Simulate canvas size {0,0}
rect := canvas.NewRectangle(color.Black)
rect.SetMinSize(fyne.NewSize(0, 0))
w := test.NewWindow(rect)
w.SetPadded(false)
w.Resize(fyne.NewSize(0, 0))
assert.Zero(t, w.Canvas().Size())

pop := NewPopUp(NewLabel("Label"), w.Canvas())
popBgSize := fyne.NewSize(200, 200)
pop.Resize(popBgSize)
pop.Show()

winSize := fyne.NewSize(300, 300)
w.Resize(winSize)

// get content padding dynamically
popContentPadding := pop.MinSize().Subtract(pop.Content.MinSize())

assert.Equal(t, popBgSize.Subtract(popContentPadding), pop.Content.Size())
assert.Equal(t, winSize, pop.Size())
}

func TestModalPopUp_Tapped(t *testing.T) {
label := NewLabel("Hi")
pop := NewModalPopUp(label, test.Canvas())
Expand Down Expand Up @@ -451,3 +478,30 @@ func TestModalPopUp_ResizeOnShow(t *testing.T) {
assert.Equal(t, size, pop.Size())
pop.Hide()
}

func TestModelPopUp_ResizeBeforeShow_CanvasSizeZero(t *testing.T) {
test.NewApp()
defer test.NewApp()

// Simulate canvas size {0,0}
rect := canvas.NewRectangle(color.Black)
rect.SetMinSize(fyne.NewSize(0, 0))
w := test.NewWindow(rect)
w.SetPadded(false)
w.Resize(fyne.NewSize(0, 0))
assert.Zero(t, w.Canvas().Size())

pop := NewModalPopUp(NewLabel("Label"), w.Canvas())
popBgSize := fyne.NewSize(200, 200)
pop.Resize(popBgSize)
pop.Show()

winSize := fyne.NewSize(300, 300)
w.Resize(winSize)

// get content padding dynamically
popContentPadding := pop.MinSize().Subtract(pop.Content.MinSize())

assert.Equal(t, popBgSize.Subtract(popContentPadding), pop.Content.Size())
assert.Equal(t, winSize, pop.Size())
}