<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>The ZAZ Blog</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/" />
    <link rel="self" type="application/atom+xml" href="http://www.thezaz.com/blog/atom.xml" />
   <id>tag:www.thezaz.com,2008:/blog//10</id>
    <link rel="service.post" type="application/atom+xml" href="http://www.thezaz.com/mt4/mt-atom.cgi/weblog/blog_id=10" title="The ZAZ Blog" />
    <updated>2008-10-12T17:01:25Z</updated>
    <subtitle>When all you have left is a chicken and a rocket launcher, make some really badass scrambled eggs.</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.0</generator>
 

<entry>
    <title>Image Masking</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/tutorials/image_masking.php" />
    <link rel="enclosure" title="PNG Machine" type="application/zip" href="http://stuff.thezaz.com/png_machine.zip" length="2721" />
    <id>tag:www.thezaz.com,2008:/blog//10.227</id>
    
    <published>2008-10-12T05:27:24Z</published>
    <updated>2008-10-12T17:01:25Z</updated>
    
    <summary>Learn everything you need to know about proper image masking.</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="REALbasic" />
    
        <category term="Tutorials" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        Over the past few days I&apos;ve seen this topic come up on the REAL Software Forums and the REALbasic NUG. There&apos;s quite a mix of information - some correct and misleading. Luckily, I&apos;ve not seen information that is just flat out wrong.
        <![CDATA[<style type="text/css">div.image { background-color: #AC3525; width: 64px; margin-left: auto; margin-right: auto; padding: 5px; border: 1px solid #500900; margin-top: 10px; margin-bottom: 10px; }</style>
<p style="font-size: larger; font-weight: bold;">The double mask effect</p>
<p>The single most common issue I see with masking is what I call &quot;double masking&quot; - which is the art of applying a mask to an image that has already been masked. Below, is an original PNG image shown on a background color. This is our &quot;correct&quot; image:</p>
<div class="image"><img src="http://www.thezaz.com/blog/images/splash_original.png" width="64" height="64" alt="" /></div>
<p>Now, the advice I commonly see is to use another program to retrieve just the mask from the png, then import both images into REALbasic. When this happens, you end up with two images:</p>
<div class="image"><img src="http://www.thezaz.com/blog/images/splash_masked.png" width="64" height="64" alt="" /></div>
<div class="image"><img src="http://www.thezaz.com/blog/images/splash_mask.png" width="64" height="64" alt="" /></div>
<p>Notice the white background on the first image. REALbasic doesn't properly handle the alpha channel, so you'll end up with that, thus the reason for this entry. Anyway, when you apply the third image as a mask to the second, you get this:</p>
<div class="image"><img src="http://www.thezaz.com/blog/images/splash_wrong.png" width="64" height="64" alt="" /></div>
<p>It looks reasonably close, but it's not correct. The blue shadow is too light, and in fact, has a white ghost effect to it. It certainly looks different from the first image - and that's bad. So what went wrong? Why did we not get the original image back? That's because image two already had a masked applied, we just didn't have translucency, the translucent image we wanted was drawn onto a white backdrop.</p>
<p>There is a difference between a pixel that is 50% black, and a pixel that is 100% black at 50% opacity. By doing this double masking, you essentially take a 50% black pixel and make it 50% opaque which is not correct.</p>
<p style="font-size: larger; font-weight: bold;">Solutions</p>
<p>There are a handful of solutions. The easiest is to use the <a href="http://developer.chaoticbox.com/#pngutilities">PNG Utilities</a> plugin. It's open source, and cross-platform. Just store your images on disk and read them at run time. But what if your project has a requirement of not using any plugins or you really want to drag your images into the IDE? Then you need to be a little more fancy.</p>
<p>The solution I use in such a case is a small app I wrote to properly split a PNG into a new PNG with the data (not the composite, there is a difference) on the left and the mask on the right. That project has been linked with this entry, and does require the PNG Utilities plugin mentioned earlier. When images are dropped on the app, it will turn image one into:</p>
<div class="image" style="width: 128px;"><img src="http://www.thezaz.com/blog/images/splash_split.png" width="128" height="64" alt="" /></div>
<p>Then, I can simply drag that new image into the IDE and use it as necessary, with the assistance of a simple method:</p>
<p><pre class="rbcode"><?php echo FormatRBCode('Function CombineImage(Input As Picture) As Picture
  dim result as picture
  dim w as integer = input.width / 2
  dim h as integer = input.height
  result = newpicture(w,h,32)
  result.graphics.drawpicture input,0,0,w,h,0,0,w,h
  result.mask.graphics.drawpicture input,0,0,w,h,w,0,w,h
  
  return result
End Function'); ?></pre></p>
<p>That code will perfectly turn the combo image into the original image, image one. This method has the advantage of still only requiring one file per image too.</p>
<p style="font-size: larger; font-weight: bold;">Misconceptions</p>
<p>Let's say you only have the composite image (image two) to work with. Well, then you're doomed and out of luck. You'll never get the image back to it's original 100% because crucial information is lost. You can, however, try to fake it and come reasonably close. Photoshop can help with this, but there's no how-to for this because every image is different. If I were going to try to do it with the sample used here, I'd use a circle select to delete everything outside the globe, and try to recreate the shadow by hand. But there is no tool that can do that for you perfectly because at that point, information is lost.</p>
<p>As you can tell, I like PNG. That's because it is lossless (basically meaning full quality) and smaller than JPEG. PNGs are only sometimes smaller than GIF, but GIF cannot display a full color spectrum. JPEGs can be made smaller than PNGs, but at a loss of quality. There is TIFF too, but it's not often used (besides in Apple apps) and we have the PNG Utilities plugin to work with. So I typically go with PNG every time.</p>]]>
    </content>
</entry>

<entry>
    <title>Custom Controls: Finding your global screen bounds</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/tutorials/custom_controls_finding_your_g.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.226</id>
    
    <published>2008-10-11T05:46:08Z</published>
    <updated>2008-10-11T05:53:32Z</updated>
    
    <summary>GPS for your controls</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="REALbasic" />
    
        <category term="Tutorials" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>I find myself writing a fair amount of custom controls. Frequently, I find myself wanting to find the position of the mouse relative to my control. The MouseDown, MouseDrag, etc. events have this info, but if you need this in the Paint event, you must either save it to a property or get it from the system. We're exploring the latter, as it's not as simple as you might think.</p>]]>
        <![CDATA[<p>System.MouseX and System.MouseY will tell you where the mouse is. You might think that simply using System.MouseX - Self.Left is sufficient - but it's not. Self.Left and Self.Top only return values relative to the parent window. In today's REALbasic, ContainerControls come into play. In fact, multiple layers of ContainerControls can occur. Then, finding your control's true position on screen can become difficult.</p>

<p>The solution is a method I use call TrueWindow, that extends any Window (and thus ContainerControl) or RectControl. It traverses up the Window.Parent chain until it hits a Window that is not a ContainerControl.</p>

<p><pre class="rbcode"><?php echo FormatRBCode('Function TrueWindow(Extends R As RectControl) As Window
  return r.window.truewindow
End Function'); ?></pre></p>

<p><pre class="rbcode"><?php echo FormatRBCode('Function TrueWindow(Extends W As Window) As Window
  if w isa containercontrol then
    return containercontrol(w).window.truewindow
  else
    return w
  end
End Function'); ?></pre></p>

<p>Now technically, this will be enough. But I like to use a couple other tricks too. I usually create a structure, we'll call it ZAZRect, which has four integer properties: Left, Top, Width, and Height. I also create two extender methods for it: Right() and Bottom() which just calculate that for me.</p>

<p>I then use this nice TrueBoundary() method to instantly get the bounding rect of any control relative to the user's screen:</p>

<p><pre class="rbcode"><?php echo FormatRBCode('Function TrueBoundary(Extends C As RectControl) As ZAZRect
  dim r as zazrect
  r.height = c.height
  r.width = c.width
  r.top = c.top
  r.left = c.left
  
  dim w as window = c.window
  while w isa containercontrol
    r.top = r.top + w.top
    r.left = r.left + w.left
    w = containercontrol(w).window
  wend
  
  r.top = r.top + w.top
  r.left = r.left + w.left
  return r
End Function'); ?></pre></p>

<p>So there's some ground work for some upcoming tutorials I plan to write.</p>]]>
    </content>
</entry>

<entry>
    <title>I hate Gmail</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/rants/i_hate_gmail.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.225</id>
    
    <published>2008-10-06T22:33:02Z</published>
    <updated>2008-10-06T23:04:39Z</updated>
    
    <summary>How Gmail makes Microsoft suck less.</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="Rants" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>I hated Gmail before I ever used it. Now I've been using it for about 5 months now and I've learned to complete despise it.</p>]]>
        <![CDATA[<p><span style="color: #0000FF;">&lt;evil_rant&gt;</span><br />
We use Google Apps here at REAL. I've heard when we managed our own server the e-mail system was a hassle, so letting Google handle it for us was not a bad idea. Now, we have a hosting service run our server for us, and e-mail is a breeze... for the mailing lists. All our @realsoftware.com addresses still go to Gmail.</p>

<p>And I really hate Gmail. I don't use the web interface, because I find it completely unusable. It wasn't so bad originally. The biggest problem was when using a desktop client, Gmail will not deliver messages with the same "from" and "to" addresses to you. They'll appear in your web inbox, but on the desktop, they hide it from you just to piss you off. I got a number of e-mails about that one, and I don't like responding with "sorry, it's out of my hands."</p>

<p>But now my biggest issue is Gmail keeps flagging legitimate messages as spam. Every topic notification I get from our forums keeps going to my spam box, and many of my status e-mails are too. This is really, really getting on my nerves and it's affecting the way I do my job. Well, kind of, I've added some contacts to the awful web interface, but I shouldn't have to.</p>

<p>I can't even turn off my spam filter and let Mail.app handle it. Worse still, since we have a Google Apps account, obviously all e-mails to realsoftware.com are part of Gmail - shouldn't it be smart enough to NOT flag inter-office emails as spam? I'm also getting complaints about Gmail's conversations making it difficult to keep track of conversations - I love the irony there. Gmail doesn't care about the "In-Reply-To" header and instead, groups conversations by subject. But since a lot of e-mails go out of customer service with the same subject to different people... you should be able to figure out where I'm going with this.</p>

<p>I'm tempted to work some of my trademark magic and find a way to have my address go to our server and let everybody else stay with Gmail. That way I can not worry about losing my mind and tossing myself our a window!</p>

<p>Please Google, stop trying to outsmart us. You suck at it.<br />
<span style="color: #0000FF;">&lt;/evil_rant&gt;</span></p>]]>
    </content>
</entry>

<entry>
    <title>What I&apos;ve been up to</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/general/what_ive_been_up_to.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.224</id>
    
    <published>2008-09-06T03:03:58Z</published>
    <updated>2008-09-06T03:22:55Z</updated>
    
    <summary>Just some stuff going on in my life.</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="General" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>Just a general post, nothing special about it.</p>]]>
        <![CDATA[<p><strong>Subway</strong></p>

<p>So I still do some odd-jobs for my previous employer, since I'm still the best tech guy he knows and likely the best in CT when it comes to Subway stuff. His stores are still the most high-tech Subway restaurants in CT because of the stuff I did while there.</p>

<p>In the middle of the lunch rush yesterday, one of the store's cash registers went down completely. Claimed it could not detect the chipset heatsink and thus would not startup. Upon opening it, one of the little loops that holds the integrated graphics chip heatsink down had snapped off.</p>

<p>And worse, it wasn't in the case. Still trying to figure out how it left the case, but we may never know.</p>

<p><em>Brief interlude</em>: This computer is a Dell. I have a challenge for Dell. Can you please make a computer that does not suck with every ounce of it's existence? Is that so much to ask? We have two Dell registers, both needed their motherboards replaced, and now this one will a second time. Brilliant, way to set the bar low Dell. It takes real talent to suck that hard.</p>

<p>So the problem was not that the heatsink didn't exist, it was that the board could not detect it. I concluded that since the entire hook mechanism was metal, the board must be sending an electrical current through to make sure the heatsink was there. So after trying many different types of material, a stripped-clean piece of 14-gauge speaker cable did the trick to fit in the tiny holes in the motherboard. But that didn't do it. So I tried putting pressure on the heatsink as well, and presto! The computer would boot. To experiment, I removed the speaker cable yet kept pressure and the computer would not boot. I was able to conclude that the motherboard was using a combination of a pressure sensor and current sensor. So I shoved a folded-over piece of cardboard between the heatsink and the hard drive, and the computer works - although it's fragile.</p>

<p>So I called Dell to begin the process of getting a new motherboard. Turns out, the system is out of warranty. I was told they would not simply sell me a motherboard, I had to have some sort of service contract. But in order to get a service contract, the computer had to undergo an inspection - which it would fail. Thus, Dell is completely useless. We found the same motherboard from a third-party and I'll install it when it arrives. In the meantime, we have a computer that is functional only thanks to cardboard and a piece of speaker cable.</p>

<p><strong>REAL</strong></p>

<p>Not much I can say here, since I'm still employed with REAL. But I did just complete a miniature logic processor for something special we're cooking up - not something I really wanted to do, but there was no better way. I'm a bit proud of it though. And no, I did not base my code on <a href="http://www.elfdata.com/angellogic/index.html">AngelLogic</a> - sorry Theo, I just don't care.</p>]]>
    </content>
</entry>

<entry>
    <title>HIToolbar 1.1.3 Released</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/announcements/hitoolbar_113_released.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.222</id>
    
    <published>2008-08-23T05:50:19Z</published>
    <updated>2008-08-23T06:06:43Z</updated>
    
    <summary>HIToolbar has been updated for REALbasic 2008r3; Looking forward at the future of HIToolbar.</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="Announcements" />
    
        <category term="HIToolbar" />
    
        <category term="REALbasic" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>Even though I should be working on getting two other projects made public, I thought I would update HIToolbar first. Since it broke on REALbasic 2008r3, it made sense that this one should get more attention.</p>]]>
        <![CDATA[<p>This release is merely a maintenance release to keep the code up-to-date.</p>

<p>But this is also the first release in my steps towards making everything more &quot;open&quot; and to that end, you'll notice that the updated HIToolbar page contains the URL for the source control. The download is also nothing more than an export of the same url.</p>

<p>As such, the demo project is included but the app is not built. The documentation is included, but as the original RTF instead of a PDF. And the structure is a little different inside too.</p>

<p>Looking forward, HIToolbar has two potential issues in the future.</p>

<p>First, the required PNGUtilities plugin has been deprecated. This means I should find a new way to convert an RB picture object into a MemoryBlock containing the PNG data. I never liked requiring a plugin anyway. I'm proactively working on this.</p>

<p>Second... Cocoa. This project will need to be updated significantly to support Cocoa. In fact, even the name will be completely wrong as the Cocoa version is <em>NS</em>Toolbar. They are slightly different, but largely similar. This is why my search field is Mac OS X Search Field and not HISearchField - I planned better!</p>

<p>HIToolbar will likely still run in Cocoa projects, but could also fail miserably. Luckily, since I have early access to REALbasic releases, I may be able to have the showstopper bugs worked out before Cocoa is ready for the public. No promises though. It will still be a Carbon toolbar in a Cocoa window... really silly... but it'd at least not break your code. That'll give me enough time to re-work the code so it uses HIToolbar on Carbon and NSToolbar on Cocoa if necessary.</p>]]>
    </content>
</entry>

<entry>
    <title>Determining if a window should be highlighted</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/realbasic/determining_if_a_window_should.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.221</id>
    
    <published>2008-08-01T14:29:41Z</published>
    <updated>2008-08-01T14:46:50Z</updated>
    
    <summary>Quick and easy way to determine if you should draw your controls in the foreground or background.</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="Mac OS X" />
    
        <category term="REALbasic" />
    
        <category term="Tutorials" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>I've been working on a window designed to look similar to Safari. This means a window with a "Unified" toolbar and tabs that blend into said toolbar.</p>]]>
        <![CDATA[<p>The issue I have been having though is when sheets are involved. If you bring up the "Report Bug" sheet in Safari, you will notice that the window stays "active" - it's still drawn like it's in the foreground. So I used the code I posted earlier to determine if the window had a sheet attached, and drew the tabs active in that case.</p>

<p>But wait, it's not that simple. What if the window has a sheet attached, but the sheet is not the foreground window? This was becoming complicated.</p>

<p>That is, until I found the IsWindowHilited() Carbon function. This function, very simply, gives you a boolean stating wether or not to draw your controls in the foreground or background. Enjoy</p>

<pre class="rbcode"><?php echo FormatRBCode("Function IsHighlighted(Extends w As Window) As Boolean
  #if TargetMacOS
    soft declare function IsWindowHilited lib \"Carbon.framework\" (window As WindowPtr) as boolean
    return IsWindowHilited(w)
  #else
    return false
  #endif
End Function
"); ?></pre>]]>
    </content>
</entry>

<entry>
    <title>Does a window have a sheet?</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/realbasic/does_a_window_have_a_sheet.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.220</id>
    
    <published>2008-08-01T06:44:30Z</published>
    <updated>2008-08-01T06:54:13Z</updated>
    
    <summary>A more complete Window.HasSheet method.</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="Mac OS X" />
    
        <category term="REALbasic" />
    
        <category term="Tutorials" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>So Norman Palardy recently posted some code for detecting if a window has a sheet attached. Charles Yeomans took this code and modified it to work without subclassing window.</p>

<p>I take it one step further, and fix a bug...</p>]]>
        <![CDATA[<p>See, when I tried to use the code, I quickly ran into an issue: MessageDialog. When showing a MessageDialog as a sheet, the current code returns false. That's because the code loops through the REALbasic windows until it finds a sheet window, then asks for the parent of that sheet, and compares the result of that to the window passed to it. But MessageDialog is not a subclass of Window.</p>

<p>So we need to delve deeper into the Carbon API.</p>

<p>When a sheet window is created, a Window Group is created as well and the sheet is then grouped with the parent window. This is how the two stay &quot;linked&quot; together. We'll exploit that.</p>

<p>First, we find the group of the window in question. Then, we loop through all the windows using declares until we find one that is in the same window group and is a sheet. This is done completely using declares, which is good, because it'll work for both window-based sheets and MessageDialog sheets.</p>

<p>There isn't an excellent amount of error checking, but then again, the API does leave a lot of room for something to go wrong.</p>

<pre class="rbcode"><?php echo FormatRBCode("Function HasSheet(extends w as Window) As Boolean
  #if targetMacOS
    const framework = \"Carbon.framework\"
    const kSheetWindowClass = 11
    
    soft declare function GetWindowList lib framework () as integer
    soft declare function GetNextWindow lib framework (window as integer) as integer
    soft declare function GetWindowClass lib framework (window as integer, byref outclass as integer) as integer
    soft declare function GetWindowGroup lib framework (window as integer) as integer
    
    dim windGroup as integer = GetWindowGroup(w.handle)
    dim nextWind as integer = GetWindowList()
    dim windClass as integer
    
    while nextWind <> 0
      if GetWindowGroup(nextWind) = windGroup then
        if GetWindowClass(nextwind,windclass) <> 0 then
          return false
        end
        if windclass = kSheetWindowClass then
          return true
        end
      end
      nextWind = GetNextWindow(nextWind)
    wend
    
    return false
  #else
    return false
  #endif
End Function"); ?></pre>]]>
    </content>
</entry>

<entry>
    <title>The ZAZ&apos;s Open Source Roadmap</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/announcements/the_zazs_open_source_roadmap.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.219</id>
    
    <published>2008-07-28T05:42:42Z</published>
    <updated>2008-07-28T06:01:10Z</updated>
    
    <summary>Plans for improving my open source offerings.</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="Announcements" />
    
        <category term="General" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>I've got a brand new open source project coming up. In fact, the code is already complete and in use, I'm just working on the documentation... and this one will have significant documentation. I imagine that nearly every REALbasic project will want this code included.</p>]]>
        <![CDATA[<p>But why am I writing this, you ask? (or maybe you didn't.)</p>

<p>Because this project will be handled a little differently, hopefully for the better. First of all, the project is fully under version control and you will have public read-only access to the repository. It is my plan to move all my projects into this as well. This means you will have access to bleeding-edge code (if you so dare), even access to separate branches and new projects before they are announced or ready. The repository will not contain documentation. You will be welcome to poke around however you wish, but it will be a use-at-your-own risk feature. I will still be making ready-to-use distributions available as well, just like I do now. The only difference is the distribution will contain the project in RB's version control format, rather than binary format.</p>

<p>I'm also going to be using a real issue tracker, integrated with the repository. I will make the URL for this available to the public. The issue tracker requires a user to create an account before submitting tickets - which I do not like. So I will be making it possible to submit tickets without an account through this website. Thankfully, the issue tracker has an API I can make use of for many things.</p>

<p>Lastly, both the subversion repository and the issue tracker will allow multiple users and permissions. As such, I can invite additional developers, should the need arise.</p>

<p>My goal is to make my open source stuff more open source.</p>]]>
    </content>
</entry>

<entry>
    <title>Best. Song. Ever.</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/general/best_song_ever.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.218</id>
    
    <published>2008-07-15T05:06:03Z</published>
    <updated>2008-07-15T05:15:45Z</updated>
    
    <summary>There is a picture - view it.</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="General" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>I'm going to keep this short and simple. View the picture.</p>]]>
        <![CDATA[<div style="float: right; margin-left: 10px; margin-bottom: 10px; width: 100px;"><a href="http://www.thezaz.com/blog/images/portal.png" rel="lightbox[thumbs]" title="Best. Song. Ever."><img src="http://www.thezaz.com/blog/images/portal_thumb.png" style="margin-bottom: 10px;" width="100" height="150" alt="Portal" /></a></div>If you don't quite understand, play more games. If you already consider yourself a gamer and don't get it, get off your crappy Xbox and play <em>real</em> games!

<p>I am in love with the song at the credits. Found a recording online, converted it to an AAC and put some good artwork on it (the artwork is not mine), added the lyrics and presto! Now I can confuse the hell out of anybody that rides in the car with me.</p>]]>
    </content>
</entry>

<entry>
    <title>Relove for the iPhone</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/general/relove_for_the_iphone.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.217</id>
    
    <published>2008-07-11T04:13:51Z</published>
    <updated>2008-07-11T04:17:34Z</updated>
    
    <summary>I used the leaked iPhone 2.0 firmware. It&apos;s like I when I first bought the iPhone over a year ago - I can&apos;t put it down. But this time, I can keep adding features. Some will be better when push...</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="General" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>I used the leaked iPhone 2.0 firmware. It's like I when I first bought the iPhone over a year ago - I can't put it down.</p>

<p>But this time, I can keep adding features. Some will be better when push support comes in September, like AIM and NetNewsWire, but it's pretty damn cool.</p>

<p>My personal favorite new app is Shazam. That's one really cool thing Verizon customers could have over me - but this is here now and free!</p>

<p>OmniFocus is pretty great too, I'm keeping it synched with my desktop. </p>

<p>I'm sure you'll read about this everywhere else, but I felt like saying something here.</p>

<p>:: Sent from my iPhone, BTW ::</p>]]>
        
    </content>
</entry>

<entry>
    <title>Figures...</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/general/figures.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.214</id>
    
    <published>2008-06-19T03:53:30Z</published>
    <updated>2008-06-27T15:14:17Z</updated>
    
    <summary>I&apos;ve been working on an internal tool for REAL Software that is probably my best web app to date. It&apos;s a web 2.0 app, feels like a desktop app, on caliber with some of the .Mac stuff. Really sweet. And...</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="General" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>I've been working on an internal tool for REAL Software that is probably my best web app to date. It's a web 2.0 app, feels like a desktop app, on caliber with some of the .Mac stuff. Really sweet.</p>

<p>And yet, I'll never get to show the world.</p>

<p>Figures.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Tropical Sillyness</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/general/tropical_sillyness.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.213</id>
    
    <published>2008-06-18T04:45:34Z</published>
    <updated>2008-06-19T01:52:15Z</updated>
    
    <summary>When commercial websites have access to private government info, there&apos;s a problem.</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="General" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>So, I stumbled across a trailer I thought I might check out.</p>

<p><a href="http://www.tropicthunder.com">Tropic Thunder</a> - don't bother. Just to view the trailer, the website asks for too much personal information.</p>]]>
        <![CDATA[<p>My problem with this trailer is that it asked for my personal information - first & last names, zip code, and birthday. Seeing as they don't need that information, I decided to fill in some fake info. Real zip code, fake everything else.</p>

<p>Would you know it, <em><strong>they're actually checking government records!</strong></em> When the info was declined, it was suggested that I use past information if I have recently moved and to make sure the info I entered matched my driver's license.</p>

<p>So let me understand this correctly. A <em>commercial</em> movie website has managed to gain the ability to check driver's license info. Sure, our government wouldn't be stupid enough to actually sell the relevant bits of info to the studio - would they? It must be a one-way, verify-only system... right?</p>

<p>I can't know for sure, but this is kind of creepy. If this were a government website, I'd feel a little better about it - but this is for a <strong>commercial</strong> website. They shouldn't have such easy access to this information! If I didn't know better, I'd say this was a phishing attempt (though a really dumb one).</p>

<p>I'm not seeing this movie. I'd do well not to see anything by DreamWorks too, not much good comes from them anyway.</p>]]>
    </content>
</entry>

<entry>
    <title>Source-Controlled Website</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/general/sourcecontrolled_website.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.212</id>
    
    <published>2008-06-15T04:05:07Z</published>
    <updated>2008-06-15T05:05:38Z</updated>
    
    <summary>Keeping your website under version requires a small amount of setup, and allows an easy update path from a &quot;sandbox&quot; site to your live site.</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="General" />
    
        <category term="Tutorials" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>This concept is so simple and easy, I'm amazed I had not yet thought of it. See, I keep a subdomain of this website which I use as a sandbox. I draft new designs or concepts with it. But it's always been a complete pain to bring the sandbox to the live site. I don't want to overwrite too many or the wrong files, and I made the mistake of keeping subdomain files <em>inside</em> my www directory. It's a mess, and I know better now.</p>]]>
        <![CDATA[<p>When I started with REAL Software, they were working towards keeping their website under version control. I finished the job. Their start, while not perfect, was a good start that gave me the idea for the right way to do it.</p>

<p>The way it's setup now is brilliant. Making changes to the website and making them live is insanely easy. I'm going to be setting this up for my personal website. Here's what you'll want to do.</p>

<p>You'll need a couple of things. Most importantly, you need SSH access to your webserver. If you don't have this, you're dead in the water. My host, <a href="https://www.made2own.com/">Made2Own</a>, has cost-effective shared hosting plans (like I'm using now) for around $8-$15 a month. You'll need their developer package which is an additional $5 a month, but the price is excellent and I have been very happy with this host - and believe me, I've been through plenty.</p>

<p>You'll also need a repository. You can technically host it from your webserver, which will have the fastest data transfer times, but I'd recommend using a 3rd-party. Why? Backup. By keeping your repository elsewhere, you have an automatic backup of your website files. Of course, that won't help your databases, but it's one less thing to worry about. I'm likely to use <a href="http://beanstalkapp.com/">Beanstalk</a> myself.</p>

<p>I'm going to be making some assumptions here. This is not a subversion tutorial. There are plenty out there. I also do not know where your repository is kept. So instead, just follow along with the concepts.</p>

<p>You need to first import your current website to the repository. Subversion's import command makes that easy. Make certain you import your website into your trunk because branches are very useful for this concept. After that, you need to do something scary: break your website. We can do this with minimal downtime though. Do <strong>not</strong> simply delete your www dir and do a checkout. That will take your website down for a while. Instead, checkout your trunk to a temp dir, like www_new. Then rename www to www_old and www_new to www. You'll have nearly zero downtime. Test your website and have a blast. If all went well, you can remove www_old.</p>

<p>Now, you can setup a sandbox. If you don't have a sandbox subdomain, create one. Do <strong>not</strong> but the subdomain's contents in the www dir. That would be pointless. If you're using cPanel, delete the dir that cPanel creates for you. Next, do a checkout of the trunk to create the sandbox directory. Bingo, you should have a perfectly mirrored website for your sandbox. Test it out. If you get errors, you probably did something foolish and hard-coded your directory names. If you've ever moved a website before, you'll learn quickly to use an environmental variable such as DOCUMENT_ROOT, or as I do, define your own in the .htaccess file.</p>

<p>Make your changes to sandbox, commit them, then do an update on the www. Bingo, you've just brought changes to your live server.</p>

<p>Now for some advanced tips.</p>

<p>Create an FTP login to only give you access to the sandbox. That way, you can only update the sandbox site. There is no harm in updating the public version, since either copy can commit changes, but it's best to work in this manner.</p>

<p>Use the svn propedit command to ignore your .htaccess file. This file will be completely ignored, so you can have different versions for the sandbox and public sites. Then, you can use a SetEnv command in each .htaccess to make an environmental variable IS_STAGING_SERVER. Your code can then reference this variable and react accordingly.</p>

<p>You can create a third subdomain, call it volatile, and use that for a completely separate branch of development. Maybe you're working on something that will take weeks to do, but you'll want to be able to update your website in the meantime. Creating a branch will allow you to do so, without interrupting the main site. When you're ready, you can merge your branch into the trunk and continue with life.</p>

<p>A word of caution: your .svn directories will be visible to the public. First, if you have not yet done so, turn off directory indexing. This is a generally bad thing. It'll only help a little though. If you have access to your apache config, you can use a <DocumentMatch> directive to block access to those directories. If not, you'll want to use your .htaccess file and use a Rewrite to simply change any URL containing .svn to something else - like your main domain. You want to match more than just URLs ending in .svn, because snoopers can access the files directly.</p>

<p>Lastly, if you're on the Mac and not using <a href="http://www.panic.com/coda/">Coda</a>, get it first. It's the best damn web IDE I've ever used, and the built-in terminal will allow quick publishing.</p>

<p>Now go create havoc on your sandbox! If you cause trouble, you can just use a revert command! There were many concepts explained here, so maybe I'll go into more detail in the future, but here's something to chew on for now.</p>]]>
    </content>
</entry>

<entry>
    <title>Finally, a new day job</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/general/finally_a_new_day_job.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.211</id>
    
    <published>2008-04-16T21:37:25Z</published>
    <updated>2008-04-16T22:03:45Z</updated>
    
    <summary>So after five and a half years with Subway, I have found a new job that&apos;s actually in the industry I have real talent in. Not to say hadn&apos;t done a good job managing over a hundred teenagers, it just...</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="General" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>So after five and a half years with Subway, I have found a new job that's actually in the industry I have real talent in. Not to say hadn't done a good job managing over a hundred teenagers, it just isn't what I want to do. Not to mention it requires me to work about 50 hours a week over 6 days. If I were single and had no friends, it wouldn't be so bad, but considering neither of those are true it really gets to me sometimes.</p>

<p>But no more. I just signed and returned an offer letter.</p>]]>
        <![CDATA[<p>A few weeks ago, I was contacted by a company regarding an opening in their engineering team. I was called before the job was made public, and my initial conversation went very well. I was asked to send over some examples of my work, which I did, and we scheduled a phone interview with one of the existing engineers. That went very well. After about an hour, we hung up our phones and I expected to hear back maybe later that day or the next. Nope, I got a call about ten minutes later - to setup a time to fly me out there.</p>

<p>This was a Thursday, I was at their office on Monday. Talk about short notice. The experience was fantastic, and a lot of fun. I spent the day with them, and since I knew many of their names ahead of time, felt very comfortable.</p>

<p>My return flight was terrible, I literally spent twelve hours returning home, only six of which were actually flying. It was 2:30 when I actually made it back.</p>

<p>I didn't hear anything for a couple days, which worried me. Then I get an email from the lead engineer stating they had decided not to hire me.</p>

<p>What? Really? After all that? Why?</p>

<p>Basically, I don't have any experience with a team development environment which was a source of concern and the main reason they had decided not to hire me. I spent another day pretty depressed, because I was really looking forward to working there. Then, literally as I'm talking to a friend about the entire situation, I get a call from the original person who contacted me. He explained what happened, and brought up the idea of a different position. The new position would work more with the website and such like that, which I have a lot of experience in. It paid a bit less, but still acceptable. This way, they could see how I work and potentially get an engineer position in the future as it becomes available - granted I prove myself. Which I will.</p>

<p>So I talked to a different couple people on Monday. It went well. Well enough that a couple hours later, I was offered the position.</p>

<p>My head is still wrapping around the idea. I love it, but I've been with Subway for so long (and never left a job before) that it almost doesn't seem real. But it is. I have to move. Far away. To a state I'm less than fond of. But Kelly loves the idea and location, so it's not all bad. And the cost of living is cheaper. I'll lose seasons, but that's okay. (<em>note to self: stop using sentence fragments</em>.)</p>

<p>Luckily, I can work remote until after the wedding, then we'll move. That makes life much easier, since we already have everything booked.</p>

<p>My last day with Subway will be May second. I have the weekend to adjust, then I fly out Monday the fifth for my first day on May the sixth. They need me on-site for the first two weeks - which won't be ideal as I have to live out of a hotel with no car for the time. But it'll be okay.</p>

<p>Oh, and the company is REAL Software, makers of the wonderful REALbasic. I figured I'd save that until the end.</p>]]>
    </content>
</entry>

<entry>
    <title>AnimationKit 2.0 Released</title>
    <link rel="alternate" type="text/html" href="http://www.thezaz.com/blog/announcements/animationkit_20_released.php" />
    
    <id>tag:www.thezaz.com,2008:/blog//10.210</id>
    
    <published>2008-03-30T16:50:08Z</published>
    <updated>2008-03-30T16:55:20Z</updated>
    
    <summary>I have finally found some free time, so I decided to release a brand new version of AnimationKit. This new version is significantly changed, and will break existing code. It does, however, include some great new features....</summary>
    <author>
        <name>Thom McGrath</name>
        <uri>http://www.thezaz.com/</uri>
    </author>
    
        <category term="Announcements" />
    
        <category term="REALbasic" />
    
    <content type="html" xml:lang="en" xml:base="http://www.thezaz.com/blog/">
        <![CDATA[<p>I have finally found some free time, so I decided to release a brand new version of AnimationKit. This new version is significantly changed, and will break existing code. It does, however, include some great new features.</p>]]>
        <![CDATA[<p>First of all, the Start and Stop methods are no longer needed - AnimationKit will start and stop itself automatically, saving vital system resources.</p>

<p>But most importantly, there is a completely new class structure. The new AKTask class handles the generic code to describe an animation, while the AKMoveTask is a subclass used to describe a movement. AKMoveTask is the newer version of AnimationTask.</p>

<p>The great new feature is AKFrameTask - an AKTask subclass which allows very simple graphic-based animations. Animations such as progress wheels are now very easy to accomplish.</p>

<p>So <a href="http://www.thezaz.com/opensource/realbasic/animkit/">check it out</a>, though be prepared to update some code.</p>]]>
    </content>
</entry>

</feed> 

