X-Git-Url: http://git.nikiroo.be/?p=fanfix.git;a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Fjexer%2FTTableCellRenderer.java;fp=src%2Fbe%2Fnikiroo%2Fjexer%2FTTableCellRenderer.java;h=6d7b3b35af5e6011c74f9508de0373154b86826a;hp=0000000000000000000000000000000000000000;hb=8f34a7954f96acdd5d7be5ed6f08fea2713f7d75;hpb=4162793727db52a12e0efeaca48ac5dbdcb57bdf diff --git a/src/be/nikiroo/jexer/TTableCellRenderer.java b/src/be/nikiroo/jexer/TTableCellRenderer.java new file mode 100644 index 0000000..6d7b3b3 --- /dev/null +++ b/src/be/nikiroo/jexer/TTableCellRenderer.java @@ -0,0 +1,240 @@ +/* + * Jexer - Java Text User Interface + * + * The MIT License (MIT) + * + * Copyright (C) 2019 David "Niki" ROULET + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * @author David ROULET [niki@nikiroo.be] + * @version 1 + */ +package be.nikiroo.jexer; + +import jexer.bits.CellAttributes; +import jexer.bits.ColorTheme; + +/** + * A {@link TTable} cell renderer allows you to customize the way a single cell + * will be displayed on screen. + *

+ * It can be used in a {@link TTable} for the haeders or the separators or in a + * {@link TTableColumn} for the data. + * + * @author niki + */ +abstract public class TTableCellRenderer { + private CellRendererMode mode; + + /** + * The simple renderer mode. + * + * @author niki + */ + public enum CellRendererMode { + /** Normal text mode */ + NORMAL, + /** Only display a separator */ + SEPARATOR, + /** Header text mode */ + HEADER, + /** Both HEADER and SEPARATOR at once */ + HEADER_SEPARATOR; + + /** + * This mode represents a separator. + * + * @return TRUE for separators + */ + public boolean isSeparator() { + return this == SEPARATOR || this == HEADER_SEPARATOR; + } + + /** + * This mode represents a header. + * + * @return TRUE for headers + */ + public boolean isHeader() { + return this == HEADER || this == HEADER_SEPARATOR; + } + } + + /** + * Create a new renderer of the given mode. + * + * @param mode + * the renderer mode, cannot be NULL + */ + public TTableCellRenderer(CellRendererMode mode) { + if (mode == null) { + throw new IllegalArgumentException( + "Cannot create a renderer of type NULL"); + } + + this.mode = mode; + } + + /** + * Render the given value. + * + * @param table + * the table to write on + * @param value + * the value to write + * @param rowIndex + * the row index in the table + * @param colIndex + * the column index in the table + * @param y + * the Y position at which to draw this row + */ + abstract public void renderTableCell(TTable table, Object value, + int rowIndex, int colIndex, int y); + + /** + * The mode of this {@link TTableCellRenderer}. + * + * @return the mode + */ + public CellRendererMode getMode() { + return mode; + } + + /** + * The cell attributes to use for the given state. + * + * @param theme + * the color theme to use + * @param isSelected + * TRUE if the cell is selected + * @param hasFocus + * TRUE if the cell has focus + * + * @return the attributes + */ + public CellAttributes getCellAttributes(ColorTheme theme, + boolean isSelected, boolean hasFocus) { + return theme.getColor(getColorKey(isSelected, hasFocus)); + } + + /** + * Measure the width of the value. + * + * @param value + * the value to measure + * + * @return its width + */ + public int getWidthOf(Object value) { + if (getMode().isSeparator()) { + return asText(null, 0, false).length(); + } + return ("" + value).length(); + } + + /** + * The colour to use for the given state, specified as a Jexer colour key. + * + * @param isSelected + * TRUE if the cell is selected + * @param hasFocus + * TRUE if the cell has focus + * + * @return the colour key + */ + protected String getColorKey(boolean isSelected, boolean hasFocus) { + if (mode.isHeader()) { + return "tlabel"; + } + + String colorKey = "tlist"; + if (isSelected) { + colorKey += ".selected"; + } else if (!hasFocus) { + colorKey += ".inactive"; + } + + return colorKey; + } + + /** + * Return the X offset to use to draw a column at the given index. + * + * @param table + * the table to draw into + * @param colIndex + * the column index + * + * @return the offset + */ + protected int getXOffset(TTable table, int colIndex) { + int xOffset = -table.getHorizontalValue(); + for (int i = 0; i <= colIndex; i++) { + TTableColumn tcol = table.getColumns().get(i); + xOffset += tcol.getWidth(); + if (i > 0) { + xOffset += table.getSeparatorRenderer().getWidthOf(null); + } + } + + TTableColumn tcol = table.getColumns().get(colIndex); + if (!getMode().isSeparator()) { + xOffset -= tcol.getWidth(); + } + + return xOffset; + } + + /** + * Return the text to use (usually the converted-to-text value, except for + * the special separator mode). + * + * @param value + * the value to get the text of + * @param width + * the width we should tale + * @param align + * the text to the right + * + * @return the {@link String} to display + */ + protected String asText(Object value, int width, boolean rightAlign) { + if (getMode().isSeparator()) { + // some nice characters for the separator: ┃ │ | + return " │ "; + } + + if (width <= 0) { + return ""; + } + + String format; + if (!rightAlign) { + // Left align + format = "%-" + width + "s"; + } else { + // right align + format = "%" + width + "s"; + } + + return String.format(format, value); + } +} \ No newline at end of file