diff --git a/.github/workflows/platform_tests.yml b/.github/workflows/platform_tests.yml index 6b4bafa5..aaf234f5 100644 --- a/.github/workflows/platform_tests.yml +++ b/.github/workflows/platform_tests.yml @@ -7,12 +7,12 @@ jobs: strategy: fail-fast: false matrix: - go-version: [1.14, 1.17] + go-version: ['1.17.x', '1.21.x'] os: [ubuntu-latest, windows-latest, macos-latest] steps: - uses: actions/checkout@v2 - - uses: WillAbides/setup-go-faster@v1.5.0 + - uses: WillAbides/setup-go-faster@v1.9.1 id: setup-go-faster with: go-version: ${{ matrix.go-version }} @@ -39,4 +39,4 @@ jobs: GOROOT: ${{steps.setup-go-faster.outputs.GOROOT}} with: path-to-profile: coverage.out - if: ${{ runner.os == 'Linux' && matrix.go-version == '1.17' && github.event_name == 'push' }} + if: ${{ runner.os == 'Linux' && matrix.go-version == '1.17.x' && github.event_name == 'push' }} diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index 31a4f67a..0a548696 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/checkout@v2 - uses: WillAbides/setup-go-faster@v1.6.0 with: - go-version: '1.16.x' + go-version: '1.17.x' - name: Get dependencies run: | diff --git a/widget/calendar.go b/widget/calendar.go index 184fa8fc..ae204df8 100644 --- a/widget/calendar.go +++ b/widget/calendar.go @@ -16,35 +16,53 @@ import ( // Declare conformity with Layout interface var _ fyne.Layout = (*calendarLayout)(nil) -const daysPerWeek int = 7 +const ( + daysPerWeek = 7 + maxWeeksPerMonth = 6 +) type calendarLayout struct { - cellSize float32 + cellSize fyne.Size } func newCalendarLayout() fyne.Layout { return &calendarLayout{} } -// Get the leading (top or left) edge of a grid cell. -// size is the ideal cell size and the offset is which col or row its on. -func (g *calendarLayout) getLeading(offset int) float32 { - ret := (g.cellSize) * float32(offset) +// Get the leading edge position of a grid cell. +// The row and col specify where the cell is in the calendar. +func (g *calendarLayout) getLeading(row, col int) fyne.Position { + x := (g.cellSize.Width) * float32(col) + y := (g.cellSize.Height) * float32(row) - return float32(math.Round(float64(ret))) + return fyne.NewPos(float32(math.Round(float64(x))), float32(math.Round(float64(y)))) } -// Get the trailing (bottom or right) edge of a grid cell. -// size is the ideal cell size and the offset is which col or row its on. -func (g *calendarLayout) getTrailing(offset int) float32 { - return g.getLeading(offset + 1) +// Get the trailing edge position of a grid cell. +// The row and col specify where the cell is in the calendar. +func (g *calendarLayout) getTrailing(row, col int) fyne.Position { + return g.getLeading(row+1, col+1) } // Layout is called to pack all child objects into a specified size. // For a GridLayout this will pack objects into a table format with the number // of columns specified in our constructor. func (g *calendarLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) { - g.cellSize = size.Width / float32(daysPerWeek) + weeks := 1 + day := 0 + for i, child := range objects { + if !child.Visible() { + continue + } + + if day%daysPerWeek == 0 && i >= daysPerWeek { + weeks++ + } + day++ + } + + g.cellSize = fyne.NewSize(size.Width/float32(daysPerWeek), + size.Height/float32(weeks)) row, col := 0, 0 i := 0 for _, child := range objects { @@ -52,13 +70,10 @@ func (g *calendarLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) { continue } - x1 := g.getLeading(col) - y1 := g.getLeading(row) - x2 := g.getTrailing(col) - y2 := g.getTrailing(row) - - child.Move(fyne.NewPos(x1, y1)) - child.Resize(fyne.NewSize(x2-x1, y2-y1)) + lead := g.getLeading(row, col) + trail := g.getTrailing(row, col) + child.Move(lead) + child.Resize(fyne.NewSize(trail.X, trail.Y).Subtract(lead)) if (i+1)%daysPerWeek == 0 { row++ @@ -70,9 +85,12 @@ func (g *calendarLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) { } } -//MinSize sets the minimum size for the calendar -func (g *calendarLayout) MinSize(objects []fyne.CanvasObject) fyne.Size { - return fyne.NewSize(250, 250) +// MinSize sets the minimum size for the calendar +func (g *calendarLayout) MinSize(_ []fyne.CanvasObject) fyne.Size { + pad := theme.Padding() + largestMin := widget.NewLabel("22").MinSize() + return fyne.NewSize(largestMin.Width*daysPerWeek+pad*(daysPerWeek-1), + largestMin.Height*maxWeeksPerMonth+pad*(maxWeeksPerMonth-1)) } // Calendar creates a new date time picker which returns a time object @@ -174,7 +192,7 @@ func (c *Calendar) CreateRenderer() fyne.WidgetRenderer { c.dates = container.New(newCalendarLayout(), c.calendarObjects()...) - dateContainer := container.NewVBox(nav, c.dates) + dateContainer := container.NewBorder(nav, nil, nil, nil, c.dates) return widget.NewSimpleRenderer(dateContainer) } diff --git a/widget/calendar_test.go b/widget/calendar_test.go index 978a8b5e..37233ca5 100644 --- a/widget/calendar_test.go +++ b/widget/calendar_test.go @@ -5,10 +5,11 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "fyne.io/fyne/v2" "fyne.io/fyne/v2/test" "fyne.io/fyne/v2/widget" - "github.com/stretchr/testify/assert" ) func TestNewCalendar(t *testing.T) { @@ -60,6 +61,29 @@ func TestNewCalendar_Previous(t *testing.T) { assert.Equal(t, date.Format("January 2006"), c.monthLabel.Text) } +func TestNewCalendar_Resize(t *testing.T) { + date := time.Now() + c := NewCalendar(date, func(time.Time) {}) + r := test.WidgetRenderer(c) // and render + layout := c.dates.Layout.(*calendarLayout) + + baseSize := c.MinSize() + r.Layout(baseSize) + min := layout.cellSize + + r.Layout(baseSize.AddWidthHeight(100, 0)) + assert.Greater(t, layout.cellSize.Width, min.Width) + assert.Equal(t, layout.cellSize.Height, min.Height) + + r.Layout(baseSize.AddWidthHeight(0, 100)) + assert.Equal(t, layout.cellSize.Width, min.Width) + assert.Greater(t, layout.cellSize.Height, min.Height) + + r.Layout(baseSize.AddWidthHeight(100, 100)) + assert.Greater(t, layout.cellSize.Width, min.Width) + assert.Greater(t, layout.cellSize.Height, min.Height) +} + func firstDateButton(c *fyne.Container) *widget.Button { for _, b := range c.Objects { if nonBlank, ok := b.(*widget.Button); ok { diff --git a/widget/gif_slow_test.go b/widget/gif_slow_test.go index 5ca3aed4..930c90d5 100644 --- a/widget/gif_slow_test.go +++ b/widget/gif_slow_test.go @@ -1,3 +1,4 @@ +//go:build slowtests // +build slowtests package widget