Thursday, March 3, 2011

iPad2 the Computer for Everyone

Truth be told, I have envisioned devices like this for years. Back when I was working on the Touch and Gesturing features for Delphi, I had hopes/visions/predictions that Windows 7 would get a makeover and run on devices like this. But nothing ever happened. Backup about 10 years, I wanted to make a "kitchen computer" or "house computer" that could be used by my grandma. At the time though the pressure sensitive touch displays were terrible and huge. That project didn't go very far. Gotta hand it to Apple for going out on a limb and using the capacitive touch display. Not many companies are willing to go out on a limb and build cool stuff. I know it's in Apple's DNA because I have a lot of friends that work there. Calling this an intersection of technology and liberal arts is probably a really good way of putting it. The term "post PC" keeps coming from Apple to describe the iPad 2 which is an aggressive term, but I can't fault them, they've got some good cards and they've played them well. I just got an iPhone now that it's on Verizon. It's a nice device. When it the iPhone 4 was release some equated it to a Leica camera. I have to admit, it does have a Leica like feeling. Pretty crappy antenna though, even on Verizon.

Wednesday, March 2, 2011

Text Placement in a Java JList

This is just for future reference so I don't have to dig around for the answer.

private static final int LIST_LEFT_MARGIN = 5;

jList1.setCellRenderer(new DefaultListCellRenderer() {
  public Component getListCellRendererComponent(JList list, Object value,
    int index, boolean isSelected, boolean cellHasFocus) {
      super.getListCellRendererComponent(list, value,
                                         index, isSelected, cellHasFocus);
      this.setBorder(BorderFactory.createEmptyBorder(0, LIST_LEFT_MARGIN, 0, 0));
      return this;
    }
  }
}

Friday, February 4, 2011

Code

If there has been anything I've learned over the years is "take some pride in your code". You can quote me on that.

Wednesday, January 5, 2011

Delphi Box2D

Last month I was looking at the physics engine Box2D and ran across a Delphi port of it you can find here. Overall it is pretty cool to have the ability to link it right in to your app. One major problem however is performance. The exact same app written in C takes hardly any processor cycles while the Delphi version takes quite a bit more. I don't have any scientific tests or any explanations of the cause, but I look forward to watching this open source project mature!

Friday, December 3, 2010

Review: Garmin Heart Rate Monitor

A few years back I posted about a Nike heart rate monitor here. Well that was over three years ago and I guess all good things must come to an end; the chest strap broke beyond repair and Nike no longer manufactures the unit. So I looked for a new heart rate monitor. I found the Garmin FR60. There is a really good review of it here. I really liked the Nike heart rate monitor. The watch was a bit large but it was really simple and didn't lose the signal from the chest piece. The Garmin on the other hand looses the signal more often than I'd like and then goes back to the main screen which is less than ideal. But at the end of the day the Garmin is the best simple heart rate monitor I could find with user changeable batteries. Plus it's really nice to have while mountain unicycling!

Thursday, December 2, 2010

New Life in Mono Lake


Mono Lake, California

Copyright © 2009 Chris Bensen. All rights reserved.


NASA has found new life in Mono Lake! It isn't like they haven't found new life there before, but this is different. Apparently this bacteria uses arsenic instead of phosphorus for it's DNA.

Mono Lake is one of my favorite places. I took the photo at the top of this post there years ago. It is a stitched from 12 photos in the late fall.

Update: This isn't quite as exciting as the news was leading to believe (big surprise). After reading this article it turns out they put the bacteria in an environment containing high levels of arsenic (which Mono Lake does contain) and reduced the phosphorus and eventually the bacteria substituted arsenic for phosphorus.

Wednesday, December 1, 2010

New Delphi RTL symlink functions

Symbolic links (symlinks) have been around on *nix for some time but only recently introduced to Windows in Vista with CreateSymbolicLink. Windows 2000 had introduced junction points which is half way there by allowing a link to directory, also known as a soft link (if the file moves the link points nowhere) but does not allow a link to a file.

Windows has a few idiosyncrasies that everyone should be made aware of. Here is a link to Microsoft symlink documentation but there are a few key differences between Windows and *nix. Symlinks in *nix are simply a file with a link target. The target file can be either a directory or a file and could actually change. Windows on the other hand has symlinks to files and symlinks to directories. They are different and cannot be interchanged as they can with *nix.

In the Delphi RTL the goal was to do what made the most sense for the developer. In most cases this is treating the symlink as a file but in other cases as a directory. The only real problem comes with POSIX when checking if a DirectoryExists and trying to find out information on the symlink. The following are notes that I made of the changes to the Delphi RTL functions in SysUtils.pas and IOUtils.pas.

IsRelativePath\TDirectory.IsRelativePath (new)

IsRelativePath returns a boolean value that indicates whether the specified
path is a relative path.


FileCreateSymLink\TFile.CreateSymLink (new, Windows Vista and above)

FileCreateSymLink creates a symbolic link. The parameter Link is the name of
the symbolic link created and Target is the string contained in the symbolic
link. On Windows the target directory must exist at the time of calling FileCreateSymLink.


FileGetSymLinkTarget\TFile.GetSymLinkTarget (new, Windows Vista and above)

FileGetSymLinkTarget reads the contents of a symbolic link. The result is
returned in the symbolic link record given by SymLinkRec.

Note: The access rights of symlinks are unpredictable over network drives. It is
therefore not recommended to create symlinks over a network drive. To enable
remote access of symlinks under Windows Vista and Windows 7 use the command:
"fsutil behavior set SymlinkEvaluation R2R:1 R2L:1"


FileGetSymLinkTarget\TFile.GetSymLinkTarget (new, Windows Vista and above) overload that takes a string

FileGetSymLinkTarget returns the target of a symbolic link.


FileAge

FileAge retrieves the date-and-time stamp of the specified file as a
TDateTime. This version supports all valid NTFS date-and-time stamps
and returns a boolean value that indicates whether the specified
file exists. If the specified file is a symlink the function is performed on
the target file. If FollowLink is false then the date-and-time of the
symlink file is returned.


FileExists

FileExists returns a boolean value that indicates whether the specified
file exists. If the specified file is a symlink the function is performed on
the target file. If FollowLink is false then the symlink file is used
regardless if the link is broken.

files

case 1: file.txt FollowLink = true returns true
case 2: file.txt FollowLink = false returns true
case 3: [does not exist] FollowLink = true returns false
case 4: [does not exist] FollowLink = false returns false

symlink to file

case 5: link.txt -> file.txt FollowLink = true returns true
case 6: link.txt -> file.txt FollowLink = false returns true
case 7: link.txt -> [does not exist] FollowLink = true returns false
case 8: link.txt -> [does not exist] FollowLink = false returns true

directories

case 9: dir FollowLink = true returns false
case 10: dir FollowLink = false returns false

symlink to directories

case 11: link -> dir FollowLink = true returns false
case 12: link -> dir FollowLink = false returns true
case 13: link -> [does not exist] FollowLink = true returns false
case 14: link -> [does not exist] FollowLink = false returns true


DirectoryExists

DirectoryExists returns a boolean value that indicates whether the
specified directory exists (and is actually a directory). If the specified
file is a symlink the function is performed on the target file. If FollowLink
is false then the symlink file is used. If the link is broken DirectoryExists
will always return false.

Notes:
On Windows there are directory symlinks and file symlinks. On POSIX a symlink is created
as a file that just happens to point to a directory.

directories

case 1: dir FollowLink = true returns true
case 2: dir FollowLink = false returns true
case 3: [does not exist] FollowLink = true returns false
case 4: [does not exist] FollowLink = false returns false

symlink to directories

case 5: link -> dir FollowLink = true returns true
case 6: link -> dir FollowLink = false returns true
case 7: link -> [does not exist] FollowLink = true returns false
case 8: link -> [does not exist] FollowLink = false returns true

files

case 9: file.txt FollowLink = true returns false
case 10 file.txt FollowLink = false returns false
case 11: link -> file.txt FollowLink = true returns false
case 12: link -> file.txt FollowLink = false returns false
case 13: file -> [does not exist] FollowLink = true returns false
case 14: file -> [does not exist] FollowLink = false returns true


FileGetAttr

FileGetAttr returns the file attributes of the file given by FileName. The
attributes can be examined by AND-ing with the faXXXX constants defined
above. A return value of -1 indicates that an error occurred. If the
specified file is a symlink then the function is performed on the target file.
If FollowLink is false then the symlink file is used.


FileSetAttr (Windows only)

FileSetAttr sets the file attributes of the file given by FileName to the
value given by Attr. The attribute value is formed by OR-ing the
appropriate faXXXX constants. The return value is zero if the function was
successful. Otherwise the return value is a system error code. If the
specified file is a symlink then the function is performed on the target file.
If FollowLink is false then the symlink file is used.

Note: It is suggested to use TFile.SetAttributes because it is cross platform.


DeleteFile

DeleteFile deletes the file given by FileName. The return value is True if
the file was successfully deleted, or False if an error occurred. DeleteFile
can delete a symlinks and symlinks to directories.


RemoveDir

RemoveDir deletes an existing empty directory. The return value is
True if the directory was successfully deleted, or False if an error
occurred. If the given directory is a symlink to a directory then the
symlink is deleted. On Windows the link can be broken and the symlink
can still be verified to be a symlink.


FileIsReadOnly

FileIsReadOnly tests whether a given file is read-only for the current
process and effective user id. If the file does not exist, the
function returns False. (Check FileExists before calling FileIsReadOnly)
This function is platform portable. If the file specified is a symlink
then the function is performed on the target file.


FileSetReadOnly

FileSetReadOnly sets the read only state of a file. The file must
exist and the current effective user id must be the owner of the file.
On Unix systems, FileSetReadOnly attempts to set or remove
all three (user, group, and other) write permissions on the file.
If you want to grant partial permissions (writeable for owner but not
for others), use platform specific functions such as chmod.
The function returns True if the file was successfully modified,
False if there was an error. This function is platform portable. If the
specified file is a symlink then the function is performed on the target
file.


FileSetDate

FileSetDate sets the OS date-and-time stamp of the file given by FileName
to the value given by Age. The DateTimeToFileDate function can be used to
convert a TDateTime value to an OS date-and-time stamp. The return value
is zero if the function was successful. Otherwise the return value is a
system error code. If the specified file is a symlink then the function is
performed on the target file. If FollowLink is false then the symlink file
is used.


RenameFile

RenameFile renames the file given by OldName to the name given by NewName.
The return value is True if the file was successfully renamed, or False if
an error occurred. If the file specified is a symlink then the function is
performed on the symlink.


FileGetDateTime (new)

Returns all file times associated with a file. If the specified file is a
symlink then the function is performed on the target file. If FollowLink is
false then the symlink file is used.


TSearchRec = record (updated)

Added TimeStamp property


TSymLinkRec = record (new)


TDirectory.Exists

Added FollowLink parameter


TDirectory.GetAttributes

Added FollowLink parameter


TPath.GetAttributes

Added FollowLink parameter


TFile.Exists

Added FollowLink parameter


TFile.GetAttributes

Added FollowLink parameter


FileGetDateTime (new)

Returns the TDateTime of the file's creation time, last access time and last write time.


FileGetDateTimeInfo

FileGetDateTimeInfo returns the date-and-time stamp of the specified file
and supports all valid NTFS date-and-time stamps. A boolena value is returned
indicating whether the specified file exists. If the specified file is a
symlink the function is performed on the target file. If FollowLink is false
then the date-and-time of the symlink file is returned.


TDateTimeInfoRec = record

Used by FileGetDateTimeInfo to return the various date times on demand. It is a public record but only consumable.

Tuesday, November 30, 2010

New Property - TBitButton.StylusHotImageIndex

TBitButton.StylusHotImageIndex is a new property in Delphi XE. -1 is the default and it will no longer pulsate. Choose an image index to pulsate to. If you want the old behavior which was a bug then add a blank image to the image list and choose that. Click here for the official documentation.

Thursday, November 18, 2010

RAD Studio XE Examples on Sourceforge

New to XE is all demos on on Sourceforge.

http://sourceforge.net/projects/radstudiodemos/

You can also update any demo to the latest from within the IDE by opening the project and updating using the SVN integration.

Tuesday, November 9, 2010

I Picked up a Panasonic GF1

In a previous post about selling my Canon G10. Since then the Panasonic LX-5, Canon G12, Canon S95 and a few other cameras have been released (and since originally writing this the GF2). I looked at each one very carefully. All three cameras are very similar to their previous generations. The Canon's add 720p video. And it looks pretty darn good. But I still have the same issues as before:

- slow autofocus
- unusable past ISO 200

So in good light you get great photos but in mediocre to terrible light you get terrible photos. For the primary intended use of this camera, family photos, mediocre to terrible light is the norm. I was about to plunk down the cash and buy the Panasonic LX-5 and then I noticed the Panasonic GF1 has a serious price drop. Then it dropped again. So a couple weeks back I went for it and I couldn't be happier! I'll post some photos soon but the autofocus while not on par with an SLR it is really good. The image quality and low ISO while not on par with an SLR is really good too. The video is amazing. And the size of the unit while not a pants pocketable camera it can fit in a jacket or sweatshirt pocket without any problems. I've had small Elph cameras and I have never put them in my jeans pocket so I didn't consider the small size of the S95 much of a benefit. In fact, my large hands had a hard time using the S95 which is another reason I opted for the GF1.

I have a small lens case for an 85mm lens that it fits in quite comfortably. I used the same lens case for the G10. Both cameras are very similar in size except for the protruding lens. I opted for the Panasonic 20mm f/1.7 pancake lens. Someday I'll buy the Panasonic 14mm f/2.5. Probably when I do my next epic outdoor trip this Winder.

For family photos I've been carrying around the Canon 5D with the 50mm f/1.8 but the GF1 + 20mm is much much smaller. For long outdoor trips I have been using the Canon 5D with the 24-105. I think if I get the 14mm I'd be happy to carry the GF1 instead.

I do have a few complaints. The nob on the back is a little hard to rotate. The grip on it seems to be a little to rounded. And for some reason the autorotate of the images is tied to the lens and the 20mm lens doesn't have that feature.

Monday, November 8, 2010

Suggestion Box: Implementing Custom Gestures

"Today I try to implement custom Gesture on my application. I try to create the form that the user can customize Gesture for "Close" action at runtime, I don't know how to do this. Two week before I designed "C" gesture for "Close" action but the user want to design it himself.
Thank you.
-paracet-"


Great question. Go watch Hands-On: Gestures in the VCL by Seppy Bloom. That should answer all the questions you have about creating and using custom gestures in your applications.

Friday, November 5, 2010

TDirect2DCanvas Performance

A question about the performance of TDirect2DCanvas was brought to my attention on Stack Overflow the other day and I decided to answer it. Check it out here. Hopefully this solves some of the mystery around the performance issues of Direct2D. Direct2D really is cool.