github.com/grzegorz-zur/bm@v0.0.0-20240312214136-6fc133e3e2c0/area.go (about)

     1  package main
     2  
     3  // Area describes a rectangular area.
     4  type Area struct {
     5  	// Top.
     6  	Top int
     7  	// Bottom.
     8  	Bottom int
     9  	// Left.
    10  	Left int
    11  	// Right.
    12  	Right int
    13  }
    14  
    15  // Contains checks if position is inside area.
    16  func (area Area) Contains(position Position) bool {
    17  	return area.Top <= position.Line && position.Line < area.Bottom &&
    18  		area.Left <= position.Column && position.Column < area.Right
    19  }
    20  
    21  // Size calculates the number of lines and columns in the area.
    22  func (area Area) Size() Size {
    23  	return Size{
    24  		Lines:   area.Bottom - area.Top,
    25  		Columns: area.Right - area.Left,
    26  	}
    27  }
    28  
    29  // Resize resizes the area.
    30  func (area Area) Resize(size Size) Area {
    31  	return Area{
    32  		Top:    area.Top,
    33  		Bottom: area.Top + size.Lines,
    34  		Left:   area.Left,
    35  		Right:  area.Left + size.Columns,
    36  	}
    37  }
    38  
    39  // Shift shifts area to include position.
    40  func (area Area) Shift(position Position) Area {
    41  	if area.Contains(position) {
    42  		return area
    43  	}
    44  	size := area.Size()
    45  	switch {
    46  	case position.Line < area.Top:
    47  		area.Top = position.Line
    48  	case position.Line >= area.Bottom:
    49  		area.Top += position.Line - area.Bottom + 1
    50  	}
    51  	switch {
    52  	case position.Column < area.Left:
    53  		area.Left = position.Column
    54  	case position.Column >= area.Right:
    55  		area.Left += position.Column - area.Right + 1
    56  	}
    57  	return area.Resize(size)
    58  }