Wednesday, April 30, 2008

Tackling a Desktop / GUI Project? Consider MrEd

I've just about finished my first MrEd based app for one of my customer's, and I have to say, the experience has been quite positive. I haven't done a whole lot of desktop apps, and so I didn't have a lot go on when I chose MrEd (just some VB, Swing and TclTk experience). It turns out PLT Scheme and MrEd were a good choice.

Here are a few reasons why:

  • MrEd produces lightweight, stand alone, executables. This, after all, is the end game and MrEd nails this. The last thing you want to do is write some software and then have to tell your client they need to download a 800Meg runtime library.
  • MrEd's GUI framework is simple. Yes, there's a learning curve with respect to the object model, and even with the OO framework that drives it. But compared to say Swing, GUI programming is a breeze. In less than the amount of time it takes to understand how to use GridBagLayout works you can master the entire GUI API.
  • It's Scheme, so it's extensible and scalable. With my limited experience with doing GUI programming (for example, a few years ago I worked on a hefty sized swing app - it was called AdMinder, right?), I've found that the layout and GUI code in general can grow to be quite hard to manage. With Java, we resorted to code generation, and just dealing with large files of code. With Scheme, I know I can always write macros which will do the code generation for me. Also, I can take advantage of concepts like mixins that also allow for code generation on the fly.
  • There's a real application you can always look at the source of. DrScheme, a feature complete Scheme IDE is written on top of MrEd. This means that you can always grep through some source to see how a particular concept is implemented. It also means that MrEd's framework is grounded in real needs, and not just the hypothetical-we-better-include-it-just-in-case philosophy.

MrEd isn't without some drawbacks. The most significant one is that the GUI isn't easily stylized. You can make some tweaks, like changing the font used in a label, but setting the background color, or getting access to the latest and greatest widget set Windows isn't possible.

For the particular application I worked on, the benefits identified above outweighed the need to have the most customizable GUI. For example, I know that a VB app would have given me access to a pretty looking UI, but the code wouldn't have scaled as well, and who the heck knows how I would do multi-threading or web scraping in a sane way.

Tuesday, April 29, 2008

Apr 29th - Free Cone Day

Thanks to Elizabeth for pointing this one out -- today is Free Cone Day at Ben & Jerry's.

Given my love of all things desert related, I feel like it's my responsibility to spread this good news.

Some ramblings about some movies

This last weekend, we watched Radio and Eternal Sunshine of the Spotless Mind. Both turned out to be good movies and one's that I'd recommend. Why? Well, I'm glad you asked...

Radio was one of these films that I'm glad I saw, but wasn't particularly easy or fun to watch. I think it's an example of Hollywood using their power to tell an important and non-flash story. Like the coach said in the movie - "life is about priorities," and this film is a reminder that people should be at the top of the list.

Eternal Sunshine of the Spotless Mind is also a film that wasn't particularly easy to watch. Instead of being about a difficult subject matter, it's trickiness lies in that fact that you have to sort out a mixed up time sequence and dream versus reality. But, as romantic comedies go, it was so refreshing not to see another variation of When Harry Met Sally (not that there's anything remotely wrong with WHMS).

I'm not even sure yet that what I took away from the film was even intended -- but I'm not sure I care. It was thought provoking, which was good enough for me.

So, they were both decent movies. Movies that weren't just Hollywood fluff (well, Radio is a bit of fluff - but give 'em a break, it's a tough story to tell). I'd give them an 8/10 or something like that.

A Real Milestone

Sure, turning 32 is a milestone and all. But if you want to talk milestones, this is a milestone.

Wow, 52 blog posts and 10 months of time. So very impressive. I'm all for reading SICP, but even I think this is going above and beyond.

And here, I get all excited about finishing a single exercise.

Congrats Eli!

Artist Of The Day: Jill Johnson

Tell me you're not just a little bit curious what a Swedish country music star (as in Nashville, not the country of Sweden) sounds like. Well, if you are, you should check out Jill Johnson.

I'm totally not making this up. Thanks to one of my favorite country music stations, I heard this somewhat odd song, and it triggered a search on YouTube to investigate. And I found Ms. Johnson.

Here's a selection of her work from YouTube. Say what you want about some of her music, she certainly has quite a range. Though I put this more in the can't-turn-away-from-this-train-wreck type of video than high quality country music.

Perhaps not quite as impressive as Dolly Parton, here she is singing Jolene:

And here she is belting out Angel Of The Morning. If nothing else you have to watch the Swedish intro.

Could this be a Swidish country music song. Maybe? My guess is it's about pickup trucks and beer.

See, she really does sing country music:

Now this video here really pushes the envelope. Talk about advanced technology, nothing like integrating low quality computer graphics and country music. We need more of this. A lot more.

Monday, April 28, 2008

A Birthday Lunch

Warning - I've posted this message from my cell phone too, though it never came through. So, sorry in advance for the double post if it comes in and I don't see it.

What a fantastic birthday lunch. Shira arranged to have a bunch of folks get me away from the computer and into society for the day. On the down side, I had to wear something other than PJs. But on the upside, I got to interact with real live people. And eat good food. And get birthday wishes.

Thanks Guys!

Verizon - to complain or not complain?

Last night, after Passover, I went to go online and check my e-mail. No
dice, our Fios was down. So I called tech support. After 20 minutes on
hold, a nice rep helped me debug the problem.

After running a test or two, he finally asked me to pick up one of my
landline handsets. Sure enough, it was totally dead.

So, not only was internet down, but so was our home phone.

And when can they come out and fix it? Tuesday morning, at the
earliest. You have to be kidding me, right? No phone or internet for
36 hours, yikes!

The rep told me to call back this morning, and see if they can squeeze
me in sooner, which I'll do.

I'm actually trying to make the most of this situation. With no
internet, that means no distractions. My plan is to stay in my cone of
silence until 9am this morning, when the main library opens. Then I'll
do the e-mail and put out fires thing there. Until then, it's just
quiet programming time, with no YouTube or CNN politics ticker to get in
the way.

I'm also getting a renewed appreciation for my sidekick. I've been able
to respond to mail fairly easily on it, access the gmail mobile version
to look at archived messages (and even view text only PDF docs) and last
night I used the ssh client to fix a server issue for a client.

Who knows, perhaps this no internet thing for a few hours in the morning
is a good thing?

--Ben

Sunday, April 27, 2008

The Birthday Fairy Arrives Early

Tomorrow is my birthday and Shira couldn't resist giving me an early
present.

I now have a 22" monitor hooked up to my laptop, with dual desktops.
Whoo! This rocks. It's gigantic.

The birthday fairy even got one of her wishes too - our internet (and
phone service!) is down and won't be repaired (in theory) until
Tuesday. That means no late hacking session with my new monitor.

Oh well, I'm not complaining...

--Ben

Friday, April 25, 2008

What GoDaddy Gets Right

Today I needed to sort out a DNS oops I made with a client, and decided calling GoDaddy technical support would be the best way to get it taken care of (which, by the way, was right!). Now, I actually have a handful of negative things to say about GoDaddy as a hosting provider, but, one thing they absolutely do nail is offering access to their customer support.

I visited their website, and sure enough, on the home page is the 24/7 phone number:

Also, included with a sign-up e-mails is the number, right below the other pertinent information:

I have to say, I'm impressed. All too often, getting a human on the phone at a web company is nearly impossible - so for them to push their number as much as they do, is just awesome.

Perhaps, just like Zappos wants you to return those shoes, GoDaddy wants you to call them?

Either way, it's good to see them spending money on more than just Super Bowl commercials.

ActionScript Transitions - Scripting Animation Effects

Tonight I had a chance to make use of the Flash ActionScript based Tweening effects - specifically, I used the TransitionManager object.

I have to say, I'm really impressed. Not only is it possible to get impressive looking animation effects via ActionScript, but it's actually not hard to use.

Here's a tiny example that I through together to better understand the API. Who the heck nows if this is good style, but hey, if you find it useful, that's great. You can get the FLA here.

And here's the ActionScript that drives this:

/*
 * A chance to play with ActionScript Transitions. By Ben Simon.
 * http://benjisimon.blogspot.com/
 */
stop();
import mx.transitions.*;
import mx.transitions.easing.*;

function warp(clip) {
	var mgr= new TransitionManager(clip);
	mgr.startTransition({type:Fade, direction:Transition.OUT, 
						duration: .5, easing:None.easeNone});
	mgr.addEventListener(
		"allTransitionsOutDone",
		{ allTransitionsOutDone: function() { 
			clip._x = Math.round(Math.random() * (Stage.width - clip._width));
			clip._y = Math.round(Math.random() * (Stage.height- clip._height));	
			var mgr= new TransitionManager(clip);
			mgr.startTransition({type:Zoom, direction:Transition.IN, 
								duration: 1, easing:Bounce.easeInOut});
		}});
}

var loader = new MovieClipLoader();
loader.onLoadInit = function(target_mc) { 
	target_mc.onRelease = function() { 
		warp(this);
	}
	warp(target_mc); 
};
loader.loadClip("http://static.flickr.com/6/86690184_ac1e205488_o.gif", target_mc);

Thursday, April 24, 2008

For All You DrScheme Power Users

Today there was a great conversation on the PLT-Scheme mailing list about features that are and are not in DrScheme.

I learned quite a few useful tricks, including one that makes dealing with subversion keywords much more bearable.

If you use DrScheme, it's a must read.

If you don't use DrScheme, it might still be an entertaining read - as it's the usual: program X is nice...but it's not emacs. And here's why...

.

Ahh emacs, the cause of, and solution to, all life's problems. Oh wait, that's beer.

Wednesday, April 23, 2008

A Dose Of Sports PMA

I was looking for some temporary content for a coaching site I'm working on, and stumbled on this collection of sports quotes. Lots of PMA and fun stuff here.

I also needed a YouTube video as a place holder, and so I chose this one by Vince Lombardi. Man, that guy could motivate. He had me ready suit up and take the field.

Note, the following clip is rated R for language - so, this one isn't for your kids.

The Genius Behind RSS

Was working on a site today for an i2x client, and had this thought about RSS:

The genius behind RSS is that all the work of dealing with RSS happens on the client side. This means that writing a client is relatively hard, while developing a new feed is easy. This was a brilliant move, because you want a nice selection of RSS readers, but you want gobs and gobs of feeds for them to consume.

The tricky part of a protocol has to go somewhere - and in the case of RSS - they put it exactly where it belongs.

Just something to think about when you're designing a protocol of some sort - make sure you decide who's doing the heavy lifting, and choose that party carefully.

Tuesday, April 22, 2008

Request - Lost Dog Advice, Please

So, earlier tonight Shira and I were walking through our neighborhood and came across what appeared to be a stray dog. The dog was of the tiny and brown variety (how's that for descriptive?). In fact, it was small enough that even I felt comfortable walking up to it see if it had a collar. It didn't.

For reasons that escape me, I didn't take a snapshot of said pup. D'oh.

Anyway, here's the question - what should we have done?

The dog didn't look at all familiar, and there was no one around to claim him. He had no collar. He seemed a bit spooked when I got sorta close to him to see if he had any ID on him.

Should we have called animal control?

Any suggestions? Use the leave a comment link below to leave your suggestions.

Thanks in advance!

Oh, and if you live in Arlington, and are missing your tiny brown dog...I think I may have seen him or her.

My Brother, The Doctor

A ginourmous mazel tov to my brother David on the defense of his Ph.D.! It's official, I'm now the non-Dr. of the family.

As he put it, this isn't only the completion of years of research and study - but the completion of 29 years of school. Yikes!

Somehow, I just think this joke is just perfect:

The first Jewish president was just elected.

He calls his mother, and tells her that he was elected president of the Unites States.

Her reply was "so".

He tells her that she will have to attend his inauguration.

She tells him I don't have a thing to wear. Don't worry I'll get you a dress.

How will I get there? I will send a limousine for you.

At the inauguration, she was sitting amongst all the dignitaries, as he is being sworn in.

She tells everyone around her, in a loud voice. See that fellow up there being sworn in.

His brother is a Doctor.

Dave, we couldn't be more proud!

Passover Notes 2008 - While they're still fresh in my head...

So, last year, I was a little late in posting my 2007 Passover notes for myself to read. Here's what I want to take away from 2008.

So here goes - remember - this is mostly a note to my 2009 self:

  • Spices - Ben, it's time. It's time expand your Passover spice collection beyond salt, paprika and cinnamon. So, please, make sure you buy some before next year.
  • Don't over complicate the whole matzo Seder plate thing - it's very simple. Despite what you remember from growing up, you don't cover the Seder plate. Just take a plate, put 3 pieces of matzo on it, and cover it. Boom. Done. No need to get fancier than that. Oh, and when you break the middle matzo, make sure you make the bigger piece of the afikoman. For some great reasons why we do this, check out this page.
  • Manischewitz ruffled potato chips were good this year - you probably still only need to buy a single bag worth, but still, they were tasty.
  • Splurge - buy an extra container of herring in wine sauce. Yes, Shira will make a gagging sound when you eat it, get over it. It's tasty stuff and goes well on matzo.
  • You like vanilla yogurt - not plain yogurt. Try to remember this *before* you buy the big tub of the stuff, OK?
  • The International, Glatt Kosher, Hot & Spicy, Beef Frankfurters were actually quite tasty (and spicy, yum!). When looking for hot dogs for the week of Passover, these are a good choice. Don't forget to buy the sauerkraut and chicken-flavored mashed potatoes so you can make Hot Dog Surprise.

Hope your Passover is going well!

Monday, April 21, 2008

Escape From Zurg - A Scheme Solution

I came across this paper, which offers up a fun programming problem. Mainly:

Buzz, Woody, Rex, and Hamm have to escape from Zurg.

They merely have to cross one last bridge before they are free. However, the bridge is fragile and can hold at most two of them at the same time. Moreover, to cross the bridge a flashlight is needed to avoid traps and broken parts.

The problem is that our friends have only one flashlight with one battery that lasts for only 60 minutes (this is not a typo: sixty). The toys need different times to cross the bridge (in either direction):

TOY    TIME
Buzz   5 minutes
Woody 10 minutes
Rex   20 minutes
Hamm  25 minutes
Since there can be only two toys on the bridge at the same time, they cannot cross the bridge all at once. Since they need the flashlight to cross the bridge, whenever two have crossed the bridge, somebody has to go back and bring the flashlight to those toys onthe other side that still have to cross the bridge.

The problem now is: In which order can the four toys cross the bridge in time (thatis, in 60 minutes) to be saved from Zurg?

Here's a solution to the problem in Scheme. Note, it makes use of the very cool amb operator.

;; Inspired by:
;;  http://web.engr.oregonstate.edu/~erwig/papers/Zurg_JFP04.pdf
;;  http://web.engr.oregonstate.edu/~erwig/zurg/
;;
;; amb stuff
;;  http://mitpress.mit.edu/sicp/full-text/sicp/book/node88.html
;;  http://docs.mandragor.org/files/Programming_languages/Scheme/Teach_Yourself_Scheme_in_Fixnum_Days_en/tysch016.htm
;;
(require (planet "amb.scm" ("wmfarr" "amb.plt" 1 0))) 

(define (require x)
  (if (not x)
      (amb)))

(define (pick-one elts)
  (require (> (length elts) 0))
  (amb (car elts) (pick-one (cdr elts))))

;; Setup the rules for the game
(define all-toys '(buzz woody rex hamm))

; How much time does it cost for each toy?
(define (cost who)
  (cond ((assq who '((buzz . 5)
                     (woody . 10)
                     (rex . 20)
                     (hamm . 25))) => cdr)
        (else (error (format "Can't calculate the cost of ~a, unknown type" who)))))


;; The actual solution to the problem.
(define (cross toys clock)
  ;; Cross the toys from left to right.
  (define (cross-left-to-right left-side right-side remaining moves)
    (cond ((null? left-side) (cons remaining (reverse moves)))
          (else
           (let* ((t1 (pick-one left-side))
                  (t2 (pick-one left-side))
                  (time-used  (max (cost t1) (cost t2))))
             (require (not (eq? t1 t2)))
             (require (>= (- remaining time-used) 0))
             (cross-right-to-left (remove t2 (remove t1 left-side))
                                  (append (list t1 t2) right-side)
                                  (- remaining time-used)
                                  (cons (list t1 t2) moves))))))
  ;; Cross the toys the other way around
  (define (cross-right-to-left left-side right-side remaining moves)
    (cond ((null? left-side) (cons remaining (reverse moves)))
          (else
           (let* ((t (pick-one right-side))
                  (time-used (cost t)))
             (require (>=  (- remaining time-used) 0))
             (cross-left-to-right (cons t left-side)
                                  (remove t right-side)
                                  (- remaining time-used)
                                  (cons (list t) moves))))))
  
  ;; Actually kick off the process by sending them from 
  ;; the left side to the right
  (with-amb
   (cross-left-to-right toys '() clock '())))

;; Go!
(cross all-toys 60)

Personally, I find this solution cleaner than both the Haskell and Prolog solution - but that's probably more what I'm comfortable with.

Hmm, I wonder, what's a good way to measure the different solutions?

Friday, April 18, 2008

The Last Piece

To the untrained eye, this appears to be a plate of Nan. But to the to
me, this is way more. Probably the last bit of bread till next Monday
night, when Passover completes.

I'm so savoring this.

If you're celebrating Passover, I hope you have a wonderful first two
days - and enjoyable seders.

Anyone care to share in the comments any specific plans for their seders
(what's on the menu, hiding places for the Afi, etc.)?


--Ben

Mixins - An OO Idea Worth Getting To Know

A while back I commented about how I was impressed the PLT Scheme OO library included a keyword/concept I hadn't heard of before: pubment.

Today, for the first time, I used another concept which I've only seen implemented in PLT Scheme: mixins.

The idea behind a mixin is simple, but unexpected: you write code that has a parameterized superclass. And then, at run time, pass in the super class you'd like your code to use. Or as stated here:

We're taking in a superclass, and "mixing in" a few more methods to create a new class.

While I had seen this feature documented in the manual, it wasn't until I read this recipe that I both Got It and appreciated how I could use this capability to solve real problems.

Even if you don't program in Scheme, it's worth taking a few minutes out and reviewing that recipe. Just like pubment, it's good to remind yourself that there's more to OO than Classes, Interfaces, Methods and Fields.

Perhaps what I like most about mixins is that they have the same play-doh feel that most of Scheme does. Want to, at run time, generate a class dynamically? No problem, easy to do. It's just a whole lot more flexible than the the Java OO world I've spent quite a bit of time in.

Thursday, April 17, 2008

Yet Another Item Done

Passover Hair Cut - Done.

A good chunk of my kitchen is cleaned.

We have shopping done for the holiday.

Only another 100 things to do, and I'll be ready for Passover 2008.


--Ben

Wednesday, April 16, 2008

A Simple match.ss Example

The match.ss pattern matching library is a terrifically powerful library. It not only reduces the pain of having to destructure objects manually (boy, could Java and the whole getXXX() convention use this), but it actually makes your code more readable.

I only have one tiny, itty-bitty problem with it. I always forget the frigging syntax to use it. And to make matters worse the examples section provides some impressive examples - but nothing simple enough to trigger my memory of the more basic usage of (match ...).

I've also found this recipe on the topic, but it's mostly text. So here, as mostly a reminder to myself, are some trivial examples of how to use match.ss.

I plan to thank myself later for this.

;;
;; Plain old list data (an sexpr).  This data
;; describes an HTML form.
;;
(define form-defn
  '((input name "Your Name" 30)
    (input phone "Your Phone" 30)
    (select occupation "Your Job" ("Programmer" "Bit-Pusher" "Developer" "Keyboard Jockey"))
    (submit "Thanks!")))

;;
;; Convert an individual defn row into HTML
;;
(define (defn->html defn)
  (match defn
    (('input name label width)
     (format "~a: <input name='~a' size='~a'/><br/>\n" label name width))
    (('select name label choices)
     (format "~a: <select name='~a'>~a</select><br/>\n" label name 
             (map (lambda (o)
                    (format "<option>~a</option>" o))
                  choices)))
    (('submit label)
     (format "<input type='submit' value='~a'/><br/>\n" label))))

;; use our functions
(for-each display
          (map defn->html form-defn))

And here's the output:

Your Name: <input name='name' size='30'/><br/>
Your Phone: <input name='phone' size='30'/><br/>
Your Job: <select name='occupation'>(<option>Programmer</option> <option>Bit-Pusher</option> <option>Developer</option> <option>Keyboard Jockey</option>)</select><br/>
<input type='submit' value='Thanks!'/><br/>

Tuesday, April 15, 2008

Dear Uncle Sam

Dear Uncle Sam,

Please find my check enclosed for the tax bill you sent me. The amount
seemed a bit high, are you sure you calculated it properly?

Of course you are, you don't make mistakes.

Do me one favor, will you? Please, please, please, don't waste it.

--Ben

The Fast And Free Way To Fill Up Your Mp3 Player

Now that I have plenty of disk space, I wanted a fast and free way to get a whole lot of music on my new Sidekick Slide. Here's how I did it.

Note - this approach is all about quantity over quality. I'm looking for a way to have some tunes with me while on the occasional flight or metro trip - I'm not looking to put together a high quality music library.

  1. Download the latest version of Real Player
  2. Pick some radio stations to be your music source. Here are some stations to try: Groove Salad, Radio Crazy Opera and Radio Country Club
  3. Using the suggestion here, record a couple hours of your preferred radio stations.
  4. Download an mp3 splitting program. My preferred is mp3splt. It zipped through my gigantic mp3 files without breaking a sweat.
  5. Run a series of commands to split up the big recording you've made into smaller, more manageable, chunks:
     cd /cygdrive/c/Users/ben/Videos/RealPlayer Downloads/
     mkdir slices
     mp3splt.exe -t 7.0 -d slices RadioCountryClub6.mp3
    

    In this case, I'm splitting the above file into 7 minute chunks. This is hardly elegant, as it will cut songs off before they are complete. But for my purposes, this should be fine.

  6. Download a program to set mp3 tags. This will allow you to add various bits of information to the files, such as the Genre, or Artists. I used massid3lib to set the genre (Country), artist (Radio Country Club) and album (RCC, Apr 3rd) on 30 files at once.
  7. Copy the split up .mp3 files to your mp3 player
  8. Listen and enjoy!

Ahh....music on my Sidekick Slide...

More Adventures In Creating MrEd Components - The Canvas Panel

I've been on the lookout for the best way to style MrEd components. One suggestion that was made was to mix and match the drawing API (really, a canvas% object) with the other widgets (like buttons and panels). Today, I gave this a shot, and the result is a canvas-panel% - panel% that you can draw on the background of.

Specifically, I used it to draw a colored border around a collection of components.

While the solution isn't perfect - it did demonstrate to me that between the power of the canvas% objects, and the relative ease of creating custom containers. I think this approach may really come in handy for customizing apps.

Before I share the code, I should put in an especially strong disclaimer. This is my first container component, so I have no idea if this is the recommended approach for solving this problem. Or even if this is correct. Or even if this will cause some horrible resource leak that will ruin my application and your day. Use at your own risk.

There, with that out of the way, here's the code:

;;
;; A panel that can hold children, but is also a canvas.
;;
(module canvas-panel mzscheme
 (require (lib "mred.ss" "mred")
          (lib "class.ss")
          "../../lib/list.ss")

 (provide canvas-panel%)

 (define canvas-panel%
   (class panel%
     (inherit get-width get-height get-size)
     (init-field parent (paint-callback (lambda (canvas dc) (void))) (panel-padding '(2 2 2 2)))
     (super-new (parent parent))
    
     ;; Layout our our children. We'll be stacking them
     ;; one on top of another, inside the panel.
     ;;
     ;; Note: the first child in our list is always
     ;; the canvas object which serves as the background.
     (define/override (place-children info width height)
       (let* ((left-margin (fourth panel-padding))
              (current-y (first panel-padding))
              (canvas-info (first info))
              (children-info (rest info)))                  
         (cons
          (list 0 0 width height)
          (map (lambda (min-width min-height horiz-stretch? vert-stretch?)
                 ; x, y, w, h
                 (let ((v (list left-margin
                                current-y
                                (if horiz-stretch?
                                    (- width (* 2 (second panel-padding))
                                    min-width)
                                min-height)))
                   (set! current-y  (+ current-y min-height))
                   v))
               (map first children-info)
               (map second children-info)
               (map third children-info)
               (map fourth children-info)))))
            
     ;; The size of this container. Which is:
     ;;  width: our largest child + the padding use on this panel
     ;;  height: our children's heights added up + the padding
     (define/override (container-size info)
       (let ((children-info (rest info)))
         (values (+ (second panel-padding)
                    (fourth panel-padding)
                    (fold max 0 (map first  children-info)))
                 (+ (first panel-padding)
                    (third panel-padding)
                    (fold + 0 (map second  children-info))))))

     ;; Define our canvas that people can draw on,
     ;; Notice that the parent is this. That's key.
     ;; When asked to layout our children, the first child.
     (define canvas (new canvas%
                         (parent this)
                         (paint-callback paint-callback)))
    
     (define/public (get-canvas)
       canvas)
   )))

To define a new panel% you need to implement two functions: container-size and place-children.

It took me some time to wrap my head around how these methods work. What struck me as odd is that the list of children are passed into these functions. In other words, my component doesn't need to keep track of its list of children. Instead, it just needs to say, given a particular set of children, how to position them and how big the container is.

Once I really processed this - it hit me that this whole layout thing isn't so bad. I just needed to do some simple arithmetic on the information passed into these functions, to implement the exact layout I needed. This let me focus just on the calculation aspect of laying the children out, and not the actual management of the children themselves. Turns out, it's a nice approach.

The other set of dots I connected is how I could get the canvas% object to be laid out under the other components. To make it work, I set the canvas%'s parent as myself. The result: it would be added to my list of children I'd be responsible for laying out, and I'd be given control over it. Not only that, but I'd know it was first in the list (because I added it first) and could do something intelligent with this fact. If you look at the code above, you'll see that when I'm calculating my size or positioning my components, I'm treating the first child specially.

Again, once I put the pieces together, I realized that the component itself wouldn't be hard to write at all.

And here's an example of using the component:

(require "canvas-panel.ss"
        (lib "mred.ss" "mred")
        (lib "class.ss"))

(define f (new frame% (label "CanvasPanelTest") (width 400) (height 400)))
(define c (new canvas-panel%
              (parent f)
              (stretchable-height #f)
              (panel-padding '(10 10 10 10))
              (paint-callback (lambda (canvas dc)
                                (let ((w (send canvas get-width))
                                      (h (send canvas get-height)))
                                  (send dc set-pen (instantiate pen% ("Black" 1 'transparent)))
                                  (send dc set-brush (instantiate brush% ("Blue" 'solid)))
                                  (send dc draw-rectangle 0 0 w h)
                                  (send dc set-pen (instantiate pen% ("Green" 10 'solid)))
                                  (send dc draw-line 0 0 w 0)
                                  (send dc draw-line 0 h w h))))))
(new text-field% (parent c) (label "Name: "))
(new text-field% (parent c) (label "Rank: "))
(new text-field% (parent c) (label "Serial #: "))
(new button% (parent c) (label "Submit"))
(send f show #t)

Monday, April 14, 2008

U2 3D - Up Close And Personal

Shira and I saw U2 3D last night. If you're a U2 fan this is simply a must see. if you haven't heard about it, it's a 3D IMAX of compilation of 7 concerts they did on their Vertigo tour.

The movie brings you into the front row and on stage to be immersed in the show. You get to see the band members sweat and work their butts off to entertain the 10's of thousands of fans in attendance. It's impressive to feel like Bono is playing just for you.

As cool as it was, I have to say that I was a bit surprised between the difference of being at the concert and watching the concert on the screen. As good as the movie was - and the sound was really remarkable - we were definitely watching the spectacle and not part of it.

Still, for $15.00/ticket instead of say $100/ticket, that's a pretty great deal.

Go see it, it's a fun experience.

--Ben

Sunday, April 13, 2008

Free Games For Your 3 Year Old - Kid Tested, Babysitter Approved

This morning, I was hanging out with my 3 year old buddy, Josh, and decided we should spend some time playing with the computer. My first attempt to entertain him was with Tuxpaint. That only went so-so. So, I decided to go for plan B. I asked him what his favorite truck was, hoping to bring up some photos on flickr. Again, that only kept him entertained for a minute or two.

Finally, he told me that his favorite car was Lightning McQueen. A quick Google search found me the free and instantly usable Cars: Lightning McQueen's Desert Dash game.

It took Josh about 30 seconds to figure out how to control the car, and he was in heaven. Home run.

We poked around dan-dare.org and there are other games that Josh found fun, like the Nintendo Super Mario Brother's Game(the original one, implemented as a 2.9meg flash file - how sweet is that?) and others. Though we kept coming back to the race car game.

If you're looking for a source of kids games, you should definitely check the site out. I'm sure that most of them aren't ideal for your 3 year old - so use your judgment (and I don't have kids, so what the heck do I know!). But they are free, and easy to use.

Another activity Josh really enjoyed was watching the space shuttle launch. this video was especially fun as it has the ever-important count down sequence.

Happy game playing!

The Wegmans Touch

Other supermarkets offer Kosher Meat. Wegmans offers Glatt Kosher
Bison.

As usual, they one are one step ahead of the competion.

--Ben

Saturday, April 12, 2008

Disk Space Is Just So Dang Cheap

It boggles my mind that for $11.90 I can buy a 2 gig microSD card for my new Sidekick Slide. And shipping is free. And I didn't even shop around that much - just tried TigerDirect and Amazon (Amazon won out).

That's just so dang cheap.

2 gig - amazing. That's 1,946 photos at the highest resolution.

Time to setup my sidekick as my Linux boot disk / utility toolbox / music player / podcast streamer.

--Ben

Friday, April 11, 2008

The Taste Of Summer

OK, it may not be summer technically - but at 78 degrees, I consider it
close enough.

My plan for the summer: eat myself chilly with ice cream.

--Ben

Passover Prep

We made the yearly visit-the-Koshermart-to-stock-up-for-passover
today. We went on Friday morning instead the usual Sunday before, so
it was less chaotic than usual.

The Koshermart never ceases to amaze me with the Kosher for Passover
products they offer -like Angel food Cake, Gummi Bears, and not just
Pasta Sauce, but *Vodka* Pasta Sauce.

The Kosher Food industry is creative, if nothing else.

--Ben

Finally - The Grad-Shool-Ruled Notebook

Mix my love of fake news with notebooks and you have a winning story:

From The Onion::

RICHMOND, VA—After decades of only offering ruled notebook paper suitable for college-level education and below, school-supply giant Mead introduced its new grad-school-ruled notebook Monday, which features lines twice as narrow as college-ruled paper.

My favorite quote:

"And with the time you'll save by not having to flip a page every 33 lines, you could earn your Ph.D. a year early."

Too bad I only have a Bachelors Degree, so I can't truly appreciate the ramifications of this article.

Passover Notes - What was I thinking?

Back in 2006 I left my 2007 self a handy note as to tips for Passover. I had intended to do the same last year, but never got beyond a rough set of bullets. Here, in fact, is the list I left myself from last year (comments in italics):

- kids hagadah -- Buy some, I guess?
- unpack, then shop -- Now this is sagely advice
- cream cheese and matza -- Is good? Yes, now I remember - is good.
- herring in wine sauce -- Same here
- first night, can fiddle with the times -- Don't know how, better ask Rabbi
- non-jews at a seder -- And this relates to?
- potato chips for day before the first seder  -- Good to know
- maneschweitz yellow cake and carrot cake, very good -- Also good to know
- 3 boxes of Matzo -- Super, I won't buy the 12 pack
- herring good, lox too 
- cream cheese and matzo - very good -- So good, it's on the list twice!
- marshmallows were not good this year -- Well, ya win some, lose some
- whole wheat matzo was good 
- a sealed, year old box of matzo, will still taste good -- Sweet!

I was hoping this list would be useful for the Kosher Mart trip we have planned tomorrow. Perhaps it may be - at least I'll know to pick up some cream cheese!

What Passover tips do you have to share?

Deskshot - My Desk This Afternoon

Here's a snapshot of my "desk" this afternoon. I was inspired by deskshot.com to capture it. The only downside of working at here is that it actually requires me to get dressed. My neighbors aren't ready to see me working outside in my PJs.

You can comment on my deskshot here. And you should definitely upload one of your own - just don't forget to the URL to it in the comments.

Wednesday, April 09, 2008

5 Pleasant Sidekick Slide Surprises

I have to say, I'm enjoying my new Slidekick Slide. I did a bit of research before I got the phone, so I knew what to expect. The screen was going to be great (which it is), the keyboard awful (which it is) - but at the heart of it, the device was a Sidekick and there wasn't going to be a whole heck of a lot of difference between using it and my SK III. And that's basically true - which is a good thing.

But here are 5 pleasant surprises I've had from the Sidekick Slide. If you're not a Sidekick user, they probably won't seem like much. But for those who have come to know, and love the Sidekick, you might appreciate these.

  • They added highly configurable sound profiles:

    While I've always found it easy to switch between, say, vibrate and ringing, I've never quite been able to customize the sound on the device enough. For example, I'd love a mode that I can put the phone into before bed that turns off most sounds, yet will still make noise if SMS messages come in (those pesky servers again, no doubt). I think this has finally been added - not only can you tweak the different existing sound profiles, but you can also schedule them.

  • The default game is no longer Asteroids and is now Bob's Journey To the Center Of The Earth:

    I'm far from a gamer. But even I find there are times when I don't want to blog, respond to e-mail, do IM or some other thoughtful activity. To be able to play an easy and fun game would be handy. Asteroids was neither easy nor fun. Bob's Journey seems like a sort of Nintendo Super Mario Brother's knock off, which is the only game I ever mastered. So it's nice to have a diversion on the phone that I'll actually use.

  • New keyboard shortcuts added:

    One thing I love about the Sidekick is the ability to navigate among apps very, very quickly. They've made this better by adding two new short cuts: the X key and Circle key together, now bring up this "New Messages" dialog box, and the Circle key plus the letter 0, now jumps you to the first unread message. This means that a message can come in, you can check it, regardless of whether it's E-mail, MMS or SMS, and then jump right to it. All with just a few keys. In fact, you can keep hitting Circle + 0 to keep reading new messages. I suppose this is the emacs geek in me coming out with this one.

  • MMS, with Sound Recording has been added:

    I knew MMS was going to be included in the Slide (whoo!), but I was surprised that it so easily allowed you to record audio content. It limits you to 20 seconds of audio. This feature has hack written all over it. I so need to start www.sayitin20.com, a sort of audio version of twitter, where all your postings need to be audio clips of less than 20 seconds. Or maybe veryshortpoetry.com? Like I said, lots of possibilities here.

  • The device can now be charged via USB. This one is probably the nicest surprise of all. No more worrying about leaving the adapter at home, or in the hotel room. I can always replace it with a cheap USB cable. And as a bonus, I don't need to carry around two cables - one for charging and one for data.

Did I miss anything that pleasantly surprised you? Besides the keyboard, what else don't you like about the phone?

Putting The Comments Feed To Use

Thanks to Grant Rettke and Dave Nelson for educating me about the comments feed for my blog. It's an RSS feed that captures the comments people are leaving on articles on the blog.

You can subscribe to these comments by visiting: http://benjisimon.blogspot.com/feeds/comments/full?alt=rss.

I even went one step further and added them to the sidebar on the blog. (Yeah, just look on the right, it's over there, under the i2x news. It looks like:

I did this by creating a Blidget. I have to say, widgetbox does an awesome job of allowing you to easily make these suckers. Just visit this link and drop in the your comment feed URL (or any other feed URL), and you're basically done.

Thanks Dave and Grant for letting me know about this cool feature that's been there all along. And hopefully, the Latest Comments feature will be handy for folks.

Tuesday, April 08, 2008

Need your lawn cut in Arlington? Have I got a guy for you...

Update: You really need to read my latest update on Ray. I'm definitely not saying you shouldn't do business with the guy, I'd just make sure you ask him why he stopped calling me back and be sure you are satisfied with the answer.

Live in the Northern VA area and need your lawn cut? You should consider having Ray Payton, of Payton Lawn Services do it for you. I've started using his lawn service to cut my grass - and today was my first appointment.

I have to say - I was impressed. Ray was knowledgeable, efficient, and did a great job. Best of all, he was easily reachable via e-mail - which was really convenient.

Part of me will definitely miss the challenge of fighting it out with my lawn - but the rest of me will be happy that the job can get done, while I'm busy hacking away.

Tool Of The Day: Internet Speed Test

When I'm playing tech support specialist, I find that among the trickier problems to diagnose are connectivity issues. That's because I can't remote access the machine to see what's going on, in the first place.

To help cope with this - I found this handy utility that among other things, contains a "Troubleshoot" button which goes through a complete set of checks of your connectivity.

While the program's graphics are somewhat crude, the no installation needed -- just double click on the icon to run it approach, more than makes up for those shortcomings. Most importantly, the set of checks it goes through seem fairly complete.

I think it's probably a good idea to be proactive with this tool - get a snapshot of the troubleshooting information before the connection is broken, that way you can see what should and shouldn't be working.

The only suggestion I'd make to make the app better would be to add a big 'ol "Copy To Clipboard" button so that novices can easily get you the diagnostic output.

Still, what do you want for free?

Monday, April 07, 2008

Developing Components For Joomla Version 1.0

Yesterday I had a chance to start poking around Joomla, as one of my customers was moving his site to it. I have to say, I'm impressed. From a development perspective, Joomla is really an extensible framework that offers a clean MVC PHP library, and a CMS with lots of pre-built modules to go with it.

There's only one minor catch - the docs really only appear to cover version 1.5. Which means that, when I needed to build a custom component in a version 1.0 environment there wasn't exactly a clear how to to refer to.

So here are some dev tips I've picked up while trying to work with a 1.0 based system. Hopefully, they can save you some time if you end up in a similar situation.

  • The best example of a 1.0 component I could find was here. The good news is that a 1.0 component is more straightforward to implement than a 1.5 version one. There's no framework to mess with - just create a top level PHP file that will kick off the entire process and name it appropriately. That is, if you have the foo component you'll want to create: foo.php and foo.xml (more about the XML in a second). You can, if you want, put these items in a zip file and use the installer to install them, or just push them via FTP to the directory: [Joomla root]/components/com_foo/.
  • The docs mention it, but it's worth mentioning again: _JEXEC is not defined in version 1.0. If you include:
       defined( '_JEXEC' ) or die( 'Restricted access' );
    
    You'll always get a Restricted access message. You want to start your scripts with:
       defined( '_VALID_MOS' ) or die( 'Restricted access' );
    
  • The variable $task is automagically available to you in your top level script.
  • If you want your component to add custom CSS files to the page, or JavaScript tags in the head component you can do following from anywhere in your code:
       $mainframe->addCustomHeadTag( "<link type='text/css' ...>" );
       ...
    
    $mainframe is another magic variable. Don't forget to use global to get at it from inside a function.
  • To have your component break out of the page structure and return back a different content type, you can do:
      header('Content-Type: text/xml');
      echo "<?xml version='1.0' ?>";
      ... more echo statements...
      exit();
    
    This seems like the wrong way to do this. But, from [Joomla root]/includes/feedcreator.class.php, it appears that's how it's done.
  • I had a bunch of trouble finding the format description of a 1.0 xml package description. Turns out, this page has one. Note that the format is very close to the 1.5 format, but uses the outer tags: <mosinstall type='component'> ...</mosinstall>.
  • I find the 1.0.11 user manual to be relatively helpful. And I found the best source of components to examine to be in the Joomla source tree under /components.

Happy 1.0 Hacking!

Sidekick Slide Blog-A-Photo Test

Do photos get posted like expected?

Man this keyboard is poor. Luckily, the key layout is so familiar, I can still type reasonably fast. But still, the keys are awful.

--Ben

Update:

Passes! Whew, that went better than my audio test. I think the photo quality isn't half bad. Perhaps the fairly bright window wasn't a challenging test subject - but at least it can perform under good conditions.

Test Of The Sidekick Slide audio ability

Wonder if Blogger will handle this audio...

Update: That's a big fat no. The Sidekick Slide has MMS messaging built in, including a way to record 20 seconds of audio. I sent a 10 second audio clip to Blogger hoping it would render it, just like it renders photo attachments. Unfortunately, it did not.

It's probably not that bad that the feature doesn't work - though it would be a cool add on.

My New Toy - The Sidekick Slide

Long story short - Elana won a free Sidekick Slide, and thought I might be interested in it. I've basically worn my SK III out and have been considering a phone switch. So, I jumped at the chance to be a new Sidekick Slide owner.

I did some research so I knew what to expect: a smaller device, with a nicer screen and a worse keyboard. How is it possible to make a device with the best keyboard on the market, and then, every generation of phone you produce, have it be *worse*?

Regardless, I'm going to have an open mind and give it a shot. If the camera and battery life are better, I'll be a happy camper.

Thanks E, you rock!

--Ben

Saturday, April 05, 2008

Dipping A Toe Into Squidoo - My First Lens

I finally gave Squidoo a try tonight. Squidoo, for those who haven't heard of it, is a site where you can create a 1 page website on anything you're passionate about. From Hillary Clinton to Craftsman Pressure Washers, Squidoo hosts it all.

I made my first lens on the topic of having your idea turned into software. No surprise there, right? It's actually a compilation of information that I've found that my clients find helpful. I suppose it's essentially the web version of the i2x infomercial - minus the offer of Ginzu knives. Actually I tried to be a bit more education based than marketing based.

The lens was pretty fun to make. Though, I'm starting to appreciate that I could have made it about a more narrow topic - say questions you should ask the programmer who's building your software. But, for now, this is a good start.

If you feel passionate about a topic, and don't feel like you can support a whole blog on the topic, a Squidoo page may be a good way to go. Give it a try and let me know what lens you create.

Friday, April 04, 2008

Mixed Message

Whoever thought the ideal place for the clearance basket of Easter Eggs
was in front of the Passover Display, apparently missed the last 2000
years of history.

Or, they were trying to make a statement of brotherly love. Brotherly
love that's on sale and must go now.

I couldn't walk by the display without buying something. So, I'm now
good to go for a week, as I have: chocolate covered cashews (yum!),
grape juice, ruffled potato chips and a jar of mayo. Yep, that's the
essentials alright.

Let the holiday prep begin!

--Ben

Field Testing My Big Decision - The Agave 32

No, I didn't buy a new laptop or gadget. I got something even better...

Shira hates to go backpack shopping with me. You'd think I was picking a child to adopt. I spent way more time deciding what pack to buy, than say, if I should marry her. Or buy a house. Or a car. Those are easy decisions.

A backpack, on the other hand, is a tricky decision. You've got to decide: big or small, expensive or cheap, what straps and pockets are must haves and which are annoying. Do I want something that more or less just fits my laptop - or something I can use for traveling and fits my laptop plus two days worth of clothes. Heck, do I even want a back pack - maybe I want a messenger bag (I don't) or one of those funky 1 strap backpacks (yikes, no).

Shira had the solution - we had various discounts at REI, and they were expiring, so we headed to them. And that's where this story really begins - I walked out with a a Jansport Agave 32.

I chose it because it seemed relatively large, but not massive (it's 2000 cu in). I also liked the convenient front zippered pocket, which I guessed would be handy to just chuck stuff in while preparing to go through a security line at the airport, or some other crunched time. It has relatively few straps and specialty pockets, which for me was a good thing. Perhaps most importantly, it has a very durable feel to it.

Tonight was my first field test. I had my laptop, a notebook, and various odds and ends in it - and there was plenty of room to spare. The compression straps worked well to shrink the pack down for this relatively small load, which is what I was hoping for.

The side mesh pockets worked very well for holding my umbrella, which was a plus. The straps and back are quite padded so it was comfortable, too. Though, my load was light, so who knows just how comfy it is.

Bottom line - I have to say, I'm pleased. The bag was a solid performer on its first journey. If you want a good, general purpose bag, I can happily recommend the Jansport Agave 32.

Thursday, April 03, 2008

So Nu, Where's all the fighting?

And now a word from our guest blogger, Greg:

------

We were looking for a fight in downtown DC, and a hockey game broke out.

I just came in hopes of catching a free t-shirt, but Ben was all about the hockey. He was screaming for blood the whole game.

If you need a snack at a capitals game, the soft serve on the 400 level is a tasty value at 5 bucks. I prefer the ice cream of the present, and not nearby dippin dots of the future (when oh when will the delicious future arrive?)

Oh yeah, lets go caps.

------

Thanks Greg.

Note: Opinions specified above do not reflect the opinions of Management. All Rights Reserved. Past performance does not guarantee future performance. Results not typical. Enlarged to show texture. Objects may be larger than they appear. Always wear your seatbelt.

Wednesday, April 02, 2008

CarFreeDiet.com - A Program Arlington Got Right

I've been noticing ads for the Car Free Diet on Arlington buses, and they finally piqued my interest tonight to check out the program's website. I have to say, I'm quite impressed with the campaign they have put together.

Here's what they got right:

  • The bus campaign is, I think, quite cute and clever. It's the whole go green concept, but centered around dieting. The buses have proud individuals bragging about the powerful effects of the diet. Consider: "I lost 2,000 pounds the first day," or "Eat Anything You Want (it's not that kind of diet)." They could have gone bland here, and they didn't.
  • The site's URL is catchy - carfreediet.com. They didn't make it some monstrosity like www.co.arlington.va.us/transportation/carfree
  • The site itself is quite clean and offers some useful interactivity like a calculator, transportation options and a challenge. The site won't win any design awards - but it gets the point across and hopefully didn't cost a fortune to build.
  • They leverage a typepad blog to provide for regular updates to the site and a place to easily publish user stories. Again, this had to be an economical way to go - and one that's effective.
  • They link off to other resources - such as books and YouTube

Like I said, I'm impressed Arlington pulled this off so well. I also think it's a great example of executing a concept on the web in a clean and efficient (and maybe cost effective too?) manner.

Here's a clip about the program:

Me, I'm so inspired I've decided I'm no longer driving to work. Heck, I may just skip the commute and work from bed.

Tips For Running ASP Code On Linux

Yesterday, I worked on an i2x project that involved porting a small ASP application over to a Linux box. Here's some tips I learned along the way:

  • What do you know, you can run ASP on Linux! Who knew? Well, my customer did, or they wouldn't have suggested it. The magic is provided by Chilisoft, a SUN product believe it or not.
  • Chilisoft knows about various VB style objects, so you can say:
     Set conn = Server.CreateObject("ADODB.Connection") 
     Set rs   = Server.CreateObject("ADODB.RecordSet")
     ...
    
  • While Chilisoft supports database access, it does not support MS Access. If you do:
     Set conn = Server.CreateObject("ADODB.Connection") 
     conn.Open Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _
                        & Server.MapPath("foo.mdb")
    
    You'll get an incomprehensible error message - something along the lines of:
    ADODB.Connection (0x800A0BB9)
    Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another.
    Which is just a cryptic way of saying: Dude, you're on a Linux box, you can't run MS Access stuff here. What were you thinking?
  • One way to deal with the fact that Chilisoft doesn't do MS Access is to convert your database to MySQL. Chilisoft gets along just fine with MySQL. To do this, you should not, as I attempted to do, manually export files from Access and try to manually import them into MySQL. Instead, use the near magical migration toolkit, which is provided by MySQL. It will slurp in your MS Access .mdb file and produce a populated MySQL database. It's awesome.
  • To connect to a MySQL database from Chilisoft, you want to use the connection string:
     Set conn = Server.CreateObject("ADODB.Connection")
     conn.Open "Driver={Mysql}; Server=<host>; Database=<db name>; UID=<username>; PWD=<password>"
    
    
  • You can't use the CDO.Message object to send mail in Chilisoft, as the object isn't available. But take heart, the CDONTS.NewMail object is. See this discussion for how to use it. Luckily, it boils down to:
     Dim MyEmail
     Set MyEmail = Server.CreateObject("CDONTS.NewMail")
     MyEmail.Subject = "testing"
     MyEmail.Body = "test message"
     MyEmail.From = "some email address you set up from your own domain" 
     MyEmail.To = "anybody@anydomain.com"
     MyEmail.Send
    

Happy ASP hacking!

Tuesday, April 01, 2008

Spring has sprung in Arlington

It was a perfect Spring Evening, so I dragged Shira on a multi-mile schlep through the neighborhood. I could get used to this kind of weather.

Of course, tomorrow they are calling for temperatures in the 40s. It was fun while it lasted.