Changeset 1102 for trunk/src/org/expeditee/gui/Popup.java
- Timestamp:
- 05/10/18 16:04:51 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/expeditee/gui/Popup.java
r919 r1102 19 19 package org.expeditee.gui; 20 20 21 import java.awt.BasicStroke; 22 import java.awt.Color; 23 import java.awt.Component; 24 import java.awt.Container; 25 import java.awt.Graphics; 26 import java.awt.Graphics2D; 27 import java.awt.LayoutManager; 28 29 import javax.swing.JComponent; 30 import javax.swing.JPanel; 31 21 import org.expeditee.core.Clip; 22 import org.expeditee.core.Colour; 23 import org.expeditee.core.EnforcedClipStack.EnforcedClipKey; 24 import org.expeditee.core.Fill; 25 import org.expeditee.core.Lifetime; 26 import org.expeditee.core.Stroke; 27 import org.expeditee.core.bounds.AxisAlignedBoxBounds; 28 import org.expeditee.gio.EcosystemManager; 29 import org.expeditee.gio.GraphicsManager; 30 import org.expeditee.gui.PopupManager.PopupAnimator; 32 31 import org.expeditee.items.ItemUtils; 33 32 34 33 /** 34 * A Custom swing pop-up in Expeditee. 35 35 * 36 * A Custom swing popup in Expeditee. 37 * 38 * Expeditee popus can be re-used. Popups are always heavyweight (i.e. uses invalidation). 36 * Expeditee pop-ups can be re-used. Pop-ups are always heavyweight (i.e. uses invalidation). 39 37 * 40 38 * @see {@link PopupManager} 41 39 * 42 40 * @author Brook Novak 43 *44 41 */ 45 public abstract class Popup extends JPanel {46 42 public abstract class Popup 43 { 47 44 //Mike says: Can we get the border for the IW to which this popup corresponds? 48 // Brook says: Would be nice - but popups are actually independ ant from widgets45 // Brook says: Would be nice - but popups are actually independent from widgets 49 46 // =>Now: It is up to the user of the popup to set the border thickness 50 private static final BasicStroke DEFAULT_STROKE = new BasicStroke(2.0f); 51 52 private BasicStroke _borderStroke = DEFAULT_STROKE; 53 private Color _borderColor = Color.BLACK; 54 55 private boolean _isReadyToPaint = false; 47 private static final Stroke DEFAULT_STROKE = new Stroke(2.0f); 48 49 private Stroke _borderStroke = DEFAULT_STROKE; 50 private Colour _borderColour = Colour.BLACK; 51 private Fill _backgroundFill = new Fill(Colour.WHITE); 52 53 private PopupAnimator _animator = null; 54 55 private Lifetime _autoHideTime = new Lifetime(Lifetime.INFINITE_LIFETIME); 56 private Runnable _autoHideRoutine = new Runnable() 57 { 58 @Override 59 public void run() 60 { 61 hide(); 62 DisplayController.invalidateArea(getBounds()); 63 DisplayController.requestRefresh(true); 64 } 65 }; 66 67 private boolean _hidden = true; 68 56 69 private boolean _consumeBackClick = false; 57 private boolean _autoHide = true; 58 59 /** 60 * Creates a new popup. 61 * Autohide is set to true. 62 * 63 */ 64 public Popup() { 65 super(); 66 setVisible(false); 67 } 68 69 /** 70 * Creates a new popup. 71 * 72 * @param layout the LayoutManager to use 73 */ 74 public Popup(LayoutManager layout) { 75 super(layout); 76 setVisible(false); 77 } 78 79 @Override 80 public void paint(Graphics g) { 81 super.paint(g); 82 83 // Draw border - if not transparent 84 if (_borderStroke != null && _borderColor != null) { 85 g.setColor(_borderColor); 86 ((Graphics2D)g).setStroke(_borderStroke); 87 g.drawRect(0, 0, getWidth(), getHeight()); 88 } 89 } 90 91 private void ignoreAWTPainting(Component c) { 92 93 if (c instanceof JComponent) { 94 ((JComponent)c).setDoubleBuffered(false); 95 } 96 97 c.setIgnoreRepaint(true); 98 99 if (c instanceof Container) { 100 for (Component child : ((Container) c).getComponents()) { 101 102 if (child instanceof Container) { 103 ignoreAWTPainting(child); 104 } else { 105 if (child instanceof JComponent) { 106 ((JComponent)child).setDoubleBuffered(false); 107 } 108 109 child.setIgnoreRepaint(true); 70 71 /** 72 * Creates a new pop-up. 73 * Auto-hide is set to true. 74 */ 75 public Popup(PopupAnimator animator) 76 { 77 setAnimator(animator); 78 } 79 80 public Popup(PopupAnimator animator, long lifetime) 81 { 82 this(animator); 83 _autoHideTime.setLifetime(lifetime); 84 } 85 86 public Lifetime getAutoHideTime() 87 { 88 return _autoHideTime; 89 } 90 91 public void setAnimator(PopupAnimator animator) 92 { 93 _animator = animator; 94 } 95 96 public PopupAnimator getAnimator() 97 { 98 return _animator; 99 } 100 101 public boolean isShowing() 102 { 103 return !_hidden; 104 } 105 106 public void show() 107 { 108 if (_hidden) onShow(); 109 110 if (_animator != null) { 111 _animator.show(); 112 if (!_animator.isFinished()) { 113 _autoHideTime.cancelExpiry(); 114 } else { 115 _autoHideTime.refresh(); 116 _autoHideTime.onExpiry(_autoHideRoutine); 117 } 118 } else { 119 _autoHideTime.refresh(); 120 _autoHideTime.onExpiry(_autoHideRoutine); 121 } 122 123 _hidden = false; 124 } 125 126 public void hide() 127 { 128 if (!_hidden) onHide(); 129 130 if (_animator != null) _animator.hide(); 131 _autoHideTime.cancelExpiry(); 132 _hidden = true; 133 } 134 135 public boolean update() 136 { 137 if (_animator != null) { 138 if (!_hidden && !_animator.isFinished()) { 139 if (!_animator.update()) { 140 _autoHideTime.refresh(); 141 _autoHideTime.onExpiry(_autoHideRoutine); 110 142 } 111 143 } 112 } 113 114 } 115 116 /** 117 * Ensures that AWT painting turned off 118 */ 119 void prepareToPaint() { 120 if (!_isReadyToPaint) { 121 _isReadyToPaint = true; 122 ignoreAWTPainting(this); 123 } 124 } 125 126 /** 127 * Invoked when the popup becomes hidden, or when the popup is animating to show but cancelled. 128 */ 129 public void onHide() {} 130 131 /** 132 * Invoked when the popup shows. Note this might not eventuate for animated popups. 133 */ 134 public void onShow() {} 135 136 /** 137 * Invoked when popups is going to show. 138 * This always is invoked first. 139 */ 140 public void onShowing() {} 141 142 public boolean shouldConsumeBackClick() { 144 145 if (_hidden && !_animator.isFinished()) { 146 return _animator.update(); 147 } 148 } else { 149 if (_autoHideTime.hasExpired()) hide(); 150 } 151 152 return false; 153 154 } 155 156 public final void paint() 157 { 158 GraphicsManager g = EcosystemManager.getGraphicsManager(); 159 160 // Make sure the popup isn't hidden 161 AxisAlignedBoxBounds currentBounds = getBounds(); 162 if (currentBounds == null) return; 163 164 // Draw border and background 165 g.drawRectangle(currentBounds, 0.0, _backgroundFill, _borderColour, _borderStroke, null); 166 167 EnforcedClipKey key = g.pushClip(new Clip(currentBounds)); 168 169 paintInternal(); 170 171 g.popClip(key); 172 } 173 174 /** Draws the interior paint area of the popup. */ 175 protected abstract void paintInternal(); 176 177 /** Gets the bounds of this popup when it's fully shown. */ 178 public abstract AxisAlignedBoxBounds getFullBounds(); 179 180 /** Gets the bounds of this popup in its current animated state. */ 181 public AxisAlignedBoxBounds getBounds() 182 { 183 if (_animator == null) { 184 if (_autoHideTime.hasExpired()) { 185 return null; 186 } else { 187 return getFullBounds(); 188 } 189 } 190 191 return _animator.getAnimatedBounds(getFullBounds()); 192 } 193 194 /** Invoked when the popup becomes hidden, or when the popup is animating to show but cancelled. */ 195 public abstract void onHide(); 196 197 /** Invoked when the popup shows. Note this might not eventuate for animated popups. */ 198 public abstract void onShow(); 199 200 public boolean shouldConsumeBackClick() 201 { 143 202 return _consumeBackClick; 144 203 } … … 150 209 * consume the back-click event. 151 210 */ 152 protected void setConsumeBackClick(boolean consumeBackClick) { 211 protected void setConsumeBackClick(boolean consumeBackClick) 212 { 153 213 _consumeBackClick = consumeBackClick; 154 }155 156 /**157 * @param autoHideOn158 * Set to True if this popup should auto hide. (The default).159 * Set to false if this popup should be manually hidden.160 */161 protected void setAudoHide(boolean autoHideOn) {162 _autoHide = autoHideOn;163 214 } 164 215 … … 167 218 * True if this popup auto hides. 168 219 */ 169 public boolean doesAutoHide() { 170 return _autoHide; 220 public boolean doesAutoHide() 221 { 222 return _autoHideTime.remainingLifetime() != Lifetime.INFINITE_LIFETIME; 171 223 } 172 224 … … 177 229 * The new thickness to set. Null for no border. 178 230 */ 179 public void setBorderThickness(float thickness) { 231 public void setBorderThickness(float thickness) 232 { 180 233 assert(thickness >= 0); 181 234 182 if (_borderStroke != null && _borderStroke.getLineWidth() == thickness) 183 return; 235 if (_borderStroke != null && _borderStroke.thickness == thickness) return; 184 236 185 237 boolean posInvalidate = true; 186 238 187 if (thickness < _borderStroke. getLineWidth()) {239 if (thickness < _borderStroke.thickness) { 188 240 invalidateAppearance(); 189 241 posInvalidate = false; 190 242 } 191 243 192 if (thickness == 0) _borderStroke = null; 193 else _borderStroke = new BasicStroke(thickness); 244 if (thickness == 0) { 245 _borderStroke = null; 246 } else { 247 _borderStroke = new Stroke(thickness); 248 } 194 249 195 250 if (posInvalidate) invalidateAppearance(); … … 201 256 * The border thickness of this popup. Zero or more. 202 257 */ 203 public float getBorderThickness() { 258 public float getBorderThickness() 259 { 204 260 if (_borderStroke == null) return 0.0f; 205 return _borderStroke.getLineWidth(); 206 261 262 return _borderStroke.thickness; 207 263 } 208 264 … … 214 270 * The new color. Null for transparent. 215 271 */ 216 public void setBorderColor(Color c) { 217 218 if (c == null && _borderColor != null) 272 public void setBorderColor(Colour c) 273 { 274 if (c == null && _borderColour != null) invalidateAppearance(); 275 276 if (c != _borderColour) { 277 _borderColour = c; 219 278 invalidateAppearance(); 220 221 if (c != _borderColor) { 222 _borderColor = c; 223 invalidateAppearance(); 224 } 225 } 226 227 /** 228 * 279 } 280 } 281 282 /** 229 283 * @return 230 284 * The border color for the popup. NUll if transparent 231 285 */ 232 public Color getBorderColor() { 233 return _borderColor; 234 } 235 236 /** 237 * Invalidates the whole popup so that it must be fully repainted. 238 */ 239 public void invalidateAppearance() { 240 241 if (_borderColor != null && _borderStroke != null && _borderStroke.getLineWidth() > 0) { // border 242 FrameGraphics.invalidateArea(ItemUtils.expandRectangle(getBounds(), 243 (int)Math.ceil(getBorderThickness()) + 1)); 286 public Colour getBorderColor() 287 { 288 return _borderColour; 289 } 290 291 /** 292 * Invalidates the whole pop-up so that it must be fully repainted. 293 */ 294 public void invalidateAppearance() 295 { 296 AxisAlignedBoxBounds bounds = getBounds(); 297 298 if (bounds == null) return; 299 300 if (_borderColour != null && _borderStroke != null && _borderStroke.thickness > 0) { // border 301 DisplayController.invalidateArea(ItemUtils.expandRectangle(bounds, (int)Math.ceil(getBorderThickness()) + 1)); 244 302 } else { // no border 245 FrameGraphics.invalidateArea(getBounds()); 246 } 247 248 } 249 250 251 303 DisplayController.invalidateArea(bounds); 304 } 305 306 } 252 307 }
Note:
See TracChangeset
for help on using the changeset viewer.