ttable navigation minimally working
[fanfix.git] / src / jexer / TTableWindow.java
CommitLineData
1dac6b8d
KL
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 */
29package jexer;
30
31import java.util.ResourceBundle;
32
33import jexer.event.TCommandEvent;
34import jexer.event.TKeypressEvent;
35import jexer.event.TMouseEvent;
36import jexer.event.TResizeEvent;
37import jexer.menu.TMenu;
38import static jexer.TCommand.*;
39import static jexer.TKeypress.*;
40
41/**
42 * TTableWindow is used to display and edit regular two-dimensional tables of
43 * cells.
44 */
45public class TTableWindow extends TScrollableWindow {
46
47 /**
48 * Translated strings.
49 */
50 private static final ResourceBundle i18n = ResourceBundle.getBundle(TTableWindow.class.getName());
51
52 // ------------------------------------------------------------------------
53 // Variables --------------------------------------------------------------
54 // ------------------------------------------------------------------------
55
56 /**
57 * The table widget.
58 */
59 private TTableWidget tableField;
60
61 // ------------------------------------------------------------------------
62 // Constructors -----------------------------------------------------------
63 // ------------------------------------------------------------------------
64
65 /**
66 * Public constructor sets window title.
67 *
68 * @param parent the main application
69 * @param title the window title
70 */
71 public TTableWindow(final TApplication parent, final String title) {
72
73 super(parent, title, 0, 0, parent.getScreen().getWidth() / 2,
74 parent.getScreen().getHeight() / 2 - 2, RESIZABLE | CENTERED);
75
76 tableField = new TTableWidget(this, 0, 0, getWidth() - 2, getHeight() - 2);
77 setupAfterTable();
78 }
79
80 // ------------------------------------------------------------------------
81 // Event handlers ---------------------------------------------------------
82 // ------------------------------------------------------------------------
83
84 /**
85 * Called by application.switchWindow() when this window gets the
86 * focus, and also by application.addWindow().
87 */
88 public void onFocus() {
89 // Enable the table menu items.
90 getApplication().enableMenuItem(TMenu.MID_CUT);
77961919
KL
91 getApplication().enableMenuItem(TMenu.MID_TABLE_VIEW_ROW_LABELS);
92 getApplication().enableMenuItem(TMenu.MID_TABLE_VIEW_COLUMN_LABELS);
93 getApplication().enableMenuItem(TMenu.MID_TABLE_VIEW_HIGHLIGHT_ROW);
94 getApplication().enableMenuItem(TMenu.MID_TABLE_VIEW_HIGHLIGHT_COLUMN);
1dac6b8d
KL
95 getApplication().enableMenuItem(TMenu.MID_TABLE_BORDER_NONE);
96 getApplication().enableMenuItem(TMenu.MID_TABLE_BORDER_ALL);
97 getApplication().enableMenuItem(TMenu.MID_TABLE_BORDER_RIGHT);
98 getApplication().enableMenuItem(TMenu.MID_TABLE_BORDER_LEFT);
99 getApplication().enableMenuItem(TMenu.MID_TABLE_BORDER_TOP);
100 getApplication().enableMenuItem(TMenu.MID_TABLE_BORDER_BOTTOM);
101 getApplication().enableMenuItem(TMenu.MID_TABLE_BORDER_DOUBLE_BOTTOM);
102 getApplication().enableMenuItem(TMenu.MID_TABLE_BORDER_THICK_BOTTOM);
103 getApplication().enableMenuItem(TMenu.MID_TABLE_DELETE_LEFT);
104 getApplication().enableMenuItem(TMenu.MID_TABLE_DELETE_UP);
105 getApplication().enableMenuItem(TMenu.MID_TABLE_DELETE_ROW);
106 getApplication().enableMenuItem(TMenu.MID_TABLE_DELETE_COLUMN);
107 getApplication().enableMenuItem(TMenu.MID_TABLE_INSERT_LEFT);
108 getApplication().enableMenuItem(TMenu.MID_TABLE_INSERT_RIGHT);
109 getApplication().enableMenuItem(TMenu.MID_TABLE_INSERT_ABOVE);
110 getApplication().enableMenuItem(TMenu.MID_TABLE_INSERT_BELOW);
111 getApplication().enableMenuItem(TMenu.MID_TABLE_COLUMN_NARROW);
112 getApplication().enableMenuItem(TMenu.MID_TABLE_COLUMN_WIDEN);
113 getApplication().enableMenuItem(TMenu.MID_TABLE_FILE_SAVE_CSV);
114 getApplication().enableMenuItem(TMenu.MID_TABLE_FILE_SAVE_TEXT);
115 }
116
117 /**
118 * Called by application.switchWindow() when another window gets the
119 * focus.
120 */
121 public void onUnfocus() {
122 // Disable the table menu items.
123 getApplication().disableMenuItem(TMenu.MID_CUT);
77961919
KL
124 getApplication().disableMenuItem(TMenu.MID_TABLE_VIEW_ROW_LABELS);
125 getApplication().disableMenuItem(TMenu.MID_TABLE_VIEW_COLUMN_LABELS);
126 getApplication().disableMenuItem(TMenu.MID_TABLE_VIEW_HIGHLIGHT_ROW);
127 getApplication().disableMenuItem(TMenu.MID_TABLE_VIEW_HIGHLIGHT_COLUMN);
1dac6b8d
KL
128 getApplication().disableMenuItem(TMenu.MID_TABLE_BORDER_NONE);
129 getApplication().disableMenuItem(TMenu.MID_TABLE_BORDER_ALL);
130 getApplication().disableMenuItem(TMenu.MID_TABLE_BORDER_RIGHT);
131 getApplication().disableMenuItem(TMenu.MID_TABLE_BORDER_LEFT);
132 getApplication().disableMenuItem(TMenu.MID_TABLE_BORDER_TOP);
133 getApplication().disableMenuItem(TMenu.MID_TABLE_BORDER_BOTTOM);
134 getApplication().disableMenuItem(TMenu.MID_TABLE_BORDER_DOUBLE_BOTTOM);
135 getApplication().disableMenuItem(TMenu.MID_TABLE_BORDER_THICK_BOTTOM);
136 getApplication().disableMenuItem(TMenu.MID_TABLE_DELETE_LEFT);
137 getApplication().disableMenuItem(TMenu.MID_TABLE_DELETE_UP);
138 getApplication().disableMenuItem(TMenu.MID_TABLE_DELETE_ROW);
139 getApplication().disableMenuItem(TMenu.MID_TABLE_DELETE_COLUMN);
140 getApplication().disableMenuItem(TMenu.MID_TABLE_INSERT_LEFT);
141 getApplication().disableMenuItem(TMenu.MID_TABLE_INSERT_RIGHT);
142 getApplication().disableMenuItem(TMenu.MID_TABLE_INSERT_ABOVE);
143 getApplication().disableMenuItem(TMenu.MID_TABLE_INSERT_BELOW);
144 getApplication().disableMenuItem(TMenu.MID_TABLE_COLUMN_NARROW);
145 getApplication().disableMenuItem(TMenu.MID_TABLE_COLUMN_WIDEN);
146 getApplication().disableMenuItem(TMenu.MID_TABLE_FILE_SAVE_CSV);
147 getApplication().disableMenuItem(TMenu.MID_TABLE_FILE_SAVE_TEXT);
148 }
149
150 // ------------------------------------------------------------------------
151 // TWindow ----------------------------------------------------------------
152 // ------------------------------------------------------------------------
153
154 /**
155 * Draw the window.
156 */
157 @Override
158 public void draw() {
159 // Draw as normal.
160 super.draw();
161
162 // Add borders on rows and columns.
163 // TODO
164 }
165
166 /**
167 * Handle mouse press events.
168 *
169 * @param mouse mouse button press event
170 */
171 @Override
172 public void onMouseDown(final TMouseEvent mouse) {
173 // Use TWidget's code to pass the event to the children.
174 super.onMouseDown(mouse);
175
176 if (mouseOnTable(mouse)) {
177 // The table might have changed, update the scollbars.
178 // TODO
179 /*
180 setBottomValue(editField.getMaximumRowNumber());
181 setVerticalValue(editField.getVisibleRowNumber());
182 setRightValue(editField.getMaximumColumnNumber());
183 setHorizontalValue(editField.getEditingColumnNumber());
184 */
185 } else {
186 if (mouse.isMouseWheelUp() || mouse.isMouseWheelDown()) {
187 // Vertical scrollbar actions
188 // TODO
189 // editField.setVisibleRowNumber(getVerticalValue());
190 }
191 }
192 }
193
194 /**
195 * Handle mouse release events.
196 *
197 * @param mouse mouse button release event
198 */
199 @Override
200 public void onMouseUp(final TMouseEvent mouse) {
201 // Use TWidget's code to pass the event to the children.
202 super.onMouseUp(mouse);
203
204 if (mouse.isMouse1() && mouseOnVerticalScroller(mouse)) {
205 // Clicked on vertical scrollbar
206 // TODO
207 // editField.setVisibleRowNumber(getVerticalValue());
208 }
209
210 // TODO: horizontal scrolling
211 }
212
213 /**
214 * Method that subclasses can override to handle mouse movements.
215 *
216 * @param mouse mouse motion event
217 */
218 @Override
219 public void onMouseMotion(final TMouseEvent mouse) {
220 // Use TWidget's code to pass the event to the children.
221 super.onMouseMotion(mouse);
222
223 if (mouseOnTable(mouse) && mouse.isMouse1()) {
224 // The editor might have changed, update the scollbars.
225 // TODO
226 /*
227 setBottomValue(editField.getMaximumRowNumber());
228 setVerticalValue(editField.getVisibleRowNumber());
229 setRightValue(editField.getMaximumColumnNumber());
230 setHorizontalValue(editField.getEditingColumnNumber());
231 */
232 } else {
233 if (mouse.isMouse1() && mouseOnVerticalScroller(mouse)) {
234 // Clicked/dragged on vertical scrollbar
235 // TODO
236 // editField.setVisibleRowNumber(getVerticalValue());
237 }
238
239 // TODO: horizontal scrolling
240 }
241
242 }
243
244 /**
245 * Handle keystrokes.
246 *
247 * @param keypress keystroke event
248 */
249 @Override
250 public void onKeypress(final TKeypressEvent keypress) {
251 // Use TWidget's code to pass the event to the children.
252 super.onKeypress(keypress);
253
254 // The editor might have changed, update the scollbars.
255 // TODO
256 /*
257 setBottomValue(editField.getMaximumRowNumber());
258 setVerticalValue(editField.getVisibleRowNumber());
259 setRightValue(editField.getMaximumColumnNumber());
260 setHorizontalValue(editField.getEditingColumnNumber());
261 */
262 }
263
264 /**
265 * Handle window/screen resize events.
266 *
267 * @param event resize event
268 */
269 @Override
270 public void onResize(final TResizeEvent event) {
271 if (event.getType() == TResizeEvent.Type.WIDGET) {
272 // Resize the table
273 TResizeEvent tableSize = new TResizeEvent(TResizeEvent.Type.WIDGET,
274 event.getWidth() - 2, event.getHeight() - 2);
275 tableField.onResize(tableSize);
276
277 // Have TScrollableWindow handle the scrollbars
278 super.onResize(event);
279 return;
280 }
281
282 // Pass to children instead
283 for (TWidget widget: getChildren()) {
284 widget.onResize(event);
285 }
286 }
287
288 // ------------------------------------------------------------------------
289 // TTableWindow -----------------------------------------------------------
290 // ------------------------------------------------------------------------
291
292 /**
293 * Setup other fields after the table is created.
294 */
295 private void setupAfterTable() {
296 hScroller = new THScroller(this, 17, getHeight() - 2, getWidth() - 20);
297 vScroller = new TVScroller(this, getWidth() - 2, 0, getHeight() - 2);
298 setMinimumWindowWidth(25);
299 setMinimumWindowHeight(10);
300 setTopValue(1);
301 // setBottomValue(editField.getMaximumRowNumber());
302 setLeftValue(1);
9c172016 303 setRightValue(tableField.getMaximumWidth());
1dac6b8d
KL
304
305 statusBar = newStatusBar(i18n.getString("statusBar"));
306 statusBar.addShortcutKeypress(kbF1, cmHelp,
307 i18n.getString("statusBarHelp"));
308 /*
309 statusBar.addShortcutKeypress(kbF2, cmSave,
310 i18n.getString("statusBarSave"));
311 statusBar.addShortcutKeypress(kbF3, cmOpen,
312 i18n.getString("statusBarOpen"));
313 */
314 statusBar.addShortcutKeypress(kbF10, cmMenu,
315 i18n.getString("statusBarMenu"));
316 }
317
318 /**
319 * Check if a mouse press/release/motion event coordinate is over the
320 * table.
321 *
322 * @param mouse a mouse-based event
323 * @return whether or not the mouse is on the table
324 */
325 private boolean mouseOnTable(final TMouseEvent mouse) {
326 if ((mouse.getAbsoluteX() >= getAbsoluteX() + 1)
327 && (mouse.getAbsoluteX() < getAbsoluteX() + getWidth() - 1)
328 && (mouse.getAbsoluteY() >= getAbsoluteY() + 1)
329 && (mouse.getAbsoluteY() < getAbsoluteY() + getHeight() - 1)
330 ) {
331 return true;
332 }
333 return false;
334 }
335
336}