mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Merge remote-tracking branch 'origin/GP-3866_ghidragon_fieldpanel_scroll_bug' into Ghidra_11.0
This commit is contained in:
commit
fda9c1f35e
4 changed files with 139 additions and 59 deletions
|
@ -250,7 +250,7 @@ public class ByteViewerPanel extends JPanel
|
|||
startField.setText(start);
|
||||
ByteBlock lastBlock = blocks[blocks.length - 1];
|
||||
endField.setText(lastBlock
|
||||
.getLocationRepresentation(lastBlock.getLength().subtract(BigInteger.ONE)));
|
||||
.getLocationRepresentation(lastBlock.getLength().subtract(BigInteger.ONE)));
|
||||
|
||||
indexPanelWidth = getIndexPanelWidth(blocks);
|
||||
int center = indexPanelWidth / 2;
|
||||
|
@ -1172,6 +1172,11 @@ class CompositePanel extends JPanel implements IndexedScrollable, IndexScrollLis
|
|||
// handled by indexPanel
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseWheelMoved(double preciseWheelRotation, boolean isHorizontal) {
|
||||
indexPanel.mouseWheelMoved(preciseWheelRotation, isHorizontal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void indexRangeChanged(BigInteger startIndex, BigInteger endIndex, int yStart,
|
||||
int yEnd) {
|
||||
|
|
|
@ -110,7 +110,17 @@ public class FieldPanel extends JPanel
|
|||
addKeyListener(new FieldPanelKeyAdapter());
|
||||
addMouseListener(new FieldPanelMouseAdapter());
|
||||
addMouseMotionListener(new FieldPanelMouseMotionAdapter());
|
||||
addMouseWheelListener(new BigFieldPanelMouseWheelListener());
|
||||
|
||||
// This the default scroll wheel listener. Note: to work around a bug in the scroll pane,
|
||||
// this component will not expand to entirely fill the parent scroll pane (See the
|
||||
// IndexedScrollPane). This listener will handle scroll wheel events that happen over
|
||||
// field panel. There is a similar listener to handle events that happen over the
|
||||
// IndexScrollPane
|
||||
addMouseWheelListener(e -> {
|
||||
mouseWheelMoved(e.getPreciseWheelRotation(), e.isShiftDown());
|
||||
e.consume();
|
||||
});
|
||||
|
||||
addFocusListener(new FieldPanelFocusListener());
|
||||
|
||||
setDoubleBuffered(false);
|
||||
|
@ -1387,6 +1397,46 @@ public class FieldPanel extends JPanel
|
|||
return accessibleFieldPanel;
|
||||
}
|
||||
|
||||
public void mouseWheelMoved(double preciseWheelRotation, boolean horizontal) {
|
||||
|
||||
Layout firstLayout = model.getLayout(BigInteger.ZERO);
|
||||
if (firstLayout == null) {
|
||||
return; // nothing to scroll
|
||||
}
|
||||
|
||||
int scrollUnit = firstLayout.getScrollableUnitIncrement(0, 1);
|
||||
int scrollAmount = (int) (preciseWheelRotation * scrollUnit * MOUSEWHEEL_LINES_TO_SCROLL);
|
||||
|
||||
if (hoverHandler.isHoverShowing()) {
|
||||
hoverHandler.scroll(scrollAmount);
|
||||
}
|
||||
else {
|
||||
hoverHandler.stopHover();
|
||||
|
||||
if (horizontal && horizontalScrollingEnabled) {
|
||||
scrollViewHorizontally(scrollAmount);
|
||||
}
|
||||
else {
|
||||
scrollView(scrollAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void scrollViewHorizontally(int scrollAmount) {
|
||||
|
||||
JViewport vp = getViewport();
|
||||
if (vp == null) {
|
||||
// this will happen for Field Panels not placed inside of scroll panes
|
||||
return;
|
||||
}
|
||||
|
||||
Point pos = vp.getViewPosition();
|
||||
|
||||
// don't allow new x position to go negative or else you can scroll left past the beginning
|
||||
int x = Math.max(0, pos.x + scrollAmount);
|
||||
vp.setViewPosition(new Point(x, pos.y));
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Inner Classes
|
||||
//==================================================================================================
|
||||
|
@ -1753,50 +1803,6 @@ public class FieldPanel extends JPanel
|
|||
}
|
||||
}
|
||||
|
||||
private class BigFieldPanelMouseWheelListener implements MouseWheelListener {
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
double wheelRotation = e.getPreciseWheelRotation();
|
||||
|
||||
Layout firstLayout = model.getLayout(BigInteger.ZERO);
|
||||
int layoutScrollHt = firstLayout != null //
|
||||
? firstLayout.getScrollableUnitIncrement(0, 1)
|
||||
: 0;
|
||||
int scrollAmount = (int) (wheelRotation * layoutScrollHt * MOUSEWHEEL_LINES_TO_SCROLL);
|
||||
if (scrollAmount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hoverHandler.isHoverShowing()) {
|
||||
hoverHandler.scroll(scrollAmount);
|
||||
}
|
||||
else {
|
||||
hoverHandler.stopHover();
|
||||
|
||||
if (e.isShiftDown() && horizontalScrollingEnabled) {
|
||||
scrollViewHorizontally(scrollAmount);
|
||||
}
|
||||
else {
|
||||
scrollView(scrollAmount);
|
||||
}
|
||||
}
|
||||
e.consume();
|
||||
}
|
||||
|
||||
private void scrollViewHorizontally(int scrollAmount) {
|
||||
|
||||
JViewport vp = getViewport();
|
||||
if (vp == null) {
|
||||
// this will happen for Field Panels not placed inside of scroll panes
|
||||
return;
|
||||
}
|
||||
|
||||
// horizontal scroll (only move viewport)
|
||||
Point pos = vp.getViewPosition();
|
||||
vp.setViewPosition(new Point(Math.max(0, pos.x + scrollAmount), pos.y));
|
||||
}
|
||||
}
|
||||
|
||||
private class MouseHandler implements ActionListener {
|
||||
private Timer scrollTimer; // used to generate auto scroll
|
||||
private int mouseDownX;
|
||||
|
|
|
@ -50,6 +50,14 @@ public class IndexedScrollPane extends JPanel implements IndexScrollListener {
|
|||
|
||||
add(scrollPane);
|
||||
viewport = scrollPane.getViewport();
|
||||
|
||||
// This scroll pane does not have the view component track the width. This is to
|
||||
// prevent a text clipping issue caused by the scroll pane not compensating for the
|
||||
// scroll bars. Since the component may not occupy the full width of this scroll pane,
|
||||
// we need to process any scroll wheel events that happen outside of that component.
|
||||
viewport.addMouseWheelListener(e -> {
|
||||
scrollable.mouseWheelMoved(e.getPreciseWheelRotation(), e.isShiftDown());
|
||||
});
|
||||
viewport.setBackground(comp.getBackground());
|
||||
viewport.addChangeListener(e -> viewportStateChanged());
|
||||
viewport.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
|
||||
|
@ -191,6 +199,7 @@ public class IndexedScrollPane extends JPanel implements IndexScrollListener {
|
|||
ScrollView(JComponent component) {
|
||||
setLayout(new ScrollViewLayout());
|
||||
add(component);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -18,29 +17,90 @@ package docking.widgets.indexedscrollpane;
|
|||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Interface for scrolling a FieldPanel or container of a group of FieldPanels which displays
|
||||
* a list of displayable items (layouts)
|
||||
*/
|
||||
public interface IndexedScrollable {
|
||||
|
||||
BigInteger getIndexCount();
|
||||
/**
|
||||
* Returns the number individually addressable items displayed.
|
||||
* @return the number individually addressable items displayed
|
||||
*/
|
||||
public BigInteger getIndexCount();
|
||||
|
||||
boolean isUniformIndex();
|
||||
/**
|
||||
* Returns true if all the items are the same vertical size.
|
||||
* @return true if all the items are the same vertical size
|
||||
*/
|
||||
public boolean isUniformIndex();
|
||||
|
||||
int getHeight(BigInteger index);
|
||||
/**
|
||||
* Returns the height of the n'th item.
|
||||
* @param index the index of the time to get height for
|
||||
* @return the height of the n'th item.
|
||||
*/
|
||||
public int getHeight(BigInteger index);
|
||||
|
||||
void showIndex(BigInteger index, int verticalOffset);
|
||||
/**
|
||||
* Makes the item at the given index be visible on the screen at the given vertical offset
|
||||
* @param index the index of the item to show
|
||||
* @param verticalOffset the number of pixels from the top of the screen to show the item
|
||||
*/
|
||||
public void showIndex(BigInteger index, int verticalOffset);
|
||||
|
||||
BigInteger getIndexAfter(BigInteger index);
|
||||
/**
|
||||
* Returns the index of the next non-null item. Not all indexes have items. Some items span
|
||||
* multiple indexes
|
||||
* @param index the index to start searching for the next non-null item
|
||||
* @return the index of the next non-null item, or -1 if there is none
|
||||
*/
|
||||
public BigInteger getIndexAfter(BigInteger index);
|
||||
|
||||
BigInteger getIndexBefore(BigInteger index);
|
||||
/**
|
||||
* Returns the index of the previous non-null item. Not all indexes have items. Some items span
|
||||
* multiple indexes
|
||||
* @param index the index to start searching backwards for the previous non-null item
|
||||
* @return the index of the previous non-null item, or -1 if there is none
|
||||
*/
|
||||
public BigInteger getIndexBefore(BigInteger index);
|
||||
|
||||
void scrollLineUp();
|
||||
/**
|
||||
* Scrolls the displayed items up by the height of one line of text
|
||||
*/
|
||||
public void scrollLineUp();
|
||||
|
||||
void scrollLineDown();
|
||||
/**
|
||||
* Scrolls the displayed items down by the height of one line of text
|
||||
*/
|
||||
public void scrollLineDown();
|
||||
|
||||
void scrollPageUp();
|
||||
/**
|
||||
* Scrolls the displayed items up by the height of one screen of text
|
||||
*/
|
||||
public void scrollPageUp();
|
||||
|
||||
void scrollPageDown();
|
||||
/**
|
||||
* Scrolls the displayed items down by the height of one screen of text
|
||||
*/
|
||||
public void scrollPageDown();
|
||||
|
||||
void addIndexScrollListener(IndexScrollListener listener);
|
||||
/**
|
||||
* Adds a listener to be notified when the view is scrolled in any way.
|
||||
* @param listener the listener to be notified when the visible items change
|
||||
*/
|
||||
public void addIndexScrollListener(IndexScrollListener listener);
|
||||
|
||||
void removeIndexScrollListener(IndexScrollListener listener);
|
||||
/**
|
||||
* Removes the given listener from those to be notified when the view changes.
|
||||
* @param listener the listener to remove
|
||||
*/
|
||||
public void removeIndexScrollListener(IndexScrollListener listener);
|
||||
|
||||
/**
|
||||
* Notify the scrollable that the mouse wheel was moved.
|
||||
* @param preciseWheelRotation the amount of rotation of the wheel
|
||||
* @param isHorizontal true if the rotation was horizontal, false for vertical
|
||||
*/
|
||||
public void mouseWheelMoved(double preciseWheelRotation, boolean isHorizontal);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue