Fixed popup window placement issue

This commit is contained in:
dragonmacher
2024-09-05 17:51:57 -04:00
parent fd7694b0c3
commit 54f0995d85
2 changed files with 29 additions and 9 deletions
@@ -43,6 +43,7 @@ import ghidra.util.Swing;
import ghidra.util.layout.PairLayout; import ghidra.util.layout.PairLayout;
import ghidra.util.layout.VerticalLayout; import ghidra.util.layout.VerticalLayout;
import ghidra.util.timer.GTimer; import ghidra.util.timer.GTimer;
import ghidra.util.timer.GTimerMonitor;
/** /**
* Internal panel of the memory search window that manages the controls for the search feature. This * Internal panel of the memory search window that manages the controls for the search feature. This
@@ -62,8 +63,10 @@ class MemorySearchControlPanel extends JPanel {
private List<ButtonState<Combiner>> initialSearchButtonStates; private List<ButtonState<Combiner>> initialSearchButtonStates;
private List<ButtonState<Combiner>> combinerSearchButtonStates; private List<ButtonState<Combiner>> combinerSearchButtonStates;
private JComboBox<SearchFormat> formatComboBox; private JComboBox<SearchFormat> formatComboBox;
private PopupWindow popup; private PopupWindow popup;
private String errorMessage; private String errorMessage;
private GTimerMonitor clearInputMonitor;
MemorySearchControlPanel(MemorySearchProvider provider, SearchGuiModel model, MemorySearchControlPanel(MemorySearchProvider provider, SearchGuiModel model,
SearchHistory history) { SearchHistory history) {
@@ -296,7 +299,7 @@ class MemorySearchControlPanel extends JPanel {
if (errorMessage == null) { if (errorMessage == null) {
return; return;
} }
errorMessage = null;
DockingUtils.setTipWindowEnabled(false); DockingUtils.setTipWindowEnabled(false);
Point location = searchInputField.getLocation(); Point location = searchInputField.getLocation();
@@ -305,13 +308,15 @@ class MemorySearchControlPanel extends JPanel {
JToolTip tip = new JToolTip(); JToolTip tip = new JToolTip();
tip.setTipText(errorMessage); tip.setTipText(errorMessage);
errorMessage = null;
if (popup != null) { if (popup != null) {
popup.dispose(); popup.dispose();
clearInputMonitor.cancel();
} }
popup = new PopupWindow(tip); popup = new PopupWindow(tip);
popup.showPopup(searchInputField, location, true); popup.showPopup(searchInputField.getParent(), location, true);
GTimer.scheduleRunnable(1500, this::clearInputError); clearInputMonitor = GTimer.scheduleRunnable(2000, this::clearInputError);
Toolkit.getDefaultToolkit().beep(); Toolkit.getDefaultToolkit().beep();
} }
@@ -321,6 +326,9 @@ class MemorySearchControlPanel extends JPanel {
PopupWindow.hideAllWindows(); PopupWindow.hideAllWindows();
if (popup != null) { if (popup != null) {
popup.dispose(); popup.dispose();
popup = null;
clearInputMonitor.cancel();
clearInputMonitor = null;
} }
} }
@@ -4,9 +4,9 @@
* 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.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -264,7 +264,18 @@ public class PopupWindow {
* Shows this popup window unless popups are disabled as reported by * Shows this popup window unless popups are disabled as reported by
* {@link DockingUtils#isTipWindowEnabled()}. If {@code forceShow} is true, then the popup * {@link DockingUtils#isTipWindowEnabled()}. If {@code forceShow} is true, then the popup
* will be shown regardless of the state returned by {@link DockingUtils#isTipWindowEnabled()}. * will be shown regardless of the state returned by {@link DockingUtils#isTipWindowEnabled()}.
* @param component the component for the popup * <P>
* Note: the component passed in is the component to which the {@code location} the location
* belongs. In the example below, the component used to get the location is to the component
* passed to this method. This is because the location is relative to the parent's coordinate
* space. Thus, when calling this method, make sure to use the correct component.
* <PRE>
* Point location = textField.getLocation(); // this is relative to the text field's parent
* Component parent = textField.getParent();
* PopupWindow.showPopup(parent, location, true);
* </PRE>
*
* @param component the component whose coordinate space the location belongs
* @param location the location to show the popup * @param location the location to show the popup
* @param forceShow true to show the popup even popups are disabled application-wide * @param forceShow true to show the popup even popups are disabled application-wide
*/ */
@@ -395,14 +406,14 @@ public class PopupWindow {
Rectangle newArea = new Rectangle(keepVisibleAea); Rectangle newArea = new Rectangle(keepVisibleAea);
Point point = newArea.getLocation(); Point point = newArea.getLocation();
SwingUtilities.convertPointToScreen(point, source.getParent()); SwingUtilities.convertPointToScreen(point, source);
newArea.setLocation(point); newArea.setLocation(point);
return newArea; return newArea;
} }
// for debug // for debug
private void installDebugPainter(Rectangle keepVisibleArea) { private void installDebugPainter(Rectangle keepVisibleArea) {
//
// GGlassPane glassPane = GGlassPane.getGlassPane(source); // GGlassPane glassPane = GGlassPane.getGlassPane(source);
// for (GGlassPanePainter p : painters) { // for (GGlassPanePainter p : painters) {
// glassPane.removePainter(p); // glassPane.removePainter(p);
@@ -439,7 +450,8 @@ public class PopupWindow {
// show where the user hovered // show where the user hovered
if (location != null) { if (location != null) {
Point p = new Point(location); Point p = new Point(location);
p = SwingUtilities.convertPoint(source.getParent(), p.x, p.y, glassPane); p = SwingUtilities.convertPoint(source, p.x, p.y, glassPane);
g.setColor(Palette.RED.withAlpha(alpha)); g.setColor(Palette.RED.withAlpha(alpha));
int offset = 10; int offset = 10;
g.fillRect(p.x - offset, p.y - offset, (offset * 2), (offset * 2)); g.fillRect(p.x - offset, p.y - offset, (offset * 2), (offset * 2));