Skip to content

Commit

Permalink
Merge pull request #75 from andydotxyz/fix/74
Browse files Browse the repository at this point in the history
Fix layout of calendar to adapt to available height, not assuming square cells
  • Loading branch information
andydotxyz authored Oct 4, 2023
2 parents ad10f34 + 1640410 commit c04c36b
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 28 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/platform_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand All @@ -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' }}
2 changes: 1 addition & 1 deletion .github/workflows/static_analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
- uses: actions/checkout@v2
- uses: WillAbides/[email protected]
with:
go-version: '1.16.x'
go-version: '1.17.x'

- name: Get dependencies
run: |
Expand Down
64 changes: 41 additions & 23 deletions widget/calendar.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,49 +16,64 @@ 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 {
if !child.Visible() {
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++
Expand All @@ -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
Expand Down Expand Up @@ -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)
}
Expand Down
26 changes: 25 additions & 1 deletion widget/calendar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions widget/gif_slow_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build slowtests
// +build slowtests

package widget
Expand Down

0 comments on commit c04c36b

Please sign in to comment.