forked from tslocum/cview
Reduce Box inner rect calculations
This commit is contained in:
parent
62c7289449
commit
30838d75cd
|
@ -17,6 +17,7 @@ v1.5.1 (WIP)
|
|||
- Generalize tag stripping as StripTags
|
||||
- Make printWithStyle public and rename as PrintStyle
|
||||
- Optimize TextView (writing is 90% faster, drawing is 50% faster)
|
||||
- Reduce Box inner rect calculations
|
||||
- Remove return values from methods which return their primitive (breaks chaining)
|
||||
- Remove Application.ForceDraw (Application.Draw may be called anywhere)
|
||||
- Rename SetBorderPadding and GetBorderPadding as SetPadding and GetPadding
|
||||
|
|
116
box.go
116
box.go
|
@ -13,15 +13,15 @@ type Box struct {
|
|||
// The position of the rect.
|
||||
x, y, width, height int
|
||||
|
||||
// Padding.
|
||||
paddingTop, paddingBottom, paddingLeft, paddingRight int
|
||||
|
||||
// The inner rect reserved for the box's content.
|
||||
innerX, innerY, innerWidth, innerHeight int
|
||||
|
||||
// Whether or not the box is visible.
|
||||
visible bool
|
||||
|
||||
// Padding.
|
||||
paddingTop, paddingBottom, paddingLeft, paddingRight int
|
||||
|
||||
// The border color when the box has focus.
|
||||
borderColorFocused tcell.Color
|
||||
|
||||
|
@ -81,7 +81,6 @@ func NewBox() *Box {
|
|||
b := &Box{
|
||||
width: 15,
|
||||
height: 10,
|
||||
innerX: -1, // Mark as uninitialized.
|
||||
visible: true,
|
||||
backgroundColor: Styles.PrimitiveBackgroundColor,
|
||||
borderColor: Styles.BorderColor,
|
||||
|
@ -91,13 +90,43 @@ func NewBox() *Box {
|
|||
showFocus: true,
|
||||
}
|
||||
b.focus = b
|
||||
b.updateInnerRect()
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *Box) updateInnerRect() {
|
||||
x, y, width, height := b.x, b.y, b.width, b.height
|
||||
|
||||
// Subtract border space
|
||||
if b.border {
|
||||
x++
|
||||
y++
|
||||
width -= 2
|
||||
height -= 2
|
||||
}
|
||||
|
||||
// Subtract padding
|
||||
x, y, width, height =
|
||||
x+b.paddingLeft,
|
||||
y+b.paddingTop,
|
||||
width-b.paddingLeft-b.paddingRight,
|
||||
height-b.paddingTop-b.paddingBottom
|
||||
|
||||
if width < 0 {
|
||||
width = 0
|
||||
}
|
||||
if height < 0 {
|
||||
height = 0
|
||||
}
|
||||
|
||||
b.innerX, b.innerY, b.innerWidth, b.innerHeight = x, y, width, height
|
||||
}
|
||||
|
||||
// GetPadding returns the size of the padding around the box content.
|
||||
func (b *Box) GetPadding() (top, bottom, left, right int) {
|
||||
b.l.RLock()
|
||||
defer b.l.RUnlock()
|
||||
|
||||
return b.paddingTop, b.paddingBottom, b.paddingLeft, b.paddingRight
|
||||
}
|
||||
|
||||
|
@ -107,6 +136,8 @@ func (b *Box) SetPadding(top, bottom, left, right int) {
|
|||
defer b.l.Unlock()
|
||||
|
||||
b.paddingTop, b.paddingBottom, b.paddingLeft, b.paddingRight = top, bottom, left, right
|
||||
|
||||
b.updateInnerRect()
|
||||
}
|
||||
|
||||
// GetRect returns the current position of the rectangle, x, y, width, and
|
||||
|
@ -123,32 +154,9 @@ func (b *Box) GetRect() (int, int, int, int) {
|
|||
// will clamp to 0 and thus never be negative.
|
||||
func (b *Box) GetInnerRect() (int, int, int, int) {
|
||||
b.l.RLock()
|
||||
if b.innerX >= 0 {
|
||||
defer b.l.RUnlock()
|
||||
return b.innerX, b.innerY, b.innerWidth, b.innerHeight
|
||||
}
|
||||
b.l.RUnlock()
|
||||
defer b.l.RUnlock()
|
||||
|
||||
x, y, width, height := b.GetRect()
|
||||
b.l.RLock()
|
||||
if b.border {
|
||||
x++
|
||||
y++
|
||||
width -= 2
|
||||
height -= 2
|
||||
}
|
||||
x, y, width, height = x+b.paddingLeft,
|
||||
y+b.paddingTop,
|
||||
width-b.paddingLeft-b.paddingRight,
|
||||
height-b.paddingTop-b.paddingBottom
|
||||
if width < 0 {
|
||||
width = 0
|
||||
}
|
||||
if height < 0 {
|
||||
height = 0
|
||||
}
|
||||
b.l.RUnlock()
|
||||
return x, y, width, height
|
||||
return b.innerX, b.innerY, b.innerWidth, b.innerHeight
|
||||
}
|
||||
|
||||
// SetRect sets a new position of the primitive. Note that this has no effect
|
||||
|
@ -160,11 +168,9 @@ func (b *Box) SetRect(x, y, width, height int) {
|
|||
b.l.Lock()
|
||||
defer b.l.Unlock()
|
||||
|
||||
b.x = x
|
||||
b.y = y
|
||||
b.width = width
|
||||
b.height = height
|
||||
b.innerX = -1 // Mark inner rect as uninitialized.
|
||||
b.x, b.y, b.width, b.height = x, y, width, height
|
||||
|
||||
b.updateInnerRect()
|
||||
}
|
||||
|
||||
// SetVisible sets the flag indicating whether or not the box is visible.
|
||||
|
@ -353,6 +359,8 @@ func (b *Box) SetBorder(show bool) {
|
|||
defer b.l.Unlock()
|
||||
|
||||
b.border = show
|
||||
|
||||
b.updateInnerRect()
|
||||
}
|
||||
|
||||
// SetBorderColor sets the box's border color.
|
||||
|
@ -417,16 +425,15 @@ func (b *Box) SetTitleAlign(align int) {
|
|||
// Draw draws this primitive onto the screen.
|
||||
func (b *Box) Draw(screen tcell.Screen) {
|
||||
b.l.Lock()
|
||||
defer b.l.Unlock()
|
||||
|
||||
// Don't draw anything if the box is hidden
|
||||
if !b.visible {
|
||||
b.l.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
// Don't draw anything if there is no space.
|
||||
if b.width <= 0 || b.height <= 0 {
|
||||
b.l.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -499,43 +506,8 @@ func (b *Box) Draw(screen tcell.Screen) {
|
|||
|
||||
// Call custom draw function.
|
||||
if b.draw != nil {
|
||||
b.l.Unlock()
|
||||
newX, newY, newWidth, newHeight := b.draw(screen, b.x, b.y, b.width, b.height)
|
||||
b.l.Lock()
|
||||
b.innerX, b.innerY, b.innerWidth, b.innerHeight = newX, newY, newWidth, newHeight
|
||||
} else {
|
||||
// Remember the inner rect.
|
||||
b.innerX = -1
|
||||
b.l.Unlock()
|
||||
newX, newY, newWidth, newHeight := b.GetInnerRect()
|
||||
b.l.Lock()
|
||||
b.innerX, b.innerY, b.innerWidth, b.innerHeight = newX, newY, newWidth, newHeight
|
||||
b.innerX, b.innerY, b.innerWidth, b.innerHeight = b.draw(screen, b.x, b.y, b.width, b.height)
|
||||
}
|
||||
|
||||
// Clamp inner rect to screen.
|
||||
width, height := screen.Size()
|
||||
if b.innerX < 0 {
|
||||
b.innerWidth += b.innerX
|
||||
b.innerX = 0
|
||||
}
|
||||
if b.innerX+b.innerWidth >= width {
|
||||
b.innerWidth = width - b.innerX
|
||||
}
|
||||
if b.innerY+b.innerHeight >= height {
|
||||
b.innerHeight = height - b.innerY
|
||||
}
|
||||
if b.innerY < 0 {
|
||||
b.innerHeight += b.innerY
|
||||
b.innerY = 0
|
||||
}
|
||||
if b.innerWidth < 0 {
|
||||
b.innerWidth = 0
|
||||
}
|
||||
if b.innerHeight < 0 {
|
||||
b.innerHeight = 0
|
||||
}
|
||||
|
||||
b.l.Unlock()
|
||||
}
|
||||
|
||||
// ShowFocus sets the flag indicating whether or not the borders of this
|
||||
|
|
|
@ -141,6 +141,7 @@ func (wm *WindowManager) MouseHandler() func(action MouseAction, event *tcell.Ev
|
|||
w.x -= offsetX + w.dragWX
|
||||
w.y -= offsetY + w.dragWY
|
||||
|
||||
w.updateInnerRect()
|
||||
consumed = true
|
||||
}
|
||||
|
||||
|
@ -160,6 +161,7 @@ func (wm *WindowManager) MouseHandler() func(action MouseAction, event *tcell.Ev
|
|||
}
|
||||
}
|
||||
|
||||
w.updateInnerRect()
|
||||
consumed = true
|
||||
}
|
||||
|
||||
|
@ -179,6 +181,7 @@ func (wm *WindowManager) MouseHandler() func(action MouseAction, event *tcell.Ev
|
|||
}
|
||||
}
|
||||
|
||||
w.updateInnerRect()
|
||||
consumed = true
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue