Browse Source

Use minimum cell size for determining the necessity of a cell popup.

Don't show a popup if a popup menu is open, as it would obstruct the menu.
pull/229/head
weisj 4 years ago
parent
commit
647d4e6a15
  1. 2
      core/src/main/java/com/github/weisj/darklaf/graphics/StringPainter.java
  2. 134
      core/src/main/java/com/github/weisj/darklaf/ui/cell/hint/CellHintPopupListener.java

2
core/src/main/java/com/github/weisj/darklaf/graphics/StringPainter.java

@ -150,8 +150,6 @@ public class StringPainter {
(int) Math.round(scaleY * textRect.height)); (int) Math.round(scaleY * textRect.height));
drawingGraphics = prepareImage(img, bgColor, fgColor, scaleX, scaleY); drawingGraphics = prepareImage(img, bgColor, fgColor, scaleX, scaleY);
textRect.setLocation(0, 0); textRect.setLocation(0, 0);
} else {
drawingGraphics.clipRect(textRect.x, textRect.y, textRect.width, textRect.height);
} }
drawingGraphics.setFont(font); drawingGraphics.setFont(font);

134
core/src/main/java/com/github/weisj/darklaf/ui/cell/hint/CellHintPopupListener.java

@ -86,24 +86,14 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
private void updatePopup(final I index, final Point p) { private void updatePopup(final I index, final Point p) {
if (cellContainer.getComponent() == null || index == null) return; if (cellContainer.getComponent() == null || index == null) return;
if (isDifferentPopupOpen()) return;
final boolean isEditing = cellContainer.isEditingCell(index); final boolean isEditing = cellContainer.isEditingCell(index);
final Rectangle allocation = cellContainer.getAllocation(); final Rectangle allocation = cellContainer.getAllocation();
final Rectangle cellBounds = cellContainer.getCellBoundsAt(index, isEditing); final Rectangle cellBounds = cellContainer.getCellBoundsAt(index, isEditing);
if (cellBounds != null && allocation != null) { if (cellBounds != null && allocation != null) {
final Rectangle visibleBounds = allocation.intersection(cellBounds); final Rectangle visibleBounds = allocation.intersection(cellBounds);
if (visibleBounds.contains(p)) { if (visibleBounds.contains(p)) {
final Component comp = cellContainer.getEffectiveCellRendererComponent(index, isEditing); if (isPopupNeeded(index, isEditing, visibleBounds)) {
final Dimension prefSize = isEditing ? comp.getBounds().getSize() : comp.getPreferredSize();
if (comp instanceof JComponent) {
// Avoid showing the popup if only the border is obscured.
Border border = ((JComponent) comp).getBorder();
if (border != null) {
Insets borderInsets = border.getBorderInsets(comp);
prefSize.width -= borderInsets.left + borderInsets.right;
prefSize.height -= borderInsets.top + borderInsets.bottom;
}
}
if (!(visibleBounds.width >= prefSize.width && visibleBounds.height >= prefSize.height)) {
Point popupLocation = cellContainer.getComponent().getLocationOnScreen(); Point popupLocation = cellContainer.getComponent().getLocationOnScreen();
Rectangle popupBounds = calculatePopupBounds(cellBounds, visibleBounds, !isEditing); Rectangle popupBounds = calculatePopupBounds(cellBounds, visibleBounds, !isEditing);
if (!visibleBounds.contains(popupBounds)) { if (!visibleBounds.contains(popupBounds)) {
@ -112,12 +102,10 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
popupBounds.x += popupLocation.x; popupBounds.x += popupLocation.x;
popupBounds.y += popupLocation.y; popupBounds.y += popupLocation.y;
enter(index, popupBounds, cellBounds); enter(index, popupBounds, cellBounds);
return;
} else {
lastIndex = index;
}
} }
} else {
leave(); leave();
}
return; return;
} }
} }
@ -125,6 +113,34 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
leave(); leave();
} }
private boolean isDifferentPopupOpen() {
return MenuSelectionManager.defaultManager().getSelectedPath().length > 0;
}
private boolean isPopupNeeded(final I index, final boolean isEditing, final Rectangle visibleBounds) {
final Component comp = cellContainer.getEffectiveCellRendererComponent(index, isEditing);
final Dimension prefSize = getPreferredSize(isEditing, comp);
return !fitsInside(prefSize, visibleBounds);
}
private boolean fitsInside(final Dimension size, final Rectangle bounds) {
return bounds.width >= size.width && bounds.height >= size.height;
}
private Dimension getPreferredSize(final boolean isEditing, final Component comp) {
final Dimension prefSize = isEditing ? comp.getBounds().getSize() : comp.getMinimumSize();
if (comp instanceof JComponent) {
// Avoid showing the popup if only the border is obscured.
Border border = ((JComponent) comp).getBorder();
if (border != null) {
Insets borderInsets = border.getBorderInsets(comp);
prefSize.width -= borderInsets.left + borderInsets.right;
prefSize.height -= borderInsets.top + borderInsets.bottom;
}
}
return prefSize;
}
private Rectangle calculatePopupBounds(final Rectangle cellBounds, final Rectangle visibleBounds, private Rectangle calculatePopupBounds(final Rectangle cellBounds, final Rectangle visibleBounds,
final boolean addBorder) { final boolean addBorder) {
Rectangle rect = new Rectangle(visibleBounds); Rectangle rect = new Rectangle(visibleBounds);
@ -132,27 +148,23 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
popupComponent.setBorderInsets(1, 1, 1, 1); popupComponent.setBorderInsets(1, 1, 1, 1);
if (isRespectCellWidth()) { if (isRespectCellWidth()) {
if (cellBounds.x >= visibleBounds.x calculatePopupWidth(cellBounds, visibleBounds, rect, ltr);
&& cellBounds.x + cellBounds.width <= visibleBounds.x + visibleBounds.width) { }
rect.x = cellBounds.x; if (isRespectCellHeight()) {
rect.width = cellBounds.width; calculatePopupHeight(cellBounds, visibleBounds, rect);
} else {
int upperDiff = Math.max(cellBounds.x + cellBounds.width - visibleBounds.x - visibleBounds.width, 0);
int lowerDiff = Math.max(visibleBounds.x - cellBounds.x, 0);
if (ltr && upperDiff > 0) lowerDiff = 0;
if (!ltr && lowerDiff > 0) upperDiff = 0;
if (upperDiff >= lowerDiff) {
rect.x = visibleBounds.x + visibleBounds.width;
rect.width = upperDiff;
popupComponent.setLeft(0);
} else {
rect.x = cellBounds.x;
rect.width = lowerDiff;
popupComponent.setRight(0);
} }
if (!addBorder) {
popupComponent.setBorderInsets(0, 0, 0, 0);
} else {
rect.x -= popupComponent.getLeft();
rect.y -= popupComponent.getTop();
rect.width += popupComponent.getLeft() + popupComponent.getRight();
rect.height += popupComponent.getTop() + popupComponent.getBottom();
} }
return rect;
} }
if (isRespectCellHeight()) {
private void calculatePopupHeight(final Rectangle cellBounds, final Rectangle visibleBounds, final Rectangle rect) {
if ((cellBounds.y >= visibleBounds.y if ((cellBounds.y >= visibleBounds.y
&& cellBounds.y + cellBounds.height <= visibleBounds.y + visibleBounds.height)) { && cellBounds.y + cellBounds.height <= visibleBounds.y + visibleBounds.height)) {
rect.y = cellBounds.y; rect.y = cellBounds.y;
@ -172,15 +184,28 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
} }
} }
} }
if (!addBorder) {
popupComponent.setBorderInsets(0, 0, 0, 0); private void calculatePopupWidth(final Rectangle cellBounds, final Rectangle visibleBounds, final Rectangle rect,
final boolean ltr) {
if (cellBounds.x >= visibleBounds.x
&& cellBounds.x + cellBounds.width <= visibleBounds.x + visibleBounds.width) {
rect.x = cellBounds.x;
rect.width = cellBounds.width;
} else { } else {
rect.x -= popupComponent.getLeft(); int upperDiff = Math.max(cellBounds.x + cellBounds.width - visibleBounds.x - visibleBounds.width, 0);
rect.y -= popupComponent.getTop(); int lowerDiff = Math.max(visibleBounds.x - cellBounds.x, 0);
rect.width += popupComponent.getLeft() + popupComponent.getRight(); if (ltr && upperDiff > 0) lowerDiff = 0;
rect.height += popupComponent.getTop() + popupComponent.getBottom(); if (!ltr && lowerDiff > 0) upperDiff = 0;
if (upperDiff >= lowerDiff) {
rect.x = visibleBounds.x + visibleBounds.width;
rect.width = upperDiff;
popupComponent.setLeft(0);
} else {
rect.x = cellBounds.x;
rect.width = lowerDiff;
popupComponent.setRight(0);
}
} }
return rect;
} }
@Override @Override
@ -218,14 +243,17 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
popupComponent.setRendererBounds(rendererBounds); popupComponent.setRendererBounds(rendererBounds);
if (popup != null) { if (popup != null) {
Point p = popupComponent.isShowing() ? popupComponent.getLocationOnScreen() : null; Point p = popupComponent.isShowing() ? popupComponent.getLocationOnScreen() : null;
if (p == null || p.x != bounds.x || p.y != bounds.y || popupComponent.getWidth() != bounds.width if (p == null
|| p.x != bounds.x
|| p.y != bounds.y
|| popupComponent.getWidth() != bounds.width
|| popupComponent.getHeight() != bounds.height) { || popupComponent.getHeight() != bounds.height) {
movePopup(bounds); movePopup(bounds);
} }
} }
if (popup == null) { if (popup == null) {
popup = PopupFactory.getSharedInstance().getPopup(cellContainer.getComponent(), popupComponent, popup = PopupFactory.getSharedInstance()
bounds.x, bounds.y); .getPopup(cellContainer.getComponent(), popupComponent, bounds.x, bounds.y);
popup.show(); popup.show();
if (DarkPopupFactory.getPopupType(popup) == DarkPopupFactory.PopupType.HEAVY_WEIGHT) { if (DarkPopupFactory.getPopupType(popup) == DarkPopupFactory.PopupType.HEAVY_WEIGHT) {
// Ensure heavy weight popup is at desired location. // Ensure heavy weight popup is at desired location.
@ -363,13 +391,7 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
public void paint(final Graphics g) { public void paint(final Graphics g) {
Component renderer = cellHintPopupListener.getRenderer(); Component renderer = cellHintPopupListener.getRenderer();
if (rendererBounds != null && renderer != null) { if (rendererBounds != null && renderer != null) {
Color bg = cellHintPopupListener.getBackground(renderer); paintBackground(g, renderer);
if (bg == null) bg = cellHintPopupListener.cellContainer.getComponent().getBackground();
if (bg == null) bg = getBackground();
if (bg != null) {
g.setColor(bg);
g.fillRect(0, 0, getWidth(), getHeight());
}
g.translate(-rendererBounds.x, -rendererBounds.y); g.translate(-rendererBounds.x, -rendererBounds.y);
// If the renderer is an editor we need to restore the bounds. // If the renderer is an editor we need to restore the bounds.
@ -385,6 +407,16 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
PaintUtil.drawRect(g, 0, 0, getWidth(), getHeight(), borderInsets); PaintUtil.drawRect(g, 0, 0, getWidth(), getHeight(), borderInsets);
} }
public void paintBackground(final Graphics g, final Component renderer) {
Color bg = cellHintPopupListener.getBackground(renderer);
if (bg == null) bg = cellHintPopupListener.cellContainer.getComponent().getBackground();
if (bg == null) bg = getBackground();
if (bg != null) {
g.setColor(bg);
g.fillRect(0, 0, getWidth(), getHeight());
}
}
public Color getBorderColor() { public Color getBorderColor() {
return borderColor; return borderColor;
} }

Loading…
Cancel
Save