User interface toolkit for Go with support for SDL2 and HTML Canvas render targets.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

80 lines
1.9 KiB

  1. package ui
  2. import (
  3. "git.kirsle.net/go/render"
  4. )
  5. // AbsolutePosition computes a widget's absolute X,Y position on the
  6. // window on screen by crawling its parent widget tree.
  7. func AbsolutePosition(w Widget) render.Point {
  8. abs := w.Point()
  9. var (
  10. node = w
  11. ok bool
  12. )
  13. for {
  14. node, ok = node.Parent()
  15. if !ok { // reached the top of the tree
  16. return abs
  17. }
  18. abs.Add(node.Point())
  19. }
  20. }
  21. // AbsoluteRect returns a Rect() offset with the absolute position.
  22. // X and Y are the AbsolutePosition of the widget.
  23. // W and H are the widget's width and height. (X,Y not added to them)
  24. func AbsoluteRect(w Widget) render.Rect {
  25. var (
  26. P = AbsolutePosition(w)
  27. R = w.Rect()
  28. )
  29. return render.Rect{
  30. X: P.X,
  31. Y: P.Y,
  32. W: R.W,
  33. H: R.H, // TODO: the Canvas in EditMode lets you draw pixels
  34. // below the status bar if we do `+ R.Y` here.
  35. }
  36. }
  37. // HasParent returns whether the target widget is a descendant of the parent.
  38. // This scans the parents of the widget recursively until it finds a match.
  39. func HasParent(w Widget, parent Widget) bool {
  40. next, ok := w.Parent()
  41. for ok {
  42. if next == parent {
  43. return true
  44. }
  45. next, ok = next.Parent()
  46. }
  47. return false
  48. }
  49. // widgetInFocusedWindow returns whether a widget (like a Button) is a
  50. // descendant of a Window that is being Window Managed by Supervisor, and
  51. // said window is in a Focused state.
  52. //
  53. // This is used by Supervisor to decide whether the widget should be given
  54. // events or not: a widget in a non-focused window ignores events, so that a
  55. // button in a "lower" window could not be clicked through a "higher" window
  56. // that overlaps it.
  57. func widgetInFocusedWindow(w Widget) (isManaged, isFocused bool) {
  58. var node = w
  59. for {
  60. // Is the node a Window?
  61. if window, ok := node.(*Window); ok {
  62. return window.managed, window.Focused()
  63. }
  64. node, _ = node.Parent()
  65. if node == nil {
  66. return false, true // reached the root
  67. }
  68. }
  69. }