Thursday, November 11, 2010

Convert string with carriage returns to one line in php

I have a database string containing new lines characters (\n) and needed to print it out with no linebreaks -- since it was being printed as a javascript variable. This script does the trick:

$input = trim( preg_replace( '/\s+/', ' ', $input ) );

courtesy: http://www.codingforums.com/showthread.php?t=137009

Sunday, November 7, 2010

Print booklets on Mac

One feature that is missing on Mac Snow Leopard is the ability to print a booklet from a pdf. But here is a great free application that fills that void:

http://bit.ly/2JupkE

By the way, to print even and odd pages on a Mac you need to select the "Paper Handling" option in the "Preview" dropdown.

Thursday, November 4, 2010

Create AIR app without a taskbar icon

I needed to create a chromeless AIR app that would act like the the old Active Desktop in Windows -- and did not show a taskbar icon that a user could close. Here is how it was done:


Create a new AIR app (for which a taskbar icon is required). This app spawns a new application component based on mx:Window with the HTMLLoader in it. I used a separate component for this so it could function independently from the main app. Child apps in AIR do *not* require an icon so you can set the type=NativeWindowType.LIGHTWEIGHT on this new component when you open it. As soon as this new window opens it dispatches a complete event. The main window listens for the complete event and then closes itself -- taking the taskbar icon with it. Since (I believe) in Windows 7 the shortcut "Windows/M" works from the items in the task bar, the fact that the child app is not in the task bar prevents it from being minimized by the shortcut.

By the way, this seems to work only on Windows -- not Mac -- so a different solution would be required for that.

Thursday, October 28, 2010

Communicating between Javascript and Actionscript in an AIR application

Using the HTMLLoader class you can communicate between javascript and actionscript in the same application. This means that you can trigger AS3 functions from a loaded HTML page through javascript (and vice versa). Here is a quick sample:

// AS3 code:

var windowBounds:Rectangle = new Rectangle(0,0,1024,768);
var htmlLoader:HTMLLoader = HTMLLoader.createRootWindow(true, null, false, windowBounds );
htmlLoader.runtimeApplicationDomain = ApplicationDomain.currentDomain;
htmlLoader.load(new URLRequest('myfile.html'));

htmlLoader.addEventListener(Event.COMPLETE, onComplete);

private function onComplete(e:Event):void{
// creates a new javascript function in the HTML page that map to the AS3 function
// you don't need to define these functions at all in the JS -- they become available automatically
htmlLoader.window.jsFunction = flashFunction;
}

private function flashFunction(msg:String):void{
trace("message: " + msg);
}


Once the onComplete() function runs, it creates the link between the newly created HTML javascript function and the AS3 function -- which can then be called directly in the HTML:

HTML code:

onclick="jsFunction('called from js');"

Wednesday, October 27, 2010

Round time to nearest 30 seconds

I had a requirement to round the time for a video (in seconds) to the nearest 30 seconds. Not being so strong in math, I am grateful to be better at Googling. So here it is for anyone else in a similar situation:

Math.round(myTime/30)*30

Awesome and simple!

Wednesday, October 20, 2010

Titanium gradient for buttonbar

Doesn't seem that the gradient works for the buttonbar either. So here is the workaround:

myButtonBar = Ti.UI.createButtonBar({
id:'buttonbar',
height:40,
backgroundColor:'#663399',
style:Titanium.UI.iPhone.SystemButtonStyle.BAR,
labels:['Close Keyboard >']
});

Just use a background color and the Titanium.UI.iPhone.SystemButtonStyle.BAR as the style -- and the app will create a gradient for you -- from lighter to darker.

Tuesday, October 19, 2010

Show and hide hidden files on a Mac

This command shows the hidden files in Finder on a Mac:

$ defaults write com.apple.finder AppleShowAllFiles TRUE
$ killall Finder

and this hides them again:

$ defaults write com.apple.finder AppleShowAllFiles FALSE
$ killall Finder

Friday, October 8, 2010

Titanium does not currently support the clipboard

Just a heads up for anyone that might stumble on this accidentally. Titanium Mobile does not currently support copying to the clipboard. I should have checked that before I coded a copy feature into my app...

Thursday, October 7, 2010

Time Machine issues when hard drive is partitioned

I have a Mac Book Pro (Snow Leopard) and set up Time Machine using a 1 TB Seagate external USB hard drive. The first time I set it up, I partitioned the drive into 600GB and 400GB and used the 600GB partition for Time Machine -- leaving the 400 GB partition for standard backups. However I found that the behavior of Time Machine was very buggy. For instance, if I tried to enter TM with any programs open, the Mac would freeze and I would have to restart.

So in order to use TM I had to close every program I had running. Secondly, about a month ago I maxed out the 600GB and TM stopped working altogether. It would just fail when I tried to back up.

In any event, I reformatted the drive to a single 1TB partition and now Time Machine works exactly as advertised...

UPDATE (November 5): After a few months I have had another error that the HD cannot be used by Time Machine and cannot be repaired. Either the HD is defective for Time Machine just doesn't play nice with it...

Creating a Titanium gradient button for iPhone

This took a while to figure out. I wanted to get a gradient button in Titanium but there were a number of variables that didn't seem to work properly. Here is a finished button with a gradient from black to lighter gray:

closeButton = Titanium.UI.createButton({
title:'Close',
width:150,
height:40,
style:Titanium.UI.iPhone.SystemButtonStyle.PLAIN,
borderRadius:10,
font:{fontSize:16,fontFamily:_fontFamily,fontWeight:'bold'},
backgroundGradient:{type:'linear',
colors:['#000001','#666666'],
startPoint:{x:0,y:0},
endPoint:{x:2,y:50},
backFillStart:false},
borderWidth:1,
borderColor:'#666'
});

It seems that a few items are critical to make it work:

1. You have to define the style as "style:Titanium.UI.iPhone.SystemButtonStyle.PLAIN" -- BORDERED will not work and if you don't have a style it also won't show.
2. Make sure that the gradient property for backFillStart is false.
3. There seems to be a bug when you put in #000000 as one of the colors. You need to set it to #000001 (or something like that), in order to get black to show

Sunday, September 26, 2010

Titanium Titanium.App.Properties problem

Here is another case where in Titanium the iPhone simulator successfully runs a feature that fails on the iPhone. In this case its the Titanium.App.Properties. This is supposed you allow you save global variables. From the documentation, you set it up like this:

Save variable:
Titanium.App.Properties.setString("myVar","myValue");

Retrieve variable:
Titanium.App.Properties.getString("myVar"); '// returns "myValue"

This works fine on the simulator but fails on the iPhone unless you follow two additional steps:

1. From the Kitchen Sink project -- copy /modules/iphone/settings.bundle
2. Create a /modules/iphone folder in your project and paste the settings.bundle file there
3. Make sure to name all your variables with a "_preference" suffix. So our examples above should be:

Save variable:
Titanium.App.Properties.setString("myVar_preference","myValue");

Retrieve variable:
Titanium.App.Properties.getString("myVar_preference"); '// returns "myValue"

Titanium build and iPhone simulator issues

I've found that the iPhne simulator and Titaniums build process are quite buggy. For instanace I have had numerous occasions where for no apparent reason Titanium refuses to launch in the simulator. Sometimes there is an error message -- like the iPhone SDK was installed in the wrong place -- and other times it launches and then just shuts down without an error code.

I've found that when there is no obvious reason for the issue, I create a new project and then copy all of the assets from the Resources folder of the original project and place them in the new project Resources folder and (usually) we're back in business.

It's a pain but after all it is free software! :-)

Saturday, September 25, 2010

Unable to write to filesystem using Titanium

This took several hours to figure out...

In Titanium Mobile it allows you to create and write to files in the Resources directory (Titanium.Filesystem.resourcesDirectory) using the emulator, but it fails when you try to run it on the iPhone. This is because you don't have actual write permissions on that directory -- you need to save data to the Titanium.Filesystem.applicationDataDirectory.

Here is how you write to a file: (btw -- if the file does not already exist, it creates it automatically -- you don't need to use the Ti.Filesystem.createFile() method)

var f = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, 'myFile.txt');
f.write('this is the new file');

To read the contents of a file:

var g = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, 'myFile.txt');
var contents = g.open();
Titanium.API.info("Contents of the file = " + contents.text);

Thursday, September 23, 2010

Window height in Titanium/iPhone

Just a caution: while using Appcelerator Titanium, we aware that Titanium.Platform.displayCaps.platformHeight includes the iPhone status bar height -- which is essentially unusable real estate since it always shows in an application. So you have to deduct 20 to get the actual usable space on an iPhone.

For instance:

I created a buttonbar (with a height of 50) and wanted position it at the bottom of the screen. So I thought that the easiest way would be to use the Titanium.Platform.displayCaps.platformHeight as my layout height and then just set the buttonbar to have a top value of Titanium.Platform.displayCaps.platformHeight - myButtonBar.height.

However, this always placed the buttonbar too low on the screen. It was only when I modified the variable to account for the 20 pixel status bar did everything line up properly:

Titanium.Platform.displayCaps.platformHeight - myButtonBar.height - 20

Wednesday, September 22, 2010

"Error creating project" in Titanium

I had installed Titanium a few months ago and had not used it for a while but when I tried to create a new project -- or compile an old one -- I kept getting errors.

In the end, I installed the Android SDKs and followed the advice in this post:

https://developer.appcelerator.com/question/34821/build-failed

but without installing the patch.

After this was all done -- and updated -- Titanium allowed me to correctly create a new project from iPhone but it still doesn't find the Android SDK. I'll leave that for another day....

Phonegap for iPhone development

For what it might be worth to others, I have tried Phonegap for a while now and although its relatively easy to get started if you have a straight forward html/javascript project, it doesn't seem to be so simple to access the native functions of the iPhone. For instance, I tried to implement the tab bar and after several tries found that it does not position properly -- nor could I quite figure out how to add an icon to a tab item.

I'm going to try and use Titanium and see how hard it is to port the existing code to it.

Tuesday, September 21, 2010

Firefox download manager

After failing for the second time to successfully download the newest XCode and iPhone SDK (3+Gb) I found this list of download managers on LifeHacker:

http://lifehacker.com/347827/top-10-free-download-managers

It seems the highest rated is the Firefox extension: Download Them All!

Update: Turns out that Apple has a non-resume on their SDK download so I had to try a few more times before I got the whole thing down in one try....

Monday, September 20, 2010

XCode shows: "No provisioned iPhone device is connected"

In case this is helpful for anyone else. I was trying to install a demo iPhone project on my iPod Touch and got the error: "No provisioned iPhone device is connected". I knew that I had the provisioning set up -- but it turns out that I had not upgraded the SDK -- so while the iPod Touch was 4.0, the SDK was 3.2. Once the SDK was updated the install went fine.

Friday, September 17, 2010

Solved - Problem connecting Mac using Check Point SecureClient

On a Mac (Snow Leopard) I was having issues using a Check Point Secure access. I kept getting "Gateway not responding | Connection failed". I had installed the latest software from Check Point (Check Point VPN-1 SecureClient NG with Application Intelligence - R56 HFA2 Build Number 015), but I was still having a problem.

A friend finally suggested that I try disabling NAT filtering in my modem.

This solved it!

Saturday, September 4, 2010

Restrictions on flash fullscreen mode

From Adobe:
  • The ActionScript that initiates full-screen mode can be called only in response to a mouse click or keypress. If it is called in other situations, it will be ignored (in ActionScript 2.0) or throw an exception (in ActionScript 3.0).
  • Users cannot enter text in text input fields while in full-screen mode. All keyboard input and key-related ActionScript is disabled while in full-screen mode, with the exception of the keyboard shortcuts that take the viewer out of full-screen mode.
That last bit is sad news if you want to allow a user to share via email while in fullscreen mode :-(

Friday, June 18, 2010

Very cool Flash debugger tool

While trying to do some live web debugging of a flash app I came across this great Air app that lets you see all of your trace and error statements as the app is running. It outouts the standard trace commands so there is no need to import any new classes and write to a console.

Awesome!!

http://bit.ly/ck3KpN

Sunday, June 13, 2010

Flash CS cannot find fl.core and fl.video packages

This is just strange. I was trying to import the classes in fl.core and fl.video into a Flash project and the compiler gave a "Definition could not be found." error. Apparently this has been a problem since (at least) Flash CS3. The IDE does not automatically add those libraries to the classpath so you need to do it yourself.

Here are the instructions:

Open Flash
Go to Edit>Preferences>Actionscript>ActionScript3 Settings>

and add these two paths to the Source Path:

$(AppConfig)/Component Source/Actionscript 3.0/User Interface
$(AppConfig)/Component Source/Actionscript 3.0/FLVPlayback

Friday, May 21, 2010

Hiding dotted lines around links in Firefox

This is just simple and brilliant:

http://sonspring.com/journal/removing-dotted-links

/* this removes the dotted line around everything linked item */

:-moz-any-link:focus {
outline: none;
}

Friday, May 14, 2010

Adding shadows to divs

Safari and Firefox also have different ways of adding shadows to divs:

// safari
-webkit-box-shadow: 1px 1px 3px #888;
//mozilla
-moz-box-shadow: 1px 1px 3px #888;

Adding gradients to divs

Safari and Firefox require different css to create gardients:

#myDiv{
//Safari:
background-image: -webkit-gradient(linear,left top,left bottom, from(#666), to(#000));
//Mozilla:
background: -moz-linear-gradient(top, #666, #000);
}

Tuesday, May 4, 2010

How to delete a post from a Wordpress database

For some reason the data that I inserted into a post got corrupted and I was unable to delete or edit it within the Wordpress console. So to manually delete a post from the database just do this update:

update (name of posts table) set post_status = 'trash' where id = (ID of offending post)

Wednesday, March 3, 2010

Unable to see SD card on Blackberry

I was helping someone today to put some documents on their Blackberry Bold 9000 and for some reason when I connected it to my PC I a drive letter was assigned to the Blackberry itself but not the SD card. Doing a bit of Googling it seems that this is a hige problem for users and there were hundreds of hits for this exact problem -- including people trying to use the Roxio Media Manager. In any case, one post had the answer that worked for me and here is the step by step solution:

1. Click Start>Run and then type: compmgmt.msc
2. Select Disk Management
3. In the right panel you should see both the Blackberry and the SD card as separate devices
4. Right click the SD card and select: Change Drive Letter and Paths
5. Click "Change" and then select the drive letter you want to assign to the device. Make sure that you do not assign an already assigned drive letter. If in doubt, right click your My Computer icon on the desktop and choose Map Network drive, then open the dropdown for the drives and note one of the unassigned drive letters.
6. Click OK

Hopefully you'll now be able to see the SD card and can treat it like any other USB drive. All in all this is way better than using the Roxio Media Manager app(which is a 200MB+ download!). But in any case once you've assigned the drive properly Roxio should now be able to access the drive as well.

Saturday, February 20, 2010

Comparing two objects in jQuery

Had a strange problem in comparing two objects in js. I am dynamically creating a number of divs, adding them to the DOM and also placing them into an array in order to keep tack of what divs are hidden or shown at a given time. Later, I tried to loop through all of the divs and compare them using the === operator but they never returned true -- even though both objects were divs and even showed the same innerHTML.

Anway, a Google search turned up a suggestion to add this function to the jQuery prototype:

$.fn.equals = function(compareTo) {
if (!compareTo || !compareTo.length || this.length!=compareTo.length)
{
return false;
}
for (var i=0; i
if (this[i]!==compareTo[i]) {
return false;
}
}
return true;
}

Problem fixed!

Tuesday, February 16, 2010

More problems with the AS3 Loader Class

I've built an AS3 preloader so a Flash app can preload assets before starting. The app uses a number of Loaders to load about 15 swfs and when the LoaderEvent.INIT is fired it increments the index. When all of the assets have loaded, it starts the app and adds the contents of the Loaders to the display list:

myclip.addChild(MovieClip(myLoader.content);

However, when the app is run from the web occasionally it throws an error that a myLoader.content is null -- so it can't be added to the display list.

I assume that this means that a false INIT event is being fired -- or the player is not always seeing that the content is available to add.

In any event, I wound up setting a Timer that waits 2 seconds before adding the content to the display list. So far this seems to solve the problem for me -- but not the bug....

Saturday, February 6, 2010

Great javascript editor - Aptana Studio

I have been using Dreamweaver for over 10 years and never thought I would need another html code editor -- and ponied up the price for updates every few years. But now that I'm spending increasing time doing javascript development I found that it just wasn't that good for code completion/hinting/documentation etc. After a bit of searching I came across Aptana Studio and absolutely love it. It's built on Eclipse and has everything I could hope for js development -- including being able to install plugins for various frameworks like JQuery, DoJo and more. Plus you can even add a plugin for AIR development.

To install the JQuery plugin just go to:

Help>Install Aptana features>Ajax>JQuery Support

Did I mention that its free?

Thursday, January 28, 2010

IE7 javascript error in for each loops

One of the reasons I like Flash is the fact that one piece of code will work on every browser. But not so with javascript. Case in point:

If you have an array (langArray) in javascript and want to loop through it the common way is this:

for each(var item in langArray){
...
}

but this causes IE 7 to choke. Instead you have to use the more verbose:

for(var item=0;item var item = langArray[i];
...
}

Thursday, January 21, 2010

Flash elements disappear in full screen mode

I was surprised to find that a button and a dropdown list disappeared when I went full screen on a Flash app. Turns out that if you use an FLVPlayerback component it forces everything else on screen to disappear if you go fullscreen. Nice feature unless you don't want that to happen.

To fix it:

myFlvPlayback.fullScreenTakeOver = false;


Thanks Adobe forums :-)

Thursday, January 7, 2010

Working with AS3 Video cuepoints

I have been working with cuePoints in flash video and so far have been unable to add actionscript cuePoints and then seek to them. (Update: see solution below)
  • Encode a video: "myVideo.flv" without embedded cuePoints
  • Attach the video to a FLV playback component "my_FLVPlybk"
  • Add cuepoints like this: my_FLVPlybk.addASCuePoint(15, "Cue1");
  • Set up an event Listener to see if the cuepoints are there:
my_FLVPlybk.addEventListener(MetadataEvent.CUE_POINT, cp_listener);

function cp_listener(eventObject:MetadataEvent):void {
trace("Elapsed time in seconds: " + my_FLVPlybk.playheadTime);
trace("Cue point name is: " + eventObject.info.name);
trace("Cue point type is: " + eventObject.info.type);
}

When you run the app, it all works expected. Once the cuepoints are reached it traces out each point. However when you try to go to the cuepoint using this method:

my_FLVPlybk.seekToNavCuePoint("Cue1");

It fails with this error:

VideoError: 1003: Invalid seek
at fl.video::FLVPlayback/seekToNavCuePoint()

Now, this last bit of code works fine if you embed navigation cuepoints in the video itself -- using Adobe Media Encoder (FLV only -- F4V seems not to support cuepoints--at least not well), but according to Adobe it should be possible to add the cuepoints and reference them through actionscript only. In this particular case its not a problem for me since its easier to add the cuepoints to the encoded video, but if anyone has come up with a solution, please post it!


***************************

Update: I found the solution on another forum (http://bit.ly/8EdgdN):

The answer is to locate the cuePoint using findCuePoint() -- which returns an associative array of the point -- and then get the value of "time". At this point you can just do a seek. The final code would be like this:

my_FLVPlybk.seek(my_FLVPlybk.findCuePoint("Cue4", CuePointType.ACTIONSCRIPT)["time"]);