package com.project.website.canvas.client.canvastools.textedit;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.project.shared.data.Point2D;
public class TextEditUtils {
static final HTMLPanel testWidget = new HTMLPanel("");
static boolean testWidgetInit = false;
static void init() {
Style targetStyle = testWidget.getElement().getStyle();
targetStyle.setProperty("width", "auto");
targetStyle.setProperty("height", "auto");
targetStyle.setTop(-9999, Unit.PX);
targetStyle.setLeft(-9999, Unit.PX);
RootPanel.getBodyElement().appendChild(testWidget.getElement());
testWidgetInit = true;
}
static {
init();
}
protected static Point2D autoSizeWidget(Widget widget, String html, boolean usePreWhiteSpace) {
if (false == testWidgetInit) {
init();
}
Style targetStyle = testWidget.getElement().getStyle();
targetStyle.setDisplay(Display.INLINE_BLOCK);
// This code based on:
// http://stackoverflow.com/questions/1288297/jquery-auto-size-text-input-not-textarea/1288475#1288475
int comfortZone = 40;
int minWidth = 0;
Style widgetStyle = widget.getElement().getStyle();
copyTextSizingProps(targetStyle, widgetStyle);
//targetStyle.setFontSize(16.0, Unit.PX);
if (usePreWhiteSpace) {
targetStyle.setProperty("whiteSpace", "pre");
}
// // append a char after every newline. fixes some PRE formatting bugs
// // (esp. last empty line)
// html.replace("\n", "\nM");
// // Also prepend a character
// // (if the text begins with whitespace the browser may strip it in the
// // test widget)
// html = html + "<br>";
testWidget.getElement().setInnerHTML(html);
int testerWidth = testWidget.getOffsetWidth();
int newWidth = (testerWidth + comfortZone) >= minWidth ? testerWidth + comfortZone : minWidth;
int currentWidth = widget.getOffsetWidth();
boolean isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
|| (newWidth > minWidth);
int newHeight = testWidget.getOffsetHeight(); // always add a spare
widget.setHeight(Integer.toString(newHeight) + "px");
int width;
if (isValidWidthChange) {
width = newWidth;
} else {
width = currentWidth;
}
widget.setWidth(Integer.toString(width) + "px");
testWidget.getElement().setInnerHTML(""); // for security reasons don't
// leave hiding data...
testWidget.getElement().getStyle().setDisplay(Display.NONE);
return new Point2D(width, newHeight);
}
private static void copyTextSizingProps(Style targetStyle, Style widgetStyle) {
String[] copyProps = new String[] { "fontFamily", "fontSize", "fontWeight", "fontStyle",
"textTransform", "textDecoration", "letterSpacing", "wordSpacing", "lineHeight", "textAlign",
"verticalAlign", "direction", "padding", "border", "margin", "whiteSpace" };
for (String propName : copyProps) {
targetStyle.setProperty(propName, widgetStyle.getProperty(propName));
}
}
/**
* Heuristic method to estimate the character position in a text-based
* widget assuming that the setText method also causes the widget to resize
* itself to fit the text.
*/
protected static <T extends Widget & HasText> int estimateCharPos(T widget, int relativeX) {
String text = widget.getText();
widget.setText("");
int i;
for (i = 0; i < text.length(); i++) {
widget.setText(widget.getText() + text.charAt(i));
if (relativeX <= widget.getOffsetWidth()) {
break;
}
}
return i;
}
}