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. 158
      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));
drawingGraphics = prepareImage(img, bgColor, fgColor, scaleX, scaleY);
textRect.setLocation(0, 0);
} else {
drawingGraphics.clipRect(textRect.x, textRect.y, textRect.width, textRect.height);
}
drawingGraphics.setFont(font);

158
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) {
if (cellContainer.getComponent() == null || index == null) return;
if (isDifferentPopupOpen()) return;
final boolean isEditing = cellContainer.isEditingCell(index);
final Rectangle allocation = cellContainer.getAllocation();
final Rectangle cellBounds = cellContainer.getCellBoundsAt(index, isEditing);
if (cellBounds != null && allocation != null) {
final Rectangle visibleBounds = allocation.intersection(cellBounds);
if (visibleBounds.contains(p)) {
final Component comp = cellContainer.getEffectiveCellRendererComponent(index, isEditing);
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)) {
if (isPopupNeeded(index, isEditing, visibleBounds)) {
Point popupLocation = cellContainer.getComponent().getLocationOnScreen();
Rectangle popupBounds = calculatePopupBounds(cellBounds, visibleBounds, !isEditing);
if (!visibleBounds.contains(popupBounds)) {
@ -112,12 +102,10 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
popupBounds.x += popupLocation.x;
popupBounds.y += popupLocation.y;
enter(index, popupBounds, cellBounds);
return;
} else {
lastIndex = index;
}
} else {
leave();
}
leave();
return;
}
}
@ -125,6 +113,34 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
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,
final boolean addBorder) {
Rectangle rect = new Rectangle(visibleBounds);
@ -132,45 +148,10 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
popupComponent.setBorderInsets(1, 1, 1, 1);
if (isRespectCellWidth()) {
if (cellBounds.x >= visibleBounds.x
&& cellBounds.x + cellBounds.width <= visibleBounds.x + visibleBounds.width) {
rect.x = cellBounds.x;
rect.width = cellBounds.width;
} 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);
}
}
calculatePopupWidth(cellBounds, visibleBounds, rect, ltr);
}
if (isRespectCellHeight()) {
if ((cellBounds.y >= visibleBounds.y
&& cellBounds.y + cellBounds.height <= visibleBounds.y + visibleBounds.height)) {
rect.y = cellBounds.y;
rect.height = cellBounds.height;
} else {
int upperDiff = Math.max(cellBounds.y + cellBounds.height - visibleBounds.y - visibleBounds.height, 0);
int lowerDiff = Math.max(visibleBounds.y - cellBounds.y, 0);
if (upperDiff > 0) lowerDiff = 0;
if (upperDiff >= lowerDiff) {
rect.y = visibleBounds.y + visibleBounds.height;
rect.height = upperDiff;
popupComponent.setBottom(0);
} else {
rect.y = cellBounds.y;
rect.height = lowerDiff;
popupComponent.setTop(0);
}
}
calculatePopupHeight(cellBounds, visibleBounds, rect);
}
if (!addBorder) {
popupComponent.setBorderInsets(0, 0, 0, 0);
@ -183,6 +164,50 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
return rect;
}
private void calculatePopupHeight(final Rectangle cellBounds, final Rectangle visibleBounds, final Rectangle rect) {
if ((cellBounds.y >= visibleBounds.y
&& cellBounds.y + cellBounds.height <= visibleBounds.y + visibleBounds.height)) {
rect.y = cellBounds.y;
rect.height = cellBounds.height;
} else {
int upperDiff = Math.max(cellBounds.y + cellBounds.height - visibleBounds.y - visibleBounds.height, 0);
int lowerDiff = Math.max(visibleBounds.y - cellBounds.y, 0);
if (upperDiff > 0) lowerDiff = 0;
if (upperDiff >= lowerDiff) {
rect.y = visibleBounds.y + visibleBounds.height;
rect.height = upperDiff;
popupComponent.setBottom(0);
} else {
rect.y = cellBounds.y;
rect.height = lowerDiff;
popupComponent.setTop(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 {
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);
}
}
}
@Override
public void mouseExited(final MouseEvent e) {
if (isOverEditor(e.getPoint())) {
@ -218,14 +243,17 @@ public class CellHintPopupListener<T extends JComponent, I> extends MouseInputAd
popupComponent.setRendererBounds(rendererBounds);
if (popup != 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) {
movePopup(bounds);
}
}
if (popup == null) {
popup = PopupFactory.getSharedInstance().getPopup(cellContainer.getComponent(), popupComponent,
bounds.x, bounds.y);
popup = PopupFactory.getSharedInstance()
.getPopup(cellContainer.getComponent(), popupComponent, bounds.x, bounds.y);
popup.show();
if (DarkPopupFactory.getPopupType(popup) == DarkPopupFactory.PopupType.HEAVY_WEIGHT) {
// 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) {
Component renderer = cellHintPopupListener.getRenderer();
if (rendererBounds != null && renderer != null) {
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());
}
paintBackground(g, renderer);
g.translate(-rendererBounds.x, -rendererBounds.y);
// 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);
}
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() {
return borderColor;
}

Loading…
Cancel
Save