mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-21 21:52:10 +02:00
Bug 489505 - Add hovering support to the traditional memory render
Change-Id: I06d7264835a8199398aad1a0215d775caa29e079
This commit is contained in:
parent
70fe82a151
commit
5d6bef7eb5
2 changed files with 186 additions and 5 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2015 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2006, 2016 Wind River Systems, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* Ted R Williams (Wind River Systems, Inc.) - initial implementation
|
||||
* Teodor Madan (Freescale) - Fix PageDn/PageUp
|
||||
* Alvaro Sanchez-leon (Ericsson) - Add hovering support to the traditional memory render (Bug 489505)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.ui.memory.traditional;
|
||||
|
@ -26,6 +27,7 @@ import org.eclipse.swt.events.KeyListener;
|
|||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.events.MouseListener;
|
||||
import org.eclipse.swt.events.MouseMoveListener;
|
||||
import org.eclipse.swt.events.MouseTrackAdapter;
|
||||
import org.eclipse.swt.events.PaintEvent;
|
||||
import org.eclipse.swt.events.PaintListener;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
|
@ -323,6 +325,8 @@ public abstract class AbstractPane extends Canvas
|
|||
|
||||
this.addMouseMoveListener(createMouseMoveListener());
|
||||
|
||||
this.addMouseTrackListener(createMouseHoverListener());
|
||||
|
||||
this.addKeyListener(createKeyListener());
|
||||
|
||||
this.addFocusListener(createFocusListener());
|
||||
|
@ -336,6 +340,16 @@ public abstract class AbstractPane extends Canvas
|
|||
return new AbstractPaneMouseMoveListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.4
|
||||
*/
|
||||
protected MouseTrackAdapter createMouseHoverListener() {
|
||||
// This method provides an empty implementation of MouseTrackAdapter
|
||||
// The non empty implementation instance is left to the subclasses that do support Hovering
|
||||
return new MouseTrackAdapter() {
|
||||
};
|
||||
}
|
||||
|
||||
protected FocusListener createFocusListener() {
|
||||
return new AbstractPaneFocusListener();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006-2013 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2006-2016 Wind River Systems, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ted R Williams (Wind River Systems, Inc.) - initial implementation
|
||||
* Alvaro Sanchez-leon (Ericsson) - Add hovering support to the traditional memory render (Bug 489505)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.ui.memory.traditional;
|
||||
|
@ -15,12 +16,23 @@ import java.math.BigInteger;
|
|||
|
||||
import org.eclipse.debug.core.DebugException;
|
||||
import org.eclipse.debug.core.model.MemoryByte;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.events.MouseTrackAdapter;
|
||||
import org.eclipse.swt.events.PaintEvent;
|
||||
import org.eclipse.swt.graphics.GC;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
||||
public class DataPane extends AbstractPane
|
||||
{
|
||||
private Shell fToolTipShell;
|
||||
public DataPane(Rendering parent)
|
||||
{
|
||||
super(parent);
|
||||
|
@ -128,6 +140,17 @@ public class DataPane extends AbstractPane
|
|||
+ (fRendering.getCellPadding() * 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The width length in pixels needed to draw the characters of an addressable unit
|
||||
*/
|
||||
private int getAddressableWidth() {
|
||||
// derive the number of characters per addressable size e.g. 2 * NumOfOctets
|
||||
int charsPerOctet = 2;
|
||||
int addressCharacterCount = fRendering.getAddressableSize() * charsPerOctet;
|
||||
// derive width by multiplying by the size of a character
|
||||
return addressCharacterCount * getCellCharacterWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getCellCharacterCount()
|
||||
{
|
||||
|
@ -161,6 +184,43 @@ public class DataPane extends AbstractPane
|
|||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The address associated to the hovering location
|
||||
*/
|
||||
private BigInteger getAddressAt(int x, int y) {
|
||||
// Resolve the first address in the cell
|
||||
BigInteger cellBaseAddress;
|
||||
try {
|
||||
cellBaseAddress = getCellAddressAt(x, y);
|
||||
} catch (DebugException e) {
|
||||
fRendering.logError(TraditionalRenderingMessages.getString("TraditionalRendering.FAILURE_DETERMINE_ADDRESS_LOCATION"), e); //$NON-NLS-1$
|
||||
return null;
|
||||
}
|
||||
|
||||
if (cellBaseAddress == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get the start location of the cell
|
||||
Point cellPosition = getCellLocation(cellBaseAddress);
|
||||
if (cellPosition == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Resolve the horizontal offset between hover location and
|
||||
// the start of the cell
|
||||
int offset = x - cellPosition.x;
|
||||
if (offset < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Resolve the number of addresses between hover location and first address in the cell
|
||||
int addressableOffset = offset / getAddressableWidth();
|
||||
assert addressableOffset <= getAddressableOctetsPerColumn();
|
||||
|
||||
return cellBaseAddress.add(BigInteger.valueOf(addressableOffset));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Point getCellLocation(BigInteger cellAddress)
|
||||
{
|
||||
|
@ -168,6 +228,7 @@ public class DataPane extends AbstractPane
|
|||
{
|
||||
BigInteger address = fRendering.getViewportStartAddress();
|
||||
|
||||
// cell offset from base address in octets
|
||||
int cellOffset = cellAddress.subtract(address).intValue();
|
||||
cellOffset *= fRendering.getAddressableSize();
|
||||
|
||||
|
@ -264,7 +325,7 @@ public class DataPane extends AbstractPane
|
|||
|
||||
try
|
||||
{
|
||||
BigInteger start = fRendering.getViewportStartAddress();
|
||||
BigInteger startAddress = fRendering.getViewportStartAddress();
|
||||
|
||||
for(int i = 0; i < this.getBounds().height / cellHeight; i++)
|
||||
{
|
||||
|
@ -277,7 +338,7 @@ public class DataPane extends AbstractPane
|
|||
else
|
||||
gc.setForeground(fRendering.getTraditionalRendering().getColorTextAlternate());
|
||||
|
||||
BigInteger cellAddress = start.add(BigInteger.valueOf((i
|
||||
BigInteger cellAddress = startAddress.add(BigInteger.valueOf((i
|
||||
* fRendering.getColumnCount() + col)
|
||||
* fRendering.getAddressesPerColumn()));
|
||||
|
||||
|
@ -401,4 +462,110 @@ public class DataPane extends AbstractPane
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
if (fToolTipShell != null) {
|
||||
fToolTipShell.dispose();
|
||||
fToolTipShell = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MouseTrackAdapter createMouseHoverListener() {
|
||||
return new DataPaneMouseHoverListener();
|
||||
}
|
||||
|
||||
private int getAddressableOctetsPerColumn() {
|
||||
// Prevent division by zero
|
||||
int addressableSize = (fRendering.getAddressableSize() > 0) ? fRendering.getAddressableSize() : 1;
|
||||
return fRendering.getBytesPerColumn() / addressableSize;
|
||||
}
|
||||
|
||||
|
||||
class DataPaneMouseHoverListener extends MouseTrackAdapter {
|
||||
private BigInteger fTooltipAddress = null;
|
||||
private final Label fLabelContent;
|
||||
|
||||
DataPaneMouseHoverListener() {
|
||||
fLabelContent = createToolTip();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExit(MouseEvent e) {
|
||||
if (fToolTipShell != null && !fToolTipShell.isDisposed()) {
|
||||
fToolTipShell.setVisible(false);
|
||||
fTooltipAddress = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseHover(MouseEvent e) {
|
||||
if (e.widget == null || !(e.widget instanceof Control) || fToolTipShell == null || fToolTipShell.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Control control = (Control) e.widget;
|
||||
|
||||
// Resolve the address associated to the hovering location
|
||||
BigInteger address = getAddressAt(e.x, e.y);
|
||||
|
||||
if (address == null) {
|
||||
// Invalid Address at location
|
||||
return;
|
||||
}
|
||||
|
||||
// Display tooltip if there is a change in hover
|
||||
Point hoverPoint = control.toDisplay(new Point(e.x, e.y));
|
||||
if (!fToolTipShell.isVisible() || !address.equals(fTooltipAddress)) {
|
||||
diplayToolTip(hoverPoint, address);
|
||||
} else {
|
||||
// Still pointing to the same cell
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep Track of the latest visited address
|
||||
fTooltipAddress = address;
|
||||
}
|
||||
|
||||
private void diplayToolTip(Point hoverPoint, BigInteger subAddress) {
|
||||
// Show the current hovering address as the first line in the tooltip
|
||||
StringBuilder sb = new StringBuilder("0x").append(subAddress.toString(16));
|
||||
|
||||
fLabelContent.setText(sb.toString());
|
||||
|
||||
// Setting location of the tool tip
|
||||
Rectangle shellBounds = fToolTipShell.getBounds();
|
||||
shellBounds.x = hoverPoint.x;
|
||||
shellBounds.y = hoverPoint.y + getCellHeight();
|
||||
|
||||
fToolTipShell.setBounds(shellBounds);
|
||||
fToolTipShell.pack();
|
||||
|
||||
fToolTipShell.setVisible(true);
|
||||
}
|
||||
|
||||
private Label createToolTip() {
|
||||
if (fToolTipShell != null) {
|
||||
fToolTipShell.dispose();
|
||||
}
|
||||
|
||||
fToolTipShell = new Shell(getShell(), SWT.ON_TOP | SWT.RESIZE);
|
||||
GridLayout gridLayout = new GridLayout();
|
||||
gridLayout.numColumns = 1;
|
||||
gridLayout.marginWidth = 2;
|
||||
gridLayout.marginHeight = 0;
|
||||
fToolTipShell.setLayout(gridLayout);
|
||||
fToolTipShell.setBackground(fToolTipShell.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
|
||||
return createToolTipContent(fToolTipShell);
|
||||
}
|
||||
|
||||
private Label createToolTipContent(Composite composite) {
|
||||
Label toolTipContent = new Label(composite, SWT.NONE);
|
||||
toolTipContent.setForeground(composite.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
|
||||
toolTipContent.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
|
||||
toolTipContent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER));
|
||||
return toolTipContent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue