REALbasic Developer Magazine
Transcription
REALbasic Developer Magazine
Windows 7 / interview: alex restrepo / report writers / rectcontrol Published by DesignWrite U.S. $16.99 NOV/DEC2009 issue teaching pro g ra mm in g karel: the rb robot by andy dent Going to Colorado: RB Summit 2009 by geoffrey a. rabe making rb plugins by christian schmitz 8.1 2%!,3ERVERISTHEIDEALDATABASEFOR2%!,BASICDEVELOPERSWHOWANTTOCONVERTASINGLEUSERDATABASETOA MULTIUSERONE)TgSFASTHASASMALLFOOTPRINTISHIGHLYRELIABLEANDRUNSON7INDOWS-AC/38AND,INUX 4RY2%!,3ERVERTODAY a"ESTSUPPORT a4OTALLY#ONSISTENT a%ASY)NSTALLATION a3IMPLE0RICING a%ASY-IGRATION a#RYSTAL#LEAR,ICENSING $OYOUFEELTHENEEDFORSPEED &ASTEASYINSTALLATION !TITgSCORE2%!,3ERVERUSES31,ITETHEMOST POPULARDATABASEENGINEINTHEWORLD7HENANEW FASTERRELEASEOF31,ITEBECOMESAVAILABLE2%!, 3ERVERBENEFITS -OSTDATABASESERVERSREQUIREMODIFYINGCONFIGFILES ANDMESSINGWITHTHECOMMANDLINE.OT2%!, 3ERVER*USTDOUBLECLICKTHEINSTALLERANDYOURSERVER WILLBEREADYFORUSEINUNDERONEMINUTE 9OURDATAISSAFEANDSOUND &REETO$EVELOPERS 31,ITEISNEARLYINCORRUPTIBLEANDWEHAVENgTHADA REPORTOFACORRUPTEDDATABASE!NDJUSTINCASE 2%!,3ERVERHASBOTHAJOURNALENGINEANDAUTO MATICBACKUPSYSTEM 4HE2%!,3ERVER$EVELOPER%DITIONISCOMPLETELY FREEANDENABLESYOUTODEVELOPANAPPLICATIONBASED ON2%!,3ERVERWITHOUTPAYINGANYLICENSEFEES UNTILYOUDEPLOYYOURAPPLICATION WWWREALSOFTWARECOMDOWNLOAD NOV/DEC2009 issue 8.1 THE MAGA Z INE F OR REALBA S I C ® U S ER S REALbasic Developer is not affiliated with REAL Software, Inc. FEATURES 13 RB Summit 2009 RB Summit 2009 13 by Geoffrey A. Rabe In September Geoffrey attended the RB Summit in Boulder, Colorado, and he provides us with his report. 19 Interview: Meet Alex Restrepo by Marc Zeedar Alex is famous for creating the impressive CustomEditField—a text editor Interview 19 control built entirely with REALbasic code out of a canvas. 23 Making RB Plugins by Christian Schmitz Have you ever wondered how to make a plugin for REALbasic? Christian adapts his talk from the 2009 RB Summit and provides us with an overview RB Plugins 23 of the process. 30 Karel, the REALbasic Robot by Andy Dent Karel is a virtual robot that has been used for decades to teach programming. Andy created a version of Karel with REALbasic that uses RBScript to program the robot. Karel Robot 30 REALbasic Developer (ISSN 1540-3122) is the ultimate source for tutorials and advanced techniques for programming with the REALbasic language. REALbasic Developer is published bi-monthly (six times per year) by DesignWrite, PO Box 872, Lafayette, OR 97127. Subscription Rate: Annual subscriptions are $49.99 (order at http://www.rbdeveloper.com/subscribe/). Customer Service: For changes of address, go to <http://www.rbdeveloper.com/addresschange.shtml>. For other customer service issues, see <http://www.rbdeveloper.com/support.shtml>. Back Issues: Previous issues may be ordered at <http://www.rbdeveloper.com/orders.shtml>. Printed Issues: Issues printed in full color may be ordered at <http://rbd.magcloud.com/>. November/December 2009 | REALbasic Developer | www.rbdeveloper.com 3 T H E M A G A Z I N E F O R R E A L B A S I C® U S E R S COLUMNS 5 Source Code: A word from the Publisher . . . . . . . . . . . . . . . . . . . . . . . . Marc Zeedar Year Eight begins. 41 Beginner’s Corner: For those getting started . . . . . . . . . . . . . . . . . . . . . Marc Zeedar Part 1 of learning about basic controls, beginning with RectControl, the parent of all other controls. 45 From Scratch: A project from start to finish . . . . . . . . . . . . . . . . . . . . . . . Brad Rhine Starting a new project, ClipSaver. 48 BKeeney Briefs: The REALbasic developer’s life . . . . . . . . . . . . . . . . . . . . . Bob Keeney Exploring database reporting tools. 51 Databases for REAL: Learn to use databases . . . . . . . . . . . . . . . . . . . . . Paul Lefebvre How to use REALbasic’s new built-in reporting tool. News, Reviews, Etc. Advertiser Index Hacker (comic) . . . . . . . . . . . 7 Association of REALbasic Professionals arbp.org . . . . . . . . . . . . . . . . . . . . 55 REALbasic News . . . . . . . . . . 8 ChartDirector Plugin monkeybreadsoftware.de . . . . . . . . . . . . . . . . . . . . . . 32 Windows 7 . . . . . . . . . . . . 10 DynaPDF Plugin monkeybreadsoftware.de . . . . . . . . . . . . . . . . . . . . . . . . . 38 SQLite Migrator . . . . . . . . . . 11 Eat Big While Eating Lean eatingbig.com . . . . . . . . . . . . . . . . . . . . . . . . . 55 Bento 3.0 . . . . . . . . . . . . . 12 Monkeybread Software monkeybreadsoftware.de . . . . . . . . . . . . . . . . . . . . 25 RBDArchive 1-7 rbdeveloper.com . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 REALbasic Developer Magazine rbdeveloper.com . . . . . . . . . . . . . . . . . . . . 56 REAL Software realsoftware.com . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 4 November/December 2009 | REALbasic Developer | www.rbdeveloper.com Source Code by Marc Zeedar publisher@rbdeveloper.com At a Glance RBD#8100 About the Author: When RBD publisher Marc Zeedar was a kid he used to create magazines just for fun. Now he’s doing it for a living! Thoughts from the Publisher Year Eight Begins This issue marks the beginning of a new year of REALbasic Developer magazine. I have no more insight into the future than you, but I’m hoping the new year will bring some fun developments. For instance, there are some interesting technologies in the works in mobile applications and I would love to see a way to create iPhone apps with REALbasic.... Year 7 Printed Book Available If you didn’t pre-order your RBD Archive Volume 7, you can still order it for a 25% percent subscriber discount. The printed books have been ordered and should be Figure 1: Volume 7 of RBD Archive is now available in printed book format. November/December 2009 | REALbasic Developer | www.rbdeveloper.com arriving to me in a week or so and I’ll begin shipping out orders in mid-November. The 338-page book contains the complete contents of Year Seven of the magazine (issues 7.1-7.6) in print form, so it makes a great archive. In This Issue Did you miss the REALbasic conference in Colorado? From all reports, it was a success, though of course much smaller than the much-missed REALWorld in Austin (hopefully that will be back once the economy gets better and more people are able to attend). But in the meantime Geoffrey Rabe attended the Colorado summit and writes about what went on so you can live vicariously through his experiences. At the conference MonkeyBread Software’s Christian Schmitz gave a presentation on creating plugins for REALbasic and he was kind enough to condense his talk into an article for us. You unfortunately can’t use REALbasic itself to create plugins (that is a much-desired feature request), but if you’re curious about the process, this is an excellent overview. One of my favorite custom controls for REALbasic is Alex Restrepo’s CustomEditField, so I was delighted to interview him for this issue. Of course our main feature is on Andy Dent’s rbKarel program: it’s a REALbasic version of the classic Karel robot, which is designed for teaching programming. Students control the robot with a simple language (implemented via RBScript) and learn about logic. Definitely a fascinating project! In our columns, I begin a series on basic controls in REALbasic, while Paul and Bob write about database reporting, and Brad starts a new clipboard manager project in From Scratch. Enjoy! 5 R E A L l e t t e rs o p i n i o n & f e e d b a c k is published by DesignWrite, P.O. Box 872, Lafayette, OR 97127-0872 dragging files to open Did I miss it [in your Beginner’s Corner column in RBD 7.6 covering drag-and-drop] or did you not cover launching an app by dragging a file on top of it? I kept seeing how to accept drops onto controls once the app was launched. I guess, if the app will accept a dropped file on its icon, one would need to check if it were already open and could accept a second (or more) file? Paul I hadn’t thought of explaining that, but it’s easy. But it’s not obvious and should be explained, so here goes. First you go to the AcceptFileTypes property of your App and set the file types your program will support. Then, in your App’s OpenDocument event, you’ll get passed a folderItem pointing to any dropped files (they’ll each drop one at a time, even if multiple are dropped in one go). It is up to you to handle the actual opening of the files, checking to see if they are already opened, etc., but that’s fairly simple. In my apps, each window is a document and has a folderItem property that is that file’s location on disk, so it’s just a matter of looping through all your open document windows and comparing the dropped folderItem to the each window’s folderItem—if they match, the file’s already open, so you can just bring that document to the front (via a window.show command) and you’re all set. More Drag-and-Drop Hi Marc. As usual, I greatly enjoyed your last issue. In particular, my attention was called to a couple of “throw-away” items in your Drag-n-Drop article. I’ve used the Rnd function on many occasions without giving it a second thought since it’s used in Fortran, Visual Basic, and many other languages I’ve used before I became a convert to RBism. I did not realize, however, there was a Random Class. Even though I do read the manuals, I guess I just skipped over it confusing it with the function. The other throw-away was your use of “words” in the code line: dim text() as string = split(replaceLineEndings(words, endOfLine), endOfLine) This was confusing, since I could not see where “words” was defined. I opened your Project file, and lo, I find it’s a text file 6 you’ve apparently dragged into the IDE. I’m wondering what other kinds of goodies I can drag onto the IDE without causing the world to slide into the nearest black hole. And then, what can I do with them? Does this mean I can skip reading files for small bits of information I often store in dictionaries or lists? That would certainly simplify coding, as your line of code illustrates. Harris It might be worth an article (or maybe a sidebar) on the Random class. It didn’t originally exist as part of REALbasic—but they added it and rnd now exists mostly for compatibility with old programs (and other BASICs). As for my use of the imported text file, Words, I should have mentioned that in my explanation. Importing files into your REALbasic project is a terrific way to embed content in your application. (You can either drag them into your project window or use the Import command on the File menu.) You can import text, sound, or picture files. Just remember that the file is not actually embedded in your REALbasic project file—it is only linked to the original. So you still need the original file when you compile (important if you move your project to a different computer). It is embedded in your final app, though, so you don’t need to send that file with your app. Once the file is imported, you can access it by name throughout your REALbasic project. Another tip: if this imported file is something you wish to change periodically, you’ll need to recompile your app to get the change to pass through, so it’s not always ideal. It may seem easier to import a text configuration file into your app than messing with reading in a folderitem—but each time you change the config you’ll need to recompile your app. So you need to decide in advance which method is appropriate for your specific situation. If it’s a file that rarely changes, importing it can be easier. Send your Letters to the Editor to letters@rbdeveloper.com. You must include your full name and valid email address, but we will withhold publishing your name on request. All letters may be edited for content or length, and become the property of REALbasic Developer. and has no affiliation with REAL Software, Inc. Publisher & Editor-in-Chief Marc Zeedar publisher@rbdeveloper.com Editorial Board Joe Strout jstrout@rbdeveloper.com Erick Tejkowski etejkowski@rbdeveloper.com Managing Editor Marc Zeedar editor@rbdeveloper.com News Editor Marc Zeedar news@rbdeveloper.com Reviews Editor Dave Mancuso revieweditor@rbdeveloper.com Copy Editors Toby Rush Scott Griebel trush@rbdeveloper.com sgriebel@rbdeveloper.com Advertising Coordinator Marc Zeedar ads@rbdeveloper.com Webmaster Marc Zeedar webmaster@rbdeveloper.com Layout & Design Marc Zeedar mzeedar@rbdeveloper.com Cover Art Jeff Quan jquan@rbdeveloper.com Artwork Dan Wilson (Hacker, Caricatures) hacker@rbdeveloper.com Columnists Paul Lefebvre plefebvre@rbdeveloper.com Toby Rush trush@rbdeveloper.com Brad Rhine brhine@rbdeveloper.com Bob Keeney bkeeney@rbdeveloper.com REALbasic® is a registered trademark of REAL Software, Inc. It and other trademarks used within this publication are the property of their holders and are used only for editorial purposes with no intent to infringe. REALbasic Developer, the REALbasic Developer logo, and the Arby mascot name and icon are trademarks of DesignWrite. Contents Copyright © 2009 by DesignWrite. All Rights Reserved November/December 2009 | REALbasic Developer | www.rbdeveloper.com How to Download Source Code Article resources available at: http://www.rbdeveloper.com/browse/ The “browse” website gives every RBD article a permanent web page where you can find links to downloads, updates and corrections, and more. Note that downloads include a modification date. Every article in REALbasic Developer includes an “RBD number” at the beginning presented like this: RBD#1234 To retrieve an article’s resources, follow these steps: Step 1: Go to the RBD website (http://www.rbdeveloper.com/browse/). Step 2 (find article by number): In the Get Article search field type in the RBD number of the article you need. Alternate Step 2a (find article by issue): Find the issue you’d like to Browse and click on the link for that issue’s Table of Contents. Alternate Step 2b (download all resources): On an issue’s Table of Contents page, there’s a link to a file which includes all the downloads for a particular issue in one large archive. HACKER by Dan Wilson <hacker@rbdeveloper.com> November/December 2009 | REALbasic Developer | www.rbdeveloper.com 7 REALBASICNEWS e v e n t s & r e RBD#8101 fp Plugin 2.5 Version 2.5 adds the Beta Function, the Incomplete Beta Function, the Error Functions, the Exponential Integral, the Fresnel Integrals, and the Confluent Hypergeometric Function. Using a custom fp multi-precision engine, fp Plugin for REALbasic adds two new data types, BigInteger and BigFloat. Except for available memory, there is no limitation on the size of a BigInteger. BigFloat is a multi-precision floating point number. You can set both the internal precision and the decimal output precision for BigFloat, with no limitation except for available memory. fp Plugin itself allows you to construct programs which can handle the two new data types much like doubles and integers are handled. To a large extent the new data types can be freely used with the +, -, *, and / operators, and can be used in comparisons. And most of REALbasic’s functions have been overloaded to take the new data types, where it makes sense to do so. Also fp Plugin supports the Gamma function and the Bessel functions. Product: fp Plugin 2.5 Platforms: All Product: Monkeybread Software Plugin for REALBasic Platforms: OSX / WIN Price: 200 Euros (complete set); 20 Euros and up (per component) Website: http://www.monkeybreadsoftware.de/realbasic/plugins.shtml Price: Freeware RBScript Open Source Site Website: http://homepage.mac.com/delaneyrm/fpPlugin.html Steve Garman has started a new open source site for RBScript which he hopes will become a center for the sharing of RBScript context classes and useful scripts or snippets. Currently it consists of a single project with a couple of mini-projects inside it. One demonstrates a context that allows access to reading/setting data in ListBoxes and ProgressBars but will later be extended for lots more types of RectControl. The other mini-project showcases a Date class which does many of the things we expect from a RB Date object. MBS Plugins 9.7 The MBS plug-in comprises a collection of several plug-in parts which extend the REALbasic development environment with 1,200 classes featuring over 26,000 documented functions. This release adds two new plugin parts. One to integrate the mobileMe (.mac) features into your application and another one to control the CUPS printing engine on Mac OS X and Linux. 8 This way you can print files on a printer directly. Also we added several new Cocoa classes including a better integration in the future Cocoa REALbasic target. For compressions we not only have the zlib compression engine, but now also the BZip2 engine. The plug-ins require REALbasic 2006r4 or newer. Also required are 500 MB hard disc space and around 64 MB of RAM in addition to the requirements of REALbasic and your operation system itself. While all plug-in parts compile on Mac OS X (universal), Linux, and Windows, each function may depend on additional system requirements to work successfully. Plugin licenses are available for components or for the complete collection. If you buy a current license, you will get free updates for one year. After that year, you can update your license to cover an additional year. The code has been minimally tested on Windows and Linux but not on any Mac platform. Steve is eager for code or scripts to share in the project and asks that you email him about getting your code added as he hasn’t quite decided exactly what checkin access any new members will have to the repository. Currently snippets of script code such as class definitions are currently held in constants mostly because it’s a nice easy place to edit them. He hopes to later have a separate scripts directory where simple text files can be added. He also points out that the project currently uses EditFields and asks that if you check in code not to resolve them to TextFields and TextAreas as he’d like to leave them there for backward compatibility until Cocoa comes out. Product: RBScript Open Source Site Platforms: All Price: Free Website: http://code.google.com/p/rbscriptjottings/ Ramblings on REALbasic Book Aaron Ballman has edited and updated a compilation of over 200 of his best blog entries, including new content that’s never been seen before, into a new book. In it you will find tips and tricks for REALbasic that are not available in any other source. Weighing in at around 550 pages, Ramblings on REALbasic covers topics such as the REALbasic language, design patterns, user experience, and Windows-specific technologies. Product: Book: Ramblings on REALbasic Platforms: All l e a s e s Price: $50 Website: http://ramblings.aaronballman.com/book REALbasic 2009 Release 4 REAL Software, creator of REALbasic, a cross-platform software development tool for Mac, Windows and Linux, has announced the availability of REALbasic and REAL Studio 2009 Release 4. This release offers 97 improvements and 39 new features, including a new report editor, which will be included in all versions of REALbasic, and build automation, a feature exclusive to REAL Studio. The new report editor allows developers to visually create a layout for printing by dragging and dropping labels, fields, images and more. Reports can be created to print a single page or multiple pages. The layout is divided into sections (header, body, footer as well as grouping sections for reports that have sorted data). “Reporting has been the most requested feature from our users and we are pleased to deliver,” commented Geoff Perlman, REAL Software Founder and CEO. “The report editor will allow users to print from any source including text files, arrays, databases, etc. and since the interface is open any database supported by REALbasic can be used.” The new build automation feature of the Project Editor is only available in the REAL Studio Edition. With Build Automation developers can now automate the most common functions of building their applications without having to write IDE scripts. The complete list of improvements and new features in this release can be found in the release notes in the product download section. Product: REALbasic and REAL Studio 2009 Release 4 November/December 2009 | REALbasic Developer | www.rbdeveloper.com REALBASICNEWS Platforms: All Price: $1495 (REAL Studio), $299 (Pro), $99 (Personal for OSX/Win, free for Linux) Website: http://www.realsoftware.com/download Dataflow/Graphical Programming Framework John Balestrieri of Tinrocket, LLC is releasing the first version of a REALbasic framework for creating, editing, and running dataflow programming systems—also known as graphical programming systems. Here’s a screenshot of the framework running in a REALbasic application (http://cargobay.tinrocket.com/Rb/ Dataflow/Media/Screen-shot-2009-0923-at-11.16.49-PM.jpg). This is a similar type of system that’s used in other software packages, such as Apple’s Quartz Composer, Cinema 4D’s Xpresso, and Prograph CPX. The need for this software arose from another project John is working on where he needed to patch together several image processing modules in GUI environment. This seemed like the best solution. Now he can now layout and edit the interconnection of modules. When a node is selected in the editor view, a page-panel reveals the configuration options for that node. He’s releasing this framework hoping that others will find it useful as well. e re-write of code she wrote and released almost seven years ago when new to REALbasic. It’s main purpose was to provide an event that signaled the end of moving the thumb during LiveScroll, something the RB slider does not support. This useful when you wish to give the user some live numeric or visual feedback of the slider’s current value but perform a final action that takes too long to perform while the user is actually moving the slider. This version provides a ChangeFinished event that is called when the Mouse button is released after dragging the thumb. This event should not break any existing code as for a “dead” scroll (LiveScrollChangeFinshed = false), the ValueChanged event is still called normally, and then the event immediately afterwards. That event order ensures the same code would work for both live and “dead” scrolls. This class also supports using the MouseWheel to change the slider value on all platforms (it’s not normally supported on the Mac in the RB Framework). Also now holding the shiftkey down when the arrow key results in PageSteps instead of LineSteps for the delta. The big change with mousewheel support is that the ChangeFinished event will also fire when user stop moving the MouseWheel for a set time period, unless you turn it off. Product: Dataflow Programming Framework Product: UltimateSlider 2.0 Platforms: All Platforms: All Price: Free Price: Free Website: http://cargobay.tinrocket.com/Rb/Dataflow/Dataflow_DR25.zip Website: http://mysite.verizon.net/vzezdg8x/sitebuildercontent/ sitebuilderfiles/UltimateSlider2_RBP.zip UltimateSlider 2.0 Karen Atkocius has released the source for UltimateSlider 2.0. This Slider Subclass is a v PictureEffects 6.7 Einhugur Software has released a breakthrough update to the e n t s & r e PictureEffects plugin, now supporting use of up to 8 CPU cores at once, allowing REALbasic to compete with best speeds of Image processing that is out there. The PictureEffects is a REALbasic plugin to do picture manipulation on 32bit images. The plugin is supported on MacOS Classic, MacOS X, Win32 and Linux target platforms. Main features: Red Eye Reduction, Brightness, Contrast, Sepia, Color Filter, NTSCColorFilter, Hue, Saturation, Lightness, Desaturate, Gamma, Blend, Rotate, Diffuse, Interlace, Flip Horizontal, Flip Vertical, GrayScale, Invert , Sharpen, Smooth, Blur, MotionBlur, Gaussian Blur, Edge Detect, RankOrderFilter, Emboss, Pixelate, Mean Removal, Invert,Contrast Stretch, Equalize, Replace Color, Custom 3x3 matrix filter, Oil Paint, high quality Bilinear Scaling, Stretch, Polar Coordinates, Shape Distort, Barrel Distort, Twirl, Wave, Water Drops, Surface Wave, PageCurl, TrimPicture, Create Chroma masks, Render Clouds, Render Wood, Render Marble, Render Textile, Render Labyrinth, Map, ChannelMixer and a IProgressHandler Interface support for every filter. The PictureEffects also supports masking for most of the effects. The following effects have been accelerated on MacOS X, Windows, and Linux platforms to make use of up to 8 CPU cores: Rotate, Brightness, Contrast, Sephia, Color Filter, Grayscale, Desaturate, Hue, Saturation, Lightness, Invert,Invert,Contrast Stretch, Equalize, Replace Color,Gamma , Blend, Flip Horizontal, Flip Vertical, Sharpen, Smooth, Blur, Edge Detect, Emboss, Interlace, Mean Removal, Custom 3x3 matrix filter, Map, ChannelMixer, TrimPicture, Create Chroma masks, Render Clouds, Render Wood, Render Marble, Render Textile, Render November/December 2009 | REALbasic Developer | www.rbdeveloper.com l e a s e s Labyrinth, Shape Distort, Bilinear Scaling and Stretch. Product: PictureEffects 6.7 Platforms: All Price: $199 (for all plugins), $45 (upgrade) Website: http://www.einhugur.com/ instaplaylist 1.0 Bains Software, a longtime developer of Mac software, is proud to announce the release of their first iPhone app: instaplaylist. instaplaylist is the universal remote for music. It allows users to quickly create a playlist of YouTube music videos from their iPhone or iPod touch and enjoy them on any computer on the same WiFi network. The videos play on the user’s computer while they control playback from their iPhone. Videos continue to play even if the user exits instaplaylist or turns off their iPhone. With a tap of their finger, the user can: Play/pause, Jump to the previous/next video, Add and remove videos, Reorder their playlist, Adjust the volume, and more. No software installation is required. instaplaylist is compatible with any computer (Mac or PC) with a modern browser installed. Minimum requirements: WiFi network, iPhone or iPod touch with OS 2.2.1 or later, and Computer capable of visiting YouTube. Product: instaplaylist 1.0 Platforms: iPhone Price: $0.99 Website: http://www.bainsware.com/instaplaylist/ http://www.itunes.com/app/instaplaylist 9 R E A L R EVIEW S t o o Windows 7 Windows Vista was a decent operating system. Its bad reputation seems to be a lesson to developers: don’t always give users what they want. Vista addressed every note, every gripe, and every bad PR story about Windows XP. It was made to be safe, sleek, and sophisticated. Unfortunately, Microsoft bit off more than it could chew. Vista’s huge development team had grand ideas but little substance to show for it. The new WinFS file system was dropped, as were other major features. The main priority became shipping Vista before software client contracts expired (and not renewed by customers who had run out of patience). Vista became a slow, cumbersome OS whose elegant features were buried under the weight of its overhead. More annoyingly, it infamously asked you for permission to perform (seemingly) every simple little task you tried to perform. Vista, the powerful OS that kept you connected and in control, got in your way. Vista was arguably and unfortunately Microsoft’s black sheep of the Windows family. Enter Windows 7. Microsoft’s main goal for Windows 7 was to lighten the load. It trimmed little used features and whole applications like Windows Mail, Photo Gallery, and Movie Maker. It tightened up every performance feature in the OS, notably all Aero interface features. The goal and mantra for Windows 7 was to make it simple, snappy, and light. Users are supposed to get what they need with a minimum of muss and fuss. In a way, Windows 7 is the first real version of Vista, almost as if Vista were an early beta of what has now shipped on October 22. Windows 7 is available in both 32 bit and 64 bit versions. I opted for the 32 bit version (note that this was the Release Candidate from summer 2009, although the current final shipping version is virtually identical). I installed Windows 7 in a new Parallels virtual machine on my Macintosh. Since I wasn’t running Windows natively, I expected the 10 l s & p l u g Dave Mancuso same slow performance I have with Vista. The installation, however, proceeded cleanly and smoothly. More importantly, it installed more quickly than previous versions of Windows. I’ve read of issues with Windows 7 installs, but I experienced no problems at all, even on my virtual hosted OS. This could be the 4 GB of RAM in my laptop, although my Parallels virtual machine is configured for a recommended 1 GB of RAM. Regardless, so far so good. The 32 bit version of Windows 7 booted in one minute and thirty seconds from a cold start. Reports are that the 64 bit version takes longer. More importantly, Vista’s boot time on my laptop is excruciatingly slow. When it does boot, it’s incredibly sluggish for a few minutes until everything finishes initializing. Windows 7 is ready to use once the desktop appears. Things don’t happen instantly, but they’re noticeably snappy and responsive. The desktop itself is much lighter and cleaner. I felt that Vista’s reputa- for better contrast on my screen. The Personalize settings are new, and the rotating desktops are a nice touch. You can set multiple desktop pictures to change on a timed basis of your choosing. It’s a nice touch, although changing the screen upon each restart would be even nicer. Dragging a window to the side of the screen snaps it to a half screen zoomed window. It’s easy to snap two windows side by side on the screen, a useful feature that’s surprisingly easy to pick up and make a habit. This cannot be understated, especially for Mac users. This is the first time that I’ve used a Windows feature that made me think “Why shouldn’t it be this way? Why didn’t someone think of this before?” It’s a typical Apple move to create a solution to a problem you didn’t know you had, only now it’s in Windows. Windows 7 developers have obviously made a paradigm shift in their user interface design. Shaking a window to hide all other windows is another nice touch. Information about these features tion was in large part undeserved, but its dark, thick look certainly didn’t help. Windows 7’s lighter default theme is a huge improvement. In fact, the first thing I did was to set the window theme to be a but darker can be found easily by exploring the OS, or on the Microsoft website. In each case, features are easy to use and remember, yet valuable for everyday use. i n s IN BRIEF Product Windows 7 Manufacturer Microsoft Price Home Premium $109.99, Professional $149.99, Ultimate $199.99 (OEM versions) Contact Info http://www.microsoft.com/windows/windows-7/ Pros Speed, interface improvements, addresses most Vista annoyances Cons Multiple prices and versions can be confusing, price should be lower Rating (1.0-5.0): 4.2 RBD#8102 November/December 2009 | REALbasic Developer | www.rbdeveloper.com R E A L R EVIEW S IN BRIEF Product SQLite Migrator Manufacturer LogicalVue Software Price $49.95 Contact Info http://www.logicalvue.com/sqlite/sqlite.html Pros Quick, simple, clean, effective Cons None to speak of Rating (1.0-5.0): 4.5 RBD#8104 t o o l s & p SQLite Migrator SQLite Migrator, from LogicalVue Software, is essentially a one-stop shop for conversion of databases into SQLite format. What kinds of databases? SQLite will transform, Access, FoxPro, MySql, Postgresql, MS SQL, and the list goes on. The reason that SQLite Migrator is such a Swiss Army knife kind of tool is that it can connect to any database format that makes use of ODBC for connections. The possibilities for this are very impressive. If a client wants you to remake an old database for them, and the database is in Access, you’re not too far away from a quick magic trick. Convert the database to SQLite with SQLite Migrator and you can start building something in REALbasic right away. This could be very handy when you need something quick. Installing the app is pretty standard on Mac OS and Windows using the standard installers. I installed The Microsoft Windows 7 website deserves a mention as well. Microsoft reportedly spent over 300 million dollars on marketing for Windows 7, and it shows. The seven second demo videos on the site each showcased a nice feature that you could use every day. More importantly, they were quick, funny, and not afraid to have a little fun. Microsoft is trying not to take itself too seriously with its approach, and it’s fairly successful (although spending 300 million dollars to present this persona seems heavily serious on closer examination). It’s the first time I’ve seen some warmth for Windows that comes across as genuine. The applications that come with Windows have been given facelifts as well. WordPad is the most drastically different, with a Ribbon interface a la Office 2007. Even Notepad seems a bit new, and Calculator is new for the first time since Windows 3.1, seemingly. Solitaire is new too. The only application apparently left untouched is the venerable Command Prompt, probably to appease DOS purists. The most important application to run on Windows 7 is arguably REALbasic. I used a demo copy of REALbasic 2009 Release 4. It started smoothly, and compiled a few proj- November/December 2009 | REALbasic Developer | www.rbdeveloper.com u g i n s Dave Mancuso the application on both Mac OS (Snow Leopard) and Windows 7 (where the installation took less than six seconds). The interface is pretty simple, with buttons (and corresponding menu commands) to selects a database source and destination. On OS X, I couldn’t get the Source DB command to open a dialog box, either an issue with Snow Leopard or an issue with my own machine. On Windows 7, the dialog box opened with no problems. Choosing commands was a bit slow but not bad, probably a Windows 7 issue (I’m using the beta). Converting a database took a few steps, but went well. The PDF documentation, found in the SQLite Migrator application folder, is invaluable for running through the process the first time. Note that in Windows this application folder is in the C drive’s Program Files directory. I set up the ODBC data source using the Windows ODBC Administrator ects cleanly. There hasn’t been much in the online communities about Windows 7 and REALbasic, although you may hear more by the time you read this. Things definitely seem to be workable. As a side note, REALbasic looks pretty good running in a Windows 7 themed environment. Windows 7 isn’t without annoyances. As in Vista, it notified me that I was missing antispyware and antivirus software. I checked off Windows Defender for an easy answer, but I installed the open source antivirus software ClamWin instead of my usual AVG. Windows 7 refused to recognize ClamWin even after repeated efforts and multiple restarts. Perhaps I missed something simple, but Windows 7 is all about not fighting the user. It’s also clear that some interface elements are unchanged from older versions of Windows, making workflows clunky at odd times. Frankly though, Windows 7 is a huge change to smoother, more organic interface. The leftovers can be overlooked in the hopes that they’ll be steadily upgraded over the next few years. The one real annoyance with Windows 7 are its versions. Having three versions (Home Premium, Professional, and Ultimate) is better than Vista’s versions, but can’t it be l Control Panel for my test database, and then used SQLite to convert the database to SQLite. The original database was left untouched, always a good thing. The new SQLite database was cleanly made and worked fine. Essentially, that was it. SQLite Migrator worked, and it worked simply, quickly, and accurately. LogicalVue has an online support site, and I noticed a few features targeted for future versions, mostly enhancements in how primary keys, indexes, views, and tables are handled. The developer (Paul Lefebvre) has an active blog and online presence, a key necessity for an application of this nature. The application is priced at $49.95, and in demo mode will convert the first three tables and ten rows of a database. That’s certainly enough to test a few databases for conversion in your own situation. SQLite Migrator promises to be a valuable tool in a developer’s programming arsenal. two versions, or (dare I say it) one? Also, upgrade paths are confusing at best. It’s hard to tell how and if your copy of Windows is upgradeable to Windows 7 (this may be a personal issue, since my Vista launch promo license has no upgrade path whatsoever). If you need a new license, places like Tiger Direct or NewEgg are your most likely sources of new OEM versions of Windows 7 (Home Premium $109.99, Professional $149.99, Ultimate 189.99). Upgrades, if you qualify, are more expensive than the OEM versions: $119.99 for Home Premium, $199.99 for Professional, and $219.99 for Ultimate. These websites, along with Microsoft’s site, have charts detailing the features in each version. It’s clear that I think Windows 7 is a winner. I’ve been a Mac user for twenty years, since System 6. I’ve been a Windows user since Windows 3.0 and DOS 3.3. This is the first time that I can say that Microsoft has an OS that I could use on a daily basis as an alternative to the Mac OS. It’s the biggest upgrade from a usability standpoint since Windows 95. It fulfills the promise that Vista made. Finally, it makes me very interested in what Microsoft does next, and perhaps that’s the most important thing of all. 11 R E A L R EVIEW S t o o Bento 3.0 The story of Bento, FileMaker’s personal database application, is an odd one. The rumor is that it was originally intended to be the database element of the iWork application suite. At some point the database was spun off into its own orbit. The database application (codenamed “Gluon”) became Bento, and FileMaker took custodianship of it. It became an entry level cousin to FileMaker Pro, but it was obviously a very different beast. Bento is a nexus point for iApps, heavily integrated with iPhoto, Address Book, and iCal. It’s designed to become a home for all your data, trying to prove that the whole is greater than the sum of its parts. Bento autosaves like FileMaker Pro, but the reason is completely different. Bento isn’t document-based. It’s library-based. The libraries are displayed in the left panel of Bento’s main window. Each library in Bento could be considered a table in a SQLite database. In fact, the libraries are all stored in a SQLite database hidden in the user’s Library folder (Application Support, Bento). You’d never know this from using the application. Bento is all about the interface, and the interface is all about giving you a turnkey solution. Bento is designed to hide you from the complexities of anything to do with database design, form, or function. Bento has prebuilt templates in a variety of styles. If you want a different style, Bento gives you the ability to change the look of your forms at any time, with a live transition to the new look that’s obviously based on Core Image. It gives you both a Forms view and a table List view, and will give you both in the same window if you’d like. Thus you can have a field list inside a form. Adding a new field to the form (and the Library) displays a dialog box with numbered steps and explanations for each step (Choose a Field Type, Name the Field, and Options). It’s clear that Bento works extremely hard to help the regular user design databases. It’s not completely clear if Bento is flat file or relational. You can relate fields in two different libraries, but 12 l s & p l u g Dave Mancuso FileMaker used to do this with flat file databases and a special “Lookup” field. FileMaker says that Bento is relational, and the SQLite the databases are saved in is relational, but purists on the web differ. What’s clear is that Bento gives you no power user mode to dig into the SQLite parts of the database. A primary or key field can be made implicitly, but there’s no way to control the database as you can do by making your own in REALbasic. In addition, there’s no way to make a database that runs itself without the host Bento application. It seems silly to compare Bento with REALbasic’s database capabilities, but you might look at Bento as a quick way to create a database for yourself. Could Bento be used for some quick purposes instead of taking the time to build a database in REALbasic? In contrast, there’s no comparison. Bento is very good at doing what it does, but what it does is very narrowly focused. REALbasic is wide open in terms of flexibility if you have a bit of time, and it lets you dig into SQLLite all you want. One thing that Bento does nicely is integrate with iPhoto, Address Book, and iCal. You can see data from these applications in Bento Libraries, and manipulate their data from inside the Bento application. Be careful to read the documentation of you do this. In some cases Bento will modify data in these other applications, but not always. Also, things you add to Bento for these other applications will not be added to their data sets. Bento tracks your extra information and uses it as extended fields, but does not modify original data in the other applications. You’ll need to study how Bento uses data from other applications to get a feel for it (and avoid messing things up). Apple’s HyperCard is receding into the past fairly quickly, but one thing that HyperCard has was an active user community that shared files, templates, and ideas very well. The community was a secret killer feature of HyperCard. FileMaker is trying to do something similar with Bento. It’s created a user community for Bento with shared templates. FileMaker has seeded the template exchange with starter files, and slowly the collection is being added to by users. With the release of Bento 3, FileMaker hopes that the application gains critical mass and that the template area expands. Designing and using libraries and templates are, as you might expect, easy to do as long as you don’t need anything outside of the boundaries that Bento has set for you. Even within these rules, you can design new templates that are related to each other, getting much further than you might think. At first glance, Bento seems like a database application that might work in a pinch instead of creating one from scratch in SQL. On further examination, Bento is a tool for certain kinds of things, but by no means for everything. If you need what it does, you’ll do very well with it. FileMaker offers a free trial download to experiment with Bento for thirty days. It’s certainly worth a look, and perhaps a purchase if it meets your needs. i n s IN BRIEF Product Bento 3.0 Manufacturer FileMaker, Inc. Price $49.00 single user, $99.00 five license family pack (web site download) Contact Info http://www.filemaker.com/products/bento/ Pros Prebuilt templates, easy to start using, integration with other Mac OS apps, online community Cons Lack of flexibility, ambiguous relational database capability, lack of SQL support Rating (1.0-5.0): 3.9 RBD#8106 November/December 2009 | REALbasic Developer | www.rbdeveloper.com F e a t u r e by Geoffrey A. Rabe RB Summit 2009 Visiting the Boulder, Colorado Conference At a Glance RBD#8107 Target Reader: Beginner About the Author: Geoffrey began programming on a Radio Shack Color Computer, back in the early-to-mid 80s. When he could finally afford one, he bought a PC clone and VB3-6, but eventually wised up and moved to the Mac platform and REALbasic 2009r3. He’s much happier now! (All photos courtesy of Geoffrey Rabe.) Inspiring Apps, an independent Colorado firm that specializes in writing custom software using REALbasic, and the Association of REALbasic Professionals (ARBP), jointly sponsored a three-day Summit at Inspiring Apps’s offices in Boulder (see Figure 1), September 24-26, the first such REALbasic conference held in Colorado. The Summit began Thursday afternoon with a “meet-and-greet” during which our hosts, Joe Strout and Brad Weber of Inspiring Apps, and ARBP President, Bob Keeney, outlined the sessions to be held the next two days. Following that, we broke for dinner at several nearby restaurants on Pearl Street, a pedestrian mall that runs through downtown Boulder (see Figure 9). On Saturday morning, Bob Keeney (who also writes the BKeeney Briefs column for this magazine) had the first session, “Reporting Tools, Options, and Techniques” (see Figure 2). He mentioned that, at the last REALWorld Conference, there was only one such application to use for reporting, On-Target Reports, and that a good reporting tool was at the top of the list of feature requests received by REAL Software’s Feedback tool. But one year later, there are several, in various stages of development, usability and support (see his column in this issue for more on that topic). He also discussed how making a print-out was one such way of “reporting” that many REALbasic developers use, and the various tools and controls for making print-outs that come with REALbasic. During the next session, we engaged in a live iChat with Geoff Perlman, CEO of REAL Software (see Figure 3). Many of his comments regarded the then-upcoming Release 4 of RB 2009. The transition of the underlying framework for Mac OS X from Carbon to Cocoa was mentioned, but was not going to be ready for R4, nor was an interesting-sounding new control, the Passcode Field, which would allow for built-in password-checking functionality, though they both would be in a future release. Related to Bob’s session, Geoff also showed a demo using the reporting tool now built-in to REALbasic, and as noted earlier, one of the most requested features. He also mentioned moving away from Type and Creator codes, long used by Macs to identify which programs could open which files, beginning with Tiger, to Uniform Type Identifiers, a much more useful way to do this. (A very informative article on Uniform Type Identifiers can be found at http://forums. appleinsider.com/showthread.php?s=&threadid=103219 if you’re interested.) The next several sessions and demos were all centered around databases, an area I’m no expert in, though the comments and discussion of the other participants left me wanting to know more. First up was Ryan Vail, of Inspiring Apps (see Figure 4). His November/December 2009 | REALbasic Developer | www.rbdeveloper.com 13 Figure 1: Taken Thursday, during the “meet-and-greet.” Brad Weber noticed the rainbow out of the window of the Inspiring Apps office and pointed it out to us, commenting on the frequently-changing nature of the weather here on the Front Range. session, “SQLite Power Tools,” provided an introduction to the uses of SQLite, with many examples tied in with the REALSQLdatabase, documentation for which can be found within the Language Reference. Some pros mentioned in association with this are that it’s free (i.e., it comes with RB), it’s cross-platform, and while not for use directly in the IDE, there is a Firefox plug-in available for development in the browser environment; a con that was mentioned was its userinterface. In addition, he went over the command-line client of SQLite3, which comes with the development tools, and provided a demo. He also showed demos for encrypting, backing-up, and attaching databases (e.g., shipping a program to a client with some default information set on a USB drive). Both attaching and detaching a database sounded relatively easy. However, importing an SQLite database to a MySQL database did not sound nearly as simple. The reference Ryan gave for this can be found at http://stackoverflow.com/ questions/18671/ if you’d like more details. However, I discovered another reference online (http://sqlite.phxsoftware.com/forums/p/941/4725. 14 Figure 2: This are from the first session, on Friday (“Reporting Tools, Options, and Techniques”) given by Bob Keeney, Pres. of the ARBP, co-sponsors of the Summit, and frequent contributor to RB Developer. November/December 2009 | REALbasic Developer | www.rbdeveloper.com Figure 3: This is from the second session (“Cocoa and Reporting Features in REALbasic”) which was given by Geoff Perlman, head of REAL Software, via iChat, where he also discussed some of the changes/features of RB2009r4, which is now available. (That’s Joe Strout in the blue shirt in the foreground.) aspx) which was easier for me to understand given my lack of experience with databases. Ryan’s session was followed by a demo, given by Brad Weber, of how even large databases can be imported, encrypted/ decrypted, and zipped, which led to a large discussion on the topic, which — as mentioned above — was beyond my experience. But on the other hand, Seth Verrinder, of BKeeney Software, Inc., led the next session, “OO Database Framework and Introspection,” which was easier for me to follow. Figure 4: This is Ryan Vail of Inspiring Apps, delivering his session on “SQLite Power Tools.” November/December 2009 | REALbasic Developer | www.rbdeveloper.com I want to make a comment here which relates to the Summit specifically and to the REALbasic community in general. As mentioned several times, I don’t have nearly as much experience using RB as the other participants, and in fact I’m more of a hobbyist, while the others were all professional programmers. However, I found the group to be very helpful and patient with my questions and comments. In fact, for a project I’ve been “working” on (more planning than actual programming) I needed a custom control which I’ve tried designing myself with rather unsatisfactory results. However, as a result of my bringing this up with the group, the following day Bob Keeney had an excellent suggestion on a different approach I could take designing the control, and both Christian Schmitz and Joe Strout gave me a control they had whipped up in minutes. So what I’m getting at is that the RB community, from my experience and what I’ve seen online and in the REALbasic Developer magazine, is very open and helpful to both new and experienced programmers, and that these smaller events are well worth attending even if you’re not a full-time developer. (In a similar vein, I found the following quote from a review of REALbasic 5 on MacWorld’s site: Software-Development Application Remains Top in Its Field “When you commit to REALbasic, you become part of an enormous base of smart, dedicated, and friendly users who provide a variety of great resources, from books to message boards.” Now, back to the Summit....) Speaking of Joe, who is a frequent contributor to the RB community in many areas, he had the next session, “Profiling and Performance Tweaking.” Simply speaking, this topic relates to getting the most out of your code and the best performance of your application. One of his first points was on program optimization — “don’t do it yet” — wait until after you’ve profiled your code. How to do this? You can do it manually, using the Pause button at certain points in your application’s run, to check properties, variables, etc. You can also measure the time certain routines take by including profiling code before and after the run, using microseconds. In addition, Joe included some performance pitfalls to watch out for: with databases, minimize the number of queues and cache small look-up tables; avoid unnecessary double-buffering (and be careful — OSX uses double-buffering with all drawing routines); when repeated operations are involved, DIM local variables, as they are always fast; and avoid creating 15 Figure 5: This is Christian Schmitz of Monkeybread Software talking about “Building REALbasic Plugins,” the first session on Saturday. Figure 6: This is Jay Crain of Inspiring Apps talking about and destroying objects and strings when possible. And he also “Usability ¥ Design Techniques,” the second session on mentioned some handy habits: retain objects you’ll need again, Saturday. creating and exporting them; use Split and Join, which are almost always faster than CountFields and NthField; flipping loops around can of it great, but I’ll try to summarize briefly. His introduction to usability began with a comparison of desktop versus web design, sometimes add speed; and use a Dictionary for random look-ups. their shared principles, and he mentioned a renewed focus on The last session on Friday was also one of the most lively ones: usability having grown with the web. A major point he began “Version Control, and Why it Rocks,” by Aaron Gerber and Mathias with is user-centered design, putting the user at the center of Gran. You could tell they were really into their subject from your design strategy. Some principles he shared are as follows: the start as they provided lots of fun comments and examples. designs should be transparent; aesthetics are important, but not Unfortunately, their’s was one of the longer sessions and is beyond everything; and the success of a design can be measured by how the scope of this article. However, they did provide some URLs infrequently the user has to stop and figure out how the program to resources online: you can get the Mac Subversion Client (http:// versionsapp.com/#), the documentation (http://svnbook.red-bean.com/), and the works. He also emphasized consistency: within the user expectamain site for Subversion (http://subversion.tigris.org/). tions; within an app or web site; and between related apps and web sites. Inconsistencies can also be a strength within an app, After Friday’s last session, we were in for quite a treat. Included with the Summit’s ticket price was dinner at Salt, a fairly new restaurant downstairs from and next door to IA’s offices. Our group took over most of the basement seating area, and we could order basically whatever we wanted to eat and drink. However, this was more than just a nice dinner, but a chance to socialize and network with the other members of the Summit, and as such was very worthwhile. It also showed what great hosts we had! The first session on Saturday was “Building REALbasic Plugins,” by Christian Schmitz, well-known for his MonkeyBread Software collection of plugins for REALbasic (see Figure 5). However, again, the summation of this presentation is beyond the scope of this article (he’s written a full article for this magazine based on his presentation). But Christian is very accessible and helpful, via his website (http://www.monkeybreadsoftware.de/) and mailing list (https://www.monkeybreadsoftware.de/ realbasic/mailinglist.shtml). The last formal session was “Usability and Design Techniques,” by Jay Crain, Figure 7: Bob Keeney, discussing the state of REALbasic programmers, and showing Inspiring Apps Designer (see Figure 6). the difference between ARBP members and non-members. He packed quite a lot into his hour, all 16 November/December 2009 | REALbasic Developer | www.rbdeveloper.com Figure 8: Various participants of the Summit. That’s Brad Weber on the laptop, leading the “Facilitated RB/RS/Summit Feedback Session” at the end of the Summit, on Saturday afternoon. as cues to the user that some things are meant to act or to be operated differently. In addition, he says to always allow Undo, to give the user an ‘out,’ and that feedback is key, to let the user know they are in the right place or doing something the right way. All in all, many useful suggestions. After Jay’s session and a lunch break, we all were involved in a feedback session, led by Brad Weber (see Figure 8). This was not only to be about the Summit, though November/December 2009 | REALbasic Developer | www.rbdeveloper.com of course that was key to the people from Inspiring Apps and Bob Keeney (for the ARBP), but we also discussed in general our thoughts on the RB community as a whole. Norman Palardy, unofficial REAL Software representative and frequent pres- 17 Figure 9: After the “meet-and-greet” on Thursday afternoon opening of the Summit, people split into groups for dinner. This is at Old Chicago Pizza. Clockwise around the table, from the left: Monika and Christian Schmitz, Rick Praetzel, Rick Roberts, Fred Roller, and the author, Geoffrey Rabe. Figure 10: Another shot of the participants of the Summit, also showing Ryan Vail (in front with the laptop) and Seth Verrinder, operating the video camera to tape the conference. ence on the RB Forums, answered some questions and comments, and the session was very positive for all involved. As I mentioned, I found the Summit and my interaction with professional members of the RB community to be 18 a very good one, and I look forward to future conferences, here in Boulder, or abroad, if I can make it. And I encourage any RB programmer out there who has a chance to attend such a conference, whether it’s REAL World in Austin, or one of the smaller ones that are beginning to take place around the country, to do so. I think you’ll find it very worthwhile (and a lot of fun!). November/December 2009 | REALbasic Developer | www.rbdeveloper.com Interview by Marc Zeedar Meet Alex Restrepo REALbasic, custom controls, and iPhone apps At a Glance RBD#8108 Target Reader: Beginner About the Interview Subject: Alex Restrepo lives in Colombia and develops educational software, iPhone applications, and uses REALbasic to write custom controls, such as the acclaimed CustomEditField (a line editor written from scratch in pure REALbasic code, no plugins required). His software can be found on his website (http://homepage. mac.com/alexrestrepo/indexmain.html). How did you get into computers and programming? Well, my father used to teach programming to college students in the late 70’s and early 80’s, so I can’t really remember my house without a computer in it. Somewhere in storage my dad has an Apple ][ and it’s the first computer I have memory of. We always had Apple computers in the house. So from a very young age my dad taught me the basics of programming, but it wasn’t until my senior year in high school that I really got into programming and eventually went into Computer Science in college. You’re from Colombia? Yes, born and raised in Colombia. My father taught computers, calculus, and physics in a local university. Are computers, Macs, and iPhones in particular, popular there? For the longest time they weren’t. Unfortunately Macs, and everything Apple (except for maybe the iPhone) was extremely expensive. It wasn’t until the whole iPod success and later the iPhone success that prices became somewhat reasonable (though still much more expensive than PCs). Ten years ago I knew maybe three people who had Macs. Nowadays you can easily spot people using their MacBooks wherever a Wifi hotspot is available. Does living in Colombia give you a different perspective on computing? I think not. The world is now small enough that you have access to everything just about everywhere, especially technology and computing in particular. Everything is on the net. How did you discover RB? Figure 1: Alex Restrepo. In college, all computers were PCs, except maybe for a few workstations here and there, so teachers always expected all assignments to run on PCs, which to me was an insult. So one day — I don’t remember where — I read about RB and how it was going to be able to compile for Windows in a future version. That got me really excited as I could get away from using a PC. I downloaded a demo and was instantly hooked, I loved its Object-Oriented approach and how easy you could get an app running with almost no effort. Back then Java was also just appearing, and like many other languages, you would find yourself writing tons of code to add UI elements to windows, and wiring their actions with code. November/December 2009 | REALbasic Developer | www.rbdeveloper.com 19 Figure 2: A visual editor, written in REALbasic, that allows the user to create content for the company’s web-based educational software. REALbasic freed me of all that so I could concentrate on what was important, the program itself. So what sort of programs did you write? All sorts of things. Teachers would ask us to implement classic algorithms for lots of things. I’ve always been a very visual person and I remember writing these using all sorts of animations while everyone else used command-line apps. I also got into hardware programming and at one point built a small plotter driven by an RB app, via the serial port of a PC, even though the app was written entirely in a Mac. What do you do today? Do you make a living writing software? Yes, I currently work for an educational software company, and even though our products are web-based, every tool used in-house from content editors and content management systems, to sales tools and reporting systems, are built using REALbasic. They all run on both Macs and PCs, with barely any specific code for either of the platforms. Our web apps are all .net based, however, the content they display is managed by RB apps. Why did you take that approach? Speed. Using RB we were able to write visual content editors, the drag and drop kind, that allow our editors to review and create content quite easily (see Figure 2). These apps then simply upload the formatted content to our server’s database. Doing the same kind of things with 20 Figure 3: A still-in-development custom control Alex is creating. November/December 2009 | REALbasic Developer | www.rbdeveloper.com Figure 4: Alex’s awesome CustomEditField control. a web-based app would have been much more difficult and time consuming. What else do you do with RB? I enjoy writing custom controls. A lot of those I end up using in projects at work and are born from very specific needs, but a lot of times I also simply enjoy the way a control works in some other app or platform and enjoy the challenge of being able to reproduce that. (Figure 3 shows an unfinished control I’m working on.) You wrote CustomEditField. How did that come about? I find it funny that CustomEditField (see Figure 4) was actually born from an autocomplete editfield... I had written my SyntaxHighlightEditField and found myself frustrated when I tried to add an autocomplete engine for it. It was simply too limited for what I had in mind (a basic XML editor) as there was basically no way for me to precisely place the autocomplete options. From there I started looking at how text editors worked. That led me to learn about gap buffers and piece tables (to store the actual text). In a few days I had the storage classes working and was amazed at how fast they actually worked. It all kind of snowballed from there. I started adding the line managers and my syntax highlight engine. I showed it to a couple of RB developers that I knew used my previous editfield and they were sold. They were the ones that convinced me to finish it and make it available to the public. if the user deletes characters, the gap becomes larger, up to a specified limit, in which case the data is copied to a new array and the gap reduced. This approach is simpler to implement and quite fast, not to mention that line management was also much simpler, though it’s a bit more inefficient if the file turns out to be really big. What are gap buffers and piece tables? Currently CustomEditField is a line editor. Any plans to add word wrap and make it more like a text editor? They are structures to store large chunks of text. Piece tables are structures in which edits are handled using linked lists in which you simply replace the changed text with a new node. These are super fast and make undo almost a no-brainer (as you can simply restore old nodes to support undo) but line management is really complicated. Gap buffers are large arrays (memoryBlocks in CEF’s case) in which you add a “gap” to the array wherever the insertion point is at. If the user types something the new characters are added to the “gap” without having to resize the array (unless there’s no more room, in which case a new gap needs to be created). Same for deletions, November/December 2009 | REALbasic Developer | www.rbdeveloper.com That is the most requested feature. Unfortunately it’s also the most difficult one to implement when it comes to user interaction.... I do have that feature as a big to-do in my list. Maybe in version 2.0, who knows. How popular has CustomEditField been? Has it been successful for you? It has been very successful, or at least more than I expected! I was able to get a new MBP from it, so that made me a happy man. I know of a lot of people that 21 Figure 5: Prismas, made with REALbasic, running on a Mac. use it in their projects, commercial and free, that in itself is a reward for me. Coolness. On a personal note, I like it very much! Thanks! I see you’re now making iPhone applications. Yes, I have a couple of iPhone apps out there, three to be exact. How’s that going? One of them is for sale; the other two are free. The commercial one did okay for a couple of months, nothing great, enough to pay for a couple of dinners. Not bad, especially without doing a lot of advertising, and I just don’t have the time for that. How do you find developing for iPhone versus REALbasic? Well, when the iPhone SDK came out a friend from college who had been working on a graphic calculator for WinMobile devices contacted me for help getting it to run on the iPhone. I really liked the SDK and the tools. I had worked with Xcode/ Obj-C in college but nothing beyond academic “experiments” so it took me a 22 while to get up to speed. After we finished the calculator, I ported the small physics app I have on my website (Prismas) which was originally written in REALbasic (see Figures 5 and 6). The game “Crazy Drops” was a copy of a really good old game for Mac, “Candy Crisis.” I always wanted to make a “networked” version and that’s how it was born. You can play against another player, via Wifi. It was done pre-OS3, so GameKit wasn’t available yet. How was your experience doing the port from RB? It was surprisingly easy. Basically it’s the exact same code, except for the drawing code which in the phone is done using core graphics. In just a few hours I had a prototype running. It was almost copying and pasting and reformatting a bit. What’s your take on where RB fits into the programming world? REALbasic is a great language, I still don’t know of any other tool that lets you build Mac and PC applications without pulling your hair out. Its speed from idea to executable is also unbeatable (in my opinion). That being said, I think it has a Figure 6: Prismas, ported to iPhone. spot in every developer’s arsenal. Its OO approach is so elegant that it would be a great language in which to learn how to program, while also providing the power to do some serious work when you need to. The only problem I have with it is the final size of the executables, but that is a whole different matter. What improvements would you like? One thing I love about Cocoa is its view hierarchy and how it can easily be extended, allowing you to create just about any control you can think of with very little code. If that made it into RB’s upcoming Cocoa extensions, I’d be very happy. What’s in the future for you? Anything exciting coming up? Not knowing what the future holds is exciting. Basically finishing a couple of updates to my iPhone apps, and finally releasing a couple of custom controls to the RB community that I just haven’t had the time to finish, though some people are already using pre-release versions. Thanks for the interview! November/December 2009 | REALbasic Developer | www.rbdeveloper.com Feature REALbasic Plugins Getting started with the Plugin SDK At a Glance RBD#8109 Target Reader: Intermediate Source Code: No RB Version Required: 2005+ Platform(s) Supported: Mac OS X, Windows, Linux Platform(s) Unsupported: Mac Classic About the Author: Christian Schmitz is the creator of the Monkeybread Software REALbasic Plugins. Getting started with the REALBasic plugin SDK can be difficult. The following article shows you how to get started on Mac OS X, Windows, and Linux. It is based on the presentation from the REALbasic Summit 2009 in Boulder, Colorado. About plugins If you compare REALbasic with a car, you can see plug-ins as replacement, extension, or tuning parts. So while REALbasic comes with a lot of built-in stuff, you always find things which are missing. Or you have a function in REALbasic which doesn’t work for you and you need a replacement function. Or you need a tuning part to perform a task faster. For example, a picture effect which performs better in optimized C code than in REALbasic code. And in that case you can take a plugin off the shelf or make your own. There are a few reasons you may have to write a plugin. For example you can embed an existing static library or existing code in C/C++ or Objective-C into a plug-in. Technically you can even embed code from other platforms into your plugin. For example you can compile and link into your plugin code written in Fortran. Another reason to write a plugin is to call operating system functions which are difficult to call from REALbasic. Some calls to COM interfaces or C++ classes are much easier from a plug-in. A third reason may be that you want to use symmetric multi-threading. This is easier to setup and run in a plug-in than in REALbasic code with declares or existing plug-ins. Requirements To compile a plugin you need a C compiler. We’ll later check the different compilers you find on different platforms. Technically you could use any other compiler which creates a shared library with a specific entry point, but a C/C++ compiler is the easiest as the SDK has C/C++ code. Once you download the SDK and get started you need a lot of patience. The plug-in documentation is limited and for a few functions you only find documentation in an email in the plugin mailing list. Mac OS X For Mac OS X you can use different compilers. GCC and LLVM come for free with Xcode on Mac OS X. For a better optimization you can of course pick other compilers like the Intel compilers. If you like you can use the Xcode IDE from Apple. November/December 2009 | REALbasic Developer | www.rbdeveloper.com 23 In the long run, and if you have several plug-ins, you will certainly switch to some scripts running in the terminal. Whatever you use doesn’t matter, but you need to compile a dylib shared library in bundle style. You compile a 32 bit universal binary library for the Mac OS X Universal target in REALbasic and if you support older REALbasic versions a second PPC-only library for the Mac OS X target. Until version 2009r4REALbasic was based on the Carbon application framework, but future versions will use the Cocoa framework. So you will want to compile all GUI code twice. Once for Carbon and one for Cocoa. Non-GUI code should still be linked twice, one time for Cocoa without the Carbon framework. Windows On Windows you can go with the free GCC compiler. You may want to use the Microsoft Visual C compilers. Of course it does not really matter which C compiler as long as it creates a native Windows DLL. Even Codewarrior 8 can do this. And it has the great advantage that it runs on Mac. So Mac users can use it to compile code on Mac for both Mac and Windows. But whatever DLL you compile, make sure it is native code and not some byte code from the .net world. Linux For Linux you can use the compilers coming with your favorite Linux distribution. If you don’t have one preinstalled, it is easy to install the packages for gcc or llvm. Those are two open source compilers you can use for free. For your distribution, make sure you install the 32 bit version so you have it easier and all libraries already installed in 32 bit. Because REALbasic expects a 32 bit ELF shared library compiler for x86 CPUs. One important thing on Linux is to keep your plugin linking to older library versions. Each Linux distribution has different versions of the libraries installed. And your existing user base may use older distributions with even older libraries. So you may want to install packages for older C/C++ runtime libraries, and you may prefer to link to libstdc++.so.5 instead of libstdc++.so.6 or libstdc++.so.7. Each newer version introduces new functions which may not be available in older versions. So if you depend on the older versions, your plugin will work with older and newer versions. 24 Figure 1: The new project dialog in Xcode with the REALbasic template REALbasic versions What REALbasic version do you want to support at a minimum? Depending on which version you choose as minimum you are limited to what you can use. REALbasic 2005r4 introduces console flags. So you can mark which functions, classes, and modules are supported for console applications. If you don’t set the console flag the given item will not be visible in developing a console application. And console safe declara- tions are not allowed to use the picture, the graphics, or the window class. But those console flags will be no problem for older versions of REALbasic as they are ignored there. For REALbasic 2009r3 and newer you need to provide a universal Mac OS X library. For older REALbasic versions you need to provide a PPC library, too. With REALbasic 2006r4 new 64 bit data types are added. If you want to use these new data types any older REALbasic versions will report an error Figure 2: The new project in Xcode November/December 2009 | REALbasic Developer | www.rbdeveloper.com Free Movie Tutorials! The MBS Plugin ™ The Ultimate REALbasic plugin Adds Over 30,000 functions to REALbasic! www.monkeybreadsoftware.de/realbasic/movies/ The Monkeybread Software REALbasic plug-in collection is a big toolbox to help you solving your problems. Thousands of new functions will help you developing better applications! ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ ■■ Use the CUPS plugin to access the Mac OS X and Linux print system. Compress data using BZip2 and ZLib engines Copy files asynchronously or synchronously. Use the DotMacKit to access .mac/mobileme features. New for Snow Leopard: Get geo coordinates using CoreLocation / Use OpenCL / New CoreImage filters / Quicklook Preview Panel / New functions for PDFKit and QTKit classes Use Spotlight classes to search on a Mac Use OCR classes for optical text recognition Extract frames from a QuickTime movie Use GraphicsMagick to read/write/manipulate over 88 major formats. Create your own serial number system for your applications Access image metadata (exif, iptc, and others) using CoreGraphics Powerful SQL plugin for accessing multiple SQL databases (Oracle, Microsoft SQL Server, DB2, Sybase, Informix, InterBase, SQLBase, MySQL, PostgreSQL, and odbc, SQLite). The PictureMBS class handles pictures of any size using virtual memory. Connect to jdbc databases and use java classes using the Java plugin. Control USB HID devices on Mac and Windows Burn CD/DVDs in your application Record audio and video Create transparent windows Run Javascript in a HTMLviewer control Create professional charts using ChartDirector Change/fade the screen gamma Run PHP scripts in your applications. Perform window and screen transitions Read and write jpeg, tiff, png, and gif images. Use Dongles to protect your software (hasp, Unikey, and Rockey) Use the x-rite Eye-One Device for color measurement Handle ICC Profiles, XMP metadata, CMYK images in jpeg and Tiff. Cocoa classes: picture taker, color palette, spellchecking, and picture effects. Compile, decompile, and execute AppleScripts Download and Upload data using the curl class over ftp, ftps, http, https, Gopher, Telnet, dict, ldap, and file protocol. Perform color management using ColorSync or LCMS. Use SpeechSynthesizer and SpeechRecognizer, Integrate your app with iCal, iChat, iPhoto, and Addressbook on Mac OS X v9.3 Supports Snow Leopard! PARTS $30 – $75 See the website for individual part pricing: https://www.monkeybreadsoftware.de/realbasic/buy/ plugins-buy-nonEU-new-paypal-us.shtml COMPLETE * $294 / $147 Commercial License / Academic License SQL Access SQL Databases: Oracle, Microsoft SQL Server, DB2, Sybase, Informix, InterBase/Firebird, SQLBase, MySQL, PostgreSQL and ODBC and SQLite $898.50 / $1498.50 Create/import/modify PDF files on Mac/Win/Linux. Includes embedding of fonts and text extraction. (Lite/Pro) (Academic Lite/Pro License) ($448.50 / 748.50) $148.50 DynaPDF ChartDirector $298.50 / $148.50 Professional charts for RB. Commercial License / Academic License * Includes all plugins except independent plugins like DynaPDF, SQL, and ChartDirector. FREE Trial Download and Full Documentation: www.monkey breads of t ware .de Figure 3: We change the architecture setting to Universal binary on compilation. It simply does not know what an “SInt32” or an “UInt64” data type is. With REALbasic 2008r1 you have better array access functions in the plugin SDK. You need this to create and fill an array in the plugin and return it to REALbasic code. And starting with 26 REALbasic 2008r3 the SDK comes with everything you need to make plugins for the new Cocoa target. Plugin file format Plugin archives in REALbasic are virtual volumes. You can create and open virtual volumes in REALbasic using folderitem.CreateVirtualVolume and folderitem.OpenAsVirtualVolume. This virtual volume contains for each platform a shared library in a special folder hierarchy. There is a folder for build resources containing the shared November/December 2009 | REALbasic Developer | www.rbdeveloper.com libraries and there are folders for IDE resources which contain the help files or the control palette pictures. You don’t need to build this folder hierarchy yourself. You can use the Plugin Converter project that comes with the plugin SDK to create the plugin archive for your libraries. Over the long run you will want to write your own tool so you can automate the build process. If you like you can add pictures for the control palette. For a better look on different operating systems you can even have different pictures there. One for Windows 2000, another picture for Windows XP, and one for Windows Vista. You can also add html pages for the online help. But using a lot of html pages slows REALbasic down as the html files are copied to a temporary folder. Developing a plugin Now we want to show you how to start with the plugin SDK to get a plugin compiled. Together we will create a little plugin with one simple function and compile it for all three platforms. At the end we merge those libraries to one plugin archive. To get started go to the REALbasic website and download the REALbasic package. Inside the extras folder you should find the Plugin SDK files. Mac OS X On Mac OS X we use Xcode for this example. Inside the examples that come with the plugin SDK, you find a folder named “Xcode Mach-O Template”. Inside is the “REALbasic Mach-O Plugin” folder which you want to copy to the other Xcode templates. Depending on your Xcode version this location is different, but for Snow Leopard you can use the templates folder in “/Developer/Library/ Xcode/Project Templates”. Now launch Xcode and create a new project. Select the “Xcode Mach-O Template” template and save your new project (see figure 1). Once you have the project open, you see a lot of red entries (see figure 2). To fix this, find your plugin project folder in the Finder and copy the folders “Glue Code” and “Includes” from the plugin SDK. Once you are back in Xcode the red entries are gone and Xcode finds all of the files. Now you want to edit the project settings and opt to compile a universal binary. For that you select in Architecture the entry “32-bit Universal”. Also you want to check the deployment target setting. Scroll down and look for the Figure 4: We change the deployment target setting to Mac OS X 10.4 “Mac OS X deployment target” which is by default the “Compiler default”. Change it to “Mac OS X 10.4” to compile your plugin for all Mac OS X versions starting with Mac OS X 10.4. (see figures 3 and 4) Now you can build your project once. Hit Command-B or select Build from the Build menu. It takes some time for Xcode to build the project, but once it finishes you should see an error message or a “Succeeded” message on the bottom right of the window. Now replace your plugin cpp file with this code. By default it is very short with just an empty PluginEntry function and one include line. Take this code: #ifdef _MSC_VER #include "WinHeader++.h" #endif #include "rb_plugin.h" static int sum(int x, int y) { return x+y; } REALmethodDefinition sumMethod = { (REALproc) sum, REALnoImplementation, "sum(x as integer, y as integer) as integer" }; void PluginEntry() { REALRegisterMethod(&sumMethod); } Let’s discuss the code above. The first lines are for Windows only. So we use conditional compiling to only compile them where the _MSC_VER constant November/December 2009 | REALbasic Developer | www.rbdeveloper.com is defined. Actually this is the version number of the Microsoft C compiler which exists only if the code is compiled using the Microsoft C compiler. Mac and Linux targets will ignore it. As we want to use the same code for all platforms, we have it already here. Next is the include for the REALbasic plugin functions. In the rb_plugin.h file and the realplugin.h file it references you find all the classes, constants, and functions in the REALBasic plugin API. Now in the next 4 lines you find the definition of the C function called sum. It basically adds one integer to another integer and returns that value. Very simple. The key thing is the next line. There we define a REALmethodDefinition structure which is the definition for a global function. This definition tells the REALbasic compiler which C function it needs to call for the given REALbasic function. And for REALbasic we provide here the function pointer to the sum function and the REALbasic declaration. The compiler parses this declaration in order to know how to call our function in C. Although both are named sum here, only the name in the REALbasic method matters. The C name is just decoration, but we keep it in sync because this name can appear in a crash report. In the PluginEntry function, you can do all the initialization of your plugin. Be aware that this function is called in the IDE so the compiler can learn the plugin function. So you should check for your initialization code to make it very efficient and not mess up the IDE. Better to make initialization methods or put your initialization in a class constructor. But the important part of the initialization is what we do here. We register the global 27 Figure 5: In Visual C on Windows with the test plugin project method to REALbasic by calling the REALRegisterMethod function. Actually you can see a deprecation warning here. For your plugin you might want to go and make a new module or a class and add a shared method. But for some things you want to have a short name and still use a global method. If you want to test it, copy the compiled dylib to your plugins folder. REALbasic loads plugin libraries for the current platform directly from the plugins folder. But for bundling plugin libraries for several platform, you need to create the rbx archive. Run REALbasic with the dylib in your plugins folder and you can use the sum function in your code: MsgBox str(sum(5,4)) This messagebox shows 9 if the plugin is found and compiled correctly. That is your plugin for the Mac. Next we look at the Windows target. 28 Windows For Windows, you start by copying the plugin SDK to a Windows (virtual) machine. For this example I prefer to use Visual C 2005 on Windows 2000 inside VMWare Fusion. Visual C 2005 is a good choice because the plugin SDK comes with an example for that Visual C version. So copy your plugin SDK folder to a Windows machine. Locate the “Visual Studio .NET 2005 Example” folder in the examples. Open the Test Plugin project in Visual C by double clicking the “Test Plugin.vcproj” file. We copied the whole plugin SDK file so Visual C automatically finds the Includes and GlueCode files automatically. Now change TestPlugin.cpp. You should simply copy the code we have above on the Mac to Windows with the clipboard. Choose Build Solution from the Build menu and after a couple of seconds, your project will be compiled (see figure 5). You find several files in the Release folder inside the project folder, but the one you need is the “Test Plugin.dll” file. With that DLL we have the Windows part compiled. If you like you can drop this DLL file into the plugins folder on Windows and launch REALbasic to test it. Linux For Linux you copy the plugin SDK on your Linux machine. Also you copy the TestPlugin from Mac or Windows to the Linux machine. Now in the plugin SDK you find the example “Box Control” which has a makefile for you. Copy this makefile to your PluginTest folder. A makefile is a little script file which is run with the make tool. It runs compiler and linker commands if needed so you don’t need to recompile everything every time. You need to modify it: First replace all instances of “boxcontrol” with “testplugin”. On the top of the makefile below the comment lines November/December 2009 | REALbasic Developer | www.rbdeveloper.com you find a few constants defined. The PLUGINSDKDIR needs to point to your plugin SDK folder. You should change it to “../..” for the case where you have your testplugin inside the examples folder. For other folders you need to have the path different of course. Further down you find the definition of the PREFIXHEADER constant. Change it to “LinuxHeader.h” so it finds the Linux header file correctly. Now you can go to the terminal. Use cd and ls commands to go inside the plugin folder. Now run the makefile with the make command. You type “make all” to call the make utility and let it start on the all: line in the makefile. From there it will see that it needs to compile both testplugin.o and PluginMain.o before it compiles the libtestplugin.so library (see figure 6). This library file is needed for the next step. Of course you can test your plugin by copying it into the plugins folder and running REALbasic for Linux. Figure 6: The typical output of make in Linux Merging parts Back on your favorite platform you now have all three libraries in one folder. Inside the plugin SDK folder you find the “Plugin Converter” folder. There you find the “Plugin Converter.rbp” project which you compile for your platform. Now you have the plugin converter command line application. Open the terminal on Mac OS X/Linux or the command shell on Windows. There you can use cd to go to the folder with your libraries. Now run the PluginConverter tool with the following options: PluginConverter -n test.rbx -w32 "Test Plugin.dll" -car TestPlugin.dylib -lnx libtestplugin.so The -n switch tells the converter to create a new plugin. With the other three options you can specify the parts to embed. We specify the Windows part, the Carbon partn and the Linux part. In the future you may want to add another dylib for the Cocoa target. Some more words In the long run you will want to have all platforms share the same files. A common way is to host them on one platform and use Samba file sharing (SMB) to let all platforms access all files. Or to use subversion (SVN) to synchronize between platforms. After you setup your file sharing you need to setup both projects and the makefile. The paths must be correct and the build folder paths need to be changed too. Also you may want to write a script to create the final rbx file automatically. On MonkeybreadSoftware we currently have 350 plugin projects which assemble to 43 rbx plugin files. So you see you can have several plugins in one rbx file. But with this number you need to automate things. So we have several scripts which compile all these plugins. One for Windows, one for Mac OS X, and one for Linux. And a final one to create the rbx files. Also we use self-written tools to write the scripts above, create the rbx files, and extract the declarations for the documentation. If you have questions about developing plugins, please ask your questions in the plugins section of the REALbasic forums. Figure 7: Looking into the final plugin file But please read the documentation coming with the SDK first, check the other plugins and search on the web for other people having the same problems first. Web Resources: http://www.realsoftware.com/download/ http://www.monkeybreadsoftware.de/realbasic/movies/CreatePluginMac.shtml http://forums.realsoftware.com/viewforum.php?f=5 November/December 2009 | REALbasic Developer | www.rbdeveloper.com 29 REALWord by Andy Dent Karel, the REALbasic Robot How the rbKarel robot simulation teaches logic with RBScript At a Glance RBD#8110 Target Reader: Intermediate Source Code: Yes RB Version Required: 2006+ Platform(s) Supported: Mac OS X, Windows, Linux Platform(s) Unsupported: Linux, Mac Classic About the Author: Andy is a freelance developer from Perth, Western Australia who alternates REALbasic with C++, C#, Ruby, and Objective-C and welcomes the return to the kindler, gentler and often moreproductive world of REALbasic. Karel the Robot has been around for nearly thirty years as a way to teach people the basics of logic through solving simple problems. The rbKarel project uses RBScript to provide the language interpreter for Karel along with a few goodies like spoken output and single-stepping. It also uses a much simpler context object for a second RBScript to define worlds. Why write a parser when RBScript does the hard work for you? This article doesn’t attempt to teach the basics of RBScript — see the resources list at the end for past RBDeveloper articles on that topic. What I do cover are some of the interesting challenges in adapting RBScript for Karel and particularly how to add single-stepping and other controls over the script execution. As I wrote the article I also found myself explaining a few points about the software design decisions, which may seem heavy-handed to experienced programmers but hopefully will keep reminding others of some core principles. When Jeff Ayling posted his request for help, I was intrigued by the “Just how hard could it be?” prospect of trying to implement a particularly REALbasic style of Karel. I had already published a complex example of RBScript being used to drive 2D graphics. Putting a little user logic on top of this didn’t seem that hard, just a case of adding a few methods to the context object to manipulate a robot. Things are never quite as simple as they seem in the first rush of enthusiasm and one challenge I hadn’t anticipated is that Karel’s world is not one of pixel coordinates but of a grid with intervening walls and coordinates. The first public teaching trial also proved that adding single-stepping and some feedback as to what was going to happen next was a hugely desirable feature. Karel From the Users’s Viewpoint Karel moves around on a simple grid of vertical Avenues and horizontal Streets, with walls between. See Figures 1 and 2 for examples. He carries a Beeper Bag into which he can put the Beepers he picks up and from which he takes beepers to put on the grid points. Beepers are conceptually there — they are visible but (thankfully) do not actually beep. Real audible beeping is not an enhancement that has been requested and is probably the Karel equivalent of the <BLINK> tag. If more than one beeper is on a given grid location, we have improved visual feedback that a count is visible in the middle of the beeper. 30 November/December 2009 | REALbasic Developer | www.rbdeveloper.com rbKarel supports multiple robots but at this stage won’t animate them all. There are no restrictions on what order you place items, and beepers and the robot can be placed on top of each other. Worlds exist between the grid coordinates being either North (1) or West (4) of an intersection. As the world files are run as an RBScript, you could also write complex loops rather than keep using literal segments — an entire maze generator or fractal program could be supplied as a script to define a Karel world. A Trivial World World 5 5 Beepers 4 3 10 Robot 3 3 1 0 Wall 3 3 4 wall 3 3 1 wall 3 4 4 Karel Programming The original Karel language had a simple conditional if.. then and looping iterate N times constructs. We can’t remove anything from the RBScript language so the full power of RBScript conditionals is available. To make life a little easier for people who are new to the idea of variables, a single index variable is predefined dim i as integer unless it is already included in their code. This takes advantage of the RBScript idiom of composing your own preface with user scripts to have variables defined in RBScript space. Original Karel Code from KarelJ examples BEGINNING-OF-PROGRAM if facing-east then turnleft; move; iterate 5 times begin pickbeeper end; end; rbKarel Version of Original The only instructions you can issue Karel are to move, turn, pick up and put down beepers. The other verbs in the language, as you will see below, are to evaluate the world so Karel can decide what to do next. Something to consider is, with this kind of interactive environment, users can write complex Karel scripts to solve a problem in one go, as a typical programmer might. They can also enter just one verb to tell Karel to move or turn, and see how that affects the state of the world. That is like the experience of exploring algorithms with a dynamic language such as Ruby or Python. Defining Worlds The three verbs that define a world position stacks of beepers, walls made out of segments, and a robot. Internally, if facingeast then turnleft move for i = 1 to 5 pickbeeper next end Original C++ Karel Code Simple Example #include <karel.h> using namespace std; int main() November/December 2009 | REALbasic Developer | www.rbdeveloper.com 31 { TurnOn(); Move(); Move(); PickBeeper(); The Karel verbs I implemented are close to the apparent standard — there has been a little variation between versions. Being written in RBScript means we don’t have to worry about terminating semicolons and, although the context methods listed below are, strictly speaking, invoked through function calls, we can take the normal REALbasic approach of dropping the parentheses to get very clean syntax. Another benefit is lack of case sensitivity in RBScript, unlike the Java implementation. Errors from case are an issue you do not want to have to debug for beginner classes! I also took the liberty of making TurnOn and TurnOff optional. My view is that the graphical text box into which they type their program clearly bounds the program so requiring these extra verbs is another added thing people shouldn’t have to worry about. The environment testing functions are pretty selfexplanatory. The only one I think is slightly confusing is the idea of being nextToABeeper which is when a beeper is at the same street corner as Karel, I think of it as the robot leaning against a signpost, eyeing a stack of beepers over the top of his sunglasses and deciding how many to pick up. Looking at the list of functions below, you can see how all of them have a negated version, rather than having to parse a logical not statement. Of course, if people put a not in front of any conditional, followed by a space, RBScript normal interpretation will work anyway. Movement is blocked by there being a wall or edge of the world in front of Karel. An interesting aspect of the Karel world is that it combines both absolute NSEW directions and a relative sense. People can write code thinking in either paradigm and it will work better for some worlds than others. The Mountain Climbing problem shown in Figure 1 is an interesting one which asks the user to imagine Karel moving vertically, as seen from the side, rather than the normal top-down viewpoint. Standard Karel Environment Testing Functions ■ ■ anyBeepersInBeeperBag ■ ■ facingEast ■ ■ facingNorth ■ ■ facingSouth ■ ■ facingWest ■ ■ frontIsBlocked ■ ■ frontIsClear ■ ■ leftIsBlocked The MBS ChartDirector Plugin ™ The ultimate charting solution for REALbasic n Professional charts in your cross platform applications! n Supports Mac OS X, Windows and Linux. New Version 5.0! n Visit gallery to see sample charts: http://www.monkeybreadsoftware.de/realbasic/chartdirector/ n Download a free demo copy on www.monkeybreadsoftware.de as part of the MBS REALbasic plugin collection. n Royalty-free licenses available per developer for $298.50 (Commercial) and $148.50 (Academic). 32 November/December 2009 | REALbasic Developer | www.rbdeveloper.com GUI but there are no dependencies on it. As you can see from Figure 3, the window is connected to the KarelWorld by interfaces and you could implement your own variation quite easily. The drawing surface used is a subclass of my GraphicsScripter which exposes the Graphics2D functions as a REALbasic context object, allowing you to write scripts that do all kinds of drawing on a Canvas. Most of what it does is very simply repeat each of the methods on a known Graphics object DrawCircle(x as integer, y as integer, r as integer) mDest.DrawOval x, y, r, r Figure 1: Simple Karel World — Mountain Climbing ■ ■ leftIsClear ■ ■ nextToABeeper ■ ■ noBeepersInBeeperBag ■ ■ notFacingEast ■ ■ notFacingNorth ■ ■ notFacingSouth ■ ■ notFacingWest ■ ■ notNextToABeeper ■ ■ rightIsBlocked ■ ■ rightIsClear Standard Karel Imperative Actions (all logged) ■ ■ Move Non-Standard Methods Exposed to Script, mainly for mapping coordinates. ■ ■ Avenue2X ■ ■ AvenueGapX ■ ■ IsRunning ■ ■ NextAvenue ■ ■ NextStreet ■ ■ Street2Y ■ ■ StreetGapY ■ ■ StreetSpacing ■ ■ Wait ■ ■ WorldResized ■■ X ■■ Y ■ ■ TurnLeft ■ ■ PickBeeper ■ ■ PutBeeper Property Exposed to Script ■ ■ MovePause Other Karel Imperative Actions Say ■ ■ TurnOff ■ ■ TurnOn Other Public Functions not Intended for Script Use: ■ ■ ErrorShutdown ■ ■ LeftDirection ■ ■ PrepareKarelScript ■ ■ RightDirection ■ ■ SetLogger Implementing the Basics From the start, I wanted the core Karel engine to be reusable. The SimpleKarelRunner window is a nice November/December 2009 | REALbasic Developer | www.rbdeveloper.com When you use a subclass as a context object, all the public methods of the parent are still available to RBScript so this is a nice way of separating the development. From postings I’ve seen in various mailing lists and forums, I think many people think they have to copy all the methods they want in their context into a single class. So, if you want to write a spinoff, consider just inheriting KarelScripter and adding your own methods, and you can continue to take advantage of any fixes in the original. In classical OOD terms, rbKarel has a separate Model which is the KarelWorld class. It maintains the state of the world and does minor dual duty as an RBScript context object when parsing the World files. The main visible objects within the world, the Robot, Walls, and Beepers are stored as objects which maintain their own state. All these draw using a KarelScripter to supply the drawing commands. See Figure 4 for a comprehensive class diagram of all the classes involved in the user interface and drawing. Worlds of Streets and Avenues The streets which are drawn as gridlines are calculated and drawn as shown in Code Listing #1. They are just background graphics, having no active role and so didn’t need modeling independently. Note how the KarelWorld gets its width and height from the KarelScripter at the time of drawing. That way, if the original Canvas is resized, the grid will redraw proportionately. I can’t emphasize too highly — avoid caching such values unless you are really certain the cached value is needed for performance reasons, hopefully because you’ve proved a need through 33 testing. The more values you cache, the more fragile your architecture becomes and you find yourself with weird edge condition bugs where an uncommon user action has side-effects in apparently unrelated areas. There is no attempt to see how well the avenue and street lines fit. The user is responsible for specifying how many are in the world and they get to choose the size to which they drag the Canvas in the GUI so it is up to them to achieve an aesthetic result. One of the late changes in rbKarel was adding the disclosure triangles on the window, so the script and controls panels can be hidden. Jeff was lecturing with 800x600 projectors and wanted an easy way to show complex worlds. Hiding the UI was easier than adding a separate zoomed window. Drawing Objects All the Karel objects draw using a KarelScripter and you can see in Code Listing #2 how a few simple shapes are composed to draw the robot. The impression of direction is given by choosing where to draw the blue oval representing the robot’s eye, rather than rotating a complex object. This is a good example of how we often can fake things in games and animation rather than having to actually model the more sophisticated aspect of a rotating body. If we had a 3D robot with an animated waggle as it moved, something a lot smarter would be needed. Even using a fancier graphic would probably require real rotation. The most obscure part of Code Listing #2 is how this direction is calculated. A simple enum is used to specify direction and the robot has a Facing property. This shows up in the script commands where you can see the final action is to set the robot direction. KarelScripter.TurnLeft Wait MovePause // this implements the speed of playback if mLogger<>nil then mLogger.LogKarelEvent "Turn Left", self end if mDirection = LeftDirection mWorld.TurnRobotTo mDirection Custom Drawing The world of Karel objects is in street and avenue coordinates, only 34 Figure 2: Karel Maze translated to X and Y pixels at the last minute. If someone wants to mix their own drawing logic into the script they could scribble anywhere they want on the Canvas but would probably want to use coordinates relative to the Karel objects. The methods X and Y expose relative coordinates calculated at runtime. Thus the scripted objects will appear at the correct location even if the window is resized and the grid drawn scaled. If you really wanted fancy custom graphics, the scaling factors are also exposed to the graphics context as AvenueGapX and StreetGapY. Collision Detection The collision detection problem in rbKarel is very simple because the only things Karel can collide with are walls and the boundaries of the world. In a much bigger world, with performance issues, an optimal solution would be needed but the simple Karel world allows me to write easy code: KarelWorld.IsWallBetween(ave1 as integer, street1 as integer, ave2 as integer, street2 as integer) As Boolean for each w as KarelWall in mWalls if w.IsBetween( ave1, street1, ave2, street2 ) then return true end if next return false REALbasic is fast enough that I suspect we could run through hundreds if not thousands of walls in such a loop without a user noticing the delay. The more complex code is in the IsBetween test as shown in Code Listing #3. As a general design pattern, I like to have collections of fairly smart objects. That design also lends itself to testing with separate unit tests. The apparent simplicity of this collision detection hides some sophisticated thinking. Currently, you can only move a robot one cell at a time. However, the collision detection doesn’t make assumptions about adjacent cells. You could specify a jump in a straight line of four cells and the detection would still work because it only checks the start and destination. The collision November/December 2009 | REALbasic Developer | www.rbdeveloper.com some things were obvious, in some cases to both of us. Logging to Speech Speech was one of those cool features I just had to add because REALbasic makes it so easy. It’s also a good example of how a simple feature sparks the user imagination to create a much more complex requirement. I added the Say verb to the core Karel syntax just so users could celebrate with a few words aloud. The initial version was used in a demonstration of speaking when the problem was solved. As soon as we started trying to use Say within loops, it became obvious that Karel could both run and talk at the same time — not a problem if you’re going slowly. The issue really came to a head when I added the logging Say each change feature and Karel would complete running a script whilst the computer gabbled on for a couple of minutes. This has been solved for Mac in SpeechUtilties.SpeakSynchronously but there is an outstanding issue for Windows to work out a way with declares to wait whilst speech is still being output. Figure 3: GUI Connections to Karel detection also is only checking the geometry of the world — it is not related to movement in any way. That means you could reuse the same collision detection to see if two robots could see each other or fire at each other in a straight line. Logging Logging is an essential element of debugging any program. There is a richer logging mechanism built into easy extension would be an rbKarel program logging across a socket interface! A simple Composite pattern is used — a KarelMultiLogger allows a series of loggers to be invoked. Logging can also be a way of introducing delays, in rbKarel’s case deliberately. As discussed in more detail below, logging to speech and single-stepping both require the logging class to pause so the user can catch up with Karel. The impression of direction is given by choosing where to draw the blue oval representing the robot’s eye, rather than rotating a complex object. This is a good example of how we often can fake things in games and animation rather than having to actually model the more sophisticated aspect of a rotating body. rbKarel than exposed through the user interface. The KarelWriteLogger provides a base class you could subclass to write to anything supporting the standard REALbasic Writeable interface, so an Adding Fun and Features Once the basics were implemented, Jeff was able to start playtesting. Even before he used rbKarel with a class, November/December 2009 | REALbasic Developer | www.rbdeveloper.com Usability Through Delays From the start, I’d built in the delay feature to keep Karel running at a visible pace. The delay period, of course, is specified in a variable. It was very easy to add a slider on the main window that adjusted this variable, although we invert the sense of the slider so that faster is to the right. The quick evolution of this slider is a nice example of iterative design and how sometimes less is more. I started putting text on the slider which was updated to indicate the delay, stewed with Jeff over whether a typical Karel user would care about the amount of delay and we finally tested it with a class with all the text removed. The idea of a slider that adjusts speed is intuitive and people easily related to the scale of the slider and its sense of direction. I think the actual magnitudes of the delay were fine-tuned in three iterations — it now ranges from one second delay down to zero. Single-Stepping and Canceling All the significant actions of Karel that affect the state of the world log before they perform their action. That allows us to have an about to blah approach to logging. Single-stepping is 35 Figure 4: Overall Class Diagram implemented very simply — if you turn on single-stepping then a KarelStepLogger is inserted ahead of all the other loggers. It waits until the step is acknowledged, by the user pressing a Step button on the main window. Because it knows what is about to happen, the user gets to see that as a comment on the window. With the stepping logger causing the delay before the other loggers, if the user also has speech logging turned on, they don’t hear the description of the action until they press the Step button. SimpleKarelRunner.StepNeeded(msg as String) StepButton.Enabled= true StepAboutPrompt.Visible = true StepActionMsg.text = msg StepActionMsg.Visible = true // spins waiting for that button to be enabled // this will be called from a separate non-GUI thread running Karel 36 Do app.YieldToNextThread loop until mStepButtonPressed or StepCheck.value=false StepButton.Enabled = false mStepButtonPressed = false StepAboutPrompt.Visible = false StepActionMsg.Visible = false There are a number of interesting aspects to the stepping method which deserve careful thought — it was not arrived at easily! It is invoked through an interface and the caller knows nothing about how it is implemented. It could as well be a timer or monitoring a microphone for a sufficiently loud noise. A minor but appreciated usability feature is that the loop monitors the StepCheck state as well — unchecking will continue the same as pressing the Step button. The main point of course is that it requires the RBScript to be running in a separate thread. If the script ran in the November/December 2009 | REALbasic Developer | www.rbdeveloper.com Code Listing #1: KarelWorld. DrawWorldBackground(ks as KarelScripter) dim width as integer = ks.Width dim height as integer = ks.Height const marginPenSize = 4 dim insetFrame as integer = Margin — marginPenSize // the thick line is inside the margin dim doubleInset as integer = 2*insetFrame dim frameWidth as integer = width — doubleInset Why Google Code? One of the ways to spread the news about REALbasic is to provide public examples of interesting projects or useful snippets of code. There are several major code repositories which have the kind of prominence I wanted — Google dim frameHeight as integer = height — doubleInset Code has an appealingly straightforward wiki ks.PenSize = marginPenSize and already hosted several major REALbasic ks.PenColor = ks.white projects. ks.FillRect 0, 0, width, height // clear background ks.PenColor = ks.black ks.DrawRect insetFrame, insetFrame, frameWidth, frameHeight ks.PenSize = 1 ks.PenColor = ks.blue // vertical gridlines and numbers You can count on projects on Google Code to be well-indexed by Google! The simple project management tools it provides make it easy to track issues and provide a notification feed for issues logged as well as version control updates. // gap either side of lines At the time, the other major contender was dim aveSep as double = ks.AvenueGapX SourceForge which had a much more compli- dim aveY1 as integer = Margin dim aveY2 as integer = height — Margin dim x as double = Margin for i as integer = 1 to mNumAvenues x = x + aveSep dim aveX as integer = Round(x) ks.DrawLine aveX, aveY1, aveX, aveY2 cated interface. They have since significantly improved their appearance and features but I’d still recommend Google Code as easier to maintain. ks.DrawString str(i), aveX-4, height-2 // tweaked position next // horizontal gridlines and numbers dim streetSep as double = ks.StreetGapY dim streetX1 as integer = Margin dim streetX2 as integer = width — Margin dim y as double = Margin for i as integer = 1 to mNumStreets y = y + streetSep dim streetY as integer = round(y) ks.DrawLine streetX1, streetY, streetX2, streetY dim flippedStreetNum as integer = mNumStreets — i + 1 ks.DrawString str(flippedStreetNum), 1, streetY+2 next main thread, it would be locked up and the user interface would not react to the actions you see tested above. The threaded approach that enables single-stepping was first added to give the ability to halt Karel. The Run button is renamed to Stop once we start running and it is also possible for an error condition within the script to cause a halt (e.g., if the user runs Karel into a wall). These all rely on an undocumented but, in hindsight, obvious aspect of how REALbasic works — if you are running an RBScript in a thread you can kill the thread to halt the script. KarelWorld.ErrorShutdown(msg as string) for each obs as KarelWorldObserver in mObservers obs.ErrorShutdown self, msg next if mOurThread is nil then // unable to actually stop running else November/December 2009 | REALbasic Developer | www.rbdeveloper.com 37 mOurThread.Kill //will stop any KarelScripter that is using us as well end if Currently, the only KarelWorldObserver we use is the SimpleKarelRunner GUI itself which is able to report the error message in red text. Packaging Predefined Worlds and Scripts A free program like rbKarel is often quickly rejected unless it includes sample documents. This article is not about how to make dynamic menu handlers so I won’t go into details. In brief, rbKarel includes the DynamicDelegatingMenuItem and its subclass FolderItemMenuItem to make it easy to have menus of FolderItems that are loaded at startup from a couple of special folders. These menu items are tagged with the folder item so it can just be opened late and a script read. The SimpleKarelRunner. SetupDynamicFolderMenus method searches a number of directories starting with the immediate application parent directory, Documents, and others Code Listing #2:KarelRobot.DrawInContext(ks as KarelScripter) dim x as integer = ks.Avenue2X( mAvenue ) dim y as integer = ks.Street2Y( mStreet ) ks.PenColor = ks.red const halfWidth = 8 ks.FillSquare x-halfWidth, y-halfWidth, 2*halfWidth // now work out side to put blob blue eye on dim sideOffsetX, sideOffsetY as integer if Facing = KarelScripter.North then sideOffsetX = 0 sideOffsetY = -halfWidth elseif Facing = KarelScripter.South then sideOffsetX = 0 sideOffsetY = halfWidth elseif Facing = KarelScripter.East then sideOffsetX = halfWidth sideOffsetY = 0 else sideOffsetX = -halfWidth sideOffsetY = 0 end if const blobRadius = 4 ks.PenColor = ks.blue ks.fillCircle x + sideOffsetX — blobRadius, y + sideOffsetY — blobRadius, 2*blobRadius The MBS DynaPDF Plugin ™ The ultimate PDF solution for REALbasic Professional PDF support in your cross platform applications! Supporting Mac OS X, Windows and Linux. n Create PDFs with interactive forms, add vector graphics, web and file links, annotations, bookmarks and file attachments. n Use digital certificates to sign your PDF files with digital signatures and encrypt them with 64 or 128 Bit keys. n Import PDF pages and extract content, edit text, forms and graphics. n Split and merge PDF files. n Supports color spaces: RGB, CMYK and Grayscale, multipage TIFF files, custom page templates and much more. NEW Academic Licensing Now Available! Royalty free licenses available for 599 € (Lite), 999 € (Pro), and 1499 € (Enterprise) per developer. Academic licenses are available for 299 € (Lite) and 499 € (Pro). This license can be used also in C/C++ cross platform applications and on Windows with C#, VisualBasic, VB .NET. Download a free demo copy on www.monkeybreadsoftware.de as part of the MBS REALbasic plugin collection. 38 November/December 2009 | REALbasic Developer | www.rbdeveloper.com Jeff Ayling’s Story Based in Sydney, Australia, my Game Training ( HTTP://www.gametraining.net) business has been growing consistently since early 2009. In the early days my students always had trouble getting their head around simple coding concepts while working on our game projects as most had not had any previous coding experience. I knew I needed to take each student through a training process which started with simple basic concepts and became gradually more challenging to get them ready for some serious video game coding. I discovered Karel the Robot while watching an online Stanford University lecture on ‘Programming Methodology’ by Professor Mehran Sahami. You can watch all 28 parts of the lecture via iTunes U with the link below. http://deimos3.apple.com/WebObjects/Core.woa/Browse/ itunes.stanford.edu.1615329425.01615329428 What impressed me about Karel the Robot was the way students were able to learn basic programming techniques and concepts in a unique and enjoyable way. I think the key lies in allowing students to write code which gradually increases in complexity without changing the underlying content of each project. Karel never changes yet Karel’s world does change and the student is required to solve problems and get Karel to perform various tasks. After seeing Karel in action I knew this was what I needed to introduce my students to code writing. However, I didn’t want to introduce them to the complexities of getting Eclipse, a Java Runtime Environment, and the project up and running. I’ve always been a huge fan of REALbasic and I posted a message in the REALbasic User Forum (the NUG) to see if anyone was interested in assisting with the project. This was my post on the NUG: Hi all, Next week I’m teaching some young kids a bit about software development. After watching the Stanford University Programming Methodology videos at (http://deimos3.apple.com/WebObjects/Core.woa/Browse/ itunes.stanford.edu.1615329425.01615329428) I feel that Karel the Robot could be a nice project to show my students. Unfortunately Karel is written in Java — I’d love to get Karel up and running in REALbasic. http://karel.sourceforge.net/ Is anyone up for the challenge of getting Karel running in RB? I’m spinning too many plates right now to attempt it but I’d be willing to pay a small amount to anyone who could help — sorry no real budget for this teaching gig. Andy Dent to the rescue! I was excited to receive a response from Andy who offered to have a look at the project — as long as I didn’t tell his wife :-) Here is his response to my post: G’day Jeff Does it have to exactly match the Karel syntax? I’m pretty sure I can come very close with something in RBScript which would make it a small enough project that I could justify the time this weekend (I am very busy and you are NOT allowed to tell my wife!). I was very excited to be able to finally use RBScript for something productive. I had initially intended to have my students learn to use Karel while working within the REALbasic IDE but Andy’s idea meant we could have a freestanding Karel application which our students could use in class without introducing the additional learning curve of working within the REALbasic IDE. I now take every new student (my youngest is 8 and eldest is 65 years old) through a process of 3 x 1 hour lessons using rbKarel. I have created approx 20 Maps which begin with super simple concepts and become increasingly difficult. I have one Map which is so difficult that I have had only one student able to solve it. He actually came up with the answer at 2am after the challenge had been haunting him for two weeks. I teach each student four main concepts which I have found the most useful before moving into game development. 1) The While Loop 2) For/Next Loops 3) If Statements 4) Subroutines, methods and functions Once a new student understands these concepts we are able to start scripting games without the student getting intimidated by the more complex code used in our game projects. We are even able to write basic AI code using Karel such as the following which allows Karel to navigate through a maze. while notnexttoabeeper if frontisclear then move elseif rightisclear then turnright move elseif leftisclear then turnleft move else turnleft end wend rbKarel has transformed the way I teach and I sincerely appreciate the wonderful work of Andy Dent who brought my idea to life. November/December 2009 | REALbasic Developer | www.rbdeveloper.com 39 SetupDynamicFolderMenus() mWorldsFolder = FindSpecialFolder("KarelWorlds") mScriptsFolder = FindSpecialFolder("KarelScripts") if mWorldsFolder<>nil then FolderItemMenuItem.MakeMenuForFlatFolder App.MenuBar, "Worlds", 5, mWorldsFolder, AddressOf handleWorldsMenu, AddressOf FileIsOKAsScript end if if mScriptsFolder<>nil then FolderItemMenuItem.MakeMenuForFlatFolder App.MenuBar, "Scripts", 6, mScriptsFolder, AddressOf handleScriptsMenu, AddressOf FileIsOKAsScript end if if mOnEdge = KarelScripter.North or mOnEdge = KarelScripter.South then if street1 = street2 then return false // we don't block anything that is horizontal if street1 > street2 then dim tempStreet as integer = street1 street2 = tempStreet I got a huge kick out of writing rbKarel and it’s the closest thing I’ve done to being a games programmer. I can’t claim any credit for the design because the inspiration was Richard E. Pattis’s but I think I added a few nice usability touches. A lot of the fun of designing software comes from iterating a design and smoothing off rough edges. If you caught yourself rolling your eyes at too many statements of the obvious, with little lectures on design practices, you’re obviously experienced enough to go off and add an eye-rolling option to rbKarel! Hopefully this work will inspire a few other people to consider RBScript as a games platform and they can start with rbKarel and code their own. Jeff and I would really like to see a community of rbKarel users develop and that will give me further motivation to enhance rbKarel. I have a dream of even smarter users who start playing with the graphics properties — why can’t Karel leave a trail of breadcrumbs? References and Additional Reading Material Karel Overview: http://code.google.com/p/rbstuff/wiki/rbKarelOverview Karel the Robot home page for C++ implementation: http://www.cs.mtsu.edu/~untch/karel/ end if // swap street1 and 2 if mOnEdge = KarelScripter.North then // North is above the point if street1 <= mStreet and street2 > mStreet and ave1 <= mAvenue and ave2 >= mAvenue then return true else // South is below the point if street1 < mStreet and street2 >= mStreet and ave1 <= mAvenue and ave2 >= mAvenue then return true end if else // vertical lines if ave1 = ave2 then return false // we don't block verticals if ave1 > ave2 then dim tempAve as integer = ave1 ave1 = ave2 ave2 = tempAve Karel Java home: http://sourceforge.net/projects/karel/ Karel Java version documentation: http://karel.sourceforge.net/doc/html_mono/karel.html end if // swap ave1 and 2 if mOnEdge = KarelScripter.East then // East is right of the point Related REALbasic Developer articles: RBD 2.6 “Using RBScript” by Thomas Reed RBD 3.1 “Command-Line RBScript” by Joe Strout RBD 5.5 “Dynamic RB, Part 1” by Marc Zeedar RBD 5.6 “Dynamic RB, Part 2” by Marc Zeedar RBD 7.1 “Scripting for Fun and Profit” by Marc Zeedar RBD 7.5 “A Plugin System” by Thomas Tempelmann if street1 <= mStreet and street2 >= mStreet and ave1 <= mAvenue and ave2 > mAvenue then return true else // West is left of the point Karel The Robot: A Gentle Introduction to the Art of Programming by Richard E. Pattis: http://www.amazon.com/Karel-Robot-Gentle-Introduction-Programming/dp/0471597252 Karel++: A Gentle Introduction to the Art of Object-Oriented Programming by Joseph Bergin, Mark Stehlik, Jim Roberts, Richard E. Pattis: http://www.amazon.com/Karel-Gentle-Introduction-Object-Oriented-Programming/dp/0471138096 40 // horizontal lines street1 = street2 Conclusion Code Listing #3: KarelWall.IsBetween(ave1 as integer, street1 as integer, ave2 as integer, street2 as integer) As Boolean if street1 <= mStreet and street2 >= mStreet and ave1 < mAvenue and ave2 >= mAvenue then return true end if end if return false November/December 2009 | REALbasic Developer | www.rbdeveloper.com Beginner’s Column Title Corner by Marc Zeedar editor@rbdeveloper.com At a Glance RBD#8111 Target Reader: Beginner Source Code: Yes RB Version Required: 2006+ Platform(s) Supported: Mac OS X Platform(s) Untested: Windows XP, Linux, Mac Classic About the Author: Marc taught himself programming in high school when he bought his first computer but had no money for software. He’s had fun learning ever since. Basic RB Controls, Part 1 Exploring the RectControl class Lately I’ve been covering some fairly advanced beginner topics, so I’ve decided to take a moment to cover the obvious. Often the most simple things are not well documented or publicly explained and present awkward obstacles for those just starting out. As one simple example, I remember when I first used REALbasic being puzzled about how to group radio buttons together. If I just had one group on a window it worked fine, but two or more groups didn’t as they still acted like one group. It was a while before I realized I had to group the radio buttons inside a GroupBox for them to work in sync. So today we’re going to begin an exploration of some of the most basic of REALbasic controls. Much of this may be obvious to you, but hopefully you’ll find at least one or two nuggets of new information. Shared Basics We’ll begin by covering the most basic aspects of basic controls. In the past we’ve talked about the object-oriented principle of inheritance — that’s how you’re able to create custom subclasses of existing controls, for instance. If you look through most controls you’ll see they’re all based on a generic object called RectControl. RectControl Note that you don’t interact with a RectControl directly: REALbasic does not give you a way to create a RectControl object. Instead you’ll always work with a subclass such as a PushButton. Because of that, you may not be that familiar with the RectControl object so this could be an important primer. A RectControl has a number of standard methods, properties, and events, that, because of inheritance, all basic controls also share. This means that if you know how to programmatically set the location of a CheckBox, you also know how to set the location of a RadioButton, since both work the same way. So we’ll begin by exploring some of these shared features and later I’ll cover the unique aspects of each control. Note that this article is designed to be a general overview, not a comprehensive exploration, so I won’t spend a huge amount of time on each feature. The specifics of how each feature works are covered in the Language Reference and of course I’ve explained many of these in other columns dedicated to topics that depended on those features. Let’s start with RectControl Events. RectControl Events These are basic events that any controls based on RectControl can receive. Most of these should be familiar to you. Note that though many subclasses of RectControl can receive these events, that doesn’t necessarily make them useful. For instance, the Line control can receive a KeyDown event, but how, when, and why would you use that? Figure 1: The HelpTag feature in action. November/December 2009 | REALbasic Developer | www.rbdeveloper.com 41 A Line doesn’t really need key presses. It gains that ability via inheritance, but it’s not of much practical value. Just ignore the feature on objects that don’t need it. ConstructContextualMenu - Used to build a ContextualMenu. See RBD 6.5 for my column on working with Contextual Menus. ContextualMenuAction - Gives you a way to execute a Contextual Menu action. Again, see my article in issue 6.5 for more. DragEnter - This event happens when something is being dragged to this control. It is useful if you want to do something special with the drop, such as highlight the control in a custom manner. I wrote about drag-and-drop in RBD 7.6. Though the primary drag event I talked about was DropObject, these others should be easily understood if you understand basic drag-and-drop. DragExit - This gets called when the drag is leaving your object. For instance, perhaps the user started to drop something onto this control, then changed their mind and moved away, in which case you’d want to undo any special highlighting you did in DragEnter. DragOver - This gets called while an object is being dragged over this control. It’s primary benefit is that it passes the live x/y coordinates of the dragged object. This could be useful for live updating as the object is being dragged around, or if you had a large custom control, such as a canvas, with multiple drop targets inside it. This event gets triggered every time the dragged object moves, so you could check to see if the object is within an internal target and highlight or unhighlight that target. DropObject - This is when the user lets go of the mouse button and actually drops the object onto this control. Thoroughly covered in RBD 7.6. KeyDown - The user has pressed a key on the keyboard. The pressed key is passed to the event as a string so you can look at it to see what it is and do something with that information if you want. As mentioned earlier, not necessarily useful with many controls. Also keep in mind that this event only gets called when this control has the focus. Many basic controls, such as Lines, never get the focus, or don’t keep it (PushButtons only have to focus while being pushed). 42 KeyUp - The user has released a key on the keyboard. MouseEnter - This gets triggered when the mouse arrow enters the control’s area. It is extremely useful for providing simple “hot help.” See the Hot Help example in today’s demo project. Note that this type of help isn’t as useful as in the past now that there’s the HelpTag property (see the next section). MouseExit - This happens when the user moves the mouse pointer outside of the control. MouseMove - This event gets called when I remember when I first used REALbasic being puzzled about how to group radio buttons together. If I just had one group on a window it worked fine, but two or more groups didn’t as they still acted like one group. It was a while before I realized I had to group the radio buttons inside a GroupBox for them to work in sync. the mouse moves around inside the control. The coordinates of the pointer are passed, so if you want you can do various things based on where the cursor is pointing. MouseWheel - This gets triggered when the user scrolls a mouse wheel. Not all users have mice with wheels, but this allows you to customize the control’s response for those that do. Because wheels can be scrolled horizontally or vertically, this gives you additional input from the user. Depending on the type of control, you could scroll the control’s contents in a different manner (i.e., faster or in larger increments), or perhaps change a setting. The Slider control on the Hot Help window in today’s demo shows this with the following simple code: me.value = me.value + deltaX This adjusts the slider position based on the user’s use of the horizontal scroll wheel. (Cool feature: on a Mac OS X laptop this even works with two fingers on the touch pad to do horizontal scrolling!) Note: It’s important to remember that this event is dependent upon the mouse pointer being inside this control. If the pointer is elsewhere, this event does not get triggered. (If you wanted such behavior, you’d have to put the code inside the window’s MouseWheel event, but then your scroll wheel feature would only benefit a single control, which might be okay.) RectControl Properties Properties store information inside an object. Some are readonly, meaning you cannot change them. They are for information purposes only. Others you can change and it may change the behavior of the control. Active - This returns true or false based on whether the control is active or not. In most circumstances, it is automatically activated or deactivated (such as when its window is not frontmost). This is read-only so you cannot set this, only examine it. AutoDeactivate - You can turn the automatic deactivation feature off if you’d like. Enabled - This is where you can enable or disable a control. This is extremely useful if a control should not be useable in certain situations. For example, you might only enable a “save” PushButton if there is data that requires saving. If there is no data or it’s already saved, you would disable the button. Height - This sets or gets the height of the control. You can use this to dynamically adjust the control’s size, or use Top and Left to set the control’s position on the window. HelpTag - This sets the help text that is displayed in a small popup box when the pointer hovers over the control (see Figure 1). The disadvantage of this type of help over an always-visible help display is that the help isn’t obvious and the user may not realize it is there. Left - This sets or gets the left-most location of the control. This is relative to the window, not the screen. Note that you’re free to set this to a value off the window — that can be a useful way to hide a control without deleting it. (Though if you do that, you should disable it, since an off-screen control can still intercept user input and November/December 2009 | REALbasic Developer | www.rbdeveloper.com Figure 2: Before and After window resizing with various locked BevelButtons. Notice how the position and the shape of the buttons change depending on how their sides are “pinned” to the parent window. could create confusion. For instance, an off-screen text field could trap the user’s typing but they wouldn’t see the results on-screen and would wonder what was happening to their text.) LockBottom - This “locks” the bottom of the control. Think of it as a stick-pin into the bottom side of the control, pinning it to the window (or own parent object if this is inside something else, like a GroupBox). That way if the user resizes the window (or parent object), the bottom of the control will move with the adjusted window size. Because there are four sides to a control, you can lock any or all of them for different effects. For instance, if you just want the control to move with the window, just lock one side. If you want the control to change shape, lock several sides (see Figure 2 for some examples). LockLeft - This locks the left side. LockRight - This locks the right side. LockTop - This locks the top side. MouseCursor - This allows you to set the pointer cursor that is displayed while the pointer is within the control (if it’s not overridden by setting it within the Application class or Window). REALbasic includes a number of standard cursors within system. cursors, such as a pointing finger, grabber hand, magnifying glass, etc. Parent - This refers to the object that contains this control. That usually is the parent window, but not always. Some controls, such as PagePanels or GroupBoxes, can enclose other controls. In those cases, November/December 2009 | REALbasic Developer | www.rbdeveloper.com parent would point to that enclosing object, not the window. (That object’s parent property would presumably point to the window unless it was also nested, such as a RadioButton inside a GroupBox inside a TabPanel. Be careful about nesting too deep, however, as that can cause complications and it’s not a good idea interface-wise.) TabIndex - This is an integer value that controls the order of the controls on the window so that when the user presses the Tab key to switch between controls, the switch happens in numerical order. TabStop - If you set this to false, the user cannot tab to this control. The default is true. Top - This gets or sets the position of the top of the control on the window. Adjusting it will move the control. 43 TrueWindow - This returns the actual window parent of the control, even if it’s deeply nested inside other controls. Visible - This sets whether the control is visible or not. (Handy Tip: controls that contain a lot of data, such as ListBoxes or text fields, can be slow to fill with data while visible. Set them to invisible, fill them with data, and then make them visible again for a speed up!) Width - This gets or sets the width of the control. Window - A reference to the parent window of the object. RectControl Methods Standard methods implemented by RectControl objects are: AcceptFileDrop - This is where you set the file type of acceptable files that can be dropped on this control. You can call this method multiple times, once for each file type. If you don’t do this, the file drop will be rejected. See my drag-and-drop article in RBD 7.6. AcceptPictureDrop - You call this if you want the control to accept dropped pictures. AcceptRawDataDrop - Here you can specify a specific type of data that can be dropped on the control. AcceptTextDrop - You call this if you want the control to accept dropped text. Note that there is a difference between dropped text and a dropped text file. If you want your control to accept both, you need set your control to accept both. DrawInto - This is a rarely used command and has proven to be buggy and unreliable in my experience, but it’s a fun method to experiment with. It basically allows you to draw the control into a graphics object. You could use this to print a control, for instance (drawing it into a graphics object you are printing). Invalidate - Forces the control to immediately redraw itself. It’s similar to Refresh but happens right away. It’s useful if you’ve changed aspects of the control and need it to be updated. You can also call this specifying the region (rect) to redraw. NewDragItem - This creates a new drag item when the user’s dragging away from the control. You can specify the size of the dragged item. See my drag-and-drop article in RBD 7.6 for more. Refresh - Redraws the control when the system has time. RefreshRect - Redraws just the specified portion of the control when the system has time. SetFocus - This gives this control the focus. When a control has the focus, key presses and other inputs are sent to that control. 44 Figure 3: Today’s awesome demo project. Shared Control Features Now that we’ve covered the basic shared features of controls by going over the events, properties, and methods of the RectControl base class, there’s one more base object we should examine. RectControl itself is based on a class called Control, and it has a few events, properties, and methods that are also inherited by all other controls. Most of these will be familiar to you, but just to be thorough, I’ll go over them briefly. Control Events Controls have two basic events, Open and Close, which are triggered when the control is about to be opened and when it is about to close. Within Open you can do any initializations needed, or set various attributes of the control (such a size, label, display characteristics, data, etc.). Within the Close event you’d do any cleanup required (save data, dispose of objects, save a setting, etc.). Control Properties Most Control properties are read-only: you cannot modify them (Name, PanelIndex, and TabPanelIndex are the exceptions). Many of these properties are esoteric and rarely needed. Handle - The control’s handle. Used by advanced programmers only. (If you don’t know what a handle is, you don’t need to use this feature.) Index - The control’s number, if part of a control array. MouseX - The horizontal location of the mouse pointer, in pixels from the left edge of the window (not the screen). MouseY - The vertical location of the mouse pointer, in pixels from the top of the window. Name - The control’s name. You can change this programmatically if you want. PanelIndex - This gets or sets the panel number this control is placed upon. It is set to -1 if it’s not on any panel. Scope - This lets you know if the control’s scope is private or public. Private controls cannot be accessed from outside of their parent window. TabPanelIndex - This gets or sets the tab panel number this control is placed upon. It is set to -1 if it’s not on any panel. Window - The control’s parent window. Control Methods There’s only one method, Close, which is used to close the control. You should use this with caution as attempting to access a closed control will crash your program with a Nil Object error. Normally you don’t need to use this as the control will automatically be disposed when its parent window is closed. Usually this is used for deleting dynamic controls that are part of a control array. Conclusion That’s all we have time for today, but it’s a good start: we’ve actually covered 90% of the functionality of most basic controls! In part 2 I’ll cover some basic controls where we’ll study the unique characteristics of each control and how to use it. November/December 2009 | REALbasic Developer | www.rbdeveloper.com From Scratch ClipSaver by Brad Rhine At a Glance RBD#8112 Target Reader: Beginner Source Code: No RB Version Required: 2006+ Platform(s) Supported: Mac OS X, Windows, Linux About the Author: Brad Rhine is a database administrator and webmaster who uses a variety of languages, including PHP, Ruby, and, of course, REALbasic. Build a clipboard manager Hello, my name is Brad and I am addicted to having multiple clipboards. I can’t help myself. I don’t remember exactly when it started, but I vaguely remember how it happened. There was some sort of promotion or sale, and I ended up with a free copy of one of the more popular clipboard managers out there. I didn’t use it at first, but once I got the hang of it, I was hooked. I loved that my computer remembered the last hundred things I copied. It was so liberating. I could copy, copy, copy to my heart’s delight with nary a thought to losing my precious memories. Er... memory. Random access memory, to be exact. And to top it all, the history stayed there between restarts. So I could copy something, restart my computer, and still paste the same thing. Those were good days. you’ve cut and copied and allows you to retrieve them when necessary. The Adventure Begins But alas, progress comes at a price. Times change, and operating systems change, and things stop being compatible, and sometimes they want to charge for a minor point upgrade just because you got a freebie a couple years back. And suddenly, for the same functionality you had before, you have to pay. Well, those of you who have been reading my column for long enough will know my typical reaction to such a situation: Forget buying it; I can build it! And so we begin our bold and fateful journey to build a clipboard manager in REALbasic. Right off the bat, I know that we will have to make some compromises. First, just to keep things simple, we’re only going to worry about text that has been on the clipboard. Handling images, video, audio, and other arbitrary data is beyond the scope of this column and will be left as an exercise for the reader. Also, some of the user interface goodness I had come to love about my previous clipboard manager (no, I’m not going to identify it by name, so don’t even ask) simply won’t be easily achievable in a cross-platform application, so we’ll need to come up with a good interface that can work on multiple operating systems. But, on the other hand, we have an opportunity to improve on some things. For example, our clipboard manager will feature time and date stamps, so that we can know at a glance when we added something to the clipboard history. In addition, wouldn’t it be great if our clipboard manager could keep multiple computers in sync with the same clipboard history? As someone who uses a laptop in conjunction with several desktop machines at various locations (home, office, etc.), I would find that tremendously helpful. A Brief Explanation Designing The System For those of you who have never used a clipboard manager and may not have made it through my rambling introduction, a clipboard manager simply stores a history of items that Let’s focus now on how we want our clipboard manager to work. Obviously, there will be a timer that runs at regular intervals to capture the clipboard’s contents, but let’s step back and figure out how we want it to behave for our Trying Times November/December 2009 | REALbasic Developer | www.rbdeveloper.com 45 end user. Then we’ll lay out the interface and write the code to match the behavior that we want. Our clipboard manager should have an unobtrusive interface that sits in the background, refraining from drawing attention to itself. It should only be noticed by the user when the user wants to access the clipboard history. Duplicate items should be filtered out of the clipboard history if they occur right next to each other. In other words, if the user copies the text “Hello, world!” two or three times in a row, it should only show up in our application one time. However, if the user copies “Hello, world!”, then copies “foo”, then copies “Hello, world!” again, “Hello, world should show up twice, separated by “foo.” Our clipboard history should be easily and quickly searchable, giving our end user three ways to find information: by scanning the clipboard history, by looking for a specific time and date, or by using our search feature. Finally, we’ll need to discuss how our clipboard manager will keep multiple computers in sync. More on that later. For now, let’s turn to the interface. Building The Interface Create a new project in REALbasic. I’m using REALbasic 2008 Release 5.1. Yes, I’m a bit behind the times, but I like to stay a few versions behind in this column to accommodate those who don’t necessarily live on the bleeding edge. I called my project ClipSaver, but I encourage you to come up with a name that’s far less lame than mine. To get things started, I renamed Window1 to MainWindow and opened it up. Its default size of 600 pixels by 400 pixels will be perfect for design time, but I did make it resizable. I also added a ListBox to the window and gave it two columns. I set the column headers to “Clipboard” for column zero and “Date” for column one. I also set the ListBox’s LockLeft, LockRight, LockTop, and LockBottom properties to True, so that it resizes with the window. I gave it the name ClipBox. I also made sure its EnableDrag property was set to True. In addition, I placed an EditField in the upper right corner of the window and named it SearchField. I set its LockTop and LockRight properties to True. I also placed a StaticText to its left to act as a label. 46 Finally, I dragged a Timer onto the window and named it ClipTimer. I set its mode to 2 (so it fires repeatedly) and its period to 1000. Adding Some Code Give MainWindow a new property: LastClip As String. Now let’s open up the code editor for ClipTimer. In its Action event, ClipTimer is going to do a lot of the heavy lifting for us. First, it’s going to check to see if the clipboard has any text in it. If it does, it’s going to check the text against the last item in our clipboard history. If it matches, it bails out. If it doesn’t match, it adds it to ClipBox, along with a time and date stamp. So the first thing we need to do is instantiate a new Clipboard object and a new Date object: Dim C As New Clipboard Dim D As New Date Then we check to see if the clipboard contains any text, and we exit the method if not: If Not C.TextAvailable Then Return Next, we check to make sure the text on the clipboard doesn't match the last item we saved: If C.Text = LastClip Then Return Finally, we've made it through all those hoops and conditions, and we add the text to ClipBox, along with our time and date stamp (while assigning the current clipboard text to LastClip): LastClip = C.Text ClipBox.InsertRow(0,C.Text. ConvertEncoding(Encodings.UTF8)) ClipBox.Cell(0,1) = D.SQLDateTime ClipBox.Refresh One thing you may notice is that we’re going to convert any text we find to the UTF-8 encoding. I’m not sure of technical reasons behind this, but I found that I got the cleanest text that way. If any loyal reader can offer an explanation or alternative, I’m all ears. Getting Data Out So far, so good. We have an application that’s monitoring the clipboard and appending any new text it finds to ClipBox. But at some point, we’re going to want to do something with all those clipboard history items. So let’s enable dragging and dropping from ClipBox. We’ve already set its EnableDrag property to True, so all we have to do now is implement the DragRow event. The DragRow event gives us two parameters: Drag As DragItem and Row As Integer. Row, obviously, indicates which row of the ListBox is being dragged. Drag is an instance of a DragItem, something containing arbitrary data (in our case, plain text) that can be dragged from one program to another. What we’ll to do is set Drag’s Text property. But before any of that, we have to make sure we have a valid, existing ListBox row: If Row = -1 Then Return False Returning False tells REALbasic that we haven’t done anything to handle the Drag event, and that the system should do whatever it would normally do, which is, in this case, nothing. Now to set Drag’s Text property: Drag.Text = Me.Cell(Row,0) Finally, we need to return True, to tell REALbasic that we have indeed handled the Drag, and that it no longer needs to worry about doing the right thing: Return True Go ahead and run the project to see what we’ve got so far. You should now, after copying a few things to load up your clipboard history, be able to drag items out of the ListBox and into other applications. Data Storage Quit the application and run it again. Did you notice the problem? Our clipboard history is lost between application runs. That is, in very technical terms, a bad thing. We want our clipboard to be saved not only between application runs, but between restarts, and ideally on multiple computers. So it goes without saying that we’ll need to store the clipboard history somewhere on disk. The questions are where and how? What format should we use and where should we store it? This brings up a related question: how do November/December 2009 | REALbasic Developer | www.rbdeveloper.com we store the data in such a way as to enable simultaneous access from multiple computers. We have a few possibilities for data storage. One would be a simple delimited text file. On the plus side, this would be very easy to implement in REALbasic, and it should be relatively fast, as long as we limit our clipboard history to a reasonable number of entries, such as one hundred. On the negative side, access from multiple computers could be problematic. Location of the file could be as simple as using a service like DropBox, but multiple copies of our clipboard manager could potentially be reading and/or writing to the file at the same time. Unless managed very carefully, that could end up not working at all, or worse, destroying user data. Another possibility is to designate one computer as the master and develop a protocol to manage clipboard synchronization over a network. On the up side, this stands an excellent chance of keeping the history synchronized in real time. There are multiple downsides. For starters, managing network transfers like that isn’t really for the faint of heart. It’s not terribly hard if you know what you’re doing, but for newcomers to either REALbasic or networking in general, it can be a rather daunting task. Secondly, what happens when the master computer is offline? Do we cache our multiple histories locally and them merge them when the master computer is available? There would be a lot of details to sweat out with this implementation, but it has the potential to be very successful. A third possibility, and the last that we’ll entertain, is to use a database server. On the positive side, this should make synchronizing our clipboard history a piece of cake: a few SQL queries here and there, and it’s done. It would also make implementing our search feature very easy. But with great upsides often come great downsides. It would require setting up a database server, such as REAL Server, PostgreSQL, or MySQL, which is beyond the skill level of many developers. And the server would always have to be available, so a machine that’s accessible across the internet would be best. Not everyone has access to such a computer or server setup. A Cliffhanger? Seriously? So what do we do? How will we choose? Tune in next time to find out. Until then, happy coding! By the way, I’ll make the source code available in the next issue (when there’s more to show). Get RBD Year 7 in print form! • Quality perfect-bound book • 330+ pages • Color cover, black insides • Complete issues 7.1–7.6 • 25% off retail price for current RBD subscribers Order today at www.rbdeveloper.com November/December 2009 | REALbasic Developer | www.rbdeveloper.com 47 BKeeney Briefs Reporting Tools by Bob Keeney bkeeney@rbdeveloper.com At a Glance RBD#8113 Target Reader: Beginner Source Code: No Platform(s) Supported: Mac OS X, Windows XP, Linux, Mac Classic About the Author: Bob is the owner of BKeeney Software located in Kansas City. He is a founder and the current President of the Association of REALbasic Professionals. Database reporting It’s been a pretty amazing year and a half since Real World 2008. During the conference, between sessions, and even in the after-hours events, I’ve had conversations with many REALbasic developers about the lack of reporting options for REALbasic. I’ve even lobbied every REAL Software employee that I could bend the ear of for a built-in reporting tool. The community obviously thought it was a pretty important thing as well. In the 2008 Association of REALbasic Professionals “Wish List” Survey, it was the top rated wish among ARBP and non-ARBP survey takers alike. REAL Software was listening as well. When I spoke at the REALbasic Summit in Boulder, Colorado in late September of this year, I was pleased to do an hour long session on nothing but reporting tools. Instead of just one, there are now several options! Here is a summary of what is available. O n - T a r g e t R e p o r t s (http://www.ontargetreports.com) was the only commercially available option a year and a half ago. This ‘banded’ report designer allows you to save your report templates to disk and use them in your REALbasic application. Many developers have been frustrated with On-Target in recent years, but a recent update and a push for better support makes On Target a reasonable choice. Valentina Reports (http://valentina-db.com/index. php/en/products/valentina-reports) is a banded reporting tool and a relative newcomer to the reporting field but they’ve been in the When I spoke at the REALbasic Summit in Boulder, Colorado in late September of this year, I was pleased to do an hour long session on nothing but reporting tools. Instead of just one, there are now several options! 48 REALbasic arena for many years. Their external designer is very nice but a little buggy. It also only works with Valentina databases, which is either a strength or weakness depending upon your needs. The Valentina Reports tool does a good job with Sub-Reporting. Like On Target Reports, Valentina Reports can be used outside of your RB application. RSReport (http://www.rothsoft.ch/realbasic/ rsreport/) is a non-banded reporting tool. Non-banded reporting tools have you place every object (even repeating data fields) on the page and you have to keep track of page placement for pagination purposes. Even though it’s not a ‘banded’ reporting tool it’s fairly easy to create repeating lines of data. RSReport is also introducing a report designer using external formats that should be available by the time you read this. The report viewer and designer are both drop-in RB container controls. Einhugur Reports (http://www.einhugur.com/ EinhugurReports/) is currently in development and it’s hard to tell if this product will ever see the light of day considering the competition. It makes extensive use of the Einhugur plugins which makes this ‘free in development’ tool not so free. The tool has a drop in viewer/designer (They are one component!) which is interesting and it makes use of an external file format as well. Turbo-Report (http://www.turboreport.com/) is an open source non-banded report tool. Like RSReport you have to place all elements on the page so it takes a little bit more time to set up and use. It has an interesting ‘table’ feature that makes repeating rows simple to use. RBRW (http://code.google.com/p/rbrw-core/) is another open source reporting tool and it’s been ported to REALbasic from C++ by its creator Andy Dent. It’s a big, November/December 2009 | REALbasic Developer | www.rbdeveloper.com Figure 1: On-Target Reports. Figure 2: REALbasic’s Report Designer. November/December 2009 | REALbasic Developer | www.rbdeveloper.com 49 Figure 3: Valentina Reports. complex project that has some interesting features and is definitely worth looking at. The new kid on the block is REAL Software’s reporting tool that I’m dubbing REAL Reports (for lack of a better name) which was introduced in RB 2009 Release 4. The banded report designer is integrated into the REALbasic IDE and is fairly easy to use and it works with any database supported by RB as well as other types of data sources. It’s a little too early to tell how well this tool will work for beginning and advanced RB users, but since it ships with RB it’s now the de-facto standard for reporting tools and all others will be compared to it from now on. I wouldn’t hesitate to look at any of these reporting tools. I was surprised at how well they all worked despite some being relatively new or being sparsely documented. Depending upon your needs, each one has some interesting strengths and weaknesses. All are inexpensive when compared to their counterparts available in the Windows world. What they all lack, however, is runtime interaction. Runtime interaction means allowing the user to click on a report object and receiving an event at runtime that allows the developer to present a more detailed report (or do some other interesting things). Some call this ‘drill down’ capabilities. An example of this would be a Chart of Accounts report typical in many accounting applications. If the Vehicle account seems really high, the user could double click on it and be presented with an account detail report rather than running the report manually. Exporting options are relatively limited as well. A few have PDF export but nearly all have some sort of graphical export. This is a far cry from the Microsoft Office and email format options available for Windows developers using Crystal Reports and Active Reports. Hopefully it won’t take another 18 months to get some more advanced features. Happy coding! 50 Writ e fo r RBD! Have an idea for an article? Want to contribute a Review or Postmortem? We’re always looking for new material! Send a query letter to editor@rbdeveloper.com describing your idea. If we’re interested, we’ll contact you and establish a schedule. Read our Writer’s Guidelines: http://www.rbdeveloper.com/ writerguidelines.shtml November/December 2009 | REALbasic Developer | www.rbdeveloper.com Databases for REAL by Paul Lefebvre plefebvre@rbdeveloper.com At a Glance RBD#8114 Target Reader: Intermediate RB Version Required: 2009r4 Source Code: No About the Author: Paul Lefebvre has been using REALbasic for 8 years and is the owner of LogicalVue Software, RBDevZone, and a founding member of the Association of REALbasic Professionals. Reporting with REALbasic REALbasic 2009 Release 4 On September 29th, REAL Software shipped REALbasic 2009 Release 4. Its big new feature? You guessed it: reporting! That’s right, the REALbasic IDE now has a built-in report designer! So without further ado, let’s take a look at it. A Quick Overview To create a report in REALbasic 2009r, you first need to add a report object to your project. To do this select Project->Add->Report. You can also edit your toolbar to add an “Add Report” button. Figure 1 shows what the report designer looks like. As you can see, it has three main areas. A list of controls on the left, the main editor window in the center and the properties editor on the right. REALbasic supports these report controls: ■ ■ Field ■ ■ Label ■ ■ Picture ■ ■ Line ■ ■ Oval ■ ■ Rectangle ■ ■ RoundRectangle Just drag one of these controls to the report editing area to add it to the report. Each control that you add, has its own set of properties that you can modify. In addition, each control has two events associated with it (AfterPrinting and BeforePrinting) where you can put your own code. The report designer also supports grouping and a wide variety of data sources. For more information, be sure to check out Chapter 8 in the REALbasic User’s Guide and to look up the various reporting classes in the Language Reference. Creating a Report To start using REALbasic reports, launch REALbasic 2009 Release 4 and create a new project, which we’ll call RBDReport. Add a new report object to this project and call it MyFirstReport. Double-click the report to start editing it. We’ll start simple, so just drag a Label onto the PageHeader section of the report designer. Change its name to HeaderLabel and play around with the properties. I made mine bigger, increased the font size and centered it. Now let’s add a couple fields to the report. Drag two Fields to the Body section of the report designer. Change their DataField properties to FirstName and LastName, respectively and position them next to each other (see Figure 2). Next, we want to actually view the report. Unfortunately, you’ll have to do a bit more work here. The designer does not have built-in preview capability (no, File->Print does not actually print a preview of the report). November/December 2009 | REALbasic Developer | www.rbdeveloper.com 51 Figure 1: REALbasic Report Editor Creating A DataSet First we’ll need some data for the report. We’ll create our own simple class that will always return the same data. You can also use a database as a data source or have a class that pulls data from text files (or wherever else you might have your data). We’ll use the class method as it’s a bit trickier to get started with. Using a database RecordSet is quite easy so you can just refer to the REALbasic documentation for that. Create a new class called SimpleDataSet and specify Reports.DataSet as its Interface. You’ll be prompted by REALbasic to have it add the methods for the interface for you. You should answer Yes. When you open SimpleDataSet, you’ll now see that it has several methods which need to be implemented. Before we do that, though, we’ll need to create a couple properties to help track our state: Private mCurrentRow As Integer Private mData() As String Run This method contains code to initialize the data. In our case we’ll just populate a simple array with a couple names and set it to start at the first row. Code: // DataSet consists of two columns, FirstName and LastName (separated by commas) Dim row As String 52 row = "Bob,Roberts" mData.Append(row) row = "Bilbo,Baggins" mData.Append(row) mCurrentRow = 0 NextRecord This method increases our internal row counter: mCurrentRow = mCurrentRow + 1 EOF As Boolean This method simply returns True when we’ve reached the end of the data. If mCurrentRow > mData.Ubound Then Return True Else Return False End If Field(idx As Integer) As Variant This method returns a specific field value for the current row. The field index is a 0-based integer: // Get the specified field data for the current row Dim row As String November/December 2009 | REALbasic Developer | www.rbdeveloper.com Figure 2: Our Sample Report Layout row = mData(mCurrentRow) Dim columns() As String columns = SplitB(row, ",") Return columns(idx) Field(name As String) As Variant This method looks up the field data based on the fields name. We just call the above Field implementation to get this: Select Case name Case "FirstName" Return Field(0) Case "LastName" Return Field(1) Else Return Nil End Select Type(fieldName As String) As Integer This method returns the data type of the specified field name. Since our simple data set only has two fields and they’re both Strings, the code is simple: Select Case fieldName Case "FirstName", "LastName" Return 5 // Text End Select Displaying and Printing the Report Now that we have some sample data, we can go ahead with displaying and printing the report. Open the default window in the project and add the following: ■■ a Canvas control and name it ReportViewer PushButton and name it RunReportButton ■ ■ a PushButton and name it PrintReportButton ■ ■ a method called RunReport(print As Boolean) ■ ■ a property: Private Property mCurrentPage As Picture ■■ a Now we can add the necessary code. We’ll start with the RunReport method since it is where all the work is done. We create our DataSet and pass it to the report engine. Note the different code paths when printing the report versus just displaying it: Dim ps As New PrinterSetup Dim output As Graphics If print Then November/December 2009 | REALbasic Developer | www.rbdeveloper.com 53 Figure 3: The Completed Report If ps.PageSetupDialog Then output = OpenPrinterDialog(ps, Self) End If End If End If To run the report when the Run Report button is clicked, the Action event is this: RunReport(False) Dim ds As New SimpleDataSet And lastly, the Print Button code is this: Dim rpt As New Report rpt = New MyFirstReport RunReport(True) If rpt.Run(ds, ps) Then Dim rptPage As Reports.Document rptPage = rpt.Document If rptPage <> Nil Then If print Then rptPage.Print(output) Else mCurrentPage = rptPage.Page(1) ReportViewer.Refresh End If End If End If That’s it. You can now run the project, click the Run Report button and see your report displayed (see Figure 3). Click the Print Report button to be prompted to print it. Summary It’s great to see reports as a built-in feature of REALbasic. The designer is easy to work with and it is nice to be able to use anything as a data source. Features I’d like to see added: ■ ■ an Our Canvas needs to paint the picture, so it’s Paint event looks like this: If mCurrentPage <> Nil Then g.DrawPicture(mCurrentPage, 0, 0, Me.Width, Me.Height) 54 included report viewer rather than having to create our own ■ ■ an ability to preview the report while designing it ■ ■ a way to allow end users to create reports ■ ■ a way to load reports externally at run-time November/December 2009 | REALbasic Developer | www.rbdeveloper.com Diets leaving you hungry? Learn the secrets to huge meals that let you lose weight in Marc Zeedar’s new book, Eating BIG While Eating Lean. Available in print and PDF from www.eatingbig.com Get RBD in book form! Quality perfectbound books ■■ 300+ pages each ■■ Color cover, black insides ■■ Complete issues of each year ■■ Discount for current RBD subscribers ■■ Order today at www.rbdeveloper.com New to REALbasic Developer? You need all the issues! Order back issues in Print or on CD! Volume 1 Volume 2 All Six CDs Now Available! Volume 3 Volume 4 Printed back issues available while supplies last! CDs Include Issues in high-res PDF format, searchable database, project files, REALbasic University archive, and more! Volume 5 Order today—this offer is for a limited time! www.rbdeveloper.com/cd/ REALbasic is a registered trademark of REAL Software, Inc. REALbasic Developer is not affiliated with REAL Software.
Similar documents
- MonkeyBread Software
better integration in the future Cocoa REALbasic target. For compressions there is the zlib compression engine, but now also the BZip2 engine. The plug-ins require REALbasic 2006r4 or newer. While ...
More information