BreakTimer v2.0 – Update

May 13th, 2009

I made some major updates to BreakTimer. It now minimizes to the dock/system tray, with a nice icon that counts down. Also has icon menu options so BreakTimer can be started, or stopped from the dock/system tray, and well as toggle the repeat. O, I added a stop feature so you can stop the timer rather than close the application. I don’t see a point in pause, since if you pause it, you are most likely taking a break so just restart it.

Also fixed a few bugs with the break window not grabbing focus and moving to the front on a Mac. Also a little instruction slides down to let you know Escape closes the break window. Hope you enjoy!

Download at the BreaTimer Page.

BreakTimer – an AIR app to remind you to take a break from the computer

May 4th, 2009

My current career path has me sittign on my ass infront of a computer for most of the daylight hours. I have back issues, and sometimes I get too involved in my work and forget to move.  Combine that with years of volleyball and tight muscles I got a herniated disc.  So I made a simple AIR application that will block out the screen and tell you to take a break after a proscribed period of time (30 minutes).  This can be set from 0 to 180 minutes (no person should be sitting for 180 minutes straight though!).  If you have multiple monitores it will block all your monitors.

The source is there for you to tweak, right click on the app and view source.

Google App Engine and dynamic Django Forms

January 28th, 2009

Let me define dynamic form: a form that can have 0 to x number of entries for a field. For example a form that contains a list of items, like a grocery list. Its part of the same form but can have more than one entry. In PHP, they can be grouped by appending “[]” to their name attribute, and PHP stores them the $_POST variable as array (i.e. $_POST['list'][0]). I am working a project using Google App Engine, which uses Django forms, and I needed a dynamic form (list).  I found this can be done using the get_all() function of the self.request object (i.e. self.request.get_all(‘list’)) will return a list object.

Cool! But how do I use that with the Django form model with this list?  Make a list of form models. Loop through the posted list, create a form object with that data, append it to the form list, check if its valid and repeat.  If there was an error, just send the form list to the template, and loop through the forms displaying them with error messages. Else, the entire form is valid, save it to the data object.  Here is some code:

#main.py

import wsgiref.handlers
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.db import djangoforms

class Groceries(db.Model):
	quantity = db.IntegerProperty()
	name = db.StringProperty(required=True)

class GroceryForm(djangoforms.ModelForm):
	class Meta:
		model = Groceries

class MainHandler(webapp.RequestHandler):
	def get(self):
		groceryform = GroceryForm()
		values = {'groceriesformlist': [groceryform]}
		self.response.out.write(template.render('main.html',values))
	def post(self):
		postedQuantities = self.request.get_all('quantity')
		postedNames = self.request.get_all('name')
		groceriesList = []
		allGroceriesValid = True;
		n = 0;
		for i in self.request.get_all('quantity'):
			groc = GroceryForm(data={'quantity':postedQuantities[n],'name':postedNames[n]})
			allIngredientsValid = allIngredientsValid and groc.is_valid()
			groceriesList.append(groc)
			n += 1
		if allGroceriesValid:
			for grocerydata in groceriesList:
				grocery = grocerydata.save(commit=False)
				#do something with data
				grocery.put()
			self.redirect('/')
		else:
			values = {'groceriesformlist': groceriesList}
			self.response.out.write(template.render('main.html',values))
def main():
	application = webapp.WSGIApplication([('/', MainHandler)],debug=True)
	wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
	main()

The commit=False is useful when you do not want to save the data right away, like some other variable manipulation. Then there is the template file. There are numerous ways to output the form, it even has a built in table or paragraph method. If you wanted to just use the default table method to output the form, with errors, simple use <table>{{groceryform}}</table> (the output omits the table declartions, just the rows and columns) and your are done. I like a little more control, so to output the erros: {{ groceryform.quanity.errors }} and then output the input tag: {{groceryform.quantity}. Here is the template file, main.html:

<h3 class="form_headers">Groceries</h3>
<ol id="directions_form">
	{% for groceryform in groceriesformlist %}
		<li>{{ groceryform.quanity.errors }}{{groceryform.quantity}}{{ groceryform.name.errors }}{{groceryform.name}}</li>
	{% endfor %}
</ol>
<input type="button" value="+" id="add_btn" onclick="AddLi(this.previousSibling.previousSibling)" />

You also need to toss in some javascript for adding new grocery items:

function AddDirLi(ol)
{
	var li = ol.firstChild.nextSibling.cloneNode(true);
	ol.appendChild(li);
}

There are many ways to accomplish this, with AJAX or just posting items one at a time. But my project actually had a few sections of this nature and it this method seemed to work the best. I hope that made sense. The next post will cover Using Relationships with the Google App Engine Datastore. Creating and storing multiple grocery lists. The grocery list would be the the parent to many grocery items.

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!