/** * The SmileArea is a replacement for the TextArea component in AS3. * It is useful to place smileys between text blocks whereas * the TextArea by Adobe creates unlovely breaks. * * Please contribute any changes and extensions back to me. * Feel free to use the SmileArea for your non-commercial projects. * For other purpose of use please drop me an email. * * @author Valentin Manthei (www.valentin-manthei.de - contact/at/valentin-manthei.de) */ package SmileArea { import fl.events.ScrollEvent; import flash.display.Sprite; import flash.display.MovieClip; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import fl.controls.ScrollBar; import fl.controls.UIScrollBar; import fl.controls.ScrollBarDirection; import flash.text.TextField; import flash.text.TextLineMetrics; import flash.text.TextFormat; import flash.net.URLRequest; import flash.system.System; import flash.ui.ContextMenu; import flash.ui.ContextMenuItem; import flash.events.Event; import flash.events.ContextMenuEvent; import flash.events.MouseEvent; import fl.events.ScrollEvent; import flash.geom.Rectangle; import SmileArea.SmileRow; public class SmileArea extends Sprite { private var scrollMask:Sprite; private var scrollClip:MovieClip; private var scrollBar:UIScrollBar; private var textFields:Array; private var smileys:Array; private var librarySmileys:Array; private var maskWidth:int; private var bg:Sprite; private var size:int; private var lineHeight:int; private var blankWidth:int; private var textFormat:TextFormat; private var textFormatBlanks:TextFormat; private var contextMenue:ContextMenu; private var xOffset:uint = 3; private var MouseWheelDelta:uint = 50; public var completeWidth:int; public var completeHeight:int; public var maxRows:int = 60; public function SmileArea(sWidth:int, sHeight:int, size:int, maxRows:int = 50) { scrollBar = new UIScrollBar(); completeWidth = sWidth; completeHeight = sHeight; maskWidth = completeWidth - scrollBar.width; // ScrollBar scrollBar.direction = ScrollBarDirection.VERTICAL; scrollBar.x = maskWidth; scrollBar.height = completeHeight; addChild(scrollBar); // Background bg = new Sprite(); bg.graphics.beginFill(0xEAEAEA); bg.graphics.drawRect(0, 0, maskWidth, completeHeight); bg.width = maskWidth; bg.height = completeHeight; addChild(bg); // Mask scrollMask = new Sprite(); scrollMask.graphics.beginFill(0xFFFFFF); scrollMask.graphics.drawRect(0, 0, maskWidth, completeHeight); addChild(scrollMask); // MovieClip to scroll scrollClip = new MovieClip(); scrollClip.mask = scrollMask; addChild(scrollClip); // TextFormat for texts textFormat = new TextFormat(); textFormat.font = "Arial"; textFormat.size = size; // TextFormat for blanks textFormatBlanks = new TextFormat(); textFormatBlanks.font = "Arial"; textFormatBlanks.size = size; textFormatBlanks.color = 0xEAEAEA; // Discover the width of one blank space with the given font size var tf:TextField = new TextField(); tf.setTextFormat(textFormat); tf.text = "."; for(var tfi:int=20; tfi>-1; tfi--) if(tf.getCharIndexAtPoint(tfi, size / 2) > -1) break; tf = null; blankWidth = tfi; // Contextmenu contextMenue = new ContextMenu(); contextMenue.hideBuiltInItems(); var clipboardLineItem:ContextMenuItem = new ContextMenuItem('Copy line to clipboard'); clipboardLineItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, copyLineToClipboard); var clipboardAllItem:ContextMenuItem = new ContextMenuItem('Copy chat to clipboard'); clipboardAllItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, copyAllToClipboard); contextMenue.customItems.push(clipboardLineItem); contextMenue.customItems.push(clipboardAllItem); textFields = new Array(); smileys = new Array(); librarySmileys = new Array(); this.maxRows = maxRows; this.size = size; this.lineHeight = size + 5; scrollBar.addEventListener(ScrollEvent.SCROLL, scrollEvent); } public function addText(text:String, cleanup:Boolean = true):void { var yOffset:uint = 0; if(cleanup && textFields.length >= maxRows) removeOldRows(); var newTIndex:int = textFields.length; for(var tin:int=0; tin -1) smileyFound = true; } if(!smileyFound) continue; var tfWidth:uint = textFields[newTIndex].width; charIndexLoop: for(var i:int=0; i -1) { for(var ls:uint=0; ls blanks.length - 1) blanks += "."; textFields[newTIndex].replaceText(charIndex, charIndex+codeLength, blanks); // Add the smiley to a temporary array addedSmileys.push(charIndex+"-"+(charIndex+codeLength)+"-"+librarySmileys[ls][0]); // Skip some pixels i += smileys[newIndex].bitmapData.width; // Make the space filled with blanks invisible (bg == fg) textFields[newTIndex].setTextFormat(textFormatBlanks, charIndex, charIndex+blanks.length); // Update this variable because of the added blanks lineText = textFields[newTIndex].text; // Remove stuff that isn't needed anymore boundaries = null; lineMetrics = null; blanks = null; } } } } } textFields[newTIndex].height = textFields[newTIndex].numLines * (lineHeight + 2); scrollBar.setScrollProperties(scrollClip.height - scrollMask.height, 0, scrollClip.height - scrollMask.height); scrollBar.scrollPosition = scrollBar.maxScrollPosition; } private function removeOldRows():void { var stayOffset:int = textFields.length - maxRows + 1; var yOffset:uint = textFields[0].y; for(var tin:int=0; tin-1; rs--) { if(smileys[rs] is Bitmap) { scrollClip.removeChild(smileys[rs]); smileys[rs] = null; } smileys.splice(rs, 1); } // Remove all TextFields for(var tin:int=textFields.length-1; tin>-1; tin--) { scrollClip.removeChild(textFields[tin]); textFields[tin] = null; textFields.splice(tin, 1); } // Add new TextFields for(tin=0; tin").join(""); text = text.split("").join(""); text = text.split("").join(""); text = text.split("").join(""); text = text.split("").join(""); return text; } } }