package com.yoursway.swt.scrollbar;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.swt.custom.PaintObjectEvent;
import org.eclipse.swt.custom.PaintObjectListener;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.GlyphMetrics;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
public class StyledTextEmbedder {
private static int MARGIN = 5;
private final StyledText styledText;
private Map<Integer, Control> offsets;
public StyledTextEmbedder(StyledText styledText) {
if (styledText == null)
throw new IllegalArgumentException("styledText is null");
this.styledText = styledText;
styledText.addPaintObjectListener(new PaintObjectListener() {
public void paintObject(PaintObjectEvent event) {
StyleRange style = event.style;
int start = style.start;
// System.out.println(offsets);
Control control = offsets.get(start);
if (control != null) {
Point pt = control.getSize();
int x = event.x + MARGIN;
int y = event.y + event.ascent - 2 * pt.y / 3;
// System.out.println(x + ", " + y + " " + control);
control.setLocation(x, y);
}
// System.out.println();
}
});
}
void setStyleRange(Control control, int offset) {
StyleRange style = new StyleRange();
style.start = offset;
style.length = 1;
control.pack();
Rectangle rect = control.getBounds();
int ascent = 2 * rect.height / 3;
int descent = rect.height - ascent;
style.metrics = new GlyphMetrics(ascent + MARGIN, descent + MARGIN, rect.width + 2 * MARGIN);
styledText.setStyleRange(style);
}
public void setTextWithControls(String text, Control[] controls) {
this.offsets = new HashMap<Integer, Control>();
styledText.setText(text);
int lastOffset = 0;
for (int i = 0; i < controls.length; i++) {
int offset = text.indexOf("\uFFFC", lastOffset);
if (offset == -1)
break; // just skip extra controls
this.offsets.put(offset, controls[i]);
setStyleRange(controls[i], offset);
lastOffset = offset + 1;
}
}
}