Fix selection of scaled down text in text field

This commit is contained in:
drdev
2014-06-06 02:34:11 +00:00
parent 4aa70cb5c0
commit d51fe586ab

View File

@@ -33,7 +33,7 @@ public class FTextField extends FDisplayObject implements ITextField {
} }
private String text, ghostText, textBeforeKeyInput; private String text, ghostText, textBeforeKeyInput;
protected FSkinFont font; protected FSkinFont font, renderedFont;
private HAlignment alignment; private HAlignment alignment;
private int selStart, selLength; private int selStart, selLength;
private boolean isEditing; private boolean isEditing;
@@ -107,6 +107,7 @@ public class FTextField extends FDisplayObject implements ITextField {
} }
public void setFont(FSkinFont font0) { public void setFont(FSkinFont font0) {
font = font0; font = font0;
renderedFont = font0;
setHeight(getDefaultHeight(font)); setHeight(getDefaultHeight(font));
} }
@@ -126,14 +127,14 @@ public class FTextField extends FDisplayObject implements ITextField {
if (x < charLeft) { if (x < charLeft) {
return 0; return 0;
} }
if (x >= charLeft + font.getBounds(text).width) { if (x >= charLeft + renderedFont.getBounds(text).width) {
return text.length(); return text.length();
} }
//find closest character of press //find closest character of press
float charWidth; float charWidth;
for (int i = 0; i < text.length(); i++) { for (int i = 0; i < text.length(); i++) {
charWidth = font.getBounds(text.substring(i, i + 1)).width; charWidth = renderedFont.getBounds(text.substring(i, i + 1)).width;
if (x < charLeft + charWidth / 2) { if (x < charLeft + charWidth / 2) {
return i; return i;
} }
@@ -292,12 +293,13 @@ public class FTextField extends FDisplayObject implements ITextField {
g.fillRect(BACK_COLOR, 0, 0, w, h); g.fillRect(BACK_COLOR, 0, 0, w, h);
//determine actual rendered font so selection logic is accurate //determine actual rendered font so selection logic is accurate
FSkinFont fontBackup = font; renderedFont = font;
TextBounds textBounds = font.getMultiLineBounds(text); float availableTextWidth = w - PADDING - getRightPadding();
while (textBounds.width > w || textBounds.height > h) { TextBounds textBounds = renderedFont.getMultiLineBounds(text);
if (font.canShrink()) { //shrink font to fit if possible while (textBounds.width > availableTextWidth || textBounds.height > h) {
font = font.shrink(); if (renderedFont.canShrink()) { //shrink font to fit if possible
textBounds = font.getMultiLineBounds(text); renderedFont = renderedFont.shrink();
textBounds = renderedFont.getMultiLineBounds(text);
} }
else { else {
break; break;
@@ -308,7 +310,7 @@ public class FTextField extends FDisplayObject implements ITextField {
if (isEditing) { if (isEditing) {
float selLeft = PADDING; float selLeft = PADDING;
if (selStart > 0) { if (selStart > 0) {
selLeft += font.getBounds(text.substring(0, selStart)).width; selLeft += renderedFont.getBounds(text.substring(0, selStart)).width;
} }
float selTop = PADDING; float selTop = PADDING;
float selHeight = h - 2 * PADDING; float selHeight = h - 2 * PADDING;
@@ -317,7 +319,7 @@ public class FTextField extends FDisplayObject implements ITextField {
g.drawLine(BORDER_THICKNESS, FORE_COLOR, selLeft, selTop, selLeft, selTop + selHeight); g.drawLine(BORDER_THICKNESS, FORE_COLOR, selLeft, selTop, selLeft, selTop + selHeight);
} }
else if (selStart == 0 && selLength == text.length()) { else if (selStart == 0 && selLength == text.length()) {
float selWidth = font.getBounds(text.substring(selStart, selStart + selLength)).width; float selWidth = renderedFont.getBounds(text.substring(selStart, selStart + selLength)).width;
g.fillRect(SEL_COLOR, selLeft, selTop, selWidth, selHeight); g.fillRect(SEL_COLOR, selLeft, selTop, selWidth, selHeight);
drawText(g, w, h); //draw text in front of selection background drawText(g, w, h); //draw text in front of selection background
} }
@@ -327,20 +329,18 @@ public class FTextField extends FDisplayObject implements ITextField {
} }
g.drawRect(BORDER_THICKNESS, FORE_COLOR, BORDER_THICKNESS, BORDER_THICKNESS, w - 2 * BORDER_THICKNESS, h - 2 * BORDER_THICKNESS); //allow smooth border to fully display within bounds g.drawRect(BORDER_THICKNESS, FORE_COLOR, BORDER_THICKNESS, BORDER_THICKNESS, w - 2 * BORDER_THICKNESS, h - 2 * BORDER_THICKNESS); //allow smooth border to fully display within bounds
font = fontBackup; //restore font after finishing render
} }
private void drawText(Graphics g, float w, float h) { private void drawText(Graphics g, float w, float h) {
float diff = h - font.getCapHeight(); float diff = h - renderedFont.getCapHeight();
if (diff > 0 && Math.round(diff) % 2 == 1) { if (diff > 0 && Math.round(diff) % 2 == 1) {
h++; //if odd difference between height and font height, increment height so text favors displaying closer to bottom h++; //if odd difference between height and font height, increment height so text favors displaying closer to bottom
} }
if (!text.isEmpty()) { if (!text.isEmpty()) {
g.drawText(text, font, FORE_COLOR, PADDING, 0, w - PADDING - getRightPadding(), h, false, alignment, true); g.drawText(text, renderedFont, FORE_COLOR, PADDING, 0, w - PADDING - getRightPadding(), h, false, alignment, true);
} }
else if (!ghostText.isEmpty()) { else if (!ghostText.isEmpty()) {
g.drawText(ghostText, font, GHOST_TEXT_COLOR, PADDING, 0, w - PADDING - getRightPadding(), h, false, alignment, true); g.drawText(ghostText, renderedFont, GHOST_TEXT_COLOR, PADDING, 0, w - PADDING - getRightPadding(), h, false, alignment, true);
} }
} }