Viewing Issue Advanced Details

ID 0003849 Category [DMDirc] *Unsorted Severity minor
Reproducibility always Date Submitted 2010-03-06 21:24 Last Update 2010-03-06 22:55
Reporter MD87 Assigned To Greboid View Status public
Priority normal Status resolved Resolution fixed
Platform Fixed in Version Target Version 0.6.4
Product Version Product Build
Summary 0003849: Textpane mouse events are ignored above first line
Description
Textpane mouse events are ignored above first line
Needs unit test no
Upstream Bug URL

Relationships

Notes

A patchset (1) related to this change has been added to gerrit by Greboid

Fixes issue 3849

Textpane now investigates highlight events that dont touch a line, if the event
is above the first line the first line is selected, if the event if below the
last line the last line is selected.

Change-Id: Id99f11bee2215e361b4da5726f88c56d5ba95cc4
authorGreboid <greg@dmdirc.com>2010-03-06 22:51:37 (GMT)
committer Chris Smith <chris@dmdirc.com>2010-03-06 22:54:54 (GMT)
commit9a8fd6a92d272da02972e8bd0bc2cd63c9434b22 (patch) (side-by-side diff)
Textpane now investigates highlight events that dont touch a line, if the event is above the first line the first line is selected, if the event if below the last line the last line is selected. Change-Id: Id99f11bee2215e361b4da5726f88c56d5ba95cc4 Reviewed-on: http://gerrit.dmdirc.com/967 Automatic-Compile: DMDirc Local Commits <dmdirc@googlemail.com> Reviewed-by: Chris Smith <chris@dmdirc.com>
-rw-r--r--src/com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas.java162
1 files changed, 125 insertions, 37 deletions
Click to Expand/Collapse
diff src/com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas.java
@@ -20,7 +20,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-
package com.dmdirc.addons.ui_swing.textpane;
import com.dmdirc.addons.ui_swing.BackgroundOption;
@@ -95,9 +94,9 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
/** Background image. */
private Image backgroundImage;
/** Config Manager. */
- private ConfigManager manager;
+ private ConfigManager manager;
/** Config domain. */
- private String domain;
+ private String domain;
/** Background image option. */
private BackgroundOption backgroundOption;
@@ -177,8 +176,8 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
}
});
try {
- backgroundOption = BackgroundOption.valueOf(manager.getOption(domain,
- "textpanebackgroundoption"));
+ backgroundOption = BackgroundOption.valueOf(manager.getOption(domain,
+ "textpanebackgroundoption"));
} catch (IllegalArgumentException ex) {
backgroundOption = BackgroundOption.CENTER;
}
@@ -270,10 +269,11 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
firstVisibleLine = line;
textLayouts.put(layout, new LineInfo(line, numberOfWraps));
positions.put(new Rectangle(0,
- (int) (drawPosY - layout.getAscent() + layout.getDescent()),
+ (int) (drawPosY - layout.getAscent() + layout.
+ getDescent()),
(int) formatWidth + DOUBLE_SIDE_PADDING,
- (int) (layout.getAscent() + layout.getDescent())
- ), layout);
+ (int) (layout.getAscent() + layout.getDescent())),
+ layout);
}
numberOfWraps++;
@@ -340,8 +340,8 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
selectionStartChar = selection.getEndPos();
selectionEndLine = selection.getStartLine();
selectionEndChar = selection.getStartPos();
- } else if (selection.getStartLine() == selection.getEndLine() &&
- selection.getStartPos() > selection.getEndPos()) {
+ } else if (selection.getStartLine() == selection.getEndLine() && selection.
+ getStartPos() > selection.getEndPos()) {
// Just swap the chars
selectionStartLine = selection.getStartLine();
selectionStartChar = selection.getEndPos();
@@ -368,15 +368,16 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
}
// ... And the last
- if (selectionEndLine > line || selectionEndChar > chars + layout.getCharacterCount()) {
+ if (selectionEndLine > line || selectionEndChar > chars + layout.
+ getCharacterCount()) {
lastChar = chars + layout.getCharacterCount();
} else {
lastChar = selectionEndChar;
}
// If the selection includes the chars we're showing
- if (lastChar > chars && firstChar < chars +
- layout.getCharacterCount()) {
+ if (lastChar > chars && firstChar < chars
+ + layout.getCharacterCount()) {
String text = document.getLine(line).getText();
if (firstChar >= 0 && text.length() > lastChar) {
text = text.substring(firstChar, lastChar);
@@ -400,10 +401,9 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
textPane.getForeground());
final TextLayout newLayout = new TextLayout(as.getIterator(),
g.getFontRenderContext());
- final Shape shape = layout.getLogicalHighlightShape(firstChar -
- chars,
- lastChar -
- chars);
+ final Shape shape = layout.getLogicalHighlightShape(firstChar
+ - chars,
+ lastChar - chars);
final int trans = (int) (newLayout.getDescent() + drawPosY);
if (firstChar != 0) {
@@ -688,12 +688,12 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
private void checkForLink() {
final LineInfo lineInfo = getClickPosition(getMousePosition(), false);
- if (lineInfo.getLine() != -1 && document.getLine(lineInfo.getLine()) !=
- null) {
+ if (lineInfo.getLine() != -1 && document.getLine(lineInfo.getLine())
+ != null) {
final AttributedCharacterIterator iterator = document.getStyledLine(
lineInfo.getLine());
- if (lineInfo.getIndex() < iterator.getBeginIndex() ||
- lineInfo.getIndex() > iterator.getEndIndex()) {
+ if (lineInfo.getIndex() < iterator.getBeginIndex() || lineInfo.
+ getIndex() > iterator.getEndIndex()) {
return;
}
iterator.setIndex(lineInfo.getIndex());
@@ -738,21 +738,29 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
point.getY());
} else if (mousePos.getX() > (bounds.getX() + bounds.
getWidth())) {
- point.setLocation(bounds.getX() + bounds.getWidth() -
- SINGLE_SIDE_PADDING,
+ point.setLocation(bounds.getX() + bounds.getWidth()
+ - SINGLE_SIDE_PADDING,
point.getY());
}
if (mousePos.getY() < bounds.getY()) {
- point.setLocation(point.getX(), bounds.getY() +
- DOUBLE_SIDE_PADDING);
- } else if (mousePos.getY() >
- (bounds.getY() + bounds.getHeight())) {
- point.setLocation(bounds.getX() + bounds.getWidth() -
- SINGLE_SIDE_PADDING, bounds.getY() +
- bounds.getHeight() - DOUBLE_SIDE_PADDING - 1);
+ point.setLocation(point.getX(), bounds.getY()
+ + DOUBLE_SIDE_PADDING);
+ } else if (mousePos.getY() > (bounds.getY() + bounds.
+ getHeight())) {
+ point.setLocation(bounds.getX() + bounds.getWidth()
+ - SINGLE_SIDE_PADDING, bounds.getY() + bounds.
+ getHeight() - DOUBLE_SIDE_PADDING - 1);
+ }
+ }
+ LineInfo info = getClickPosition(point, true);
+ if (info.getLine() == -1 && info.getPart() == -1 && contains(point)) {
+ if (getFirstLineRectangle().getY() >= point.getY()) {
+ info = getFirstLineInfo();
+ } else if (getLastLineRectangle().getY() <= point.getY()) {
+ info = getLastLineInfo();
}
}
- final LineInfo info = getClickPosition(point, true);
+
if (info.getLine() != -1 && info.getPart() != -1) {
if (type == MouseEventType.CLICK) {
selection.setStartLine(info.getLine());
@@ -767,6 +775,86 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
}
/**
+ * Returns the visible rectangle of the first line.
+ *
+ * @return First line's rectangle
+ */
+ private Rectangle getFirstLineRectangle() {
+ TextLayout firstLineLayout = null;
+ for (Map.Entry<TextLayout, LineInfo> entry : textLayouts.entrySet()) {
+ if (entry.getValue().getLine() == firstVisibleLine) {
+ firstLineLayout = entry.getKey();
+ }
+ }
+ if (firstLineLayout == null) {
+ return null;
+ }
+ for (Map.Entry<Rectangle, TextLayout> entry : positions.entrySet()) {
+ if (entry.getValue() == firstLineLayout) {
+ return entry.getKey();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the last line's visible rectangle.
+ *
+ * @return Last line's rectangle
+ */
+ private Rectangle getLastLineRectangle() {
+ TextLayout lastLineLayout = null;
+ for (Map.Entry<TextLayout, LineInfo> entry : textLayouts.entrySet()) {
+ if (entry.getValue().getLine() == lastVisibleLine) {
+ lastLineLayout = entry.getKey();
+ }
+ }
+ if (lastLineLayout == null) {
+ return null;
+ }
+ for (Map.Entry<Rectangle, TextLayout> entry : positions.entrySet()) {
+ if (entry.getValue() == lastLineLayout) {
+ return entry.getKey();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the LineInfo for the first visible line.
+ *
+ * @return First line's line info
+ */
+ private LineInfo getFirstLineInfo() {
+ int firstLineParts = Integer.MAX_VALUE;
+ for (Map.Entry<TextLayout, LineInfo> entry : textLayouts.entrySet()) {
+ if (entry.getValue().getLine() == firstVisibleLine) {
+ if (entry.getValue().getPart() < firstLineParts) {
+ firstLineParts = entry.getValue().getPart();
+ }
+ }
+ }
+ return new LineInfo(firstVisibleLine, firstLineParts);
+ }
+
+ /**
+ * Returns the LineInfo for the last visible line.
+ *
+ * @return Last line's line info
+ */
+ private LineInfo getLastLineInfo() {
+ int lastLineParts = -1;
+ for (Map.Entry<TextLayout, LineInfo> entry : textLayouts.entrySet()) {
+ if (entry.getValue().getLine() == lastVisibleLine) {
+ if (entry.getValue().getPart() > lastLineParts) {
+ lastLineParts = entry.getValue().getPart();
+ }
+ }
+ }
+ return new LineInfo(lastVisibleLine + 1, lastLineParts);
+ }
+
+ /**
*
* Returns the line information from a mouse click inside the textpane.
*
@@ -813,10 +901,10 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
if (textLayouts.get(entry.getValue()).getLine() == lineNumber) {
if (textLayouts.get(entry.getValue()).getPart() < linePart) {
pos += entry.getValue().getCharacterCount();
- } else if (textLayouts.get(entry.getValue()).getPart() ==
- linePart) {
- final TextHitInfo hit = entry.getValue().hitTestChar(x -
- DOUBLE_SIDE_PADDING, y);
+ } else if (textLayouts.get(entry.getValue()).getPart()
+ == linePart) {
+ final TextHitInfo hit = entry.getValue().hitTestChar(x
+ - DOUBLE_SIDE_PADDING, y);
if (selection) {
pos += hit.getInsertionIndex();
} else {
@@ -840,8 +928,8 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
return new LinePosition(selection.getEndLine(),
selection.getEndPos(), selection.getStartLine(),
selection.getStartPos());
- } else if (selection.getStartLine() == selection.getEndLine() &&
- selection.getStartPos() > selection.getEndPos()) {
+ } else if (selection.getStartLine() == selection.getEndLine() && selection.
+ getStartPos() > selection.getEndPos()) {
// Just swap the chars
return new LinePosition(selection.getStartLine(), selection.
getEndPos(), selection.getEndLine(),

Issue History

Date Modified Username Field Change
2010-03-06 21:24 MD87 New Issue
2010-03-06 21:24 MD87 Status new => assigned
2010-03-06 21:24 MD87 Assigned To => Greboid
2010-03-06 22:52 Version Control Checkin
2010-03-06 22:52 Version Control Note Added: 0010122
2010-03-06 22:52 Version Control Status assigned => fix pending
2010-03-06 22:55 Greboid Checkin
2010-03-06 22:55 Greboid Note Added: 0010125
2010-03-06 22:55 Greboid Status fix pending => resolved
2010-03-06 22:55 Greboid Resolution open => fixed