Prep for 2019 release
[fanfix.git] / src / jexer / TImageWindow.java
CommitLineData
a69ed767
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.awt.image.BufferedImage;
32import java.io.File;
33import java.io.IOException;
34import javax.imageio.ImageIO;
35
36import jexer.event.TKeypressEvent;
37import jexer.event.TMouseEvent;
38import jexer.event.TResizeEvent;
39import static jexer.TKeypress.*;
40
41/**
42 * TImageWindow shows an image with scrollbars.
43 */
44public class TImageWindow extends TScrollableWindow {
45
46 // ------------------------------------------------------------------------
47 // Constants --------------------------------------------------------------
48 // ------------------------------------------------------------------------
49
50 /**
51 * The number of lines to scroll on mouse wheel up/down.
52 */
53 private static final int wheelScrollSize = 3;
54
55 // ------------------------------------------------------------------------
56 // Variables --------------------------------------------------------------
57 // ------------------------------------------------------------------------
58
59 /**
60 * Hang onto the TImage so I can resize it with the window.
61 */
62 private TImage imageField;
63
64 // ------------------------------------------------------------------------
65 // Constructors -----------------------------------------------------------
66 // ------------------------------------------------------------------------
67
68 /**
69 * Public constructor opens a file.
70 *
71 * @param parent the main application
72 * @param file the file to open
73 * @throws IOException if a java.io operation throws
74 */
75 public TImageWindow(final TApplication parent,
76 final File file) throws IOException {
77
78 this(parent, file, 0, 0, parent.getScreen().getWidth(),
79 parent.getScreen().getHeight() - 2);
80 }
81
82 /**
83 * Public constructor opens a file.
84 *
85 * @param parent the main application
86 * @param file the file to open
87 * @param x column relative to parent
88 * @param y row relative to parent
89 * @param width width of window
90 * @param height height of window
91 * @throws IOException if a java.io operation throws
92 */
93 public TImageWindow(final TApplication parent, final File file,
94 final int x, final int y, final int width,
95 final int height) throws IOException {
96
97 super(parent, file.getName(), x, y, width, height, RESIZABLE);
98
99 BufferedImage image = ImageIO.read(file);
100
101 imageField = new TImage(this, 0, 0, getWidth() - 2, getHeight() - 2,
102 image, 0, 0, null);
103 setTitle(file.getName());
104
105 setupAfterImage();
106 }
107
108 /**
109 * Setup other fields after the image is created.
110 */
111 private void setupAfterImage() {
112 if (imageField.getRows() < getHeight() - 2) {
113 imageField.setHeight(imageField.getRows());
114 setHeight(imageField.getRows() + 2);
115 }
116 if (imageField.getColumns() < getWidth() - 2) {
117 imageField.setWidth(imageField.getColumns());
118 setWidth(imageField.getColumns() + 2);
119 }
120
121 hScroller = new THScroller(this, 17, getHeight() - 2, getWidth() - 20);
122 vScroller = new TVScroller(this, getWidth() - 2, 0, getHeight() - 2);
123 setTopValue(0);
124 setBottomValue(imageField.getRows() - imageField.getHeight());
125 setLeftValue(0);
126 setRightValue(imageField.getColumns() - imageField.getWidth());
127 }
128
129 // ------------------------------------------------------------------------
130 // Event handlers ---------------------------------------------------------
131 // ------------------------------------------------------------------------
132
133 /**
134 * Handle mouse press events.
135 *
136 * @param mouse mouse button press event
137 */
138 @Override
139 public void onMouseDown(final TMouseEvent mouse) {
140 // Use TWidget's code to pass the event to the children.
141 super.onMouseDown(mouse);
142
143 if (mouse.isMouseWheelUp()) {
144 imageField.setTop(imageField.getTop() - wheelScrollSize);
145 } else if (mouse.isMouseWheelDown()) {
146 imageField.setTop(imageField.getTop() + wheelScrollSize);
147 }
148 setVerticalValue(imageField.getTop());
149 }
150
151 /**
152 * Handle mouse release events.
153 *
154 * @param mouse mouse button release event
155 */
156 @Override
157 public void onMouseUp(final TMouseEvent mouse) {
158 // Use TWidget's code to pass the event to the children.
159 super.onMouseUp(mouse);
160
161 if (mouse.isMouse1() && mouseOnVerticalScroller(mouse)) {
162 // Clicked/dragged on vertical scrollbar
163 imageField.setTop(getVerticalValue());
164 }
165 if (mouse.isMouse1() && mouseOnHorizontalScroller(mouse)) {
166 // Clicked/dragged on horizontal scrollbar
167 imageField.setLeft(getHorizontalValue());
168 }
169 }
170
171 /**
172 * Method that subclasses can override to handle mouse movements.
173 *
174 * @param mouse mouse motion event
175 */
176 @Override
177 public void onMouseMotion(final TMouseEvent mouse) {
178 // Use TWidget's code to pass the event to the children.
179 super.onMouseMotion(mouse);
180
181 if (mouse.isMouse1() && mouseOnVerticalScroller(mouse)) {
182 // Clicked/dragged on vertical scrollbar
183 imageField.setTop(getVerticalValue());
184 }
185 if (mouse.isMouse1() && mouseOnHorizontalScroller(mouse)) {
186 // Clicked/dragged on horizontal scrollbar
187 imageField.setLeft(getHorizontalValue());
188 }
189 }
190
191 /**
192 * Handle window/screen resize events.
193 *
194 * @param event resize event
195 */
196 @Override
197 public void onResize(final TResizeEvent event) {
198 if (event.getType() == TResizeEvent.Type.WIDGET) {
199 // Resize the image field
200 TResizeEvent imageSize = new TResizeEvent(TResizeEvent.Type.WIDGET,
201 event.getWidth() - 2, event.getHeight() - 2);
202 imageField.onResize(imageSize);
203
204 // Have TScrollableWindow handle the scrollbars
205 super.onResize(event);
206 return;
207 }
208
209 // Pass to children instead
210 for (TWidget widget: getChildren()) {
211 widget.onResize(event);
212 }
213 }
214
215 /**
216 * Handle keystrokes.
217 *
218 * @param keypress keystroke event
219 */
220 @Override
221 public void onKeypress(final TKeypressEvent keypress) {
222 if (keypress.equals(kbUp)) {
223 verticalDecrement();
224 imageField.setTop(getVerticalValue());
225 return;
226 }
227 if (keypress.equals(kbDown)) {
228 verticalIncrement();
229 imageField.setTop(getVerticalValue());
230 return;
231 }
232 if (keypress.equals(kbPgUp)) {
233 bigVerticalDecrement();
234 imageField.setTop(getVerticalValue());
235 return;
236 }
237 if (keypress.equals(kbPgDn)) {
238 bigVerticalIncrement();
239 imageField.setTop(getVerticalValue());
240 return;
241 }
242 if (keypress.equals(kbRight)) {
243 horizontalIncrement();
244 imageField.setLeft(getHorizontalValue());
245 return;
246 }
247 if (keypress.equals(kbLeft)) {
248 horizontalDecrement();
249 imageField.setLeft(getHorizontalValue());
250 return;
251 }
252
253 // We did not take it, let the TImage instance see it.
254 super.onKeypress(keypress);
255
256 setVerticalValue(imageField.getTop());
257 setBottomValue(imageField.getRows() - imageField.getHeight());
258 setHorizontalValue(imageField.getLeft());
259 setRightValue(imageField.getColumns() - imageField.getWidth());
260 }
261
262 // ------------------------------------------------------------------------
263 // TWindow ----------------------------------------------------------------
264 // ------------------------------------------------------------------------
265
266 /**
267 * Draw the window.
268 */
269 @Override
270 public void draw() {
271 // Draw as normal.
272 super.draw();
273
274 // We have to get the scrollbar values after we have let the image
275 // try to draw.
276 setBottomValue(imageField.getRows() - imageField.getHeight());
277 setRightValue(imageField.getColumns() - imageField.getWidth());
278 }
279
280}