├── .gitignore ├── LICENSE ├── README.md ├── pom.xml ├── tablelayout-android ├── .classpath ├── .project ├── .settings │ └── org.eclipse.jdt.core.prefs ├── lib │ └── android-2.0.jar ├── pom.xml ├── project.yaml └── src │ └── com │ └── esotericsoftware │ └── tablelayout │ └── android │ ├── AndroidToolkit.java │ ├── Stack.java │ ├── Table.java │ └── TableLayout.java ├── tablelayout-swing ├── .classpath ├── .project ├── pom.xml ├── project.yaml ├── src │ └── com │ │ └── esotericsoftware │ │ └── tablelayout │ │ └── swing │ │ ├── Stack.java │ │ ├── SwingToolkit.java │ │ ├── Table.java │ │ └── TableLayout.java └── test │ └── com │ └── esotericsoftware │ └── tablelayout │ └── swing │ └── SwingTest.java ├── tablelayout-twl ├── .classpath ├── .project ├── lib │ ├── lwjgl-debug.jar │ ├── natives │ │ ├── OpenAL32.dll │ │ ├── OpenAL64.dll │ │ ├── liblwjgl.jnilib │ │ ├── lwjgl.dll │ │ ├── lwjgl64.dll │ │ └── openal.dylib │ ├── twl.jar │ └── xpp3-1.1.4c.jar ├── pom.xml ├── project.yaml ├── src │ └── com │ │ └── esotericsoftware │ │ └── tablelayout │ │ └── twl │ │ ├── Stack.java │ │ ├── Table.java │ │ ├── TableLayout.java │ │ └── TwlToolkit.java └── test │ ├── com │ └── esotericsoftware │ │ └── tablelayout │ │ └── twl │ │ └── TwlTest.java │ ├── font.fnt │ ├── font.png │ ├── widgets.png │ ├── widgets.xml │ └── widgets.xml.old └── tablelayout ├── .classpath ├── .project ├── .settings └── org.eclipse.jdt.core.prefs ├── pom.xml └── src └── com └── esotericsoftware ├── TableLayout.gwt.xml └── tablelayout ├── BaseTableLayout.java ├── Cell.java ├── Toolkit.java └── Value.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Temporary Files 2 | *~ 3 | .*.swp 4 | .DS_STORE 5 | 6 | bin/ 7 | target/ 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2018, Nathan Sweet 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/logo.gif) 2 | 3 | Please use the [TableLayout discussion group](http://groups.google.com/group/tablelayout-users) for support. 4 | 5 | ## Overview 6 | 7 | TableLayout is a lightweight Java library for setting the position and size of UI widgets using a logical table, similar to HTML tables. The core of TableLayout is UI toolkit agnostic and comes with support for Swing, Android, and TWL. Layout using tables is intuitive and TableLayout's Java API is very easy to use. 8 | 9 | A fork of TableLayout is included inside [libgdx](https://libgdx.badlogicgames.com/), so TableLayout is not needed if using libgdx. 10 | 11 | - [Quickstart](#quickstart) 12 | - [Root table](#root-table) 13 | - [Debugging](#debugging) 14 | - [Adding cells](#adding-cells) 15 | - [Logical table](#logical-table) 16 | - [Cell properties](#cell-properties) 17 | - [Expand](#expand) 18 | - [Alignment](#alignment) 19 | - [Fill](#fill) 20 | - [Widget size](#widget-size) 21 | - [Padding](#padding) 22 | - [Spacing](#spacing) 23 | - [Colspan](#colspan) 24 | - [Uniform](#uniform) 25 | - [Defaults](#defaults) 26 | - [Cell defaults](#cell-defaults) 27 | - [Column defaults](#column-defaults) 28 | - [Row defaults](#row-defaults) 29 | - [Stacks](#stacks) 30 | - [Android](#Android) 31 | - [Similar libraries](#similar-libraries) 32 | 33 | ## Quickstart 34 | 35 | Here is a quick example of a simple form in libgdx: 36 | 37 | ```java 38 | // Keep your code clean by creating widgets separate from layout. 39 | Label nameLabel = new Label("Name:", skin); 40 | TextField nameText = new TextField(skin); 41 | Label addressLabel = new Label("Address:", skin); 42 | TextField addressText = new TextField(skin); 43 | 44 | Table table = new Table(); 45 | table.add(nameLabel); // Row 0, column 0. 46 | table.add(nameText).width(100); // Row 0, column 1. 47 | table.row(); // Move to next row. 48 | table.add(addressLabel); // Row 1, column 0. 49 | table.add(addressText).width(100); // Row 1, column 1. 50 | ``` 51 | 52 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/quickstart.png) 53 | 54 | This code adds 4 cells to the table which are arranged in two columns and two rows. The `add` method returns a Cell, which has methods to control layout. Here the width of the text fields are set to 100. 55 | 56 | The example code used in this documentation is for libgdx, but the API for the other supported toolkits is almost identical. 57 | 58 | ## Root table 59 | 60 | When doing UI layout, a UI widget does not set its own size. Instead, it provides a minimum, preferred, and maximum size. The widget's parent uses its own size along with these hints to size the widget. Many layouts will use a single table at the root which has a fixed size, often the whole screen. Widgets and nested tables are added to the root table. 61 | 62 | Sizing the root table varies in each UI toolkit. Eg, in Swing you would likely add the table to the JFrame's content pane. In libgdx the `setFillParent` method can be used: 63 | 64 | ```java 65 | Table table = new Table(); 66 | table.setFillParent(true); 67 | stage.addActor(table); 68 | ``` 69 | 70 | ## Debugging 71 | 72 | TableLayout can draw debug lines to visualize what is happening in the layout. Debugging is enabled by calling `debug` on the table. libgdx automatically renders debug lines if they are enabled. Other UI toolkits may require a method to be called to render the lines. 73 | 74 | ```java 75 | table.debug(); // Turn on all debug lines (table, cell, and widget). 76 | table.debugTable(); // Turn on only table lines. 77 | ``` 78 | 79 | ## Adding cells 80 | 81 | Widgets are added to a table with the `add` method (for UI toolkits that already have an `add` method, `addCell` is used). This adds a cell to the current row. To move to the next row, call the `row` method. 82 | 83 | ```java 84 | table.add(nameLabel); // Row 0, column 0. 85 | table.add(nameText); // Row 0, column 1. 86 | table.row(); // Move to next row. 87 | table.add(addressLabel); // Row 1, column 0. 88 | table.add(addressText); // Row 1, column 1. 89 | ``` 90 | 91 | The `add` method returns a Cell, which has properties that control the layout. Every method on the cell returns the cell, allowing calls to be chained. 92 | 93 | ```java 94 | table.add(nameText).padLeft(10).width(100); // Sets left padding and width on the new cell. 95 | ``` 96 | 97 | ## Logical table 98 | 99 | The cells make up a logical table, but it is not sized to the table widget. 100 | 101 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/logicaltable.png) 102 | 103 | The outer blue rectangle shows the size of the table widget. The inner blue rectangle shows the size of the logical table, which is aligned to center by default. The alignment can be changed using methods on the table. The table methods return the table, so can be chained just like the cell methods. 104 | 105 | ```java 106 | table.right().bottom(); 107 | ``` 108 | 109 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/tablealign.png) 110 | 111 | ## Cell properties 112 | 113 | ### Expand 114 | 115 | To make the logical table take up the entire size of the table widget, TableLayout needs to be told which cells will receive the extra space. 116 | 117 | ```java 118 | table.add(nameLabel).expandX(); // Column 0 receives all extra horizontal space. 119 | table.add(nameText).width(100); 120 | table.row(); 121 | table.add(addressLabel); 122 | table.add(addressText).width(100); 123 | ``` 124 | 125 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/expand.png) 126 | 127 | The red lines show the cell bounds and the green lines show the widget bounds. Note that the left column has received all of the extra space in the x direction. Only one cell needs to have expand to cause the entire column or row to expand. If multiple columns expand, the extra space is distributed evenly. 128 | 129 | ```java 130 | table.add(nameLabel).expandX(); // Receives extra horizontal space. 131 | table.add(nameText).width(100).expandX(); // Also receives extra horizontal space. 132 | table.row(); 133 | table.add(addressLabel); 134 | table.add(addressText).width(100); 135 | ``` 136 | 137 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/expandmultiple.png) 138 | 139 | Expand also works in the y direction via the `expandY` method. The `expand` method causes expand to happen in both directions. 140 | 141 | ```java 142 | table.add(nameLabel).expand(); // Receives all extra horizontal and vertical space. 143 | table.add(nameText).width(100); 144 | table.row(); 145 | table.add(addressLabel); 146 | table.add(addressText).width(100); 147 | ``` 148 | 149 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/expandboth.png) 150 | 151 | ### Alignment 152 | 153 | Similar to aligning the logical table, a widget can be aligned inside the cell. 154 | 155 | ```java 156 | table.add(nameLabel).expand().bottom().right(); // Aligned bottom right. 157 | table.add(nameText).width(100).top(); // Aligned top. 158 | table.row(); 159 | table.add(addressLabel); 160 | table.add(addressText).width(100); 161 | ``` 162 | 163 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/align.png) 164 | 165 | ### Fill 166 | 167 | The `fill` method causes a widget to be sized to the cell. Like expand, there are also `fillX` and `fillY` methods. 168 | 169 | ```java 170 | table.add(nameLabel).expand().bottom().fillX(); // Sized to cell horizontally. 171 | table.add(nameText).width(100).top(); 172 | table.row(); 173 | table.add(addressLabel); 174 | table.add(addressText).width(100); 175 | ``` 176 | 177 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/fill.png) 178 | 179 | Note the red cell lines are drawn on top of the green widget lines. 180 | 181 | ## Widget size 182 | 183 | By default, the table attempts to size widgets to their preferred size. If the widgets don't fit, they are sized between their preferred size and their minimum size, with widgets that have a larger preferred size receiving more space. If the widgets don't fit at their minimum size then the layout is broken and widgets may overlap. The `fill` methods won't make a widget larger than the widget's maximum size. 184 | 185 | Widgets should not be subclassed to change the preferred, minimum, or maximum size. Instead, these sizes can be set on the cell and will be used instead of the widget's value. 186 | 187 | ```java 188 | table.add(nameLabel); 189 | table.add(nameText).minWidth(100); // Sets min width. 190 | table.row(); 191 | table.add(addressLabel); 192 | table.add(addressText).prefWidth(999); // Sets pref width. 193 | ``` 194 | 195 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/size.png) 196 | 197 | Here the `prefWidth` of 999 is larger than the table, so it is sized down to fit. 198 | 199 | `width` is a shortcut method for setting `minWidth`, `prefWidth`, and `maxWidth` to the same value. `height` is a shortcut method for setting `minHeight`, `prefHeight`, and `maxHeight` to the same value. The `size` method takes a width and a height and sets all six properties. 200 | 201 | ### Padding 202 | 203 | Padding is extra space around the edges of a cell. 204 | 205 | ```java 206 | table.add(nameLabel); 207 | table.add(nameText).width(100).padBottom(10); // Sets bottom padding. 208 | table.row(); 209 | table.add(addressLabel); 210 | table.add(addressText).width(100).pad(10); // Sets top, left, bottom, right padding. 211 | ``` 212 | 213 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/pad.png) 214 | 215 | Note that padding between cells combines, so there are 20 pixels between the text fields. The debug lines don't necessarily show which cell the padding comes from, since it is not important for the layout of the table. 216 | 217 | Padding can also be applied to the edges of the table. 218 | 219 | ```java 220 | table.pad(10); 221 | ``` 222 | 223 | ### Spacing 224 | 225 | Like padding, spacing is extra space around the edges of a cell. However, spacing between cells does not combine, instead the larger of the two is used. Also, spacing is not applied at the edge of the table. Spacing makes it easy to have consistent space between cells. 226 | 227 | ```java 228 | table.add(nameLabel); 229 | table.add(nameText).width(100).spaceBottom(10); // Sets bottom spacing. 230 | table.row(); 231 | table.add(addressLabel); 232 | table.add(addressText).width(100).space(10); // Sets top, left, bottom, right spacing. 233 | ``` 234 | 235 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/space.png) 236 | 237 | Note that the spacing between cells doesn't combine, so there are 10 pixels between the text fields. Also note that there is no spacing under the bottom text field because spacing isn't applied around the edge of the table. 238 | 239 | ### Colspan 240 | 241 | A cell can span multiple columns. 242 | 243 | ```java 244 | table.add(nameLabel); 245 | table.add(nameText).width(100).spaceBottom(10); 246 | table.row(); 247 | table.add(addressLabel).colspan(2); // Spans 2 columns. 248 | ``` 249 | 250 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/colspan.png) 251 | 252 | Note that there is no rowspan. To acheive this, use a nested table. 253 | 254 | ## Uniform 255 | 256 | Cells with `uniform` set to true will be the same size. 257 | 258 | ```java 259 | table.add(nameLabel).uniform(); // These two cells will have 260 | table.add(nameText).width(100).uniform(); // the same width and height. 261 | table.row(); 262 | table.add(addressLabel); 263 | table.add(addressText).width(100); 264 | ``` 265 | 266 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/uniform.png) 267 | 268 | ## Defaults 269 | 270 | ### Cell defaults 271 | 272 | Often many cells have the same properties, so setting the default properties for all cells can greatly reduce the code needed for a layout. The `defaults` method on the table returns a cell whose properties are the defaults for all cells. 273 | 274 | ```java 275 | table.defaults().width(100); // Sets defaults for all cells. 276 | table.add(nameLabel); 277 | table.add(nameText); 278 | table.row(); 279 | table.add(addressLabel); 280 | table.add(addressText); 281 | ``` 282 | 283 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/defaults.png) 284 | 285 | ### Column defaults 286 | 287 | The `columnDefaults` method on the table returns a cell whose properties are the defaults for all cells in that column. Any properties set here will override the cell default properties. Columns are indexed starting at 0. 288 | 289 | ```java 290 | table.columnDefaults(1).width(150); // Sets defaults for cells in column 0. 291 | table.add(nameLabel); 292 | table.add(nameText); 293 | table.row(); 294 | table.add(addressLabel); 295 | table.add(addressText); 296 | ``` 297 | 298 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/columndefaults.png) 299 | 300 | ### Row defaults 301 | 302 | When the `row` method is called, it returns a cell whose properties are the defaults for all cells in that row. Any properties set here will override both the cell default properties and the column default properties. Note it is allowed to call `row` before any cells are added. This allows the first row to have row default properties. 303 | 304 | ```java 305 | table.row().height(50); // Set cell defaults for row 0. 306 | table.add(nameLabel); 307 | table.add(nameText); 308 | table.row().height(100); // Set cell defaults for row 1. 309 | table.add(addressLabel); 310 | table.add(addressText); 311 | ``` 312 | 313 | ![](https://raw.github.com/wiki/EsotericSoftware/tablelayout/images/home/rowdefaults.png) 314 | 315 | ## Stacks 316 | 317 | A stack widget is a special kind of container that lays out each child to be the size of the stack. This is useful when it is necessary to have widgets stacked on top of each other. The first widget added to the stack is drawn on the bottom, and the last widget added is drawn on the top. 318 | 319 | ## Android 320 | 321 | On Android, when the application starts, `AndroidToolkit.setup` must be called: 322 | 323 | ```java 324 | AndroidToolkit.setup(yourActivity, R.drawable.class); 325 | ``` 326 | 327 | ## Similar libraries 328 | 329 | A few Java, table-based layout managers: 330 | 331 | [GridBagLayout](https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html) can handle complex table-based layouts, but does so via a clunky API. 332 | 333 | TableLayout (the other one from Sun, webpage no longer available) uses 2D arrays of percentages, sizes, and flags to describe the table and how it should be sized. This approach has the same problems as GridBagLayout. 334 | 335 | [PageLayout](http://pagelayout.sourceforge.net/) uses a concise Java API to describe the table. 336 | 337 | [PnutsLayout](https://github.com/kmizu/spnuts/blob/master/modules/pnuts.awt/src/pnuts/awt/PnutsLayout.java) was written by Toyokazu Tomatsu as part of [Pnuts](http://en.wikipedia.org/wiki/Pnuts). TableLayout was originally inspired by PnutsLayout. 338 | 339 | [UIHierarch](https://web.archive.org/web/20200216023713/http://chrriis.free.fr/projects/uihierarchy/index.html) was also inspired by PnutsLayout. It is interesting because it is not actually a layout manager, instead it uses a combination of method chaining and constraint strings to more cleanly create UI hierarchies and configure layout parameters. 340 | 341 | [RiverLayout](https://github.com/Deses/RiverLayout) uses tags in constraint strings. 342 | _[Orignal webpage](http://www.datadosen.se/riverlayout/) is no longer available._ 343 | 344 | [FormLayout](https://www.jgoodies.com/freeware/libraries/forms/) is similar to RiverLayout, but more sophisticated. 345 | 346 | [MIGLayout](http://www.miglayout.com/) is even more sophisticated than FormLayout. It attempts to support many kinds of layouts beyond tables and has a somewhat bloated number of features. It has a complex constraint language. It can layout using a grid, border, absolute, etc. 347 | 348 | [DesignGridLayout](https://web.archive.org/web/20070728043408/https://designgridlayout.dev.java.net/)) uses canonical grids. For the most part, widgets are simply added and the ideal table is determined automatically. This cuts down the needed Java code to a minimum and enforces UI guidelines. The downside is that DesignGridLayout does not handle arbitrary table layouts. If a UI problem can be handled using a canonical grid, DesignGridLayout is the most elegant solution. If you want to deviate from a canonical grid, you have no recourse. 349 | 350 | [PanelMatic](https://github.com/codeworth-gh/PanelMatic) both a layout and a simple UI builder mostly on the page axis. The fluent builder allows to add text fields or components. 351 | 352 | [Sliding Layout](https://github.com/AurelienRibon/sliding-layout) is an interesting layout that allows to reposition components, it works with an interpolation library to animate the changes. 353 | 354 | [Slick Layout](https://github.com/jpxor/slick) is a row- and constraint-based layout, where various constraints are created when added to the container. Constraints can be alignment, vertical/horizontal, fill, or packed. 355 | 356 | [Better Layout](https://github.com/Osiris-Team/Better-Layout) is similar to MigLayout but uses a typed fluent builder API to add components and specify their constraints. 357 | 358 | Please feel free to submit additional libraries to be included in this section or suggest better descriptions. 359 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 8 | 9 | com.esotericsoftware 10 | tablelayout-parent 11 | 1.0-SNAPSHOT 12 | pom 13 | 14 | tablelayout-parent 15 | https://github.com/EsotericSoftware/tablelayout 16 | 17 | 18 | Table-based layout for Java UI toolkits: libgdx, Swing, Android, TWL 19 | 20 | 21 | 2011 22 | 23 | 24 | 25 | BSD 3-Clause "New" or "Revised" License 26 | https://api.github.com/licenses/bsd-3-clause 27 | repo 28 | 29 | 30 | 31 | 32 | 33 | NathanSweet 34 | Nathan Sweet 35 | http://esotericsoftware.com 36 | 37 | 38 | 39 | 40 | tablelayout 41 | tablelayout-swing 42 | tablelayout-twl 43 | tablelayout-android 44 | 45 | 46 | 47 | UTF-8 48 | 49 | 50 | 51 | src 52 | test 53 | 54 | -------------------------------------------------------------------------------- /tablelayout-android/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tablelayout-android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | tablelayout-android 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /tablelayout-android/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.source=1.8 8 | -------------------------------------------------------------------------------- /tablelayout-android/lib/android-2.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/tablelayout/9ded474db7a6fc1fd8ffe8058f78c0b92f1e5776/tablelayout-android/lib/android-2.0.jar -------------------------------------------------------------------------------- /tablelayout-android/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.esotericsoftware 7 | tablelayout-parent 8 | 1.0-SNAPSHOT 9 | ../ 10 | 11 | 12 | tablelayout-android 13 | 14 | tablelayout-android 15 | 16 | 17 | 18 | ${project.groupId} 19 | tablelayout 20 | ${project.version} 21 | 22 | 23 | 24 | com.google.android 25 | android 26 | 2.0 27 | system 28 | ${project.basedir}/lib/android-2.0.jar 29 | 30 | 31 | -------------------------------------------------------------------------------- /tablelayout-android/project.yaml: -------------------------------------------------------------------------------- 1 | source: 2 | - src|**/*.java 3 | - ../tablelayout/src|**/*.java 4 | -------------------------------------------------------------------------------- /tablelayout-android/src/com/esotericsoftware/tablelayout/android/AndroidToolkit.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.android; 3 | 4 | import java.lang.reflect.Constructor; 5 | import java.lang.reflect.Field; 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | 10 | import android.R; 11 | import android.app.Activity; 12 | import android.content.Context; 13 | import android.graphics.Color; 14 | import android.graphics.Paint; 15 | import android.graphics.Rect; 16 | import android.graphics.drawable.Drawable; 17 | import android.graphics.drawable.StateListDrawable; 18 | import android.util.DisplayMetrics; 19 | import android.view.View; 20 | import android.view.ViewGroup; 21 | import android.widget.Button; 22 | import android.widget.FrameLayout; 23 | import android.widget.ImageView; 24 | import android.widget.ImageView.ScaleType; 25 | import android.widget.TextView; 26 | 27 | import com.esotericsoftware.tablelayout.BaseTableLayout.Debug; 28 | import com.esotericsoftware.tablelayout.Cell; 29 | import com.esotericsoftware.tablelayout.Toolkit; 30 | 31 | public class AndroidToolkit extends Toolkit { 32 | static public Context context; 33 | static public float density = 1; 34 | 35 | static final HashMap drawableToID = new HashMap(); 36 | static Paint paint; 37 | 38 | public Cell obtainCell (TableLayout layout) { 39 | Cell cell = new Cell(); 40 | cell.setLayout(layout); 41 | return cell; 42 | } 43 | 44 | public void freeCell (Cell cell) { 45 | } 46 | 47 | public void setWidget (TableLayout layout, Cell cell, View widget) { 48 | super.setWidget(layout, cell, widget); 49 | layout.otherChildren.remove(widget); 50 | } 51 | 52 | public void clearDebugRectangles (TableLayout layout) { 53 | if (layout.debugRects != null) layout.debugRects.clear(); 54 | } 55 | 56 | public void addDebugRectangle (TableLayout layout, Debug type, float x, float y, float w, float h) { 57 | if (layout.debugRects == null) layout.debugRects = new ArrayList(); 58 | layout.debugRects.add(new DebugRect(type, (int)x, (int)y, (int)w, (int)h)); 59 | } 60 | 61 | public float width (float value) { 62 | return (int)(value * density); 63 | } 64 | 65 | public float height (float value) { 66 | return (int)(value * density); 67 | } 68 | 69 | public void addChild (View parent, View child) { 70 | ((ViewGroup)parent).addView(child); 71 | } 72 | 73 | public void removeChild (View parent, View child) { 74 | ((ViewGroup)parent).removeView(child); 75 | } 76 | 77 | public float getMinWidth (View view) { 78 | return view.getMeasuredWidth(); 79 | } 80 | 81 | public float getMinHeight (View view) { 82 | return view.getMeasuredHeight(); 83 | } 84 | 85 | public float getPrefWidth (View view) { 86 | return view.getMeasuredWidth(); 87 | } 88 | 89 | public float getPrefHeight (View view) { 90 | return view.getMeasuredHeight(); 91 | } 92 | 93 | public float getMaxWidth (View view) { 94 | return 0; 95 | } 96 | 97 | public float getMaxHeight (View view) { 98 | return 0; 99 | } 100 | 101 | public float getWidth (View view) { 102 | return view.getWidth(); 103 | } 104 | 105 | public float getHeight (View view) { 106 | return view.getHeight(); 107 | } 108 | 109 | static Paint getDebugPaint () { 110 | if (paint == null) { 111 | paint = new Paint(); 112 | paint.setStyle(Paint.Style.STROKE); 113 | paint.setStrokeWidth(1); 114 | } 115 | return paint; 116 | } 117 | 118 | static public void setup (Activity activity, Class drawableClass) { 119 | context = activity; 120 | // if (!drawableClass.getName().endsWith(".R$drawable")) 121 | // throw new RuntimeException("The drawable class must be R.drawable: " + drawableClass); 122 | 123 | // DisplayMetrics metrics = new DisplayMetrics(); 124 | // activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); 125 | // density = metrics.density; 126 | 127 | drawableToID.clear(); 128 | Field[] fields = drawableClass.getFields(); 129 | for (int i = 0, n = fields.length; i < n; i++) { 130 | Field field = fields[i]; 131 | try { 132 | drawableToID.put(field.getName(), field.getInt(null)); 133 | } catch (Exception ex) { 134 | throw new RuntimeException("Error getting drawable field value: " + field, ex); 135 | } 136 | } 137 | } 138 | 139 | static public boolean setBackground (View view, String name, String value) { 140 | if (name.equals("bg")) { 141 | view.setBackgroundDrawable(getDrawable(value)); 142 | return true; 143 | } 144 | 145 | if (name.equals("normal")) { 146 | setBackgroundState(view, 0, value); 147 | return true; 148 | } 149 | 150 | if (name.equals("pressed")) { 151 | setBackgroundState(view, R.attr.state_pressed, value); 152 | return true; 153 | } 154 | 155 | if (name.equals("focused")) { 156 | setBackgroundState(view, R.attr.state_focused, value); 157 | return true; 158 | } 159 | 160 | return false; 161 | } 162 | 163 | static public void setBackgroundState (View view, int state, String value) { 164 | Drawable background = view.getBackground(); 165 | StateListDrawable states; 166 | if (background instanceof CustomizedStateListDrawable) 167 | states = (StateListDrawable)background; 168 | else { 169 | states = new CustomizedStateListDrawable(); 170 | view.setBackgroundDrawable(states); 171 | } 172 | states.addState(new int[] {state}, getDrawable(value)); 173 | } 174 | 175 | static public int getDrawableID (String name) { 176 | Integer id = drawableToID.get(name); 177 | if (id == null) return 0; 178 | return id; 179 | } 180 | 181 | static public Drawable getDrawable (String name) { 182 | Integer id = drawableToID.get(name); 183 | if (id == null) throw new IllegalArgumentException("Unknown drawable name: " + name); 184 | return context.getResources().getDrawable(id); 185 | } 186 | 187 | static public ImageView getImageView (String name) { 188 | Integer id = drawableToID.get(name); 189 | if (id != null) return getImageView(id); 190 | return null; 191 | } 192 | 193 | static public ImageView getImageView (int id) { 194 | ImageView view = new ImageView(context); 195 | view.setScaleType(ScaleType.FIT_XY); 196 | view.setImageResource(id); 197 | return view; 198 | } 199 | 200 | static public boolean setCompoundDrawable (TextView view, String name, String value) { 201 | if (name.equals("left")) { 202 | Drawable[] drawables = view.getCompoundDrawables(); 203 | view.setCompoundDrawablesWithIntrinsicBounds(getDrawable(value), drawables[1], drawables[2], drawables[3]); 204 | return true; 205 | } 206 | 207 | if (name.equals("top")) { 208 | Drawable[] drawables = view.getCompoundDrawables(); 209 | view.setCompoundDrawablesWithIntrinsicBounds(drawables[0], getDrawable(value), drawables[2], drawables[3]); 210 | return true; 211 | } 212 | 213 | if (name.equals("right")) { 214 | Drawable[] drawables = view.getCompoundDrawables(); 215 | view.setCompoundDrawablesWithIntrinsicBounds(drawables[0], drawables[1], getDrawable(value), drawables[3]); 216 | return true; 217 | } 218 | 219 | if (name.equals("bottom")) { 220 | Drawable[] drawables = view.getCompoundDrawables(); 221 | view.setCompoundDrawablesWithIntrinsicBounds(drawables[0], drawables[1], drawables[2], getDrawable(value)); 222 | return true; 223 | } 224 | 225 | return false; 226 | } 227 | 228 | /** Marker class to know when the background is no longer the default. */ 229 | static class CustomizedStateListDrawable extends StateListDrawable { 230 | } 231 | 232 | static public class DebugRect { 233 | final Debug type; 234 | final Rect rect; 235 | 236 | public DebugRect (Debug type, int x, int y, int width, int height) { 237 | rect = new Rect(x, y, x + width - 1, y + height - 1); 238 | this.type = type; 239 | } 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /tablelayout-android/src/com/esotericsoftware/tablelayout/android/Stack.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.android; 3 | 4 | import android.content.Context; 5 | import android.widget.FrameLayout; 6 | 7 | public class Stack extends FrameLayout { 8 | public Stack (Context context) { 9 | super(context); 10 | } 11 | 12 | protected void onLayout (boolean changed, int left, int top, int right, int bottom) { 13 | int width = right - left; 14 | int height = bottom - top; 15 | for (int i = 0, n = getChildCount(); i < n; i++) 16 | getChildAt(i).layout(0, 0, width, height); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tablelayout-android/src/com/esotericsoftware/tablelayout/android/Table.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.android; 3 | 4 | import java.util.List; 5 | 6 | import com.esotericsoftware.tablelayout.BaseTableLayout.Debug; 7 | import com.esotericsoftware.tablelayout.BaseTableLayout; 8 | import com.esotericsoftware.tablelayout.Cell; 9 | import com.esotericsoftware.tablelayout.Toolkit; 10 | import com.esotericsoftware.tablelayout.Value; 11 | 12 | import android.graphics.Canvas; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | 16 | public class Table extends ViewGroup { 17 | static { 18 | Toolkit.instance = new AndroidToolkit(); 19 | } 20 | 21 | static private final OnHierarchyChangeListener hierarchyChangeListener = new OnHierarchyChangeListener() { 22 | public void onChildViewAdded (View parent, View child) { 23 | ((Table)parent).layout.otherChildren.add(child); 24 | } 25 | 26 | public void onChildViewRemoved (View parent, View child) { 27 | ((Table)parent).layout.otherChildren.remove(child); 28 | } 29 | }; 30 | 31 | final TableLayout layout; 32 | private boolean sizeToBackground; 33 | 34 | public Table () { 35 | this(new TableLayout()); 36 | } 37 | 38 | public Table (TableLayout layout) { 39 | super(AndroidToolkit.context); 40 | this.layout = layout; 41 | layout.setTable(this); 42 | setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 43 | setOnHierarchyChangeListener(hierarchyChangeListener); 44 | } 45 | 46 | protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) { 47 | boolean widthUnspecified = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.UNSPECIFIED; 48 | boolean heightUnspecified = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED; 49 | 50 | measureChildren(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 51 | MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 52 | 53 | // Measure GONE children to 0x0. 54 | List cells = layout.getCells(); 55 | for (int i = 0, n = cells.size(); i < n; i++) { 56 | Cell c = cells.get(i); 57 | if (c.getIgnore()) continue; 58 | if (((View)c.getWidget()).getVisibility() == GONE) { 59 | ((View)c.getWidget()).measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY), 60 | MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY)); 61 | } 62 | } 63 | 64 | layout.layout(0, 0, // 65 | widthUnspecified ? 0 : MeasureSpec.getSize(widthMeasureSpec), // 66 | heightUnspecified ? 0 : MeasureSpec.getSize(heightMeasureSpec)); 67 | 68 | int measuredWidth = (int)(widthUnspecified ? layout.getMinWidth() : layout.getPrefWidth()); 69 | int measuredHeight = (int)(heightUnspecified ? layout.getMinHeight() : layout.getPrefHeight()); 70 | 71 | invalidate(); 72 | measuredWidth = Math.max(measuredWidth, getSuggestedMinimumWidth()); 73 | measuredHeight = Math.max(measuredHeight, getSuggestedMinimumHeight()); 74 | 75 | setMeasuredDimension(resolveSize(measuredWidth, widthMeasureSpec), resolveSize(measuredHeight, heightMeasureSpec)); 76 | } 77 | 78 | protected void onLayout (boolean changed, int left, int top, int right, int bottom) { 79 | layout.layout(0, 0, right - left, bottom - top); 80 | 81 | if (layout.getDebug() != Debug.none && layout.debugRects != null) { 82 | setWillNotDraw(false); 83 | invalidate(); 84 | } 85 | } 86 | 87 | public void requestLayout () { 88 | if (layout != null) layout.invalidateSuper(); 89 | super.requestLayout(); 90 | } 91 | 92 | protected int getSuggestedMinimumWidth () { 93 | int width = (int)layout.getMinWidth(); 94 | if (sizeToBackground && getBackground() != null) width = Math.max(width, getBackground().getMinimumWidth()); 95 | return width; 96 | } 97 | 98 | protected int getSuggestedMinimumHeight () { 99 | int height = (int)layout.getMinHeight(); 100 | if (sizeToBackground && getBackground() != null) height = Math.max(height, getBackground().getMinimumHeight()); 101 | return height; 102 | } 103 | 104 | protected void dispatchDraw (Canvas canvas) { 105 | super.dispatchDraw(canvas); 106 | layout.drawDebug(canvas); 107 | } 108 | 109 | public void setSizeToBackground (boolean sizeToBackground) { 110 | this.sizeToBackground = sizeToBackground; 111 | } 112 | 113 | /** Adds a new cell to the table with the specified widget. */ 114 | public Cell add (View widget) { 115 | return layout.add(widget); 116 | } 117 | 118 | /** Invalidates the layout. The cached min and pref sizes are recalculated the next time layout is done or the min or pref 119 | * sizes are accessed. */ 120 | // Should this be uncommented? 121 | // public void invalidate () { 122 | // super.invalidate(); 123 | // layout.invalidate(); 124 | // } 125 | 126 | /** Invalidates the layout of this table and every parent widget. */ 127 | public void invalidateHierarchy () { 128 | layout.invalidateHierarchy(); 129 | } 130 | 131 | /** Indicates that subsequent cells should be added to a new row and returns the cell values that will be used as the defaults 132 | * for all cells in the new row. */ 133 | public Cell row () { 134 | return layout.row(); 135 | } 136 | 137 | /** Gets the cell values that will be used as the defaults for all cells in the specified column. Columns are indexed starting 138 | * at 0. */ 139 | public Cell columnDefaults (int column) { 140 | return layout.columnDefaults(column); 141 | } 142 | 143 | /** Removes all widgets and cells from the table (same as {@link #clear()}) and additionally resets all table properties and 144 | * cell, column, and row defaults. */ 145 | public void reset () { 146 | layout.reset(); 147 | } 148 | 149 | /** Removes all widgets and cells from the table. */ 150 | public void clear () { 151 | layout.clear(); 152 | } 153 | 154 | /** Returns the cell for the specified widget in this table, or null. */ 155 | public Cell getCell (View widget) { 156 | return layout.getCell(widget); 157 | } 158 | 159 | /** Returns the cells for this table. */ 160 | public List getCells () { 161 | return layout.getCells(); 162 | } 163 | 164 | /** The minimum width of the table. */ 165 | public float getMinWidth () { 166 | return layout.getMinWidth(); 167 | } 168 | 169 | /** The minimum size of the table. */ 170 | public float getMinHeight () { 171 | return layout.getMinHeight(); 172 | } 173 | 174 | /** The preferred width of the table. */ 175 | public float getPrefWidth () { 176 | return layout.getPrefWidth(); 177 | } 178 | 179 | /** The preferred height of the table. */ 180 | public float getPrefHeight () { 181 | return layout.getPrefHeight(); 182 | } 183 | 184 | /** The cell values that will be used as the defaults for all cells. */ 185 | public Cell defaults () { 186 | return layout.defaults(); 187 | } 188 | 189 | /** Sets the padTop, padLeft, padBottom, and padRight around the table to the specified value. */ 190 | public Table pad (Value pad) { 191 | layout.pad(pad); 192 | return this; 193 | } 194 | 195 | public Table pad (Value top, Value left, Value bottom, Value right) { 196 | layout.pad(top, left, bottom, right); 197 | return this; 198 | } 199 | 200 | /** Padding at the top edge of the table. */ 201 | public Table padTop (Value padTop) { 202 | layout.padTop(padTop); 203 | return this; 204 | } 205 | 206 | /** Padding at the left edge of the table. */ 207 | public Table padLeft (Value padLeft) { 208 | layout.padLeft(padLeft); 209 | return this; 210 | } 211 | 212 | /** Padding at the bottom edge of the table. */ 213 | public Table padBottom (Value padBottom) { 214 | layout.padBottom(padBottom); 215 | return this; 216 | } 217 | 218 | /** Padding at the right edge of the table. */ 219 | public Table padRight (Value padRight) { 220 | layout.padRight(padRight); 221 | return this; 222 | } 223 | 224 | /** Sets the padTop, padLeft, padBottom, and padRight around the table to the specified value. */ 225 | public Table pad (float pad) { 226 | layout.pad(pad); 227 | return this; 228 | } 229 | 230 | public Table pad (float top, float left, float bottom, float right) { 231 | layout.pad(top, left, bottom, right); 232 | return this; 233 | } 234 | 235 | /** Padding at the top edge of the table. */ 236 | public Table padTop (float padTop) { 237 | layout.padTop(padTop); 238 | return this; 239 | } 240 | 241 | /** Padding at the left edge of the table. */ 242 | public Table padLeft (float padLeft) { 243 | layout.padLeft(padLeft); 244 | return this; 245 | } 246 | 247 | /** Padding at the bottom edge of the table. */ 248 | public Table padBottom (float padBottom) { 249 | layout.padBottom(padBottom); 250 | return this; 251 | } 252 | 253 | /** Padding at the right edge of the table. */ 254 | public Table padRight (float padRight) { 255 | layout.padRight(padRight); 256 | return this; 257 | } 258 | 259 | /** Alignment of the logical table within the table widget. Set to {@link BaseTableLayout#CENTER}, {@link BaseTableLayout#TOP}, 260 | * {@link BaseTableLayout#BOTTOM} , {@link BaseTableLayout#LEFT}, {@link BaseTableLayout#RIGHT}, or any combination of 261 | * those. */ 262 | public Table align (int align) { 263 | layout.align(align); 264 | return this; 265 | } 266 | 267 | /** Sets the alignment of the logical table within the table widget to {@link BaseTableLayout#CENTER}. This clears any other 268 | * alignment. */ 269 | public Table center () { 270 | layout.center(); 271 | return this; 272 | } 273 | 274 | /** Adds {@link BaseTableLayout#TOP} and clears {@link BaseTableLayout#BOTTOM} for the alignment of the logical table within 275 | * the table widget. */ 276 | public Table top () { 277 | layout.top(); 278 | return this; 279 | } 280 | 281 | /** Adds {@link BaseTableLayout#LEFT} and clears {@link BaseTableLayout#RIGHT} for the alignment of the logical table within 282 | * the table widget. */ 283 | public Table left () { 284 | layout.left(); 285 | return this; 286 | } 287 | 288 | /** Adds {@link BaseTableLayout#BOTTOM} and clears {@link BaseTableLayout#TOP} for the alignment of the logical table within 289 | * the table widget. */ 290 | public Table bottom () { 291 | layout.bottom(); 292 | return this; 293 | } 294 | 295 | /** Adds {@link BaseTableLayout#RIGHT} and clears {@link BaseTableLayout#LEFT} for the alignment of the logical table within 296 | * the table widget. */ 297 | public Table right () { 298 | layout.right(); 299 | return this; 300 | } 301 | 302 | /** Turns on all debug lines. */ 303 | public Table debug () { 304 | layout.debug(); 305 | return this; 306 | } 307 | 308 | /** Turns on table debug lines. */ 309 | public Table debugTable () { 310 | layout.debugTable(); 311 | return this; 312 | } 313 | 314 | /** Turns on cell debug lines. */ 315 | public Table debugCell () { 316 | layout.debugCell(); 317 | return this; 318 | } 319 | 320 | /** Turns on widget debug lines. */ 321 | public Table debugWidget () { 322 | layout.debugWidget(); 323 | return this; 324 | } 325 | 326 | /** Turns on debug lines. */ 327 | public Table debug (Debug debug) { 328 | layout.debug(debug); 329 | return this; 330 | } 331 | 332 | public Debug getDebug () { 333 | return layout.getDebug(); 334 | } 335 | 336 | public Value getPadTopValue () { 337 | return layout.getPadTopValue(); 338 | } 339 | 340 | public float getPadTop () { 341 | return layout.getPadTop(); 342 | } 343 | 344 | public Value getPadLeftValue () { 345 | return layout.getPadLeftValue(); 346 | } 347 | 348 | public float getPadLeft () { 349 | return layout.getPadLeft(); 350 | } 351 | 352 | public Value getPadBottomValue () { 353 | return layout.getPadBottomValue(); 354 | } 355 | 356 | public float getPadBottom () { 357 | return layout.getPadBottom(); 358 | } 359 | 360 | public Value getPadRightValue () { 361 | return layout.getPadRightValue(); 362 | } 363 | 364 | public float getPadRight () { 365 | return layout.getPadRight(); 366 | } 367 | 368 | public int getAlign () { 369 | return layout.getAlign(); 370 | } 371 | 372 | /** Returns the row index for the y coordinate, or -1 if there are no cells. */ 373 | public int getRow (float y) { 374 | return layout.getRow(y); 375 | } 376 | 377 | public BaseTableLayout getTableLayout () { 378 | return layout; 379 | } 380 | } 381 | -------------------------------------------------------------------------------- /tablelayout-android/src/com/esotericsoftware/tablelayout/android/TableLayout.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.android; 3 | 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | import android.graphics.Canvas; 8 | import android.graphics.Color; 9 | import android.graphics.Paint; 10 | import android.view.View; 11 | 12 | import com.esotericsoftware.tablelayout.BaseTableLayout; 13 | import com.esotericsoftware.tablelayout.Cell; 14 | import com.esotericsoftware.tablelayout.android.AndroidToolkit.DebugRect; 15 | 16 | class TableLayout extends BaseTableLayout { 17 | ArrayList otherChildren = new ArrayList(1); 18 | ArrayList debugRects; 19 | 20 | public TableLayout () { 21 | super((AndroidToolkit)AndroidToolkit.instance); 22 | } 23 | 24 | public TableLayout (AndroidToolkit toolkit) { 25 | super(toolkit); 26 | } 27 | 28 | public Cell add (View widget) { 29 | Cell cell = super.add(widget); 30 | otherChildren.remove(widget); 31 | return cell; 32 | } 33 | 34 | public void layout (float layoutX, float layoutY, float layoutWidth, float layoutHeight) { 35 | List cells = getCells(); 36 | for (int i = 0, n = cells.size(); i < n; i++) { 37 | Cell c = cells.get(i); 38 | if (c.getIgnore()) continue; 39 | ((View)c.getWidget()).layout((int)c.getWidgetX(), (int)c.getWidgetY(), // 40 | (int)(c.getWidgetX() + c.getWidgetWidth()), // 41 | (int)(c.getWidgetY() + c.getWidgetHeight())); 42 | } 43 | 44 | super.layout(layoutX, layoutY, layoutWidth, layoutHeight); 45 | 46 | for (int i = 0, n = cells.size(); i < n; i++) { 47 | Cell c = cells.get(i); 48 | if (c.getIgnore()) continue; 49 | ((View)c.getWidget()).layout((int)c.getWidgetX(), (int)c.getWidgetY(), // 50 | (int)(c.getWidgetX() + c.getWidgetWidth()), // 51 | (int)(c.getWidgetY() + c.getWidgetHeight())); 52 | } 53 | 54 | for (int i = 0, n = otherChildren.size(); i < n; i++) { 55 | View child = otherChildren.get(i); 56 | child.layout(0, 0, (int)layoutWidth, (int)layoutHeight); 57 | } 58 | } 59 | 60 | void invalidateSuper () { 61 | super.invalidate(); 62 | } 63 | 64 | public void invalidate () { 65 | super.invalidate(); 66 | getTable().requestLayout(); 67 | } 68 | 69 | public void invalidateHierarchy () { 70 | super.invalidate(); 71 | getTable().requestLayout(); 72 | } 73 | 74 | public void drawDebug (Canvas canvas) { 75 | if (getDebug() == Debug.none || debugRects == null) return; 76 | Paint paint = AndroidToolkit.getDebugPaint(); 77 | for (int i = 0, n = debugRects.size(); i < n; i++) { 78 | DebugRect rect = debugRects.get(i); 79 | int r = rect.type == Debug.cell ? 255 : 0; 80 | int g = rect.type == Debug.widget ? 255 : 0; 81 | int b = rect.type == Debug.table ? 255 : 0; 82 | paint.setColor(Color.argb(255, r, g, b)); 83 | canvas.drawRect(rect.rect, paint); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /tablelayout-swing/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tablelayout-swing/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | tablelayout-swing 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /tablelayout-swing/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.esotericsoftware 7 | tablelayout-parent 8 | 1.0-SNAPSHOT 9 | ../ 10 | 11 | 12 | tablelayout-swing 13 | 14 | tablelayout-swing 15 | 16 | 17 | 18 | ${project.groupId} 19 | tablelayout 20 | ${project.version} 21 | 22 | 23 | -------------------------------------------------------------------------------- /tablelayout-swing/project.yaml: -------------------------------------------------------------------------------- 1 | source: 2 | - src|**/*.java 3 | - ../tablelayout/src|**/*.java 4 | --- 5 | Build.build(project); 6 | Build.oneJAR(project); -------------------------------------------------------------------------------- /tablelayout-swing/src/com/esotericsoftware/tablelayout/swing/Stack.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.swing; 3 | 4 | import java.awt.Component; 5 | import java.awt.Container; 6 | import java.awt.Dimension; 7 | import java.awt.Graphics; 8 | import java.awt.LayoutManager; 9 | 10 | import javax.swing.JPanel; 11 | 12 | public class Stack extends JPanel { 13 | public Stack () { 14 | super(new LayoutManager() { 15 | public void layoutContainer (Container parent) { 16 | int width = parent.getWidth(); 17 | int height = parent.getHeight(); 18 | for (int i = 0, n = parent.getComponentCount(); i < n; i++) { 19 | parent.getComponent(i).setLocation(0, 0); 20 | parent.getComponent(i).setSize(width, height); 21 | } 22 | } 23 | 24 | public Dimension preferredLayoutSize (Container parent) { 25 | Dimension size = new Dimension(); 26 | for (int i = 0, n = parent.getComponentCount(); i < n; i++) { 27 | Dimension pref = parent.getComponent(i).getPreferredSize(); 28 | size.width = Math.max(size.width, pref.width); 29 | size.height = Math.max(size.height, pref.height); 30 | } 31 | return size; 32 | } 33 | 34 | public Dimension minimumLayoutSize (Container parent) { 35 | Dimension size = new Dimension(); 36 | for (int i = 0, n = parent.getComponentCount(); i < n; i++) { 37 | Dimension min = parent.getComponent(i).getMinimumSize(); 38 | size.width = Math.max(size.width, min.width); 39 | size.height = Math.max(size.height, min.height); 40 | } 41 | return size; 42 | } 43 | 44 | public void addLayoutComponent (String name, Component comp) { 45 | } 46 | 47 | public void removeLayoutComponent (Component comp) { 48 | } 49 | }); 50 | } 51 | 52 | protected void paintChildren (Graphics g) { 53 | super.paintChildren(g); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tablelayout-swing/src/com/esotericsoftware/tablelayout/swing/SwingToolkit.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.swing; 3 | 4 | import com.esotericsoftware.tablelayout.BaseTableLayout.Debug; 5 | import com.esotericsoftware.tablelayout.Cell; 6 | import com.esotericsoftware.tablelayout.Toolkit; 7 | 8 | import java.awt.Component; 9 | import java.awt.Container; 10 | import java.awt.EventQueue; 11 | import java.util.ArrayList; 12 | import java.util.Timer; 13 | import java.util.TimerTask; 14 | 15 | import javax.swing.JScrollPane; 16 | 17 | class SwingToolkit extends Toolkit { 18 | static Timer timer; 19 | static ArrayList debugLayouts = new ArrayList(0); 20 | 21 | public Cell obtainCell (TableLayout layout) { 22 | Cell cell = new Cell(); 23 | cell.setLayout(layout); 24 | return cell; 25 | } 26 | 27 | public void freeCell (Cell cell) { 28 | } 29 | 30 | public void addChild (Component parent, Component child) { 31 | if (parent instanceof JScrollPane) 32 | ((JScrollPane)parent).setViewportView(child); 33 | else 34 | ((Container)parent).add(child); 35 | } 36 | 37 | public void removeChild (Component parent, Component child) { 38 | ((Container)parent).remove(child); 39 | } 40 | 41 | public float getMinWidth (Component widget) { 42 | return widget.getMinimumSize().width; 43 | } 44 | 45 | public float getMinHeight (Component widget) { 46 | return widget.getMinimumSize().height; 47 | } 48 | 49 | public float getPrefWidth (Component widget) { 50 | return widget.getPreferredSize().width; 51 | } 52 | 53 | public float getPrefHeight (Component widget) { 54 | return widget.getPreferredSize().height; 55 | } 56 | 57 | public float getMaxWidth (Component widget) { 58 | return widget.getMaximumSize().width; 59 | } 60 | 61 | public float getMaxHeight (Component widget) { 62 | return widget.getMaximumSize().height; 63 | } 64 | 65 | public float getWidth (Component widget) { 66 | return widget.getWidth(); 67 | } 68 | 69 | public float getHeight (Component widget) { 70 | return widget.getHeight(); 71 | } 72 | 73 | public void clearDebugRectangles (TableLayout layout) { 74 | if (layout.debugRects != null) debugLayouts.remove(layout); 75 | layout.debugRects = null; 76 | } 77 | 78 | public void addDebugRectangle (TableLayout layout, Debug type, float x, float y, float w, float h) { 79 | if (layout.debugRects == null) { 80 | layout.debugRects = new ArrayList(); 81 | debugLayouts.add(layout); 82 | } 83 | layout.debugRects.add(new DebugRect(type, x, y, w, h)); 84 | } 85 | 86 | static void startDebugTimer () { 87 | if (timer != null) return; 88 | timer = new Timer("TableLayout Debug", true); 89 | timer.schedule(newDebugTask(), 100); 90 | } 91 | 92 | static TimerTask newDebugTask () { 93 | return new TimerTask() { 94 | public void run () { 95 | if (!EventQueue.isDispatchThread()) { 96 | EventQueue.invokeLater(this); 97 | return; 98 | } 99 | for (TableLayout layout : debugLayouts) 100 | layout.drawDebug(); 101 | timer.schedule(newDebugTask(), 250); 102 | } 103 | }; 104 | } 105 | 106 | static class DebugRect { 107 | final Debug type; 108 | final int x, y, width, height; 109 | 110 | public DebugRect (Debug type, float x, float y, float width, float height) { 111 | this.x = (int)x; 112 | this.y = (int)y; 113 | this.width = (int)(width - 1); 114 | this.height = (int)(height - 1); 115 | this.type = type; 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /tablelayout-swing/src/com/esotericsoftware/tablelayout/swing/Table.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.swing; 3 | 4 | import java.util.List; 5 | 6 | import javax.swing.JComponent; 7 | import javax.swing.JLabel; 8 | 9 | import com.esotericsoftware.tablelayout.BaseTableLayout; 10 | import com.esotericsoftware.tablelayout.BaseTableLayout.Debug; 11 | import com.esotericsoftware.tablelayout.Cell; 12 | import com.esotericsoftware.tablelayout.Toolkit; 13 | import com.esotericsoftware.tablelayout.Value; 14 | 15 | import java.awt.Component; 16 | import java.awt.Container; 17 | import java.awt.Dimension; 18 | import java.awt.LayoutManager; 19 | 20 | public class Table extends JComponent { 21 | static { 22 | Toolkit.instance = new SwingToolkit(); 23 | } 24 | 25 | private final TableLayout layout; 26 | 27 | public Table () { 28 | this(new TableLayout()); 29 | } 30 | 31 | public Table (final TableLayout layout) { 32 | this.layout = layout; 33 | layout.setTable(this); 34 | 35 | setLayout(new LayoutManager() { 36 | private Dimension minSize = new Dimension(), prefSize = new Dimension(); 37 | 38 | public Dimension preferredLayoutSize (Container parent) { 39 | layout.layout(); // BOZO - Cache layout? 40 | prefSize.width = (int)layout.getMinWidth(); 41 | prefSize.height = (int)layout.getMinHeight(); 42 | return prefSize; 43 | } 44 | 45 | public Dimension minimumLayoutSize (Container parent) { 46 | layout.layout(); // BOZO - Cache layout? 47 | minSize.width = (int)layout.getMinWidth(); 48 | minSize.height = (int)layout.getMinHeight(); 49 | return minSize; 50 | } 51 | 52 | public void layoutContainer (Container ignored) { 53 | layout.layout(); 54 | } 55 | 56 | public void addLayoutComponent (String name, Component comp) { 57 | } 58 | 59 | public void removeLayoutComponent (Component comp) { 60 | } 61 | }); 62 | } 63 | 64 | /** Adds a new cell to the table with the specified Components in a {@link Stack}. 65 | * @param components May be null to add a cell without an Component. */ 66 | public Cell stack (Component... components) { 67 | Stack stack = new Stack(); 68 | for (int i = 0, n = components.length; i < n; i++) 69 | stack.add(components[i]); 70 | return addCell(stack); 71 | } 72 | 73 | /** Positions and sizes children of the Component being laid out using the cell associated with each child. 74 | * @see TableLayout#layout() */ 75 | public void layout () { 76 | layout.layout(); 77 | } 78 | 79 | public Cell addCell (String text) { 80 | return addCell(new JLabel(text)); 81 | } 82 | 83 | /** Adds a cell with a placeholder Component. */ 84 | public Cell addCell () { 85 | return addCell((Component)null); 86 | } 87 | 88 | /** Adds a new cell to the table with the specified Component. 89 | * @see TableLayout#add(Component) 90 | * @param Component May be null to add a cell without an Component. */ 91 | public Cell addCell (Component Component) { 92 | return layout.add(Component); 93 | } 94 | 95 | /** Invalidates the layout. The cached min and pref sizes are recalculated the next time layout is done or the min or pref 96 | * sizes are accessed. */ 97 | public void invalidate () { 98 | super.invalidate(); 99 | layout.invalidate(); 100 | } 101 | 102 | /** Invalidates the layout of this table and every parent widget. */ 103 | public void invalidateHierarchy () { 104 | layout.invalidateHierarchy(); 105 | } 106 | 107 | /** Indicates that subsequent cells should be added to a new row and returns the cell values that will be used as the defaults 108 | * for all cells in the new row. */ 109 | public Cell row () { 110 | return layout.row(); 111 | } 112 | 113 | /** Gets the cell values that will be used as the defaults for all cells in the specified column. Columns are indexed starting 114 | * at 0. */ 115 | public Cell columnDefaults (int column) { 116 | return layout.columnDefaults(column); 117 | } 118 | 119 | /** Removes all widgets and cells from the table (same as {@link #clear()}) and additionally resets all table properties and 120 | * cell, column, and row defaults. */ 121 | public void reset () { 122 | layout.reset(); 123 | } 124 | 125 | /** Removes all widgets and cells from the table. */ 126 | public void clear () { 127 | layout.clear(); 128 | invalidate(); 129 | } 130 | 131 | /** Returns the cell for the specified widget in this table, or null. */ 132 | public Cell getCell (Component widget) { 133 | return layout.getCell(widget); 134 | } 135 | 136 | /** Returns the cells for this table. */ 137 | public List getCells () { 138 | return layout.getCells(); 139 | } 140 | 141 | /** The minimum width of the table. */ 142 | public float getMinWidth () { 143 | return layout.getMinWidth(); 144 | } 145 | 146 | /** The minimum size of the table. */ 147 | public float getMinHeight () { 148 | return layout.getMinHeight(); 149 | } 150 | 151 | /** The preferred width of the table. */ 152 | public float getPrefWidth () { 153 | return layout.getPrefWidth(); 154 | } 155 | 156 | /** The preferred height of the table. */ 157 | public float getPrefHeight () { 158 | return layout.getPrefHeight(); 159 | } 160 | 161 | /** The cell values that will be used as the defaults for all cells. */ 162 | public Cell defaults () { 163 | return layout.defaults(); 164 | } 165 | 166 | /** Sets the padTop, padLeft, padBottom, and padRight around the table to the specified value. */ 167 | public Table pad (Value pad) { 168 | layout.pad(pad); 169 | return this; 170 | } 171 | 172 | public Table pad (Value top, Value left, Value bottom, Value right) { 173 | layout.pad(top, left, bottom, right); 174 | return this; 175 | } 176 | 177 | /** Padding at the top edge of the table. */ 178 | public Table padTop (Value padTop) { 179 | layout.padTop(padTop); 180 | return this; 181 | } 182 | 183 | /** Padding at the left edge of the table. */ 184 | public Table padLeft (Value padLeft) { 185 | layout.padLeft(padLeft); 186 | return this; 187 | } 188 | 189 | /** Padding at the bottom edge of the table. */ 190 | public Table padBottom (Value padBottom) { 191 | layout.padBottom(padBottom); 192 | return this; 193 | } 194 | 195 | /** Padding at the right edge of the table. */ 196 | public Table padRight (Value padRight) { 197 | layout.padRight(padRight); 198 | return this; 199 | } 200 | 201 | /** Sets the padTop, padLeft, padBottom, and padRight around the table to the specified value. */ 202 | public Table pad (float pad) { 203 | layout.pad(pad); 204 | return this; 205 | } 206 | 207 | public Table pad (float top, float left, float bottom, float right) { 208 | layout.pad(top, left, bottom, right); 209 | return this; 210 | } 211 | 212 | /** Padding at the top edge of the table. */ 213 | public Table padTop (float padTop) { 214 | layout.padTop(padTop); 215 | return this; 216 | } 217 | 218 | /** Padding at the left edge of the table. */ 219 | public Table padLeft (float padLeft) { 220 | layout.padLeft(padLeft); 221 | return this; 222 | } 223 | 224 | /** Padding at the bottom edge of the table. */ 225 | public Table padBottom (float padBottom) { 226 | layout.padBottom(padBottom); 227 | return this; 228 | } 229 | 230 | /** Padding at the right edge of the table. */ 231 | public Table padRight (float padRight) { 232 | layout.padRight(padRight); 233 | return this; 234 | } 235 | 236 | /** Alignment of the logical table within the table widget. Set to {@link BaseTableLayout#CENTER}, {@link BaseTableLayout#TOP}, 237 | * {@link BaseTableLayout#BOTTOM} , {@link BaseTableLayout#LEFT}, {@link BaseTableLayout#RIGHT}, or any combination of 238 | * those. */ 239 | public Table align (int align) { 240 | layout.align(align); 241 | return this; 242 | } 243 | 244 | /** Sets the alignment of the logical table within the table widget to {@link BaseTableLayout#CENTER}. This clears any other 245 | * alignment. */ 246 | public Table center () { 247 | layout.center(); 248 | return this; 249 | } 250 | 251 | /** Adds {@link BaseTableLayout#TOP} and clears {@link BaseTableLayout#BOTTOM} for the alignment of the logical table within 252 | * the table widget. */ 253 | public Table top () { 254 | layout.top(); 255 | return this; 256 | } 257 | 258 | /** Adds {@link BaseTableLayout#LEFT} and clears {@link BaseTableLayout#RIGHT} for the alignment of the logical table within 259 | * the table widget. */ 260 | public Table left () { 261 | layout.left(); 262 | return this; 263 | } 264 | 265 | /** Adds {@link BaseTableLayout#BOTTOM} and clears {@link BaseTableLayout#TOP} for the alignment of the logical table within 266 | * the table widget. */ 267 | public Table bottom () { 268 | layout.bottom(); 269 | return this; 270 | } 271 | 272 | /** Adds {@link BaseTableLayout#RIGHT} and clears {@link BaseTableLayout#LEFT} for the alignment of the logical table within 273 | * the table widget. */ 274 | public Table right () { 275 | layout.right(); 276 | return this; 277 | } 278 | 279 | /** Turns on all debug lines. */ 280 | public Table debug () { 281 | layout.debug(); 282 | return this; 283 | } 284 | 285 | /** Turns on table debug lines. */ 286 | public Table debugTable () { 287 | layout.debugTable(); 288 | return this; 289 | } 290 | 291 | /** Turns on cell debug lines. */ 292 | public Table debugCell () { 293 | layout.debugCell(); 294 | return this; 295 | } 296 | 297 | /** Turns on widget debug lines. */ 298 | public Table debugWidget () { 299 | layout.debugWidget(); 300 | return this; 301 | } 302 | 303 | /** Turns on debug lines. */ 304 | public Table debug (Debug debug) { 305 | layout.debug(debug); 306 | return this; 307 | } 308 | 309 | public Debug getDebug () { 310 | return layout.getDebug(); 311 | } 312 | 313 | public Value getPadTopValue () { 314 | return layout.getPadTopValue(); 315 | } 316 | 317 | public float getPadTop () { 318 | return layout.getPadTop(); 319 | } 320 | 321 | public Value getPadLeftValue () { 322 | return layout.getPadLeftValue(); 323 | } 324 | 325 | public float getPadLeft () { 326 | return layout.getPadLeft(); 327 | } 328 | 329 | public Value getPadBottomValue () { 330 | return layout.getPadBottomValue(); 331 | } 332 | 333 | public float getPadBottom () { 334 | return layout.getPadBottom(); 335 | } 336 | 337 | public Value getPadRightValue () { 338 | return layout.getPadRightValue(); 339 | } 340 | 341 | public float getPadRight () { 342 | return layout.getPadRight(); 343 | } 344 | 345 | public int getAlign () { 346 | return layout.getAlign(); 347 | } 348 | 349 | /** Returns the row index for the y coordinate, or -1 if there are no cells. */ 350 | public int getRow (float y) { 351 | return layout.getRow(y); 352 | } 353 | 354 | public BaseTableLayout getTableLayout () { 355 | return layout; 356 | } 357 | } 358 | -------------------------------------------------------------------------------- /tablelayout-swing/src/com/esotericsoftware/tablelayout/swing/TableLayout.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.swing; 3 | 4 | import java.awt.Color; 5 | import java.awt.Component; 6 | import java.awt.Graphics2D; 7 | import java.awt.Insets; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import com.esotericsoftware.tablelayout.BaseTableLayout; 12 | import com.esotericsoftware.tablelayout.Cell; 13 | import com.esotericsoftware.tablelayout.swing.SwingToolkit.DebugRect; 14 | 15 | class TableLayout extends BaseTableLayout { 16 | ArrayList debugRects; 17 | 18 | public TableLayout () { 19 | super((SwingToolkit)SwingToolkit.instance); 20 | } 21 | 22 | public TableLayout (SwingToolkit toolkit) { 23 | super(toolkit); 24 | } 25 | 26 | public void layout () { 27 | Table table = getTable(); 28 | Insets insets = table.getInsets(); 29 | super.layout(insets.left, insets.top, // 30 | table.getWidth() - insets.left - insets.right, // 31 | table.getHeight() - insets.top - insets.bottom); 32 | 33 | List cells = getCells(); 34 | for (int i = 0, n = cells.size(); i < n; i++) { 35 | Cell c = cells.get(i); 36 | if (c.getIgnore()) continue; 37 | Component component = (Component)c.getWidget(); 38 | component.setLocation((int)c.getWidgetX(), (int)c.getWidgetY()); 39 | component.setSize((int)c.getWidgetWidth(), (int)c.getWidgetHeight()); 40 | } 41 | 42 | if (getDebug() != Debug.none) SwingToolkit.startDebugTimer(); 43 | } 44 | 45 | public void invalidate () { 46 | super.invalidate(); 47 | if (getTable().isValid()) getTable().invalidate(); 48 | } 49 | 50 | public void invalidateHierarchy () { 51 | if (getTable().isValid()) getTable().invalidate(); 52 | } 53 | 54 | void drawDebug () { 55 | Graphics2D g = (Graphics2D)getTable().getGraphics(); 56 | if (g == null) return; 57 | g.setColor(Color.red); 58 | for (DebugRect rect : debugRects) { 59 | if (rect.type == Debug.cell) g.setColor(Color.red); 60 | if (rect.type == Debug.widget) g.setColor(Color.green); 61 | if (rect.type == Debug.table) g.setColor(Color.blue); 62 | g.drawRect(rect.x, rect.y, rect.width, rect.height); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tablelayout-swing/test/com/esotericsoftware/tablelayout/swing/SwingTest.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.swing; 3 | 4 | import java.awt.EventQueue; 5 | import java.awt.GraphicsConfiguration; 6 | import java.awt.HeadlessException; 7 | 8 | import javax.swing.JButton; 9 | import javax.swing.JFrame; 10 | import javax.swing.JLabel; 11 | import javax.swing.JTextField; 12 | 13 | public class SwingTest extends JFrame { 14 | 15 | public SwingTest () { 16 | setTitle("SwingTest"); 17 | setSize(640, 480); 18 | setLocationRelativeTo(null); 19 | setDefaultCloseOperation(DISPOSE_ON_CLOSE); 20 | setVisible(true); 21 | 22 | JButton button1 = new JButton("One"); 23 | JButton button2 = new JButton("Two"); 24 | JButton button3 = new JButton("Three"); 25 | JButton button4 = new JButton("Four"); 26 | JButton button5 = new JButton("Five"); 27 | JTextField text1 = new JTextField("One"); 28 | JTextField text2 = new JTextField("Two"); 29 | JTextField text3 = new JTextField("Three"); 30 | 31 | Table table = new Table(); 32 | getContentPane().add(table); 33 | 34 | table.addCell(button1); 35 | table.addCell(button2); 36 | table.row(); 37 | table.addCell(button3).colspan(2); 38 | table.row(); 39 | table.addCell(text1).colspan(2).fill(); 40 | table.row(); 41 | table.addCell(text2).right().width(150); 42 | table.addCell(text3).width(250); 43 | table.row(); 44 | table.addCell(button4).expand().colspan(2); 45 | table.debug(); 46 | } 47 | 48 | public static void main (String[] args) throws Exception { 49 | EventQueue.invokeLater(new Runnable() { 50 | public void run () { 51 | new SwingTest(); 52 | } 53 | }); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tablelayout-twl/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tablelayout-twl/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | tablelayout-twl 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /tablelayout-twl/lib/lwjgl-debug.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/tablelayout/9ded474db7a6fc1fd8ffe8058f78c0b92f1e5776/tablelayout-twl/lib/lwjgl-debug.jar -------------------------------------------------------------------------------- /tablelayout-twl/lib/natives/OpenAL32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/tablelayout/9ded474db7a6fc1fd8ffe8058f78c0b92f1e5776/tablelayout-twl/lib/natives/OpenAL32.dll -------------------------------------------------------------------------------- /tablelayout-twl/lib/natives/OpenAL64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/tablelayout/9ded474db7a6fc1fd8ffe8058f78c0b92f1e5776/tablelayout-twl/lib/natives/OpenAL64.dll -------------------------------------------------------------------------------- /tablelayout-twl/lib/natives/liblwjgl.jnilib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/tablelayout/9ded474db7a6fc1fd8ffe8058f78c0b92f1e5776/tablelayout-twl/lib/natives/liblwjgl.jnilib -------------------------------------------------------------------------------- /tablelayout-twl/lib/natives/lwjgl.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/tablelayout/9ded474db7a6fc1fd8ffe8058f78c0b92f1e5776/tablelayout-twl/lib/natives/lwjgl.dll -------------------------------------------------------------------------------- /tablelayout-twl/lib/natives/lwjgl64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/tablelayout/9ded474db7a6fc1fd8ffe8058f78c0b92f1e5776/tablelayout-twl/lib/natives/lwjgl64.dll -------------------------------------------------------------------------------- /tablelayout-twl/lib/natives/openal.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/tablelayout/9ded474db7a6fc1fd8ffe8058f78c0b92f1e5776/tablelayout-twl/lib/natives/openal.dylib -------------------------------------------------------------------------------- /tablelayout-twl/lib/twl.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/tablelayout/9ded474db7a6fc1fd8ffe8058f78c0b92f1e5776/tablelayout-twl/lib/twl.jar -------------------------------------------------------------------------------- /tablelayout-twl/lib/xpp3-1.1.4c.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/tablelayout/9ded474db7a6fc1fd8ffe8058f78c0b92f1e5776/tablelayout-twl/lib/xpp3-1.1.4c.jar -------------------------------------------------------------------------------- /tablelayout-twl/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.esotericsoftware 7 | tablelayout-parent 8 | 1.0-SNAPSHOT 9 | ../ 10 | 11 | 12 | tablelayout-twl 13 | 14 | tablelayout-twl 15 | 16 | 17 | 18 | ${project.groupId} 19 | tablelayout 20 | ${project.version} 21 | 22 | 23 | 24 | de.matthiasmann 25 | twl 26 | 841 27 | system 28 | ${project.basedir}/lib/twl.jar 29 | 30 | 31 | 32 | org.lwjgl.lwjgl 33 | lwjgl 34 | 2.9.3 35 | test 36 | 37 | 38 | -------------------------------------------------------------------------------- /tablelayout-twl/project.yaml: -------------------------------------------------------------------------------- 1 | source: 2 | - src|**/*.java 3 | - ../tablelayout/src|**/*.java 4 | -------------------------------------------------------------------------------- /tablelayout-twl/src/com/esotericsoftware/tablelayout/twl/Stack.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.twl; 3 | 4 | import de.matthiasmann.twl.Widget; 5 | 6 | public class Stack extends Widget { 7 | public Stack () { 8 | setTheme(""); 9 | } 10 | 11 | protected void layout () { 12 | layoutChildrenFullInnerArea(); 13 | } 14 | 15 | public int getMinWidth () { 16 | int width = 0; 17 | for (int i = 0, n = getNumChildren(); i < n; i++) 18 | width = Math.max(width, getChild(i).getMinWidth()); 19 | return width; 20 | } 21 | 22 | public int getMinHeight () { 23 | int height = 0; 24 | for (int i = 0, n = getNumChildren(); i < n; i++) 25 | height = Math.max(height, getChild(i).getMinHeight()); 26 | return height; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tablelayout-twl/src/com/esotericsoftware/tablelayout/twl/Table.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.twl; 3 | 4 | import com.esotericsoftware.tablelayout.Cell; 5 | 6 | import de.matthiasmann.twl.Widget; 7 | 8 | public class Table extends Widget { 9 | public final TableLayout layout; 10 | 11 | public Table () { 12 | this(new TableLayout()); 13 | } 14 | 15 | public Table (TableLayout layout) { 16 | this.layout = layout; 17 | layout.setTable(this); 18 | setTheme(""); 19 | } 20 | 21 | public Cell addCell (Widget widget) { 22 | return layout.add(widget); 23 | } 24 | 25 | public Cell row () { 26 | return layout.row(); 27 | } 28 | 29 | public Cell columnDefaults (int column) { 30 | return layout.columnDefaults(column); 31 | } 32 | 33 | public Cell defaults () { 34 | return layout.defaults(); 35 | } 36 | 37 | protected void layout () { 38 | layout.layout(); 39 | } 40 | 41 | public int getMinWidth () { 42 | return (int)layout.getMinWidth(); 43 | } 44 | 45 | public int getMinHeight () { 46 | return (int)layout.getMinHeight(); 47 | } 48 | 49 | public int getPreferredWidth () { 50 | return (int)layout.getPrefWidth(); 51 | } 52 | 53 | public int getPreferredHeight () { 54 | return (int)layout.getPrefHeight(); 55 | } 56 | 57 | public void invalidateLayout () { 58 | super.invalidateLayout(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tablelayout-twl/src/com/esotericsoftware/tablelayout/twl/TableLayout.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.twl; 3 | 4 | import java.util.List; 5 | 6 | import com.esotericsoftware.tablelayout.BaseTableLayout; 7 | import com.esotericsoftware.tablelayout.Cell; 8 | 9 | import de.matthiasmann.twl.Widget; 10 | 11 | public class TableLayout extends BaseTableLayout { 12 | public TableLayout () { 13 | super(TwlToolkit.instance); 14 | } 15 | 16 | public TableLayout (TwlToolkit toolkit) { 17 | super(toolkit); 18 | } 19 | 20 | public void layout () { 21 | Table table = getTable(); 22 | super.layout(table.getBorderLeft(), table.getBorderTop(), table.getInnerWidth(), table.getInnerHeight()); 23 | 24 | List cells = getCells(); 25 | for (int i = 0, n = cells.size(); i < n; i++) { 26 | Cell c = cells.get(i); 27 | if (c.getIgnore()) continue; 28 | Widget cellWidget = (Widget)c.getWidget(); 29 | cellWidget.setPosition((int)c.getWidgetX(), (int)c.getWidgetY()); 30 | cellWidget.setSize((int)c.getWidgetWidth(), (int)c.getWidgetHeight()); 31 | } 32 | } 33 | 34 | public void invalidate () { 35 | getTable().invalidateLayout(); 36 | } 37 | 38 | public void invalidateHierarchy () { 39 | getTable().invalidateLayout(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tablelayout-twl/src/com/esotericsoftware/tablelayout/twl/TwlToolkit.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.twl; 3 | 4 | import com.esotericsoftware.tablelayout.BaseTableLayout.Debug; 5 | import com.esotericsoftware.tablelayout.Cell; 6 | import com.esotericsoftware.tablelayout.Toolkit; 7 | 8 | import de.matthiasmann.twl.Widget; 9 | 10 | public class TwlToolkit extends Toolkit { 11 | static public final TwlToolkit instance = new TwlToolkit(); 12 | 13 | public Cell obtainCell (TableLayout layout) { 14 | Cell cell = new Cell(); 15 | cell.setLayout(layout); 16 | return cell; 17 | } 18 | 19 | public void freeCell (Cell cell) { 20 | } 21 | 22 | public void addChild (Widget parent, Widget child) { 23 | parent.add(child); 24 | } 25 | 26 | public void removeChild (Widget parent, Widget child) { 27 | parent.removeChild(child); 28 | } 29 | 30 | public float getMinWidth (Widget widget) { 31 | return widget.getMinWidth(); 32 | } 33 | 34 | public float getMinHeight (Widget widget) { 35 | return widget.getMinHeight(); 36 | } 37 | 38 | public float getPrefWidth (Widget widget) { 39 | return widget.getPreferredWidth(); 40 | } 41 | 42 | public float getPrefHeight (Widget widget) { 43 | System.out.println(widget.getClass() + " " + widget.getPreferredHeight()); 44 | return widget.getPreferredHeight(); 45 | } 46 | 47 | public float getMaxWidth (Widget widget) { 48 | return widget.getMaxWidth(); 49 | } 50 | 51 | public float getMaxHeight (Widget widget) { 52 | return widget.getMaxHeight(); 53 | } 54 | 55 | public float getWidth (Widget widget) { 56 | return widget.getWidth(); 57 | } 58 | 59 | public float getHeight (Widget widget) { 60 | return widget.getHeight(); 61 | } 62 | 63 | public void clearDebugRectangles (TableLayout layout) { 64 | } 65 | 66 | public void addDebugRectangle (TableLayout layout, Debug type, float x, float y, float w, float h) { 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tablelayout-twl/test/com/esotericsoftware/tablelayout/twl/TwlTest.java: -------------------------------------------------------------------------------- 1 | 2 | package com.esotericsoftware.tablelayout.twl; 3 | 4 | import java.io.File; 5 | 6 | import org.lwjgl.opengl.Display; 7 | import org.lwjgl.opengl.DisplayMode; 8 | import org.lwjgl.opengl.GL11; 9 | 10 | import de.matthiasmann.twl.FPSCounter; 11 | import de.matthiasmann.twl.GUI; 12 | import de.matthiasmann.twl.ProgressBar; 13 | import de.matthiasmann.twl.ScrollPane; 14 | import de.matthiasmann.twl.TextArea; 15 | import de.matthiasmann.twl.Widget; 16 | import de.matthiasmann.twl.renderer.lwjgl.LWJGLRenderer; 17 | import de.matthiasmann.twl.textarea.HTMLTextAreaModel; 18 | import de.matthiasmann.twl.theme.ThemeManager; 19 | 20 | public class TwlTest { 21 | public TwlTest () throws Exception { 22 | LWJGLRenderer renderer = new LWJGLRenderer(); 23 | 24 | ThemeManager theme = ThemeManager.createThemeManager(TwlTest.class.getResource("/widgets.xml"), renderer); 25 | 26 | Widget root = new Widget() { 27 | protected void layout () { 28 | layoutChildrenFullInnerArea(); 29 | } 30 | }; 31 | root.setTheme(""); 32 | 33 | GUI gui = new GUI(root, renderer); 34 | gui.setSize(); 35 | gui.applyTheme(theme); 36 | 37 | final HTMLTextAreaModel htmlText = new HTMLTextAreaModel(); 38 | TextArea textArea = new TextArea(htmlText); 39 | htmlText 40 | .setHtml("
TWL TextAreaTest
Lorem ipsum dolor sit amet, douchebagus joglus. Sed fermentum gravida turpis, sit amet gravida justo laoreet non. Donec ultrices suscipit metus a mollis. Mollis varius egestas quisque feugiat pellentesque mi, quis scelerisque velit bibendum eget. Nulla orci in enim nisl mattis varius dignissim fringilla.

Curabitur purus leo, ultricies ut cursus eget, adipiscing in quam. Duis non velit vel mauris vulputate fringilla et quis.

Suspendisse lobortis iaculis tellus id fermentum. Integer fermentum varius pretium. Nullam libero magna, mattis vel placerat ac, dignissim sed lacus. Mauris varius libero id neque auctor a auctor odio fringilla.

Mauris orci arcu, porta eget porttitor luctus, malesuada nec metus. Nunc fermentum viverra leo eu pretium. Curabitur vitae nibh massa, imperdiet egestas lectus. Nulla odio quam, lobortis eget fermentum non, faucibus ac mi. Morbi et libero nulla. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam sit amet rhoncus nulla. Morbi consectetur ante convallis ante tristique et porta ligula hendrerit. Donec rhoncus ornare augue, sit amet lacinia nulla auctor venenatis.

Etiam semper egestas porta. Proin luctus porta faucibus. Curabitur sagittis, lorem nec imperdiet ullamcorper, sem risus consequat purus, non faucibus turpis lorem ut arcu. Nunc tempus lobortis enim vitae facilisis. Morbi posuere quam nec sem aliquam eleifend.
"); 41 | ScrollPane scrollPane = new ScrollPane(textArea); 42 | scrollPane.setFixed(ScrollPane.Fixed.HORIZONTAL); 43 | FPSCounter fpsCounter = new FPSCounter(4, 2); 44 | ProgressBar progressBar = new ProgressBar(); 45 | progressBar.setValue(0.4f); 46 | 47 | Table table = new Table(); 48 | table.addCell(scrollPane).expand().fill(); 49 | table.row(); 50 | table.addCell(fpsCounter).right(); 51 | table.row(); 52 | table.addCell(progressBar).fill(); 53 | root.add(table); 54 | 55 | while (!Display.isCloseRequested()) { 56 | GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); 57 | gui.update(); 58 | Display.update(); 59 | } 60 | } 61 | 62 | public static void main (String[] args) throws Exception { 63 | System.setProperty("org.lwjgl.librarypath", new File("lib/natives").getAbsolutePath()); 64 | Display.setTitle("TWL Examples"); 65 | Display.setDisplayMode(new DisplayMode(800, 600)); 66 | Display.setVSyncEnabled(true); 67 | Display.create(); 68 | new TwlTest(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tablelayout-twl/test/font.fnt: -------------------------------------------------------------------------------- 1 | info face="Verdana" size=30 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 2 | common lineHeight=38 base=31 scaleW=256 scaleH=256 pages=1 packed=0 3 | page id=0 file=font.png 4 | chars count=95 5 | char id=32 x=0 y=0 width=0 height=0 xoffset=0 yoffset=31 xadvance=11 page=0 chnl=0 6 | char id=124 x=0 y=0 width=5 height=31 xoffset=6 yoffset=7 xadvance=14 page=0 chnl=0 7 | char id=125 x=5 y=0 width=16 height=31 xoffset=3 yoffset=7 xadvance=19 page=0 chnl=0 8 | char id=123 x=21 y=0 width=16 height=31 xoffset=2 yoffset=7 xadvance=19 page=0 chnl=0 9 | char id=93 x=37 y=0 width=10 height=31 xoffset=3 yoffset=7 xadvance=14 page=0 chnl=0 10 | char id=91 x=47 y=0 width=10 height=31 xoffset=4 yoffset=7 xadvance=14 page=0 chnl=0 11 | char id=41 x=57 y=0 width=11 height=31 xoffset=2 yoffset=7 xadvance=14 page=0 chnl=0 12 | char id=40 x=68 y=0 width=10 height=31 xoffset=3 yoffset=7 xadvance=14 page=0 chnl=0 13 | char id=36 x=78 y=0 width=17 height=30 xoffset=2 yoffset=7 xadvance=19 page=0 chnl=0 14 | char id=106 x=95 y=0 width=11 height=30 xoffset=-2 yoffset=8 xadvance=10 page=0 chnl=0 15 | char id=81 x=106 y=0 width=22 height=30 xoffset=2 yoffset=8 xadvance=24 page=0 chnl=0 16 | char id=92 x=128 y=0 width=14 height=29 xoffset=1 yoffset=7 xadvance=14 page=0 chnl=0 17 | char id=47 x=142 y=0 width=14 height=29 xoffset=0 yoffset=7 xadvance=14 page=0 chnl=0 18 | char id=64 x=156 y=0 width=27 height=28 xoffset=3 yoffset=8 xadvance=30 page=0 chnl=0 19 | char id=127 x=183 y=0 width=25 height=25 xoffset=4 yoffset=7 xadvance=30 page=0 chnl=0 20 | char id=59 x=208 y=0 width=7 height=25 xoffset=4 yoffset=13 xadvance=14 page=0 chnl=0 21 | char id=121 x=215 y=0 width=17 height=25 xoffset=1 yoffset=13 xadvance=18 page=0 chnl=0 22 | char id=113 x=232 y=0 width=16 height=25 xoffset=2 yoffset=13 xadvance=19 page=0 chnl=0 23 | char id=112 x=0 y=31 width=16 height=25 xoffset=3 yoffset=13 xadvance=19 page=0 chnl=0 24 | char id=108 x=16 y=31 width=5 height=25 xoffset=3 yoffset=7 xadvance=9 page=0 chnl=0 25 | char id=107 x=21 y=31 width=16 height=25 xoffset=3 yoffset=7 xadvance=18 page=0 chnl=0 26 | char id=104 x=37 y=31 width=15 height=25 xoffset=3 yoffset=7 xadvance=19 page=0 chnl=0 27 | char id=103 x=52 y=31 width=16 height=25 xoffset=2 yoffset=13 xadvance=19 page=0 chnl=0 28 | char id=102 x=68 y=31 width=13 height=25 xoffset=1 yoffset=7 xadvance=11 page=0 chnl=0 29 | char id=100 x=81 y=31 width=16 height=25 xoffset=2 yoffset=7 xadvance=19 page=0 chnl=0 30 | char id=98 x=97 y=31 width=16 height=25 xoffset=3 yoffset=7 xadvance=19 page=0 chnl=0 31 | char id=38 x=113 y=31 width=22 height=24 xoffset=2 yoffset=8 xadvance=22 page=0 chnl=0 32 | char id=35 x=135 y=31 width=21 height=24 xoffset=3 yoffset=8 xadvance=25 page=0 chnl=0 33 | char id=37 x=156 y=31 width=30 height=24 xoffset=2 yoffset=8 xadvance=32 page=0 chnl=0 34 | char id=63 x=186 y=31 width=14 height=24 xoffset=2 yoffset=8 xadvance=16 page=0 chnl=0 35 | char id=33 x=200 y=31 width=5 height=24 xoffset=4 yoffset=8 xadvance=12 page=0 chnl=0 36 | char id=48 x=205 y=31 width=17 height=24 xoffset=2 yoffset=8 xadvance=19 page=0 chnl=0 37 | char id=56 x=222 y=31 width=16 height=24 xoffset=2 yoffset=8 xadvance=19 page=0 chnl=0 38 | char id=55 x=238 y=31 width=17 height=24 xoffset=2 yoffset=8 xadvance=19 page=0 chnl=0 39 | char id=54 x=0 y=56 width=16 height=24 xoffset=2 yoffset=8 xadvance=19 page=0 chnl=0 40 | char id=53 x=16 y=56 width=16 height=24 xoffset=3 yoffset=8 xadvance=19 page=0 chnl=0 41 | char id=52 x=32 y=56 width=18 height=24 xoffset=1 yoffset=8 xadvance=19 page=0 chnl=0 42 | char id=51 x=50 y=56 width=17 height=24 xoffset=2 yoffset=8 xadvance=19 page=0 chnl=0 43 | char id=50 x=67 y=56 width=17 height=24 xoffset=2 yoffset=8 xadvance=19 page=0 chnl=0 44 | char id=49 x=84 y=56 width=14 height=24 xoffset=4 yoffset=8 xadvance=19 page=0 chnl=0 45 | char id=116 x=98 y=56 width=12 height=24 xoffset=1 yoffset=8 xadvance=12 page=0 chnl=0 46 | char id=105 x=110 y=56 width=5 height=24 xoffset=3 yoffset=8 xadvance=9 page=0 chnl=0 47 | char id=90 x=115 y=56 width=19 height=24 xoffset=2 yoffset=8 xadvance=21 page=0 chnl=0 48 | char id=89 x=134 y=56 width=20 height=24 xoffset=0 yoffset=8 xadvance=18 page=0 chnl=0 49 | char id=88 x=154 y=56 width=20 height=24 xoffset=1 yoffset=8 xadvance=21 page=0 chnl=0 50 | char id=87 x=174 y=56 width=29 height=24 xoffset=1 yoffset=8 xadvance=30 page=0 chnl=0 51 | char id=86 x=203 y=56 width=22 height=24 xoffset=0 yoffset=8 xadvance=21 page=0 chnl=0 52 | char id=85 x=225 y=56 width=18 height=24 xoffset=3 yoffset=8 xadvance=22 page=0 chnl=0 53 | char id=84 x=0 y=80 width=21 height=24 xoffset=0 yoffset=8 xadvance=18 page=0 chnl=0 54 | char id=83 x=21 y=80 width=19 height=24 xoffset=2 yoffset=8 xadvance=21 page=0 chnl=0 55 | char id=82 x=40 y=80 width=19 height=24 xoffset=3 yoffset=8 xadvance=21 page=0 chnl=0 56 | char id=80 x=59 y=80 width=16 height=24 xoffset=3 yoffset=8 xadvance=18 page=0 chnl=0 57 | char id=79 x=75 y=80 width=22 height=24 xoffset=2 yoffset=8 xadvance=24 page=0 chnl=0 58 | char id=78 x=97 y=80 width=18 height=24 xoffset=3 yoffset=8 xadvance=22 page=0 chnl=0 59 | char id=77 x=115 y=80 width=21 height=24 xoffset=3 yoffset=8 xadvance=25 page=0 chnl=0 60 | char id=76 x=136 y=80 width=16 height=24 xoffset=3 yoffset=8 xadvance=17 page=0 chnl=0 61 | char id=75 x=152 y=80 width=19 height=24 xoffset=3 yoffset=8 xadvance=21 page=0 chnl=0 62 | char id=74 x=171 y=80 width=12 height=24 xoffset=1 yoffset=8 xadvance=14 page=0 chnl=0 63 | char id=73 x=183 y=80 width=11 height=24 xoffset=2 yoffset=8 xadvance=13 page=0 chnl=0 64 | char id=72 x=194 y=80 width=19 height=24 xoffset=3 yoffset=8 xadvance=23 page=0 chnl=0 65 | char id=71 x=213 y=80 width=21 height=24 xoffset=2 yoffset=8 xadvance=23 page=0 chnl=0 66 | char id=70 x=234 y=80 width=16 height=24 xoffset=3 yoffset=8 xadvance=17 page=0 chnl=0 67 | char id=69 x=0 y=104 width=16 height=24 xoffset=3 yoffset=8 xadvance=19 page=0 chnl=0 68 | char id=68 x=16 y=104 width=20 height=24 xoffset=3 yoffset=8 xadvance=23 page=0 chnl=0 69 | char id=67 x=36 y=104 width=20 height=24 xoffset=2 yoffset=8 xadvance=21 page=0 chnl=0 70 | char id=66 x=56 y=104 width=18 height=24 xoffset=3 yoffset=8 xadvance=21 page=0 chnl=0 71 | char id=65 x=74 y=104 width=22 height=24 xoffset=0 yoffset=8 xadvance=21 page=0 chnl=0 72 | char id=57 x=96 y=104 width=17 height=23 xoffset=2 yoffset=9 xadvance=19 page=0 chnl=0 73 | char id=43 x=113 y=104 width=20 height=20 xoffset=3 yoffset=11 xadvance=25 page=0 chnl=0 74 | char id=58 x=133 y=104 width=6 height=19 xoffset=5 yoffset=13 xadvance=14 page=0 chnl=0 75 | char id=122 x=139 y=104 width=16 height=19 xoffset=1 yoffset=13 xadvance=16 page=0 chnl=0 76 | char id=120 x=155 y=104 width=17 height=19 xoffset=1 yoffset=13 xadvance=18 page=0 chnl=0 77 | char id=119 x=172 y=104 width=24 height=19 xoffset=1 yoffset=13 xadvance=25 page=0 chnl=0 78 | char id=118 x=196 y=104 width=17 height=19 xoffset=1 yoffset=13 xadvance=18 page=0 chnl=0 79 | char id=117 x=213 y=104 width=15 height=19 xoffset=3 yoffset=13 xadvance=19 page=0 chnl=0 80 | char id=115 x=228 y=104 width=15 height=19 xoffset=2 yoffset=13 xadvance=16 page=0 chnl=0 81 | char id=114 x=243 y=104 width=12 height=19 xoffset=3 yoffset=13 xadvance=13 page=0 chnl=0 82 | char id=110 x=0 y=128 width=15 height=19 xoffset=3 yoffset=13 xadvance=19 page=0 chnl=0 83 | char id=109 x=15 y=128 width=27 height=19 xoffset=2 yoffset=13 xadvance=29 page=0 chnl=0 84 | char id=101 x=42 y=128 width=17 height=19 xoffset=2 yoffset=13 xadvance=18 page=0 chnl=0 85 | char id=99 x=59 y=128 width=15 height=19 xoffset=2 yoffset=13 xadvance=16 page=0 chnl=0 86 | char id=97 x=74 y=128 width=15 height=19 xoffset=2 yoffset=13 xadvance=18 page=0 chnl=0 87 | char id=62 x=89 y=128 width=19 height=18 xoffset=4 yoffset=13 xadvance=25 page=0 chnl=0 88 | char id=60 x=108 y=128 width=19 height=18 xoffset=4 yoffset=13 xadvance=25 page=0 chnl=0 89 | char id=111 x=127 y=128 width=16 height=18 xoffset=2 yoffset=14 xadvance=18 page=0 chnl=0 90 | char id=42 x=143 y=128 width=15 height=16 xoffset=3 yoffset=7 xadvance=19 page=0 chnl=0 91 | char id=94 x=158 y=128 width=20 height=14 xoffset=3 yoffset=8 xadvance=25 page=0 chnl=0 92 | char id=44 x=178 y=128 width=7 height=12 xoffset=2 yoffset=26 xadvance=11 page=0 chnl=0 93 | char id=126 x=185 y=128 width=20 height=11 xoffset=3 yoffset=16 xadvance=25 page=0 chnl=0 94 | char id=61 x=205 y=128 width=19 height=10 xoffset=4 yoffset=16 xadvance=25 page=0 chnl=0 95 | char id=39 x=224 y=128 width=4 height=10 xoffset=2 yoffset=7 xadvance=8 page=0 chnl=0 96 | char id=34 x=228 y=128 width=10 height=10 xoffset=2 yoffset=7 xadvance=14 page=0 chnl=0 97 | char id=96 x=238 y=128 width=7 height=7 xoffset=5 yoffset=6 xadvance=19 page=0 chnl=0 98 | char id=46 x=245 y=128 width=6 height=6 xoffset=4 yoffset=26 xadvance=11 page=0 chnl=0 99 | char id=45 x=0 y=147 width=11 height=5 xoffset=2 yoffset=19 xadvance=14 page=0 chnl=0 100 | kernings count=170 101 | kerning first=121 second=44 amount=-3 102 | kerning first=121 second=45 amount=-1 103 | kerning first=121 second=46 amount=-3 104 | kerning first=121 second=97 amount=-1 105 | kerning first=107 second=45 amount=-1 106 | kerning first=102 second=34 amount=1 107 | kerning first=102 second=39 amount=1 108 | kerning first=102 second=41 amount=1 109 | kerning first=102 second=42 amount=1 110 | kerning first=102 second=44 amount=-2 111 | kerning first=102 second=45 amount=-1 112 | kerning first=102 second=46 amount=-2 113 | kerning first=102 second=63 amount=2 114 | kerning first=102 second=92 amount=1 115 | kerning first=102 second=93 amount=1 116 | kerning first=102 second=125 amount=1 117 | kerning first=116 second=45 amount=-1 118 | kerning first=90 second=45 amount=-1 119 | kerning first=90 second=97 amount=-1 120 | kerning first=90 second=101 amount=-1 121 | kerning first=90 second=111 amount=-1 122 | kerning first=90 second=119 amount=-1 123 | kerning first=90 second=121 amount=-1 124 | kerning first=89 second=44 amount=-4 125 | kerning first=89 second=45 amount=-2 126 | kerning first=89 second=46 amount=-4 127 | kerning first=89 second=58 amount=-3 128 | kerning first=89 second=59 amount=-3 129 | kerning first=89 second=65 amount=-1 130 | kerning first=89 second=97 amount=-2 131 | kerning first=89 second=100 amount=-2 132 | kerning first=89 second=101 amount=-2 133 | kerning first=89 second=103 amount=-2 134 | kerning first=89 second=109 amount=-1 135 | kerning first=89 second=110 amount=-1 136 | kerning first=89 second=111 amount=-2 137 | kerning first=89 second=112 amount=-1 138 | kerning first=89 second=113 amount=-2 139 | kerning first=89 second=114 amount=-1 140 | kerning first=89 second=115 amount=-2 141 | kerning first=89 second=117 amount=-2 142 | kerning first=89 second=118 amount=-1 143 | kerning first=88 second=45 amount=-1 144 | kerning first=88 second=97 amount=-1 145 | kerning first=88 second=101 amount=-1 146 | kerning first=88 second=111 amount=-1 147 | kerning first=88 second=121 amount=-1 148 | kerning first=87 second=44 amount=-4 149 | kerning first=87 second=45 amount=-1 150 | kerning first=87 second=46 amount=-3 151 | kerning first=87 second=58 amount=-1 152 | kerning first=87 second=59 amount=-1 153 | kerning first=87 second=65 amount=-1 154 | kerning first=87 second=97 amount=-1 155 | kerning first=87 second=101 amount=-1 156 | kerning first=87 second=111 amount=-1 157 | kerning first=87 second=114 amount=-1 158 | kerning first=87 second=117 amount=-1 159 | kerning first=87 second=121 amount=-1 160 | kerning first=86 second=44 amount=-4 161 | kerning first=86 second=45 amount=-1 162 | kerning first=86 second=46 amount=-4 163 | kerning first=86 second=58 amount=-1 164 | kerning first=86 second=59 amount=-1 165 | kerning first=86 second=65 amount=-1 166 | kerning first=86 second=97 amount=-1 167 | kerning first=86 second=101 amount=-1 168 | kerning first=86 second=111 amount=-1 169 | kerning first=86 second=117 amount=-1 170 | kerning first=86 second=121 amount=-1 171 | kerning first=84 second=44 amount=-4 172 | kerning first=84 second=45 amount=-2 173 | kerning first=84 second=46 amount=-4 174 | kerning first=84 second=58 amount=-3 175 | kerning first=84 second=59 amount=-3 176 | kerning first=84 second=63 amount=1 177 | kerning first=84 second=65 amount=-2 178 | kerning first=84 second=67 amount=-1 179 | kerning first=84 second=71 amount=-1 180 | kerning first=84 second=79 amount=-1 181 | kerning first=84 second=84 amount=-1 182 | kerning first=84 second=97 amount=-4 183 | kerning first=84 second=99 amount=-3 184 | kerning first=84 second=101 amount=-3 185 | kerning first=84 second=103 amount=-3 186 | kerning first=84 second=111 amount=-3 187 | kerning first=84 second=114 amount=-3 188 | kerning first=84 second=115 amount=-3 189 | kerning first=84 second=117 amount=-3 190 | kerning first=84 second=118 amount=-3 191 | kerning first=84 second=119 amount=-3 192 | kerning first=84 second=121 amount=-3 193 | kerning first=84 second=122 amount=-2 194 | kerning first=82 second=45 amount=-1 195 | kerning first=82 second=84 amount=-1 196 | kerning first=82 second=97 amount=-1 197 | kerning first=82 second=101 amount=-1 198 | kerning first=82 second=111 amount=-1 199 | kerning first=82 second=121 amount=-1 200 | kerning first=80 second=44 amount=-4 201 | kerning first=80 second=46 amount=-4 202 | kerning first=80 second=65 amount=-1 203 | kerning first=80 second=97 amount=-1 204 | kerning first=80 second=101 amount=-1 205 | kerning first=80 second=111 amount=-1 206 | kerning first=79 second=84 amount=-1 207 | kerning first=76 second=39 amount=-2 208 | kerning first=76 second=45 amount=-2 209 | kerning first=76 second=74 amount=1 210 | kerning first=76 second=84 amount=-2 211 | kerning first=76 second=86 amount=-2 212 | kerning first=76 second=87 amount=-1 213 | kerning first=76 second=89 amount=-2 214 | kerning first=76 second=118 amount=-2 215 | kerning first=76 second=121 amount=-2 216 | kerning first=75 second=45 amount=-2 217 | kerning first=75 second=97 amount=-1 218 | kerning first=75 second=101 amount=-1 219 | kerning first=75 second=111 amount=-1 220 | kerning first=75 second=117 amount=-1 221 | kerning first=75 second=118 amount=-1 222 | kerning first=75 second=119 amount=-1 223 | kerning first=75 second=121 amount=-1 224 | kerning first=70 second=44 amount=-4 225 | kerning first=70 second=46 amount=-4 226 | kerning first=70 second=58 amount=-1 227 | kerning first=70 second=59 amount=-1 228 | kerning first=70 second=63 amount=1 229 | kerning first=70 second=65 amount=-1 230 | kerning first=70 second=97 amount=-1 231 | kerning first=70 second=101 amount=-1 232 | kerning first=70 second=111 amount=-1 233 | kerning first=68 second=44 amount=-1 234 | kerning first=68 second=46 amount=-1 235 | kerning first=68 second=84 amount=-1 236 | kerning first=67 second=45 amount=-1 237 | kerning first=66 second=84 amount=-1 238 | kerning first=65 second=45 amount=-1 239 | kerning first=65 second=84 amount=-2 240 | kerning first=65 second=86 amount=-1 241 | kerning first=65 second=87 amount=-1 242 | kerning first=65 second=89 amount=-1 243 | kerning first=65 second=118 amount=-1 244 | kerning first=65 second=121 amount=-1 245 | kerning first=120 second=45 amount=-1 246 | kerning first=119 second=44 amount=-1 247 | kerning first=119 second=46 amount=-1 248 | kerning first=118 second=44 amount=-3 249 | kerning first=118 second=45 amount=-1 250 | kerning first=118 second=46 amount=-3 251 | kerning first=118 second=97 amount=-1 252 | kerning first=114 second=44 amount=-4 253 | kerning first=114 second=46 amount=-4 254 | kerning first=114 second=97 amount=-1 255 | kerning first=101 second=84 amount=-2 256 | kerning first=99 second=84 amount=-1 257 | kerning first=39 second=65 amount=-1 258 | kerning first=46 second=44 amount=-2 259 | kerning first=46 second=45 amount=-2 260 | kerning first=45 second=65 amount=-1 261 | kerning first=45 second=74 amount=-1 262 | kerning first=45 second=84 amount=-2 263 | kerning first=45 second=86 amount=-1 264 | kerning first=45 second=87 amount=-1 265 | kerning first=45 second=88 amount=-1 266 | kerning first=45 second=89 amount=-2 267 | kerning first=45 second=118 amount=-1 268 | kerning first=45 second=120 amount=-1 269 | kerning first=45 second=121 amount=-1 270 | kerning first=45 second=122 amount=-1 271 | -------------------------------------------------------------------------------- /tablelayout-twl/test/font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/tablelayout/9ded474db7a6fc1fd8ffe8058f78c0b92f1e5776/tablelayout-twl/test/font.png -------------------------------------------------------------------------------- /tablelayout-twl/test/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EsotericSoftware/tablelayout/9ded474db7a6fc1fd8ffe8058f78c0b92f1e5776/tablelayout-twl/test/widgets.png -------------------------------------------------------------------------------- /tablelayout-twl/test/widgets.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ctrl A 7 | cmd A 8 | ctrl X 9 | cmd X 10 | ctrl C 11 | cmd C 12 | ctrl V 13 | cmd V 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 31 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | none 81 | none 82 | normal 83 | left 84 | 0 85 | 0 86 | 0 87 | 0 88 | -defaultInputMap 89 | 90 | 91 | box 92 | 93 | 94 | 95 | 96 | 10,0 97 | button.font 98 | focus-rectangle 99 | button.background 100 | 101 | 102 | 103 | checkbox.background 104 | checkbox.overlay 105 | 106 | checkbox.background 107 | radiobutton.overlay 108 | 109 | editfield.* 110 | 0,10,0,10 111 | 112 | 113 | 114 | hscrollbar.button 115 | 116 | hscrollbar.button 117 | 118 | hscrollbar.button 119 | hscrollbar.thumb.overlay 120 | box 121 | true 122 | 123 | 124 | vscrollbar.button 125 | 126 | vscrollbar.button 127 | 128 | vscrollbar.button 129 | vscrollbar.thumb.overlay 130 | 131 | box 132 | true 133 | 134 | 135 | 136 | true 137 | 138 | 139 | 0 140 | 0 141 | false 142 | 143 | 144 | 145 | 146 | button.font 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | listbox.display.background 155 | 3,6,0,0 156 | panel-blue 157 | 10,5 158 | 150 159 | 160 | 161 | 162 | combobox.button.overlay 163 | 164 | 0,10,0,0 165 | 166 | 167 | 168 | 200 169 | 170 | 171 | progressbar.* 172 | panel-blue 173 | box 174 | 175 | 176 | -------------------------------------------------------------------------------- /tablelayout-twl/test/widgets.xml.old: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ctrl A 7 | cmd A 8 | ctrl X 9 | cmd X 10 | ctrl C 11 | cmd C 12 | ctrl V 13 | cmd V 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 31 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | none 112 | none 113 | normal 114 | left 115 | 0 116 | 0 117 | 0 118 | 0 119 | -defaultInputMap 120 | 121 | 122 | box 123 | 124 | 125 | 126 | 127 | 10,0 128 | button.font 129 | focus-rectangle 130 | button.background 131 | 132 | 133 | 134 | checkbox.background 135 | checkbox.overlay 136 | 137 | checkbox.background 138 | radiobutton.overlay 139 | 140 | editfield.* 141 | 0,10,0,10 142 | 143 | 144 | 145 | hscrollbar.button 146 | 147 | hscrollbar.button 148 | 149 | hscrollbar.button 150 | hscrollbar.thumb.overlay 151 | box 152 | true 153 | 154 | 155 | vscrollbar.button 156 | 157 | vscrollbar.button 158 | 159 | vscrollbar.button 160 | vscrollbar.thumb.overlay 161 | 162 | box 163 | true 164 | 165 | 166 | 167 | true 168 | 169 | 170 | 0 171 | 0 172 | false 173 | 174 | 175 | 176 | 177 | button.font 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | listbox.display.background 186 | 3,6,0,0 187 | panel-blue 188 | 10,5 189 | 150 190 | 191 | 192 | 193 | combobox.button.overlay 194 | 195 | 0,10,0,0 196 | 197 | 198 | 199 | 200 200 | 201 | 202 | progressbar.* 203 | panel-blue 204 | 205 | 206 | -------------------------------------------------------------------------------- /tablelayout/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tablelayout/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | tablelayout 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /tablelayout/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | #Thu Jan 21 00:57:06 PST 2010 2 | eclipse.preferences.version=1 3 | org.eclipse.jdt.core.compiler.doc.comment.support=enabled 4 | org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning 5 | org.eclipse.jdt.core.compiler.problem.autoboxing=ignore 6 | org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning 7 | org.eclipse.jdt.core.compiler.problem.deadCode=ignore 8 | org.eclipse.jdt.core.compiler.problem.deprecation=ignore 9 | org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled 10 | org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled 11 | org.eclipse.jdt.core.compiler.problem.discouragedReference=warning 12 | org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore 13 | org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore 14 | org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled 15 | org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore 16 | org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning 17 | org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning 18 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 19 | org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning 20 | org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning 21 | org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore 22 | org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore 23 | org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning 24 | org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled 25 | org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled 26 | org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled 27 | org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private 28 | org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore 29 | org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning 30 | org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore 31 | org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore 32 | org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore 33 | org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled 34 | org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public 35 | org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag 36 | org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore 37 | org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled 38 | org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private 39 | org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore 40 | org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore 41 | org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore 42 | org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning 43 | org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning 44 | org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore 45 | org.eclipse.jdt.core.compiler.problem.nullReference=warning 46 | org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning 47 | org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore 48 | org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning 49 | org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore 50 | org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore 51 | org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore 52 | org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore 53 | org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled 54 | org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning 55 | org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled 56 | org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning 57 | org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning 58 | org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore 59 | org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore 60 | org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning 61 | org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore 62 | org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore 63 | org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore 64 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore 65 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled 66 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled 67 | org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled 68 | org.eclipse.jdt.core.compiler.problem.unusedImport=ignore 69 | org.eclipse.jdt.core.compiler.problem.unusedLabel=warning 70 | org.eclipse.jdt.core.compiler.problem.unusedLocal=ignore 71 | org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore 72 | org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled 73 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled 74 | org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled 75 | org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=ignore 76 | org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning 77 | org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning 78 | -------------------------------------------------------------------------------- /tablelayout/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.esotericsoftware 7 | tablelayout-parent 8 | 1.0-SNAPSHOT 9 | ../ 10 | 11 | 12 | tablelayout 13 | 14 | tablelayout 15 | -------------------------------------------------------------------------------- /tablelayout/src/com/esotericsoftware/TableLayout.gwt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tablelayout/src/com/esotericsoftware/tablelayout/BaseTableLayout.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2011, Nathan Sweet 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | ******************************************************************************/ 27 | 28 | package com.esotericsoftware.tablelayout; 29 | 30 | import com.esotericsoftware.tablelayout.Value.FixedValue; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | /** Base layout functionality. 36 | * @author Nathan Sweet */ 37 | abstract public class BaseTableLayout> { 38 | static public final int CENTER = 1 << 0; 39 | static public final int TOP = 1 << 1; 40 | static public final int BOTTOM = 1 << 2; 41 | static public final int LEFT = 1 << 3; 42 | static public final int RIGHT = 1 << 4; 43 | 44 | static public enum Debug { 45 | none, all, table, cell, widget 46 | } 47 | 48 | K toolkit; 49 | T table; 50 | private int columns, rows; 51 | 52 | private final ArrayList cells = new ArrayList(4); 53 | private final Cell cellDefaults; 54 | private final ArrayList columnDefaults = new ArrayList(2); 55 | private Cell rowDefaults; 56 | 57 | private boolean sizeInvalid = true; 58 | private float[] columnMinWidth, rowMinHeight; 59 | private float[] columnPrefWidth, rowPrefHeight; 60 | private float tableMinWidth, tableMinHeight; 61 | private float tablePrefWidth, tablePrefHeight; 62 | private float[] columnWidth, rowHeight; 63 | private float[] expandWidth, expandHeight; 64 | private float[] columnWeightedWidth, rowWeightedHeight; 65 | 66 | Value padTop, padLeft, padBottom, padRight; 67 | int align = CENTER; 68 | Debug debug = Debug.none; 69 | 70 | public BaseTableLayout (K toolkit) { 71 | this.toolkit = toolkit; 72 | cellDefaults = toolkit.obtainCell((L)this); 73 | cellDefaults.defaults(); 74 | } 75 | 76 | /** Invalidates the layout. The cached min and pref sizes are recalculated the next time layout is done or the min or pref sizes 77 | * are accessed. */ 78 | public void invalidate () { 79 | sizeInvalid = true; 80 | } 81 | 82 | /** Invalidates the layout of this table and every parent widget. */ 83 | abstract public void invalidateHierarchy (); 84 | 85 | /** Adds a new cell to the table with the specified widget. */ 86 | public Cell add (C widget) { 87 | Cell cell = toolkit.obtainCell((L)this); 88 | cell.widget = widget; 89 | 90 | if (cells.size() > 0) { 91 | // Set cell column and row. 92 | Cell lastCell = cells.get(cells.size() - 1); 93 | if (!lastCell.endRow) { 94 | cell.column = lastCell.column + lastCell.colspan; 95 | cell.row = lastCell.row; 96 | } else { 97 | cell.column = 0; 98 | cell.row = lastCell.row + 1; 99 | } 100 | // Set the index of the cell above. 101 | if (cell.row > 0) { 102 | outer: 103 | for (int i = cells.size() - 1; i >= 0; i--) { 104 | Cell other = cells.get(i); 105 | for (int column = other.column, nn = column + other.colspan; column < nn; column++) { 106 | if (column == cell.column) { 107 | cell.cellAboveIndex = i; 108 | break outer; 109 | } 110 | } 111 | } 112 | } 113 | } else { 114 | cell.column = 0; 115 | cell.row = 0; 116 | } 117 | cells.add(cell); 118 | 119 | cell.set(cellDefaults); 120 | if (cell.column < columnDefaults.size()) { 121 | Cell columnCell = columnDefaults.get(cell.column); 122 | if (columnCell != null) cell.merge(columnCell); 123 | } 124 | cell.merge(rowDefaults); 125 | 126 | if (widget != null) toolkit.addChild(table, widget); 127 | 128 | return cell; 129 | } 130 | 131 | /** Indicates that subsequent cells should be added to a new row and returns the cell values that will be used as the defaults 132 | * for all cells in the new row. */ 133 | public Cell row () { 134 | if (cells.size() > 0) endRow(); 135 | if (rowDefaults != null) toolkit.freeCell(rowDefaults); 136 | rowDefaults = toolkit.obtainCell((L)this); 137 | rowDefaults.clear(); 138 | return rowDefaults; 139 | } 140 | 141 | private void endRow () { 142 | int rowColumns = 0; 143 | for (int i = cells.size() - 1; i >= 0; i--) { 144 | Cell cell = cells.get(i); 145 | if (cell.endRow) break; 146 | rowColumns += cell.colspan; 147 | } 148 | columns = Math.max(columns, rowColumns); 149 | rows++; 150 | cells.get(cells.size() - 1).endRow = true; 151 | invalidate(); 152 | } 153 | 154 | /** Gets the cell values that will be used as the defaults for all cells in the specified column. Columns are indexed starting 155 | * at 0. */ 156 | public Cell columnDefaults (int column) { 157 | Cell cell = columnDefaults.size() > column ? columnDefaults.get(column) : null; 158 | if (cell == null) { 159 | cell = toolkit.obtainCell((L)this); 160 | cell.clear(); 161 | if (column >= columnDefaults.size()) { 162 | for (int i = columnDefaults.size(); i < column; i++) 163 | columnDefaults.add(null); 164 | columnDefaults.add(cell); 165 | } else 166 | columnDefaults.set(column, cell); 167 | } 168 | return cell; 169 | } 170 | 171 | /** Removes all widgets and cells from the table (same as {@link #clear()}) and additionally resets all table properties and 172 | * cell, column, and row defaults. */ 173 | public void reset () { 174 | clear(); 175 | padTop = null; 176 | padLeft = null; 177 | padBottom = null; 178 | padRight = null; 179 | align = CENTER; 180 | if (debug != Debug.none) toolkit.clearDebugRectangles((L)this); 181 | debug = Debug.none; 182 | cellDefaults.defaults(); 183 | for (int i = 0, n = columnDefaults.size(); i < n; i++) { 184 | Cell columnCell = columnDefaults.get(i); 185 | if (columnCell != null) toolkit.freeCell(columnCell); 186 | } 187 | columnDefaults.clear(); 188 | } 189 | 190 | /** Removes all widgets and cells from the table. */ 191 | public void clear () { 192 | for (int i = cells.size() - 1; i >= 0; i--) { 193 | Cell cell = cells.get(i); 194 | Object widget = cell.widget; 195 | if (widget != null) toolkit.removeChild(table, (C)widget); 196 | toolkit.freeCell(cell); 197 | } 198 | cells.clear(); 199 | rows = 0; 200 | columns = 0; 201 | if (rowDefaults != null) toolkit.freeCell(rowDefaults); 202 | rowDefaults = null; 203 | invalidate(); 204 | } 205 | 206 | /** Returns the cell for the specified widget in this table, or null. */ 207 | public Cell getCell (C widget) { 208 | for (int i = 0, n = cells.size(); i < n; i++) { 209 | Cell c = cells.get(i); 210 | if (c.widget == widget) return c; 211 | } 212 | return null; 213 | } 214 | 215 | /** Returns the cells for this table. */ 216 | public List getCells () { 217 | return cells; 218 | } 219 | 220 | public void setToolkit (K toolkit) { 221 | this.toolkit = toolkit; 222 | } 223 | 224 | /** Returns the table widget that will be laid out. */ 225 | public T getTable () { 226 | return table; 227 | } 228 | 229 | /** Sets the table widget that will be laid out. */ 230 | public void setTable (T table) { 231 | this.table = table; 232 | } 233 | 234 | /** The minimum width of the table. */ 235 | public float getMinWidth () { 236 | if (sizeInvalid) computeSize(); 237 | return tableMinWidth; 238 | } 239 | 240 | /** The minimum size of the table. */ 241 | public float getMinHeight () { 242 | if (sizeInvalid) computeSize(); 243 | return tableMinHeight; 244 | } 245 | 246 | /** The preferred width of the table. */ 247 | public float getPrefWidth () { 248 | if (sizeInvalid) computeSize(); 249 | return tablePrefWidth; 250 | } 251 | 252 | /** The preferred height of the table. */ 253 | public float getPrefHeight () { 254 | if (sizeInvalid) computeSize(); 255 | return tablePrefHeight; 256 | } 257 | 258 | /** The cell values that will be used as the defaults for all cells. */ 259 | public Cell defaults () { 260 | return cellDefaults; 261 | } 262 | 263 | /** Sets the padTop, padLeft, padBottom, and padRight around the table to the specified value. */ 264 | public L pad (Value pad) { 265 | padTop = pad; 266 | padLeft = pad; 267 | padBottom = pad; 268 | padRight = pad; 269 | sizeInvalid = true; 270 | return (L)this; 271 | } 272 | 273 | public L pad (Value top, Value left, Value bottom, Value right) { 274 | padTop = top; 275 | padLeft = left; 276 | padBottom = bottom; 277 | padRight = right; 278 | sizeInvalid = true; 279 | return (L)this; 280 | } 281 | 282 | /** Padding at the top edge of the table. */ 283 | public L padTop (Value padTop) { 284 | this.padTop = padTop; 285 | sizeInvalid = true; 286 | return (L)this; 287 | } 288 | 289 | /** Padding at the left edge of the table. */ 290 | public L padLeft (Value padLeft) { 291 | this.padLeft = padLeft; 292 | sizeInvalid = true; 293 | return (L)this; 294 | } 295 | 296 | /** Padding at the bottom edge of the table. */ 297 | public L padBottom (Value padBottom) { 298 | this.padBottom = padBottom; 299 | sizeInvalid = true; 300 | return (L)this; 301 | } 302 | 303 | /** Padding at the right edge of the table. */ 304 | public L padRight (Value padRight) { 305 | this.padRight = padRight; 306 | sizeInvalid = true; 307 | return (L)this; 308 | } 309 | 310 | /** Sets the padTop, padLeft, padBottom, and padRight around the table to the specified value. */ 311 | public L pad (float pad) { 312 | padTop = new FixedValue(pad); 313 | padLeft = new FixedValue(pad); 314 | padBottom = new FixedValue(pad); 315 | padRight = new FixedValue(pad); 316 | sizeInvalid = true; 317 | return (L)this; 318 | } 319 | 320 | public L pad (float top, float left, float bottom, float right) { 321 | padTop = new FixedValue(top); 322 | padLeft = new FixedValue(left); 323 | padBottom = new FixedValue(bottom); 324 | padRight = new FixedValue(right); 325 | sizeInvalid = true; 326 | return (L)this; 327 | } 328 | 329 | /** Padding at the top edge of the table. */ 330 | public L padTop (float padTop) { 331 | this.padTop = new FixedValue(padTop); 332 | sizeInvalid = true; 333 | return (L)this; 334 | } 335 | 336 | /** Padding at the left edge of the table. */ 337 | public L padLeft (float padLeft) { 338 | this.padLeft = new FixedValue(padLeft); 339 | sizeInvalid = true; 340 | return (L)this; 341 | } 342 | 343 | /** Padding at the bottom edge of the table. */ 344 | public L padBottom (float padBottom) { 345 | this.padBottom = new FixedValue(padBottom); 346 | sizeInvalid = true; 347 | return (L)this; 348 | } 349 | 350 | /** Padding at the right edge of the table. */ 351 | public L padRight (float padRight) { 352 | this.padRight = new FixedValue(padRight); 353 | sizeInvalid = true; 354 | return (L)this; 355 | } 356 | 357 | /** Alignment of the logical table within the table widget. Set to {@link #CENTER}, {@link #TOP}, {@link #BOTTOM} , 358 | * {@link #LEFT}, {@link #RIGHT}, or any combination of those. */ 359 | public L align (int align) { 360 | this.align = align; 361 | return (L)this; 362 | } 363 | 364 | /** Sets the alignment of the logical table within the table widget to {@link #CENTER}. This clears any other alignment. */ 365 | public L center () { 366 | align = CENTER; 367 | return (L)this; 368 | } 369 | 370 | /** Adds {@link #TOP} and clears {@link #BOTTOM} for the alignment of the logical table within the table widget. */ 371 | public L top () { 372 | align |= TOP; 373 | align &= ~BOTTOM; 374 | return (L)this; 375 | } 376 | 377 | /** Adds {@link #LEFT} and clears {@link #RIGHT} for the alignment of the logical table within the table widget. */ 378 | public L left () { 379 | align |= LEFT; 380 | align &= ~RIGHT; 381 | return (L)this; 382 | } 383 | 384 | /** Adds {@link #BOTTOM} and clears {@link #TOP} for the alignment of the logical table within the table widget. */ 385 | public L bottom () { 386 | align |= BOTTOM; 387 | align &= ~TOP; 388 | return (L)this; 389 | } 390 | 391 | /** Adds {@link #RIGHT} and clears {@link #LEFT} for the alignment of the logical table within the table widget. */ 392 | public L right () { 393 | align |= RIGHT; 394 | align &= ~LEFT; 395 | return (L)this; 396 | } 397 | 398 | /** Turns on all debug lines. */ 399 | public L debug () { 400 | this.debug = Debug.all; 401 | invalidate(); 402 | return (L)this; 403 | } 404 | 405 | /** Turns on table debug lines. */ 406 | public L debugTable () { 407 | this.debug = Debug.table; 408 | invalidate(); 409 | return (L)this; 410 | } 411 | 412 | /** Turns on cell debug lines. */ 413 | public L debugCell () { 414 | this.debug = Debug.cell; 415 | invalidate(); 416 | return (L)this; 417 | } 418 | 419 | /** Turns on widget debug lines. */ 420 | public L debugWidget () { 421 | this.debug = Debug.widget; 422 | invalidate(); 423 | return (L)this; 424 | } 425 | 426 | /** Turns on debug lines. */ 427 | public L debug (Debug debug) { 428 | this.debug = debug; 429 | if (debug == Debug.none) 430 | toolkit.clearDebugRectangles((L)this); 431 | else 432 | invalidate(); 433 | return (L)this; 434 | } 435 | 436 | public Debug getDebug () { 437 | return debug; 438 | } 439 | 440 | public Value getPadTopValue () { 441 | return padTop; 442 | } 443 | 444 | public float getPadTop () { 445 | return padTop == null ? 0 : padTop.height(this); 446 | } 447 | 448 | public Value getPadLeftValue () { 449 | return padLeft; 450 | } 451 | 452 | public float getPadLeft () { 453 | return padLeft == null ? 0 : padLeft.width(this); 454 | } 455 | 456 | public Value getPadBottomValue () { 457 | return padBottom; 458 | } 459 | 460 | public float getPadBottom () { 461 | return padBottom == null ? 0 : padBottom.height(this); 462 | } 463 | 464 | public Value getPadRightValue () { 465 | return padRight; 466 | } 467 | 468 | public float getPadRight () { 469 | return padRight == null ? 0 : padRight.width(this); 470 | } 471 | 472 | public int getAlign () { 473 | return align; 474 | } 475 | 476 | /** Returns the row index for the y coordinate, or -1 if there are no cells. */ 477 | public int getRow (float y) { 478 | int row = 0; 479 | y += h(padTop); 480 | int i = 0, n = cells.size(); 481 | if (n == 0) return -1; 482 | if (n == 1) return 0; 483 | if (cells.get(0).widgetY < cells.get(1).widgetY) { 484 | // Using y-down coordinate system. 485 | while (i < n) { 486 | Cell c = cells.get(i++); 487 | if (c.getIgnore()) continue; 488 | if (c.widgetY + c.computedPadTop > y) break; 489 | if (c.endRow) row++; 490 | } 491 | return row - 1; 492 | } 493 | // Using y-up coordinate system. 494 | while (i < n) { 495 | Cell c = cells.get(i++); 496 | if (c.getIgnore()) continue; 497 | if (c.widgetY + c.computedPadTop < y) break; 498 | if (c.endRow) row++; 499 | } 500 | return row; 501 | } 502 | 503 | private float[] ensureSize (float[] array, int size) { 504 | if (array == null || array.length < size) return new float[size]; 505 | for (int i = 0, n = array.length; i < n; i++) 506 | array[i] = 0; 507 | return array; 508 | } 509 | 510 | private float w (Value value) { 511 | return value == null ? 0 : value.width(table); 512 | } 513 | 514 | private float h (Value value) { 515 | return value == null ? 0 : value.height(table); 516 | } 517 | 518 | private float w (Value value, Cell cell) { 519 | return value == null ? 0 : value.width(cell); 520 | } 521 | 522 | private float h (Value value, Cell cell) { 523 | return value == null ? 0 : value.height(cell); 524 | } 525 | 526 | private void computeSize () { 527 | sizeInvalid = false; 528 | 529 | Toolkit toolkit = this.toolkit; 530 | ArrayList cells = this.cells; 531 | 532 | if (cells.size() > 0 && !cells.get(cells.size() - 1).endRow) endRow(); 533 | 534 | columnMinWidth = ensureSize(columnMinWidth, columns); 535 | rowMinHeight = ensureSize(rowMinHeight, rows); 536 | columnPrefWidth = ensureSize(columnPrefWidth, columns); 537 | rowPrefHeight = ensureSize(rowPrefHeight, rows); 538 | columnWidth = ensureSize(columnWidth, columns); 539 | rowHeight = ensureSize(rowHeight, rows); 540 | expandWidth = ensureSize(expandWidth, columns); 541 | expandHeight = ensureSize(expandHeight, rows); 542 | 543 | float spaceRightLast = 0; 544 | for (int i = 0, n = cells.size(); i < n; i++) { 545 | Cell c = cells.get(i); 546 | if (c.ignore) continue; 547 | 548 | // Collect columns/rows that expand. 549 | if (c.expandY != 0 && expandHeight[c.row] == 0) expandHeight[c.row] = c.expandY; 550 | if (c.colspan == 1 && c.expandX != 0 && expandWidth[c.column] == 0) expandWidth[c.column] = c.expandX; 551 | 552 | // Compute combined padding/spacing for cells. 553 | // Spacing between widgets isn't additive, the larger is used. Also, no spacing around edges. 554 | c.computedPadLeft = w(c.padLeft, c) + (c.column == 0 ? 0 : Math.max(0, w(c.spaceLeft, c) - spaceRightLast)); 555 | c.computedPadTop = h(c.padTop, c); 556 | if (c.cellAboveIndex != -1) { 557 | Cell above = cells.get(c.cellAboveIndex); 558 | c.computedPadTop += Math.max(0, h(c.spaceTop, c) - h(above.spaceBottom, above)); 559 | } 560 | float spaceRight = w(c.spaceRight, c); 561 | c.computedPadRight = w(c.padRight, c) + ((c.column + c.colspan) == columns ? 0 : spaceRight); 562 | c.computedPadBottom = h(c.padBottom, c) + (c.row == rows - 1 ? 0 : h(c.spaceBottom, c)); 563 | spaceRightLast = spaceRight; 564 | 565 | // Determine minimum and preferred cell sizes. 566 | float prefWidth = w(c.prefWidth, c); 567 | float prefHeight = h(c.prefHeight, c); 568 | float minWidth = w(c.minWidth, c); 569 | float minHeight = h(c.minHeight, c); 570 | float maxWidth = w(c.maxWidth, c); 571 | float maxHeight = h(c.maxHeight, c); 572 | if (prefWidth < minWidth) prefWidth = minWidth; 573 | if (prefHeight < minHeight) prefHeight = minHeight; 574 | if (maxWidth > 0 && prefWidth > maxWidth) prefWidth = maxWidth; 575 | if (maxHeight > 0 && prefHeight > maxHeight) prefHeight = maxHeight; 576 | 577 | if (c.colspan == 1) { // Spanned column min and pref width is added later. 578 | float hpadding = c.computedPadLeft + c.computedPadRight; 579 | columnPrefWidth[c.column] = Math.max(columnPrefWidth[c.column], prefWidth + hpadding); 580 | columnMinWidth[c.column] = Math.max(columnMinWidth[c.column], minWidth + hpadding); 581 | } 582 | float vpadding = c.computedPadTop + c.computedPadBottom; 583 | rowPrefHeight[c.row] = Math.max(rowPrefHeight[c.row], prefHeight + vpadding); 584 | rowMinHeight[c.row] = Math.max(rowMinHeight[c.row], minHeight + vpadding); 585 | } 586 | 587 | // Colspan with expand will expand all spanned columns if none of the spanned columns have expand. 588 | outer: 589 | for (int i = 0, n = cells.size(); i < n; i++) { 590 | Cell c = cells.get(i); 591 | if (c.ignore || c.expandX == 0) continue; 592 | for (int column = c.column, nn = column + c.colspan; column < nn; column++) 593 | if (expandWidth[column] != 0) continue outer; 594 | for (int column = c.column, nn = column + c.colspan; column < nn; column++) 595 | expandWidth[column] = c.expandX; 596 | } 597 | 598 | // Distribute any additional min and pref width added by colspanned cells to the columns spanned. 599 | for (int i = 0, n = cells.size(); i < n; i++) { 600 | Cell c = cells.get(i); 601 | if (c.ignore || c.colspan == 1) continue; 602 | 603 | float minWidth = w(c.minWidth, c); 604 | float prefWidth = w(c.prefWidth, c); 605 | float maxWidth = w(c.maxWidth, c); 606 | if (prefWidth < minWidth) prefWidth = minWidth; 607 | if (maxWidth > 0 && prefWidth > maxWidth) prefWidth = maxWidth; 608 | 609 | float spannedMinWidth = -(c.computedPadLeft + c.computedPadRight), spannedPrefWidth = spannedMinWidth; 610 | for (int column = c.column, nn = column + c.colspan; column < nn; column++) { 611 | spannedMinWidth += columnMinWidth[column]; 612 | spannedPrefWidth += columnPrefWidth[column]; 613 | } 614 | 615 | // Distribute extra space using expand, if any columns have expand. 616 | float totalExpandWidth = 0; 617 | for (int column = c.column, nn = column + c.colspan; column < nn; column++) 618 | totalExpandWidth += expandWidth[column]; 619 | 620 | float extraMinWidth = Math.max(0, minWidth - spannedMinWidth); 621 | float extraPrefWidth = Math.max(0, prefWidth - spannedPrefWidth); 622 | for (int column = c.column, nn = column + c.colspan; column < nn; column++) { 623 | float ratio = totalExpandWidth == 0 ? 1f / c.colspan : expandWidth[column] / totalExpandWidth; 624 | columnMinWidth[column] += extraMinWidth * ratio; 625 | columnPrefWidth[column] += extraPrefWidth * ratio; 626 | } 627 | } 628 | 629 | // Collect uniform size. 630 | float uniformMinWidth = 0, uniformMinHeight = 0; 631 | float uniformPrefWidth = 0, uniformPrefHeight = 0; 632 | for (int i = 0, n = cells.size(); i < n; i++) { 633 | Cell c = cells.get(i); 634 | if (c.ignore) continue; 635 | 636 | // Collect uniform sizes. 637 | if (c.uniformX == Boolean.TRUE && c.colspan == 1) { 638 | float hpadding = c.computedPadLeft + c.computedPadRight; 639 | uniformMinWidth = Math.max(uniformMinWidth, columnMinWidth[c.column] - hpadding); 640 | uniformPrefWidth = Math.max(uniformPrefWidth, columnPrefWidth[c.column] - hpadding); 641 | } 642 | if (c.uniformY == Boolean.TRUE) { 643 | float vpadding = c.computedPadTop + c.computedPadBottom; 644 | uniformMinHeight = Math.max(uniformMinHeight, rowMinHeight[c.row] - vpadding); 645 | uniformPrefHeight = Math.max(uniformPrefHeight, rowPrefHeight[c.row] - vpadding); 646 | } 647 | } 648 | 649 | // Size uniform cells to the same width/height. 650 | if (uniformPrefWidth > 0 || uniformPrefHeight > 0) { 651 | for (int i = 0, n = cells.size(); i < n; i++) { 652 | Cell c = cells.get(i); 653 | if (c.ignore) continue; 654 | if (uniformPrefWidth > 0 && c.uniformX == Boolean.TRUE && c.colspan == 1) { 655 | float hpadding = c.computedPadLeft + c.computedPadRight; 656 | columnMinWidth[c.column] = uniformMinWidth + hpadding; 657 | columnPrefWidth[c.column] = uniformPrefWidth + hpadding; 658 | } 659 | if (uniformPrefHeight > 0 && c.uniformY == Boolean.TRUE) { 660 | float vpadding = c.computedPadTop + c.computedPadBottom; 661 | rowMinHeight[c.row] = uniformMinHeight + vpadding; 662 | rowPrefHeight[c.row] = uniformPrefHeight + vpadding; 663 | } 664 | } 665 | } 666 | 667 | // Determine table min and pref size. 668 | tableMinWidth = 0; 669 | tableMinHeight = 0; 670 | tablePrefWidth = 0; 671 | tablePrefHeight = 0; 672 | for (int i = 0; i < columns; i++) { 673 | tableMinWidth += columnMinWidth[i]; 674 | tablePrefWidth += columnPrefWidth[i]; 675 | } 676 | for (int i = 0; i < rows; i++) { 677 | tableMinHeight += rowMinHeight[i]; 678 | tablePrefHeight += Math.max(rowMinHeight[i], rowPrefHeight[i]); 679 | } 680 | float hpadding = w(padLeft) + w(padRight); 681 | float vpadding = h(padTop) + h(padBottom); 682 | tableMinWidth = tableMinWidth + hpadding; 683 | tableMinHeight = tableMinHeight + vpadding; 684 | tablePrefWidth = Math.max(tablePrefWidth + hpadding, tableMinWidth); 685 | tablePrefHeight = Math.max(tablePrefHeight + vpadding, tableMinHeight); 686 | } 687 | 688 | /** Positions and sizes children of the table using the cell associated with each child. The values given are the position 689 | * within the parent and size of the table. */ 690 | public void layout (float layoutX, float layoutY, float layoutWidth, float layoutHeight) { 691 | Toolkit toolkit = this.toolkit; 692 | ArrayList cells = this.cells; 693 | 694 | if (sizeInvalid) computeSize(); 695 | 696 | float hpadding = w(padLeft) + w(padRight); 697 | float vpadding = h(padTop) + h(padBottom); 698 | 699 | float totalExpandWidth = 0, totalExpandHeight = 0; 700 | for (int i = 0; i < columns; i++) 701 | totalExpandWidth += expandWidth[i]; 702 | for (int i = 0; i < rows; i++) 703 | totalExpandHeight += expandHeight[i]; 704 | 705 | // Size columns and rows between min and pref size using (preferred - min) size to weight distribution of extra space. 706 | float[] columnWeightedWidth; 707 | float totalGrowWidth = tablePrefWidth - tableMinWidth; 708 | if (totalGrowWidth == 0) 709 | columnWeightedWidth = columnMinWidth; 710 | else { 711 | float extraWidth = Math.min(totalGrowWidth, Math.max(0, layoutWidth - tableMinWidth)); 712 | columnWeightedWidth = this.columnWeightedWidth = ensureSize(this.columnWeightedWidth, columns); 713 | for (int i = 0; i < columns; i++) { 714 | float growWidth = columnPrefWidth[i] - columnMinWidth[i]; 715 | float growRatio = growWidth / (float)totalGrowWidth; 716 | columnWeightedWidth[i] = columnMinWidth[i] + extraWidth * growRatio; 717 | } 718 | } 719 | 720 | float[] rowWeightedHeight; 721 | float totalGrowHeight = tablePrefHeight - tableMinHeight; 722 | if (totalGrowHeight == 0) 723 | rowWeightedHeight = rowMinHeight; 724 | else { 725 | rowWeightedHeight = this.rowWeightedHeight = ensureSize(this.rowWeightedHeight, rows); 726 | float extraHeight = Math.min(totalGrowHeight, Math.max(0, layoutHeight - tableMinHeight)); 727 | for (int i = 0; i < rows; i++) { 728 | float growHeight = rowPrefHeight[i] - rowMinHeight[i]; 729 | float growRatio = growHeight / (float)totalGrowHeight; 730 | rowWeightedHeight[i] = rowMinHeight[i] + extraHeight * growRatio; 731 | } 732 | } 733 | 734 | // Determine widget and cell sizes (before expand or fill). 735 | for (int i = 0, n = cells.size(); i < n; i++) { 736 | Cell c = cells.get(i); 737 | if (c.ignore) continue; 738 | 739 | float spannedWeightedWidth = 0; 740 | for (int column = c.column, nn = column + c.colspan; column < nn; column++) 741 | spannedWeightedWidth += columnWeightedWidth[column]; 742 | float weightedHeight = rowWeightedHeight[c.row]; 743 | 744 | float prefWidth = w(c.prefWidth, c); 745 | float prefHeight = h(c.prefHeight, c); 746 | float minWidth = w(c.minWidth, c); 747 | float minHeight = h(c.minHeight, c); 748 | float maxWidth = w(c.maxWidth, c); 749 | float maxHeight = h(c.maxHeight, c); 750 | if (prefWidth < minWidth) prefWidth = minWidth; 751 | if (prefHeight < minHeight) prefHeight = minHeight; 752 | if (maxWidth > 0 && prefWidth > maxWidth) prefWidth = maxWidth; 753 | if (maxHeight > 0 && prefHeight > maxHeight) prefHeight = maxHeight; 754 | 755 | c.widgetWidth = Math.min(spannedWeightedWidth - c.computedPadLeft - c.computedPadRight, prefWidth); 756 | c.widgetHeight = Math.min(weightedHeight - c.computedPadTop - c.computedPadBottom, prefHeight); 757 | 758 | if (c.colspan == 1) columnWidth[c.column] = Math.max(columnWidth[c.column], spannedWeightedWidth); 759 | rowHeight[c.row] = Math.max(rowHeight[c.row], weightedHeight); 760 | } 761 | 762 | // Distribute remaining space to any expanding columns/rows. 763 | if (totalExpandWidth > 0) { 764 | float extra = layoutWidth - hpadding; 765 | for (int i = 0; i < columns; i++) 766 | extra -= columnWidth[i]; 767 | float used = 0; 768 | int lastIndex = 0; 769 | for (int i = 0; i < columns; i++) { 770 | if (expandWidth[i] == 0) continue; 771 | float amount = extra * expandWidth[i] / totalExpandWidth; 772 | columnWidth[i] += amount; 773 | used += amount; 774 | lastIndex = i; 775 | } 776 | columnWidth[lastIndex] += extra - used; 777 | } 778 | if (totalExpandHeight > 0) { 779 | float extra = layoutHeight - vpadding; 780 | for (int i = 0; i < rows; i++) 781 | extra -= rowHeight[i]; 782 | float used = 0; 783 | int lastIndex = 0; 784 | for (int i = 0; i < rows; i++) { 785 | if (expandHeight[i] == 0) continue; 786 | float amount = extra * expandHeight[i] / totalExpandHeight; 787 | rowHeight[i] += amount; 788 | used += amount; 789 | lastIndex = i; 790 | } 791 | rowHeight[lastIndex] += extra - used; 792 | } 793 | 794 | // Distribute any additional width added by colspanned cells to the columns spanned. 795 | for (int i = 0, n = cells.size(); i < n; i++) { 796 | Cell c = cells.get(i); 797 | if (c.ignore) continue; 798 | if (c.colspan == 1) continue; 799 | 800 | float extraWidth = 0; 801 | for (int column = c.column, nn = column + c.colspan; column < nn; column++) 802 | extraWidth += columnWeightedWidth[column] - columnWidth[column]; 803 | extraWidth -= Math.max(0, c.computedPadLeft + c.computedPadRight); 804 | 805 | extraWidth /= c.colspan; 806 | if (extraWidth > 0) { 807 | for (int column = c.column, nn = column + c.colspan; column < nn; column++) 808 | columnWidth[column] += extraWidth; 809 | } 810 | } 811 | 812 | // Determine table size. 813 | float tableWidth = hpadding, tableHeight = vpadding; 814 | for (int i = 0; i < columns; i++) 815 | tableWidth += columnWidth[i]; 816 | for (int i = 0; i < rows; i++) 817 | tableHeight += rowHeight[i]; 818 | 819 | // Position table within the container. 820 | float x = layoutX + w(padLeft); 821 | if ((align & RIGHT) != 0) 822 | x += layoutWidth - tableWidth; 823 | else if ((align & LEFT) == 0) // Center 824 | x += (layoutWidth - tableWidth) / 2; 825 | 826 | float y = layoutY + h(padTop); 827 | if ((align & BOTTOM) != 0) 828 | y += layoutHeight - tableHeight; 829 | else if ((align & TOP) == 0) // Center 830 | y += (layoutHeight - tableHeight) / 2; 831 | 832 | // Position widgets within cells. 833 | float currentX = x, currentY = y; 834 | for (int i = 0, n = cells.size(); i < n; i++) { 835 | Cell c = cells.get(i); 836 | if (c.ignore) continue; 837 | 838 | float spannedCellWidth = 0; 839 | for (int column = c.column, nn = column + c.colspan; column < nn; column++) 840 | spannedCellWidth += columnWidth[column]; 841 | spannedCellWidth -= c.computedPadLeft + c.computedPadRight; 842 | 843 | currentX += c.computedPadLeft; 844 | 845 | if (c.fillX > 0) { 846 | c.widgetWidth = spannedCellWidth * c.fillX; 847 | float maxWidth = w(c.maxWidth, c); 848 | if (maxWidth > 0) c.widgetWidth = Math.min(c.widgetWidth, maxWidth); 849 | } 850 | if (c.fillY > 0) { 851 | c.widgetHeight = rowHeight[c.row] * c.fillY - c.computedPadTop - c.computedPadBottom; 852 | float maxHeight = h(c.maxHeight, c); 853 | if (maxHeight > 0) c.widgetHeight = Math.min(c.widgetHeight, maxHeight); 854 | } 855 | 856 | if ((c.align & LEFT) != 0) 857 | c.widgetX = currentX; 858 | else if ((c.align & RIGHT) != 0) 859 | c.widgetX = currentX + spannedCellWidth - c.widgetWidth; 860 | else 861 | c.widgetX = currentX + (spannedCellWidth - c.widgetWidth) / 2; 862 | 863 | if ((c.align & TOP) != 0) 864 | c.widgetY = currentY + c.computedPadTop; 865 | else if ((c.align & BOTTOM) != 0) 866 | c.widgetY = currentY + rowHeight[c.row] - c.widgetHeight - c.computedPadBottom; 867 | else 868 | c.widgetY = currentY + (rowHeight[c.row] - c.widgetHeight + c.computedPadTop - c.computedPadBottom) / 2; 869 | 870 | if (c.endRow) { 871 | currentX = x; 872 | currentY += rowHeight[c.row]; 873 | } else 874 | currentX += spannedCellWidth + c.computedPadRight; 875 | } 876 | 877 | // Draw debug widgets and bounds. 878 | if (debug == Debug.none) return; 879 | toolkit.clearDebugRectangles(this); 880 | currentX = x; 881 | currentY = y; 882 | if (debug == Debug.table || debug == Debug.all) { 883 | toolkit.addDebugRectangle(this, Debug.table, layoutX, layoutY, layoutWidth, layoutHeight); 884 | toolkit.addDebugRectangle(this, Debug.table, x, y, tableWidth - hpadding, tableHeight - vpadding); 885 | } 886 | for (int i = 0, n = cells.size(); i < n; i++) { 887 | Cell c = cells.get(i); 888 | if (c.ignore) continue; 889 | 890 | // Widget bounds. 891 | if (debug == Debug.widget || debug == Debug.all) 892 | toolkit.addDebugRectangle(this, Debug.widget, c.widgetX, c.widgetY, c.widgetWidth, c.widgetHeight); 893 | 894 | // Cell bounds. 895 | float spannedCellWidth = 0; 896 | for (int column = c.column, nn = column + c.colspan; column < nn; column++) 897 | spannedCellWidth += columnWidth[column]; 898 | spannedCellWidth -= c.computedPadLeft + c.computedPadRight; 899 | currentX += c.computedPadLeft; 900 | if (debug == Debug.cell || debug == Debug.all) { 901 | toolkit.addDebugRectangle(this, Debug.cell, currentX, currentY + c.computedPadTop, spannedCellWidth, rowHeight[c.row] 902 | - c.computedPadTop - c.computedPadBottom); 903 | } 904 | 905 | if (c.endRow) { 906 | currentX = x; 907 | currentY += rowHeight[c.row]; 908 | } else 909 | currentX += spannedCellWidth + c.computedPadRight; 910 | } 911 | } 912 | } 913 | -------------------------------------------------------------------------------- /tablelayout/src/com/esotericsoftware/tablelayout/Cell.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2011, Nathan Sweet 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | ******************************************************************************/ 27 | 28 | package com.esotericsoftware.tablelayout; 29 | 30 | import com.esotericsoftware.tablelayout.Value.FixedValue; 31 | 32 | import static com.esotericsoftware.tablelayout.BaseTableLayout.*; 33 | 34 | /** A cell in a table. 35 | * @author Nathan Sweet */ 36 | public class Cell { 37 | Value minWidth, minHeight; 38 | Value prefWidth, prefHeight; 39 | Value maxWidth, maxHeight; 40 | Value spaceTop, spaceLeft, spaceBottom, spaceRight; 41 | Value padTop, padLeft, padBottom, padRight; 42 | Float fillX, fillY; 43 | Integer align; 44 | Integer expandX, expandY; 45 | Boolean ignore; 46 | Integer colspan; 47 | Boolean uniformX, uniformY; 48 | 49 | C widget; 50 | float widgetX, widgetY; 51 | float widgetWidth, widgetHeight; 52 | 53 | private BaseTableLayout layout; 54 | boolean endRow; 55 | int column, row; 56 | int cellAboveIndex = -1; 57 | float computedPadTop, computedPadLeft, computedPadBottom, computedPadRight; 58 | 59 | public Cell () { 60 | } 61 | 62 | public void setLayout (BaseTableLayout layout) { 63 | this.layout = layout; 64 | } 65 | 66 | void set (Cell defaults) { 67 | minWidth = defaults.minWidth; 68 | minHeight = defaults.minHeight; 69 | prefWidth = defaults.prefWidth; 70 | prefHeight = defaults.prefHeight; 71 | maxWidth = defaults.maxWidth; 72 | maxHeight = defaults.maxHeight; 73 | spaceTop = defaults.spaceTop; 74 | spaceLeft = defaults.spaceLeft; 75 | spaceBottom = defaults.spaceBottom; 76 | spaceRight = defaults.spaceRight; 77 | padTop = defaults.padTop; 78 | padLeft = defaults.padLeft; 79 | padBottom = defaults.padBottom; 80 | padRight = defaults.padRight; 81 | fillX = defaults.fillX; 82 | fillY = defaults.fillY; 83 | align = defaults.align; 84 | expandX = defaults.expandX; 85 | expandY = defaults.expandY; 86 | ignore = defaults.ignore; 87 | colspan = defaults.colspan; 88 | uniformX = defaults.uniformX; 89 | uniformY = defaults.uniformY; 90 | } 91 | 92 | void merge (Cell cell) { 93 | if (cell == null) return; 94 | if (cell.minWidth != null) minWidth = cell.minWidth; 95 | if (cell.minHeight != null) minHeight = cell.minHeight; 96 | if (cell.prefWidth != null) prefWidth = cell.prefWidth; 97 | if (cell.prefHeight != null) prefHeight = cell.prefHeight; 98 | if (cell.maxWidth != null) maxWidth = cell.maxWidth; 99 | if (cell.maxHeight != null) maxHeight = cell.maxHeight; 100 | if (cell.spaceTop != null) spaceTop = cell.spaceTop; 101 | if (cell.spaceLeft != null) spaceLeft = cell.spaceLeft; 102 | if (cell.spaceBottom != null) spaceBottom = cell.spaceBottom; 103 | if (cell.spaceRight != null) spaceRight = cell.spaceRight; 104 | if (cell.padTop != null) padTop = cell.padTop; 105 | if (cell.padLeft != null) padLeft = cell.padLeft; 106 | if (cell.padBottom != null) padBottom = cell.padBottom; 107 | if (cell.padRight != null) padRight = cell.padRight; 108 | if (cell.fillX != null) fillX = cell.fillX; 109 | if (cell.fillY != null) fillY = cell.fillY; 110 | if (cell.align != null) align = cell.align; 111 | if (cell.expandX != null) expandX = cell.expandX; 112 | if (cell.expandY != null) expandY = cell.expandY; 113 | if (cell.ignore != null) ignore = cell.ignore; 114 | if (cell.colspan != null) colspan = cell.colspan; 115 | if (cell.uniformX != null) uniformX = cell.uniformX; 116 | if (cell.uniformY != null) uniformY = cell.uniformY; 117 | } 118 | 119 | /** Sets the widget in this cell and adds the widget to the cell's table. If null, removes any current widget. */ 120 | public Cell setWidget (C widget) { 121 | layout.toolkit.setWidget(layout, this, widget); 122 | return this; 123 | } 124 | 125 | /** Returns the widget for this cell, or null. */ 126 | public C getWidget () { 127 | return widget; 128 | } 129 | 130 | /** Returns true if the cell's widget is not null. */ 131 | public boolean hasWidget () { 132 | return widget != null; 133 | } 134 | 135 | /** Sets the minWidth, prefWidth, maxWidth, minHeight, prefHeight, and maxHeight to the specified value. */ 136 | public Cell size (Value size) { 137 | minWidth = size; 138 | minHeight = size; 139 | prefWidth = size; 140 | prefHeight = size; 141 | maxWidth = size; 142 | maxHeight = size; 143 | return this; 144 | } 145 | 146 | /** Sets the minWidth, prefWidth, maxWidth, minHeight, prefHeight, and maxHeight to the specified values. */ 147 | public Cell size (Value width, Value height) { 148 | minWidth = width; 149 | minHeight = height; 150 | prefWidth = width; 151 | prefHeight = height; 152 | maxWidth = width; 153 | maxHeight = height; 154 | return this; 155 | } 156 | 157 | /** Sets the minWidth, prefWidth, maxWidth, minHeight, prefHeight, and maxHeight to the specified value. */ 158 | public Cell size (float size) { 159 | size(new FixedValue(size)); 160 | return this; 161 | } 162 | 163 | /** Sets the minWidth, prefWidth, maxWidth, minHeight, prefHeight, and maxHeight to the specified values. */ 164 | public Cell size (float width, float height) { 165 | size(new FixedValue(width), new FixedValue(height)); 166 | return this; 167 | } 168 | 169 | /** Sets the minWidth, prefWidth, and maxWidth to the specified value. */ 170 | public Cell width (Value width) { 171 | minWidth = width; 172 | prefWidth = width; 173 | maxWidth = width; 174 | return this; 175 | } 176 | 177 | /** Sets the minWidth, prefWidth, and maxWidth to the specified value. */ 178 | public Cell width (float width) { 179 | width(new FixedValue(width)); 180 | return this; 181 | } 182 | 183 | /** Sets the minHeight, prefHeight, and maxHeight to the specified value. */ 184 | public Cell height (Value height) { 185 | minHeight = height; 186 | prefHeight = height; 187 | maxHeight = height; 188 | return this; 189 | } 190 | 191 | /** Sets the minHeight, prefHeight, and maxHeight to the specified value. */ 192 | public Cell height (float height) { 193 | height(new FixedValue(height)); 194 | return this; 195 | } 196 | 197 | /** Sets the minWidth and minHeight to the specified value. */ 198 | public Cell minSize (Value size) { 199 | minWidth = size; 200 | minHeight = size; 201 | return this; 202 | } 203 | 204 | /** Sets the minWidth and minHeight to the specified values. */ 205 | public Cell minSize (Value width, Value height) { 206 | minWidth = width; 207 | minHeight = height; 208 | return this; 209 | } 210 | 211 | public Cell minWidth (Value minWidth) { 212 | this.minWidth = minWidth; 213 | return this; 214 | } 215 | 216 | public Cell minHeight (Value minHeight) { 217 | this.minHeight = minHeight; 218 | return this; 219 | } 220 | 221 | /** Sets the minWidth and minHeight to the specified value. */ 222 | public Cell minSize (float size) { 223 | minWidth = new FixedValue(size); 224 | minHeight = new FixedValue(size); 225 | return this; 226 | } 227 | 228 | /** Sets the minWidth and minHeight to the specified values. */ 229 | public Cell minSize (float width, float height) { 230 | minWidth = new FixedValue(width); 231 | minHeight = new FixedValue(height); 232 | return this; 233 | } 234 | 235 | public Cell minWidth (float minWidth) { 236 | this.minWidth = new FixedValue(minWidth); 237 | return this; 238 | } 239 | 240 | public Cell minHeight (float minHeight) { 241 | this.minHeight = new FixedValue(minHeight); 242 | return this; 243 | } 244 | 245 | /** Sets the prefWidth and prefHeight to the specified value. */ 246 | public Cell prefSize (Value size) { 247 | prefWidth = size; 248 | prefHeight = size; 249 | return this; 250 | } 251 | 252 | /** Sets the prefWidth and prefHeight to the specified values. */ 253 | public Cell prefSize (Value width, Value height) { 254 | prefWidth = width; 255 | prefHeight = height; 256 | return this; 257 | } 258 | 259 | public Cell prefWidth (Value prefWidth) { 260 | this.prefWidth = prefWidth; 261 | return this; 262 | } 263 | 264 | public Cell prefHeight (Value prefHeight) { 265 | this.prefHeight = prefHeight; 266 | return this; 267 | } 268 | 269 | /** Sets the prefWidth and prefHeight to the specified value. */ 270 | public Cell prefSize (float width, float height) { 271 | prefWidth = new FixedValue(width); 272 | prefHeight = new FixedValue(height); 273 | return this; 274 | } 275 | 276 | /** Sets the prefWidth and prefHeight to the specified values. */ 277 | public Cell prefSize (float size) { 278 | prefWidth = new FixedValue(size); 279 | prefHeight = new FixedValue(size); 280 | return this; 281 | } 282 | 283 | public Cell prefWidth (float prefWidth) { 284 | this.prefWidth = new FixedValue(prefWidth); 285 | return this; 286 | } 287 | 288 | public Cell prefHeight (float prefHeight) { 289 | this.prefHeight = new FixedValue(prefHeight); 290 | return this; 291 | } 292 | 293 | /** Sets the maxWidth and maxHeight to the specified value. */ 294 | public Cell maxSize (Value size) { 295 | maxWidth = size; 296 | maxHeight = size; 297 | return this; 298 | } 299 | 300 | /** Sets the maxWidth and maxHeight to the specified values. */ 301 | public Cell maxSize (Value width, Value height) { 302 | maxWidth = width; 303 | maxHeight = height; 304 | return this; 305 | } 306 | 307 | public Cell maxWidth (Value maxWidth) { 308 | this.maxWidth = maxWidth; 309 | return this; 310 | } 311 | 312 | public Cell maxHeight (Value maxHeight) { 313 | this.maxHeight = maxHeight; 314 | return this; 315 | } 316 | 317 | /** Sets the maxWidth and maxHeight to the specified value. */ 318 | public Cell maxSize (float size) { 319 | maxWidth = new FixedValue(size); 320 | maxHeight = new FixedValue(size); 321 | return this; 322 | } 323 | 324 | /** Sets the maxWidth and maxHeight to the specified values. */ 325 | public Cell maxSize (float width, float height) { 326 | maxWidth = new FixedValue(width); 327 | maxHeight = new FixedValue(height); 328 | return this; 329 | } 330 | 331 | public Cell maxWidth (float maxWidth) { 332 | this.maxWidth = new FixedValue(maxWidth); 333 | return this; 334 | } 335 | 336 | public Cell maxHeight (float maxHeight) { 337 | this.maxHeight = new FixedValue(maxHeight); 338 | return this; 339 | } 340 | 341 | /** Sets the spaceTop, spaceLeft, spaceBottom, and spaceRight to the specified value. */ 342 | public Cell space (Value space) { 343 | spaceTop = space; 344 | spaceLeft = space; 345 | spaceBottom = space; 346 | spaceRight = space; 347 | return this; 348 | } 349 | 350 | public Cell space (Value top, Value left, Value bottom, Value right) { 351 | spaceTop = top; 352 | spaceLeft = left; 353 | spaceBottom = bottom; 354 | spaceRight = right; 355 | return this; 356 | } 357 | 358 | public Cell spaceTop (Value spaceTop) { 359 | this.spaceTop = spaceTop; 360 | return this; 361 | } 362 | 363 | public Cell spaceLeft (Value spaceLeft) { 364 | this.spaceLeft = spaceLeft; 365 | return this; 366 | } 367 | 368 | public Cell spaceBottom (Value spaceBottom) { 369 | this.spaceBottom = spaceBottom; 370 | return this; 371 | } 372 | 373 | public Cell spaceRight (Value spaceRight) { 374 | this.spaceRight = spaceRight; 375 | return this; 376 | } 377 | 378 | /** Sets the spaceTop, spaceLeft, spaceBottom, and spaceRight to the specified value. */ 379 | public Cell space (float space) { 380 | if (space < 0) throw new IllegalArgumentException("space cannot be < 0."); 381 | Value value = new FixedValue(space); 382 | spaceTop = value; 383 | spaceLeft = value; 384 | spaceBottom = value; 385 | spaceRight = value; 386 | return this; 387 | } 388 | 389 | public Cell space (float top, float left, float bottom, float right) { 390 | if (top < 0) throw new IllegalArgumentException("top cannot be < 0."); 391 | if (left < 0) throw new IllegalArgumentException("left cannot be < 0."); 392 | if (bottom < 0) throw new IllegalArgumentException("bottom cannot be < 0."); 393 | if (right < 0) throw new IllegalArgumentException("right cannot be < 0."); 394 | spaceTop = new FixedValue(top); 395 | spaceLeft = new FixedValue(left); 396 | spaceBottom = new FixedValue(bottom); 397 | spaceRight = new FixedValue(right); 398 | return this; 399 | } 400 | 401 | public Cell spaceTop (float spaceTop) { 402 | if (spaceTop < 0) throw new IllegalArgumentException("spaceTop cannot be < 0."); 403 | this.spaceTop = new FixedValue(spaceTop); 404 | return this; 405 | } 406 | 407 | public Cell spaceLeft (float spaceLeft) { 408 | if (spaceLeft < 0) throw new IllegalArgumentException("spaceLeft cannot be < 0."); 409 | this.spaceLeft = new FixedValue(spaceLeft); 410 | return this; 411 | } 412 | 413 | public Cell spaceBottom (float spaceBottom) { 414 | if (spaceBottom < 0) throw new IllegalArgumentException("spaceBottom cannot be < 0."); 415 | this.spaceBottom = new FixedValue(spaceBottom); 416 | return this; 417 | } 418 | 419 | public Cell spaceRight (float spaceRight) { 420 | if (spaceRight < 0) throw new IllegalArgumentException("spaceRight cannot be < 0."); 421 | this.spaceRight = new FixedValue(spaceRight); 422 | return this; 423 | } 424 | 425 | /** Sets the padTop, padLeft, padBottom, and padRight to the specified value. */ 426 | public Cell pad (Value pad) { 427 | padTop = pad; 428 | padLeft = pad; 429 | padBottom = pad; 430 | padRight = pad; 431 | return this; 432 | } 433 | 434 | public Cell pad (Value top, Value left, Value bottom, Value right) { 435 | padTop = top; 436 | padLeft = left; 437 | padBottom = bottom; 438 | padRight = right; 439 | return this; 440 | } 441 | 442 | public Cell padTop (Value padTop) { 443 | this.padTop = padTop; 444 | return this; 445 | } 446 | 447 | public Cell padLeft (Value padLeft) { 448 | this.padLeft = padLeft; 449 | return this; 450 | } 451 | 452 | public Cell padBottom (Value padBottom) { 453 | this.padBottom = padBottom; 454 | return this; 455 | } 456 | 457 | public Cell padRight (Value padRight) { 458 | this.padRight = padRight; 459 | return this; 460 | } 461 | 462 | /** Sets the padTop, padLeft, padBottom, and padRight to the specified value. */ 463 | public Cell pad (float pad) { 464 | Value value = new FixedValue(pad); 465 | padTop = value; 466 | padLeft = value; 467 | padBottom = value; 468 | padRight = value; 469 | return this; 470 | } 471 | 472 | public Cell pad (float top, float left, float bottom, float right) { 473 | padTop = new FixedValue(top); 474 | padLeft = new FixedValue(left); 475 | padBottom = new FixedValue(bottom); 476 | padRight = new FixedValue(right); 477 | return this; 478 | } 479 | 480 | public Cell padTop (float padTop) { 481 | this.padTop = new FixedValue(padTop); 482 | return this; 483 | } 484 | 485 | public Cell padLeft (float padLeft) { 486 | this.padLeft = new FixedValue(padLeft); 487 | return this; 488 | } 489 | 490 | public Cell padBottom (float padBottom) { 491 | this.padBottom = new FixedValue(padBottom); 492 | return this; 493 | } 494 | 495 | public Cell padRight (float padRight) { 496 | this.padRight = new FixedValue(padRight); 497 | return this; 498 | } 499 | 500 | /** Sets fillX and fillY to 1. */ 501 | public Cell fill () { 502 | fillX = 1f; 503 | fillY = 1f; 504 | return this; 505 | } 506 | 507 | /** Sets fillX to 1. */ 508 | public Cell fillX () { 509 | fillX = 1f; 510 | return this; 511 | } 512 | 513 | /** Sets fillY to 1. */ 514 | public Cell fillY () { 515 | fillY = 1f; 516 | return this; 517 | } 518 | 519 | public Cell fill (Float x, Float y) { 520 | fillX = x; 521 | fillY = y; 522 | return this; 523 | } 524 | 525 | /** Sets fillX and fillY to 1 if true, 0 if false. */ 526 | public Cell fill (boolean x, boolean y) { 527 | fillX = x ? 1f : 0; 528 | fillY = y ? 1f : 0; 529 | return this; 530 | } 531 | 532 | /** Sets fillX and fillY to 1 if true, 0 if false. */ 533 | public Cell fill (boolean fill) { 534 | fillX = fill ? 1f : 0; 535 | fillY = fill ? 1f : 0; 536 | return this; 537 | } 538 | 539 | /** Sets the alignment of the widget within the cell. Set to {@link #CENTER}, {@link #TOP}, {@link #BOTTOM}, {@link #LEFT}, 540 | * {@link #RIGHT}, or any combination of those. */ 541 | public Cell align (Integer align) { 542 | this.align = align; 543 | return this; 544 | } 545 | 546 | /** Sets the alignment of the widget within the cell to {@link #CENTER}. This clears any other alignment. */ 547 | public Cell center () { 548 | align = CENTER; 549 | return this; 550 | } 551 | 552 | /** Adds {@link #TOP} and clears {@link #BOTTOM} for the alignment of the widget within the cell. */ 553 | public Cell top () { 554 | if (align == null) 555 | align = TOP; 556 | else { 557 | align |= TOP; 558 | align &= ~BOTTOM; 559 | } 560 | return this; 561 | } 562 | 563 | /** Adds {@link #LEFT} and clears {@link #RIGHT} for the alignment of the widget within the cell. */ 564 | public Cell left () { 565 | if (align == null) 566 | align = LEFT; 567 | else { 568 | align |= LEFT; 569 | align &= ~RIGHT; 570 | } 571 | return this; 572 | } 573 | 574 | /** Adds {@link #BOTTOM} and clears {@link #TOP} for the alignment of the widget within the cell. */ 575 | public Cell bottom () { 576 | if (align == null) 577 | align = BOTTOM; 578 | else { 579 | align |= BOTTOM; 580 | align &= ~TOP; 581 | } 582 | return this; 583 | } 584 | 585 | /** Adds {@link #RIGHT} and clears {@link #LEFT} for the alignment of the widget within the cell. */ 586 | public Cell right () { 587 | if (align == null) 588 | align = RIGHT; 589 | else { 590 | align |= RIGHT; 591 | align &= ~LEFT; 592 | } 593 | return this; 594 | } 595 | 596 | /** Sets expandX and expandY to 1. */ 597 | public Cell expand () { 598 | expandX = 1; 599 | expandY = 1; 600 | return this; 601 | } 602 | 603 | /** Sets expandX to 1. */ 604 | public Cell expandX () { 605 | expandX = 1; 606 | return this; 607 | } 608 | 609 | /** Sets expandY to 1. */ 610 | public Cell expandY () { 611 | expandY = 1; 612 | return this; 613 | } 614 | 615 | public Cell expand (Integer x, Integer y) { 616 | expandX = x; 617 | expandY = y; 618 | return this; 619 | } 620 | 621 | /** Sets expandX and expandY to 1 if true, 0 if false. */ 622 | public Cell expand (boolean x, boolean y) { 623 | expandX = x ? 1 : 0; 624 | expandY = y ? 1 : 0; 625 | return this; 626 | } 627 | 628 | public Cell ignore (Boolean ignore) { 629 | this.ignore = ignore; 630 | return this; 631 | } 632 | 633 | /** Sets ignore to true. */ 634 | public Cell ignore () { 635 | this.ignore = true; 636 | return this; 637 | } 638 | 639 | public boolean getIgnore () { 640 | return ignore != null && ignore == true; 641 | } 642 | 643 | public Cell colspan (Integer colspan) { 644 | this.colspan = colspan; 645 | return this; 646 | } 647 | 648 | /** Sets uniformX and uniformY to true. */ 649 | public Cell uniform () { 650 | uniformX = true; 651 | uniformY = true; 652 | return this; 653 | } 654 | 655 | /** Sets uniformX to true. */ 656 | public Cell uniformX () { 657 | uniformX = true; 658 | return this; 659 | } 660 | 661 | /** Sets uniformY to true. */ 662 | public Cell uniformY () { 663 | uniformY = true; 664 | return this; 665 | } 666 | 667 | public Cell uniform (Boolean x, Boolean y) { 668 | uniformX = x; 669 | uniformY = y; 670 | return this; 671 | } 672 | 673 | public float getWidgetX () { 674 | return widgetX; 675 | } 676 | 677 | public void setWidgetX (float widgetX) { 678 | this.widgetX = widgetX; 679 | } 680 | 681 | public float getWidgetY () { 682 | return widgetY; 683 | } 684 | 685 | public void setWidgetY (float widgetY) { 686 | this.widgetY = widgetY; 687 | } 688 | 689 | public float getWidgetWidth () { 690 | return widgetWidth; 691 | } 692 | 693 | public void setWidgetWidth (float widgetWidth) { 694 | this.widgetWidth = widgetWidth; 695 | } 696 | 697 | public float getWidgetHeight () { 698 | return widgetHeight; 699 | } 700 | 701 | public void setWidgetHeight (float widgetHeight) { 702 | this.widgetHeight = widgetHeight; 703 | } 704 | 705 | public int getColumn () { 706 | return column; 707 | } 708 | 709 | public int getRow () { 710 | return row; 711 | } 712 | 713 | /** @return May be null if this cell is row defaults. */ 714 | public Value getMinWidthValue () { 715 | return minWidth; 716 | } 717 | 718 | public float getMinWidth () { 719 | return minWidth == null ? 0 : minWidth.width(this); 720 | } 721 | 722 | /** @return May be null if this cell is row defaults. */ 723 | public Value getMinHeightValue () { 724 | return minHeight; 725 | } 726 | 727 | public float getMinHeight () { 728 | return minHeight == null ? 0 : minHeight.height(this); 729 | } 730 | 731 | /** @return May be null if this cell is row defaults. */ 732 | public Value getPrefWidthValue () { 733 | return prefWidth; 734 | } 735 | 736 | public float getPrefWidth () { 737 | return prefWidth == null ? 0 : prefWidth.width(this); 738 | } 739 | 740 | /** @return May be null if this cell is row defaults. */ 741 | public Value getPrefHeightValue () { 742 | return prefHeight; 743 | } 744 | 745 | public float getPrefHeight () { 746 | return prefHeight == null ? 0 : prefHeight.height(this); 747 | } 748 | 749 | /** @return May be null if this cell is row defaults. */ 750 | public Value getMaxWidthValue () { 751 | return maxWidth; 752 | } 753 | 754 | public float getMaxWidth () { 755 | return maxWidth == null ? 0 : maxWidth.width(this); 756 | } 757 | 758 | /** @return May be null if this cell is row defaults. */ 759 | public Value getMaxHeightValue () { 760 | return maxHeight; 761 | } 762 | 763 | public float getMaxHeight () { 764 | return maxHeight == null ? 0 : maxHeight.height(this); 765 | } 766 | 767 | /** @return May be null if this value is not set. */ 768 | public Value getSpaceTopValue () { 769 | return spaceTop; 770 | } 771 | 772 | public float getSpaceTop () { 773 | return spaceTop == null ? 0 : spaceTop.height(this); 774 | } 775 | 776 | /** @return May be null if this value is not set. */ 777 | public Value getSpaceLeftValue () { 778 | return spaceLeft; 779 | } 780 | 781 | public float getSpaceLeft () { 782 | return spaceLeft == null ? 0 : spaceLeft.width(this); 783 | } 784 | 785 | /** @return May be null if this value is not set. */ 786 | public Value getSpaceBottomValue () { 787 | return spaceBottom; 788 | } 789 | 790 | public float getSpaceBottom () { 791 | return spaceBottom == null ? 0 : spaceBottom.height(this); 792 | } 793 | 794 | /** @return May be null if this value is not set. */ 795 | public Value getSpaceRightValue () { 796 | return spaceRight; 797 | } 798 | 799 | public float getSpaceRight () { 800 | return spaceRight == null ? 0 : spaceRight.width(this); 801 | } 802 | 803 | /** @return May be null if this value is not set. */ 804 | public Value getPadTopValue () { 805 | return padTop; 806 | } 807 | 808 | public float getPadTop () { 809 | return padTop == null ? 0 : padTop.height(this); 810 | } 811 | 812 | /** @return May be null if this value is not set. */ 813 | public Value getPadLeftValue () { 814 | return padLeft; 815 | } 816 | 817 | public float getPadLeft () { 818 | return padLeft == null ? 0 : padLeft.width(this); 819 | } 820 | 821 | /** @return May be null if this value is not set. */ 822 | public Value getPadBottomValue () { 823 | return padBottom; 824 | } 825 | 826 | public float getPadBottom () { 827 | return padBottom == null ? 0 : padBottom.height(this); 828 | } 829 | 830 | /** @return May be null if this value is not set. */ 831 | public Value getPadRightValue () { 832 | return padRight; 833 | } 834 | 835 | public float getPadRight () { 836 | return padRight == null ? 0 : padRight.width(this); 837 | } 838 | 839 | /** @return May be null if this value is not set. */ 840 | public Float getFillX () { 841 | return fillX; 842 | } 843 | 844 | /** @return May be null. */ 845 | public Float getFillY () { 846 | return fillY; 847 | } 848 | 849 | /** @return May be null. */ 850 | public Integer getAlign () { 851 | return align; 852 | } 853 | 854 | /** @return May be null. */ 855 | public Integer getExpandX () { 856 | return expandX; 857 | } 858 | 859 | /** @return May be null. */ 860 | public Integer getExpandY () { 861 | return expandY; 862 | } 863 | 864 | /** @return May be null. */ 865 | public Integer getColspan () { 866 | return colspan; 867 | } 868 | 869 | /** @return May be null. */ 870 | public Boolean getUniformX () { 871 | return uniformX; 872 | } 873 | 874 | /** @return May be null. */ 875 | public Boolean getUniformY () { 876 | return uniformY; 877 | } 878 | 879 | /** Returns true if this cell is the last cell in the row. */ 880 | public boolean isEndRow () { 881 | return endRow; 882 | } 883 | 884 | /** The actual amount of combined padding and spacing from the last layout. */ 885 | public float getComputedPadTop () { 886 | return computedPadTop; 887 | } 888 | 889 | /** The actual amount of combined padding and spacing from the last layout. */ 890 | public float getComputedPadLeft () { 891 | return computedPadLeft; 892 | } 893 | 894 | /** The actual amount of combined padding and spacing from the last layout. */ 895 | public float getComputedPadBottom () { 896 | return computedPadBottom; 897 | } 898 | 899 | /** The actual amount of combined padding and spacing from the last layout. */ 900 | public float getComputedPadRight () { 901 | return computedPadRight; 902 | } 903 | 904 | public Cell row () { 905 | return layout.row(); 906 | } 907 | 908 | public BaseTableLayout getLayout () { 909 | return layout; 910 | } 911 | 912 | /** Sets all constraint fields to null. */ 913 | public void clear () { 914 | minWidth = null; 915 | minHeight = null; 916 | prefWidth = null; 917 | prefHeight = null; 918 | maxWidth = null; 919 | maxHeight = null; 920 | spaceTop = null; 921 | spaceLeft = null; 922 | spaceBottom = null; 923 | spaceRight = null; 924 | padTop = null; 925 | padLeft = null; 926 | padBottom = null; 927 | padRight = null; 928 | fillX = null; 929 | fillY = null; 930 | align = null; 931 | expandX = null; 932 | expandY = null; 933 | ignore = null; 934 | colspan = null; 935 | uniformX = null; 936 | uniformY = null; 937 | } 938 | 939 | /** Reset state so the cell can be reused. Doesn't reset the constraint fields. */ 940 | public void free () { 941 | widget = null; 942 | layout = null; 943 | endRow = false; 944 | cellAboveIndex = -1; 945 | } 946 | 947 | /** Set all constraints to cell default values. */ 948 | void defaults () { 949 | minWidth = Value.minWidth; 950 | minHeight = Value.minHeight; 951 | prefWidth = Value.prefWidth; 952 | prefHeight = Value.prefHeight; 953 | maxWidth = Value.maxWidth; 954 | maxHeight = Value.maxHeight; 955 | spaceTop = Value.zero; 956 | spaceLeft = Value.zero; 957 | spaceBottom = Value.zero; 958 | spaceRight = Value.zero; 959 | padTop = Value.zero; 960 | padLeft = Value.zero; 961 | padBottom = Value.zero; 962 | padRight = Value.zero; 963 | fillX = 0f; 964 | fillY = 0f; 965 | align = CENTER; 966 | expandX = 0; 967 | expandY = 0; 968 | ignore = false; 969 | colspan = 1; 970 | uniformX = null; 971 | uniformY = null; 972 | } 973 | } 974 | -------------------------------------------------------------------------------- /tablelayout/src/com/esotericsoftware/tablelayout/Toolkit.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2011, Nathan Sweet 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | ******************************************************************************/ 27 | 28 | package com.esotericsoftware.tablelayout; 29 | 30 | import com.esotericsoftware.tablelayout.BaseTableLayout.Debug; 31 | 32 | /** Base class for UI toolkit. 33 | * @author Nathan Sweet */ 34 | public abstract class Toolkit { 35 | static public Toolkit instance; 36 | 37 | abstract public Cell obtainCell (L layout); 38 | 39 | abstract public void freeCell (Cell cell); 40 | 41 | abstract public void addChild (C parent, C child); 42 | 43 | abstract public void removeChild (C parent, C child); 44 | 45 | abstract public float getMinWidth (C widget); 46 | 47 | abstract public float getMinHeight (C widget); 48 | 49 | abstract public float getPrefWidth (C widget); 50 | 51 | abstract public float getPrefHeight (C widget); 52 | 53 | abstract public float getMaxWidth (C widget); 54 | 55 | abstract public float getMaxHeight (C widget); 56 | 57 | abstract public float getWidth (C widget); 58 | 59 | abstract public float getHeight (C widget); 60 | 61 | /** Clears all debugging rectangles. */ 62 | abstract public void clearDebugRectangles (L layout); 63 | 64 | /** Adds a rectangle that should be drawn for debugging. */ 65 | abstract public void addDebugRectangle (L layout, Debug type, float x, float y, float w, float h); 66 | 67 | /** @param widget May be null. */ 68 | public void setWidget (L layout, Cell cell, C widget) { 69 | if (cell.widget == widget) return; 70 | removeChild((T)layout.table, (C)cell.widget); 71 | cell.widget = widget; 72 | if (widget != null) addChild((T)layout.table, widget); 73 | } 74 | 75 | /** Interprets the specified value as a size. This can be used to scale all sizes applied to a table. The default implementation 76 | * returns the value unmodified. 77 | * @see Value#width(Object) 78 | * @see Value#width(Cell) */ 79 | public float width (float value) { 80 | return value; 81 | } 82 | 83 | /** Interprets the specified value as a size. This can be used to scale all sizes applied to a table. The default implementation 84 | * returns the value unmodified. 85 | * @see Value#height(Object) 86 | * @see Value#height(Cell) */ 87 | public float height (float value) { 88 | return value; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /tablelayout/src/com/esotericsoftware/tablelayout/Value.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2011, Nathan Sweet 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * * Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * * Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * * Neither the name of the nor the 13 | * names of its contributors may be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | ******************************************************************************/ 27 | 28 | package com.esotericsoftware.tablelayout; 29 | 30 | /** Base class for a table or cell property value. Values are provided a table or cell for context. Eg, the value may compute its 31 | * size taking into consideration the size of the table or the widget in the cell. Some values may be only valid for use with 32 | * either call. 33 | * @author Nathan Sweet */ 34 | abstract public class Value { 35 | /** Returns the value in the context of the specified table. */ 36 | abstract public float get (Object table); 37 | 38 | /** Returns the value in the context of the specified cell. */ 39 | abstract public float get (Cell cell); 40 | 41 | /** Returns the value in the context of a width for the specified table. */ 42 | public float width (Object table) { 43 | return Toolkit.instance.width(get(table)); 44 | } 45 | 46 | /** Returns the value in the context of a height for the specified table. */ 47 | public float height (Object table) { 48 | return Toolkit.instance.height(get(table)); 49 | } 50 | 51 | /** Returns the value in the context of a width for the specified cell. */ 52 | public float width (Cell cell) { 53 | return Toolkit.instance.width(get(cell)); 54 | } 55 | 56 | /** Returns the value in the context of a height for the specified cell. */ 57 | public float height (Cell cell) { 58 | return Toolkit.instance.height(get(cell)); 59 | } 60 | 61 | /** A value that is always zero. */ 62 | static public final Value zero = new CellValue() { 63 | public float get (Cell cell) { 64 | return 0; 65 | } 66 | 67 | public float get (Object table) { 68 | return 0; 69 | } 70 | }; 71 | 72 | /** A value that is only valid for use with a cell. 73 | * @author Nathan Sweet */ 74 | static abstract public class CellValue extends Value { 75 | public float get (Object table) { 76 | throw new UnsupportedOperationException("This value can only be used for a cell property."); 77 | } 78 | } 79 | 80 | /** A value that is valid for use with a table or a cell. 81 | * @author Nathan Sweet */ 82 | static abstract public class TableValue extends Value { 83 | public float get (Cell cell) { 84 | return get(cell.getLayout().getTable()); 85 | } 86 | } 87 | 88 | /** A fixed value that is not computed each time it is used. 89 | * @author Nathan Sweet */ 90 | static public class FixedValue extends Value { 91 | private float value; 92 | 93 | public FixedValue (float value) { 94 | this.value = value; 95 | } 96 | 97 | public void set (float value) { 98 | this.value = value; 99 | } 100 | 101 | public float get (Object table) { 102 | return value; 103 | } 104 | 105 | public float get (Cell cell) { 106 | return value; 107 | } 108 | } 109 | 110 | /** Value for a cell that is the minWidth of the widget in the cell. */ 111 | static public Value minWidth = new CellValue() { 112 | public float get (Cell cell) { 113 | if (cell == null) throw new RuntimeException("minWidth can only be set on a cell property."); 114 | Object widget = cell.widget; 115 | if (widget == null) return 0; 116 | return Toolkit.instance.getMinWidth(widget); 117 | } 118 | }; 119 | 120 | /** Value for a cell that is the minHeight of the widget in the cell. */ 121 | static public Value minHeight = new CellValue() { 122 | public float get (Cell cell) { 123 | if (cell == null) throw new RuntimeException("minHeight can only be set on a cell property."); 124 | Object widget = cell.widget; 125 | if (widget == null) return 0; 126 | return Toolkit.instance.getMinHeight(widget); 127 | } 128 | }; 129 | 130 | /** Value for a cell that is the prefWidth of the widget in the cell. */ 131 | static public Value prefWidth = new CellValue() { 132 | public float get (Cell cell) { 133 | if (cell == null) throw new RuntimeException("prefWidth can only be set on a cell property."); 134 | Object widget = cell.widget; 135 | if (widget == null) return 0; 136 | return Toolkit.instance.getPrefWidth(widget); 137 | } 138 | }; 139 | 140 | /** Value for a cell that is the prefHeight of the widget in the cell. */ 141 | static public Value prefHeight = new CellValue() { 142 | public float get (Cell cell) { 143 | if (cell == null) throw new RuntimeException("prefHeight can only be set on a cell property."); 144 | Object widget = cell.widget; 145 | if (widget == null) return 0; 146 | return Toolkit.instance.getPrefHeight(widget); 147 | } 148 | }; 149 | 150 | /** Value for a cell that is the maxWidth of the widget in the cell. */ 151 | static public Value maxWidth = new CellValue() { 152 | public float get (Cell cell) { 153 | if (cell == null) throw new RuntimeException("maxWidth can only be set on a cell property."); 154 | Object widget = cell.widget; 155 | if (widget == null) return 0; 156 | return Toolkit.instance.getMaxWidth(widget); 157 | } 158 | }; 159 | 160 | /** Value for a cell that is the maxHeight of the widget in the cell. */ 161 | static public Value maxHeight = new CellValue() { 162 | public float get (Cell cell) { 163 | if (cell == null) throw new RuntimeException("maxHeight can only be set on a cell property."); 164 | Object widget = cell.widget; 165 | if (widget == null) return 0; 166 | return Toolkit.instance.getMaxHeight(widget); 167 | } 168 | }; 169 | 170 | /** Returns a value that is a percentage of the table's width. */ 171 | static public Value percentWidth (final float percent) { 172 | return new TableValue() { 173 | public float get (Object table) { 174 | return Toolkit.instance.getWidth(table) * percent; 175 | } 176 | }; 177 | } 178 | 179 | /** Returns a value that is a percentage of the table's height. */ 180 | static public Value percentHeight (final float percent) { 181 | return new TableValue() { 182 | public float get (Object table) { 183 | return Toolkit.instance.getHeight(table) * percent; 184 | } 185 | }; 186 | } 187 | 188 | /** Returns a value that is a percentage of the specified widget's width. */ 189 | static public Value percentWidth (final float percent, final Object widget) { 190 | return new Value() { 191 | public float get (Cell cell) { 192 | return Toolkit.instance.getWidth(widget) * percent; 193 | } 194 | 195 | public float get (Object table) { 196 | return Toolkit.instance.getWidth(widget) * percent; 197 | } 198 | }; 199 | } 200 | 201 | /** Returns a value that is a percentage of the specified widget's height. */ 202 | static public Value percentHeight (final float percent, final Object widget) { 203 | return new TableValue() { 204 | public float get (Object table) { 205 | return Toolkit.instance.getHeight(widget) * percent; 206 | } 207 | }; 208 | } 209 | } 210 | --------------------------------------------------------------------------------