testdriver.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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 := new(testDriver)
  27. drv.windowsMutex = sync.RWMutex{}
  28. repository.Register("file", intRepo.NewFileRepository())
  29. // make a single dummy window for rendering tests
  30. drv.CreateWindow("")
  31. return drv
  32. }
  33. // NewDriverWithPainter creates a new dummy driver that will pass the given
  34. // painter to all canvases created
  35. func NewDriverWithPainter(painter SoftwarePainter) fyne.Driver {
  36. drv := new(testDriver)
  37. drv.painter = painter
  38. drv.windowsMutex = sync.RWMutex{}
  39. return drv
  40. }
  41. func (d *testDriver) AbsolutePositionForObject(co fyne.CanvasObject) fyne.Position {
  42. c := d.CanvasForObject(co)
  43. if c == nil {
  44. return fyne.NewPos(0, 0)
  45. }
  46. tc := c.(*testCanvas)
  47. return driver.AbsolutePositionForObject(co, tc.objectTrees())
  48. }
  49. func (d *testDriver) AllWindows() []fyne.Window {
  50. d.windowsMutex.RLock()
  51. defer d.windowsMutex.RUnlock()
  52. return d.windows
  53. }
  54. func (d *testDriver) CanvasForObject(fyne.CanvasObject) fyne.Canvas {
  55. d.windowsMutex.RLock()
  56. defer d.windowsMutex.RUnlock()
  57. // cheating: probably the last created window is meant
  58. return d.windows[len(d.windows)-1].Canvas()
  59. }
  60. func (d *testDriver) CreateWindow(string) fyne.Window {
  61. canvas := NewCanvas().(*testCanvas)
  62. if d.painter != nil {
  63. canvas.painter = d.painter
  64. } else {
  65. canvas.painter = software.NewPainter()
  66. }
  67. window := &testWindow{canvas: canvas, driver: d}
  68. window.clipboard = &testClipboard{}
  69. d.windowsMutex.Lock()
  70. d.windows = append(d.windows, window)
  71. d.windowsMutex.Unlock()
  72. return window
  73. }
  74. func (d *testDriver) Device() fyne.Device {
  75. if d.device == nil {
  76. d.device = &device{}
  77. }
  78. return d.device
  79. }
  80. // RenderedTextSize looks up how bit a string would be if drawn on screen
  81. func (d *testDriver) RenderedTextSize(text string, size float32, style fyne.TextStyle) (fyne.Size, float32) {
  82. return painter.RenderedTextSize(text, size, style)
  83. }
  84. func (d *testDriver) Run() {
  85. // no-op
  86. }
  87. func (d *testDriver) StartAnimation(a *fyne.Animation) {
  88. // currently no animations in test app, we just initialise it and leave
  89. a.Tick(1.0)
  90. }
  91. func (d *testDriver) StopAnimation(a *fyne.Animation) {
  92. // currently no animations in test app, do nothing
  93. }
  94. func (d *testDriver) Quit() {
  95. // no-op
  96. }
  97. func (d *testDriver) removeWindow(w *testWindow) {
  98. d.windowsMutex.Lock()
  99. i := 0
  100. for _, window := range d.windows {
  101. if window == w {
  102. break
  103. }
  104. i++
  105. }
  106. d.windows = append(d.windows[:i], d.windows[i+1:]...)
  107. d.windowsMutex.Unlock()
  108. }