From 64fa922ec013079f8f0c90fc9e93c56db3611d30 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 22 Apr 2018 21:25:06 +0300 Subject: Switch to dep --- vendor/maunium.net/go/tview/flex.go | 173 ++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 vendor/maunium.net/go/tview/flex.go (limited to 'vendor/maunium.net/go/tview/flex.go') diff --git a/vendor/maunium.net/go/tview/flex.go b/vendor/maunium.net/go/tview/flex.go new file mode 100644 index 0000000..a698442 --- /dev/null +++ b/vendor/maunium.net/go/tview/flex.go @@ -0,0 +1,173 @@ +package tview + +import ( + "maunium.net/go/tcell" +) + +// Configuration values. +const ( + FlexRow = iota + FlexColumn +) + +// flexItem holds layout options for one item. +type flexItem struct { + Item Primitive // The item to be positioned. May be nil for an empty item. + FixedSize int // The item's fixed size which may not be changed, 0 if it has no fixed size. + Proportion int // The item's proportion. + Focus bool // Whether or not this item attracts the layout's focus. +} + +// Flex is a basic implementation of the Flexbox layout. The contained +// primitives are arranged horizontally or vertically. The way they are +// distributed along that dimension depends on their layout settings, which is +// either a fixed length or a proportional length. See AddItem() for details. +// +// See https://github.com/rivo/tview/wiki/Flex for an example. +type Flex struct { + *Box + + // The items to be positioned. + items []flexItem + + // FlexRow or FlexColumn. + direction int + + // If set to true, will use the entire screen as its available space instead + // its box dimensions. + fullScreen bool +} + +// NewFlex returns a new flexbox layout container with no primitives and its +// direction set to FlexColumn. To add primitives to this layout, see AddItem(). +// To change the direction, see SetDirection(). +func NewFlex() *Flex { + f := &Flex{ + Box: NewBox(), + direction: FlexColumn, + } + f.focus = f + return f +} + +// SetDirection sets the direction in which the contained primitives are +// distributed. This can be either FlexColumn (default) or FlexRow. +func (f *Flex) SetDirection(direction int) *Flex { + f.direction = direction + return f +} + +// SetFullScreen sets the flag which, when true, causes the flex layout to use +// the entire screen space instead of whatever size it is currently assigned to. +func (f *Flex) SetFullScreen(fullScreen bool) *Flex { + f.fullScreen = fullScreen + return f +} + +// AddItem adds a new item to the container. The "fixedSize" argument is a width +// or height that may not be changed by the layout algorithm. A value of 0 means +// that its size is flexible and may be changed. The "proportion" argument +// defines the relative size of the item compared to other flexible-size items. +// For example, items with a proportion of 2 will be twice as large as items +// with a proportion of 1. Must be at least 1 if fixedSize > 0 (ignored +// otherwise) +// +// If "focus" is set to true, the item will receive focus when the Flex +// primitive receives focus. If multiple items have the "focus" flag set to +// true, the first one will receive focus. +// +// You can provide a nil value for the primitive. This will still consume screen +// space but nothing will be drawn. +func (f *Flex) AddItem(item Primitive, fixedSize, proportion int, focus bool) *Flex { + f.items = append(f.items, flexItem{Item: item, FixedSize: fixedSize, Proportion: proportion, Focus: focus}) + return f +} + +// RemoveItem removes all items for the given primitive from the container, +// keeping the order of the remaining items intact. +func (f *Flex) RemoveItem(p Primitive) *Flex { + for index := len(f.items) - 1; index >= 0; index-- { + if f.items[index].Item == p { + f.items = append(f.items[:index], f.items[index+1:]...) + } + } + return f +} + +// Draw draws this primitive onto the screen. +func (f *Flex) Draw(screen tcell.Screen) { + f.Box.Draw(screen) + + // Calculate size and position of the items. + + // Do we use the entire screen? + if f.fullScreen { + width, height := screen.Size() + f.SetRect(0, 0, width, height) + } + + // How much space can we distribute? + x, y, width, height := f.GetInnerRect() + var proportionSum int + distSize := width + if f.direction == FlexRow { + distSize = height + } + for _, item := range f.items { + if item.FixedSize > 0 { + distSize -= item.FixedSize + } else { + proportionSum += item.Proportion + } + } + + // Calculate positions and draw items. + pos := x + if f.direction == FlexRow { + pos = y + } + for _, item := range f.items { + size := item.FixedSize + if size <= 0 { + size = distSize * item.Proportion / proportionSum + distSize -= size + proportionSum -= item.Proportion + } + if item.Item != nil { + if f.direction == FlexColumn { + item.Item.SetRect(pos, y, size, height) + } else { + item.Item.SetRect(x, pos, width, size) + } + } + pos += size + + if item.Item != nil { + if item.Item.GetFocusable().HasFocus() { + defer item.Item.Draw(screen) + } else { + item.Item.Draw(screen) + } + } + } +} + +// Focus is called when this primitive receives focus. +func (f *Flex) Focus(delegate func(p Primitive)) { + for _, item := range f.items { + if item.Item != nil && item.Focus { + delegate(item.Item) + return + } + } +} + +// HasFocus returns whether or not this primitive has focus. +func (f *Flex) HasFocus() bool { + for _, item := range f.items { + if item.Item != nil && item.Item.GetFocusable().HasFocus() { + return true + } + } + return false +} -- cgit v1.2.3