diff --git a/example/flex-box-horizonal/main.go b/example/flex-box-horizonal/main.go index 814cc01..99ec82c 100644 --- a/example/flex-box-horizonal/main.go +++ b/example/flex-box-horizonal/main.go @@ -4,7 +4,7 @@ import ( "fmt" "os" - "github.com/76creates/stickers/horizontal" + "github.com/76creates/stickers/flexbox" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" ) @@ -33,26 +33,26 @@ var ( ) type model struct { - flexBox *horizontal.HorizontalFlexBox + flexBox *flexbox.HorizontalFlexBox } func main() { m := model{ - flexBox: horizontal.NewHorizontalFlexBox(0, 0), + flexBox: flexbox.NewHorizontal(0, 0), } - columns := []*horizontal.FlexBoxColumn{ + columns := []*flexbox.Column{ m.flexBox.NewColumn().AddCells( - horizontal.NewFlexBoxCell(1, 1).SetStyle(style1), - horizontal.NewFlexBoxCell(1, 1).SetStyle(style2), + flexbox.NewCell(1, 1).SetStyle(style1), + flexbox.NewCell(1, 1).SetStyle(style2), ), m.flexBox.NewColumn().AddCells( - horizontal.NewFlexBoxCell(2, 1).SetStyle(style3), + flexbox.NewCell(2, 1).SetStyle(style3), ), m.flexBox.NewColumn().AddCells( - horizontal.NewFlexBoxCell(1, 1).SetStyle(style4), - horizontal.NewFlexBoxCell(1, 2).SetStyle(style5), - horizontal.NewFlexBoxCell(1, 1).SetStyle(style6), + flexbox.NewCell(1, 1).SetStyle(style4), + flexbox.NewCell(1, 2).SetStyle(style5), + flexbox.NewCell(1, 1).SetStyle(style6), ), } diff --git a/flexbox/cell.go b/flexbox/cell.go index ad3ef9b..65d9062 100644 --- a/flexbox/cell.go +++ b/flexbox/cell.go @@ -4,8 +4,9 @@ import ( "github.com/charmbracelet/lipgloss" ) -// FlexBoxCell is a building block object of the FlexBox, it represents a single cell within a box -// cells are stacked horizontally +// Cell is a building block object of the FlexBox, it represents a single cell within a box +// A FlexBox stacks cells horizonally. +// A HorizontalFlexBox stacks cells vertically. (controverse, isn't it?) type Cell struct { // style of the cell, when rendering it will inherit the style of the parent row style lipgloss.Style @@ -19,7 +20,8 @@ type Cell struct { ratioY int // minWidth minimal width of the cell minWidth int - // TODO: implement minimal height + // minHeigth minimal heigth of the cell + minHeigth int width int height int @@ -55,12 +57,20 @@ func (r *Cell) GetContent() string { return r.content } -// SetMinWidth sets the cells minimum width, this will not disable responsivness +// SetMinWidth sets the cells minimum width, this will not disable responsivness. +// This has only an effect to cells of a normal FlexBox, not a HorizontalFlexBox. func (r *Cell) SetMinWidth(value int) *Cell { r.minWidth = value return r } +// SetMinHeigth sets the cells minimum height, this will not disable responsivness. +// This has only an effect to cells of a HorizontalFlexBox. +func (r *Cell) SetMinHeigth(value int) *Cell { + r.minHeigth = value + return r +} + // SetStyle replaces the style, it unsets width/height related keys func (r *Cell) SetStyle(style lipgloss.Style) *Cell { r.style = style. diff --git a/horizontal/flexBoxColumn.go b/flexbox/column.go similarity index 69% rename from horizontal/flexBoxColumn.go rename to flexbox/column.go index 6ebdcf8..84ebd7f 100644 --- a/horizontal/flexBoxColumn.go +++ b/flexbox/column.go @@ -1,4 +1,4 @@ -package horizontal +package flexbox import ( "strconv" @@ -6,15 +6,15 @@ import ( "github.com/charmbracelet/lipgloss" ) -// FlexBoxColumn is the container for the cells, this object has the least to do with the ratio +// Column is the container for the cells, this object has the least to do with the ratio // of the construction as it takes all of the needed ratio information from the cell slice -// columns are stacked vertically -type FlexBoxColumn struct { +// columns are stacked horizontally. +type Column struct { // style of the column style lipgloss.Style styleAncestor bool - cells []*FlexBoxCell + cells []*Cell height int width int @@ -26,7 +26,7 @@ type FlexBoxColumn struct { // AddCells appends the cells to the column // if the cell ID is not set it will default to the index of the cell -func (r *FlexBoxColumn) AddCells(cells ...*FlexBoxCell) *FlexBoxColumn { +func (r *Column) AddCells(cells ...*Cell) *Column { r.cells = append(r.cells, cells...) for i, cell := range r.cells { if cell.id == "" { @@ -38,15 +38,15 @@ func (r *FlexBoxColumn) AddCells(cells ...*FlexBoxCell) *FlexBoxColumn { } // CellsLen returns the len of the cells slice -func (r *FlexBoxColumn) CellsLen() int { +func (r *Column) CellsLen() int { return len(r.cells) } -// GetCell returns the FlexBoxCell on the given index if it exists +// GetCell returns the Cell on the given index if it exists // note: forces the recalculation if found // // returns nil if not found -func (r *FlexBoxColumn) GetCell(index int) *FlexBoxCell { +func (r *Column) GetCell(index int) *Cell { if index >= 0 && index < len(r.cells) { r.setRecalculate() return r.cells[index] @@ -54,10 +54,10 @@ func (r *FlexBoxColumn) GetCell(index int) *FlexBoxCell { return nil } -// GetCellCopy returns a copy of the FlexBoxCell on the given index, if cell +// GetCellCopy returns a copy of the Cell on the given index, if cell // does not exist it will return nil. This is useful when you need to get // cells attribute without triggering a recalculation. -func (r *FlexBoxColumn) GetCellCopy(index int) *FlexBoxCell { +func (r *Column) GetCellCopy(index int) *Cell { if index >= 0 && index < len(r.cells) { c := r.cells[index].copy() return &c @@ -69,7 +69,7 @@ func (r *FlexBoxColumn) GetCellCopy(index int) *FlexBoxCell { // note: forces the recalculation if found // // returns nil if not found -func (r *FlexBoxColumn) GetCellWithID(id string) *FlexBoxCell { +func (r *Column) GetCellWithID(id string) *Cell { for _, c := range r.cells { if c.id == id { r.setRecalculate() @@ -81,7 +81,7 @@ func (r *FlexBoxColumn) GetCellWithID(id string) *FlexBoxCell { // UpdateCellWithIndex replaces the cell on the given index if it exists // if its not existing no changes will apply -func (r *FlexBoxColumn) UpdateCellWithIndex(index int, cell *FlexBoxCell) { +func (r *Column) UpdateCellWithIndex(index int, cell *Cell) { if index >= 0 && len(r.cells) > 0 && index < len(r.cells) { r.cells[index] = cell r.setRecalculate() @@ -89,7 +89,7 @@ func (r *FlexBoxColumn) UpdateCellWithIndex(index int, cell *FlexBoxCell) { } // SetStyle replaces the style, it unsets width/height related keys -func (r *FlexBoxColumn) SetStyle(style lipgloss.Style) *FlexBoxColumn { +func (r *Column) SetStyle(style lipgloss.Style) *Column { r.style = style. UnsetWidth(). UnsetMaxWidth(). @@ -100,22 +100,22 @@ func (r *FlexBoxColumn) SetStyle(style lipgloss.Style) *FlexBoxColumn { } // StylePassing set whether the style should be passed to the cells -func (r *FlexBoxColumn) StylePassing(value bool) *FlexBoxColumn { +func (r *Column) StylePassing(value bool) *Column { r.styleAncestor = value return r } -func (r *FlexBoxColumn) setHeight(value int) { +func (r *Column) setHeight(value int) { r.height = value r.setRecalculate() } -func (r *FlexBoxColumn) setWidth(value int) { +func (r *Column) setWidth(value int) { r.width = value r.setRecalculate() } -func (r *FlexBoxColumn) render(inherited ...lipgloss.Style) string { +func (r *Column) render(inherited ...lipgloss.Style) string { var inheritedStyle []lipgloss.Style for _, style := range inherited { @@ -135,20 +135,19 @@ func (r *FlexBoxColumn) render(inherited ...lipgloss.Style) string { return r.style. Width(r.getContentWidth()).MaxWidth(r.getMaxWidth()). Height(r.getContentHeight()).MaxHeight(r.getMaxHeight()). - //Render(lipgloss.JoinHorizontal(lipgloss.Top, renderedCells...)) Render(lipgloss.JoinVertical(lipgloss.Left, renderedCells...)) } -func (r *FlexBoxColumn) setRecalculate() { +func (r *Column) setRecalculate() { r.recalculateFlag = true } -func (r *FlexBoxColumn) unsetRecalculate() { +func (r *Column) unsetRecalculate() { r.recalculateFlag = false } // recalculate fetches the cell's height/width distribution slices and sets it on the cells -func (r *FlexBoxColumn) recalculate() { +func (r *Column) recalculate() { if r.recalculateFlag { if len(r.cells) > 0 { r.distributeCellDimensions(r.calculateCellsDimensions()) @@ -158,7 +157,7 @@ func (r *FlexBoxColumn) recalculate() { } // distributeCellDimensions sets width of each column per distribution array -func (r *FlexBoxColumn) distributeCellDimensions(xMatrix, yMatrix []int) { +func (r *Column) distributeCellDimensions(xMatrix, yMatrix []int) { for index, y := range yMatrix { r.cells[index].width = xMatrix[index] r.cells[index].height = y @@ -166,16 +165,16 @@ func (r *FlexBoxColumn) distributeCellDimensions(xMatrix, yMatrix []int) { } // calculateCellsDimensions calculates the height and width of the each cell -func (r *FlexBoxColumn) calculateCellsDimensions() (xMatrix, yMatrix []int) { +func (r *Column) calculateCellsDimensions() (xMatrix, yMatrix []int) { // calculate the cell height, it uses fixed combined ratio since the height of each cell - // is individual and does not stack, column height will be calculated using the ratio of the - // highest cell in the slice + // is individual and does not stack, column width will be calculated using the ratio of the + // widest cell in the slice cellXMatrix, cellXMatrixMax := r.getCellWidthMatrix() // reminder not needed here due to how combined ratio is passed xMatrix, _ = distributeToMatrix(r.getContentWidth(), cellXMatrixMax, cellXMatrix) - // get the min width matrix of the cells if any + // get the min heigth matrix of the cells if any withMinHeigth := false var minHeigthMatrix []int for _, c := range r.cells { @@ -185,7 +184,7 @@ func (r *FlexBoxColumn) calculateCellsDimensions() (xMatrix, yMatrix []int) { } } - // calculate the cell width matrix + // calculate the cell heigth matrix if withMinHeigth { yMatrix = calculateRatioWithMinimum(r.getContentHeight(), r.getCellHeightMatrix(), minHeigthMatrix) } else { @@ -196,7 +195,7 @@ func (r *FlexBoxColumn) calculateCellsDimensions() (xMatrix, yMatrix []int) { } // getCellHeightMatrix return the matrix of the cell height in cells -func (r *FlexBoxColumn) getCellHeightMatrix() (cellHeightMatrix []int) { +func (r *Column) getCellHeightMatrix() (cellHeightMatrix []int) { for _, cell := range r.cells { cellHeightMatrix = append(cellHeightMatrix, cell.ratioY) } @@ -204,7 +203,7 @@ func (r *FlexBoxColumn) getCellHeightMatrix() (cellHeightMatrix []int) { } // getCellWidthMatrix return the matrix of the cell width in cells and the max value in it -func (r *FlexBoxColumn) getCellWidthMatrix() (cellWidthMatrix []int, max int) { +func (r *Column) getCellWidthMatrix() (cellWidthMatrix []int, max int) { max = 0 for _, cell := range r.cells { if cell.ratioX > max { @@ -215,32 +214,32 @@ func (r *FlexBoxColumn) getCellWidthMatrix() (cellWidthMatrix []int, max int) { return cellWidthMatrix, max } -func (r *FlexBoxColumn) getContentWidth() int { +func (r *Column) getContentWidth() int { return r.getMaxWidth() - r.getExtraWidth() } -func (r *FlexBoxColumn) getContentHeight() int { +func (r *Column) getContentHeight() int { return r.getMaxHeight() - r.getExtraHeight() } -func (r *FlexBoxColumn) getMaxWidth() int { +func (r *Column) getMaxWidth() int { return r.width } -func (r *FlexBoxColumn) getMaxHeight() int { +func (r *Column) getMaxHeight() int { return r.height } -func (r *FlexBoxColumn) getExtraWidth() int { +func (r *Column) getExtraWidth() int { return r.style.GetHorizontalMargins() + r.style.GetHorizontalBorderSize() } -func (r *FlexBoxColumn) getExtraHeight() int { +func (r *Column) getExtraHeight() int { return r.style.GetVerticalMargins() + r.style.GetVerticalBorderSize() } -func (r *FlexBoxColumn) copy() FlexBoxColumn { - var cells []*FlexBoxCell +func (r *Column) copy() Column { + var cells []*Cell for _, cell := range r.cells { cellCopy := cell.copy() cells = append(cells, &cellCopy) diff --git a/horizontal/flexBox.go b/flexbox/horizontal_flexbox.go similarity index 69% rename from horizontal/flexBox.go rename to flexbox/horizontal_flexbox.go index b469c2d..d06e01c 100644 --- a/horizontal/flexBox.go +++ b/flexbox/horizontal_flexbox.go @@ -1,9 +1,9 @@ -package horizontal +package flexbox import "github.com/charmbracelet/lipgloss" -// FlexBox responsive box grid insipred by CSS flexbox -type FlexBox struct { +// HorizontalFlexBox responsive box grid insipred by CSS flexbox +type HorizontalFlexBox struct { // style to apply to the gridbox itself style lipgloss.Style styleAncestor bool @@ -13,19 +13,19 @@ type FlexBox struct { // height is fixed height of the box height int - // fixedColumnWidth will lock column height to a number, this disabless responsivness + // fixedColumnWidth will lock column width to a number, this disabless responsivness fixedColumnWidth int - columns []*FlexBoxColumn + columns []*Column // recalculateFlag indicates if next render should make calculations regarding // the columns objects height recalculateFlag bool } -// NewFlexBox initialize FlexBox object with defaults -func NewFlexBox(width, height int) *FlexBox { - r := &FlexBox{ +// NewHorizontal initialize a HorizontalFlexBox object with defaults +func NewHorizontal(width, height int) *HorizontalFlexBox { + r := &HorizontalFlexBox{ width: width, height: height, fixedColumnWidth: -1, @@ -36,7 +36,7 @@ func NewFlexBox(width, height int) *FlexBox { } // SetStyle replaces the style, it unsets width/height related keys -func (r *FlexBox) SetStyle(style lipgloss.Style) *FlexBox { +func (r *HorizontalFlexBox) SetStyle(style lipgloss.Style) *HorizontalFlexBox { r.style = style. UnsetWidth(). UnsetMaxWidth(). @@ -46,15 +46,15 @@ func (r *FlexBox) SetStyle(style lipgloss.Style) *FlexBox { } // StylePassing set whether the style should be passed to the columns -func (r *FlexBox) StylePassing(value bool) *FlexBox { +func (r *HorizontalFlexBox) StylePassing(value bool) *HorizontalFlexBox { r.styleAncestor = value return r } // NewColumn initialize a new FlexBoxColumn with width inherited from the FlexBox -func (r *FlexBox) NewColumn() *FlexBoxColumn { - rw := &FlexBoxColumn{ - cells: []*FlexBoxCell{}, +func (r *HorizontalFlexBox) NewColumn() *Column { + rw := &Column{ + cells: []*Cell{}, width: r.width, style: lipgloss.NewStyle(), } @@ -62,21 +62,21 @@ func (r *FlexBox) NewColumn() *FlexBoxColumn { } // AddColumns appends additional columns to the FlexBox -func (r *FlexBox) AddColumns(columns []*FlexBoxColumn) *FlexBox { +func (r *HorizontalFlexBox) AddColumns(columns []*Column) *HorizontalFlexBox { r.columns = append(r.columns, columns...) r.setRecalculate() return r } // SetColumns replace columns on the FlexBox -func (r *FlexBox) SetColumns(columns []*FlexBoxColumn) *FlexBox { +func (r *HorizontalFlexBox) SetColumns(columns []*Column) *HorizontalFlexBox { r.columns = columns r.setRecalculate() return r } // ColumnsLen returns the len of the columns slice -func (r *FlexBox) ColumnsLen() int { +func (r *HorizontalFlexBox) ColumnsLen() int { return len(r.columns) } @@ -84,7 +84,7 @@ func (r *FlexBox) ColumnsLen() int { // note: forces the recalculation if found // // returns nil if not found -func (r *FlexBox) GetColumn(index int) *FlexBoxColumn { +func (r *HorizontalFlexBox) GetColumn(index int) *Column { if index >= 0 && index < len(r.columns) { r.setRecalculate() return r.columns[index] @@ -96,7 +96,7 @@ func (r *FlexBox) GetColumn(index int) *FlexBoxColumn { // does not exist it will return nil. Copied column also gets copies of the // cells. This is useful when you need to get columns attribute without // triggering a recalculation. -func (r *FlexBox) GetColumnCopy(index int) *FlexBoxColumn { +func (r *HorizontalFlexBox) GetColumnCopy(index int) *Column { if index >= 0 && index < len(r.columns) { columnCopy := r.columns[index].copy() return &columnCopy @@ -108,7 +108,7 @@ func (r *FlexBox) GetColumnCopy(index int) *FlexBoxColumn { // within the given column with index y, if column or cell do not exist it will // return nil. This is useful when you need to get columns attribute without // triggering a recalculation. -func (r *FlexBox) GetColumnCellCopy(columnIndex, cellIndex int) *FlexBoxCell { +func (r *HorizontalFlexBox) GetColumnCellCopy(columnIndex, cellIndex int) *Cell { if columnIndex >= 0 && columnIndex < len(r.columns) { if cellIndex >= 0 && cellIndex < len(r.columns[columnIndex].cells) { cellCopy := r.columns[columnIndex].cells[cellIndex].copy() @@ -119,21 +119,21 @@ func (r *FlexBox) GetColumnCellCopy(columnIndex, cellIndex int) *FlexBoxCell { } // UpdateColumn replaces the FlexBoxColumn on the given index -func (r *FlexBox) UpdateColumn(index int, column *FlexBoxColumn) *FlexBox { +func (r *HorizontalFlexBox) UpdateColumn(index int, column *Column) *HorizontalFlexBox { r.columns[index] = column r.setRecalculate() return r } -// LockColumnHeight sets the fixed height value for all the columns +// LockColumnWidth sets the fixed width value for all the columns // this will disable horizontal scaling -func (r *FlexBox) LockColumnHeight(value int) *FlexBox { +func (r *HorizontalFlexBox) LockColumnWidth(value int) *HorizontalFlexBox { r.fixedColumnWidth = value return r } // SetHeight sets the FlexBox height -func (r *FlexBox) SetHeight(value int) *FlexBox { +func (r *HorizontalFlexBox) SetHeight(value int) *HorizontalFlexBox { r.height = value for _, column := range r.columns { column.setHeight(value) @@ -142,25 +142,25 @@ func (r *FlexBox) SetHeight(value int) *FlexBox { } // SetWidth sets the FlexBox width -func (r *FlexBox) SetWidth(value int) *FlexBox { +func (r *HorizontalFlexBox) SetWidth(value int) *HorizontalFlexBox { r.width = value r.setRecalculate() return r } // GetHeight yields current FlexBox height -func (r *FlexBox) GetHeight() int { +func (r *HorizontalFlexBox) GetHeight() int { return r.getMaxHeight() } // GetWidth yields current FlexBox width -func (r *FlexBox) GetWidth() int { +func (r *HorizontalFlexBox) GetWidth() int { return r.getMaxWidth() } -// Render initiates the recalculation of the columns dimensions(height) if the recalculate flag is on, -// and then it renders all the columns and combines them on the vertical axis -func (r *FlexBox) Render() string { +// Render initiates the recalculation of the columns dimensions(width) if the recalculate flag is on, +// and then it renders all the columns and combines them on the horizontal axis +func (r *HorizontalFlexBox) Render() string { var inheritedStyle []lipgloss.Style if r.styleAncestor { inheritedStyle = append(inheritedStyle, r.style) @@ -175,12 +175,11 @@ func (r *FlexBox) Render() string { return r.style. Width(r.getContentWidth()).MaxWidth(r.getMaxWidth()). Height(r.getContentHeight()).MaxHeight(r.getMaxHeight()). - //Render(lipgloss.JoinVertical(lipgloss.Left, renderedColumns...)) Render(lipgloss.JoinHorizontal(lipgloss.Top, renderedColumns...)) } // ForceRecalculate forces the recalculation for the box and all the columns -func (r *FlexBox) ForceRecalculate() { +func (r *HorizontalFlexBox) ForceRecalculate() { r.recalculate() for _, rw := range r.columns { rw.recalculate() @@ -188,7 +187,7 @@ func (r *FlexBox) ForceRecalculate() { } // recalculate fetches the column height distribution slice and sets it on the columns -func (r *FlexBox) recalculate() { +func (r *HorizontalFlexBox) recalculate() { if r.recalculateFlag { if len(r.columns) > 0 { r.distributeColumnsDimensions(r.calculateColumnWidth()) @@ -197,16 +196,16 @@ func (r *FlexBox) recalculate() { } } -func (r *FlexBox) setRecalculate() { +func (r *HorizontalFlexBox) setRecalculate() { r.recalculateFlag = true } -func (r *FlexBox) unsetRecalculate() { +func (r *HorizontalFlexBox) unsetRecalculate() { r.recalculateFlag = false } // calculateColumnWidth calculates the width of each column and returns the distribution array -func (r *FlexBox) calculateColumnWidth() (distribution []int) { +func (r *HorizontalFlexBox) calculateColumnWidth() (distribution []int) { if r.fixedColumnWidth > 0 { var fixedColumns []int for range r.columns { @@ -218,7 +217,7 @@ func (r *FlexBox) calculateColumnWidth() (distribution []int) { } // distributeColumnsDimensions sets height and width of each column per distribution array -func (r *FlexBox) distributeColumnsDimensions(ratioDistribution []int) { +func (r *HorizontalFlexBox) distributeColumnsDimensions(ratioDistribution []int) { for index, column := range r.columns { column.setHeight(r.getContentHeight()) column.setWidth(ratioDistribution[index]) @@ -226,7 +225,7 @@ func (r *FlexBox) distributeColumnsDimensions(ratioDistribution []int) { } // getColumnMatrix return the matrix of the cell widths for all the columns -func (r *FlexBox) getColumnMatrix() (columnMatrix [][]int) { +func (r *HorizontalFlexBox) getColumnMatrix() (columnMatrix [][]int) { for _, column := range r.columns { var cellValues []int for _, cell := range column.cells { @@ -237,26 +236,26 @@ func (r *FlexBox) getColumnMatrix() (columnMatrix [][]int) { return columnMatrix } -func (r *FlexBox) getContentWidth() int { +func (r *HorizontalFlexBox) getContentWidth() int { return r.getMaxWidth() - r.getExtraWidth() } -func (r *FlexBox) getContentHeight() int { +func (r *HorizontalFlexBox) getContentHeight() int { return r.getMaxHeight() - r.getExtraHeight() } -func (r *FlexBox) getMaxWidth() int { +func (r *HorizontalFlexBox) getMaxWidth() int { return r.width } -func (r *FlexBox) getMaxHeight() int { +func (r *HorizontalFlexBox) getMaxHeight() int { return r.height } -func (r *FlexBox) getExtraWidth() int { +func (r *HorizontalFlexBox) getExtraWidth() int { return r.style.GetHorizontalMargins() + r.style.GetHorizontalBorderSize() } -func (r *FlexBox) getExtraHeight() int { +func (r *HorizontalFlexBox) getExtraHeight() int { return r.style.GetVerticalMargins() + r.style.GetVerticalBorderSize() } diff --git a/horizontal/flexBoxCell.go b/horizontal/flexBoxCell.go deleted file mode 100644 index 1213b1b..0000000 --- a/horizontal/flexBoxCell.go +++ /dev/null @@ -1,128 +0,0 @@ -package horizontal - -import ( - "github.com/charmbracelet/lipgloss" -) - -// FlexBoxCell is a building block object of the FlexBox, it represents a single cell within a box -// cells are stacked horizontally -type FlexBoxCell struct { - // style of the cell, when rendering it will inherit the style of the parent column - style lipgloss.Style - // id of the cell, if not set it will default to the index in the column - id string - - // TODO: all ratios and sizes should be uint - // ratioX width ratio of the cell - ratioX int - // ratioY height ratio of the cell - ratioY int - // minHeigth minimal heigth of the cell - minHeigth int - - width int - height int - content string -} - -// NewFlexBoxCell initialize FlexBoxCell object with defaults -func NewFlexBoxCell(ratioX, ratioY int) *FlexBoxCell { - return &FlexBoxCell{ - style: lipgloss.NewStyle(), - ratioX: ratioX, - ratioY: ratioY, - minHeigth: 0, - width: 0, - height: 0, - } -} - -// SetID sets the cells ID -func (r *FlexBoxCell) SetID(id string) *FlexBoxCell { - r.id = id - return r -} - -// SetContent sets the cells content -func (r *FlexBoxCell) SetContent(content string) *FlexBoxCell { - r.content = content - return r -} - -// GetContent returns the cells raw content -func (r *FlexBoxCell) GetContent() string { - return r.content -} - -// SetMinWidth sets the cells minimum width, this will not disable responsivness -func (r *FlexBoxCell) SetMinHeigth(value int) *FlexBoxCell { - r.minHeigth = value - return r -} - -// SetStyle replaces the style, it unsets width/height related keys -func (r *FlexBoxCell) SetStyle(style lipgloss.Style) *FlexBoxCell { - r.style = style. - UnsetWidth(). - UnsetMaxWidth(). - UnsetHeight(). - UnsetMaxHeight() - return r -} - -// GetStyle returns the copy of the cells current style -func (r *FlexBoxCell) GetStyle() lipgloss.Style { - return r.style.Copy() -} - -// GetWidth returns real width of the cell -func (r *FlexBoxCell) GetWidth() int { - return r.getMaxWidth() -} - -// GetHeight returns real height of the cell -func (r *FlexBoxCell) GetHeight() int { - return r.getMaxHeight() -} - -// render the cell into string -func (r *FlexBoxCell) render(inherited ...lipgloss.Style) string { - for _, style := range inherited { - r.style = r.style.Inherit(style) - } - - s := r.GetStyle(). - Width(r.getContentWidth()).MaxWidth(r.getMaxWidth()). - Height(r.getContentHeight()).MaxHeight(r.getMaxHeight()) - return s.Render(r.content) -} - -func (r *FlexBoxCell) getContentWidth() int { - return r.getMaxWidth() - r.getExtraWidth() -} - -func (r *FlexBoxCell) getContentHeight() int { - return r.getMaxHeight() - r.getExtraHeight() -} - -func (r *FlexBoxCell) getMaxWidth() int { - return r.width -} - -func (r *FlexBoxCell) getMaxHeight() int { - return r.height -} - -func (r *FlexBoxCell) getExtraWidth() int { - return r.style.GetHorizontalMargins() + r.style.GetHorizontalBorderSize() -} - -func (r *FlexBoxCell) getExtraHeight() int { - return r.style.GetVerticalMargins() + r.style.GetVerticalBorderSize() -} - -func (r *FlexBoxCell) copy() FlexBoxCell { - cellCopy := *r - cellCopy.style = r.GetStyle() - return cellCopy -} diff --git a/horizontal/flexBoxUtil.go b/horizontal/flexBoxUtil.go deleted file mode 100644 index 313c921..0000000 --- a/horizontal/flexBoxUtil.go +++ /dev/null @@ -1,123 +0,0 @@ -package horizontal - -import ( - "math" -) - -// TODO: explain this mess using some comments - -func calculateRatioWithMinimum(distribute int, matrix []int, minimumMatrix []int) (ratioDistribution []int) { - for range matrix { - ratioDistribution = append(ratioDistribution, 0) - } - - dist := calculateRatio(distribute, matrix) - for i, d := range dist { - if minimumMatrix[i] > d { - ratioDistribution[i] = minimumMatrix[i] - - distribute -= minimumMatrix[i] - matrix[i] = 0 - minimumMatrix[i] = 0 - _dist := calculateRatioWithMinimum(distribute, matrix, minimumMatrix) - for ii, _d := range _dist { - if ii != i { - ratioDistribution[ii] = _d - } - } - break - } else { - ratioDistribution[i] = d - } - } - // TODO: calculate reminder and if negative shrink right most column - - return ratioDistribution -} - -func calculateRatio(distribute int, matrix []int) (ratioDistribution []int) { - if distribute == 0 { - for range matrix { - ratioDistribution = append(ratioDistribution, 0) - } - return ratioDistribution - } - - var combinedRatios int - for _, value := range matrix { - combinedRatios += value - } - - if combinedRatios > 0 { - var reminder int - ratioDistribution, reminder = distributeToMatrix(distribute, combinedRatios, matrix) - if reminder > 0 { - for index, reminderAdded := range distributeReminder(reminder, matrix) { - ratioDistribution[index] += reminderAdded - reminder -= reminderAdded - } - } - // TODO: rethink maybe, does this fn belong here - if reminder < 0 { - // happens when there is minimum value - } - } - - return ratioDistribution -} - -func distributeToMatrix(distribute int, combinedRatio int, matrix []int) (distribution []int, reminder int) { - reminder = distribute - for _, max := range matrix { - ratioDistributionValue := int(math.Floor((float64(max) / float64(combinedRatio)) * float64(distribute))) - distribution = append(distribution, ratioDistributionValue) - reminder -= ratioDistributionValue - - } - return distribution, reminder -} - -func calculateMatrixRatio(distribute int, matrix [][]int) (ratioDistribution []int) { - // get matrix max ratio for each int in matrix slice - var maxRatio []int - for matrixIndex, ratios := range matrix { - maxRatio = append(maxRatio, 0) - for _, ratio := range ratios { - if ratio > maxRatio[matrixIndex] { - maxRatio[matrixIndex] = ratio - } - } - } - - return calculateRatio(distribute, maxRatio) -} - -// distributeReminder is simple reminder distributor, it will distribute add 1 to next highest -// matrix value till it runs out of reminder to distribute, this might be improved for some more -// complex cases -func distributeReminder(reminder int, matrixMaxRatio []int) (reminderDistribution []int) { - for range matrixMaxRatio { - reminderDistribution = append(reminderDistribution, 0) - } - - distributed := 0 - for reminder > 0 { - maxIndex := 0 - maxRatio := 0 - for index, ratio := range matrixMaxRatio { - // skip if already expanded - if reminderDistribution[index] > 0 { - continue - } - if ratio > maxRatio { - maxRatio = ratio - maxIndex = index - } - } - reminderDistribution[maxIndex] += 1 - distributed += 1 - reminder -= 1 - } - - return reminderDistribution -}