Reading and Writing Files in AIR – using a simple text editor

January 26th, 2009

Monstagon asked me if I ever saved or opened files in Adobe AIR. Yes. I have. I made a simple text editor to demonstrate the basics of reading files in (letting the user browse for a file on their machine) and writing a save (also letting the user specify where to save the new file).

Some issues I encountered with making the text editor were the different FileModes (READ, WRITE, UPDATE, and APPEND). UPDATE and APPEND basically just add whatever you write to the FileStream to the end of the file. WRITE deletes the destination and writes only what is sent to the FileStream. READ only opens the file for reading. After erasing some files accidentally by opening it with WRITE, I realized for the text editor to work, first READ the file in, close the FileStream. When the user hits Save, open the file in WRITE mode, and send the contents of the editor to the FileStream.

I also had to removeEventListener from the FileStream because it was listening for two Event.SELECT’s: user selects which file to open, and user selects where to save. This was throwing errors when the user selects where to save and the program tries to open a file that doesn’t exist.

If you just want to know how to read a file, look at private function Open() and follow the code. For writing, private function Save(). Note that in ActionScript, its all about event listeners. So reading the file contents into the TextArea is 3 function, because we have to wait until each step is ready. Else, if you don’t setup the Event Listeners nothing will happen.

<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import mx.events.FileEvent;
private var stream:FileStream;
private var file:File = File.documentsDirectory;
private var newFile:Boolean = true;
private function New():void
{
	newFile = true;
	editor.text = '';
}
private function Open():void
{
	try
	{
	    file.browseForOpen("Open");
	    file.addEventListener(Event.SELECT, LoadFile);
	}
	catch (error:Error)
	{
	    trace("Failed:", error.message);
	}
}
private function LoadFile(evt:Event):void
{
	file.removeEventListener(Event.SELECT, LoadFile);
	file = evt.currentTarget as File;
	stream = new FileStream();
	stream.addEventListener(Event.COMPLETE, ReadFile);
	stream.openAsync(file,FileMode.READ);
}
private function ReadFile(evt:Event):void
{
	stream.removeEventListener(Event.COMPLETE,ReadFile);
	var str:String = stream.readUTFBytes(stream.bytesAvailable);
	editor.text = str;
	newFile = false;
	stream.close();
}
private function Save():void
{
	if(!newFile)
	{
		stream = new FileStream();
		stream.openAsync(file,FileMode.WRITE);
		stream.writeUTFBytes(editor.text);
		stream.close();
	}else
	{
		file.browseForSave("Save");
		file.addEventListener(Event.SELECT, SaveFile);
	}
}
private function SaveFile(evt:Event):void
{
	file.removeEventListener(Event.SELECT, SaveFile);
	var file:File = evt.currentTarget as File;
	stream = new FileStream();
	stream.openAsync(file,FileMode.WRITE);
	stream.writeUTFBytes(editor.text);
	stream.close();
	newFile = false;
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:HBox>
	<mx:Button label="New" click="New();" />
	<mx:Button label="Open" click="Open();" />
	<mx:Button label="Save" click="Save();" />
</mx:HBox>
	<mx:TextArea id="editor" width="100%" height="100%" />
</mx:VBox>
</mx:WindowedApplication>

Gmail Keyboard Shortcut Cheat Sheet

January 16th, 2009

Since Gmail has started to get a whole lotta keyboard shortcuts, and I can never keep track of them all, I created a little cheat sheet of the default shortcuts (with some extra function enabled in Labs) I could print out (landscape) and put by my monitor. 

Here it is (cheat sheet only):

Action Key(s)
Compose c
Search /
Back to threadlist u
Newer conversation k
Older conversation j
Select conversation x
Star conversation s
Remove label y
Ignore conversation m
Report as spam !
Move to trash #
Open conversation o
Previous message p
Next message n
Reply r
Reply all a
Forward f
Focus chat contact search q
Go to Inbox gi
Go to Starred conversations gs
Go to Sent messages gt
Go to Drafts gd
Go to All mail ga
Action Key(s)
Go to Contacts gc
Select all conversations *a
Deselect all conversations *n
Select read conversations *r
Select unread conversations *u
Select starred conversations *s
Select unstarred conversations *t
Focus last chat mole \27
Update conversation N
Remove label and go to previous conversation ]
Remove label and go To next conversation [
Undo last action z
Open more actions menu .
Mark as read I
Mark as unread U
Open shortcut help ?
Archive e
Go to Tasks gk
Add to Tasks T
Add to Tasks t
Go to Label gl


Detecting Screen Resolution in Flex/AIR

January 10th, 2009

Monstagon asked me how to scale and AIR application to the users screen resolution. There are
a few ways to achieve this: maximize(), StageDisplayState.FULLSCREEN, or Capabilities.screenResolutionX/Y.
Here is a little tutorial/sample of resizing a chomeless window to fit the screen
using all 3 methods.

Go open Flex Builder 3, and create a new AIR project. First, lest go chromeless.
Open the app.xml file to edit the application settings. We need to set
systemChrome and transparent to none and true
respectively.

<!-- Thetype of system chrome to use (either "standard" or "none"). Optional. Default standard. -->
<systemChrome>none</systemChrome>

<!-- Whether the window is transparent. Only applicable when systemChrome is none. Optional. Default false. -->
<transparent>true</transparent>

And now we need to set up the WindowedApplication properties showStatusBar,
showTitleBar, and just for effect backgroundAlpha to false,
false, and 0.5. Also set applicationComplete to the
startup function, in this case Init();. (I ran into some trouble accessing the stage
in the startup function when I was listening for the creationComplete event. We need to listen
for applicationComplete if we want to access stage and stage items, because when this event
is fired, everything is drawn and ready to go.
Understanding The Flex Application Startup Event Order)

	<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="Init();"
		showStatusBar="false" showTitleBar="false" backgroundAlpha="0.5" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#000000, #5D7B68]">

Enough jabber, here is are the functions source code. Layout some buttons to activate which options you want to see.

<mx:Script>
	<![CDATA[
	import mx.events.FlexEvent;
	private function Init():void
	{
		addEventListener(MouseEvent.MOUSE_DOWN,InitMove);
	}
	private function CapabilitiesMax():void
	{
		width = Capabilities.screenResolutionX;
		height = Capabilities.screenResolutionY;
	}
	private function FullScreen():void
	{
		stage.displayState = StageDisplayState.FULL_SCREEN;
	}
	/* MOVE */
	private function InitMove(evt:MouseEvent):void
	{
		stage.nativeWindow.startMove();
	}
	]]>
</mx:Script>
<mx:VBox horizontalCenter="0" verticalCenter="0" horizontalAlign="center">
	<mx:Button label="stage.nativeWindow.maximize()" click="stage.nativeWindow.maximize();" />
	<mx:Button label="Resize to Screen Resolution" click="CapabilitiesMax();" />
	<mx:Button label="stage.nativeWindow.restore()" click="stage.nativeWindow.restore();" />
	<mx:Button label="Full Screen" click="FullScreen();" />
	<mx:Button label="Close" click="close();" />
</mx:VBox>

And that is the entire source code to demostrate how each option works. A thing to note,
when using the “Resize to Screen Resolution” the window is not centered, but stretched
from its current screen position. In most cases, I maximize(); would be the function
to use, or set it to full screen. And if you want to manually resize it to the screen resolution
and have the window centered, set the x and y of stage.nativeWindow to 0.
Here is the new CapabilitiesMax() function.

private function CapabilitiesMax():void
{
	width = Capabilities.screenResolutionX;
	height = Capabilities.screenResolutionY;
	stage.nativeWindow.x = 0;
	stage.nativeWindow.y = 0;
}

Hope that helps Monsta. And I would enjoy working on a project, and I want chocolate.

What I Miss About my MacBook Pro

December 3rd, 2008

Hopefully this little rant, which I will turn into a blog post, will help me figure out how much a MacBook Pro is worth to me. First things first: A computer, in its simplest form, is a tool. A very modular tool.  This isn’t a Mac vs PC (really, Mac vs Windows since PC is a Personal Computer) but rather an inner discussion on if I want to spend the extra cash just to get a Mac. Lets be real, a Windows machine with nearly identical hardware (Intel Core 2 Due, 2 GB RAM, NVIDIA Graphics, 200GB HD, etc) is less expensive than the Mac. So does the Mac merit the extra cash, to me? O and Linux is not in the discussion because Adobe Suite doesn’t run on it.

My laptops:

  • MacBook Pro 15, 2.3 Intel Core 2, 2 GB Ram, NVIDIA 256, 250 GB HD, with the LED screen (Work Laptop, could buy it from them for $1400, ebay for less, but had to give it back)
  • HP Pavillion dv6587se, 1.8 Intel Core 2, 3 GB Ram, NVIDIA 256, 300 GB HD. (Personal, got it slightly used for $500)

First, a program breakdown.  What programs I use that are Mac or Windows exclusive, what are both, and what I prefer on one or the other. And I avoid using Microsoft Office, so that is just off the list, else I would put it on the “runs better on Windows” side.

Windows OSX
Visual Studio 2008 X
XNA GameStudio X
Softimage XSI X
Notepad++* X
Trillian* X
Unity3D X
TextMate** X
Adium** X
iLife (iPhoto) X
Eclipse X X
Adobe Suite X X
OpenOffice X X
Firefox X X
* – Similar, comparable programs are available on both OS’s.
** – I like this program better than the comparable one.

How valuable are the programs that are only available on one OS too me?  Does it improve productivity? Easier to use? More stable? Give me less aggravation? Will it help me earn more money?In most cases, it’s more a matter of usability. For instance, Trillian and Adium are nearly the same, but I prefer Adium’s look and feel to Trillian’s. The harder case is Notepad++ or TextMate. Both are excellent apps. Excellent plugins, easy to use, stable.  But TextMate has better keyboard shortcuts for auto complete and directory reading.  But Notepad++ also has nice auto complete, can read directories (via exploer plugin), and a built in FTP (but not sync). If I had to pick, I would pick TextMate, but am perfectly happy with either one. Really, the best text editor would be the light weight of Notepad++, the text manipulation power of TextMate, and the parsing and sync ability of Eclipse.

I don’t use Unity or XNA enough right now to merit one over the other. I hope to get more into game development, for serious games or not serious games, soon, but until then those will be a straight wash. Same with XSI (there’s Modo for both), and I don’t do much modeling. And also with Visual Studio. I don’t use VS enough right now, but have in the past and will in the future, so that’s like half a point. Man, I should put point score.

So the software pretty much comes down to what I am working on. Now, mostly web, PHP, so its a wash.  If I needed to do .NET, Windows would win. If I needed to do Unity3D, Mac would win. Next is hardware interface. The construction, feel, and ease of the basic hardware for an average Windows laptop and a MacBook.

I would have to pick the MacBook on design. Smooth curves, simplest shape, sturdy feel.  When you close a MacBook it just feels closed. The HP I have, has bumps and uneven surfaces. Mostly aesthetics. Usability: There’s the 2 finger scroll on the Mac. So much better than the side of the damn track pack that sort of works, and always seems to be too sensitive or not sensitive enough. Two fingers, up down, or left right.  Beautiful.  But the real kicker. What I think makes Mac so great to use:

The Apple (Command) key.  And this, to be honest, is what I enjoy the most about working on a Mac. One modifier key. Apple + … On Windows is Alt + Tab, or Ctrl + C, or Windows Key + R, etc. And the placement of the Apple. Right on your thumb. Perfect. I barely have to move my hands on the keyboard or use the mouse.  This does improve my productivity.  Makes me move faster, quicker. Seems kinda stupid, but when your typing away at code, and you need to quickly move around the computer nothing is worse than missing the control key or hitting alt and accessing the file menu.

And the kicker, you can run Windows on a Mac (Virtual or Boot), without having to pull and iHackintosh. If money was not an issue, I would love to get a MacBook Pro. So, if I had the money, it would most likely be worth it. Till then, I will have to keep trying to get Mac to work on a PC.

JavaScript Calculator

November 9th, 2008

So I made this online calculator that lets you type in commands and equations

http://www.sapethemape.com/calc.html

I based it off of a Mac Widget Calculate I had that was AWESOME! Windows Sidebar Gagdet Calculatorium is also very good.  What I liked was it had history and it was more of a command line calculator than a typical button presser.  Instead of pressing buttons, you could enter mathmatical expressions and it would solve it.

For mine, you can hit up and down arrows to scroll through your input history, exape clears it, and if you hit + – * / it automatically enters answer (the previous answer); next I need to resize it… But I want to port it to AIR.  Except ActionScript doesn’t have an EVAL function. Javascript does.  Eval basically does all the work, parses the expression for me. There is a ? for help, just lists the JS Math function available.  A friend just pointed out 1^4 = 5, so I need to add parsing for that.

Then I want to make it for my G1.  I tested this version, but the keycodes for + – * / are different on the mobile keyboard because it wouldn’t automatically add ‘answer’.  If you want to help, you can add errors to the comments here.  Just view source for source code. Yes, you can steal it. But its prolly not worth stealing =P.

Go West Young Man!

October 31st, 2008

Today is my last day in Ohio.  I move out west to live with family and get a Master Degeree in Game Development from USC.  Its been fun and painful to live in Ohio.  The Buckeyes will always be #1. I am thankful for my opportunities at Avetec.  But I am very excited to start my new chapter.  I will be posting here about what I learn.  It will most likely be more technical (like tutorials and work samples). But you can infer how I am doing and all the sappy stuff thru those.

I also wrote this post for people at Avetec, so after reading my “Peace!” email and clicking on the link they have something new to read.  Thanks again!

Fight On Buckeyes!

The Love Question

September 30th, 2008

Do we love because we are in love, or are we in love because we love?

Client Side Script in a .NET Web Part

August 26th, 2008

Quick, a little snippet on adding client side scripts (javascript) in a web part or ASP.NET page. And the link to [MSDN](http://msdn.microsoft.com/en-us/library/ms948916.aspx “Creating a Web Part with Client-side Script”) where I found this wonderful information. My script was small, basically an alert to tell the user he/she is stupid. So I embedded the script in the Web Part. It worked. Here is my code snippet, since the one on MSDN was using old function to register the client script.

	private const string ByeByeIncludeScriptKey = "myByeByeIncludeScript";
    private const string EmbeddedScriptFormat =
          "<script language=javascript>alert('Bye Bye');</script> ";

    public WebPart_ClientScript()
    {
       this.PreRender += new EventHandler(WebPart_ClientScript_PreRender);
    }

    private void WebPart_ClientScript_PreRender(object sender , System.EventArgs e )
    {

          	if (!Page.ClientScript.IsClientScriptBlockRegistered(ByeByeIncludeScriptKey))
              Page.ClientScript.RegisterClientScriptBlock(typeOf(WebPart_ClientScript), ByeByeIncludeScriptKey, EmbeddedScriptFormat);
    }

Note that [James.ToString()](http://blogs.ipona.com/james/archive/2006/10/03/6710.aspx “Don’t user GetType()”) says not to use this.GetType but rather typeOf(ControlName) where control name is the web part. So the above just tosses up an alert that happens when the page loads. Although, if you did want a function in there, to have it be called, you add the OnClientClick attribute to the asp tag.

	<asp:Button runat="server" Text="Oh, Click me.." OnClientClick="ShowAlert()" />

And that “ShowAlert()” can be any function name. Simple enough.

SharePoint 2007 Web Part Deployment Tutorial

August 11th, 2008

There are a bunch of tutorials out there that use C# to create a class library and the put that in the GAC (Windows assemblies folder) etc. I could not get those to work for the life of me. The best way I have found to develop, test, and then deploy a custom SharePoint Web Part to the production server is with Visual Studio SharePoint Extensions, for VS 2005 or VS 2008. Except it seems you can only install this if you have Windows SharePoint Services 3.0 installed. And you can only install WSS 3.0 on Windows Server 2003 SP1. Sorry, no free download for that.

Read the rest of this entry »