mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-149395 Fix viewport to support translucent scroll bars
This commit is contained in:
@@ -16,6 +16,9 @@
|
||||
package com.intellij.ui.components;
|
||||
|
||||
import com.intellij.openapi.ui.TypingTarget;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.ui.components.JBScrollPane.Alignment;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.util.ui.ComponentWithEmptyText;
|
||||
import com.intellij.util.ui.StatusText;
|
||||
@@ -32,6 +35,20 @@ public class JBViewport extends JViewport implements ZoomableViewport {
|
||||
|
||||
@Override
|
||||
public void layoutContainer(Container parent) {
|
||||
if (parent instanceof JViewport && Registry.is("ide.scroll.new.layout")) {
|
||||
JViewport viewport = (JViewport)parent;
|
||||
Component view = viewport.getView();
|
||||
if (view != null) {
|
||||
JScrollPane pane = getScrollPane(viewport);
|
||||
if (pane != null) {
|
||||
doLayout(pane, viewport, view);
|
||||
}
|
||||
else {
|
||||
super.layoutContainer(parent);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
JBViewport viewport = (JBViewport)parent;
|
||||
Component view = viewport.getView();
|
||||
JBScrollPane scrollPane = UIUtil.getParentOfType(JBScrollPane.class, parent);
|
||||
@@ -155,4 +172,120 @@ public class JBViewport extends JViewport implements ZoomableViewport {
|
||||
public boolean isPaintingNow() {
|
||||
return myPaintingNow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBackground() {
|
||||
Component view = getView();
|
||||
return view != null && view.isBackgroundSet()
|
||||
? view.getBackground()
|
||||
: super.getBackground();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getExtentSize() {
|
||||
Dimension size = super.getExtentSize();
|
||||
if (SystemInfo.isMac) return size;
|
||||
JScrollPane pane = getScrollPane(this);
|
||||
if (pane != null) {
|
||||
JScrollBar vsb = pane.getVerticalScrollBar();
|
||||
if (null != getAlignment(vsb)) {
|
||||
int width = vsb.getWidth();
|
||||
if (size.width > width) size.width -= width;
|
||||
}
|
||||
JScrollBar hsb = pane.getHorizontalScrollBar();
|
||||
if (null != getAlignment(hsb)) {
|
||||
int height = hsb.getHeight();
|
||||
if (size.height > height) size.height -= height;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alignment of the specified scroll bar
|
||||
* if and only if the specified scroll bar
|
||||
* is located over the corresponding viewport.
|
||||
*
|
||||
* @param bar the scroll bar to process
|
||||
* @return the scroll bar alignment or {@code null}
|
||||
*/
|
||||
private static Alignment getAlignment(JScrollBar bar) {
|
||||
if (bar != null && bar.isVisible() && !bar.isOpaque()) {
|
||||
Object property = bar.getClientProperty(Alignment.class);
|
||||
if (property instanceof Alignment) return (Alignment)property;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent scroll pane of the specified viewport
|
||||
* if and only if the specified viewport is a main viewport.
|
||||
*
|
||||
* @param viewport the viewport to process
|
||||
* @return the parent scroll pane or {@code null}
|
||||
*/
|
||||
private static JScrollPane getScrollPane(JViewport viewport) {
|
||||
Container parent = viewport.getParent();
|
||||
if (parent instanceof JScrollPane) {
|
||||
JScrollPane pane = (JScrollPane)parent;
|
||||
if (viewport == pane.getViewport()) return pane;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void doLayout(JScrollPane pane, JViewport viewport, Component view) {
|
||||
Dimension actualSize = viewport.getSize();
|
||||
Dimension extentSize = viewport.getExtentSize();
|
||||
Dimension viewPreferredSize = view.getPreferredSize();
|
||||
Dimension viewSize = new Dimension(viewPreferredSize);
|
||||
Point viewPosition = viewport.getViewPosition();
|
||||
|
||||
Scrollable scrollable = null;
|
||||
if (view instanceof Scrollable) {
|
||||
scrollable = (Scrollable)view;
|
||||
if (scrollable.getScrollableTracksViewportWidth()) viewSize.width = actualSize.width;
|
||||
if (scrollable.getScrollableTracksViewportHeight()) viewSize.height = actualSize.height;
|
||||
}
|
||||
// If the new viewport size would leave empty space to the right of the view,
|
||||
// right justify the view or left justify the view
|
||||
// when the width of the view is smaller than the container.
|
||||
int maxX = viewSize.width - extentSize.width;
|
||||
if (scrollable == null || pane.getComponentOrientation().isLeftToRight()) {
|
||||
if (viewPosition.x > maxX) {
|
||||
viewPosition.x = Math.max(0, maxX);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// NOT SUPPORTED YET
|
||||
viewPosition.x = maxX < 0 ? maxX : Math.max(0, Math.min(maxX, viewPosition.x));
|
||||
}
|
||||
// If the new viewport size would leave empty space below the view,
|
||||
// bottom justify the view or top justify the view
|
||||
// when the height of the view is smaller than the container.
|
||||
int maxY = viewSize.height - extentSize.height;
|
||||
if (viewPosition.y > maxY) {
|
||||
viewPosition.y = Math.max(0, maxY);
|
||||
}
|
||||
// If we haven't been advised about how the viewports size should change wrt to the viewport,
|
||||
// i.e. if the view isn't an instance of Scrollable, then adjust the views size as follows.
|
||||
if (scrollable == null) {
|
||||
// If the origin of the view is showing and the viewport is bigger than the views preferred size,
|
||||
// then make the view the same size as the viewport.
|
||||
if (viewPosition.x == 0 && actualSize.width > viewPreferredSize.width) viewSize.width = actualSize.width;
|
||||
if (viewPosition.y == 0 && actualSize.height > viewPreferredSize.height) viewSize.height = actualSize.height;
|
||||
}
|
||||
// do not force viewport size on editor component, e.g. EditorTextField and LanguageConsole
|
||||
if (!(view instanceof TypingTarget)) {
|
||||
if (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER == pane.getHorizontalScrollBarPolicy()) {
|
||||
viewPosition.x = 0;
|
||||
viewSize.width = actualSize.width;
|
||||
}
|
||||
if (ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER == pane.getVerticalScrollBarPolicy()) {
|
||||
viewPosition.y = 0;
|
||||
viewSize.height = actualSize.height;
|
||||
}
|
||||
}
|
||||
viewport.setViewPosition(viewPosition);
|
||||
viewport.setViewSize(viewSize);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -314,7 +314,8 @@ public final class IdeMouseEventDispatcher {
|
||||
private static JScrollBar findHorizontalScrollBar(Component c) {
|
||||
if (c == null) return null;
|
||||
if (c instanceof JScrollPane) {
|
||||
return ((JScrollPane)c).getHorizontalScrollBar();
|
||||
JScrollBar scrollBar = ((JScrollPane)c).getHorizontalScrollBar();
|
||||
return scrollBar != null && scrollBar.isVisible() ? scrollBar : null;
|
||||
}
|
||||
|
||||
if (isDiagramViewComponent(c)) {
|
||||
@@ -323,7 +324,7 @@ public final class IdeMouseEventDispatcher {
|
||||
if (view.getComponent(i) instanceof JScrollBar) {
|
||||
final JScrollBar scrollBar = (JScrollBar)view.getComponent(i);
|
||||
if (scrollBar.getOrientation() == Adjustable.HORIZONTAL) {
|
||||
return scrollBar;
|
||||
return scrollBar.isVisible() ? scrollBar : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user