Expose column and row min setting in GridView

- Add method setMinSize for setting minimum width for columns
  and minimum height for rows.
- Relates #805
This commit is contained in:
Janne Valkealahti
2023-07-16 18:13:39 +01:00
parent 3ac48bf15a
commit d053fab383
2 changed files with 218 additions and 21 deletions

View File

@@ -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.
* <p>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
* <p>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:
* <p>
*
* 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
* <p>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:
* <p>
*
* grid.SetMinSize(15, 20)
* grid.setMinSize(15, 20)
*
* The resulting widths would be: 30, 15, 15, 15, 20, 15, and 15 cells, a total
* <p>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,

View File

@@ -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