When adding a single letter at a time to a text field, how do I avoid the word wrap occuring mid-word? - string

Given the following example SWF:
Sample
Notice how with the words "enthusiast" at the end of the first line and "write" at the end of the second line, that they start to type out on the first line but after a few letters they are bumped.
I understand this is the correct behavior, but is there a way for "enthusiast" to begin being typed on the second line, and "write" on the third line instead of being bumped during the typing?
Currently I am thinking of doing a search ahead mechanism, so it finds the next word in whole, then makes that the active word to print, temporarily print it, see if it increases the numlines, and if it does insert a line break and continue writing. But it seems fiddly.
Code below:
import flash.text.TextField;
import flash.events.Event;
var tt:TextField = new TextField();
tt.wordWrap = true;
tt.width = 200;
tt.height = 50;
tt.border = true;
var s = "Stack Overflow is for professional and enthusiast programmers, people who write code because they love it. We feel the best Stack Overflow questions have a bit of source code in them, but if your question generally covers";
addChild(tt);
var currentLetter:int = 0;
addEventListener(Event.ENTER_FRAME, onEnter, false, 0, true);
function onEnter(e:Event):void
{
if(currentLetter < s.length)
{
tt.appendText(s.charAt(currentLetter));
}
currentLetter++;
}

adjusted your code a bit and posted the result on wonderfl: http://wonderfl.net/c/rZkm
as #mouseas suggested i put the next word into an additional textfield measure the width and compare this to the remaining space in the current line ... if the next word doesn't fit I add a line-break and continue.
here's the code:
package {
import flash.geom.Rectangle;
import flash.text.TextFieldAutoSize;
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.Event;
public class FlashTest extends Sprite {
private var currentLetter:int = 0;
private var tt:TextField;
private var debug:TextField;
private var pre:TextField;
private var s:String;
public function FlashTest()
{
// write as3 code here..
tt = new TextField();
tt.wordWrap = true;
tt.width = 200;
tt.height = 150;
tt.border = true;
s = "Stack Overflow is for professional and enthusiast programmers, people who write code because they love it. We feel the best Stack Overflow questions have a bit of source code in them, but if your question generally covers";
addChild(tt);
// predraw word
pre = new TextField();
pre.y = 150;
pre.width = 200;
pre.height = 50;
pre.autoSize = TextFieldAutoSize.LEFT;
pre.border = true;
addChild(pre);
// debug txt
debug = new TextField();
debug.x = 250;
debug.wordWrap = true;
debug.width = 200;
debug.height = 500;
debug.border = true;
addChild(debug);
addEventListener(Event.ENTER_FRAME, onEnter, false, 0, true);
}
private function onEnter(e:Event):void
{
//debug.appendText("char: " + rect.x + " " + rect.width + "\n");
var c:String = "";
if (currentLetter < s.length)
{
c = s.charAt(currentLetter);
tt.appendText(c);
}
else
{
debug.appendText("DONE! \n");
removeEventListener(Event.ENTER_FRAME, onEnter);
}
if (c == " ")
{
var rect:Rectangle = tt.getCharBoundaries(currentLetter-1);
if (rect != null)
{
//debug.appendText("char: " + rect + "\n");
var cPos:int = rect.x + rect.width;
var r:int = tt.width - 4 - cPos; // 4px for gutter on left+right side of textfield
var start:int = s.lastIndexOf(" ", currentLetter);
var end:int = s.indexOf(" ", currentLetter+1);
if (start < 0) start = 0;
pre.text = s.substr(start, end-start);
debug.appendText("rest: " + r + " " + pre.textWidth + " > " + pre.text + "\n");
if (r - pre.textWidth <= 0)
{
tt.appendText("\n");
debug.appendText("\n");
}
//debug.appendText("w:" + tt.textWidth + " " + start + "->"+ end + " /" + pre.text + "/ " + pre.textWidth + "\n");
}
}
++currentLetter;
}
}
}
works great - only the "a" in the 4th line makes trouble - maybe you need to finetune the calculations a bit...

Related

Polymer add style dynamically

In a polymer control,'my-grid', I'm trying to add style via the below code:
var styleElement = document.createElement('style', 'custom-style');
styleElement.innerHTML = cssText;
Polymer.StyleDefaults.addStyle(styleElement);
Here, the cssText can be string like
.oc-col-id-0{
flex-basis: var(--oc-col-id-0-flex-basis);
-webkit-flex-basis: var(--oc-col-id-0-flex-basis);
}
.oc-col-id-1{
flex-basis: var(--oc-col-id-1-flex-basis);
-webkit-flex-basis: var(--oc-col-id-1-flex-basis);
}
Without this custom variables, I can append the styleElement by
this.$.gridContainer.appendChild(styleElement);
But however, since there are custom variables, I'm not sure how to fix this issue.
After the element is attached, I can't change the --oc-col-id-0-flex-basis value via
this.customStyle['--oc-col-id-0-flex-basis'] = maxWidth + "px";
this.updateStyles();
It looks that the style variables are not applied to the element.
I'm not sure if there is any way to dynamically add/modify the style of the element. I'm not sure if I'm on the right track.
This is what I do in the end to inject the style class dynamically. It solved my problem so far.
var style = this._styles[0];
var text = style.textContent;
var cssText = "";
for (var id of ids)
{
var classStyle = ".col-id-" + id;
var variableProperty = "--col-id-" + id + "-flex-basis";
if (text.indexOf(classStyle) == -1)
{
cssText += classStyle + "{ flex-basis: var(" + variableProperty + ", auto); -webkit-flex-basis: var(" + variableProperty + ", auto);} ";
}
if (this._ownStylePropertyNames.indexOf(variableProperty) == -1)
{
this._ownStylePropertyNames.push(variableProperty);
}
}
if (cssText.length > 0)
{
style.textContent += " " + cssText;
style.__cssRules = null; //trick for rulesForStyle method in Polymer.html
}

Memory Leak in Actionscript 3 Substring Handling

I'm running the very begninning of a program I'm going to use for a text-based adventure, and it seems to be working very well, but I've noticed a severe slowdown in my program. I've been using trace(System.totalMemory); to discover the problem and there is a very linear increase in memory, about 500b-1kb per frame.
{
addEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler);
function fl_EnterFrameHandler(event: Event): void {
//this block sets up the blinking cursor
var_x = var_x + 1;
if (var_x > 18) {
var_x = 0;
if (str_cursor == " ") {
str_cursor = "█";
} else {
str_cursor = " ";
}
}
//Checking to see if a picture needs to be drawn or not
if (picture != "") {
fulltext = (picture + "\n\n" + responce + "\n\n" + ">>>" + user_input + str_cursor);
} else {
fulltext = (responce + "\n\n" + ">>>" + user_input + str_cursor);
}
//Setting the interval of the draw string
uInt = setInterval(writeIt, 1);
function writeIt() {
if (!printed) {
//Finding the substring of the draw string and assignign to the text field
fl_TF.text = fulltext.substring(0, count);
count += count_speed;
if (count > fulltext.length) {
clearInterval(uInt);
//Stoping the print loop
printed = true;
count = 0;
}
} else {
user_input = inputField.text;
fl_TextToDisplay = fulltext;
fl_TF.text = fl_TextToDisplay;
}
}
if (printed) {
user_input = inputField.text;
fl_TextToDisplay = fulltext;
fl_TF.text = fl_TextToDisplay;
clearInterval(uInt);
}
}
I can't seem to find the leak, as I've traced all my variables involved to the console at different points.
You can find a screenshot of the program here: http://i.imgur.com/dSWLeD5.gif
You start the interval every frame. That means about 25 times a
second. AND your delay of the interval is 1ms. Thats not possible to handle.
You define all functions every frame.
Which Scope has uInt?
Generally:
Don't use closures in enter-frame-handlers! There's no need. Define
them outer of the handler.
Don't use setInterval in AS3. There ist
the Timer-Class. What do you want to do with this curios code?

AS3 (string).split quotation mark only

I want to split up a document by quotation it's marks. I see (here) that they're able to fake this answer by adding a '\' at the beginning of the quotation mark, however in my document there are hundreds of these strings I'm trying to cut string out of, so changing that manually would be a real pain and time taker.
Here's an example of the string I'm trying to cut from:
D
And here's an example of my current code:
private function onShopTextLoaded(e:Event):void
{
shopArrayOfWebsites = e.target.data.split(/\n/);
for (var i:String in shopArrayOfWebsites)
{
trace("shopArrayOriginal: " + shopArrayOfWebsites[i]);
var arrayString:String = shopArrayOfWebsites[i].split('"' /* << that won't work */ );
trace(arrayString[1]);
//shopArrayOfWebsites[i] = arrayString[1];
}
}
private function postInShopView():void
{
var iLevel:Number = 1;
var iSection:Number = 1;
var iShop:Number = 0;
for (var i:String in shopArrayOfWebsites)
{
iShop++;
if(iShop >= 5)
{
iSection++;
iShop = 0;
}
if(iSection >= 5)
{
iLevel++;
iSection = 1;
}
var shopStringEquiv:String = "L" + iLevel.toString() + "S" + iSection.toString() + "Shop" + iShop.toString();
if(global.shopTarget == shopStringEquiv)
{
var result:uint = ExternalInterface.call("showShopFrame", shopArrayOfWebsites[i]);
}
//trace(shopStringEquiv);
//trace(shopArrayOfWebsites[i]);
}
}
I get an error of:
ReferenceError: Error #1069: Property 1 not found on String and there is no default value.
So from here I'm not quite sure how I'm able to split up this document. Any ideas? Thanks!

Reversing a path in Raphael.js

I have two curved paths, both roughly going from left to right, one above the . I need to join them up with straight lines into a closed path.
To do this, I am assuming I need to build the path string of the big closed path. But in order to build the path, I need to reverse the second curve.
How can I reverse a path in Raphael.js? Or is there a better way to do what I want to do?
Thanks.
Can you try using this example?
It creates 2 independent paths running left to right. Then it merges these into a closed path.
Try in JSFiddle.
EDITED:
var paper = Raphael(0, 0, 800, 600);
// Define 2 paths running left to right
var path1 = paper.path("M10 10L200 120 300 80 400 100 450 150")
.attr({stroke: "#00FF00"}),
path2 = paper.path("M10 200L200 220 300 280 400 300 450 250")
.attr({stroke: "#00FF00"}),
closedPath = joinPaths(path1, path2)
.attr({
fill: "#FF0000",
stroke: "#0000FF"
});
// This function is a poc and assumes that
// the paths contain a "M" at the begining
// and that that "M" is replacable by "L" (absolute Line to)
function joinPaths() {
var i,
len = arguments.length,
pathArr =[],
finalPathArr =[];
for (i = 0; i < len; i++) {
pathArr[i] = arguments[i].attr("path");
if (i) {
pathArr[i][0][0] = "L";
pathArr[i].reverse();
if (i === len-1) {
pathArr[i].push("Z");
}
}
finalPathArr = finalPathArr.concat(pathArr[i]);
}
return paper.path(finalPathArr);
}
I needed this functionality recently to fill the area between to curves on a graph. I used the following implementation.
function reversePath(pathString) {
var pathPieces = pathString.match(/[MLHVCSQTA][-0-9.,]*/gi);
var reversed = '';
var skip = true;
var previousPathType;
for (var i = pathPieces.length - 1; i >= 0; i--) {
var pathType = pathPieces[i].substr(0, 1);
var pathValues = pathPieces[i].substr(1);
switch (pathType) {
case 'M':
case 'L':
reversed += (skip ? '' : pathType) + pathValues;
skip = false;
break;
case 'C':
var curvePieces = pathValues.match(/^([-0-9.]*,[-0-9.]*),([-0-9.]*,[-0-9.]*),([-0-9.]*,[-0-9.]*)$/);
reversed += curvePieces[3] + pathType + curvePieces[2] + ',' + curvePieces[1] + ',';
skip = true;
break;
default:
alert('Not implemented: ' + pathType);
break;
}
}
return reversed;
}
And I would call it like so:
var combinedPath = path1 + 'L' + reversePath(path2) + 'Z';

Sharepoint drop down list doesn't display properly for more than 20 items with Internet Explorer

I had this problem on my three sharepoint sites and i manage to resolve this problem by modifying CSS code (cf http://social.msdn.microsoft.com/Forums/en-US/sharepoint2010general/thread/64796605-bcbb-4a87-9d8d-9d609579577f/) on two of them.
I don't know why this doesn't work on my third one which has same updates, same CSS and same html code...
I tried several solutions such as adding indesign="true"(this can't be use because the lists got more than 75 columns). cf
http://www.codeproject.com/Articles/194254/Advanced-fixing-SharePoint-2010-large-lookup-dropd
The only solutions i found required javascript but i don't really want to use it...
If someone have another solution to propose, i would really appreciate.
EDIT:
Thanks to moontear i found something quite great.
I replace the beginning of the script by :
$(document).ready(function () {
$('.ms-lookuptypeintextbox').each(function(){
OverrideDropDownList($(this).attr('title'));
});
// Main Function
function OverrideDropDownList(columnName) {
...
By this way, i just have to include the script and don't care about what columns got problems...
This script seems to be quite great to solve this problem...
Thank you moontear for your comment
The original script come from : http://sharepointegg.blogspot.de/2010/10/fixing-sharepoint-2010-lookup-drop-down.html
$(document).ready(function () {
$('.ms-lookuptypeintextbox').each(function(){
OverrideDropDownList($(this).attr('title'));
});
// Main Function
function OverrideDropDownList(columnName) {
// Construct a drop down list object
var lookupDDL = new DropDownList(columnName);
// Do this only in complex mode...
if (lookupDDL.Type == "C") {
// Hide the text box and drop down arrow
lookupDDL.Obj.css('display', 'none');
lookupDDL.Obj.next("img").css('display', 'none');
// Construct the simple drop down field with change trigger
var tempDDLName = "tempDDLName_" + columnName;
if (lookupDDL.Obj.parent().find("select[ID='" + tempDDLName + "']").length == 0) {
lookupDDL.Obj.parent().append("<select name='" + tempDDLName + "' id='" + tempDDLName + "' title='" + tempDDLName + "'></select>");
lookupDDL.Obj.parent().find("select[ID='" + tempDDLName + "']").bind("change", function () {
updateOriginalField(columnName, tempDDLName);
});
}
// Get all the options
var splittedChoices = lookupDDL.Obj.attr('choices').split("|");
// get selected value
var hiddenVal = $('input[name=' + lookupDDL.Obj.attr("optHid") + ']').val();
if (hiddenVal == "0") {
hiddenVal = lookupDDL.Obj.attr("value")
}
// Replacing the drop down object with the simple drop down list
lookupDDL = new DropDownList(tempDDLName);
// Populate the drop down list
for (var i = 0; i < splittedChoices.length; i++) {
var optionVal = splittedChoices[i];
i++;
var optionId = splittedChoices[i];
var selected = (optionId == hiddenVal) ? " selected='selected'" : "";
lookupDDL.Obj.append("<option" + selected + " value='" + optionId + "'>" + optionVal + "</option>");
}
}
}
// method to update the original and hidden field.
function updateOriginalField(child, temp) {
var childSelect = new DropDownList(child);
var tempSelect = new DropDownList(temp);
// Set the text box
childSelect.Obj.attr("value", tempSelect.Obj.find("option:selected").val());
// Get Hidden ID
var hiddenId = childSelect.Obj.attr("optHid");
// Update the hidden variable
$('input[name=' + hiddenId + ']').val(tempSelect.Obj.find("option:selected").val());
}
// just to construct a drop down box object. Idea token from SPServces
function DropDownList(colName) {
// Simple - when they are less than 20 items
if ((this.Obj = $("select[Title='" + colName + "']")).html() != null) {
this.Type = "S";
// Compound - when they are more than 20 items
} else if ((this.Obj = $("input[Title='" + colName + "']")).html() != null) {
this.Type = "C";
// Multi-select: This will find the multi-select column control on English and most other languages sites where the Title looks like 'Column Name possible values'
} else if ((this.Obj = $("select[ID$='SelectCandidate'][Title^='" + colName + " ']")).html() != null) {
this.Type = "M";
// Multi-select: This will find the multi-select column control on a Russian site (and perhaps others) where the Title looks like '????????? ????????: Column Name'
} else if ((this.Obj = $("select[ID$='SelectCandidate'][Title$=': " + colName + "']")).html() != null) {
this.Type = "M";
} else
this.Type = null;
} // End of function dropdownCtl
});
The code in the solution above is great, but it has two major shortcomings:
1) Doesn't play nicely with Required Field Validators
2) Doesn't play nicely with Cascading Dropdowns via SPServices.
I've fixed these two problems at work, and put my solution here:
http://craigvsthemachine.blogspot.com/2013/04/fixing-complex-dropdown-bug-in.html

Resources