Add 'src/jexer/' from commit 'cf01c92f5809a0732409e280fb0f32f27393618d'
[fanfix.git] / src / jexer / layout / BoxLayoutManager.java
1 /*
2 * Jexer - Java Text User Interface
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (C) 2019 Kevin Lamonte
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
28 */
29 package jexer.layout;
30
31 import java.util.ArrayList;
32
33 import jexer.TWidget;
34 import jexer.event.TResizeEvent;
35
36 /**
37 * BoxLayoutManager repositions child widgets based on the order they are
38 * added to the parent widget and desired orientation.
39 */
40 public class BoxLayoutManager implements LayoutManager {
41
42 // ------------------------------------------------------------------------
43 // Variables --------------------------------------------------------------
44 // ------------------------------------------------------------------------
45
46 /**
47 * If true, orient vertically. If false, orient horizontally.
48 */
49 private boolean vertical = true;
50
51 /**
52 * Current width.
53 */
54 private int width = 0;
55
56 /**
57 * Current height.
58 */
59 private int height = 0;
60
61 /**
62 * Widgets being managed.
63 */
64 private ArrayList<TWidget> children = new ArrayList<TWidget>();
65
66 // ------------------------------------------------------------------------
67 // Constructors -----------------------------------------------------------
68 // ------------------------------------------------------------------------
69
70 /**
71 * Public constructor.
72 *
73 * @param width the width of the parent widget
74 * @param height the height of the parent widget
75 * @param vertical if true, arrange widgets vertically
76 */
77 public BoxLayoutManager(final int width, final int height,
78 final boolean vertical) {
79
80 this.width = width;
81 this.height = height;
82 this.vertical = vertical;
83 }
84
85 // ------------------------------------------------------------------------
86 // LayoutManager ----------------------------------------------------------
87 // ------------------------------------------------------------------------
88
89 /**
90 * Process the parent widget's resize event, and resize/reposition child
91 * widgets.
92 *
93 * @param resize resize event
94 */
95 public void onResize(final TResizeEvent resize) {
96 if (resize.getType() == TResizeEvent.Type.WIDGET) {
97 width = resize.getWidth();
98 height = resize.getHeight();
99 layoutChildren();
100 }
101 }
102
103 /**
104 * Add a child widget to manage.
105 *
106 * @param child the widget to manage
107 */
108 public void add(final TWidget child) {
109 children.add(child);
110 layoutChildren();
111 }
112
113 /**
114 * Remove a child widget from those managed by this LayoutManager.
115 *
116 * @param child the widget to remove
117 */
118 public void remove(final TWidget child) {
119 children.remove(child);
120 layoutChildren();
121 }
122
123 /**
124 * Reset a child widget's original/preferred size.
125 *
126 * @param child the widget to manage
127 */
128 public void resetSize(final TWidget child) {
129 // NOP
130 }
131
132 // ------------------------------------------------------------------------
133 // BoxLayoutManager -------------------------------------------------------
134 // ------------------------------------------------------------------------
135
136 /**
137 * Resize/reposition child widgets based on horizontal/vertical
138 * arrangement.
139 */
140 private void layoutChildren() {
141 if (children.size() == 0) {
142 return;
143 }
144 if (vertical) {
145 int widgetHeight = Math.max(1, height / children.size());
146 int leftoverHeight = height % children.size();
147 for (int i = 0; i < children.size() - 1; i++) {
148 TWidget child = children.get(i);
149 child.setDimensions(child.getX(), i * widgetHeight,
150 width, widgetHeight);
151 }
152 TWidget child = children.get(children.size() - 1);
153 child.setDimensions(child.getX(),
154 (children.size() - 1) * widgetHeight, width,
155 widgetHeight + leftoverHeight);
156 } else {
157 int widgetWidth = Math.max(1, width / children.size());
158 int leftoverWidth = width % children.size();
159 for (int i = 0; i < children.size() - 1; i++) {
160 TWidget child = children.get(i);
161 child.setDimensions(i * widgetWidth, child.getY(),
162 widgetWidth, height);
163 }
164 TWidget child = children.get(children.size() - 1);
165 child.setDimensions((children.size() - 1) * widgetWidth,
166 child.getY(), widgetWidth + leftoverWidth, height);
167 }
168 }
169
170 }