testdriver.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package test
  2. import (
  3. "image"
  4. "sync"
  5. "fyne.io/fyne/v2"
  6. "fyne.io/fyne/v2/internal/driver"
  7. "fyne.io/fyne/v2/internal/painter"
  8. "fyne.io/fyne/v2/internal/painter/software"
  9. intRepo "fyne.io/fyne/v2/internal/repository"
  10. "fyne.io/fyne/v2/storage/repository"
  11. )
  12. // SoftwarePainter describes a simple type that can render canvases
  13. type SoftwarePainter interface {
  14. Paint(fyne.Canvas) image.Image
  15. }
  16. type testDriver struct {
  17. device *device
  18. painter SoftwarePainter
  19. windows []fyne.Window
  20. windowsMutex sync.RWMutex
  21. }
  22. // Declare conformity with Driver
  23. var _ fyne.Driver = (*testDriver)(nil)
  24. // NewDriver sets up and registers a new dummy driver for test purpose
  25. func NewDriver() fyne.Driver {
  26. drv := &testDriver{windowsMutex: sync.RWMutex{}}
  27. repository.Register("file", intRepo.NewFileRepository())
  28. // make a single dummy window for rendering tests
  29. drv.CreateWindow("")
  30. return drv
  31. }
  32. // NewDriverWithPainter creates a new dummy driver that will pass the given
  33. // painter to all canvases created
  34. func NewDriverWithPainter(painter SoftwarePainter) fyne.Driver {
  35. return &testDriver{
  36. painter: painter,
  37. windowsMutex: sync.RWMutex{},
  38. }
  39. }
  40. func (d *testDriver) AbsolutePositionForObject(co fyne.CanvasObject) fyne.Position {
  41. c := d.CanvasForObject(co)
  42. if c == nil {
  43. return fyne.NewPos(0, 0)
  44. }
  45. tc := c.(*testCanvas)
  46. return driver.AbsolutePositionForObject(co, tc.objectTrees())
  47. }
  48. func (d *testDriver) AllWindows() []fyne.Window {
  49. d.windowsMutex.RLock()
  50. defer d.windowsMutex.RUnlock()
  51. return d.windows
  52. }
  53. func (d *testDriver) CanvasForObject(fyne.CanvasObject) fyne.Canvas {
  54. d.windowsMutex.RLock()
  55. defer d.windowsMutex.RUnlock()
  56. // cheating: probably the last created window is meant
  57. return d.windows[len(d.windows)-1].Canvas()
  58. }
  59. func (d *testDriver) CreateWindow(string) fyne.Window {
  60. canvas := NewCanvas().(*testCanvas)
  61. if d.painter != nil {
  62. canvas.painter = d.painter
  63. } else {
  64. canvas.painter = software.NewPainter()
  65. }
  66. window := &testWindow{canvas: canvas, driver: d}
  67. window.clipboard = &testClipboard{}
  68. d.windowsMutex.Lock()
  69. d.windows = append(d.windows, window)
  70. d.windowsMutex.Unlock()
  71. return window
  72. }
  73. func (d *testDriver) Device() fyne.Device {
  74. if d.device == nil {
  75. d.device = &device{}
  76. }
  77. return d.device
  78. }
  79. // RenderedTextSize looks up how bit a string would be if drawn on screen
  80. func (d *testDriver) RenderedTextSize(text string, size float32, style fyne.TextStyle) (fyne.Size, float32) {
  81. return painter.RenderedTextSize(text, size, style)
  82. }
  83. func (d *testDriver) Run() {
  84. // no-op
  85. }
  86. func (d *testDriver) StartAnimation(a *fyne.Animation) {
  87. // currently no animations in test app, we just initialise it and leave
  88. a.Tick(1.0)
  89. }
  90. func (d *testDriver) StopAnimation(a *fyne.Animation) {
  91. // currently no animations in test app, do nothing
  92. }
  93. func (d *testDriver) Quit() {
  94. // no-op
  95. }
  96. func (d *testDriver) removeWindow(w *testWindow) {
  97. d.windowsMutex.Lock()
  98. i := 0
  99. for _, window := range d.windows {
  100. if window == w {
  101. break
  102. }
  103. i++
  104. }
  105. d.windows = append(d.windows[:i], d.windows[i+1:]...)
  106. d.windowsMutex.Unlock()
  107. }