package objects import "image" import "git.tebibyte.media/tomo/tomo" import "git.tebibyte.media/tomo/tomo/event" // Container is an object that can contain other objects. It can be used as a // primitive for building more complex layouts. It has two variants: an outer // container, and an inner container. The outer container has padding around // its edges, whereas the inner container does not. The container will have a // corresponding object role variation of either "outer" or "inner". type Container struct { box tomo.ContainerBox } func newContainer (layout tomo.Layout, children ...tomo.Object) *Container { this := &Container { box: tomo.NewContainerBox(), } this.box.SetAttr(tomo.ALayout(layout)) for _, child := range children { this.Add(child) } return this } // NewOuterContainer creates a new container that has padding around it, as well // as a solid background color. It is meant to be used as a root container for a // window, tab pane, etc. func NewOuterContainer (layout tomo.Layout, children ...tomo.Object) *Container { this := newContainer(layout, children...) this.box.SetRole(tomo.R("objects", "Container")) this.box.SetTag("outer", true) return this } // NewSunkenContainer creates a new container with a sunken style and padding // around it. It is meant to be used as a root container for a ScrollContainer. func NewSunkenContainer (layout tomo.Layout, children ...tomo.Object) *Container { this := newContainer(layout, children...) this.box.SetRole(tomo.R("objects", "Container")) this.box.SetTag("sunken", true) return this } // NewInnerContainer creates a new container that has no padding around it. func NewInnerContainer (layout tomo.Layout, children ...tomo.Object) *Container { this := newContainer(layout, children...) this.box.SetRole(tomo.R("objects", "Container")) this.box.SetTag("inner", true) return this } // GetBox returns the underlying box. func (this *Container) GetBox () tomo.Box { return this.box } // ContentBounds returns the bounds of the inner content of the container // relative to the container's InnerBounds. func (this *Container) ContentBounds () image.Rectangle { return this.box.ContentBounds() } // ScrollTo shifts the origin of the container's content to the origin of the // container's InnerBounds, offset by the given point. func (this *Container) ScrollTo (position image.Point) { this.box.ScrollTo(position) } // OnContentBoundsChange specifies a function to be called when the container's // ContentBounds or InnerBounds changes. func (this *Container) OnContentBoundsChange (callback func ()) event.Cookie { return this.box.OnContentBoundsChange(callback) } // SetLayout sets the layout of the container. func (this *Container) SetLayout (layout tomo.Layout) { this.box.SetAttr(tomo.ALayout(layout)) } // SetAlign sets the X and Y alignment of the container. func (this *Container) SetAlign (x, y tomo.Align) { this.box.SetAttr(tomo.AAlign(x, y)) } // SetOverflow sets the X and Y overflow of the container. func (this *Container) SetOverflow (x, y bool) { this.box.SetAttr(tomo.AOverflow(x, y)) } // Add appends a child object. If the object is already a child of another // object, it will be removed from that object first. func (this *Container) Add (object tomo.Object) { this.box.Add(object) } // Remove removes a child object, if it is a child of this container. func (this *Container) Remove (object tomo.Object) { this.box.Remove(object) } // Insert inserts a child object before a specified object. If the before object // is nil or is not contained within this container, the inserted object is // appended. If the inserted object is already a child of another object, it // will be removed from that object first. func (this *Container) Insert (child tomo.Object, before tomo.Object) { this.box.Insert(child, before) } // Clear removes all child objects. func (this *Container) Clear () { this.box.Clear() } // Len returns hte amount of child objects. func (this *Container) Len () int { return this.box.Len() } // At returns the child object at the specified index. func (this *Container) At (index int) tomo.Object { return this.box.At(index) }