packlayout.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. // Copyright 2018 visualfc. All rights reserved.
  2. package tk
  3. import (
  4. "fmt"
  5. )
  6. type PackLayout struct {
  7. *LayoutFrame
  8. side Side
  9. pad *Pad
  10. items []*LayoutItem
  11. }
  12. func (w *PackLayout) SetSide(side Side) error {
  13. w.side = side
  14. return w.Repack()
  15. }
  16. func (w *PackLayout) SetPadding(pad Pad) error {
  17. return w.SetPaddingN(pad.X, pad.Y)
  18. }
  19. func (w *PackLayout) SetPaddingN(padx int, pady int) error {
  20. w.pad = &Pad{padx, pady}
  21. return w.Repack()
  22. }
  23. func (w *PackLayout) removeItem(widget Widget) error {
  24. n := w.indexOfWidget(widget)
  25. if n == -1 {
  26. return ErrInvalid
  27. }
  28. PackRemove(widget)
  29. w.items = append(w.items[:n], w.items[n+1:]...)
  30. return nil
  31. }
  32. func (w *PackLayout) indexOfWidget(widget Widget) int {
  33. for n, v := range w.items {
  34. if v.widget == widget {
  35. return n
  36. }
  37. }
  38. return -1
  39. }
  40. func (w *PackLayout) AddWidget(widget Widget, attributes ...*LayoutAttr) error {
  41. if !IsValidWidget(widget) {
  42. return ErrInvalid
  43. }
  44. n := w.indexOfWidget(widget)
  45. if n != -1 {
  46. w.items = append(w.items[:n], w.items[n+1:]...)
  47. }
  48. w.items = append(w.items, &LayoutItem{widget, attributes})
  49. return w.Repack()
  50. }
  51. func (w *PackLayout) InsertWidget(index int, widget Widget, attributes ...*LayoutAttr) error {
  52. if index < 0 {
  53. return w.AddWidget(widget, attributes...)
  54. }
  55. n := w.indexOfWidget(widget)
  56. if n != -1 {
  57. if n == index {
  58. return ErrExist
  59. }
  60. w.items = append(w.items[:n], w.items[n+1:]...)
  61. }
  62. if index >= len(w.items) {
  63. return w.AddWidget(widget, attributes...)
  64. }
  65. w.items = append(w.items[:index], append([]*LayoutItem{&LayoutItem{widget, attributes}}, w.items[index:]...)...)
  66. return w.Repack()
  67. }
  68. func (w *PackLayout) AddWidgetEx(widget Widget, fill Fill, expand bool, anchor Anchor) error {
  69. return w.AddWidget(widget,
  70. PackAttrFill(fill), PackAttrExpand(expand),
  71. PackAttrAnchor(anchor))
  72. }
  73. func (w *PackLayout) InsertWidgetEx(index int, widget Widget, fill Fill, expand bool, anchor Anchor) error {
  74. return w.InsertWidget(index, widget,
  75. PackAttrFill(fill), PackAttrExpand(expand),
  76. PackAttrAnchor(anchor))
  77. }
  78. func (w *PackLayout) AddWidgets(widgets ...Widget) error {
  79. for _, widget := range widgets {
  80. n := w.indexOfWidget(widget)
  81. if n != -1 {
  82. w.items = append(w.items[:n], w.items[n+1:]...)
  83. }
  84. w.items = append(w.items, &LayoutItem{widget, nil})
  85. }
  86. return w.Repack()
  87. }
  88. func (w *PackLayout) AddWidgetList(widgets []Widget, attributes ...*LayoutAttr) error {
  89. for _, widget := range widgets {
  90. n := w.indexOfWidget(widget)
  91. if n != -1 {
  92. w.items = append(w.items[:n], w.items[n+1:]...)
  93. }
  94. w.items = append(w.items, &LayoutItem{widget, attributes})
  95. }
  96. return w.Repack()
  97. }
  98. func (w *PackLayout) RemoveWidget(widget Widget) error {
  99. if !IsValidWidget(widget) {
  100. return ErrInvalid
  101. }
  102. return w.removeItem(widget)
  103. }
  104. func (w *PackLayout) SetWidgetAttr(widget Widget, attributes ...*LayoutAttr) error {
  105. if !IsValidWidget(widget) {
  106. return ErrInvalid
  107. }
  108. n := w.indexOfWidget(widget)
  109. if n == -1 {
  110. return ErrInvalid
  111. }
  112. w.items[n].attrs = attributes
  113. return w.Repack()
  114. }
  115. func (w *PackLayout) itemAttr() []*LayoutAttr {
  116. itemsAttr := []*LayoutAttr{PackAttrSide(w.side), PackAttrInMaster(w)}
  117. if w.pad != nil {
  118. itemsAttr = append(itemsAttr, PackAttrPadx(w.pad.X), PackAttrPady(w.pad.Y))
  119. }
  120. return itemsAttr
  121. }
  122. func (w *PackLayout) resetSpacerAttr(item *LayoutItem, s *LayoutSpacer) {
  123. if s.IsExpand() {
  124. s.SetWidth(0)
  125. s.SetHeight(0)
  126. if w.side == SideTop || w.side == SideBottom {
  127. item.attrs = AppendLayoutAttrs(item.attrs, PackAttrFillY(), PackAttrExpand(true))
  128. } else {
  129. item.attrs = AppendLayoutAttrs(item.attrs, PackAttrFillX(), PackAttrExpand(true))
  130. }
  131. } else {
  132. item.attrs = AppendLayoutAttrs(item.attrs, PackAttrFillNone(), PackAttrExpand(false))
  133. if w.side == SideTop || w.side == SideBottom {
  134. s.SetHeight(s.space)
  135. s.SetWidth(0)
  136. } else {
  137. s.SetWidth(s.space)
  138. s.SetHeight(0)
  139. }
  140. }
  141. }
  142. func (w *PackLayout) Repack() error {
  143. for _, item := range w.items {
  144. if item.widget == nil {
  145. continue
  146. }
  147. if s, ok := item.widget.(*LayoutSpacer); ok {
  148. w.resetSpacerAttr(item, s)
  149. }
  150. Pack(item.widget, AppendLayoutAttrs(item.attrs, w.itemAttr()...)...)
  151. }
  152. return Pack(w, PackAttrFill(FillBoth), PackAttrExpand(true))
  153. }
  154. func (w *PackLayout) SetBorderWidth(width int) error {
  155. return eval(fmt.Sprintf("%v configure -borderwidth {%v}", w.Id(), width))
  156. }
  157. func (w *PackLayout) BorderWidth() int {
  158. r, _ := evalAsInt(fmt.Sprintf("%v cget -borderwidth", w.Id()))
  159. return r
  160. }
  161. func NewPackLayout(parent Widget, side Side) *PackLayout {
  162. pack := &PackLayout{NewLayoutFrame(parent), side, nil, nil}
  163. pack.Lower(nil)
  164. pack.Repack()
  165. return pack
  166. }
  167. func NewHPackLayout(parent Widget) *PackLayout {
  168. return NewPackLayout(parent, SideLeft)
  169. }
  170. func NewVPackLayout(parent Widget) *PackLayout {
  171. return NewPackLayout(parent, SideTop)
  172. }