package com.lucasdnd.ags.ui; import java.util.ArrayList; import java.util.Collections; import org.newdawn.slick.Font; import org.newdawn.slick.GameContainer; import org.newdawn.slick.Graphics; import org.newdawn.slick.SlickException; import org.newdawn.slick.state.StateBasedGame; import org.newdawn.slick.util.FontUtils; import com.lucasdnd.ags.gameplay.Business; import com.lucasdnd.ags.system.ResourceLoader; public abstract class List extends UIComponent { // Headers, List Items, Buttons. Basic stuff protected ListHeader[] listHeaders; protected ArrayList<ListRow> listRows; protected int currentSort; // The column it is being sorted by protected Button nextPageButton; // The Up Arrow Button, used to scroll the items protected Button previousPageButton; // The Down Arrow Button, used to scroll the items // The sizes, padding, margins, etc. protected float lineSize = 27f; // The size of one row in the list protected final float leftMargin = 19f; // Left margin, between the List and the left border of the Panel protected final float topMargin = 3f; // Top margin, between the List and the Tile Bar // Paging protected int pageSize = 18; // The amount of items that can fit one page protected int page = 0; // The current page /** * Basic Constructor * @throws SlickException */ public List(float xPos, float yPos, float width, float height) throws SlickException { this.xPos = xPos; this.yPos = yPos; this.width = width; this.height = height; // Create the Buttons nextPageButton = new Button(ResourceLoader.getInstance().nextPageButtonImages, (int)this.xPos + (int)this.width - lineSize * 2, (int)this.yPos + (int)this.height - lineSize - lineSize / 3); previousPageButton = new Button(ResourceLoader.getInstance().previousPageButtonImages, (int)this.xPos + (int)this.width - lineSize * 6, (int)this.yPos + (int)this.height - lineSize - lineSize / 3); } /** * Update * @param container * @param game * @param delta * @param business * @param leftMouseClicked * @param mouseX * @param mouseY * @throws SlickException */ public void update(GameContainer container, StateBasedGame game, int delta, Business business, boolean leftMouseClicked, boolean leftMouseDown, int mouseX, int mouseY) throws SlickException { // Button Hover nextPageButton.update(container, game, delta, leftMouseClicked, leftMouseDown, mouseX, mouseY); previousPageButton.update(container, game, delta, leftMouseClicked, leftMouseDown, mouseX, mouseY); // Page Buttons if(nextPageButton.gotLeftClicked(leftMouseClicked, mouseX, mouseY)) { if(pageSize * (page + 1) < listRows.size()) { // Next Page page++; updateRowsPositions(); // Then we reset the rectangles around the Rows for(int i = 0; i < listRows.size(); i++) { if((i >= page * pageSize) && (i < (page + 1) * (pageSize))) { listRows.get(i).createRectangle(); } } } } else if (previousPageButton.gotLeftClicked(leftMouseClicked, mouseX, mouseY)) { if(page > 0) { // Previous Page page--; updateRowsPositions(); // Then we reset the rectangles around the Rows for(int i = 0; i < listRows.size(); i++) { if((i >= page * pageSize) && (i < (page + 1) * (pageSize))) { listRows.get(i).createRectangle(); } } } } } /** * Check for list header clicks (sorting) * * @param leftMouseClicked * @param mouseX * @param mouseY */ protected void checkHeaderClicks(boolean leftMouseClicked, int mouseX, int mouseY) { for(int i = 0; i < listHeaders.length; i++) { // Check for clicks if(listHeaders[i].gotLeftClicked(leftMouseClicked, mouseX, mouseY)) { sortList(i, (currentSort == i ? true : false)); currentSort = i; this.updateRowsPositions(); for(ListRow lr : listRows) lr.createRectangle(); } } } /** * Render * @param container * @param game * @param g * @throws SlickException */ public void render(GameContainer container, StateBasedGame game, Graphics g, Font panelFont, Font disabledFont, Font shadowFont) throws SlickException { // Renders the List Headers if (listHeaders != null) { for(ListHeader lh : listHeaders) { lh.render(container, game, g, panelFont, disabledFont, shadowFont); } } // Renders the List Rows for(int i = 0; i < listRows.size(); i++) { // Here we make sure we render only what's in the current page if((i >= page * pageSize) && (i < (page + 1) * (pageSize))) { listRows.get(i).render(container, game, g, panelFont, disabledFont, shadowFont); } } // Renders the Page Number int safePageSize = 0; safePageSize = pageSize; FontUtils.drawRight(shadowFont, (page + 1) + "/" + (((listRows.size() - 1) / safePageSize) + 1), 1 + (int)this.xPos + (int)this.width - (int)lineSize * 4 + 4, 1 + (int)this.yPos + (int)this.height - (int)lineSize - (int)lineSize / 2 + 6, 30); FontUtils.drawRight(panelFont, (page + 1) + "/" + (((listRows.size() - 1) / safePageSize) + 1), (int)this.xPos + (int)this.width - (int)lineSize * 4 + 4, (int)this.yPos + (int)this.height - (int)lineSize - (int)lineSize / 2 + 6, 30); // Renders the Buttons nextPageButton.render(container, game, g); previousPageButton.render(container, game, g); } /** * Updates the position and size of the List Rows. This should be called every time the user changes the page he's browsing */ public void updateRowsPositions() { // Goes through each List Row for(int i = 0; i < listRows.size(); i++) { // Define the size and dimension of each List Column inside each List Row for(int j = 0; j < listRows.get(i).getListColumns().length; j++) { listRows.get(i).getListColumns()[j].setxPos(listHeaders[j].xPos); listRows.get(i).getListColumns()[j].setyPos(listHeaders[j].yPos + (i + 1 - (page * pageSize)) * lineSize); listRows.get(i).getListColumns()[j].setWidth(listHeaders[j].width); listRows.get(i).getListColumns()[j].setHeight(listHeaders[j].height); } // Calculate the combined width of the Headers float combinedHeadersWidth = 0f; for(int j = 0; j < listHeaders.length; j++) { combinedHeadersWidth += listHeaders[j].getWidth(); } // Define the size and dimension of each List Row listRows.get(i).setxPos(listHeaders[0].getxPos() - 2f); listRows.get(i).setyPos(listHeaders[0].getyPos() + (lineSize * (i - (page * pageSize))) + lineSize); listRows.get(i).setWidth(combinedHeadersWidth + 5f); listRows.get(i).setHeight(listHeaders[0].getHeight() - 2f); } } /** * Sorts the list based on a column id * @param columnSort * @param descending */ public void sortList(int columnSort, boolean descending) { if(descending) { Collections.reverse(listRows); } else { Collections.sort(listRows, new ListRowComparator(columnSort)); } } public ArrayList<ListRow> getListItems() { return listRows; } public void setListItems(ArrayList<ListRow> listItems) { this.listRows = listItems; } public ListHeader[] getListHeaders() { return listHeaders; } public void setListHeaders(ListHeader[] listHeaders) { this.listHeaders = listHeaders; } public ArrayList<ListRow> getListRows() { return listRows; } public void setListRows(ArrayList<ListRow> listRows) { this.listRows = listRows; } public Button getUpArrowButton() { return nextPageButton; } public void setUpArrowButton(Button upArrowButton) { this.nextPageButton = upArrowButton; } public Button getDownArrowButton() { return previousPageButton; } public void setDownArrowButton(Button downArrowButton) { this.previousPageButton = downArrowButton; } public int getCurrentSort() { return currentSort; } public void setCurrentSort(int currentSort) { this.currentSort = currentSort; } }