Skip to content

Commit

Permalink
introduce getMouseHover, getMouseOut and getMouseMove in ICodeMining
Browse files Browse the repository at this point in the history
This change allows code mining implementors to react on mouse move
events and call setCursor on the text widget for example.
  • Loading branch information
tobias-melcher committed Jan 31, 2025
1 parent 55481d3 commit 1213c88
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,7 @@ public class CodeMiningLineContentAnnotation extends LineContentAnnotation imple
* @param viewer the viewer
*/
public CodeMiningLineContentAnnotation(Position position, ISourceViewer viewer) {
super(position, viewer);
fResolvedMinings= null;
fMinings= new ArrayList<>();
fBounds= new ArrayList<>();
afterPosition= false;
this(position, viewer, false);
}

/**
Expand All @@ -84,7 +80,23 @@ public CodeMiningLineContentAnnotation(Position position, ISourceViewer viewer)
* @param viewer the viewer
*/
public CodeMiningLineContentAnnotation(Position position, ISourceViewer viewer, boolean afterPosition) {
super(position, viewer);
this(position, viewer, afterPosition, null, null, null);
}

/**
* Code mining annotation constructor.
*
* @param position the position
* @param viewer the viewer
* @param onMouseHover the consumer to be called on mouse hover. If set, the implementor needs
* to take care of setting the cursor if wanted.
* @param onMouseOut the consumer to be called on mouse out. If set, the implementor needs to
* take care of resetting the cursor.
* @param onMouseMove the consumer to be called on mouse move
*/
public CodeMiningLineContentAnnotation(Position position, ISourceViewer viewer, boolean afterPosition, Consumer<MouseEvent> onMouseHover, Consumer<MouseEvent> onMouseOut,
Consumer<MouseEvent> onMouseMove) {
super(position, viewer, onMouseHover, onMouseOut, onMouseMove);
fResolvedMinings= null;
fMinings= new ArrayList<>();
fBounds= new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,22 @@ public class CodeMiningLineHeaderAnnotation extends LineHeaderAnnotation impleme
* @param viewer the viewer
*/
public CodeMiningLineHeaderAnnotation(Position position, ISourceViewer viewer) {
super(position, viewer);
this(position, viewer, null, null, null);
}

/**
* Code mining annotation constructor.
*
* @param position the position
* @param viewer the viewer
* @param onMouseHover the consumer to be called on mouse hover. If set, the implementor needs
* to take care of setting the cursor if wanted.
* @param onMouseOut the consumer to be called on mouse out. If set, the implementor needs to
* take care of resetting the cursor.
* @param onMouseMove the consumer to be called on mouse move
*/
public CodeMiningLineHeaderAnnotation(Position position, ISourceViewer viewer, Consumer<MouseEvent> onMouseHover, Consumer<MouseEvent> onMouseOut, Consumer<MouseEvent> onMouseMove) {
super(position, viewer, onMouseHover, onMouseOut, onMouseMove);
fResolvedMinings= null;
fMinings= new ArrayList<>();
fBounds= new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@
import java.util.Set;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.osgi.framework.Bundle;

import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Rectangle;

import org.eclipse.core.runtime.Assert;
Expand Down Expand Up @@ -262,7 +264,12 @@ private void renderCodeMinings(Map<Position, List<ICodeMining>> groups, ISourceV
if (first instanceof LineContentCodeMining m) {
afterPosition= m.isAfterPosition();
}
ann= inLineHeader ? new CodeMiningLineHeaderAnnotation(pos, viewer) : new CodeMiningLineContentAnnotation(pos, viewer, afterPosition);
Consumer<MouseEvent> mouseHover= first != null ? first.getMouseHover() : null;
Consumer<MouseEvent> mouseOut= first != null ? first.getMouseOut() : null;
Consumer<MouseEvent> mouseMove= first != null ? first.getMouseMove() : null;
ann= inLineHeader
? new CodeMiningLineHeaderAnnotation(pos, viewer, mouseHover, mouseOut, mouseMove)
: new CodeMiningLineContentAnnotation(pos, viewer, afterPosition, mouseHover, mouseOut, mouseMove);
} else if (ann instanceof ICodeMiningAnnotation && ((ICodeMiningAnnotation) ann).isInVisibleLines()) {
// annotation is in visible lines
annotationsToRedraw.add((ICodeMiningAnnotation) ann);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Color;
Expand Down Expand Up @@ -115,6 +116,37 @@ public interface ICodeMining {
*/
Consumer<MouseEvent> getAction();

/**
* Returns a consumer which is called when mouse is hovered over the code mining. If set, the
* implementor needs to take care of setting the cursor if wanted.
*/
default Consumer<MouseEvent> getMouseHover() {
return e -> {
if (e.widget instanceof StyledText st) {
st.setCursor(st.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
}
};
}

/**
* Returns a consumer which is called when mouse is moved out of code mining. If set, the
* implementor needs to take care of resetting the cursor.
*/
default Consumer<MouseEvent> getMouseOut() {
return e -> {
if (e.widget instanceof StyledText st) {
st.setCursor(null);
}
};
}

/**
* Returns a consumer which is called when mouse is moved inside the code mining.
*/
default Consumer<MouseEvent> getMouseMove() {
return null;
}

/**
* Dispose the mining. Typically shuts down or cancels all related asynchronous operations.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,39 @@ public abstract class AbstractInlinedAnnotation extends Annotation {

int fY;

private final Consumer<MouseEvent> onMouseHover;

private final Consumer<MouseEvent> onMouseOut;

private final Consumer<MouseEvent> onMouseMove;

/**
* Inlined annotation constructor.
*
* @param position the position where the annotation must be drawn.
* @param viewer the {@link ISourceViewer} where the annotation must be drawn.
* @param viewer the {@link ISourceViewer} where the annotation must be drawn.
*/
protected AbstractInlinedAnnotation(Position position, ISourceViewer viewer) {
this(position, viewer, null, null, null);
}

/**
* Inlined annotation constructor.
*
* @param position the position where the annotation must be drawn.
* @param viewer the {@link ISourceViewer} where the annotation must be drawn.
* @param onMouseHover the consumer to be called on mouse hover. If set, the implementor needs
* to take care of setting the cursor if wanted.
* @param onMouseOut the consumer to be called on mouse out. If set, the implementor needs to
* take care of resetting the cursor.
* @param onMouseMove the consumer to be called on mouse move
*/
protected AbstractInlinedAnnotation(Position position, ISourceViewer viewer, Consumer<MouseEvent> onMouseHover, Consumer<MouseEvent> onMouseOut, Consumer<MouseEvent> onMouseMove) {
super(TYPE, false, ""); //$NON-NLS-1$
this.position= position;
this.onMouseHover= onMouseHover;
this.onMouseOut= onMouseOut;
this.onMouseMove= onMouseMove;
}

/**
Expand Down Expand Up @@ -165,8 +189,23 @@ public void draw(GC gc, StyledText textWidget, int widgetOffset, int length, Col
* @param e the mouse event
*/
public void onMouseHover(MouseEvent e) {
StyledText styledText= (StyledText) e.widget;
styledText.setCursor(styledText.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
if (onMouseHover != null) {
onMouseHover.accept(e);
} else {
StyledText styledText= (StyledText) e.widget;
styledText.setCursor(styledText.getDisplay().getSystemCursor(SWT.CURSOR_HAND));
}
}

/**
* Called when mouse moved in the inlined annotation.
*
* @param e the mouse event
*/
public void onMouseMove(MouseEvent e) {
if (onMouseMove != null) {
onMouseMove.accept(e);
}
}

/**
Expand All @@ -175,8 +214,12 @@ public void onMouseHover(MouseEvent e) {
* @param e the mouse event
*/
public void onMouseOut(MouseEvent e) {
StyledText styledText= (StyledText) e.widget;
styledText.setCursor(null);
if (onMouseOut != null) {
onMouseOut.accept(e);
} else {
StyledText styledText= (StyledText) e.widget;
styledText.setCursor(null);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,17 @@ private static void draw(LineHeaderAnnotation annotation, GC gc, StyledText text
annotation.draw(gc, textWidget, offset, length, color, x, y);
} else if (textWidget.getLineVerticalIndent(line) > 0) {
// Here vertical indent is done, the redraw of the full line width is done to avoid annotation clipping
Rectangle bounds= textWidget.getTextBounds(offset, offset);
Rectangle client= textWidget.getClientArea();
textWidget.redraw(0, bounds.y, client.width, bounds.height, false);
int y, height;
if (offset < charCount) {
Rectangle bounds= textWidget.getTextBounds(offset, offset);
y= bounds.y;
height= bounds.height;
} else {
y= 0;
height= client.height;
}
textWidget.redraw(0, y, client.width, height, false);
} else {
if (offset >= charCount) {
if (charCount > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ public void mouseMove(MouseEvent e) {
update(e);
if (oldAnnotation != null) {
if (oldAnnotation.equals(fAnnotation)) {
// Same annotations which was hovered, do nothing.
fAnnotation.onMouseMove(e);
return;
} else {
oldAnnotation.onMouseOut(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
*/
package org.eclipse.jface.text.source.inlined;

import java.util.function.Consumer;

import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
Expand Down Expand Up @@ -48,7 +51,23 @@ public class LineContentAnnotation extends AbstractInlinedAnnotation {
* @param viewer the {@link ISourceViewer} where the annotation must be drawn.
*/
public LineContentAnnotation(Position position, ISourceViewer viewer) {
super(position, viewer);
this(position, viewer, null, null, null);
}

/**
* Line content annotation constructor.
*
* @param position the position where the annotation must be drawn.
* @param viewer the {@link ISourceViewer} where the annotation must be drawn.
* @param onMouseHover the consumer to be called on mouse hover. If set, the implementor needs
* to take care of setting the cursor if wanted.
* @param onMouseOut the consumer to be called on mouse out. If set, the implementor needs to
* take care of resetting the cursor.
* @param onMouseMove the consumer to be called on mouse move
* @since 3.27
*/
public LineContentAnnotation(Position position, ISourceViewer viewer, Consumer<MouseEvent> onMouseHover, Consumer<MouseEvent> onMouseOut, Consumer<MouseEvent> onMouseMove) {
super(position, viewer, onMouseHover, onMouseOut, onMouseMove);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
*/
package org.eclipse.jface.text.source.inlined;

import java.util.function.Consumer;

import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.MouseEvent;

import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.ISourceViewer;
Expand All @@ -34,7 +37,23 @@ public class LineHeaderAnnotation extends AbstractInlinedAnnotation {
* @param viewer the {@link ISourceViewer} where the annotation must be drawn.
*/
public LineHeaderAnnotation(Position position, ISourceViewer viewer) {
super(position, viewer);
this(position, viewer, null, null, null);
}

/**
* Line header annotation constructor.
*
* @param position the position where the annotation must be drawn.
* @param viewer the {@link ISourceViewer} where the annotation must be drawn.
* @param onMouseHover the consumer to be called on mouse hover. If set, the implementor needs
* to take care of setting the cursor if wanted.
* @param onMouseOut the consumer to be called on mouse out. If set, the implementor needs to
* take care of resetting the cursor.
* @param onMouseMove the consumer to be called on mouse move
* @since 3.27
*/
public LineHeaderAnnotation(Position position, ISourceViewer viewer, Consumer<MouseEvent> onMouseHover, Consumer<MouseEvent> onMouseOut, Consumer<MouseEvent> onMouseMove) {
super(position, viewer, onMouseHover, onMouseOut, onMouseMove);
oldLine= -1;
}

Expand Down

0 comments on commit 1213c88

Please sign in to comment.