mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 05:57:56 +08:00
Merge remote-tracking branch 'origin/GP-3866_ghidragon_fieldpanel_scroll_bug' into Ghidra_11.0
This commit is contained in:
+6
-1
@@ -250,7 +250,7 @@ public class ByteViewerPanel extends JPanel
|
|||||||
startField.setText(start);
|
startField.setText(start);
|
||||||
ByteBlock lastBlock = blocks[blocks.length - 1];
|
ByteBlock lastBlock = blocks[blocks.length - 1];
|
||||||
endField.setText(lastBlock
|
endField.setText(lastBlock
|
||||||
.getLocationRepresentation(lastBlock.getLength().subtract(BigInteger.ONE)));
|
.getLocationRepresentation(lastBlock.getLength().subtract(BigInteger.ONE)));
|
||||||
|
|
||||||
indexPanelWidth = getIndexPanelWidth(blocks);
|
indexPanelWidth = getIndexPanelWidth(blocks);
|
||||||
int center = indexPanelWidth / 2;
|
int center = indexPanelWidth / 2;
|
||||||
@@ -1172,6 +1172,11 @@ class CompositePanel extends JPanel implements IndexedScrollable, IndexScrollLis
|
|||||||
// handled by indexPanel
|
// handled by indexPanel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved(double preciseWheelRotation, boolean isHorizontal) {
|
||||||
|
indexPanel.mouseWheelMoved(preciseWheelRotation, isHorizontal);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void indexRangeChanged(BigInteger startIndex, BigInteger endIndex, int yStart,
|
public void indexRangeChanged(BigInteger startIndex, BigInteger endIndex, int yStart,
|
||||||
int yEnd) {
|
int yEnd) {
|
||||||
|
|||||||
@@ -110,7 +110,17 @@ public class FieldPanel extends JPanel
|
|||||||
addKeyListener(new FieldPanelKeyAdapter());
|
addKeyListener(new FieldPanelKeyAdapter());
|
||||||
addMouseListener(new FieldPanelMouseAdapter());
|
addMouseListener(new FieldPanelMouseAdapter());
|
||||||
addMouseMotionListener(new FieldPanelMouseMotionAdapter());
|
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());
|
addFocusListener(new FieldPanelFocusListener());
|
||||||
|
|
||||||
setDoubleBuffered(false);
|
setDoubleBuffered(false);
|
||||||
@@ -1387,6 +1397,46 @@ public class FieldPanel extends JPanel
|
|||||||
return accessibleFieldPanel;
|
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
|
// 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 class MouseHandler implements ActionListener {
|
||||||
private Timer scrollTimer; // used to generate auto scroll
|
private Timer scrollTimer; // used to generate auto scroll
|
||||||
private int mouseDownX;
|
private int mouseDownX;
|
||||||
|
|||||||
+9
@@ -50,6 +50,14 @@ public class IndexedScrollPane extends JPanel implements IndexScrollListener {
|
|||||||
|
|
||||||
add(scrollPane);
|
add(scrollPane);
|
||||||
viewport = scrollPane.getViewport();
|
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.setBackground(comp.getBackground());
|
||||||
viewport.addChangeListener(e -> viewportStateChanged());
|
viewport.addChangeListener(e -> viewportStateChanged());
|
||||||
viewport.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
|
viewport.setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
|
||||||
@@ -191,6 +199,7 @@ public class IndexedScrollPane extends JPanel implements IndexScrollListener {
|
|||||||
ScrollView(JComponent component) {
|
ScrollView(JComponent component) {
|
||||||
setLayout(new ScrollViewLayout());
|
setLayout(new ScrollViewLayout());
|
||||||
add(component);
|
add(component);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+73
-13
@@ -1,6 +1,5 @@
|
|||||||
/* ###
|
/* ###
|
||||||
* IP: GHIDRA
|
* IP: GHIDRA
|
||||||
* REVIEWED: YES
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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;
|
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 {
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user