Tuesday, October 21, 2014

My First Mac OS Application

October 21, 2014 8:36 pm

I finished my first Mac OS application. Two screenshots are shown below, I'll be making it available download at the end of the week. This was a test application to see how easy it would be use write a portable application using Firemonkey. The application in question is a specialist tool that allows users to load systems biology models expressed in SBML models and simulate them. It also has some limited steady state functionality. It users libRoadRunner as the backend simulator (libroadrunner.org). Most of the underling UI business code is new but the graphing component is one I resurrected from an old Windows project I had. Took me a week or two to extract the code from the old VCL Delphi application and swap in Firemonkey canvas methods. The biggest issue I had was remembering that Firemonkey now uses single precision values to represent canvas coordinates (VCL uses integer values).

I developed the application first on Windows using XE6. Once it was working on Windows I compiled it for Mac OS. Other than a few very minor issues (eg forgetting to remove Windows in the uses clause) getting it running on the Mac was surprisingly uneventful. It took me about 20 mins to get it working on the Mac, I was impressed. Pserver, which is the conduit for moving a Delphi application to the Mac makes the process child's play. It copies over the relevant files and metadata and creates the bundle on the Mac's hard drive ready to be distributed.

Some gotchas to watch out for:

1. Scroll bars don't show automatically on the Mac in scrollable controls, to make them show up include the following line in your main form OnCreate event:

memo1.AniCalculations.AutoShowing:=false;

where memo1 is the name of a memo control.

2. Use the Deployment option in the Project menu to specify any Mac OS dylibs you want to distribute. pserver will handle the copying and bundling of these automatically.

3. Loading dll and dylibs. Not really a gotcha but I thought it would be tricky. This was surprisingly easy and in fact no different from Windows.

Obviously the path to the libraries will change because the files extensions are different.

but I need this code to deal with any errors in the loading:

{$IFDEF POSIX} errStr := string(dlerror()); {$ELSE}
errStr := SysErrorMessage(Winapi.Windows.GetLastError);
{\$ENDIF}

Use of GetProcAddress is identical in Windows and Mac OS.

4. I couldn't find the equivalent of GetDeviceCaps on the Mac so assumed the same size for the Mac and Windows.

5. I didn't realize the current version of Delphi (even XE7) generates 32-bit Mac OS binaries which means it can't load any 64-bit libraries. This posed a bit of a problem initially as we only distribute libRoadRunner as a 64 bit library and the current guardian of libRoadrunner was unable to create a 32-bit version. Luckily one of my other students, (Kyle Medley) was savvy enough to compile a 32-bit version which saved the day.

6. Bugs in XE6:

a) Don't use a separate stylebook for each form because closing and freeing a second form will corrupt the buttons or other visual element on the calling form.

b) TextHeight returns incorrect an value for an empty string

7. The Firemonkey TStringGrid is severely limited or at least it seems that way. It's currently a poor cousin of this VCL partner. Not sure how to get round its limitations yet.

8. The trackar is a limited control, there is no way to alter the thumb size or shape, track width, etc.

9. Various visual artifacts on some of the styles, eg Auric has problems with thumbs in tack bars.

10. The online documentation on menu handling between Mac OS and Windows appears to be completely incorrect.

Screenshots from a Mac Pro: