diff --git a/spring-shell-core/src/main/java/org/springframework/shell/component/view/control/GridView.java b/spring-shell-core/src/main/java/org/springframework/shell/component/view/control/GridView.java index 09d528d2..d61c49e7 100644 --- a/spring-shell-core/src/main/java/org/springframework/shell/component/view/control/GridView.java +++ b/spring-shell-core/src/main/java/org/springframework/shell/component/view/control/GridView.java @@ -29,6 +29,7 @@ import org.springframework.shell.component.view.event.MouseHandler; import org.springframework.shell.component.view.event.MouseHandler.MouseHandlerResult; import org.springframework.shell.component.view.geom.Rectangle; import org.springframework.shell.component.view.screen.Screen; +import org.springframework.util.Assert; /** * {@code GridView} is a layout container with no initial {@link View views}. @@ -54,38 +55,41 @@ public class GridView extends BoxView { private boolean showBorders; /** - * Defines how the columns of the grid are distributed. Each value - * defines the size of one column, starting with the leftmost column. Values - * greater 0 represent absolute column widths (gaps not included). Values less - * or equal 0 represent proportional column widths or fractions of the remaining - * free space, where 0 is treated the same as -1. That is, a column with a value + * Defines how the columns of the grid are distributed. Each value defines the + * size of one column, starting with the leftmost column. Values greater 0 + * represent absolute column widths (gaps not included). Values less or equal 0 + * represent proportional column widths or fractions of the remaining free + * space, where 0 is treated the same as -1. That is, a column with a value * of -3 will have three times the width of a column with a value of -1 (or 0). - * The minimum width set with SetMinSize() is always observed. + * The minimum width set with {@link #setMinSize(int, int)} is always observed. * - * Views may extend beyond the columns defined explicitly with this - * function. A value of 0 is assumed for any undefined column. In fact, if you - * never call this function, all columns occupied by Views will have the - * same width. On the other hand, unoccupied columns defined with this function - * will always take their place. + *

Views may extend beyond the columns defined explicitly with this function. A + * value of 0 is assumed for any undefined column. In fact, if you never call + * this function, all columns occupied by Views will have the same width. On the + * other hand, unoccupied columns defined with this function will always take + * their place. * - * Assuming a total width of the grid of 100 cells and a minimum width of 0, the + *

Assuming a total width of the grid of 100 cells and a minimum width of 0, the * following call will result in columns with widths of 30, 10, 15, 15, and 30 * cells: + *

* - * grid.SetColumns(30, 10, -1, -1, -2) + * grid.setColumnSize(30, 10, -1, -1, -2) * - * If a primitive were then placed in the 6th and 7th column, the resulting + *

If a {@link View} were then placed in the 6th and 7th column, the resulting * widths would be: 30, 10, 10, 10, 20, 10, and 10 cells. * - * If you then called SetMinSize() as follows: + * If you then called setMinSize() as follows: + *

* - * grid.SetMinSize(15, 20) + * grid.setMinSize(15, 20) * - * The resulting widths would be: 30, 15, 15, 15, 20, 15, and 15 cells, a total + *

The resulting widths would be: 30, 15, 15, 15, 20, 15, and 15 cells, a total * of 125 cells, 25 cells wider than the available grid width. * - * @param columns - * @return + * @param columns the column sizes + * @return a grid view for chaining + * @see #setRowSize(int...) */ public GridView setColumnSize(int... columns) { this.columnSize = columns; @@ -93,9 +97,10 @@ public class GridView extends BoxView { } /** + * For documentation see {@link #setColumnSize(int...)} as it's equivalent for rows. * - * @param rows - * @return + * @param rows the row sizes + * @return a grid view for chaining * @see #setColumnSize(int...) */ public GridView setRowSize(int... rows) { @@ -103,6 +108,21 @@ public class GridView extends BoxView { return this; } + /** + * Sets an absolute minimum width for rows and an absolute minimum height for + * columns. Negative values cannot be used. + * + * @param minWidth the rows minimum width + * @param minHeight the columns minimum height + * @return a grid view for chaining + */ + public GridView setMinSize(int minWidth, int minHeight) { + Assert.state(minWidth > -1 || minHeight > -1, "Minimum sizes for rows or colums cannot be negative"); + this.minWidth = minWidth; + this.minHeight = minHeight; + return this; + } + public GridView addItem(View view, int row, int column, int rowSpan, int colSpan, int minGridHeight, int minGridWidth) { GridItem gridItem = new GridItem(view, row, column, colSpan, rowSpan, minGridHeight, diff --git a/spring-shell-core/src/test/java/org/springframework/shell/component/view/control/GridViewTests.java b/spring-shell-core/src/test/java/org/springframework/shell/component/view/control/GridViewTests.java index 01dfb43e..3a4c7471 100644 --- a/spring-shell-core/src/test/java/org/springframework/shell/component/view/control/GridViewTests.java +++ b/spring-shell-core/src/test/java/org/springframework/shell/component/view/control/GridViewTests.java @@ -21,6 +21,7 @@ import org.junit.jupiter.api.Test; import org.springframework.shell.component.view.screen.DefaultScreen; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -88,6 +89,182 @@ class GridViewTests extends AbstractViewTests { verify(sbox2).setRect(0, 12, 80, 12); } + @Test + void positionsWith3x3() { + BoxView box1 = new BoxView(); + BoxView box2 = new BoxView(); + BoxView box3 = new BoxView(); + BoxView box4 = new BoxView(); + BoxView box5 = new BoxView(); + BoxView box6 = new BoxView(); + BoxView box7 = new BoxView(); + BoxView box8 = new BoxView(); + BoxView box9 = new BoxView(); + BoxView sbox1 = spy(box1); + BoxView sbox2 = spy(box2); + BoxView sbox3 = spy(box3); + BoxView sbox4 = spy(box4); + BoxView sbox5 = spy(box5); + BoxView sbox6 = spy(box6); + BoxView sbox7 = spy(box7); + BoxView sbox8 = spy(box8); + BoxView sbox9 = spy(box9); + GridView grid = new GridView(); + + grid.setShowBorders(false); + grid.setRowSize(0, 0, 0); + grid.setColumnSize(0, 0, 0); + grid.setShowBorder(false); + + grid.addItem(sbox1, 0, 0, 1, 1, 0, 0); + grid.addItem(sbox2, 0, 1, 1, 1, 0, 0); + grid.addItem(sbox3, 0, 2, 1, 1, 0, 0); + + grid.addItem(sbox4, 1, 0, 1, 1, 0, 0); + grid.addItem(sbox5, 1, 1, 1, 1, 0, 0); + grid.addItem(sbox6, 1, 2, 1, 1, 0, 0); + + grid.addItem(sbox7, 2, 0, 1, 1, 0, 0); + grid.addItem(sbox8, 2, 1, 1, 1, 0, 0); + grid.addItem(sbox9, 2, 2, 1, 1, 0, 0); + + grid.setRect(0, 0, 80, 24); + grid.draw(screen24x80); + + verify(sbox1).setRect(0, 0, 26, 8); + verify(sbox2).setRect(26, 0, 27, 8); + verify(sbox3).setRect(53, 0, 27, 8); + verify(sbox4).setRect(0, 8, 26, 8); + verify(sbox5).setRect(26, 8, 27, 8); + verify(sbox6).setRect(53, 8, 27, 8); + verify(sbox7).setRect(0, 16, 26, 8); + verify(sbox8).setRect(26, 16, 27, 8); + verify(sbox9).setRect(53, 16, 27, 8); + } + + @Test + void minimumWidthWith3x3_1() { + BoxView box1 = new BoxView(); + BoxView box2 = new BoxView(); + BoxView box3 = new BoxView(); + BoxView box4 = new BoxView(); + BoxView box5 = new BoxView(); + BoxView sbox1 = spy(box1); + BoxView sbox2 = spy(box2); + BoxView sbox3 = spy(box3); + BoxView sbox4 = spy(box4); + BoxView sbox5 = spy(box5); + GridView grid = new GridView(); + + grid.setShowBorders(false); + grid.setRowSize(0); + grid.setColumnSize(30, 10, -1, -1, -2); + grid.setShowBorder(false); + + grid.addItem(sbox1, 0, 0, 1, 1, 0, 0); + grid.addItem(sbox2, 0, 1, 1, 1, 0, 0); + grid.addItem(sbox3, 0, 2, 1, 1, 0, 0); + grid.addItem(sbox4, 0, 3, 1, 1, 0, 0); + grid.addItem(sbox5, 0, 4, 1, 1, 0, 0); + + grid.setRect(0, 0, 100, 100); + grid.draw(screen24x80); + + verify(sbox1).setRect(0, 0, 30, 100); + verify(sbox2).setRect(30, 0, 10, 100); + verify(sbox3).setRect(40, 0, 15, 100); + verify(sbox4).setRect(55, 0, 15, 100); + verify(sbox5).setRect(70, 0, 30, 100); + } + + @Test + void minimumWidthWith3x3_2() { + BoxView box1 = new BoxView(); + BoxView box2 = new BoxView(); + BoxView box3 = new BoxView(); + BoxView box4 = new BoxView(); + BoxView box5 = new BoxView(); + BoxView box6 = new BoxView(); + BoxView box7 = new BoxView(); + BoxView sbox1 = spy(box1); + BoxView sbox2 = spy(box2); + BoxView sbox3 = spy(box3); + BoxView sbox4 = spy(box4); + BoxView sbox5 = spy(box5); + BoxView sbox6 = spy(box6); + BoxView sbox7 = spy(box7); + GridView grid = new GridView(); + + grid.setShowBorders(false); + grid.setRowSize(0); + grid.setColumnSize(30, 10, -1, -1, -2); + grid.setShowBorder(false); + + grid.addItem(sbox1, 0, 0, 1, 1, 0, 0); + grid.addItem(sbox2, 0, 1, 1, 1, 0, 0); + grid.addItem(sbox3, 0, 2, 1, 1, 0, 0); + grid.addItem(sbox4, 0, 3, 1, 1, 0, 0); + grid.addItem(sbox5, 0, 4, 1, 1, 0, 0); + grid.addItem(sbox6, 0, 5, 1, 1, 0, 0); + grid.addItem(sbox7, 0, 6, 1, 1, 0, 0); + + grid.setRect(0, 0, 100, 100); + grid.draw(screen24x80); + + verify(sbox1).setRect(0, 0, 30, 100); + verify(sbox2).setRect(30, 0, 10, 100); + verify(sbox3).setRect(40, 0, 10, 100); + verify(sbox4).setRect(50, 0, 10, 100); + verify(sbox5).setRect(60, 0, 20, 100); + verify(sbox6).setRect(80, 0, 10, 100); + verify(sbox7).setRect(90, 0, 10, 100); + } + + @Test + void minimumWidthWith3x3_3() { + BoxView box1 = new BoxView(); + BoxView box2 = new BoxView(); + BoxView box3 = new BoxView(); + BoxView box4 = new BoxView(); + BoxView box5 = new BoxView(); + BoxView box6 = new BoxView(); + BoxView box7 = new BoxView(); + BoxView sbox1 = spy(box1); + BoxView sbox2 = spy(box2); + BoxView sbox3 = spy(box3); + BoxView sbox4 = spy(box4); + BoxView sbox5 = spy(box5); + BoxView sbox6 = spy(box6); + BoxView sbox7 = spy(box7); + GridView grid = new GridView(); + + grid.setShowBorders(false); + grid.setRowSize(0); + grid.setColumnSize(30, 10, -1, -1, -2); + grid.setShowBorder(false); + + grid.addItem(sbox1, 0, 0, 1, 1, 0, 0); + grid.addItem(sbox2, 0, 1, 1, 1, 0, 0); + grid.addItem(sbox3, 0, 2, 1, 1, 0, 0); + grid.addItem(sbox4, 0, 3, 1, 1, 0, 0); + grid.addItem(sbox5, 0, 4, 1, 1, 0, 0); + grid.addItem(sbox6, 0, 5, 1, 1, 0, 0); + grid.addItem(sbox7, 0, 6, 1, 1, 0, 0); + + grid.setRect(0, 0, 100, 100); + grid.setMinSize(15, 20); + grid.draw(screen24x80); + + verify(sbox1).setRect(0, 0, 30, 100); + verify(sbox2).setRect(30, 0, 15, 100); + verify(sbox3).setRect(45, 0, 15, 100); + verify(sbox4).setRect(60, 0, 15, 100); + verify(sbox5).setRect(75, 0, 18, 100); + verify(sbox6).setRect(93, 0, 7, 100); + // last one outside should not get called + verify(sbox7, never()).setRect(0, 0, 0, 0); + } + } @Nested