refactor ToolTipHandler to allow more control over content

This commit is contained in:
Eyck Jentzsch 2020-03-21 08:42:35 +01:00
parent cea11743eb
commit 14ac6654b9
5 changed files with 124 additions and 168 deletions

View File

@ -7,7 +7,6 @@ public class Constants {
public static final int[] unitMultiplier={1, 3, 10, 30, 100, 300}; public static final int[] unitMultiplier={1, 3, 10, 30, 100, 300};
public static final String CONTENT_PROVIDER_TAG = "TOOLTIP_CONTENT_PROVIDER"; public static final String CONTENT_PROVIDER_TAG = "TOOLTIP_CONTENT_PROVIDER";
public static final String TEXT_PROVIDER_TAG = "TOOLTIP_TEXT_PROVIDER";
public static final String HELP_PROVIDER_TAG = "TOOLTIP_HELP_PROVIDER"; public static final String HELP_PROVIDER_TAG = "TOOLTIP_HELP_PROVIDER";
} }

View File

@ -0,0 +1,10 @@
package com.minres.scviewer.database.swt;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
public interface ToolTipContentProvider {
public boolean createContent(Composite parent, Point pt);
}

View File

@ -1,21 +0,0 @@
package com.minres.scviewer.database.swt;
import java.util.List;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Widget;
public interface ToolTipTableContentProvider {
public ToolTipTableContentProvider initialize(Widget widget, Point pt);
public String getTableTitle();
/**
* Get tool tip table content
* @param widget the widget that is under help
* @oaram pt the point where the mouse cursor is located
* @return a list of string arrays of size 2 (content & value)
*/
public List<String[]> getTableContent();
}

View File

@ -12,9 +12,12 @@ import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableColumn;
@ -24,11 +27,11 @@ import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.Widget; import org.eclipse.swt.widgets.Widget;
import com.minres.scviewer.database.swt.Constants; import com.minres.scviewer.database.swt.Constants;
import com.minres.scviewer.database.swt.ToolTipContentProvider;
import com.minres.scviewer.database.swt.ToolTipHelpTextProvider; import com.minres.scviewer.database.swt.ToolTipHelpTextProvider;
import com.minres.scviewer.database.swt.ToolTipTableContentProvider;
class ToolTipHandler { class ToolTipHandler {
private final Display display; private final Display display;
private Shell parentShell; private Shell parentShell;
private Shell shell; private Shell shell;
@ -36,12 +39,12 @@ class ToolTipHandler {
private Table table; private Table table;
private TableColumn nameCol; private TableColumn nameCol;
private TableColumn valueCol; private TableColumn valueCol;
private Widget tipWidget; // widget this tooltip is hovering over private Widget tipWidget; // widget this tooltip is hovering over
private Point tipPosition; // the position being hovered over private Point tipPosition; // the position being hovered over
private static final int hoverYOffset = 1; private static final int hoverYOffset = 1;
/** /**
* Creates a new tooltip handler * Creates a new tooltip handler
* *
@ -49,43 +52,7 @@ class ToolTipHandler {
*/ */
public ToolTipHandler(Shell parent) { public ToolTipHandler(Shell parent) {
display = parent.getDisplay(); display = parent.getDisplay();
this.parentShell = parent; parentShell = parent;
shell = new Shell(parent, SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL);
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 1;
gridLayout.marginWidth = 2;
gridLayout.marginHeight = 2;
shell.setLayout(gridLayout);
shell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
label = new Label(shell, SWT.NONE);
label.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
label.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL |GridData.VERTICAL_ALIGN_CENTER));
final Font font = new Font(Display.getCurrent(), "Terminal", 10, SWT.NORMAL);
table = new Table(shell, SWT.NONE);
table.setHeaderVisible(false);
table.setLinesVisible(true);
table.setFont(font);
table.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
table.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
table.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
nameCol = new TableColumn(table, SWT.LEFT);
nameCol.setText("Name");
valueCol = new TableColumn(table, SWT.LEFT);
nameCol.setText("Value");
shell.addPaintListener(new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
Rectangle area = shell.getClientArea();
valueCol.setWidth(area.width - nameCol.getWidth());
}
});
} }
/** /**
@ -94,83 +61,45 @@ class ToolTipHandler {
* @control the control on which to enable hoverhelp * @control the control on which to enable hoverhelp
*/ */
public void activateHoverHelp(final Control control) { public void activateHoverHelp(final Control control) {
/* Listener listener = new Listener () {
* Get out of the way if we attempt to activate the control underneath the tooltip Shell tip = null;
*/
control.addMouseListener(MouseListener.mouseDownAdapter(e -> {
if (shell.isVisible())
shell.setVisible(false);
}));
/*
* Trap hover events to pop-up tooltip
*/
control.addMouseTrackListener(new MouseTrackAdapter () {
@Override @Override
public void mouseExit(MouseEvent e) { public void handleEvent (Event event) {
if (shell.isVisible()) shell.setVisible(false); switch (event.type) {
tipWidget = null; case SWT.Dispose:
} case SWT.KeyDown:
@Override case SWT.MouseMove: {
public void mouseHover (MouseEvent event) { if (tip == null) break;
Point pt = new Point (event.x, event.y); tip.dispose ();
Widget widget = event.widget; tip = null;
if (widget instanceof ToolBar) { label = null;
ToolBar w = (ToolBar) widget; break;
widget = w.getItem (pt);
} }
if (widget instanceof Table) { case SWT.MouseHover: {
Table w = (Table) widget; Object o = control.getData(Constants.CONTENT_PROVIDER_TAG);
widget = w.getItem (pt); if(o != null && o instanceof ToolTipContentProvider) {
} ToolTipContentProvider provider = ((ToolTipContentProvider)o);
if (widget instanceof Tree) { Point pt = new Point (event.x, event.y);
Tree w = (Tree) widget; tipPosition = control.toDisplay(pt);
widget = w.getItem (pt); if (tip != null && !tip.isDisposed ()) tip.dispose ();
} tip = new Shell (parentShell, SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL);
if (widget == null) { tip.setBackground (display.getSystemColor (SWT.COLOR_INFO_BACKGROUND));
shell.setVisible(false); RowLayout layout=new RowLayout(SWT.VERTICAL);
tipWidget = null; layout.fill=true;
return; tip.setLayout(layout);
} boolean visible = provider.createContent(tip, pt);
Point newPos = control.toDisplay(pt); tip.pack();
if(shell.isFocusControl()) return; setHoverLocation(tip, tipPosition);
if (widget == tipWidget && tipPosition.equals(newPos) && shell.isVisible()) return; tip.setVisible (visible);
tipWidget = widget;
tipPosition = newPos;
boolean showDialog = false;
Object o = widget.getData(Constants.CONTENT_PROVIDER_TAG);
if(o != null) {
ToolTipTableContentProvider provider = ((ToolTipTableContentProvider)o).initialize(widget, pt);
label.setText(provider.getTableTitle());
table.setRedraw(false);
table.removeAll();
for (String[] strings : provider.getTableContent()) {
if(strings.length>0) {
showDialog=true;
TableItem item = new TableItem(table, SWT.NONE);
item.setText(0, strings[0]);
if(strings.length>1)
item.setText(1, strings[1]);
}
} }
nameCol.pack();
valueCol.pack();
table.setRedraw(true);
table.setVisible(true);
} else {
table.setVisible(false);
} }
String text = (String) widget.getData(Constants.TEXT_PROVIDER_TAG);
if(text != null) {
label.setText(text != null ? text : "Hover test should go here");
showDialog=true;
}
if(showDialog) {
shell.pack();
setHoverLocation(shell, tipPosition);
shell.setVisible(true);
} }
} }
}); };
control.addListener (SWT.Dispose, listener);
control.addListener (SWT.KeyDown, listener);
control.addListener (SWT.MouseMove, listener);
control.addListener (SWT.MouseHover, listener);
/* /*
* Trap F1 Help to pop up a custom help box * Trap F1 Help to pop up a custom help box
@ -193,11 +122,11 @@ class ToolTipHandler {
helpShell.open(); helpShell.open();
} }
}); });
// control.addKeyListener(KeyListener.keyPressedAdapter( e-> { // control.addKeyListener(KeyListener.keyPressedAdapter( e-> {
// if (e.keyCode == SWT.F2 && shell.isVisible()) { // if (e.keyCode == SWT.F2 && shell.isVisible()) {
// shell.setFocus(); // shell.setFocus();
// } // }
// })); // }));
} }
/** /**

View File

@ -65,13 +65,21 @@ import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Widget; import org.eclipse.swt.widgets.Widget;
import com.minres.scviewer.database.DataType; import com.minres.scviewer.database.DataType;
@ -84,7 +92,8 @@ import com.minres.scviewer.database.IWaveformDb;
import com.minres.scviewer.database.IWaveformDbFactory; import com.minres.scviewer.database.IWaveformDbFactory;
import com.minres.scviewer.database.RelationType; import com.minres.scviewer.database.RelationType;
import com.minres.scviewer.database.swt.Constants; import com.minres.scviewer.database.swt.Constants;
import com.minres.scviewer.database.swt.ToolTipTableContentProvider; import com.minres.scviewer.database.swt.ToolTipContentProvider;
import com.minres.scviewer.database.swt.ToolTipHelpTextProvider;
import com.minres.scviewer.database.swt.WaveformViewerFactory; import com.minres.scviewer.database.swt.WaveformViewerFactory;
import com.minres.scviewer.database.ui.GotoDirection; import com.minres.scviewer.database.ui.GotoDirection;
import com.minres.scviewer.database.ui.ICursor; import com.minres.scviewer.database.ui.ICursor;
@ -372,35 +381,41 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
waveformPane.addDisposeListener(this); waveformPane.addDisposeListener(this);
waveformPane.getWaveformControl().setData(Constants.CONTENT_PROVIDER_TAG, new ToolTipTableContentProvider() { waveformPane.getWaveformControl().setData(Constants.CONTENT_PROVIDER_TAG, new ToolTipHelpTextProvider() {
private List<Object> res;
@Override @Override
public ToolTipTableContentProvider initialize(Widget widget, Point pt) { public String getHelpText(Widget widget) {
res = waveformPane.getElementsAt(pt); return "Waveform pane: press F2 to set the focus to the tooltip";
return this;
} }
});
waveformPane.getWaveformControl().setData(Constants.CONTENT_PROVIDER_TAG, new ToolTipContentProvider() {
@Override @Override
public String getTableTitle() { public boolean createContent(Composite parent, Point pt) {
if(res.size()>0) { List<Object> res = waveformPane.getElementsAt(pt);
Object o = res.get(0); if(res.size()>0)
if(o instanceof ITx) { if(res.get(0) instanceof ITx) {
ITx tx = (ITx)o; ITx tx = (ITx)res.get(0);
return tx.toString(); final Display display = parent.getDisplay();
} final Font font = new Font(Display.getCurrent(), "Terminal", 10, SWT.NORMAL);
}
return ""; final Label label = new Label(parent, SWT.NONE);
} label.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
label.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
label.setText(tx.toString());
label.setFont(font);
final Table table = new Table(parent, SWT.NONE);
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.setFont(font);
table.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
table.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
table.setRedraw(false);
final TableColumn nameCol = new TableColumn(table, SWT.LEFT);
nameCol.setText("Attribute");
final TableColumn valueCol = new TableColumn(table, SWT.LEFT);
valueCol.setText("Value");
@Override
public List<String[]> getTableContent() {
final ArrayList<String[]> ret = new ArrayList<>();
if(res.size()>0){
Object o = res.get(0);
if(o instanceof ITx) {
ITx tx = (ITx)o;
ret.add(new String[]{"type", tx.getGenerator().getName()});
for (ITxAttribute iTxAttribute : tx.getAttributes()) { for (ITxAttribute iTxAttribute : tx.getAttributes()) {
String value = iTxAttribute.getValue().toString(); String value = iTxAttribute.getValue().toString();
if((DataType.UNSIGNED == iTxAttribute.getDataType() || DataType.INTEGER==iTxAttribute.getDataType()) && !"0".equals(value)) { if((DataType.UNSIGNED == iTxAttribute.getDataType() || DataType.INTEGER==iTxAttribute.getDataType()) && !"0".equals(value)) {
@ -408,11 +423,35 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis
value += " [0x"+Long.toHexString(Long.parseLong(iTxAttribute.getValue().toString()))+"]"; value += " [0x"+Long.toHexString(Long.parseLong(iTxAttribute.getValue().toString()))+"]";
} catch(NumberFormatException e) { } } catch(NumberFormatException e) { }
} }
ret.add(new String[]{iTxAttribute.getName(), value}); TableItem item = new TableItem(table, SWT.NONE);
item.setText(0, iTxAttribute.getName());
item.setText(1, value);
} }
nameCol.pack();
valueCol.pack();
table.setRedraw(true);
parent.addPaintListener(new PaintListener() {
@Override
public void paintControl(PaintEvent e) {
Rectangle area = parent.getClientArea();
valueCol.setWidth(area.width - nameCol.getWidth());
}
});
return true;
} else if(res.get(0) instanceof TrackEntry) {
TrackEntry te = (TrackEntry)res.get(0);
final Display display = parent.getDisplay();
final Font font = new Font(Display.getCurrent(), "Terminal", 10, SWT.NORMAL);
final Label label = new Label(parent, SWT.NONE);
label.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND));
label.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND));
label.setText(te.waveform.getFullName());
label.setFont(font);
return true;
} }
} return false;
return ret;
} }
}); });
} }