AppleScript Studio® Programming for the Absolute Beginner
JERRY LEE FORD, JR.
© 2007 Thomson Course Technology, a division of Thomson Learning Inc. All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval system without written permission from Thomson Course Technology PTR, except for the inclusion of brief quotations in a review. The Thomson Course Technology PTR logo and related trade dress are trademarks of Thomson Course Technology, a division of Thomson Learning Inc., and may not be used without written permission.
Publisher and General Manager, Thomson Course Technology PTR: Stacy L. Hiquet Associate Director of Marketing: Sarah O’Donnell Manager of Editorial Services: Heather Talbot Marketing Manager: Mark Hughes
AppleScript, AppleScript Studio, Finder, iTunes, Mac OS, and Xcode are trademarks of Apple Computer, Inc., registered in the U.S. and other countries.
Acquisitions Editor: Mitzi Koontz
All other trademarks are the property of their respective owners.
Marketing Coordinator: Adena Flitt
Important: Thomson Course Technology PTR cannot provide software support. Please contact the appropriate software manufacturer’s technical support line or Web site for assistance.
Project Editor: Jenny Davidson
Thomson Course Technology PTR and the author have attempted throughout this book to distinguish proprietary trademarks from descriptive terms by following the capitalization style used by the manufacturer. Information contained in this book has been obtained by Thomson Course Technology PTR from sources believed to be reliable. However, because of the possibility of human or mechanical error by our sources, Thomson Course Technology PTR, or others, the Publisher does not guarantee the accuracy, adequacy, or completeness of any information and is not responsible for any errors or omissions or the results obtained from use of such information. Readers should be particularly aware of the fact that the Internet is an ever-changing entity. Some facts may have changed since this book went to press. Educational facilities, companies, and organizations interested in multiple copies or licensing of this book should contact the Publisher for quantity discount information. Training manuals, CD-ROMs, and portions of this book are also available individually or can be tailored for specific needs. ISBN-10: 1-59863-303-1 ISBN-13: 978-1-59863-303-0 eISBN-10: 1-59863-781-9 Library of Congress Catalog Card Number: 2006904399 Printed in the United States of America 07 08 09 10 11 PH 10 9 8 7 6 5 4 3 2 1
Thomson Course Technology PTR, a division of Thomson Learning Inc. 25 Thomson Place Boston, MA 02210 http://www.courseptr.com
Technical Reviewer: John Flynt PTR Editorial Services Coordinator: Erin Johnson Interior Layout Tech: Digital Publishing Solutions Cover Designer: Mike Tanamachi Indexer: Larry Sweazy Proofreader: Gene Redding
To my wonderful children, Alexander, William, and Molly, and my beautiful wife, Mary.
ACKNOWLEDGMENTS his book represents the hard work and effort of many individuals. I would like to thank Mitzi Koontz,, this book’s acquisitions editor. Thanks also go out to John Flynt, who served as the book’s technical editor. I’d be remiss if I did not thank Jenny Davidson for lending her considerable talents as both project and copy editor. Finally, I’d like to thank everyone else at Thomson Course Technology for all their contributions and hard work.
T
ABOUT THE AUTHOR erry Lee Ford, Jr. is an author, educator, and an IT professional with over 17 years of experience in information technology, including roles as an automation analyst, technical manager, technical support analyst, automation engineer, and security analyst. Jerry has a master’s degree in Business Administration from Virginia Commonwealth University in Richmond, Virginia. He is the author of 18 books and co-author of 2 additional books. His published works include Beginning REALbasic, Perl Programming for the Absolute Beginner, Microsoft Visual Basic 2005 Express Edition Programming for the Absolute Beginner, VBScript Professional Projects, Microsoft Windows Shell Scripting and WSH Administrator’s Guide, Learn VBScript in a Weekend, Microsoft Windows Shell Scripting for the Absolute Beginner, Learn JavaScript in a Weekend, and Microsoft Windows XP Professional Administrator’s Guide. He has over five years’ experience as an adjunct instructor teaching networking courses in Information Technology. Jerry lives in Richmond, Virginia, with his wife, Mary, and their children William, Alexander, and Molly.
J
Table of Contents
Introduction........................................................... xii Why AppleScript Studio?................................................................................................. xiii Who Should Read This Book?.......................................................................................... xiv What You Need to Begin.................................................................................................... xv How This Book Is Organized............................................................................................ xvi Conventions Used in This Book...................................................................................... xix
Part I
Introducing AppleScript Studio...............................1
Chapter 1
AppleScript Studio Basics.........................................3 Project Preview: The Knock-Knock Application............................................................. 4 Introducing AppleScript Studio......................................................................................... 6 A Little AppleScript Studio History .......................................................................... 6 A Quick Overview of AppleScript Studio Components ....................................... 6 A Few Words About Object-Oriented Programming..................................................... 8 AppleScript: AppleScript Studio’s Programming Language....................................... 9 When to Write AppleScript ...................................................................................... 11 When to Develop AppleScript Studio Applications ........................................... 11 Working with the Script Editor............................................................................... 12 Accessing Application Dictionaries........................................................................ 15 Back to the Knock-Knock Application............................................................................ 17 Designing the Game ................................................................................................... 18 Step 1: Creating a New AppleScript Studio Application................................... 19 Step 2: Creating a Graphical User Interface......................................................... 21 Step 3: Modifying Control Attributes and Attaching Controls to Event Handlers......................................................................................................................... 25 Step 4: Editing Your AppleScript............................................................................. 28 Step 5: Building and Running Your Mac OS X Application.............................. 30 Summary................................................................................................................................ 30
vi
AppleScript Studio Programming for the Absolute Beginner
Chapter 2
The AppleScript Studio Application Development Environment............................................................. 31 Project Preview: The AppleScript Studio Fortune Teller Game............................... 32 Project Templates................................................................................................................ 33 Setting Xcode Preferences................................................................................................. 36 Working with the Xcode Project Window.................................................................... 37 The Project Window Toolbar.................................................................................... 38 Groups & Files .............................................................................................................. 38 The Project Windows Detail View........................................................................... 40 The Editor Window..................................................................................................... 41 The Info Window......................................................................................................... 46 Integration with the Interface Builder.......................................................................... 48 The Terminology Browser.................................................................................................. 48 Debugging Capabilities...................................................................................................... 49 The Apple Developer Reference Library......................................................................... 50 Back to the AppleScript Studio Fortune Teller Game................................................ 51 Designing the AppleScript Studio Fortune Teller Game .................................. 51 Step 1: Creating a New Project................................................................................. 52 Step 2: Creating the User Interface......................................................................... 52 Step 3: Attaching Controls to Event Handlers..................................................... 55 Step 4: Adding a Little Programming Logic ......................................................... 56 Step 5: Testing the Execution of the AppleScript Studio Fortune Teller Application.................................................................................................................... 57 Summary................................................................................................................................ 58
Chapter 3
Building a Graphical User Interface................... 59 Project Preview: The Typo-Matic Typing Test Game................................................... 60 Create Graphical User Interfaces..................................................................................... 63 Cocoa Controls ............................................................................................................. 65 MainMenu.nib .............................................................................................................. 67 MainMenu.nib – MainMenu ..................................................................................... 67 Window.......................................................................................................................... 68 Cocoa Interface Elements.................................................................................................. 68 Cocoa Menus................................................................................................................. 68 Cocoa Controls and Indicators ................................................................................ 74 Cocoa Text Controls.................................................................................................... 80 Cocoa Windows............................................................................................................ 83 Cocoa Data Views ........................................................................................................ 93 Cocoa Container Views .............................................................................................. 94 Back to the Typo-Matic Typing Test Game.................................................................... 95 Designing the Game ................................................................................................... 95 Step 1: Creating a New Project................................................................................. 96
Contents
vii
Step 2: Creating the User Interface......................................................................... 96 Step 3: Customizing Menus and Control Attributes, and Associating Controls with Event Handlers.................................................................................. 97 Step 4: Adding a Little Programming Logic ....................................................... 100 Step 5: Testing the Execution of the Typo-matic Typing Test Game Application.................................................................................................................. 104 Summary.............................................................................................................................. 105
Part II
Learning How to Write AppleScripts..................107
Chapter 4
Working with Values, Variables, and Classes. 109 Project Preview: The Star Trek Trivia Game............................................................... 109 AppleScript—The Technology......................................................................................... 112 AppleScript—The Scripting Language.......................................................................... 112 Language Extensibility............................................................................................. 112 Language Features .................................................................................................... 113 Managing Data Using Variables..................................................................................... 116 Storing Values in Variables..................................................................................... 116 Retrieving Variable Values...................................................................................... 117 Naming Variables.............................................................................................................. 118 Case Sensitivity .......................................................................................................... 119 Undefined Variables ................................................................................................. 120 Working with Different Variable Classes.................................................................... 121 The String Class ......................................................................................................... 121 The Real Class ............................................................................................................. 121 The Integer Class ....................................................................................................... 121 The Date Class ............................................................................................................ 122 The Boolean Class...................................................................................................... 124 Back to the Star Trek Trivia Game................................................................................ 124 Designing the Game ................................................................................................. 124 Step 1: Creating a New Project............................................................................... 125 Step 2: Creating the User Interface....................................................................... 125 Step 3: Customizing Control Properties.............................................................. 128 Step 4: Adding a Little Programming Logic ....................................................... 129 Step 5: Testing the Execution of the Star Trek Trivia Game .......................... 138 Application Code Review......................................................................................... 139 Summary.............................................................................................................................. 142
viii
AppleScript Studio Programming for the Absolute Beginner
Chapter 5
Applying Conditional Logic and Building Loops........................................................................ 145 Project Preview: The Guess a Number Game............................................................. 146 Implementing Conditional Logic.................................................................................. 149 The if Statement ........................................................................................................ 149 The if…else Statement .............................................................................................. 150 The if…else if Statement .......................................................................................... 151 Nested if Statements ................................................................................................ 152 Different Types of Comparisons.................................................................................... 153 Building Compound Tests............................................................................................... 154 Iterative Processing........................................................................................................... 155 Creating an Endless Loop ........................................................................................ 156 Iterating a Set Number of Times ........................................................................... 157 Looping While a Condition Proves true .............................................................. 157 Looping Until a Condition Proves false............................................................... 158 Controlling Loop Execution with a Counter...................................................... 159 Processing List Contents.......................................................................................... 159 Back to the Guess a Number Game............................................................................... 160 Step 1: Creating a New Project............................................................................... 160 Step 2: Creating the User Interface....................................................................... 161 Step 3: Customizing Control Properties.............................................................. 163 Step 4: Adding a Little Programming Logic ....................................................... 165 Step 5: Testing the Execution of the Guess a Number Game ........................ 171 Summary.............................................................................................................................. 171
Chapter 6
Working with Strings, Lists, and Records......... 173 Project Preview: Alexander’s Tall Tale......................................................................... 174 Manipulating Strings........................................................................................................ 176 Assigning Strings to Variables ............................................................................... 176 Getting Information About a String .................................................................... 176 Concatenating Strings ............................................................................................. 177 Controlling String Format ...................................................................................... 177 Advanced Comparisons ........................................................................................... 178 Working with Characters, Words, and Paragraphs ......................................... 180 Defining and Accessing Lists.......................................................................................... 181 Working with Lists.................................................................................................... 181 Retrieving Elements from a List............................................................................ 182 Making Changes to Lists.......................................................................................... 183 Storing and Retrieving Data Using Records............................................................... 184 Creating and Accessing Records............................................................................ 184 Modifying Record Property Values ....................................................................... 185 Working with a List of Records ............................................................................. 185
Contents
ix
Back to Alexander’s Tall Tale.......................................................................................... 186 Step 1: Creating a New Project............................................................................... 187 Step 2: Creating the User Interface....................................................................... 187 Step 3: Customizing Control Properties.............................................................. 188 Step 4: Adding a Little Program Code .................................................................. 191 Step 5: Testing the Execution of Alexander’s Tall Tale Game ....................... 195 Summary.............................................................................................................................. 195
Chapter 7
Organizing Scripts with Handlers..................... 197 Project Preview: The Rock, Paper, Scissors Game...................................................... 198 Working with Event Handlers....................................................................................... 200 Creating Custom Event Handlers ......................................................................... 201 Defining and Calling Handlers.............................................................................. 201 Passing Arguments to Handlers ............................................................................ 202 Returning a Result from an Event Handler ....................................................... 204 Understanding Scope....................................................................................................... 205 Local Scope .................................................................................................................. 205 Global Scope ............................................................................................................... 206 Back to the Rock, Paper, Scissors Game....................................................................... 208 Step 1: Creating a New Project............................................................................... 209 Step 2: Creating the User Interface....................................................................... 209 Step 3: Customizing Control Properties.............................................................. 211 Step 4: Adding a Little Programming Logic ....................................................... 212 Step 5: Testing the Execution of the Rock, Paper, Scissors Game ................ 220 Summary.............................................................................................................................. 221
Part III
Advanced Topics.....................................................223
Chapter 8
Working with Files and Folders......................... 225 Project Preview: The Slot Machine Game.................................................................... 225 Mac and POSIX Paths........................................................................................................ 228 Full and Relative Paths..................................................................................................... 230 Establishing a File Reference.......................................................................................... 231 Working with Text Files................................................................................................... 233 Accessing Files and Folders..................................................................................... 233 Reading from and Writing to Files....................................................................... 234 Creating Small Database Files........................................................................................ 238 Creating and Saving the Database File................................................................ 238 Retrieving and Accessing Database Records ...................................................... 239 Back to the Slot Machine Game..................................................................................... 242 Step 1: Creating a New Project............................................................................... 243
x
AppleScript Studio Programming for the Absolute Beginner
Step 2: Creating the User Interface....................................................................... 243 Step 3: Customizing Control Properties.............................................................. 244 Step 4: Adding a Little Programming Logic ....................................................... 245 Step 5: Testing the Execution of the Slot Machine Game .............................. 253 Summary.............................................................................................................................. 253
Chapter 9
Controlling Other Applications........................ 255 Project Preview: The Tic-Tac-Toe Game........................................................................ 256 Automating Mac OS X Applications............................................................................. 258 Accessing Application Terminology............................................................................. 258 Application Dictionaries ......................................................................................... 259 Using tell to Direct Messages to Application Targets ...................................... 261 Automating Mac OS X Applications............................................................................. 261 TextEdit........................................................................................................................ 261 Finder............................................................................................................................ 263 iTunes ........................................................................................................................... 263 Terminal ...................................................................................................................... 264 DVD ............................................................................................................................... 264 Address Book .............................................................................................................. 265 Safari............................................................................................................................. 265 Mail ............................................................................................................................... 266 System Events............................................................................................................. 266 Help Viewer................................................................................................................. 267 Back to the Tic-Tac-Toe Game......................................................................................... 268 Step 1: Creating a New Project............................................................................... 268 Step 2: Creating the User Interface....................................................................... 268 Step 3: Customizing Control Properties.............................................................. 269 Step 4: Adding a Little Programming Logic ....................................................... 273 Step 5: Testing the Execution of the Tic-Tac-Toe Game................................... 283 Summary.............................................................................................................................. 283
Chapter 10
Debugging and Error Handling......................... 285 Project Preview: The Poker Dice Game........................................................................ 286 Finding Ways of Handling Errors.................................................................................. 289 Different Types of Errors................................................................................................. 290 Syntax Errors .............................................................................................................. 290 Logical Errors.............................................................................................................. 291 Runtime Errors .......................................................................................................... 291 Handling Errors.................................................................................................................. 292 Using the try Statement to Catch Errors............................................................. 292 Catching Specific Types of Errors.......................................................................... 295 Keeping a Watchful Eye on Your AppleScript Studio Applications..................... 296
Contents
xi
Writing Output to the Log ...................................................................................... 296 Displaying Useful Information in Popup Dialogs ............................................ 297 Using Sound to Indicate When Key Events Occur ............................................ 298 Reviewing Error Messages....................................................................................... 298 Debugging Your AppleScript Studio Applications................................................... 300 Running Your AppleScript Studio Applications in the Debugger ............... 300 Setting Breakpoints .................................................................................................. 302 Controlling Statement Execution......................................................................... 303 Back to the Poker Dice Game.......................................................................................... 304 Step 1: Creating a New Project............................................................................... 304 Step 2: Creating the Game’s Windows ................................................................ 304 Step 3: Customizing Control Properties.............................................................. 307 Step 4: Adding a Little Programming Logic ....................................................... 311 Step 5: Testing the Execution of the Poker Dice Game ................................... 321 Summary.............................................................................................................................. 321
Part IV
Appendices...............................................................323
Appendix A
What’s on the Companion Website?.................... 325 The Book’s Source Code................................................................................................... 326
Appendix B
What Next?............................................................. 327 Recommended Reading................................................................................................... 327 Locating AppleScript Studio Resources Online......................................................... 329 Apple’s AppleScript Studio Web Pages ................................................................ 329 Apple’s AppleScript Web Pages.............................................................................. 330 MacScripter.net.......................................................................................................... 331 Cocoa Dev Central ..................................................................................................... 332 AppleScript Studio Mailing Lists................................................................................... 333 Apple’s Applescript-Studio Mailing List .............................................................. 333 Apple’s Applescript-implementors Mailing List................................................ 334 Apple’s Applescript-users Mailing List................................................................. 335 MacScripter’s AppleScript Studio and Xcode Mailing List ............................. 336 Yahoo! Groups: AppleScript Mailing List ............................................................ 337 The AppleScript Studio – How to Mailing List................................................... 338
Glossary..................................................................341 Index..........................................................................351
INTRODUCTION elcome to AppleScript Studio Programming for the Absolute Beginner. AppleScript Studio is a collection of tools that work together to create a powerful application development environment that supports the development of native Mac OS X applications. AppleScript Studio supports the creation of graphical desktop applications using the AppleScript scripting language to provide the underlying program code. AppleScript is an English-like scripting language that provides the ability to interact with the Mac OS X operating system and to control the execution of desktop applications.
W
AppleScript is a popular scripting language that is native to Mac OS X. It comes preinstalled and ready to run. Apple users, hobbyists, and programmers have used it for many years to develop scripts that automate tasks by developing workflows that control multiple applications in order to perform specific tasks. AppleScript is especially useful for automating tasks that you find yourself performing repeatedly. For example, you might use AppleScript to automate the process of moving downloaded image files from your digital camera to a particular folder, changing the file type of each image to .gif or .jpeg, and then using your preferred photo manager application to print them. AppleScript provides minimal support for interaction with users, limited to a small collection of popup dialogs. AppleScript Studio fills this gap by providing you with all the tools necessary to build a graphical user interface or GUI for your AppleScripts. AppleScript Studio lets you build full-featured, user-friendly desktop applications using AppleScript instead of more complicated programming languages like C or Objective-C. Your AppleScript Studio applications can include buttons, text boxes, sliders, and just about any other graphical element that is found on even the most advanced Mac OS X application. In short, AppleScript Studio significantly simplifies the process of developing desktop applications that run on Mac OS X, making it a perfect programming language for first-time programmers and hobbyists, while at the same time providing professional programmers with a powerful tool that rivals other high-powered programming languages. This book is focused on teaching you everything that you need to know to begin developing your own AppleScript Studio applications. This includes instruction on learning how to program using AppleScript. In addition, you will also learn
Introduction
xiii
about other technologies that AppleScript Studio taps into in order to enable application development.
WHY APPLESCRIPT STUDIO? ppleScript Studio is a free application development tool provided by Apple. AppleScript Studio does more than simply allow you to develop graphical user interfaces for AppleScripts. AppleScript Studio is actually a suite of programming tools that work together to provide a powerful application development environment. These tools include:
A
• AppleScript. The scripting language used to develop the programming logic that drives AppleScript Studio applications. • Xcode. A program editor that provides sophisticated editing and script debugging capabilities as well as easy access to online AppleScript Studio documentation. • Interface Builder. A tool that provides everything needed to easily and quickly add windows to your AppleScript Studio applications and then customize them by adding buttons, text controls, sliders, image controls, menus, and a host of other graphical elements. • The Cocoa Application Framework. A behind the scenes technology that provides AppleScript Studio applications with numerous built-in features. These features include the ability to use controls found in the Interface Builder without having to develop the program code that makes windows maximize and minimize or that makes interface controls operate as you would expect. AppleScript Studio provides Mac users and programmers with the ability to develop graphical applications that interact with users via the mouse and keyboard. Because these applications use AppleScript as the underlying scripting language, it takes less time to learn how to develop applications using AppleScript Studio than it does with other Mac OS X programming languages. Its simplicity, combined with the English-like syntax of the AppleScript language, makes AppleScript Studio a perfect place to start for first-time programmers and hobbyists. However, professional programmers can benefit from AppleScript Studio as well. AppleScript Studio provides everything that is needed to quickly create prototype applications and demonstrate proof of concept before investing the time required to build an application using another
xiv
AppleScript Studio Programming for the Absolute Beginner
programming language. Professional programmers will find that AppleScript Studio applications can be developed in a fraction of the time that it might take to create the same application in different programming languages such as C or Objective-C. In short, anyone who aspires to develop applications that run on Mac OS X, can benefit from learning AppleScript Studio. It can be used to add a GUI to any existing AppleScript and to develop entirely new applications from scratch. It is a perfect tool for developing time-saving applications that automate repetitive tasks. Not only will it help you to work more quickly, but it can eliminate the errors that inevitably occur when humans are forced to perform mundane tasks, especially those tasks that are repeated time and time again. As you will see as you work your way through this book, AppleScript Studio and the AppleScript scripting language are both easy and fun to learn, although they may take you many years to fully master. If your operating system of choice is Mac OS X, AppleScript Studio is a perfect programming environment in which to begin learning application development. In addition, all of the programming techniques that you learn while mastering AppleScript and AppleScript Studio will provide you with a strong jumping-off point from which you can begin learning other programming languages. This book will teach you how to write computer games using AppleScript to build AppleScript Studio applications. However, AppleScript Studio applications can tackle just about any challenge, large and small, simple or complex.
WHO SHOULD READ THIS BOOK? designed this book to teach you how to work with AppleScript Studio and to help you become an effective programmer. No assumption is made regarding your previous programming experience, although prior programming experience is admittedly helpful. It is expected that you have access to a computer running Mac OS X and that you have a working familiarity with that operating system and the applications that come with it, such as Finder and TextEdit.
I
This book’s unique approach of teaching through the development of computer games helps make it a lot more fun and enjoyable than most other computer books. First-time programmers and Mac hobbyists will find this book’s systematic building block approach to learning how to program especially helpful. You will find that the programming skills that you develop
Introduction
xv
by mastering AppleScript Studio will lend themselves well to other programming languages that you may later want to learn. Professional programmers can also benefit from reading this book by using it as a jumpstart guide. This includes programmers who might be interested in learning another programming language as well as those who are looking to expand their skill set to include application development on Mac OS X.
WHAT YOU NEED TO BEGIN ppleScript Studio runs on computers with Mac OS X 10.1.2 or higher. When writing this book, I worked on a computer running Mac OS X 10.4. Therefore, all of the examples that you will see demonstrated will be run on that version of Mac OS X, although in most cases the examples should also run just as well on any version of Mac OS X after 10.1.2. A big portion of this book focuses on learning how to create AppleScripts. Fortunately, AppleScript ships as a standard component on Mac OS X, as does the Script Editor, which is a custom-built code editor designed specifically for AppleScript.
A
In addition to a computer running an appropriate version of Mac OS X, you also need to make sure that Xcode is installed on your computer. As of the writing of this book, the current version of Xcode was 2.3. AppleScript Studio is automatically installed along with Xcode, as are other resources that are needed for you to start developing AppleScript Studio applications. To determine if Xcode is already installed on your computer, look for it in the /Developer/Applications folder. If it is present, then Xcode is installed on your computer. If Xcode is not installed, you can download it from http://developer.apple.com/tools/download/ and then install it like any other Mac OS X application. Apple distributes Xcode for free. However, before you can download and install it, you must first join the Apple Developer Connection or ADC, which you can do at http://developer.apple.com/membership/.
xvi
AppleScript Studio Programming for the Absolute Beginner
HOW THIS BOOK IS ORGANIZED s I wrote this book, I did so with the intention that it be read from cover to cover. However, if you have previous programming experience, you may want to begin by reading the first three chapters in order to grasp the high-level fundamentals of AppleScript Studio application development and then begin jumping around to the particular topics that suit you. However, unless you are particularly adept at learning new programming language statements and syntax on sight or unless you already know how to program using AppleScript, you probably will be better off reading Chapters 4–7. These chapters cover the basics of AppleScript programming, before you begin exploring other parts of the book.
A
AppleScript Studio Programming for the Absolute Beginner is organized into four parts. Part I consists of three chapters that are designed to provide you with an introduction to AppleScript Studio, its application development environment, and the steps involved in building graphical application interfaces. Part II is made up of four chapters that focus on providing you with an overview of AppleScript and the programming statements that make up that scripting language. This material includes coverage of how to work with and store data, apply conditional programming logic, create loops to process large amounts of data or perform repetitive tasks, as well as how to store and manipulate data in a list and organize scripts using handlers. Part III consists of three additional chapters that cover advanced topics, including how to work with files, folders, and disk drives; how to control other applications; and how to locate and fix programming errors. Finally, Part IV is made up of two appendices and a glossary. The appendices provide you with information about the content stored on the book’s companion website and additional learning resources that you may want to look into as you continue your AppleScript Studio education. The glossary contains a listing of terms used throughout the book. A detailed outline of the material covered in this book is provided below. • Chapter 1, “AppleScript Studio Basics”. This chapter provides you with an overview of AppleScript Studio. This includes a review of each of the major development tools that make up AppleScript Studio. You will learn steps involved in creating and running AppleScripts. You will also learn how to build your first AppleScript Studio application, complete with a graphical user interface. Finally, you will learn how to write your first AppleScript Studio game.
Introduction
xvii
• Chapter 2, “The AppleScript Studio Application Development Environment”. This chapter provides a thorough review of AppleScript Studio’s application development environment, Xcode. You will learn how to add, edit, and execute AppleScript code. In addition, you will learn how to navigate Xcode’s menus and toolbar and to work with numerous editor features. You will also learn how to use Xcode to access application dictionaries in order to learn how to automate Mac OS X applications and create workflows. • Chapter 3, “Building a Graphical User Interface”. This chapter reviews the graphical elements supported by AppleScript Studio that you can use when developing the graphical user interfaces for your applications. You will learn how to add interface elements such as buttons, text boxes, and slider controls. You will also learn how to move, resize, and configure these controls and to connect these interface controls to AppleScripts in order to programmatically interact with and control them. • Chapter 4, “Working with Values, Variables, and Classes”. This chapter shows you how to store and reference data using variables. You will learn how to work with different types of data, including strings, numbers, and dates, and how to interact with and manipulate different types of data classes. You will also learn how to convert data from one data type to another and to build mathematical expressions. You will learn about AppleScript operators and the order in which they are applied to mathematic operations. • Chapter 5, “Applying Conditional Logic and Building Loops”. This chapter teaches you how to use conditional logic to create AppleScripts that behave differently based on the data they are provided. You will learn how to evaluate different types of values, including string, numeric, and Boolean data. This chapter also provides you with instruction on how to set up loops in order to perform repetitive operations or to process large amounts of information. • Chapter 6, “Working with Strings, Lists, and Records”. In this chapter, you learn more about how to work with strings, including how to manipulate string contents and to keep track of string elements. This chapter teaches you how to store groups of related data in lists and to access and process this data efficiently. You will also learn how to store data in records, including learning how to define and record contents. • Chapter 7, “Organizing Scripts with Handlers”. This chapter shows you how to improve the overall organization of your scripts using handlers. This includes learning how to call on handlers for execution and how to pass optional arguments to handlers for processing. You also learn how to write handlers that can return data back to the statements that call them. Handlers also have an impact on variable access and this chapter will show you how to control local and global variable scope using handlers.
xviii
AppleScript Studio Programming for the Absolute Beginner
• Chapter 8, “Working with Files and Folders”. The primary focus of this chapter is to teach you how to programmatically interact with and control files, folders, and disks. This will include learning how to create and open files, as well as learning how to read and write to and from these resources. You will also learn how to retrieve file information and to access folders and disk drives. • Chapter 9, “Controlling Other Applications”. This chapter teaches you how to create AppleScripts that control the execution of other applications such as Finder and TextEdit. This will enable you to create automation workflows that tie the actions of multiple applications together into a single process. You will learn how to work with application dictionaries in order to determine which commands applications are designed to work with. • Chapter 10, “Debugging and Error Handling”. This chapter teaches you how to track down and fix errors that may occur when you attempt to compile your AppleScript studio applications. The material covered includes the remediation of syntax and logical errors. You will also learn how to use Xcode’s debugger and to set breakpoints in order to pause application execution and to examine variable values and logical program flow. • Appendix A, “What’s on the Companion Website?”. This appendix provides a review of the materials that you will find on the book’s companion website. This material includes copies of all the AppleScript Studio game applications that are developed in this book. In addition, you will find links to shareware application editors that you may want to explore. • Appendix B, “What Next?”. This appendix provides you with ideas and tips for furthering your AppleScript Studio education. It includes pointers to additional reading material and a list of links to AppleScript and AppleScript Studio websites that I have found particularly helpful and informative. • Glossary. This unit provides a glossary of terms used throughout the book.
Introduction
xix
CONVENTIONS USED IN THIS BOOK
T
o help streamline the presentation of this book and to make your learning experience as enjoyable as possible, I have implemented a number of helpful conventions to improve the overall organization and presentation of the material in this book. These conventions are described below.
HIN
TRA
TRI
As you read along, I will provide suggestions and point out different ways of doing things to help make you a better and more efficient AppleScript Studio programmer.
T
P
CK
Whenever possible, I will try to point out areas where mistakes are sometimes likely to occur and provide you with advice on how to avoid these types of situations.
Whenever possible, I will provide you with shortcuts and programming tips that can help you to work faster and more efficiently.
IN THE REAL WORLD In addition to teaching you the basics of AppleScript Studio programming, I will pause at various places in the book to explain how certain programming techniques can be applied to specific real-world situations.
xx
AppleScript Studio Programming for the Absolute Beginner
CHALLENGES I will close out each chapter by teaching you how to create a new computer game. I will then wrap things up by providing you with a series of suggestions that you can follow up on in order to enhance and improve the chapter’s game project and to further advance your programming skills.
Part
I
Introducing AppleScript Studio
Chapter 1
AppleScript Studio Basics
Chapter 2
The AppleScript Studio Application Development Environment
Chapter 3
Building a Graphical User Interface
This page intentionally left blank
1
C H A P T E R
APPLESCRIPT STUDIO BASICS ppleScript Studio is an application development environment that supports the development of applications on Mac OS X 10.1.2 or higher. AppleScript Studio leverages the capabilities of a number of Apple technologies, including AppleScript, the Cocoa framework, Xcode, and the Interface Builder. In doing so, it provides both novice and professional programmers with the ability to develop graphical applications that can run natively on Mac OS X. This chapter will introduce you to AppleScript Studio and provide a high-level review of its key components. This chapter will also provide you with a brief introduction to AppleScript, the programming language that drives AppleScript Studio applications.
A
Specifically, you will learn • How the technologies used by AppleScript Studio work together to provide a powerful application development environment • How to use the Script Editor to create AppleScripts • How to use Xcode and the Interface Builder to create AppleScript Studio applications
4
AppleScript Studio Programming for the Absolute Beginner
PROJECT PREVIEW: THE KNOCK-KNOCK APPLICATION In this chapter and in each chapter that follows, you will learn how to create a computer game using AppleScript Studio. I hope you will find that learning through game development is both fun and effective. In this chapter, you will learn how to use AppleScript Studio to create the Knock-Knock game. When first started, the Knock-Knock game displays the window shown in Figure 1.1 and waits for the user to click on the Tell Joke button.
FIGURE 1.1 The user begins the Knock-Knock game by clicking on the Tell Joke button.
Once the user clicks on the Tell Joke button, the popup dialog shown in Figure 1.2 is displayed, prompting the user to respond to the Knock-Knock! prompt.
FIGURE 1.2 To continue, the user must click on OK.
Rather than force the user to type in the phrase “Who is there?”, the application automatically provides the required response as the default entry for the popup dialog, requiring only that the user click on the OK button to submit it. If the user clicks on the Cancel button, the popup dialog closes, leaving the application’s opening window still visible. This allows the user to start over or to close the Knock-Knock application. If the user changes the default response to something other than “Who is there?” and then clicks on the OK button, the error message shown in Figure 1.3 is displayed. Assuming that the user leaves the default response alone and clicks on the OK button, the popup dialog shown in Figure 1.4 is displayed, prompting the user to respond to the game’s next query.
Chapter 1 • AppleScript Studio Basics
5
FIGURE 1.3 The Knock-Knock game only accepts specific user input.
FIGURE 1.4 The user helps to set up the game’s punch line by asking “Orange Who?”.
Again, if the user clicks on the Cancel button, the popup dialog is closed, leaving only the game’s main window visible. If the user alters the default response and clicks on the OK button, the error message shown in Figure 1.5 is displayed. FIGURE 1.5 To continue game play, the user must submit the default response by clicking on the OK button.
Assuming that the user clicks on the OK button without altering the default response, the popup dialog shown in Figure 1.6 is displayed, showing the game’s punch line.
FIGURE 1.6 Finally, the game delivers the punch line for its joke.
6
AppleScript Studio Programming for the Absolute Beginner
By the time you have finished creating the Knock-Knock application, you will have learned the five basic steps required to create an AppleScript Studio application and will be ready to tackle more complex challenges.
INTRODUCING APPLESCRIPT STUDIO AppleScript Studio provides you with the ability to create native Mac OS X applications that include full-featured graphical user interfaces that can interact with and control other Mac OS X applications and parts of the Mac OS X operating system. AppleScript Studio applications use AppleScript as the programming language for driving application execution, making it much easier to master than other programming language environments available on the Mac OS X.
A Little AppleScript Studio History AppleScript Studio first appeared in December 2001 when it was released as version 1.0. This version of AppleScript Studio ran on Mac OS X 10.1.2. A few months later, Apple released AppleScript Studio version 1.1. A second version 1 update occurred in mid-2002 when Apple updated AppleScript to version 1.2 and made it available for execution on Mac OS X 10.2. The next update to AppleScript Studio occurred in December 2002 (version 1.2.1), which was made available for Mac OS X 10.2.3. The next update of AppleScript Studio, version 1.3, occurred in 2003 when Apple released Mac OS X 10.3. Finally, in 2005 Apple released AppleScript Studio 1.4 along with Mac OS X 10.4. This remains the current version of AppleScript Studio. During its short lifespan, AppleScript Studio has remained relatively unchanged. As a result, when Mac OS X 10.5 (Leopard) is released, it is unlikely that you will find any significant differences in AppleScript Studio. Therefore, the knowledge you pick up from this book is likely to remain current and serve you well for many years to come.
A Quick Overview of AppleScript Studio Components AppleScript Studio consists of a number of different application development technologies, including AppleScript, Xcode, the Cocoa framework, and the Interface Builder. Each of these technologies is reviewed briefly in the sections that follow and will be covered more fully throughout the remainder of this book.
AppleScript AppleScript is a scripting language supplied as part of Max OS X. If you are a long-time Mac user, then AppleScript is almost certainly going to be the easiest new programming language for you to learn. Not only is it more English-like than any other programming language
Chapter 1 • AppleScript Studio Basics
7
available on Mac OS X, it is also a lot friendlier. For example, AppleScript does away with a lot of syntactical requirements required by other programming languages, such as the addition of semicolons at the end of every statement and the bombardment of brackets, curly braces, and parentheses throughout program code. While capable of serving as a general purpose scripting language, AppleScript is primarily designed as a scripting language to be used in the creation of automated workflows, which control the operating system and other applications. By providing you with the ability to create workflows that leverage the best features of different applications, AppleScript lets you develop scripts that surpass the capabilities of any individual application. TIP
AppleScript grew out of a scripting language known as HyperTalk, which was created by Bill Atkinson in the late 1980s. HyperTalk was known for its Englishlike syntax. Its primary purpose was to facilitate the development of simple automated tasks.
Although AppleScript runs on earlier generations of the Mac operating systems, this book limits its coverage to Mac OS X. The primary reason for this limitation is that the focus of this book is on using AppleScript to support AppleScript Studio programming, and AppleScript Studio only runs on Mac OS X 10.1.2 or higher. Still, most of what you will learn about AppleScript in this book can be directly applied to earlier versions of Mac operating systems. TIP
AppleScript is just one of many scripting languages that are available on Mac OS X. These other scripting languages include Perl, Python, JavaScript, Ruby, and Unix Shell scripting. For Mac users, AppleScript is the easiest of these scripting languages to learn. Each of these scripting languages has its own particular set of strengths and weaknesses. However, when it comes to the automation of other applications, AppleScript really shines, and of course, AppleScript Studio is specifically designed to work with AppleScript.
Xcode Xcode is an application development tool that provides editing and debugging capabilities for your AppleScript Studio applications. In addition, Xcode also provides direct access to application dictionaries, making it easy for you to search for and find the commands used to automate and control individual applications. TRI
CK
Xcode is going to be the tool you will use to begin the development of new AppleScript Studio applications. Since you will be using it so much, you may find it helpful to add it to the Dock for quick access. This is accomplished by dragging and dropping it from /Developer/Applications/onto the Dock.
8
AppleScript Studio Programming for the Absolute Beginner
The Cocoa Framework The Cocoa framework provides AppleScript Studio with access to powerful application development resources. The Cocoa framework is a powerful collection of resources grouped together in an application programming interface or API. Cocoa was originally developed to support application development using a variation of the C programming languages known as Objective-C. However, because Cocoa is an open framework, Apple has made its resources accessible to other programming technologies, including AppleScript Studio. TIP
Cocoa is one of two APIs provided by Apple for the Mac OS X. The other framework is Carbon. AppleScript Studio does not use the Carbon framework; as such, a discussion of that framework is outside the scope of this book.
As you will see, AppleScript Studio applications use Cocoa in many different ways to simplify the creation and operation of graphical user interfaces. It is from the Cocoa framework that AppleScript Studio gets access to the graphical controls you will use when building application interfaces. Cocoa is also responsible for automatically ensuring that these controls look and operate as expected, saving you the effort and responsibility of creating and programming these controls yourself.
Interface Builder Another major technology used by AppleScript Studio is the Interface Builder. As outlined below, the Interface Builder consists of four windows, each of which serves a particular purpose. • Window. Each new AppleScript Studio application is automatically assigned a default window that serves as the basis for creating the application’s graphical user interface. • Cocoa Controls Palette. A collection of user interface controls, organized by category, that are used to create graphical interfaces using drag-and-drop interface design. • MainMenu.nib. Provides control over the various components that make up an application’s user interface (e.g., windows, controls, menus, sound files, images, etc.). • MainMenu.nib—MainMenu. Provides the ability to customize application menus.
A FEW WORDS ABOUT OBJECT-ORIENTED PROGRAMMING AppleScript Studio applications are Cocoa applications. Since AppleScript Studio is integrated into the Cocoa framework, it has access to Cocoa classes. This provides the ability to develop object-oriented applications capable of instantiating objects based on those classes, as well as the ability to access and manipulate object properties and methods.
Chapter 1 • AppleScript Studio Basics
9
Object-oriented programming or OOP is a programming methodology whereby objects, as well as object data and the program code that manipulates the object and its data, are stored together as a unit. Objects are things like windows, buttons, and other types of interface controls. In OOP, any information about an object such as a button, including its color or caption, is stored as object attributes. An attribute is simply a property of an object that defines it in some manner. As already stated, one of the application development technologies used by AppleScript Studio is the Cocoa framework. This framework greatly simplifies application development by providing AppleScript Studio applications with access to pre-defined collections of classes. A class is a template used to instantiate an object. For example, Cocoa defines a large number of pre-built interface control classes, representing buttons, sliders, text fields, and so on. As you will see later in this chapter, you can add instances of these classes by simply dragging and dropping them onto a window to build a graphical user interface for your AppleScript Studio applications. Once added, your application has access to all of the functionality provided by the object, as well as the ability to modify its attributes and to execute program code in order to manipulate them.
APPLESCRIPT: APPLESCRIPT STUDIO’S PROGRAMMING LANGUAGE AppleScript is a scripting language advertised by Apple as a core component of Mac OS X. AppleScript is also part of an integrated system-level interface that facilitates communications between applications. AppleScript is designed to allow you to tap into this resource and to use it to automate tasks. These tasks may be as simple as starting the Safari web browser and loading a particular web page or as complex as tying together the actions of several different applications in order to create a workflow that accomplishes something that none of the applications are capable of doing independently. AppleScript was first introduced to the world with the release of Mac OS 7. Initially, it enjoyed lukewarm success. Even Apple often seemed to be less than enthusiastic about it, with rumors occurring from time to time that AppleScript was on the endangered species list and thus close to being dropped by Apple. However, the amazing rise of Mac OS X has given new life to AppleScript. Not only has Mac OS X attracted millions of new users, but it also has provided many scriptable applications, making AppleScript a lot more useful. AppleScript is different from any other scripting language that you may have worked with in the past. In and of itself, AppleScript is a somewhat limited scripting language. It lacks many of the functions and capabilities that are typically built in to other programming languages. Instead of integrating a large collection of built-in functions and features into AppleScript, Apple chose to design the language so that it could control and automate other
10
AppleScript Studio Programming for the Absolute Beginner
Mac applications—thus enabling AppleScript to leverage functionality found in other applications without instead adding that functionality to the scripting language itself. TRI
CK
Without access to the functionality provided by other applications, AppleScript cannot be fully exploited. For example, AppleScript has very limited mathematical capabilities, lacking built-in functions provided by other scripting languages such as Perl. In addition, AppleScript has limited support for manipulating strings, files, and folders. However, by leveraging the functionality of applications like TextEdit or the Finder, you can develop AppleScripts that can perform complex string manipulations or administer files and folders.
Apple markets AppleScript as a simple English-like scripting language that is easy to learn and master. It is true that many of AppleScript’s keywords and commands follow an Englishlike structure. As previously stated, AppleScript is a little more limited than other modern scripting languages in regards to the features built in to the language itself. However, I would be doing AppleScript a great injustice if I left you with the impression that AppleScript was not a powerful, robust programming language capable of rivaling and often surpassing the capabilities of other scripting languages. AppleScript provides sophisticated programming features, including the ability to write object-oriented code that interfaces with classes and objects provided by the Cocoa framework and AppleScript Studio. According to Apple, everything about Mac OS X is easy and intuitive. Therefore, it is only natural that Apple makes the same claim about AppleScript. The reality is that learning AppleScript takes the same level of effort and commitment as learning any other scripting language. While AppleScript may not support as complete a set of built-in functionality as some other scripting languages, its ability to interact with and control other applications provides AppleScript with capabilities that often far exceed the capabilities of other scripting languages. One of the best things about AppleScript is the strength of its user community. If you check on the Internet, you will find that AppleScript programmers have posted tons of free AppleScripts, ready for you to download and use. In fact, chances are fairly good that if you need an AppleScript to perform a particular task, somebody else has already come across that same need and written an AppleScript to do it. In addition to the Internet, you will find a large collection of sample AppleScript Studio applications on your computer. These applications were automatically installed as part of the Xcode installation process. You will find them in /Developer/Examples/AppleScript Studio/. You can learn a lot from these sample applications, and you can use them as a repository from which you can copy and paste sample code into your own AppleScript Studio applications.
Chapter 1 • AppleScript Studio Basics
11
In the Real World Any time you start learning a new programming language, it is important to make sure that you understand key terminology relative to the language. In this book, the term AppleScript refers to both the programming language and to individual script files. A script file is an executable file containing script statements. Also, a scriptable application is an application that has a dictionary and is designed to interact programmatically with a script.
When to Write AppleScript Many times, tasks do not require you to develop AppleScript Studio applications in order to automate or simplify them. In fact, many times all that is needed is a small AppleScript. AppleScript is appropriate for situations where a graphical user interface is not required or desired. AppleScript is especially helpful when automating the following types of tasks. • Automating functionality for specific applications like the Finder or TextEdit • Simplifying complex tasks involving many steps into a script that can be run by doubleclicking on it • Performing repetitive tasks like cleaning out temporary files or renaming a large number of files • Creating workflows that combine the features of different applications in order to perform operations that each application is otherwise incapable of performing Because AppleScript is an integrated system-level technology, you can count on it being available on any computer running Mac OS X. In addition, it is present on older versions of the Mac operating system going back to Mac OS 7. This means that AppleScript can be used to solve problems on older operating systems where AppleScript Studio is not supported (e.g., operating systems prior to Mac OS X 10.1.2). This also means that once you have written and tested an AppleScript, you can copy it to any computer running Mac OS X, and it should run without issue. Of course, if your AppleScript utilizes the features provided by a third-party application, like Adobe Photoshop, that third-party application will have to reside on any computer where your script is deployed if you want it to run.
When to Develop AppleScript Studio Applications While AppleScript may be well suited to smaller applications that do not require a graphical user interface, AppleScript Studio applications are better suited to addressing tasks when:
12
AppleScript Studio Programming for the Absolute Beginner
• Interacting with users requires a graphical user interface • It is necessary to display output in a manner that requires visual organization • You are developing applications that will only run on computers that you know in advance support the execution of AppleScript Studio applications • You are developing applications of sufficient complexity to require the use of Xcode’s build and debugging environment TR
AP
While AppleScript Studio greatly simplifies the development of desktop applications, it does have a couple of shortcomings compared to other programming languages such as Objective-C, Python, and Perl. For starters, compared to these other programming languages, AppleScript Studio applications are slow. In addition, AppleScript Studio does not perform well when asked to display large amounts of data or to perform complex calculations. In addition, AppleScript Studio is also known to slow down when asked to perform intensive file system operations.
Working with the Script Editor In order to develop AppleScripts, you need a script or text editor. Mac OS X ships with Script Editor, a built-in script editor. Although you can use Script Editor to create other types of scripts, it comes preconfigured only for AppleScripts. Script Editor provides you with numerous helpful features that facilitate script development, including: • Color code highlighting • Automatic statement indentation • Built-in debugging capabilities • Code compilation and execution capabilities Script Editor resides, by default, inside /Applications/AppleScript/. You can start it by doubleclicking on its icon. When you do, Script Editor starts, as demonstrated in Figure 1.7. Once you have opened Script Editor, you can create a new AppleScript by entering one or more AppleScript statements in the main text area. For example, as your first AppleScript, enter the following statement in the main text area. display dialog "Hello World!"
As you type in this statement, take note of the color used to represent the text. Once you have keyed in the entire statement, click on the Compile button, which is represented by an icon that looks like a hammer. In response, Script Editor checks every AppleScript statement for errors. If an error is found, an error message is displayed. Otherwise, you will notice that the
Chapter 1 • AppleScript Studio Basics
13
color of the text representing the code statement you just keyed in has changed. In this case, language keywords are shown in blue, and everything else is displayed in black. In addition, if your AppleScript consists of multiple statements, indents are applied to help make the code more readable. At this point, Script Editor should look like the example shown in Figure 1.8.
FIGURE 1.7 Script Editor provides advanced editing features that simplify the development of AppleScripts.
TIP
Compiling is the process of converting application code statements into a format that can be efficiently executed by the operating system. During the compile process, code statements are checked to ensure that they follow the syntax rules required by the programming language.
To run this example, click on the Run icon located in Script Editor’s toolbar. In response, the popup dialog shown in Figure 1.9 is displayed, showing the output produced by the AppleScript.
14
AppleScript Studio Programming for the Absolute Beginner
FIGURE 1.8 Script Editor uses color coding to help make code statements easier to read and understand.
FIGURE 1.9 A simple popup dialog.
If you go back and look at the code statement that you entered to generate this popup dialog, you should be able to interpret what has happened. Namely, you have written an AppleScript that executed the display dialog command, telling that command to display the text string Hello World!. This is an excellent example of just how English-like AppleScript command syntax can be. Unfortunately, AppleScript command syntax is not always this straightforward. Click on the popup dialog’s OK button to dismiss it. When you do, the popup dialog closes, leaving the Script Editor visible, as shown in Figure 1.10.
Chapter 1 • AppleScript Studio Basics
15
FIGURE 1.10 Feedback regarding the button selected by the user is provided in the Result area at the bottom of Script Editor.
To save your new AppleScript so that you can execute it again later, select the Save option located on the File menu. This opens a new window that allows you to specify a name for your AppleScript and the folder where you would like it stored. TIP
You will learn more about how to work with Script Editor in Chapters 4–7, which provide you with instruction on how to create AppleScripts.
Accessing Application Dictionaries Every scriptable Mac OS X application includes a component known as a dictionary. The dictionary documents the commands required to programmatically communicate with and control the application. Unfortunately, there are many inconsistencies in the different commands that various applications support. As you might expect, a big part of AppleScript programming involves reading through application dictionaries looking for the commands needed to automate key application functionality. In order to create a workflow that automates the functionality provided by a given application, the application must be designed to accept Apple events sent to it by AppleScript. The
16
AppleScript Studio Programming for the Absolute Beginner
inclusion of this capability is up to the developer of the application. Depending on the application developer’s commitment to and knowledge of Mac OS X, third-party applications may or may not include this support. Applications such as Microsoft Word, Microsoft Excel, and FileMaker Pro, as well as Adobe Acrobat, Photoshop, and Illustrator, include this support, just to name a few. TIP
AppleScripts send messages to other applications and to the Mac OS X operating system in the form of Apple events.
To determine whether an application is scriptable, you can start up the Script Editor and then select the Open Dictionary option located on the File menu. This opens the Open Dictionary window, as demonstrated in Figure 1.11.
FIGURE 1.11 Using the Open Dictionary window to search for scriptable applications.
The Open Dictionary window displays a listing of applications that have registered themselves with Mac OS X as being scriptable. To view the dictionary for a given application, select it and click on the Open button. For example, Figure 1.12 shows the dictionary for the TextEdit application. Dictionary commands are organized into suites. You can select a suite by clicking on its name in the upper left-hand pane of the window. All of the available commands within that suite are then displayed in the lower half of the window, along with a description and syntax information. Most of the time you will find that the commands you will need to work with reside in the Standard Suite.
Chapter 1 • AppleScript Studio Basics
17
FIGURE 1.12 Examining the commands listed in the TextEdit application’s dictionary.
TIP
You can also access the Open Dictionary window when working with AppleScript Studio by starting Xcode and selecting the Open Dictionary option located under the File menu.
As you begin developing AppleScripts and AppleScript Studio applications in order to create automated application workflows, you will find yourself spending a lot of time working with application dictionaries. More detailed information on how to use application dictionaries is provided in Chapter 9, “Controlling Other Applications.”
BACK TO THE KNOCK-KNOCK APPLICATION Okay, that is enough AppleScript and AppleScript Studio background information for now. Let’s move on to something fun. It is time for you to create the first of many new AppleScript Studio applications. Admittedly, this first application is rather simplistic. Still, it is a good starting point, allowing you to learn the basic mechanics involved in creating a new AppleScript Studio application without overburdening you with layers of complexity that you do not need to deal with yet.
18
AppleScript Studio Programming for the Absolute Beginner
Do not worry if not everything makes sense as you go through the steps involved in building the Knock-Knock application. It takes time to absorb and understand everything that is going on. This is especially true of the program code statements that you will have to add to make the application work. For now, just focus on the overall process and try to get a feel for the order in which each step is performed. Things will become clearer as you read later chapters and become more comfortable with the AppleScript Studio application development environment and the AppleScript programming language.
Designing the Game The Knock-Knock application is a straightforward implementation of the classic children’s knock-knock joke. It may seem strange to be creating your first AppleScript Studio application this early in the book, especially given that you have not learned how to program using AppleScript yet. That is part of the beauty of AppleScript Studio; even with just a little knowledge, you can begin programming and write an application that really works. The Knock-Knock application is small and very straightforward. Still, by working your way through this example and duplicating everything that you see, you will learn the basic mechanics involved in developing AppleScript Studio applications, which is the real reason for creating this application so early in the book. The Knock-Knock game will start by displaying its user interface and waiting for the player to click on a button labeled Tell Joke. In response, the game will begin asking the player questions in order to set up the joke’s punch line. Once you have finished creating and testing your new application, you should take note that even though the application consists of just a handful of short programming statements, it contains all of the functionality and features that Max OS X users expect from their applications. For example, the Knock-Knock application’s user interface can be minimized, maximized, and resized. In addition, it interacts with the player using graphical elements like button controls and interactive popup dialogs. All this functionality is provided to your applications behind the scenes by the Cocoa framework, allowing you to create fully functional Mac OS X applications with surprising ease. As the development of the Knock-Knock application will show you, AppleScript Studio applications are generally developed in five basic steps. 1. 2. 3. 4. 5.
Open Xcode and create a new AppleScript Studio application. Create the graphical user interface using the Interface Builder. Attach interface controls to event handlers. Edit the AppleScript that controls the application. Build and run the application.
Each of these steps is covered in detail in the sections that follow.
Chapter 1 • AppleScript Studio Basics
19
Step 1: Creating a New AppleScript Studio Application The first step in creating a new AppleScript Studio application is to start up Xcode and create a new AppleScript Studio project as outlined in the following procedure. 1. Double-click on the Xcode icon located in /Developer/Applications. The only evidence that Xcode has started is the display of the Xcode menu at the top of the script, as demonstrated in Figure 1.13. FIGURE 1.13 When Xcode starts, only its menu bar is visible.
2. The next step is to tell Xcode to create a new project. To accomplish this, click on the New Project menu item located on the File menu. Xcode responds by launching an Assistant, as shown in Figure 1.14.
FIGURE 1.14 The Assistant presents a list of application templates.
3. The Assistant displays a list of templates, each representing a different type of Cocoa application. Cocoa supports the creation of three different types of AppleScript Studio applications.
20
AppleScript Studio Programming for the Absolute Beginner
• AppleScript Application. A Cocoa application written using AppleScript that does not support the creation of documents. • AppleScript Document-based Application. A Cocoa application written using AppleScript that supports documents. • AppleScript Droplet. A Cocoa application written using AppleScript that executes when files are dropped on it. Select the AppleScript Application template, located under the Application category, and click on Next. The Assistant next prompts you to specify a file name and location where you would like to store your new AppleScript Studio application, as demonstrated in Figure 1.15.
FIGURE 1.15 Assigning the name and path to the Knock-Knock application.
TIP
I recommend creating a new folder for storing all your AppleScript Studio applications. For example, you might want to create a new folder named MyApps in your home directory. AppleScript Studio will remember this folder name and its location the next time you create a new AppleScript Studio application.
4. To finish creating your new project, click on the Finish button. Xcode responds by displaying the Editor dialog shown in Figure 1.16.
Chapter 1 • AppleScript Studio Basics
21
FIGURE 1.16 Xcode displays a listing of all of the files that make up your new AppleScript Studio project.
The title bar displays the name assigned to the new application. The files that make up the new AppleScript Studio project are listed in a hierarchical fashion on the left-hand side of the dialog in the Groups & Files pane. By clicking on the disclosure triangles, you can drill down into different groupings of files. The Scripts folder contains all of the AppleScript files associated with the project. Within it, one file has been automatically created for the Knock-Knock application, the Knock-Knock.applescript file. This file is the default AppleScript file for the application. The right-hand side of this dialog displays the contents of the select file or resource. TIP
You will find more information on how to work with Xcode and the files that make up AppleScript Studio projects in Chapter 2, “The AppleScript Studio Application Development Environment.”
Step 2: Creating a Graphical User Interface Now that you have created a new AppleScript Studio project, the next step is to begin work setting up the application’s graphical user interface. This is accomplished by executing the steps outlined in the following procedure.
22
AppleScript Studio Programming for the Absolute Beginner
TRI
CK
The Cocoa framework provides your AppleScript Studio applications with the underlying object-oriented functionality required by any desktop application that runs on Mac OS X, thus greatly simplifying application development. To see what I mean by this, click on the Build and Go icon located at the top of the Xcode Editor window. In response, Xcode will compile your project into an executable program and run it. As you will see, even though you have not written a single line of code, your new application benefits from functionality provided by the Cocoa framework. It displays a blank window, which you can move, resize, and even minimize to the Dock. In addition, it has a title bar with the standard set of buttons located on the left-hand side. When done, close the application and the Run Log window that was also opened when you ran the application.
1. Click on the disclosure triangle for the Resources folder located in the Groups & Files pane. This exposes the MainMenu.nib file. This file contains information used to build the main window for the application. TRI
CK
If you prefer, you can also start the Interface Builder using Finder. However, it’s almost always more convenient to let Xcode start it for you.
2. Double-click on the MainMenu.nib file. In response, the Interface Builder starts, displaying the four windows shown in Figure 1.17. MainMenu.nib
Application window
Cocoa-Controls palette
MainMenu.nib - MainMenu
FIGURE 1.17 The Interface Builder provides all the tools you need to create your application’s graphical user interface.
Chapter 1 • AppleScript Studio Basics
TRI
CK
23
At this point, you may find that your screen is becoming too crowded and that it is becoming difficult to keep track of all the windows that are currently open. If you want, you can simplify things a bit by clicking on the Hide Others option located on the Interface Builder menu. This hides the Xcode Editor window (on the Dock) and the four Interface Builder windows from view.
3. Using the resize handle located in the lower right-hand side of the default application window, resize the window as shown in Figure 1.18. FIGURE 1.18 Changing the size of the window to be used as the interface for the Knock-Knock application.
4. The Knock-Knock application’s window contains a single button control. To add a button control, click on the Cocoa Controls and Indicators icon located at the top of the Cocoa Controls palette (second button from the right) and then drag and drop an instance of the button control onto the window, as demonstrated in Figure 1.19. Using drag and drop, center the button control in the middle of the application window.
FIGURE 1.19 Adding a button control to the Knock-Knock application window.
5. At this point, the application’s user interface should look like the example shown in Figure 1.20.
24
AppleScript Studio Programming for the Absolute Beginner
FIGURE 1.20 You can reposition the button control by clicking on it and dragging it to a new location within the window.
6. The application also displays instruction in the form of a text string displayed directly on the application’s window. To add this text, click on the Cocoa Text Controls icon (third from the right), located on the Interface Builder toolbar. In response, a new set of controls is displayed in the Interface Builder, as shown in Figure 1.21.
FIGURE 1.21 Adding a static text control to the Knock-Knock application.
7. Select the small system font text control and then drag and drop an instance of it onto the Knock-Knock application window, centering it just above the button control. 8. Double-click on the small system font text control that you just added to the window. This places you in input mode, allowing you to enter whatever text you want in the control. Type Welcome to the Knock-Knock application. To play, click on the Tell Joke button. 9. The next step is to customize the appearance of the button. Begin by double-clicking on the control. This places the cursor inside the control, allowing you to enter text in order to label the control. Enter Tell Joke and then click on an open area of the window. The control should immediately update and change its appearance and size as necessary to reflect the change you just made to its label.
Chapter 1 • AppleScript Studio Basics
TIP
25
You find more detailed information on how to work with the Interface Builder in Chapter 3, “Building a Graphical User Interface.”
At this point, the user interface for the Knock-Knock application is complete. The next step is to modify attributes belonging to the application window and to associate the button control with the AppleScript that will execute when the user clicks on it, as outlined in the next section.
Step 3: Modifying Control Attributes and Attaching Controls to Event Handlers The next step in setting up the Knock-Knock application is to configure a couple of attributes, or properties, belonging to its window. This can be done via the Inspector window. For the Knock-Knock application, you will want to use the Inspector window to assign a name to the application’s window. In addition, you will want to set up the window such that the user won’t be able to change window size, as outlined in the following procedure. 1. Select the button control and then click on the Show Inspector option located under the Tools menu. The Inspector window opens as shown in Figure 1.22.
FIGURE 1.22 The Inspector window provides access to window and control attributes and events.
2. To view window attributes, select Attributes from the popup control located at the top of the Inspector window. 3. Enter Knock-Knock in the Window Title field.
26
AppleScript Studio Programming for the Absolute Beginner
4. Under the Title bar controls section, clear the Zoom (and resize) checkbox as shown in Figure 1.23. This will disable the green Zoom button control located on the left-hand side of the title bar, preventing the user from being able to change the size of the application window.
FIGURE 1.23 Modifying the attributes associated with the application window.
5. Close the Interface Builder by selecting the Quit Interface Builder option located on the Interface Builder menu and click on Save when prompted. Now that the Knock-Knock application’s interface is complete and you have finished modifying the required window attributes, it is time to set things up so that an AppleScript script, which you will write in the next section, is executed whenever the user clicks on the button control located on the application’s user interface. This is accomplished using the following procedure. 1. Select the button control and then click on the Show Inspector option located under the Tools menu. The Inspector window opens. 2. Select the AppleScript option from the popup located at the top of the Inspector window. 3. A list of the different types of events that the button control can respond to is in the event handler section of the Inspector window. For the Knock-Knock application, we want to set the button up to respond whenever the user clicks on it. This is accomplished by clicking on the disclosure triangle just to the left of the Action event handler, exposing the clicked event handler. Select this event handler by clicking on its associated checkbox.
Chapter 1 • AppleScript Studio Basics
TIP
27
An event is an action for which a control can detect and respond. Controls respond to events through event handlers. Event handlers are organized into related groups in the Inspector window.
4. Now that you have specified that you want to set up the button to respond when clicked, you need to associate a clicked event handler with an AppleScript that you want to execute. This is accomplished by selecting the radio control associated with the KnockKnock.applescript script listed in the Script section at the bottom of the Inspector window, as demonstrated in Figure 1.24.
FIGURE 1.24 Associating a control with an AppleScript.
As a result of executing the previous procedure, Xcode reappears, displaying the code statements that currently make up the Knock-Knock application. As you will see, the following event handler statements have been added to Knock-Knock.applescript. These statements will automatically be executed every time the user clicks on the button. on clicked theObject (*Add your script here.*) end clicked
By entering AppleScript code statements inside this event handler, you can set up the KnockKnock application to perform any commands you specify.
28
AppleScript Studio Programming for the Absolute Beginner
You’ll find more detailed information on how to work with the Inspector window in Chapter 3.
TIP
Step 4: Editing Your AppleScript Now that you have finished setting up the Knock-Knock application’s graphical user interface and have configured the button control to respond to a click event, you need to add program code statements to the clicked event handler. This is accomplished by the steps outlined in the following procedure. 1. While still in the Inspector window (with Knock-Knock.applescript selected), select AppleScript from the popup control located at the top of the Inspector window and click on the Edit button located at the bottom of the window. 2. Xcode’s Editor window reappears, displaying the newly added clicked event handler in the editing section, located on the bottom right-hand side of the window. 3. Select and delete the (*Add your script here.*) statement. 4. In its place, enter the following statements, as demonstrated in Figure 1.25. on clicked theObject set userResponse to the text returned of (display dialog ¬ "Knock-Knock!" default answer "Who is there?") if not (userResponse = "Who is there?") then display dialog "Sorry, you must enter 'Who is there?' to play." end if set userResponse to the text returned of (display dialog ¬ "Orange!" default answer "Orange who?") if not (userResponse = "Orange who?") then display dialog "Sorry, you must enter 'Orange who?' to play." end if display dialog "Orange you glad you created your first AppleScript " & ¬ "Studio application?" end clicked
Chapter 1 • AppleScript Studio Basics
TRI
CK
29
The ¬ character is an AppleScript continuation character. To type this character, you must press the l key while holding down the Option key. It is used to arbitrarily split a programming statement over two or more lines. By default, the Xcode Code editor lets you type in code statements that are as long as you want. The more you type, the more the editor slides over to the right to make room. As you will see later in this chapter, you can configure the editor to automatically wrap long code lines for you. The decision as to whether to turn on automatic line wrapping versus inserting a continuation character to break up long code statements is entirely up to you.
These AppleScript statements generate a series of popup dialogs that interact with the player, guiding him through to the game’s punch line.
FIGURE 1.25 Adding the AppleScript code required to control the Knock-Knock application.
TIP
For now, do not worry about trying to figure out what these statements are doing. Simply key them in and move on, remembering to focus on the mechanics involved in the creation of AppleScript Studio scripts. Later chapters delve into the ins and outs of AppleScript code statements.
30
AppleScript Studio Programming for the Absolute Beginner
That is it. You have completed all the steps required to create the Knock-Knock application. All that remains is to compile and run it. Before doing so, you might want to pause and save your work by selecting the Save All option located on Xcode’s File menu.
Step 5: Building and Running Your Mac OS X Application Let’s test the Knock-Knock application. To do so, you need to compile it. You can compile your application by selecting the Build option located on the Build menu or by clicking on one of the Build icons located in the editor’s toolbar. Once it is compiled, you can run your new application by selecting the Run option located on the Build menu. In response, your application is started. Try it out and see how it works. When done, you can close it like any other Mac OS X application.
SUMMARY This chapter introduced you to AppleScript Studio and its basic components. These technologies include AppleScript, the Cocoa framework, Xcode, and the Interface Builder. AppleScript is the programming language that helps to drive AppleScript Studio applications. You also learned how to use the Script Editor to create and execute your first AppleScript. Finally, you learned how to work with Xcode and the Interface Builder to create your first AppleScript Studio application, the Knock-Knock game. In doing so, you learned the basic steps involved in AppleScript Studio application development. Now, before you move on to the next chapter, I suggest that you set aside a few extra minutes to see if you can improve on the Knock-Knock application by implementing the following list of challenges.
CHALLENGES 1.
2.
The Knock-Knock application currently tells a single joke. Try making it more interesting by modifying it to tell additional jokes. The text currently displayed in the small system font text control and on the button control is somewhat cryptic. Replace these text strings with text that is more meaningful and instructive.
2
C H A P T E R
THE APPLESCRIPT STUDIO APPLICATION DEVELOPMENT ENVIRONMENT code provides AppleScript Studio’s development environment. Through Xcode you create and modify AppleScript Studio projects. Xcode provides project templates for generating new applications. In addition, it provides the tools required to edit program code, browse application terminology, debug code errors, access documentation, and interact with the Interface Browser. In this chapter, you will learn how to use Xcode to develop new AppleScript Studio projects and to turn those projects into Max OS X applications. In addition, you will also develop a new computer game, the AppleScript Studio Fortune Teller.
X
Specifically, you will learn how to • Create new AppleScript Studio projects • Determine how Xcode interfaces with the Interface Builder to connect interface elements to code statements • Use Xcode’s built-in code editor • Use Xcode to access application terminology • Use Xcode to access the Apple Developer Reference Library • Customize Xcode’s operation by modifying preference settings
32
AppleScript Studio Programming for the Absolute Beginner
PROJECT PREVIEW: THE APPLESCRIPT STUDIO FORTUNE TELLER GAME In this chapter, you will learn how to create a new computer game using AppleScript Studio. The AppleScript Fortune Teller game prompts the player to ask questions and then responds with randomly generated answers. When started, the game displays the window shown in Figure 2.1.
FIGURE 2.1 The AppleScript Fortune Teller prompts the player to ask a question.
The game checks to verify that the player entered a question each time the OK button is pressed. In the event the player fails to enter something, the error dialog shown in Figure 2.2 is displayed.
FIGURE 2.2 The game issues an error message in the event the player clicks on OK without entering any text.
Figure 2.3 demonstrates a typical question that might be asked of the AppleScript Studio Fortune Teller game.
FIGURE 2.3 The player must click on Ask to submit her question.
In response, the game generates a random response to the player’s question, as demonstrated in Figure 2.4.
Chapter 2 • The AppleScript Studio Application Development Environment
33
FIGURE 2.4 The answer to each question is displayed in a popup dialog.
As Figures 2.5 and 2.6 show, the game can generate a number of different answers. FIGURE 2.5 Because the AppleScript Studio Fortune Teller game’s answers are randomly generated, the player can never be certain how a given question will be answered.
FIGURE 2.6 The player may ask as many questions as she wants.
When finished asking questions, the player can close the AppleScript Studio Fortune Teller game by clicking on its Close icon or by clicking on the Quit New Application item located on the Fortune Teller menu.
PROJECT TEMPLATES In Xcode, the project is the container that is used to organize the files and resources that make up applications. Xcode supports the development of both Cocoa and Carbon applications written in C, Objective-C, C++, Java, and AppleScript. Of course, for this book we are only concerned with Xcode’s ability to support AppleScript Studio applications written using AppleScript.
34
AppleScript Studio Programming for the Absolute Beginner
Xcode allows you to open and modify existing projects and to build new Mac OS X applications based on project contents. You do so by selecting one of the New or Open options located on the Xcode File menu, as shown in Figure 2.7.
FIGURE 2.7 The Xcode’s File menu provides commands for creating and accessing projects.
TIP
By selecting a project template, you identify for Xcode the default target for your application. In the case of AppleScript Studio, the target is usually a Mac OS X desktop application. Xcode then packages up all the files, resources, and framework information needed to build your new application.
To open an existing AppleScript Studio project, you can select the File menu’s Open option and specify the location of the project file. Projects are stored in a project folder and assigned a file extension of .xcodeproj. To create a new AppleScript Studio application, you click on the File menu’s New Project menu item. In response, Xcode starts an Assistant that prompts you to specify the type of application you are building, as demonstrated in Figure 2.8. For this book, you will select the AppleScript Application project template for each game project that you’ll be creating.
Chapter 2 • The AppleScript Studio Application Development Environment
35
FIGURE 2.8 An Assistant provides you with access to project templates that specify all the resources needed to build a given type of application.
After you select AppleScript Application and click on the Next button, the Assistant will prompt you to provide a name for your new application and to specify the folder where you want to save it, as demonstrated in Figure 2.9.
FIGURE 2.9 Specifying the name of your AppleScript Studio project.
36
AppleScript Studio Programming for the Absolute Beginner
By default, the Assistant will save your new application in your home directory. However, you can click on the Choose button and specify a different location. TIP
The ∼ character shown in Figure 2.9 is a special character that represents your home directory. On Unix-based operating systems, like Mac OS X, the home directory is a personal folder assigned to each unique user of the system where you can store personal files.
Once you have specified the name of your project and the location where you want your new project saved, you will notice that the Next button located in the lower right-hand corner of the Assistant is replaced with the Finish button. Click on Finish to create your new AppleScript Studio project. The Assistant will close, and Xcode’s Project window will appear. From this window, you will manage the rest of the project development process. When you are done, you will also build your new Mac OS X application from this window as well.
SETTING XCODE PREFERENCES Xcode is an extremely powerful and complex application development tool. It has so many features and capabilities that it is easy to get lost in. Having so many options is a good thing. As you spend more time working with Xcode, you will become much more comfortable navigating its many windows and menus. You can make Xcode a little more user friendly by modifying some of its preference settings. For example, there are preference settings that allow you to specify and control syntax coloring, the default project build folder, custom key bindings, line numbering, window color schemes, code statement wrapping, and indentation. To access the Xcode Preferences windows, click on the File menu and select the Preferences option. A window similar to that shown in Figure 2.10 will appear.
FIGURE 2.10 Configuring Xcode preferences.
Chapter 2 • The AppleScript Studio Application Development Environment
37
Xcode preferences are organized into groups that are accessed by clicking on icons located in the toolbar at the top of the window.
WORKING WITH THE XCODE PROJECT WINDOW Xcode is the central point from which you will work as you create AppleScript Studio applications. Therefore, to be an effective AppleScript Studio application developer, it is important that you have a strong working knowledge of Xcode. The first time you create a new AppleScript Studio application, Xcode opens, as shown in Figure 2.11, and displays the default resources and files associated with AppleScript Studio applications. Groups & Files
Toolbar
FIGURE 2.11
Status bar
Detail view
Xcode’s Project window is the primary location from which you will manage the creation of AppleScript Studio applications.
As Figure 2.11 shows, the default Xcode Project window layout consists of four major sections. At the top of the windows is the toolbar, which contains icons representing commonly used commands. Beneath the toolbar, on the left-hand side of the window, is the Groups & Files pane, which displays a hierarchical listing of all the files and resources that make up the current project. To the right is the Detail view, in which the currently selected resource in the Groups & Files pane is displayed. At the bottom of the Project window is the status bar, which displays helpful messages as you work with the Project window.
38
AppleScript Studio Programming for the Absolute Beginner
The Project Window Toolbar The Xcode Project window toolbar, shown in Figure 2.12, provides single-click access to commonly used Xcode commands. Active Target menu
Build button
Tasks button
Editor button
FIGURE 2.12 The Xcode Project window toolbar provides quick access to commonly used Xcode commands.
Action button
Build and Go button
Info button
Search field
By default, the following buttons are provided on the Xcode toolbar. • Active Target menu. Lists the active target (e.g., your Mac OS X application). • Action button. Provides access to a list of commands applicable to the currently selected item. • Build button. Runs Xcode’s application build process, creating a compiled version of your application if no errors are found. • B uild and Go button. Runs Xcode’s application build process, creating and then running a compiled version of your application if no errors are found. • Tasks button. Stops any currently executing operation. • Info button. Displays the Info window, which is used to view and modify group and file items that make up application projects. • Editor button. Opens or closes the Xcode code editor within the detailed section of the Project window. • Search field. Provides the ability to perform search operations on the currently displayed item or file in the Detail view.
Groups & Files Xcode automatically assembles the necessary resources and files required to build your application when you tell the Xcode Assistant to create an AppleScript Studio application. The Groups & Files listing, shown in Figure 2.13, provides access to all of the resources and files that Xcode generates on your behalf in order to create an AppleScript Studio project. The Groups & Files section provides you with the ability to view all of the items that make up your AppleScript Studio projects. Items listed in Groups & Files are organized hierarchically by group and are displayed as individual files. A folder icon represents groups. Individual
Chapter 2 • The AppleScript Studio Application Development Environment
39
FIGURE 2.13 The Groups & Files section of the Xcode Project window provides access to all the items that make up your AppleScript Studio projects.
items are represented by unique icons based on their type. It is important that you have a basic understanding of a number of the groups and items listed in the Groups & Files section. These are described in the following list. • Scripts Group. Contains the AppleScript files that drive your AppleScript Studio application. By default, this group contains one script, named after the project name you assigned when you created the project. This script has a file extension of .applescript. • Resources Group. Contains resource files required by the application. Any required resource files, such as graphic or sound files, should be added to this group. Included in this group is the MainMenu.nib file, which stores instructions for building the application’s user interface. The user interface is created using Interface Builder, which can be accessed by double-clicking on this .nib file. • Other Sources. This group contains a file named main.m, which contains the Cocoa code required to build your AppleScript Studio application. • Frameworks. applications.
Contains frameworks required to support AppleScript Studio
• Products. This group stores the product specified for each project target. By default, AppleScript Studio projects contain a single target that results in a single application, which is assigned an .app file extension and stored in a subgroup named Build. When
40
AppleScript Studio Programming for the Absolute Beginner
you are ready to deploy your AppleScript Studio application, copy the application files stored in the Build subgroup. • Targets. A target specifies the instructions required to build a particular application. For example, your project may build desktop, server, or command-line applications. New AppleScript Studio projects contain a single target that is assigned the same name that you assigned to the project, without any file extension. • Errors and Warnings. Contains a listing of any errors generated during the application build process. You will learn how to work with error and warning messages later in Chapter 10, “Debugging and Error Handling.” TRI
CK
Although you do not have to store files—such as sound and graphics files—used by your AppleScript Studio applications in the Resources group, doing so makes it easier to keep the resources needed to build your application together.
Using drag and drop, you can rearrange the items listed in Groups & Files. In addition, you can drag and drop items needed by your applications, such as sound files or graphics, into groups that you create within the Groups & Files section. For example, you can add a new group within Groups & Files by selecting the New Group option located on Xcode’s File menu and then dragging and dropping any number of files into it. Likewise, you can remove any item from Groups & Files by selecting it and pressing the Delete key or by selecting the Delete command located on the Edit menu.
The Project Window Detail View The Detail view of the Xcode Project window displays detailed information about the currently selected file, resource, or group. If the selected item is a group, information is provided for all group items, including any subgroups that may be present. By default, the Detail view shows the following columns. • File Type • Build Status • Errors • Warnings • Code • Target
Chapter 2 • The AppleScript Studio Application Development Environment
41
However, additional data is available for display. You can add or remove columns from the Detail view by clicking on the View menu and selecting Detail View Columns. Alternatively, you can Control+click on any column header in the Detail view to display a context menu from which you can also add or remove columns, as demonstrated in Figure 2.14.
FIGURE 2.14 Configuring the information you want displayed in the Detail view of the Xcode Project window.
You can also reorder column headings by dragging and dropping headings to new locations. Also, using the Search field located in the Xcode Project window toolbar, you can perform searches on the items listed in the Detail view.
The Editor Window Xcode provides a full-featured code editor that includes a number of convenient and powerful features. Some of these features are enabled by default. Others are not. To get the most out the Xcode code editor, you will need to configure it to best suit your personal needs and preferences. Xcode’s code editor includes features such as: • Syntax checking • Syntax color coding • Automatic code indentation • Automatic matching of closing brackets and parentheses • Code completion Xcode assigns an .applescript file extension to the default script file for each new AppleScript project and stores it in the Scripts group located in the Groups & Files section of the Xcode Project window. If you select this script file and click on the Show Editor button, located in the Xcode Project window’s toolbar, Xcode will display the script file in the detail window, allowing you to modify and edit the script as demonstrated in Figure 2.15.
42
AppleScript Studio Programming for the Absolute Beginner
FIGURE 2.15 Editing an AppleScript file from within the Xcode Project window.
At the top of the edit area, you will see the Editor Navigation Bar, which has the following features. • Previous and Next arrow buttons. Allows you to switch between script files when more than one file is being edited. • Script icon. An icon identifying the type of file being edited. • File Name menu. A popup menu displaying the name of the script currently being edited and providing access to any other currently open script files. • Function menu. A popup menu that provides quick access to the handlers within the currently edited script file. • Bookmarks menu. Provides access to any bookmarks stored for the current script file. • Breakpoints menu. Provides access to any breakpoints that have been set for the current script file. • Go To Counterpart button. This option does not apply to AppleScript files. • Included Files menu. This option does not apply to AppleScript files. • Lock Status button. By clicking on this button, you can lock and unlock the script file’s edit status.
Chapter 2 • The AppleScript Studio Application Development Environment
43
If you prefer, you can open and edit your AppleScript files in a separate editor window. To do so, double-click on the script file in the Script group located in the Group & Files section. This opens an editor window similar to the one shown in Figure 2.16.
FIGURE 2.16 Editing an AppleScript file using a separate editor window.
In addition to the Editor Navigation Bar, the standalone version of the Xcode code editor includes its own toolbar, which contains buttons that allow you to perform build operations, set breakpoints, and jump to the location of the script file within the Project window. TIP
A breakpoint is a marker that identifies a point in a script file where you want Xcode’s built-in debugger to pause when executing the script. When paused, you can use the debugger to examine variable values and monitor the logical flow of the script as its executes. You will learn how to set breakpoints and debug AppleScript Studio applications in Chapter 10.
Regardless of whether you are working with the editor inside the Project window or in its own window, it provides the same functionality and features, as shown in Figure 2.17.
44
AppleScript Studio Programming for the Absolute Beginner
The Navigation Bar
The Gutter
The Editing Area
FIGURE 2.17 The components of the Xcode code editor.
As has already been discussed, the Editor Navigation Bar provides access to menus and buttons that allow you to move quickly to various parts of your script files. The gutter is used to display optional line numbers as well as the location of breakpoints and errors. The Editing area is where you enter your AppleScript code statements.
Statement Color Coding The Xcode code editor provides a number of formatting options that can help you when you are keying in your AppleScript statements. One of these features is syntax statement coloring, which is using different colors to display the different parts of script statements. Color-coding is enabled by default. You can disable color-coding or configure how it is applied by opening the Preferences window and then clicking on the Fonts & Colors button. From there, you can specify the colors that you want applied to any of the following: • Comments • Strings • Characters • Numbers • Keywords TIP
More information regarding how to access Xcode Preferences windows is available later in this chapter.
Statement Wrapping Another useful editing feature provided by the Xcode code editor is line wrapping. Line wrapping occurs when you type a code statement that is too long to be displayed on your screen. Line wrapping is not enabled by default. To enable it, open the Xcode Preferences window
Chapter 2 • The AppleScript Studio Application Development Environment
45
and click on the Indentation button and select the Wrap Line in Editor option. From here you can also specify how many blank spaces should be used when indenting.
Statement Indentation The editor can help you format your code statements by automatically indenting your code statements. This feature is not enabled by default. To enable it, open Xcode Preferences and click on the Indentation button and select the Syntax-Aware Indenting option. From here, you can also configure how Xcode indents comments.
Code Sense Another very handy Xcode editing feature is Code Sense. With Code Sense, Xcode keeps track as you enter the text for code statements and provides suggestions for completing your statements. By default, Code Sense is enabled but runs silently in the background. Whenever Xcode see an opportunity for suggesting how to complete a portion of a code statement, it notifies you by underlining the text entered so far. To see the list of options proposed by Code Sense, press the Escape key, or you can click on the Edit menu and select the Completion option. In response, a list of possible code completion suggestions is displayed, as demonstrated in Figure 2.18.
FIGURE 2.18 Using Code Sense as a tool for entering code statements.
46
AppleScript Studio Programming for the Absolute Beginner
TRI
CK
If you prefer, you can configure Code Sense so that it automatically makes suggestions every time it sees an opportunity by opening the Xcode Preferences window, clicking on the Code Sense button, and selecting the Always option in the Automatically Suggest popup menu. Enabling this option may prove especially helpful when you are just beginning to learn how to program. However, as you grow more experienced, you will most likely find this feature to be too intrusive.
If you want, you can select a code completion suggestion by clicking on it and pressing the Return key. In response, Xcode enters the specified text, inserting placeholders for any arguments that you may need to fill in.
The Info Window Another Xcode window that you should be familiar with is the Info window. This window provides you with the ability to view and modify items in the Project window. To use the Info window, select an item in the Project window and then click on the Info button, located in the Xcode Project window’s toolbar. The Info window opens and displays information about the selected item. Depending on the item selected, the data that is presented may be organized into multiple views. For example, if you select the item representing your AppleScript Studio project and then click on the Info button, you will see information similar to that shown in Figure 2.19.
FIGURE 2.19 Examining the General view provided on the Info window.
Chapter 2 • The AppleScript Studio Application Development Environment
47
In this example, the General view of the Info window shows you the location where your project files are stored. If you prefer, you can change the location where Xcode stores project files.
In the Real World It is very important that you document your AppleScript Studio applications, explaining in detail why you created the project the way you did. One way of doing this is to embed comments throughout your application code, as explained later in this chapter. However, there is more to AppleScript Studio projects than just adding program code statements. Xcode provides you with the ability to document items displayed within the Project window by selecting the item, clicking on the Info button located in the Project toolbar, and selecting the Comments view, as demonstrated in Figure 2.20.
FIGURE 2.20 Adding documentation to the script file for an AppleScript Studio application.
By making liberal use of this documentation feature, you can fully document your AppleScript Studio applications. If you add URLs or email addresses, they will be recognized as such and can be accessed by simply clicking on them. Also, if you want, you can view item comments by configuring the display of the Comments header in the Detail view.
48
AppleScript Studio Programming for the Absolute Beginner
INTEGRATION WITH THE INTERFACE BUILDER As you already know, when developing AppleScript Studio applications, you use Xcode to create new projects, manage the files that make up that project, edit the AppleScript code required for the application to run, and debug and build the application. However, to complete your AppleScript Studio applications, you also need to work with the Interface Builder. As you have already seen, you can start the Interface Builder from within Xcode by doubleclicking on the application’s nib file. Once your application’s user interface is complete, you need a means of associating or connecting it and its component elements with the AppleScript files that drive your AppleScript Studio applications. This can be accomplished using the Inspector window. The Inspector window acts as a sort of bridge between Xcode and Interface Builder. You open it from within Interface Builder by clicking on the Show Inspector option in the Tools menu. More information on how to work with the Inspector window is provided in Chapter 3, “Building a Graphical User Interface.”
THE TERMINOLOGY BROWSER As you learned in Chapter 1, “AppleScript Studio Basics,” you can develop AppleScripts that automate the operation of other Mac OS X applications. In order to do so, you must be familiar with the command terminology supported by the applications to be automated. Unfortunately, there are many inconsistencies in the different commands that various applications support. Fortunately, each scriptable Mac OS X application provides access to this terminology through its own dictionary. Rather than access these dictionaries through the Script Editor application that you were introduced to in Chapter 1, Xcode makes things easy for you by allowing you to access the Open Dictionary window from within the Xcode Project window. The Open Dictionary window, shown in Figure 2.21, is accessed by clicking on the Open Dictionary option located on the Xcode File menu.
FIGURE 2.21 Accessing application dictionaries from within the Xcode Project window.
Chapter 2 • The AppleScript Studio Application Development Environment
49
Easy access to application dictionaries greatly simplifies the process of developing automated workflow applications. You will learn more about how to work with the application dictionaries in Chapter 9, “Controlling Other Applications.” AppleScript Studio also has its own dictionary, which you can access within the Xcode Project window by double-clicking on the AppleScriptKit.sdef item located in the detail view of the Groups & Files list. For example, Figure 2.22 shows the AppleScript Studio dictionary entry for the button control. Here you will find, for example, detailed information on all of the properties associated with a particular control. This information can be helpful when you want quick access to information about a particular AppleScript Studio object.
FIGURE 2.22 Accessing the AppleScript Studio application dictionary.
DEBUGGING CAPABILITIES The Xcode Project window also provides an integrated source code debugger, as shown in Figure 2.23. Xcode’s debugger is based on the open source GNU Debugger, GDB. Using the debugger, you can control the execution of your application, pausing it at predefined points in order to inspect the values of variables and to trace the order in which statements are executing. The debugger also provides a Fix and Continue feature that allows you to make changes in your source code and recompile it without having to stop your current debug session.
50
AppleScript Studio Programming for the Absolute Beginner
FIGURE 2.23 Xcode’s built-in debugger provides detailed control over program execution, allowing you to track down and fix hard to find errors.
Xcode also provides command-line debugging capabilities. You will learn more about Xcode’s debugging capabilities later, in Chapter 10.
THE APPLE DEVELOPER REFERENCE LIBRARY Xcode comes equipped with a full copy of the Apple Developer Reference Library documentation. You can view and perform searches on this documentation from within Xcode by selecting the Help menu and clicking on the Documentation menu item. In response, Xcode displays a window similar to the one shown in Figure 2.24. TIP
The Apple Developer Reference Library provides access to documentation, release notes, sample code, and much more. Apple makes this documentation available on its website. Xcode keeps an eye out for updates to the Apple Developer Reference Library and will automatically prompt you to update it when newer documentation is available. You can determine when the last update occurred and configure the update process from the Documentation page on the Xcode Preferences window. From this page you can also click on the Check Now button to initiate an immediate documentation update.
Chapter 2 • The AppleScript Studio Application Development Environment
51
FIGURE 2.24 Accessing the Apple Developer Reference Library from within Xcode.
BACK TO THE APPLESCRIPT STUDIO FORTUNE TELLER GAME Now it is time to turn your attention back to the AppleScript Studio Fortune Teller game. The point of emphasis for this exercise is your interaction with Xcode and its various windows and features. However, in order to build the application, you will also have to work with the Interface Builder (covered in Chapter 3), and you will have to add the required program code, which you will learn about in Chapters 4 through 7. Again, for now, limit your focus on understanding your overall interaction with Xcode and the steps required to build AppleScript Studio applications.
Designing the AppleScript Studio Fortune Teller Game As you have already seen, the AppleScript Studio Fortune Teller game is a relatively simple little Mac OS X application. In Chapter 1, you learned how to build an application using the button control, the small system font text control, and the display dialog function. In order to build the AppleScript Studio Fortune Teller game, you will have to learn how to work with a new control, the text input field control. Using the text input field control, you can build custom user interfaces that collect and display text data.
52
AppleScript Studio Programming for the Absolute Beginner
The development of the AppleScript Studio Fortune Teller game will follow the same basic procedure that you used when building the Knock-Knock Joke application. Specifically, the AppleScript Studio Fortune Teller game will be developed in five steps. 1. 2. 3. 4. 5.
Opening Xcode and creating a new AppleScript Studio application. Building the application’s graphical user interface. Customizing controls and attaching interface controls to event handlers. Adding the AppleScript code required to make the application work. Building and running the application.
Each of these steps is covered in detail in the sections that follow.
Step 1: Creating a New Project The first step in building the AppleScript Studio Fortune Teller game is to start Xcode and create a new AppleScript Studio project as outlined in the following procedure. 1. Double-click on the Xcode icon located in /Developer/Applications. 2. Tell Xcode to create a new project by clicking on the File menu and selecting the New Project menu item. Xcode responds by launching an Assistant, which displays a listing of application templates. 3. Select the AppleScript Application template and click on Next. 4. When prompted by the Assistant to specify a file name and location where you would like to store your new AppleScript Studio application, enter F ortune Teller as the project name and specify the folder where you have decided to store your AppleScript Studio application. Next, tell Xcode to finishing setting up a new project for the application by clicking on the Finish button. At this point Xcode has created a new project, complete with all the files and resources required to build the application. Now the real work begins. Your job is to take this project shell and customize it in order to provide everything needed to build the AppleScript Fortune Teller application.
Step 2: Creating the User Interface Now that you have created a new project for the AppleScript Studio Fortune Teller application, it is time to assemble the controls that will make up the game’s user interface, using the procedure outlined here. 1. Click on the disclosure triangle for the Resources group located in the Groups & Files section in order to expose the MainMenu.nib file. 2. Double-click on the MainMenu.nib file to start the Interface Builder.
Chapter 2 • The AppleScript Studio Application Development Environment
53
3. Use the default application window’s resize handle (located in the lower right-hand side of the window) to resize the window, as shown in Figure 2.25.
FIGURE 2.25 Modifying the size of the application’s user interface.
4. The game’s window is made up a button control, a text field control, and a system font text control. To add and instance of the system font text control to the window, click on the Cocoa Text Control icon located on the Cocoa Text palette toolbar. Select the system font text control and then drag and drop an instance of it onto the application window, centering it in the upper half of the window. 5. To add the text field control, drag and drop an instance of the text field control to the window, resizing it so that it takes up all but about an inch and a half of the lower half of the window. 6. To add a button control, click on the Cocoa Controls and Indicators icon located at the top of the Cocoa Controls palette. Using drag and drop, place the button control just to the left of the text field control. At this point, the application window should resemble Figure 2.26. FIGURE 2.26 The controls that make up the AppleScript Fortune Teller game still require attribute modifications.
Now that the required controls have been added to the application’s windows, it is time to modify window and control attributes, as outlined in the following procedure. 1. Double-click on the button control. This places the cursor inside the control, allowing you to enter text. Type Ask. 2. Resize the system font text control so that it is approximately a half- inch high and takes up most of the available width of the application window. Double-click on the system
54
AppleScript Studio Programming for the Absolute Beginner
font text control that you just added to the window. Type your question in the space provided below and click on Ask to pose your question to the fortune teller. 3. Click on an open area in the application window and then click on the Tools menu and select Show Inspector. 4. If necessary, select Attributes from the popup dialog located at the top of the Inspector window and enter AppleScript Studio Fortune Teller in the Windows Title field and then clear the Zoom (and resize) checkbox. 5. Next, select the window’s text field control. Then click on the Text Color color well in the Inspector window. The Colors window appears, as shown in Figure 2.27. Click on a blue color area within the rainbow colored circle in the middle of the window to set blue as the color for any text entered into the text field.
FIGURE 2.27 Configuring the text color attribute for the text field control.
6. Click on the Background Color color well and set the background color of the text field by making a cream-colored selection. 7. Click on the Line Breaking popup dialog and select the Word Wrap option and select the Wraps radio button for the Layout option on the Inspector window. Together these modifications ensure that any text entered by the player will wrap and break on a clean word boundary. At this point, the game’s interface has been assembled and configured. The next step is to associate the button control’s click event with an event handler, as outlined in the next section.
Chapter 2 • The AppleScript Studio Application Development Environment
55
Step 3: Attaching Controls to Event Handlers It is time to associate the button control with the on clicked event handler, thus allowing the application to react whenever the button is clicked. This is accomplished using the following procedure. 1. Select the button control and, if necessary, click on the Show Inspector option located under the Tools menu to display the Inspector window. 2. Select the AppleScript option from the popup dialog located at the top of the Inspector window. 3. Click on the disclosure triangle just to the left of the of the Action event handler in order to expose the clicked event handler. Select this event handler by clicking on its associated checkbox. 4. Select the radio button associated with the Fortune Teller.applescript script listed in the Script section at the bottom of the Inspector window. 5. Click on the Edit button. Xcode reappears, displaying its code editor. Code statements similar to the following should be displayed. -- Fortune Teller.applescript -- Fortune Teller --
Created by Jerry Ford on 6/30/06.
--
Copyright 2006 __MyCompanyName__. All rights reserved.
on clicked theObject (*Add your script here.*) end clicked
The first four lines are comment statements. A comment is a line of text used to internally document a script that is ignored by the compiler when the application is built and executed. The last three statements represent the on clicked event handler that you just added to the application when you selected the button control’s clicked event and clicked on the Edit button. In the next section, you’ll add the required AppleScript statement inside this event handler to make the AppleScript Fortune Teller application run. TIP
AppleScript supports two types of comments. Typing two consecutive dashes, as demonstrated in the first four statements shown in the previous example, creates the first type of comment. Any text typed after two dashes is considered to be a comment. The second type of comment supported by AppleScript is created by enclosing the text to be commented in between opening, (*, characters and closing, *), characters. You can see an example of this type of comment
56
AppleScript Studio Programming for the Absolute Beginner
in the previous example as well. The advantage of this second type of comment is that is can be used to create comments that span more than one line. By making liberal use of comments, you can make your AppleScript code a lot easier to understand, leaving behind remarks that explain what is going on.
Step 4: Adding a Little Programming Logic Okay, it is time to get down to the business of adding the program code statement required to actually make the application work like you want it to. This is accomplished by embedding the following code statements inside the on clicked event handler, as shown next. -- This code runs whenever the player clicks on the Ask button on clicked theObject -- Assign the text entered by the player to the question variable set question to contents of text field "textbox" of window "main" -- Display an error message if the player did not enter any text if question = "" then display dialog ¬ "Sorry, but you did not ask a question. Please try again." ¬ buttons {"OK"} return end if -- Assign a random number between 1 and 3 to a variable named randomNo set randomNo to random number from 1 to 3 -- If the randomly generated number equals 1 assign an answer of Yes if randomNo = 1 then set answer to "Yes" end if -- If the randomly generated number equals 2 assign an answer of No if randomNo = 2 then set answer to "No" end if -- If the randomly generated number equals 3 assign an answer of Maybe
Chapter 2 • The AppleScript Studio Application Development Environment
57
if randomNo = 3 then set answer to "Maybe" end if beep
-- Play a beep sound to get the player’s attention
-- Display the game's randomly generated answer display dialog "Question: " & question & " Answer: " & ¬ answer buttons {"OK"} end clicked TR
AP
AppleScript Studio is a robust and powerful application development environment. In order to use it to develop new Mac OS X applications, you must first learn how to interact and work with both Xcode and the Interface Builder. In addition to becoming comfortable with these two tools, you must also learn AppleScript. The approach that I have chosen for this book is to get you working with Xcode and the Interface Builder first and then to move on and learn AppleScript. Each of these topics is hard enough to learn on its own, much less simultaneously. So for now, just key in the code statements as instructed. Once you have become comfortable with Xcode and the Interface Builder, you’ll learn the ins and outs of AppleScript coding in Chapters 4 through 7. To help the following code statements make at least a little sense for now, I have embedded a number of comments explaining what various parts of the code are doing.
Step 5: Testing the Execution of the AppleScript Studio Fortune Teller Application Okay, it is time to build and execute the AppleScript Studio Fortune Teller game. Assuming that you carefully followed along each step and that you did not make any typos when entering the application’s program statements, the application should compile and run without incident. To compile the application, click on the Build and Go button located on the Xcode code editor toolbar. Xcode will respond by compiling and then executing your application. Once you have it running, try it out and make sure that everything works as expected.
58
AppleScript Studio Programming for the Absolute Beginner
TIP
If your application fails to run, then you have made a mistake somewhere. Begin by clicking on the Errors and Warnings entry in the Group & Files section of the Xcode Editor window to see if any errors have been reported. You may get a hint of what went wrong from these messages. If the error message(s) don’t help, then go back and make sure that you have followed each of the required steps exactly and that you did not make any typos when keying in the application’s code statements. You will learn the ins and outs of tracking down and debugging program errors later, in Chapter 10.
SUMMARY This chapter introduced you to Xcode and explained each of its major components. This included learning how to add files to projects, view application dictionary terminology, and access the Apple Developer Reference Library. You also learned how to take advantage of many of the features provided by the Xcode code editor and to customize specific Xcode functionality by modifying Xcode preferences. Finally, you learned how to create your second AppleScript Studio application, the AppleScript Studio Fortune Teller game. Before moving on to the next chapter, why don’t you take a few extra minutes to work on the AppleScript Studio Fortune Teller game, adding the improvements outlined in the following list of challenges.
CHALLENGES 1.
2.
The AppleScript Studio Fortune Teller game currently has only a limited collection of replies that it can generate. Improve the game by adding a number of answers such as “Ask again later”, “The answer is unclear”, and “Only time will tell”. You will also need to expand the range of randomly generated numbers. The text on the AppleScript Studio Fortune Teller game’s main window is very basic. Improve the game by adding additional text that explains to the player that the game is intended for only Yes/No type questions.
3
C H A P T E R
BUILDING A GRAPHICAL USER INTERFACE n order to build GUI-based applications using AppleScript Studio, you must become comfortable working with Interface Builder. In addition, you must become familiar with the various Cocoa interface elements that are made available through Interface Builder. Using Interface Builder and Cocoa interface elements, you can create nib files, which are then used to build application interfaces and connect the components that make up the interface to program code residing in event handlers inside AppleScripts. This chapter provides you with instruction on how to work with Interface Builder and its major features. In addition, you will receive an overview of the interface controls needed to build application interfaces. On top of all this, you will learn how to create another computer game, the Typo-matic Typing Test.
I
Specifically, you will learn how to • Work with different types of application windows • Use Cocoa interface controls to build application windows • Access and configure windows and control attributes • Create and modify application menus
60
AppleScript Studio Programming for the Absolute Beginner
PROJECT PREVIEW: THE TYPO-MATIC TYPING TEST GAME In this chapter you will learn how to develop the Typo-matic Typing Test game. This game challenges players to complete a test that measures their typing skills. Two tests are available, Easy and Hard. Players select between these two options using a slider control located at the bottom of the application window, as demonstrated in Figure 3.1.
FIGURE 3.1 The Typo-matic Typing Test game presents players with two levels of play.
In addition to the controls displayed on the application window, the game also has a menu system, which can be used to control the game and display additional information, as shown in Figure 3.2.
FIGURE 3.2 The Typo-matic Typing Test game’s menu system.
By clicking on the About menu item located on the Typo-matic menu, players can access additional information about the game, as shown in Figure 3.3.
Chapter 3 • Building a Graphical User Interface
61
FIGURE 3.3 Viewing the information presented in the application’s About window.
If necessary, players can click on the Instructions button to display a popup dialog where instructions for playing the game are presented, as shown in Figure 3.4.
FIGURE 3.4 Accessing instructions for playing the Typo-matic Typing Test game.
Play begins after the player selects the level of difficulty and then clicks on the Take Test button. Figure 3.5 shows the test that is presented when the Easy level is selected.
FIGURE 3.5 The sentences that make up the Easy level follow a predictable pattern and are not particularly long.
62
AppleScript Studio Programming for the Absolute Beginner
Figure 3.6 shows the sentences that make up the test when the Hard level is selected. As you can see, these sentences are considerably longer and vary in content.
FIGURE 3.6 The advanced test is intended to provide players with a more difficult challenge.
After retyping each of the five sentences that make up the test, players must click on the Grade Test button to see how well they did. In response, the game displays the player’s score in a popup window similar to the one shown in Figure 3.7.
FIGURE 3.7 The game keeps track of correctly and incorrectly typed sentences.
After dismissing the popup window, the game displays any mistyped sentences in red (will appear gray in the book) in order to help players locate their errors, as demonstrated in Figure 3.8.
Chapter 3 • Building a Graphical User Interface
63
FIGURE 3.8 The game identifies sentences with errors by displaying them in a red font.
This game introduces a number of new programming features. For starters, you learn how to work with the slider control. You also learn how to control the availability of interface controls. For example, the player is prevented from entering text in the five text field controls except during game play. This is accomplished by manipulating the text field control’s Enabled attribute during game play. Similarly, the slider control and Take Test button are only enabled at the beginning of each new game and are both disabled once game play begins. As soon as the player finishes taking the test and clicks on the Grade Test button, the slider control and Take Test button are re-enabled to allow for a new game play.
CREATE GRAPHICAL USER INTERFACES Mac OS X 10.4 employs a user interface called Aqua. Aqua defines the standards used by Mac OS X and its applications that control the appearance of interface elements such as windows, menus, controls, and so on. In order to build effective applications that are both intuitive and easy to use, it is important that you adhere to the Aqua guidelines. Since virtually all professionally developed Mac OS X applications adhere to this standard, you won’t find any shortage of examples to follow.
64
AppleScript Studio Programming for the Absolute Beginner
In the Real World In order to build Mac OS X applications that meet the needs and expectation of Mac users, it is important that you adhere to the standards outlined by the Apple Human Interface Guidelines. These guidelines outline standards for specifying the appropriate application window type, the proper placement of interface elements, and the correct way to organize and present menus, menu items, and so on. To help application developers follow these guidelines, Apple publishes them in a PDF document called, apply enough, Apple Human Interface Guidelines. You can view and download a copy of this PDF document at http://developer.apple.com/documentation/UserExperience/ Conceptual/OS XHIGuidelines/. The Apple Human Interface Guidelines document goes to great lengths to define the right way to create Mac OS X application interfaces and provides examples that demonstrate how things should be done.
Fortunately, the Interface Builder assists you in creating GUIs that adhere to Aqua standards. Interface Builder, as you have already seen, is a graphical interface development tool that lets you create GUI application windows. By providing access to predefined collections of Cocoa controls, the Interface Builder facilitates the creation of GUIs using a simple drag and drop approach. Interface Builder lets you move and resize controls added to windows and provides visual indicators that helps keep things straight in even the most complicated GUIs. Interface Builder also provides the ability to modify application attributes and to connect interface elements to AppleScripts using the Inspector window. By default, Interface Builder resides in the /Developer/Applications folder. It can be started by double-clicking on the Interface Builder icon located in this folder. However, it’s far more common to start it by double-clicking on the MainMenu.nib file located in the Xcode Project window’s Files & Groups area. When started, Interface Builder displays a number of windows, as shown in Figure 3.9.
Chapter 3 • Building a Graphical User Interface
Cocoa Controls
MainMenu.nip
65
Window
MainMenu.nib - MainMenu
FIGURE 3.9 Interface Builder consists of a number of interrelated windows, each of which provides a different type of functionality.
As you work with Interface Builder to create a GUI, all of the changes that you made are defined in a nib file. Each new AppleScript Studio application is assigned a default nib file named MainMenu.nib. When the application is later compiled, the instructions defined in the nib file are used to build the interface.
Cocoa Controls The window that displays all sorts of interface controls is referred to as the Cocoa Controls palette. Icons located in the toolbar at the top of the window control when different sets of controls are visible. Interface controls are grouped by category. An overview of the categories and controls is provided later in this chapter. TRI
CK
Interface Builder displays a list of toolbar configuration options when you click on the Cocoa Control palette toolbar while pressing the Control key.
Interface controls provide the basic building blocks for GUIs. To use them, simply drag and drop the appropriate control onto an application window. In addition to interface
66
AppleScript Studio Programming for the Absolute Beginner
controls, you can also add additional windows to your applications by dragging and dropping the appropriate type of window onto the MainMenu.nib window. Interface Builder provides visual indicators that help you properly lay out and align controls. Once they are added to a window, you can modify the size and location of these controls by clicking on them and using the resizing handles that appear around the control. As you resize and move interface controls around a window, the Interface Builder displays visual indicators that help you align the control with other controls already on the window, as demonstrated in Figure 3.10. In addition, as you move controls near the edge of the window, visual indicators also appear, showing you the proper distance to maintain from the side of the window. This helps you to design GUIs that follow the Aqua guidelines.
FIGURE 3.10 Using Interface Builder’s visual indicators to align interface controls.
For controls that display a title, you can change the text of that title by simply double-clicking on it and entering new text. You can further configure these and any other windows or interface controls by selecting them, opening the Inspector window, and then selecting the Attributes view. For example, many interface controls allow you to modify their size and color through attribute changes. As you have already seen a number of times in this book, you can also use the AppleScript view of the Inspector window to associate control events with specific types of event handlers, which are then automatically added to the AppleScript you specify. The AppleScript view also allows to you assign names to each window or control, allowing you to then programmatically reference and control them using AppleScript code statements.
Chapter 3 • Building a Graphical User Interface
67
MainMenu.nib The Interface Builder’s MainMenu.nib window displays a number of different views. By default, the Instances view is displayed when the window is opened, making the following icons visible. • File Owner. An object outside of the nib file that is responsible for facilitating communication between objects defined within the nib when a GUI is created. • First Responder. Specifies the interface element that receives focus when the GUI is opened. • MainMenu. Stores the definitions that describe the contents and organization of the application’s menu. • Window. Represents the default application window for the AppleScript Studio application. TIP
Focus is a term used to identify the interface element that is the target for keystrokes. Users set focus by clicking on or selecting Window objects.
You will not need to do anything with the File Owner object. You don’t usually need to do anything with First Responder either. However, you will spend a lot of time working with MainMenu and Window. MainMenu represents an instance of an application menu. If need be, you can add additional menu instances to your application in order to develop other menus. Window represents an instance of a Window object. Although AppleScript Studio projects begin with a single instance of the Window object, you can add as many instances as your project requires. TIP
The Cocoa framework is object-oriented. Each time you use Interface Builder to add a window or control to an AppleScript Studio project, you are actually creating a new instance of a Window or Control object. This new instance inherits its characteristics and attributes from the class it is based on. A class is a template, which outlines the characteristics and attributes of a particular type of object, such as a window, button, or slider control.
MainMenu.nib – MainMenu The MainMenu.nib – MainMenu window provides you with an interactive copy of your AppleScript Studio application’s menu system. You will use this window to modify the application’s menus. By default, each AppleScript Studio project includes a default set of menus and menu items. You can modify these menus and menu items by changing their names and attributes. In addition, you can delete any unneeded menus or menu items or add new ones
68
AppleScript Studio Programming for the Absolute Beginner
to meet the particular needs of your application. More information on how to work with and modify menus is provided later in this chapter.
Window The last window displayed by Interface Builder is the window representing an AppleScript Studio application’s default or main window. This window is blank for any new project. You can use its title bar to move it around and change its height and length using its resize handle. Windows make up the foundation of GUIs. Your AppleScript Studio project can include as many windows as necessary. As you will learn later in this chapter, Interface Builder allows you to add and modify many different types of windows, each of which has its own particular sets of characteristics.
COCOA INTERFACE ELEMENTS Cocoa provides the AppleScript Studio application with access to an abundant collection of interface elements. These elements include menus, controls, and windows. You will learn how to work with each of these resources in the remainder of this chapter.
Cocoa Menus Menus represent a key component of most Mac OS X applications. They provide users with access to a list of commands that can be executed and used to present and control attribute information. As an AppleScript Studio application developer, it is important that you have a solid understanding of how to construct and organize application menus. Mac OS X menus are made up of numerous parts, as demonstrated in Figure 3.11. Menu
Separator Bar Menu Item Submenu
FIGURE 3.11 The contents of a typical Mac OS X application menu.
Keyboard Equivalent
Chapter 3 • Building a Graphical User Interface
69
Mac OS X application menus are displayed in a menu bar that is located at the top of the screen. This menu bar is always visible, except in situations where an application temporarily hides it, as would be the case when playing a full screen movie or computer game. By standardizing the location of menus, Aqua simplifies the Mac OS X desktop by providing a predictable location where the user will always know to look. Menus contain one or more menu items. Logically related menu items are grouped under the same menu. A menu item may be used as a submenu, which when clicked displays a subgrouping of additional menu items. Menu items may also have keyboard equivalents assigned to them. Using the keystroke combinations assigned to a keyboard equivalent, users can access menu items directly from the keyboard without having to use a mouse. Menus may also contain Separator Bars, which are graphical lines used to visually group related menu items and help set them off from other menu items.
Default Menus By default, each new AppleScript Studio project is assigned a default set of menus, as demonstrated in Figure 3.12. These menus consist of the following. • Application • File • Edit • Window • Help
FIGURE 3.12 Each AppleScript Studio application is assigned a default set of menus.
Deleting Menus and Menu Items If your application does not need some of the menu items or menus that are provided by default, you can delete them. To delete a menu item, click on the menu that contains it, select
70
AppleScript Studio Programming for the Absolute Beginner
the menu item, and then press the Delete key. Likewise, to delete an entire menu, including all of its menu items, select the menu and press the Delete key.
Adding New Menus, Menu Items, and Submenus In order to add new menus and menu items to a menu, click on the Cocoa Menus button located in the Cocoa Control palette to display the list of available menu items, as shown in Figure 3.13.
FIGURE 3.13 Click on the Cocoa Menus button to view the available palette of menu building options.
As you will see, the list of menu items shown in Table 3.1 is displayed. Except for the Separator and Item entries, each of the menu and submenus listed in Table 3.1 comes already configured with default menu items. For example, when you add the Format menu, it already has two submenus attached to it (Font and Text), and both of these submenus are populated with numerous menu items. TIP
In addition to each of the menus outlined in Table 3.1, each Mac OS X application’s menu system always includes an Apple and a Spotlight menu. Both of these menus are automatically created and maintained by Mac OS X and are outside of your control.
You add new menus, menu items, and submenus to application menus by selecting a menu item displayed in Interface Builder and dragging and dropping it to the appropriate location in the MainMenu.nib window. For example, you can add a new menu to your application using the following procedure.
Chapter 3 • Building a Graphical User Interface
TABLE 3.1
71
COCOA MENUS LISTED ON INTERFACE BUILDER’S COCOA MENUS VIEW
Menu
Description
Application
This menu displays items that affect the entire application. Common menu items typically found on this menu include About, Hide, and Quit. This menu typically displays items that control operations like Save, Print, Open, and Close. This menu provides access to commands that facilitate editing operations and the movement of data between applications, including commands like Cut, Copy, and Paste. This menu provides access to commands that control the display of application windows, generally including commands like Minimize and Zoom. This menu provides access to commands that are used to perform search operations within a window. This menu provides access to commands used to control the display of text, including Bold, Italic, and Underline. This item is used to insert a graphic separator line between submenu items. This menu provides access to commands that control the display and alignment of text. This item is used to add a new custom menu or to create a submenu under a menu. This item is used to add a new custom item to a menu or submenu. This menu provides access to commands that control the formatting and presentation of text. This icon is added to the MainMenu.nib window in order to create a new instance of a menu bar.
File Edit Window Find Font Separator Text Submenus Item Format Menu
TIP
While you can programmatically create menus, the focus of this book is on the creation of menus using Interface Builder. Menu creation through Interface Builder has many advantages. For starters, it is easier and faster, allowing for rapid development. In addition, Interface Builder provides a WYSIWYG view of your menus, allowing you to view and navigate them without having to first compile and run your AppleScript Studio application.
1. Click on the Cocoa Menus button in the Interface Builder toolbar. 2. Drag and drop the Submenu option onto the menu area in the MainMenu.nib – MainMenu window, as shown in Figure 3.14. 3. Double-click on the new menu and give it a new name. 4. Click on the new menu to display its initial default menu item. 5. Double-click on the menu item and give it a new name. 6. Add as many additional menu items or submenus as needed to the menu.
72
AppleScript Studio Programming for the Absolute Beginner
FIGURE 3.14 Adding a new menu to the default application menu bar.
In similar fashion, you can add a menu item to any menu using the steps outlined in the following procedure. 1. Click on the Cocoa Menus button in the Interface Builder toolbar. 2. Drag and drop the Item option onto a menu in the MainMenu.nib – MainMenu window, as shown in Figure 3.15. FIGURE 3.15 Adding a new menu item to an existing menu.
3. Double-click on the menu item and give it a new name. 4. Repeat steps 2 and 3 as many times as necessary. Adding a submenu is a straightforward process as well, as outlined in the following procedure. 1. Click on the Cocoa Menus button in the Interface Builder toolbar. 2. Drag and drop the Submenu option onto a menu in the MainMenu.nib – MainMenu window, as shown in Figure 3.16.
FIGURE 3.16 Adding a new submenu item to an existing menu.
3. Double-click on the submenu item and give it a new name. 4. Double-click on its default menu item and give it a new name. 5. Add more menu items or submenus as needed to the submenu.
Chapter 3 • Building a Graphical User Interface
73
Configuring Menus, Menu Items, and Submenus Once they are added, you can rearrange menus by dragging and dropping them to new locations. You can also rearrange menu items and submenus by dragging and dropping them to different locations on a menu. Mac OS X applications also support the addition of keyboard equivalents to menu items. This allows users to access menu items from the keyboard without having to use the mouse. Keyboard equivalents are set using the Inspector window, as outlined in the following procedure. 1. Select the menu item to which you want to assign a keyboard equivalent and open the Inspector window. 2. Select the Attributes view from the popup control location at the top of the window. 3. Enter the character to be assigned or click on the <no key> popup control and select one of the available special function keys. 4. Select a combination of one or more Key Modifier keys, as shown in Figure 3.17.
Shift
Option
Command
Control
FIGURE 3.17 Assigning a keystroke equivalent to a menu item.
5. Close the Inspector window. 6. The new keyboard equivalent should be immediately visible on the menu item to which it was added, as demonstrated in Figure 3.18.
74
AppleScript Studio Programming for the Absolute Beginner
FIGURE 3.18 A keyboard equivalent of Shift+Command+J has been assigned to the Screen menu item.
TR
AP
Do not assign the same keyboard equivalent to more than one menu item. Many keyboard equivalents have predefined standard uses, so avoid assigning these except when appropriate. For example, Command+C and Command+V keyboard equivalents should only be assigned to Copy and Paste menu items located on the Edit menu. Experienced Mac OS X users will expect you to follow these types of standards. Failure to do so will result in confusion and frustration for your users.
Cocoa Controls and Indicators Application GUIs are created by adding instances of interface controls to windows. The Interface Builder’s Cocoa Controls view, shown in Figure 3.19, provides AppleScript Studio application developers with access to an assortment of Cocoa controls, including button, selection, progress indicator, and level indicator controls. The sections that follow briefly describe the controls provided on the Cocoa Controls view.
FIGURE 3.19 Use the Cocoa Controls view to add various controls to windows.
Buttons Button controls are used to initiate an immediate action within your AppleScript Studio applications. Button controls have rounded corners and can display a text label, as demonstrated in Figure 3.20.
Chapter 3 • Building a Graphical User Interface
75
FIGURE 3.20 Use the button control as a means of allowing users to initiate a specific action.
Color Well Controls The color well control, shown in Figure 3.21, is a button-sized rectangle that displays the current color setting for a specific resource. When clicked, it displays the Colors window, from which the user can select a new color. FIGURE 3.21 When clicked, the color well control opens the Color window.
Metal Buttons Metal button controls are used to initiate immediate actions within AppleScript Studio applications made up of metal windows. Metal buttons can display text, graphics, or icons. Metal buttons also have rounded corners, as demonstrated in Figure 3.22. FIGURE 3.22 The metal button control is used on metal brushed windows.
Round Buttons A round button control, as you’d expect, is a button that is round, as demonstrated in Figure 3.23. Round buttons can be used to display a graphic or can be used in conjunction with a label. Round buttons are often used to build navigation controls. FIGURE 3.23 Round buttons can be blank or display a graphic, but are not able to display text.
76
AppleScript Studio Programming for the Absolute Beginner
Help Buttons A help button control provides users with easy access to the Help Viewer, allowing you to configure it to open a specific help page. The Help button is identified by the presence of a question mark character, as shown in Figure 3.24. The Help button is usually placed in the lower left-hand corner. FIGURE 3.24 Help buttons display a question mark sign.
Bevel Buttons Bevel button controls have beveled edges that give them a three-dimensional look. Bevel buttons can have square or rounded edges. They can be configured to work like standard buttons or grouped in bunches and treated like checkboxes or radio buttons. Bevel buttons can also display text, icons, or images, as demonstrated in Figure 3.25. FIGURE 3.25 The bevel button control can be customized to display a graphic image.
Stepper Controls The stepper control, shown in Figure 3.26, is used to give the user the ability to increment or decrement a value. Typically, the stepper control is used along with a text field that displays a value controlled by the stepper control. FIGURE 3.26 Using the stepper control to control a value displayed in a text box.
Slider Controls The slider control, shown in Figure 3.27, provides the user with the ability to select from a range of values by dragging the thumb to a different location on the slider bar. Slider controls
Chapter 3 • Building a Graphical User Interface
77
can be displayed horizontally or vertically and can display optional tick marks in order to help identify different values. FIGURE 3.27 Slider controls allow users to pick from a range of values.
Disclosure Triangles A disclosure triangle, shown in Figure 3.28, is used to control the display (disclosure) of additional information on controls on windows. For example, you might develop a window that displays summary information at the top and detailed information at the bottom and then use a disclosure triangle to control the expansion of the window in order to allow the detailed information to be displayed. FIGURE 3.28 Disclosure triangles are used to control the view of information within a window.
Checkbox Controls A checkbox control, demonstrated in Figure 3.29, is used to provide the user with the ability to select between predefined options. Checkboxes are typical used in conjunction with a text field control that provides labels that describe the purpose of the checkbox controls. FIGURE 3.29 Checkbox controls are used to present users with a selection between two values.
Radio Button Controls Radio button controls, shown in Figure 3.30, are used in groups of two or more in order to allow users to make a selection from a list of available choices. Radio buttons are used to allow users to make selections and not to initiate an action like other button controls.
78
AppleScript Studio Programming for the Absolute Beginner
FIGURE 3.30 Radio buttons are used to allow users to make a selection from a list of different choices.
Popup Controls A popup control, shown in Figure 3.31, is used to display a list of two or more choices from which the user can make a selection. Popup controls provide an alternative to radio buttons when space is limited. FIGURE 3.31 A popup control provides a spacesaving way to display a list of possible choices.
Once a control is added to a window, you can define the list of available choices by doubleclicking on the control and then double-clicking on each of the default entries and overtyping them. Additional choices can be added using the Attributes view of the Inspector window.
Level Indicators A level indicator control is used to display a graphical depiction regarding the level of something. A level indicator can be configured to display data in different ways. For example, Figure 3.32 shows two level indicators. The first level indicator is displaying data in a discrete view. The second level indicator is displaying data in a continuous view and includes tick marks that identify different levels. You can also configure level indicators to display a different color when values exceed predefined levels. FIGURE 3.32 Level indicators let you visually communicate a value to a user.
Chapter 3 • Building a Graphical User Interface
79
Progress Bar Indicators Progress bar controls are used to indicate the status of a process or operation. Three types of progress bars are supported, as outlined here. • Determinate. Used when the duration of an operation is known in advance and can be tracked. • Indeterminate. Used when the duration of an operation is not known in advance and cannot be tracked. • Asynchronous. Used when there is limited space available to display the control. Each of these different types of progress bars is demonstrated in Figure 3.33. Determinate Indeterminate Asynchronous
FIGURE 3.33 Different types of progress bars are supported based on the needs of your application.
Segmented Controls Like checkbox and radio button controls, the segmented control, shown in Figure 3.34, can be used to present users with access to two or more choices, the results of which affect the view or mode of the applications. Segmented controls can display either text or icons or can also be used to initiate an action. FIGURE 3.34 A segmented control is used to present the user with access to two or more choices.
Box Controls The final set of interface elements made available on the Cocoa Controls view of the Cocoa Controls window are the box controls, which are displayed as horizontal and vertical lines, as shown in Figure 3.35. Their purpose is to help organize and group other interface elements.
80
AppleScript Studio Programming for the Absolute Beginner
FIGURE 3.35 Box controls are used to organize and group other interface elements.
Cocoa Text Controls Application GUIs typically display a lot of text and are often used to collect text input from users. The Interface Builder’s Cocoa Text controls, shown in Figure 3.36, provide AppleScript Studio application developers with access to an assortment of text-based Cocoa controls. The sections that follow briefly describe the controls provided by the Cocoa Controls view.
FIGURE 3.36 Use Cocoa Text controls to display and collect text data.
Static Text Static text field controls display read-only text and are typically used to provide instruction and to label other controls. The Interface Builder provides easy access to a number of static text fields in different fonts, as shown in Figure 3.37. FIGURE 3.37 Static text fields are used to display text that does not change.
Chapter 3 • Building a Graphical User Interface
81
Text Fields A text field control, shown in Figure 3.38, is a rectangular field that allows users to enter text. Text fields can also be modified to make them display-only and can be configured to display with different kinds of borders. FIGURE 3.38 Text fields provide a simple way for collecting information typed in by the user.
Token Fields A token field control, shown in Figure 3.39, is one that builds a token based on the text entered into it. Since the text entered into the token field is treated as a token, it can be dragged and dropped onto other token fields. FIGURE 3.39 Token fields provide a convenient way of allowing data to be copied from field to field.
Number and Date Formatters The number and date formatter controls, shown in Figure 3.40, are used in conjunction with text field controls. By dragging and dropping one of these controls onto a text field, you set the text field up to store and format the specified type of data. Using the Inspector window, you can specify the precise formatting to be applied. FIGURE 3.40 The number and date formatter controls are used to control the formatting of data entered into text fields.
82
AppleScript Studio Programming for the Absolute Beginner
Text View Fields A text view control, demonstrated in Figure 3.41, is a multi-line text entry field that displays built-in slider controls when the amount of text entered exceeds the display area of the control.
FIGURE 3.41 The text view field can be used as the basis for creating a simple text editor.
Date Pickers The date picker control, demonstrated in Figure 3.42, is used to display and collect date and time information. It can be configured to display either in a simple text field or graphically as a calendar and clock.
FIGURE 3.42 The date picker control supports two distinct formats.
Form Fields Form field controls, demonstrated in Figure 3.43, are just text fields that are designed to be used within the context of a form. FIGURE 3.43 A simple two-field form.
Combo Box Controls Combo box controls, demonstrated in Figure 3.44, are a combination of a text field and a popup control. Combo box controls allow users either to enter text or to select from a predefined set of entries.
Chapter 3 • Building a Graphical User Interface
83
FIGURE 3.44 Combo box controls provide programmers with the flexibility of setting up a field that accepts both predefined and ad-hoc text input.
Search Fields A search field control, shown in Figure 3.45, is a text field into which users type a text string in order to initiate a search. Search fields display a small magnifying glass icon and have distinct rounded edges. FIGURE 3.45 Search fields are used to support text search operations.
Cocoa Windows Windows provide a framework for building graphical user interfaces. Mac OS X applications can consist of many different types of windows, each of which has its own particular set of characteristics, such as the ability to minimize, zoom, or display a title bar. These windows can be organized into the following groups. • Document. These windows are used to display the contents of files such as text documents and spreadsheets. A document window is automatically created in any new AppleScript Studio application created using the AppleScript document-based Application template. • Application. These windows typically make up the main window for non-document applications. An application window is automatically created for any new AppleScript Studio application created using the AppleScript Studio Application template. • Dialog. These are specialized popup dialogs designed to retrieve a specific form of input from the user. Examples of dialogs include Save and Print dialogs as well as popup dialogs created using the display dialog command. • Utility. These windows are typically used to provide access to commands or tools that affect other parts of an application. These windows typically float on top of other windows, making them visible at all times. An example of this type of window is Interface
84
AppleScript Studio Programming for the Absolute Beginner
Builder’s Inspector window, which can be used to set attribute settings and associate windows and controls with event handlers.
Basic Window Components and Characteristics Mac OS X windows generally share a number of common features or components. All windows must have a title bar, even if it does not display a title. The title bar allows users to drag and drop windows, thus moving them to different locations. Except for popup dialog windows, windows should always display a Close button in the title bar. Dialog windows display button controls within the window that control window closure. In addition, document windows may also include scroll bars that allow documents that appear larger than the window to be fully examined and edited. Document windows also typically include other controls such as the resize handle. Utility windows, on the other hand, typically cannot be resized and do not display Close and Minimize buttons. Mac OS X windows can also sport either of two different appearances. The first is the standard default look, and the other is a metal brushed look. Standard windows are turned into metal windows by changing their Has Texture attribute. Metal windows are different from standard windows in other ways than just their appearance. For example, you can move a standard window only by dragging its toolbar. Dragging any part of the window’s surface, on the other hand, can move a metal window. General use of brushed metal windows is discouraged. Instead, brushed metal windows are generally reserved for applications that attempt to re-create the interface of a physical device, such as a CD-ROM or DVD player or that serve as an interface for controlling connections to physical devices. A good example of an application that uses brushed metal windows is the Apple iPhoto application, as shown in Figure 3.46. Windows have an additional set of characteristics that define their behavior towards other windows. These characteristics include: • Modeless. This type of window allows you to interact with other parts of the application while the window is displayed. • Document Modal. Once displayed, this type of window prevents you from doing anything to the document it is associated with until you close the document modal window. • Application Modal. This type of window prevents you from interacting with other parts of the application until you close it.
Chapter 3 • Building a Graphical User Interface
85
FIGURE 3.46 A brushed metal window.
Using Interface Builder to Add Windows to Your AppleScript Studio Applications A standard default window is added to each new AppleScript Studio project. You can add additional windows to your application as required by dragging and dropping items from the Interface Builder’s Cocoa Windows view, shown in Figure 3.47, onto the MainMenu.nib window. When you do so, an instance of the new window is displayed in that window. In addition, the new window is displayed so that you can begin configuring it.
FIGURE 3.47 The Cocoa Windows view simplifies the process of adding new windows to your application.
86
AppleScript Studio Programming for the Absolute Beginner
In the Real World Just about every serious Mac OS X application these days provides information about itself and its author, including copyright data, in an About window located on the application’s Application menu. For example, Figure 3.48 shows an example of a typical About menu.
FIGURE 3.48 The About window for an AppleScript Studio application named Typomatic.
About windows typically consist of a standard window that displays a Close button. In addition, the name of the application and its version are displayed, as well as copyright information. A brief description of the application may also be provided in addition to contact information. About windows are different from other windows in your AppleScript Studio applications in that they are automatically created for you based on information that you provide as you work on the project. If you go back and check, you will see that an About window has been automatically built for each AppleScript Studio application that you have created so far. The information provided by default is typically not sufficient for most applications. Fortunately, you can easily modify the data that is displayed in the About window by modifying the contents of the InfoPlist.strings file located in the Groups & Files Resources group. When you double-click on this file, the contents of the InfoPlist.strings file are displayed. You should see a statement similar to the line shown here. NSHumanReadableCopyright = "Copyright 2006 __MyCompanyName__.";
You can then edit the information displayed in this statement to update the contents of your application’s About window.
Chapter 3 • Building a Graphical User Interface
87
In the Real World The next four sections provide instruction on how to add different types of windows to your AppleScript Studio applications. Instances of these windows can be created by dragging and dropping the appropriate window from the Interface Builder’s Cocoa Windows view onto the MainMenu.nib window.
Adding Windows You could add instances of the standard default window to your project by dragging and dropping the window labeled Window from the Interface Builder’s Cocoa Windows view onto the MainMenu.nib window. Once this is added to your project, you can select the window and open the Inspector window in order to configure the window. For example, you can specify whether the Minimize or Zoom button is active by selecting or clearing the Minimize and Zoom checkbox controls listed in the title bar section. You can also specify whether the window is displayed when the application starts by setting or clearing the Visible at Launch Time checkbox located in the lower half of the Inspector window’s Attributes view. If you want, you can convert the window into a brushed metal window by selecting the Has Texture checkbox. By default, any windows that you add are not displayed at application startup. If you want, you can programmatically display a new window within your script code. For example, you might add the following statement to the on click event handler for a button control in order to initiate the display of a window named main. set visible of window " main " to true
Similarly, you could stop displaying this same window using the following code statement. set visible of window " main " to false
Adding Drawers Mac OS X also supports the addition of a drawer to a window. A drawer is a window that slides out from under a parent window in an animated fashion. Drawers are often used to display a control or information that, while useful, is not used enough to justify making it readily available on the parent window. A drawer can only be displayed when its parent window is visible. You can add a drawer to an AppleScript Studio project by dragging and dropping an instance of the Window and Drawer object from the Interface Builder’s Cocoa Windows view onto
88
AppleScript Studio Programming for the Absolute Beginner
MainMenu.nib. This adds three new instances to MainMenu.nib, as shown in Figure 3.49 and outlined below.
FIGURE 3.49 Three new instances are added to the MainMenu.nib window when a Window Drawer object is added.
• Parent Window. Use this instance to add interface items to the parent window. • DrawContentsView. Use this instance to add interface items to the Drawer window. • NSDrawer. Use this instance to connect event handlers for the Drawer object. The following example demonstrates how to add a window with a drawer to an AppleScript Studio application. 1. Create a new AppleScript Studio application project. 2. Open the MainMenu.nib file and delete the default Window object by selecting it and pressing the Delete key. 3. Drag and drop an instance of the Window and Drawer object onto the MainMenu.nib folder. 4. Select the new parent window instance and open the Inspector window. Select the Visible at Launch Time option to have the window displayed when the application first starts. 5. With the Inspector window still open, select the NSDrawer instance located in the MainMenu.nib window. Modify its Preferred Edge attribute by selecting Left from the list of available options. Switch over to the AppleScript view and assign a name of drawerwindow to the object. This name will be used to programmatically control the display of the drawer in the AppleScript portion of the application. Close the Inspector window. 6. Double-click on the parent window instance to open it.
Chapter 3 • Building a Graphical User Interface
89
7. Drag and drop an instance of a button control onto the window. Double-click on it and type Hide to set its default title. Close the parent window. 8. Select the button control and open the Inspector window. Set up the connection with the button control’s on clicked event and the application’s default script file. 9. Add the following code statements inside the on clicked event handler. on clicked theObject tell window of theObject if title of theObject is "Show" then tell drawer "drawerwindow" to open drawer set title of theObject to "Hide" else tell drawer "drawerwindow" to close drawer set title of theObject to "Show" end if end tell end clicked TRI
CK
The statement tell window of theObject tells the application to target the window whose object initiated the on clicked event handler (in this case the button control located on the parent window). The next seven lines of code check to see if the button control displays the text Show or Hide. If it displays Show, a tell command is used to display the drawer, and the set command is used to toggle the text displayed on the button control so that it says Hide. The next several lines of code do just the reverse, closing the drawer and changing the button’s title back to Show. Because AppleScript is very English-like, you should have a pretty good feel for just what is going on in this code, even if the syntax seems a little awkward. Chapters 4–7 will help wash away this awkwardness by providing you with a solid review of AppleScript programming and syntax.
10. Build and run the application. Once started, click on the Show button. In response, the drawer will appear, and the title assigned to the Button control will change to Hide, as demonstrated in Figure 3.50. Clicking on the button again will close the drawer.
90
AppleScript Studio Programming for the Absolute Beginner
FIGURE 3.50 An example of a window with a drawer extending from its left-hand side.
Note that you can also add a drawer to an existing window by dragging and dropping the drawer window from the Interface Builder’s Cocoa Windows view onto the MainMenu.nib window and then configuring an existing window to use it. However, this is an advanced exercise that is outside the scope of this book.
Creating Utility Windows Utility windows are good for situations where you want to provide users with access to data or controls while they work on a particular task. Utility windows are designed to float on top of other windows, ensuring that they always remain visible while open. One way to create a utility window is to drag and drop an instance of the panel window onto the MainMenu.nib window and then enable the panel window’s utility window attribute. Figure 3.51 shows an example of a utility window created by configuring a panel window. Note the characteristically squared corners of the utility window. You can add interface controls and configure panel windows just like any other window. If desired, you could set the utility window to automatically open when the application starts by setting its Visible at Launch Time attribute. You can also programmatically control the display of panel windows.
Chapter 3 • Building a Graphical User Interface
91
FIGURE 3.51 An example of an application and a utility window.
Attaching a Sheet to a Window A sheet is a window that is attached to the top of another window. When displayed, a sheet is document modal, meaning that until the sheet is closed, the window to which it is attached cannot be accessed. You can use the Panel object as the basis for adding a sheet to a window. Sheets are typically used for managing the saving or printing of documents. Sheets are often used to collect confirmation information, such as permission to close a particular window. Because a sheet can only be associated with a particular window, they should not be used to perform an operation that affects more than one window. In some ways sheets resemble drawers. Both are associated with specific windows, and both are opened in an animated fashion to provide access to additional content or controls. However, while a drawer appears to open from behind or under a window, sheets open on top of them. In addition, drawers are not document modal like sheets and do not hide parent window contents. The following example demonstrates how to attach a sheet to a window and use it to require the user to respond before allowing any additional activity to continue. 1. Create a new AppleScript Studio application project and add a button control and assign a title of C lose to it. 2. Using the Inspector window, change the name of the window to main. Later, in the script portion of the application, you will use this name to reference this window. 3. Set up the button control’s on clicked event handler. 4. Drag and drop an instance of the Panel object onto the MainMenu.nib folder.
92
AppleScript Studio Programming for the Absolute Beginner
5. Using the Inspector window, change the name of the window to QueryPanel. Later, in the script portion of the application, you will use this name to control the display of the panel. 6. Open the new panel window and configure it as shown in Figure 3.52.
FIGURE 3.52 Using the Panel object as the basis for attaching a sheet to a window.
7. Set up the on clicked event handler associations for both button controls. 8. Add the following code statements inside the on clicked event handler on clicked theObject set confirmation to window "QueryPanel" if title of theObject = "Close" then display confirmation attached to window "main" end if if title of theObject = "No" then close panel confirmation end if if title of theObject = "Yes" then close panel confirmation close window "main" end if end clicked TRI
CK
The previous code example begins by using the set command to associate a reference to the panel (e.g., QueryPanel). The next three sets of statements execute when their associated button control is clicked. The first set of statements runs when the main window’s Close button is clicked and is responsible for displaying the panel window as a sheet attached to the main window. Rather than display the panel as a standalone window, the attached to parameter was added to the
Chapter 3 • Building a Graphical User Interface
93
statement in order to configure the panel to display as a sheet attached to the main window. The second set of statements runs when the No button on the panel window is clicked and is responsible for closing the panel window. Finally, the last set of statements executes when the Yes button is clicked and is responsible for closing both the QueryPanel panel window and the main window.
9. Build and run the application. Once started, click on the Close button. In response, a sheet will appear by dropping down from the top of the window, as demonstrated in Figure 3.53. If you click on No, the sheet will close, and the main window will remain visible. However, if you click on Yes, the sheet disappears, and the main window closes.
FIGURE 3.53 An example of a sheet dropping down from the top of a window.
Cocoa Data Views Interface elements located in the Cocoa Data view of the Interface Builder, shown in Figure 3.54, provide the building blocks needed to create windows that display data in different views. • Browser view. Used to display a list of data and organized in a hierarchical fashion. • Table view. Displays records in a table format. Individual columns are resizable, and the data inside the table can be edited. This control is often used to build a front-end view of data stored in a database. • Outline view. Used to display hierarchical data and is typically used to display the contents of file systems.
94
AppleScript Studio Programming for the Absolute Beginner
FIGURE 3.54 Cocoa Data views provide you with the ability to select data from various types of views. Three primary views are provided as outlined below.
Browser view
Table view
Outline view
Examples of each of these controls proliferate Mac OS X applications and windows. For example, Figure 3.55 demonstrates the use of the Browser view used by the standard Save As window.
FIGURE 3.55 An example of the Browser view in action.
Cocoa Container Views The last set of interface controls reviewed in this chapter is the Cocoa Container Views controls shown in Figure 3.56. These controls serve a number of different purposes, as listed next. • Tab view. Used to define an area in a window that consists of two or more views. These views can only be seen one at a time based on the currently selected tab.
Chapter 3 • Building a Graphical User Interface
95
• Box. Used to set up an area in a window that will be used to store and organize a group of related controls. • Custom view. Used to define an area in a window where custom graphics can be programmatically drawn. • Image view. Used to define an area in a window where a graphic can be displayed. This control can also be used to display images that are dropped and dragged on to it at runtime.
FIGURE 3.56 Cocoa Container controls let you group and control access to embedded controls.
BACK TO THE TYPO-MATIC TYPING TEST GAME It is time to turn your attention back to the Typo-matic Typing Test game. The primary point of focus for this game is on the development of the game’s graphical user interface using Interface Builder. Pay particular attention to the attribute changes that are made to the interface controls added to the application window.
Designing the Game In addition to showing you how to work with the slider control, the development of the application will also provide you with insight into the manipulation and control of interface controls, both from within Interface Builder and from program code. The development of the Typo-matic Typing Test game will occur in five distinct steps, as outlined below. 1. Starting Xcode and creating an AppleScript Studio application. 2. Designing the application’s graphical user interface using Interface Builder. 3. Making menu, window, and control attribute modifications and then attaching interface controls to event handlers. 4. The addition of the required AppleScript code statements. 5. Building and compiling the application.
96
AppleScript Studio Programming for the Absolute Beginner
At this point in the book, you have already gained significant experience in working with the Inspector window in order to manipulate windows and control attributes. In addition, you already have an understanding of how to attach interface controls to AppleScripts. Therefore, in this application and all the applications that follow, I will start providing higher-level instructions on attribute changes and interface controls to AppleScript connections, with the expectation that you will be able to make these changes without detailed line-by-line instruction. This will help to simplify the overall instruction required to build the application and provide additional room for me to describe particular aspects of the application.
Step 1: Creating a New Project If Xcode is not already started, start it now and then create a new AppleScript Studio project, as outlined in the following procedure. 1. Click on the File menu and select New Project. An Assistant will launch, displaying a listing of application templates. 2. Select the AppleScript Application template and click Next. 3. When prompted, specify Typo-matic as the file name for the application and then specify the folder where you would like to store this AppleScript Studio application. 4. Finish set up of this new Xcode project by clicking on the Finish button.
Step 2: Creating the User Interface The next step in the development of the Typo-matic Typing Test game is to put together its graphical user interface, as outlined in the following procedure. 1. Expand the Resources group located in the Groups & Files section of the Xcode Project window and then double-click on the MainMenu.nib file to start the Interface Builder. 2. Use the application window’s resize handle (located in the lower right-hand side of the window) to increase the size of the window until it is approximately 10 inches wide and 7 inches tall. 3. The game’s GUI will consist of seven small system font text controls, five text field controls, one slider control, and three button controls. Using the Cocoa Text Controls view of the Interface Builder window, add the first five small system font text controls and the five text field controls, as shown in Figure 3.57.
Chapter 3 • Building a Graphical User Interface
97
FIGURE 3.57 Building the data entry portion of the game’s graphical user interface.
4. Now, using the Cocoa Controls view of the Interface Builder window, add the slider control and the three button controls. 5. Finally, switch back to the Cocoa Text Controls view of the Interface Builder window and add two additional small system font text controls, as shown in Figure 3.58.
Step 3: Customizing Menus and Control Attributes, and Associating Controls with Event Handlers The overall construction of the game’s GUI is now complete. The next step is to configure the application’s menu system, modify window and control attributes, and then associate the button controls with the on clicked event handler, as outlined in the next several sections.
Menu Customization The first step in customizing the menu system for the Typo-matic Typing Test is to remove default menus and menu items that are not required by the application. For starters, like many small applications, the Typo-matic Typing Test game does not contain any help. So you should delete the Help menu by clicking on it and pressing the Delete key. Next, delete all of the menu items located on the Window menu except for the Minimize menu item. Even though the player is unlikely to use them, you may want to keep the Edit menu and its default list of menu items. Next, click on the File menu and remove everything but the Page Setup and Print menu items.
98
AppleScript Studio Programming for the Absolute Beginner
FIGURE 3.58 Adding the rest of the controls required to build the Typo-matic Typing Test GUI.
At this point, all of the basic menus and menu items required by the application are in place. However, before moving on to the next section, there is one more set of tasks to perform on the Application menu. These tasks involve customizing this menu to make it better represent the application, as outlined here. 1. 2. 3. 4.
Double-click on the Application menu and replace its name with Typo-matic. Modify the About Application menu item to read About Typo-matic. Modify the Hide Application menu item to read Hide Typo-matic. Modify the Quit Application menu item to read Quit Typo-matic.
Setting Control Attributes A number of changes need to be made to the window and controls that make up the graphical user interface. These changes, outlined in Table 3.2, must be made on the AppleScript and Attribute views of the Inspector window. Note that the button control labeled Grade Test has been disabled. It should only be available after a test has been started and will be enabled programmatically at the right moment in the code portion of the application.
Setting Up Event Handler Connections Next, set up each of the three button controls so that they will trigger the on clicked event handler whenever the user clicks on them. It is important that you trigger each button
Chapter 3 • Building a Graphical User Interface
TABLE 3.2 MODIFICATIONS TO THE APPLICATION WINDOW CONTROLS Object
Attribute
Modification
Window
Name Window Title Zoom Name Draw Text Border Line Breaking Layout Name Draw Text Border Line Breaking Layout Name Draw Text Border Line Breaking Layout Name Draw Text Border Line Breaking Layout Name Draw Text Border Line Breaking Layout Name Number of Markers Name Name Name Title Name Title Enabled Name Title
main Typo-matic Disable txtEntryOne Enabled Bordered Word Wrap Wraps txtEntryTwo Enabled Bordered Word Wrap Wraps txtEntryThree Enabled Bordered Word Wrap Wraps txtEntryFour Enabled Bordered Word Wrap Wraps txtEntryFive Enabled Bordered Word Wrap Wraps DifficultySlider 2 Easy Hard InstructionButton Instructions GradeButton Grade Test Disable StartButton Take Test
Text Fields
Text Fields
Text Fields
Text Fields
Text Fields
Slider Static Text Static Text Button Button
Button
AND
99
100
AppleScript Studio Programming for the Absolute Beginner
individually; otherwise, they won’t trigger the event handler. The procedure for doing so is outlined next. 1. Select a button control and, if necessary, click on the Show Inspector menu item located under the Tools menu to display the Inspector window. 2. Select the AppleScript option from the popup control located at the top of the Inspector window. 3. Click on the disclosure triangle just to the left of the Action event handler in order to expose the clicked event handler. Select this event handler by clicking on its associated checkbox control. 4. Select the radio button control associated with the Typo-matic.applescript script listed in the Script section at the bottom of the Inspector window. 5. Click on the Edit button. Xcode reappears, displaying its code editor. Repeat this procedure for the application’s other two button controls.
Step 4: Adding a Little Programming Logic Now it is time to add the AppleScript code that drives the Typo-matic Typing Test game. To help you understand the overall gist of what is going on, I have added numerous comments throughout the script. -- Typo-matic.applescript -- Typo-matic --
Created by Jerry Ford on 7/8/06.
--
Copyright 2006 __Jerry Lee Ford, Jr._. All rights reserved.
on clicked theObject --Event handler called whenever a button is clicked tell window of theObject --This code runs when the 'Take Test' button is clicked if name of theObject is "StartButton" then --Enable the slider and button controls set enabled of button "StartButton" to false set enabled of button "GradeButton" to true set enabled of slider "DifficultySlider" to false --Set up the slider control to return numeric data
Chapter 3 • Building a Graphical User Interface
set GameLevel to contents of slider ¬ "DifficultySlider" as integer --Clear out the display of test sentences set contents of text field "txtChallengeOne" to "" set contents of text field "txtChallengeTwo" to "" set contents of text field "txtChallengeThree" to "" set contents of text field "txtChallengeFour" to "" set contents of text field "txtChallengeFive" to "" --Clear out the display of test answers set contents of text field "txtEntryOne" to "" set contents of text field "txtEntryTwo" to "" set contents of text field "txtEntryThree" to "" set contents of text field "txtEntryFour" to "" set contents of text field "txtEntryFive" to "" --Reset the default text color to black for all Text Fields set text color of text field "txtEntryOne" to {0, 0, 0} set text color of text field "txtEntryTwo" to {0, 0, 0} set text color of text field "txtEntryThree" to {0, 0, 0} set text color of text field "txtEntryFour" to {0, 0, 0} set text color of text field "txtEntryFive" to {0, 0, 0} --Execute these statements when the player selects 'Easy' if GameLevel = 0 then --Assign the game's five sentences set contents of text field "txtChallengeOne" to ¬ "See spot run." set contents of text field "txtChallengeTwo" to ¬ "See spot jump high." set contents of text field "txtChallengeThree" to ¬ "See spot leap over the fence." set contents of text field "txtChallengeFour" to ¬ "See spot catch the frisbee in the air." set contents of text field "txtChallengeFive" to ¬ "See spot rest after a hard day of play in the park." else --Execute these statements when the player picks 'Hard'
101
102
AppleScript Studio Programming for the Absolute Beginner
--Assign the game's five sentences set contents of text field "txtChallengeOne" to ¬ "In the end there can be only one." set contents of text field "txtChallengeTwo" to ¬ "This above all else, to thine own self be true." set contents of text field "txtChallengeThree" to ¬ "If only one is to survive, then let that one be " & ¬ "Mighty Molly Ford." set contents of text field "txtChallengeFour" to ¬ "Not everything that can be measured counts and " & ¬ "not everything that counts can be measured." set contents of text field "txtChallengeFive" to ¬ "Alexander the Great looked out across his kingdom " & ¬ "& wept. For there were no more lands left to conquer." end if --Enable each text field control to allow player input set enabled of text field "txtEntryOne" to true set enabled of text field "txtEntryTwo" to true set enabled of text field "txtEntryThree" to true set enabled of text field "txtEntryFour" to true set enabled of text field "txtEntryFive" to true --This code runs when the 'Grade Test' button is clicked else if name of theObject is "GradeButton" then set noIncorrect to 0 --Declare variable used to track typos considering case --Tell AppleScript not to ignore case (*Perform tests to determine if the sentences typed by the player are identical to the test sentences.*) if contents of text field ¬ "txtChallengeOne" is not equal to contents ¬ of text field "txtEntryOne" then set text color of text field "txtEntryOne" to ¬ {65535, 0, 0} --Set text color to red set noIncorrect to noIncorrect + 1 --Track typos end if
Chapter 3 • Building a Graphical User Interface
if contents of text field ¬ "txtChallengeTwo" is not equal to contents ¬ of text field "txtEntryTwo" then set text color of text field "txtEntryTwo" to ¬ {65535, 0, 0} --Set text color to red set noIncorrect to noIncorrect + 1 --Track typos end if if contents of text field ¬ "txtChallengeThree" is not equal to contents ¬ of text field "txtEntryThree" then set text color of text field "txtEntryThree" to ¬ {65535, 0, 0} --Set text color to red set noIncorrect to noIncorrect + 1 --Track typos end if if contents of text field ¬ "txtChallengeFour" is not equal to contents ¬ of text field "txtEntryFour" then set text color of text field "txtEntryFour" to ¬ {65535, 0, 0} --Set text color to red set noIncorrect to noIncorrect + 1 --Track typos end if if contents of text field ¬ "txtChallengeFive" is not equal to contents ¬ of text field "txtEntryFive" then set text color of text field "txtEntryFive" to ¬ {65535, 0, 0} --Set text color to red set noIncorrect to noIncorrect + 1 --Track typos end if end considering --Display popup window showing test results display dialog "Number answered correctly = " & ¬ 5 - noIncorrect & ¬ "Number answered incorrectly = " & ¬ noIncorrect buttons {"OK"} --Enable slider and button controls set enabled of button "StartButton" to true
103
104
AppleScript Studio Programming for the Absolute Beginner
set enabled of button "GradeButton" to false set enabled of slider "DifficultySlider" to true --Disable Text Field control to prevent player input set enabled of text field "txtEntryOne" to false set enabled of text field "txtEntryTwo" to false set enabled of text field "txtEntryThree" to false set enabled of text field "txtEntryFour" to false set enabled of text field "txtEntryFive" to false --This code runs when the 'Instructions' button is clicked else if name of theObject is "InstructionButton" then --Display game instructions in a popup window display dialog "Use the slider control to set difficulty" & ¬ " level. Click on the Start button to play. " & ¬ "Retype each sentence exactly as shown " & ¬ "and then click on the Grade Test button." & ¬ " Errors will display in red." buttons {"OK"} end if end tell end clicked
Step 5: Testing the Execution of the Typo-matic Typing Test Game Application Okay, that’s everything. Assuming that you have not made any errors when keying in the previous script statements, everything should work as advertised. You are ready to build and test your application. If any errors occur, chances are they are in the AppleScript code. Recheck your typing and then compile and run your application again. TIP
You have invested a great deal of time and effort to get to this point in the book and to gain a solid understanding of how to work with Xcode and Interface Builder. These are both powerful and complex applications worthy of their own books. The time that you have invested will serve you well as you move into the next part of the book, learning the ins and outs of writing AppleScript code. As such, I am going to start emphasizing coding syntax, keywords, and commands and place less attention to the inner workings. Therefore, you may want
Chapter 3 • Building a Graphical User Interface
105
to bookmark this section and make a note to come back and re-examine this code that makes up the Typo-matic application once you have completed Chapters 4–7.
SUMMARY In this chapter, you learned how to work with Interface Builder in order to develop graphical user interfaces for your AppleScript Studio applications. This included learning how to add and align Cocoa controls on application windows as well as how to create and modify application menus. You received a review of the major Cocoa interface controls. You also learned about the different application windows that are available, including their strengths and weaknesses. On top of all this, you learned how to create the Typo-matic Typing Test game. Before moving on to the next chapter, why don’t you take a few extra minutes and review the following list of challenges to see if you can improve on the Typo-matic Typing Test game.
CHALLENGES 1.
2.
3.
At present, the graphical user interface for the Typo-matic Typing Test game does not provide a lot of initial information. Consider adding text at the top of the application window that instructs the player to click on the Take Test button to begin game play. In addition, you might want to add descriptive text above the slider control that briefly states its purpose. Currently, the application’s About window provides copyright information and the name of its creator. Modify the InfoPlist.strings file in order to display additional information in the About window. For example, you might want to include information about your website. The popup dialog that displays the player’s final score currently displays the number of sentences typed correctly. Considering adding additional text that further describes the information the player is seeing.
This page intentionally left blank
Part
II
Learning How to Write AppleScripts
Chapter 4
Working with Values, Variables, and Classes
Chapter 5
Applying Conditional Logic and Building Loops
Chapter 6
Working with Strings, Lists, and Records
Chapter 7
Organizing Scripts with Handlers
This page intentionally left blank
4
C H A P T E R
WORKING WITH VALUES, VARIABLES, AND CLASSES p to this point in the book, the focus has been on learning how to work with three primary AppleScript Studio components, Xcode, Interface Builder, and Cocoa Interface controls. Now it is time to switch your focus over to the development of the scripting code that is used to actually make your AppleScript Studio applications do what you want them to do. This is the first of four chapters dedicated to this task. This chapter introduces you to the fundamentals of AppleScript programming, with a focus on learning how to store, retrieve, and manipulate data.
U
Specifically, you will learn how to • Construct AppleScript code statements • Create and assign values to variables • Work with different types of classes
PROJECT PREVIEW: THE STAR TREK TRIVIA GAME This chapter’s game project involves the creation of a computer-based exam. The exam consists of five questions. To pass, the player must correctly answer at least three questions. The game’s GUI consists of two windows, a main window, and a drawer window that slides out from underneath the main window when opened.
110
AppleScript Studio Programming for the Absolute Beginner
The main window, shown in Figure 4.1, consists of text, button controls, a box control, a progress indicator control, and an image view control.
FIGURE 4.1 A graphic image representing a familiar Star Trek uniform insignia helps to emphasize the game’s main theme.
In addition to providing access to game instructions and to initiating game play, the main window uses a progress indicator control to indicate the player’s progress through the exam. To view game instructions, which are displayed on the interface’s drawer window, the player must click on the View Instructions button. In response, the drawer window is displayed, as demonstrated in Figure 4.2.
FIGURE 4.2 A drawer window displays instructions.
After displaying the drawer window, the button control labeled View Instructions is changed to display a label of Hide Instructions. Clicking on this button closes the window and restores the button control’s original View Instructions label. The exam itself consists of five multiplechoice questions made up of two or three possible answers, as demonstrated in Figure 4.3.
Chapter 4 • Working with Values, Variables, and Classes
111
FIGURE 4.3 The player selects an answer by clicking on the appropriate button.
Once every question has been answered, the player’s answers are graded, and the results of the exam are displayed, as demonstrated in Figure 4.4.
FIGURE 4.4 After grading the player’s answers, the game determines whether the player has passed the exam.
After viewing his exam results, the player is returned to the game’s main window. As Figure 4.5 shows, the progress indicator shows that the player has completed the entire exam. At this point the player can close the game or take the test again.
FIGURE 4.5 The game’s main window is displayed at the end of the game.
112
AppleScript Studio Programming for the Absolute Beginner
APPLESCRIPT—THE TECHNOLOGY Underneath the covers, AppleScripts communicate with and control other applications via Apple events. This underlying architecture, also known as interapplication communication, allows AppleScripts to send messages to other applications in order to automate specific application functions. Applications that accept Apple events are referred to as scriptable applications. A scriptable application is one that publishes its terminology in an internal dictionary outlining the Apple events that it understands and can react to. When an AppleScript runs within the context of an AppleScript Studio application, the applications that it interacts with and controls are viewed as objects. In addition, the windows and interface element controls that make up the application’s user interface are also viewed as objects. An object, in this context, is anything to which AppleScript can send an Apple event message. AppleScripts are always focused on a target. A target is the object to which messages are passed. One way to specify the target to which Apple event messages should be sent is to use the tell command. Using tell, for example, you can explicitly identify an external application as the target. Alternatively, you might use the tell command to target a window within your AppleScript Studio application. Another option for specifying a target is the of operator. Using of, you can specify the specific attribute that you wish to access for a given object. For example, you might want to access and change the title attribute of a particular button control on your application window. You’ll learn more about tell and of and see numerous examples of them in action later in this chapter.
APPLESCRIPT—THE SCRIPTING LANGUAGE In addition to providing the under-the-covers technology required to support interapplication communications, AppleScript is also a powerful little computer scripting language and, of course, is the programming language that drives AppleScript Studio applications.
Language Extensibility The idea behind AppleScript is that the core language should be kept small, with additional functionality and capabilities being provided by the applications that AppleScript communicates with and automates. Therefore, you will find that as a programming language, AppleScript has few built-in functions when compared to other programming languages like VBScript, JavaScript, Perl, and Python. For example, you will not find any built-in capability to work with regular expressions or perform complex trigonometry calculations in AppleScript. Nor will you find a large collection of string manipulation functions. You will not even find the ability to work natively with the Mac file system. Instead, by tapping into
Chapter 4 • Working with Values, Variables, and Classes
113
the appropriate external application, you can extend AppleScript capabilities as needed. For example, using capabilities provided by the TextEdit application, you could perform a host of string manipulation tasks; likewise, using Finder, you can create an AppleScript Studio application that can create, copy, move, and delete files and folders.
Language Features The AppleScript scripting language is made up of numerous commands. Commands are keywords that, when executed, perform a specific task. Commands are used in the formulation of statements. A statement is a line of program code. Examples of commands that you have already seen in action in this book include: • beep • display dialog • tell • set In order to use commands to properly formulate code statements, you must be familiar with AppleScript syntax and statement structure.
English-Like Syntax As has already been stated, AppleScript is an uncommonly English-like programming language. AppleScript commands closely resemble their English equivalents. For example, the tell command is used to instruct (or tell) AppleScript which application or resource Apple event messages should be sent to. The AppleScript language is also filled with common transitional words such as is, of, as, and the, which are used to formulate English-like expressions. For example, you might write an AppleScript statement that compares the value of two numbers as shown below. if x is greater than y
As you can see, this statement very closely mimics spoken English. A similar statement in most other programming languages would look like the example shown here (actually, this statement is perfectly valid for AppleScript as well). if x > y
In some ways, AppleScript’s English-like style is a little long winded. For example, most programming languages let you assign a value to a variable as shown here. x = 1
114
AppleScript Studio Programming for the Absolute Beginner
However, AppleScript does not support this highly conventional, albeit somewhat cryptic style. Instead, to assign a variable to a variable in an AppleScript, you must use a lengthier, descriptive statement as shown here. set x to 4
Line-Based Statements AppleScript also differs from many other programming languages in that it is line based, meaning that it does not require a termination character at the end of each line. In AppleScript, unless explicitly extended using a continuation character, each command ends at the end of the line it is written on. For example, in AppleScript, the following statement must be written on a single line. set visible of window "main" to false TRI
CK
The keyword the is provided by AppleScript strictly for the opportunity to make your AppleScript more English like. It is not required nor does it have any impact on any statements in which it is used. Its use is entirely optional and a matter of personal choice. Using the, you could, for example, modify the previous statement, making it a little more English-like, as shown below. set visible of the window "main" to false
In other programming languages, such as Perl, you can spread statements over multiple lines without generating an error. To spread a lengthy statement out over more than one line in AppleScript, you must use the continuation character (¬) as was described back in Chapter 1, “AppleScript Studio Basics.” TRI
CK
To add a continuation character to the end of an AppleScript statement, type Option+L. Note that after compiling your application, you may find that the location of the continuation character might move. There is nothing that you can do about this. When you see continuation characters used in the examples of this book, they show the placement of the continuation character prior to any adjustments that the compiler might make to the code statements.
When used, you cannot type anything else after the continuation character; otherwise, an error will occur. You will also get an error if the line that follows a continuation character is blank. Also, if you need to continue a string over more than one line, you must use the concatenation operator in addition to the continuation character as demonstrated here. display dialog "Once upon a time there were three little children " & ¬ "that this in a magical land."
Chapter 4 • Working with Values, Variables, and Classes
115
As you can see, the AppleScript concatenation operator is the & character. It allows you to logically combine two separate strings together to form a single string.
Code Blocks In addition to working with single line code statements or statements that are continued over two or more lines using the continuation character, AppleScript also supports the ability to define code blocks. A code block, sometimes referred to as a compound statement, is a group of statements executed as a unit. Code blocks are identified by an opening statement that identifies the type of block statement and a closing statement that begins with the end keyword. Event handlers, like the one shown here, are one type of code block. on clicked theObject (*Insert Code here*) end clicked
You can place as many script statement as necessary inside a code block. You have seen event handlers used on numerous occasions in the game applications created in this book. So far event handlers have been added to your AppleScript automatically through the Inspector window. However, as you will learn in Chapter 7, “Organizing Scripts with Handlers,” you can also create your own custom handlers and use them as a means to improve the overall organization and efficiency of your AppleScripts. Another example of a compound statement that you have seen used in various situations involves the use of the tell command. The tell command is used to identify the target on which commands are focused. The tell command can be used to create a single line statement using the syntax shown below. tell target to command target identifies the resource or external application to which a command should be directed,
and command is the command to be passed. For example, the following statement directs an open command to a drawer window named InstructionDrawer, thus causing the drawer to be displayed. tell drawer "InstructionDrawer" to open drawer
The tell command is commonly used to create code blocks that send multiple commands to the specified target. When used in this manner, the following syntax is applied.
116
AppleScript Studio Programming for the Absolute Beginner
tell target statements end tell
To see how to set up a tell code block, consider the following example. on clicked theObject tell window of theObject set title of theObject to "Hide" end tell end clicked TRI
CK
Note the use of the of operator in the preceding example to specify the attribute (Title) of the object (button) that is to be changed.
Here, an on clicked event handler, executed when the user clicks on a button control, executes a tell code block. The code block sends its embedded command (statement) to the window on which the button control resides. The command that is passed changes the Title attribute of the button control to Hide. TRI
CK
To save a few keystrokes, you could type the word end in place of end tell in the previous example. The next time you compile your AppleScript Studio application, the keyword tell will be added automatically to the end statement for you. Also, you should take note that when you compile your application, the contents of compound statements will be indented automatically, making your program code easier to read and understand.
MANAGING DATA USING VARIABLES Just about any AppleScript Studio application needs to manipulate data in some manner. One way of storing individual pieces of data within AppleScripts is to use variables. A variable is a pointer to a location in memory where data is stored. Using variables, you can, for example, collect and store user inputs and then examine and manipulate those inputs at different points within the AppleScript.
Storing Values in Variables One way that AppleScript lets you store values in variables is with the set command. The syntax of the set command is outlined here. set variablename to value
Chapter 4 • Working with Values, Variables, and Classes
117
variablename represents the name assigned to the variable, and value is a placeholder repre-
senting the data associated with the variable. For example, the following statement demonstrates how to define a variable named counter and assign it an initial value of zero. set counter to 0
If you later want to change the value that is assigned to the counter variable, you may do so using another set command as shown here. set x to 11 TRI
CK
AppleScript allows you to modify a variable’s values by modifying its current value as demonstrated here. set x = x + 1
In this example, the value of x is incremented by 1 and then reassigned to itself. The end result is that if x started out with a value of 10, it is incremented and changed to 11.
If you want, rather than declaring multiple variables one at a time, AppleScript will allow you to assign groups of variables using a list as a shortcut, as demonstrated here. set {x, y, z} to {10, 20, 30}
Here, the variable x is assigned a value of 10. The variable y is assigned a value of 20. Lastly, the variable z is assigned a value of 30. Note that this example uses two lists, one on each side of the to keyword, and that each list is enclosed within {} characters.
Retrieving Variable Values Variable values can be retrieved using the get command, which has the following syntax. get variablename
For example, the following statement demonstrates how to retrieve the value assigned to a y variable and assign it to an x variable. set x to get y
However, use of the get command is superfluous and can be omitted, as demonstrated next. As a result, you will almost never see anyone use it. set x to y
118
AppleScript Studio Programming for the Absolute Beginner
NAMING VARIABLES AppleScript has rules that govern the formulation of variable names. For starters, variables must begin with either a letter or an underscore character. The remaining characters that make up variable names can consist of any combination of the characters outlined in Table 4.1. Variable names cannot be assigned the same names as AppleScript keywords, like tell, open, close, etc. In addition, you cannot assign variables the same names as any terms that make up the dictionary of any automated applications. The following list provides examples of valid variable names. userName x COUNTER __temp__ x999
Consists of uppercase and lowercase characters Consists of a single lowercase character Consists of all uppercase characters Consists of lowercase characters and underscore characters Consists of a lowercase character and numbers
To help give you an idea of how not to name your variables, consider the following list of invalid variable names. 1stname dollar$ tell TRI
CK
Variable names cannot begin with a number. Variable names cannot contain special characters. Variables cannot be named after keywords. If you feel too restricted by AppleScript’s rules for naming variables, you do have another option. AppleScript lets you define special variable names by allowing you to define the variable name inside a pair of matching vertical bar characters (|) using the following syntax. set |variablename| to value
When using vertical bars, you can assign any character you want as part of the variable name, including special characters. You can even use AppleScript
TABLE 4.1
RULES
FOR
NAMING VARIABLES
Characters
Description
a-z, A-Z 0-9 _
Uppercase and lowercase letters Numeric digits The underscore character
Chapter 4 • Working with Values, Variables, and Classes
119
commands and language keywords. For example, by enclosing them in vertical bars, all of the following variable name assignments are legal. set |tell| to "Once upon a time…" set |$5| to "Five Bucks" set |my-birthday| to "November 1964"
When defined within matching vertical bars, AppleScript enforces case sensitivity; therefore, the following two variables names would not be viewed as being equal. |my-birthday| |My-Birthday|
Lastly, when you need to refer to a specially named variable elsewhere within your AppleScript, you must include the vertical bars as part of the variable’s name as demonstrated here. set |x| = 5 set y = 10 set z = 0 set z = y + |x|
-- Equals 15
Case Sensitivity AppleScript is a case-insensitive language. It does not differentiate between different uses of capitalization within the spelling of variable names. Therefore, to AppleScript, each of the following variable references is the same thing. • username • userName • UserName • USERNAME • UsErNaMe Another interesting point about the way that AppleScript handles variables is that if you use different case spelling for the same variable’s name, AppleScript will automatically go back through and find each instance of that variable name within your AppleScript and convert it to make each instance match the capitalization of the first instance that it finds. To see what I mean, start up a new AppleScript Studio application, add a button control to the default application window, and assign the following code statements to the button control’s on clicked event handler. Take note of the different capitalization of the variable username as you key in the statements.
120
AppleScript Studio Programming for the Absolute Beginner
on clicked theObject set username to "William Ford" set UserName to "Alexander Ford" set USERNAME to "Molly Ford" end clicked
When you are done, click on the Build button. In response, your code is compiled, and you will see that the spelling of each instance of username has been modified to match the case of the first instance, as shown here. on clicked theObject set username to "William Ford" set username to "Alexander Ford" set username to "Molly Ford" end clicked
Undefined Variables AppleScript variables are not assigned default values. In order to use a variable, it must contain a value; otherwise, an error will occur and you’ll get a The variable variablename is undefined error, as demonstrated in Figure 4.6.
FIGURE 4.6 An error is generated if AppleScript finds a variable without an assigned value.
AppleScript does not require that variables be declared prior to their usage. This makes AppleScript very different from many other programming languages. It also makes it very easy for you to make mistakes because if you accidentally mistype a variable name in your programming code, rather than flag it as an error, AppleScript simply declares it as a new variable, producing unpredictable results. TIP
As I have already stated, it is important that you document your AppleScript code. One way to do so is to imbed comments. Another way to help document your scripts is to assign descriptive names to your variables. This will help to make your code statements easier to understand. For example, you might name a variable that will used to store a user’s name userName. Likewise, you might name a variable set up to store a value representing input collected from the user as userInput.
Chapter 4 • Working with Values, Variables, and Classes
121
WORKING WITH DIFFERENT VARIABLE CLASSES In AppleScript, variables are not strongly associated with specific data types. In other words, AppleScript will let you assign any type of data to any variable, even if that variable already contains a different type of data. Any variable that has been assigned a value has a defined data type, also referred to as its class. AppleScript supports a number of different classes, as discussed in the sections that follow.
The String Class You have seen the String class used many times already in this book. A string is created by enclosing one or more characters inside a pair of quotation marks as demonstrated below. "In the end there can be only one."
Strings can be used to display text using the display dialog command. Strings can also be assigned to variables. You’ll learn more about how to work with strings in Chapter 6, “Working with Strings, Lists, and Records.”
The Real Class The Real class is a numeric data type that represents real numbers. A real number is one that includes a decimal point, such as 99.9 or –10.4. Real numbers are used to display numeric values and to perform mathematic calculations. Real numbers can also be represented using scientific notation. Real numbers are used to store numeric values in the range of –1.797693e308 to 1.797693e308. TRI
CK
AppleScript often converts real numbers written in scientific notation to their non-scientific equivalent when compiling the script file. For example, AppleScript will automatically convert 10.5e-4 to 0.00105. However, this behavior is not consistent and may not happen all the time.
The Integer Class The Integer class is a numeric data type that represents whole numbers (e.g., numbers without a decimal point). The Integer class supports a much smaller range of values than the Real class. Its supported range is –536870911 to 536870911. Integers are used in place of real numbers to more efficiently store numeric data within its range. If you are working with a variable of integer data type and assign it a value outside of its supported range, AppleScript will automatically covert it to a real number.
122
AppleScript Studio Programming for the Absolute Beginner
The Date Class The Date class is used to store and manipulate date and time data. AppleScript stores date and time in the following format. weekday, month day, year hh:mm:ss ampm
Table 4.2 outlines the range of values supported by each of these date parameters. You can use the current date command to retrieve the current date and time as demonstrated here. set d to current date
When executed, this command will retrieve a value similar to that shown here. Sunday, January 12, 2007 2:03:19 PM
Classes like the Date class have different properties from which you can programmatically retrieve data about a given value. For example, the Date class provides access to the properties shown in Table 4.3. Using the properties listed in Table 4.3, you can retrieve date values as demonstrated in the following example. set d to current date display dialog d as string
-- Displays Sunday, January 12, 2007 2:03:19 PM
display dialog weekday of d as string
-- Displays Sunday
display dialog time string of d as string
TABLE 4.2
-- Displays 2:03:19 PM
DATE PARAMETERS
Parameter
Range
weekday month
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday January, February, March, April, May, June, July, August, September, October, November, December 1–31 A four character year A two character number representing hours A two character number representing minutes A two character number representing seconds am or pm
day year hh mm ss ampm
Chapter 4 • Working with Values, Variables, and Classes
TABLE 4.3
DATE PROPERTIES
Property
Description
year month
A four character year A value of January, February, March, April, May, June, July, August, September, October, November, or December An integer in the range of 1–31 An integer representing the number of hours since midnight An integer in the range of 1–60 An integer in the range of 1–60 An integer representing the number of seconds since midnight A value of Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, or Sunday A string formatted as weekday, month, day, year A string formatted as hh:mm:ss AM/PM A string formatted as mm/dd/yyyy
day hours minutes seconds time weekday date string short date string time string
TRI
CK
123
By default, AppleScript will automatically convert a variable to the appropriate data type based on the data type of the value assigned to it. Data type specification controls how AppleScript treats a given value and the properties that are associated with it. Sometimes it is necessary for you to coerce a value’s data type in order to work with it. For example, the display dialog command is used to display a text string. If you pass it a number instead of a text string, AppleScript will automatically convert it to a string and display it. However, if you pass a date value to the display dialog command, you may not get the results you expect. To ensure that the value passed to the display dialog command is treated as a string, you can use the as operator to explicitly specify the appropriate class to be used. For example, in the three preceding display dialog statements, the as string was added to the end of each statement. Had the as string been left off the first display dialog statement, an error would have been generated. In Chapter 5’s game project, the AppleScript Studio Guess a Number game, you will learn how to use the slider control as a means of allowing the player to select a number from a range of numbers. The slider control returns a real number. However, the AppleScript Studio Guess a Number game requires that all numbers used in the game be integers. As a result, you will have to coerce the value returned by the game’s slider control from a real number to an integer.
When executed, this example displays three popup dialog windows, each showing a different value. You can also use Date class properties to modify date values as demonstrated here.
124
AppleScript Studio Programming for the Absolute Beginner
set d to current date set day of d to 1 set year d as to 2008 display dialog day of d as string display dialog year of d as string
-- Displays 1 -- Displays 2008
The Boolean Class The Boolean class is used to represent a value that is either true or false. Many operations in AppleScripts involved the comparison of values, the result of which is a true or false value. As you’ll learn in Chapter 5, “Applying Conditional Logic and Building Loops,” the if statement, which is used to facilitate conditional logic, results in a Boolean value that is then used to drive the logical flow of script logic. TRI
CK
AppleScript supplies the class command as a means of determining the class or data type assigned to a given value. The use of this command is demonstrated here. set d to current date set x to 100 set y to 999999999999999 set z to "Hello World!" set b to true display dialog class of d as string
-- Displays date
display dialog class of x as string
-- Displays integer
display dialog class of y as string
-- Displays real
display dialog class of z as string
-- Displays string
display dialog class of b as string
-- Displays boolean
BACK TO THE STAR TREK TRIVIA GAME Now it is time to start working on the Star Trek Trivia game. The primary point of focus for this game is on the use of variables to store and retrieve data collected from the user and generated by the application. In addition, you should take note of the construction of code statements that interact with and control the user interface.
Designing the Game During the development of the Star Trek Trivia game, you will learn how to work with a number of new controls. For starters, the game’s GUI will be made up of a window and drawer. You will also learn how to add graphics and sound effects to AppleScript Studio applications.
Chapter 4 • Working with Values, Variables, and Classes
125
Finally, you will learn how to work with and control the automation of the progress indicator control. As with all of the applications in this book, the Star Trek Trivia game will be created in five steps, as outlined here. 1. Start Xcode and create a new AppleScript Studio application named Star Trek Trivia. 2. Design the application’s GUI using Interface Builder. 3. Configure the game’s menu, window, and drawer and control attributes and then attach interface controls to event handlers. 4. Add the AppleScript code statements required to make the application work. 5. Compile and test the application.
Step 1: Creating a New Project If it is not already started, start Xcode and create a new AppleScript Studio project, as outlined in the following procedure. 1. Click on the File menu and select New Project. An Assistant is launched, displaying a list of application templates. 2. Select AppleScript Application template and click on Next. 3. When prompted, specify Star Trek Trivia as the file name for the application and then specify the folder where you would like to store this AppleScript Studio application. 4. Click on the Finish button.
Step 2: Creating the User Interface The next step in the development of the Star Trek Trivia game is to assemble its graphical user interface, as outlined in the following procedure. 1. Locate the MainMenu.nib file located in the Resources group and then double-click on it to start the Interface Builder. 2. Click on the icon representing the default application window in the MainMenu.nib window to select it and then delete it by pressing the Delete key. 3. Click on the Cocoa Windows button located in the Cocoa Controls palette and then drag and drop an instance of the window and drawer window onto the MainMenu.nib window. In response, three icons representing the drawer, parent windows, and drawer content are added to MainMenu.nib. 4. Use the application window’s resize handle to change the size of the window until it is approximately 7.5 inches wide and 4.25 inches tall. 5. Use the DrawContentView window’s resize handle to change the size of the window until it is approximately 4.25 inches wide and 4.25 inches tall.
126
AppleScript Studio Programming for the Absolute Beginner
6. The drawer window consists of two controls. The first is a system font text control whose Title attribute should be set to Instructions, and the second is a text field control. 7. Double-click on the text field control and enter the following text. Star Fleet Academy is now accepting applications for the upcoming freshman class. Before submitting your application, you must correctly answer at least three of the five questions that make up the text. At this point the drawer window should resemble the example shown in Figure 4.7.
FIGURE 4.7 The drawer window consists of two controls and is used to display game instructions.
8. Now it is time to lay out the interface for the main window. Begin by dragging and dropping an instance of the system font text control to the upper left-hand corner of the window. Double-click on it and enter Welcome to the Star Trek Trivia Game!. TRI
CK
Note that the text displayed in the system font text control needs to be increased in size and made bold. To apply a bold font, select the control and then click on the Format menu, select the Font submenu, and click on the Bold menu item. To increase the size of the text that is displayed in this control, select the Format menu, Font submenu, and Bigger menu item. You will need to perform this operation four times to increase the text font to the appropriate size. Note that you may also have to increase the space allocated to the system font text control in order to allow all of its assigned text to be displayed.
9. The main interface will display a graphic image representing a yellow Star Trek badge. You will find a copy of this graphic, named STBadge.jpg, located on the book’s companion website (www.courseptr.com/downloads). Drag and drop this file into the Resources group located inside the Groups & Files pane of the Xcode Project window. In response,
Chapter 4 • Working with Values, Variables, and Classes
10.
11.
12. 13.
14.
15.
16.
127
a sheet appears. Select the Copy Items into Destination Group’s Folder (if needed) option and click on the Add button. Next, drag and drop an instance of the image view control located on the Cocoa Containers View of the Interface Builder palette onto the upper right-hand corner of the main window and resize the control so that it is approximately 1.5 inches tall and 1.25 inches wide. Drag and drop the STBadge.jpg file from the Xcode Project window onto the image view control located on the MainMenu.nib window. A sheet will then appear on the MainMenu.nib window asking for confirmation. Click on the Add button. Now drag and drop an instance of the STBadge icon from the MainMenu.nib window onto the image view control located on the application’s main window. Drag and drop an instance of the button control onto the middle of the application’s main window. Double-click on the button control and enter Begin E xam to set its Title attribute. Drag and drop another instance of the button control onto the lower left-hand corner of the application’s main window. Double-click on the button control and enter V iew Instructions to set its Title attribute. Drag and drop an instance of the horizontal box control onto the lower portion of the application’s main window. Position the control just above the View Instructions button and resize the horizontal box control so that it runs almost the entire width of the window. Finally, drag and drop an instance of the progress indicator control onto the lower righthand side of the application’s main window. Increase the width of the control until it is approximately four inches wide.
At this point, the game’s main window should be fully assembled, as demonstrated in Figure 4.8.
FIGURE 4.8 The game window contains a number of different types of controls.
128
AppleScript Studio Programming for the Absolute Beginner
Step 3: Customizing Control Properties The overall construction of the game’s user interface is now complete. It is now time to configure the application’s menu system, modify its window and drawer, and then set various control attributes and associate the game’s two button controls with the on clicked event handler, as outlined in the next several sections.
Menu Customization The first step in customizing the menu system for the Star Trek Trivia game is to remove unnecessary menus and menu items that were provided by default to the application. For starters, you should delete the Help menu by clicking on it and pressing the Delete key. Next, delete all of the menu items under the Window menu except for Minimize. Select the Edit menu and press Delete to remove it and its contents. Click on the File menu and remove everything but the Page Setup and Print menu items. Lastly, you need to customize the Application menu as outlined here. 1. 2. 3. 4.
Double-click on the Application menu and replace its name with S TTrivia. Modify the About Application menu item to read About STTrivia. Modify the Hide Application menu item to read Hide STTrivia. Modify the Quit Application menu item to read Q uit STTrivia.
Setting Control Attributes As with any AppleScript Studio application, a number of modifications must be made to the window, drawer, and controls that make up the user interface. These changes are outlined in Table 4.4 and must be made from the Inspector window’s AppleScript and Attribute views. Note that to assign a name to the drawer window, you must click on the NSDrawer1 icon located in the MainMenu.nib window and then use the Inspector window to assign its name. TRI
CK
The Sounds view of the MainMenu.nib window contains a number of sound files that you can use to add audio sounds to your AppleScript Studio applications. In Table 4.4, the Submarine sound was associated with the button that controls the display of the drawer window by simply typing its name into the appropriate button control’s Sound attribute field.
Setting Up Event Handler Connections Now it is time to set up both of the game’s two button controls so that they will trigger the on clicked event handler whenever they are clicked. Both of the button controls must be configured to respond to the clicked event; otherwise, they will not be able to trigger their associated code located in the AppleScript’s event handler.
Chapter 4 • Working with Values, Variables, and Classes
TABLE 4.4
MODIFICATIONS OF THE APPLICATION WINDOW, DRAWER, AND CONTROLS
Object
Attribute
Modification
Window
Name Window Title Zoom Visible at launch time Name Name Sound Name Border Name Indeterminate Name Layout Line Breaking Editable
main Star Trek Trivia Disable Enabled btnBegin btnInstructions Submarine STBadge None pgbLevel Cleared InstructionDrawer Wraps Word Wrap Cleared
Button Button Image view Progress Indicator Drawer Text Field
TIP
129
You have performed this exercise a number of times already in this book, so I won’t provide a step-by-step procedure for doing so this time. If necessary, you can refer to the previous chapter’s game script for detailed instructions.
Step 4: Adding a Little Programming Logic It is time to develop the AppleScript statements that drive the Star Trek Trivia game. In order to develop the required program code, you will have to learn how to work with a number of new scripting statements. To help define and explain these statements, I will pause along the way and provide you with additional explanation. I will also embed comments throughout the program code to further help explain what is happening. Two button controls in the Star Trek Trivia game are used to control overall game play. The first button is the Begin Exam button, which when clicked will begin presenting the player with the questions that make up the exam. The second button is the View Instructions button, which when clicked displays a drawer window that provides the player with additional instruction.
130
AppleScript Studio Programming for the Absolute Beginner
The first thing you need to do for both of these button controls is to open the Inspector window and enable the clicked event. Once you have completed this task, the following code statements should be visible in your project’s Star Trek Trivia.applescript file. TR
AP
You must configure the clicked event for each button control; otherwise, any button control that you do not configure will not be able to initiate any actions, even if you add the required scripting statements inside the application’s AppleScript file.
-- Star Trek Trivia.applescript -- Star Trek Trivia --
Created by Jerry Ford on 7/16/06.
--
Copyright 2006 __MyCompanyName__. All rights reserved.
on clicked theObject (*Add your script here.*) end clicked
The first four lines are comments. If you want to change the copyright comment, do so by modifying the InfoPlist.strings file (English) located under Resources in the Groups & Files pane. The last three lines are the AppleScript’s on clicked event handler, which is automatically added to the AppleScript when you configure the two button controls’ clicked events. TRI
CK
As you will learn in later chapters, you can add more than one AppleScript to an AppleScript Studio application. One of the reasons for doing so is to set up one script for each unique control added to your application. This allows you to group all of the code statements associated with a given control in a script dedicated to that control. This is helpful in applications with numerous controls and lots of code. However, in a small application like the Star Trek Trivia game, it is easier just to go with a single AppleScript and to add a little extra code to it to help determine which control has initiated the execution of the AppleScript. This is accomplished by examining the value of theObject, which you will notice is defined at the end of the on clicked statement. By checking the value assigned to theObject, you can determine which interface control called the AppleScript (e.g., the Begin Exam or View Instructions button).
From this point on, all the program code that you will add to the AppleScript will go inside the on clicked event handler. So, let’s begin by adding the following two statements (inside the on clicked event handler).
Chapter 4 • Working with Values, Variables, and Classes
131
tell window of theObject end tell
These two statements define a compound statement or code block. The opening statement uses the tell command to instruct AppleScript to direct all embedded commands at the window that contains the interface control that initiated the execution of the AppleScript. In other words, if the player were to click on the Begin Exam button, this statement would direct all commands to the window named main since it contains the Begin Exam button. The end tell statement simply marks the end of the compound statement. The rest of the code statements that will make up this AppleScript are all directed at the main window; therefore, all of the remaining code statements will be embedded inside the tell compound statement. The first set of statements to be added follows. -- Declare and assign default values to script variables set noCorrect to 0 -- Keep track of correct answers set noIncorrect to 0 -- Keep track of incorrect answers set rawPercentage to 0 -- Used to calculate grade set grade to 0 -- Used to store test grade -- Define variables representing answers to test questions set answer1 to "" set answer2 to "" set answer3 to "" set answer4 to "" set answer5 to ""
As you can see, these statements consist of a series of set statements that define each variable used in the AppleScript, assigning each variable a default value. Comments have been added to document the purpose of each variable. The next set of code statements addresses the actions that need to occur when the View Instructions button is clicked. Add these statements by keying them in immediately after the last variable declaration statement. TIP
The game makes additional instructions available to the player by displaying them on a drawer window attached to the game’s main window. The display of the drawer window is controlled by clicking on the button control named btnScore. Initially this button control’s Title attribute is assigned a value of View Instructions. When clicked, it will initiate the display of the drawer window and
132
AppleScript Studio Programming for the Absolute Beginner
then change its Title attribute to Hide Instructions, thus toggling the label displayed on the button control. -- Execute code that controls the display of the drawer window if title of theObject is "View Instructions" then tell drawer "InstructionDrawer" to open drawer -- Open drawer set title of theObject to "Hide Instructions" -- Change title text else if title of theObject is "Hide Instructions" then tell drawer "InstructionDrawer" to close drawer –- Close drawer set title of theObject to "View Instructions" -- Change title text end if
These statements are controlled by an if…else if code block. The if…else if code block is explained in great detail in Chapter 5. For now, here’s a simple explanation of how this code block works: The opening if statement examines the title attribute of the interface control that has initiated an action as specified by theObject (e.g., the action of clicking on a button control) to see if it’s the button control labeled View Instructions. If it is, the two statements that immediately follow are executed. If this is not the case, then the else if statement executes and checks to see if the button that was clicked has a title of Hide Instructions. And if it does, the two statements that immediately follow are executed. The statements that you should be focusing on for right now are the two pairs of statements embedded inside the if…else if code block. The first of these two sets of statements uses the tell command to direct the instructions provided by the rest of the statement to the drawer window named InstructionDrawer, telling it to open. The next statement sets the label (e.g., the Title attribute) displayed by the button control to Hide Instructions, thus letting the player know that by clicking on the button again the drawer window will close. The second set of statements embedded inside the if…else if code block is responsible for closing the drawer window and restoring the original View Instructions label on the button control. At this point, all that remains is to supply the code statements associated with the button control labeled Begin Exam. When clicked, this code will display each of the five exam questions and then analyze the player’s answers to these questions before displaying the player’s exam score. These first step in entering these code statements is to set up an if statement that determines when the Begin Exam button has been clicked. These statements, shown
Chapter 4 • Working with Values, Variables, and Classes
133
next, should be added immediately following the last set of code statements and before the end tell statement that you keyed in earlier. -- Execute code that collects player answers to test questions if title of theObject is "Begin Exam" then end if
Again, the opening if statement checks the Title attribute of the button control that was clicked to make sure that it is Begin Exam. If it is, the code statements that you are about to place inside this if statement code block will be executed. Otherwise, the if statement code block and all of the code statements inside it are skipped. The first statements that you should add inside the if statement code block follow. tell drawer "InstructionDrawer" to close drawer -- Close drawer --Reset the progress indicator back to zero set content of progress indicator "pgbLevel" to 0
Because the drawer window may or may not be open when the player decides to click on the Begin Exam button, the first statement uses the tell command to close the drawer window. If the drawer window is open, it will close. If it is closed, the command is ignored. Since it is possible that the player may want to take the exam more than once, it is necessary to reset the value of the game’s progress indicator control back to its default value of zero in order to get it ready to begin tracking the exam’s progress. At this point we know that the drawer window is closed and that the progress indicator control has reset to its default value. It is time to begin displaying test questions and to update the progress indicator control so that it reflects the current percentage of the exam that has been completed. This is accomplished by adding the following code statements. --Ask 1st test question set answer1 to the button returned of (display dialog ¬ "Question 1:
The laws that govern the actions of Star " & ¬
"Fleet personnel are referred to as Prime Directives." ¬ buttons {"True", "False"}) -- Increment the progress indicator to show that the first of five -- answers has been collected tell progress indicator "pgbLevel" to increment by 20
134
AppleScript Studio Programming for the Absolute Beginner
The first code statement shown above sets the value of a variable named answer1. It does so by displaying a popup dialog window with buttons labeled True and False. This popup dialog window is displayed using the display dialog command. You will often see the display dialog statement used in applications to display messages. However, in this case it has been embedded in a set statement. This allows the set statement to determine which button the player clicks. This is accomplished by setting the value of the answer1 variable to the value of the button that is returned by (or returned of) the display dialog statement, which in this case will either be True or False.
In the Real World One of the most commonly performed tasks in any window-based application is to display messages and capture text input from the user. While you can certainly create a new custom window each time you want to display a text message or collect a small piece of data from the user, most AppleScript and AppleScript Studio programmers instead take advantage of the display dialog command. While AppleScript has its own display dialog command, when used inside an AppleScript Studio application, the AppleScript Studio version of the display dialog command is used. This display dialog command displays a simple popup window that allows you to display a text message and collect user input. Depending on how you specify the display dialog command, this input can be either the name of a button control clicked by the user or text keyed in by the user. In its simplest format, the display dialog command displays a message and two button controls, OK and Cancel, using the following syntax. display dialog “Message text” This use of the display dialog command is very helpful when you only need to display text that needs to be read by the user. The display dialog command is very flexible and supports a number of optional parameters, as outlined here. • attached to window windowname. When specified, turns the popup dialog that is displayed into a sheet attached to the specified window. • button list. Specifies a list of up to three buttons in the format of {button1, button2, button3}.
Chapter 4 • Working with Values, Variables, and Classes
135
• default answer text. When specified causes the popup window to display with a text field showing the specified default answer, which the user can either accept or overtype. • default button buttonname. When specified, sets the button that is selected by default in the event the user responds by pressing the Return key instead of clicking on a specific button. • giving up after integer. Forces the popup window to close if the user does not respond to it within a specified number of seconds. • with icon iconname. Allows you to specify the name and path of an icon that you would like displayed inside the popup dialog window. Using optional parameters, you can customize the appearance and functionality of popup dialog windows. For example, the following statement displays a popup dialog window that displays a short message, prompting the user to click on either of two buttons. display dialog "It is raining today." buttons {"True", "False"}) The problem with this example is that is does not provide a means of capturing the user’s button selection. This can be accomplished by modifying the example as shown next. set answer1 to the button returned of ("It is raining today." ¬ buttons {"True", "False"})
Once the value of answer1 has been assigned, the last statement shown above updates the display of the progress indicator control by using the tell command to instruct the progress indicator control named pgbLevel to increment its value by 20. Given that the progress indicator control has a default range of 0.0 to 100.0, incrementing it by 20 has the effect of making the control update its display so that it shows as being 1/5th full. Now, you need to key in the code required to display the remaining four exam questions, which is shown here. --Ask 2nd test question set answer2 to the button returned of (display dialog ¬ "Question 2: When initially beaming down to an unknown " & ¬ "planet, the correct setting for phaser weapons is: " ¬ buttons {"Stun", "Kill"}) -- Increment progress indicator to show that two of five -- answers have been collected tell progress indicator "pgbLevel" to increment by 20
136
AppleScript Studio Programming for the Absolute Beginner
--Ask 3rd test question set answer3 to the button returned of (display dialog ¬ "Question 3: What is the appropriate speed of travel when" & ¬ " a star ship is leaving space dock? " ¬ buttons {"Warp 10", "Light", "Impulse"}) -- Increment progress indicator to show that three of five -- answers have been collected tell progress indicator "pgbLevel" to increment by 20 --Ask 4th test question set answer4 to the button returned of (display dialog ¬ "Question 4: The neutral zone is a term that refers to " & ¬ "an area of space where any space traveler is free to go." ¬ buttons {"True", "False"}) -- Increment progress indicator to show that four of five -- answers have been collected tell progress indicator "pgbLevel" to increment by 20 --Ask 5th test question set answer5 to the button returned of (display dialog ¬ "Question 5: According to existing Federation treaties, " & ¬ "are star ships permitted to use cloaking technology?" ¬ buttons {"Yes", "No"}) -- Increment progress indicator to show that five of five -- answers have been collected tell progress indicator "pgbLevel" to increment by 20
As you can see, each of these four sets of code statements is simply a small variation of the first set of statement, the primary differences being that the questions and the list of buttons are different. Now it is time to add the program code that analyzes the player’s answers and determines which exam questions were answered correctly and which were answered incorrectly. Begin by adding the following set of statements to your AppleScript. --Analyze test results if answer1 = "True" then -- If the player selected "True" set noCorrect to noCorrect + 1 -- Answer is correct else -- Otherwise the answer is incorrect
Chapter 4 • Working with Values, Variables, and Classes
137
set noIncorrect to noIncorrect + 1 -- Answer is correct end if
This set of statements uses an if…else code block to examine the player’s answer to the first question, which you will remember was stored in a variable named answer1. The first statement checks to see if the value assigned to answer1 (e.g., the button clicked by the player) was equal to True. Since the answer to the first question was true, the value assigned to a variable name noCorrect is incremented by one. This variable was declared at the beginning of the script and was assigned an initial value of zero. By incrementing it each time the player correctly answers an exam question, you are able to keep track of the total number of correctly answered questions. In the event that the player clicks on the False button, the else portion of the if…else code block is executed and the value of noIncorrect is incremented by one. The code required to grade the next four exam questions is listed next. if answer2 = "Stun" then -- If the player selected "Stun" set noCorrect to noCorrect + 1 -- Answer is correct else -- Otherwise the answer is incorrect set noIncorrect to noIncorrect + 1 -- Answer is correct end if if answer3 = "Impulse" then -- If the player selected Impulse" set noCorrect to noCorrect + 1 -- Answer is correct else -- Otherwise the answer is incorrect set noIncorrect to noIncorrect + 1 -- Answer is correct end if if answer4 = "False" then -- If the player selected "False" set noCorrect to noCorrect + 1 -- Answer is correct else -- Otherwise the answer is incorrect set noIncorrect to noIncorrect + 1 -- Answer is correct end if if answer5 = "No" then -- If the player selected "No" set noCorrect to noCorrect + 1 -- Answer is correct else -- Otherwise the answer is incorrect set noIncorrect to noIncorrect + 1 -- Answer is correct end if
138
AppleScript Studio Programming for the Absolute Beginner
As you can see, these four sets of statements are simply variables of the first set of statements that analyzed the first exam question. Once the answer to every question has been analyzed, it is time to determine whether the player passed the exam. This is accomplished by adding the following statements immediately after the preceding statements. -- Determine whether the player passed the exam if noCorrect • 3 then -- Three or more correct answers passes set grade to "Passed" else --Less than three correct answers fails set grade to "Failed" end if
Another if…else statement code block is used in order to determine whether the player passed the exam. If the value of noCorrect is greater than or equal to three, the player passes, in which case a variable named grade is assigned a value of Passed. Otherwise a value of Failed is assigned to the grade variable. The last thing that needs to be accomplished is adding the programming logic that displays the number of correctly and incorrectly answered questions and the player’s overall exam score. This is accomplished by the following display dialog statement. -- Displays the test results display dialog "Number correct: " & noCorrect & ¬ "Number incorrect: " & noIncorrect & ¬ "Test Results: " & grade buttons {"OK"}
Step 5: Testing the Execution of the Star Trek Trivia Game All right, at this point your new AppleScript Studio game should be complete. Before trying to run it by clicking on the Xcode Build and Go button, click on the Build button instead to see if any errors are generated. Given the amount of code that you had to key in, odds are you may have made a typo or two. When you click on the Build button, Xcode attempts to compile your application without running it. If there are any syntactical errors, they will be identified under the Error and Warnings entry in the Groups & Files section of the Xcode Project window. Using this information, you should be able to get a pretty good idea of the line number where the error resides and fix any typing errors that you may have made. Once you have identified and removed any syntax errors, click on the Build and Go button to run and test out the execution of your new game.
Chapter 4 • Working with Values, Variables, and Classes
139
Application Code Review We stepped through the development of the Star Trek Trivia game’s AppleScript file in a stepby-step fashion. It is important that we make sure that the script you have now assembled contains all of the required script statements and that they are entered in the proper order. So, just to make sure we keep everything straight, I have laid out a copy of the fully assembled AppleScript file here. -- Star Trek Trivia.applescript -- Star Trek Trivia --
Created by Jerry Ford on 7/16/06.
--
Copyright 2006. All rights reserved.
on clicked theObject tell window of theObject -- Declare and assign default values to script variables set noCorrect to 0 -- Keep track of correct answers set noIncorrect to 0 -- Keep track of incorrect answers set rawPercentage to 0 -- Used to calculate grade set grade to 0 -- Used to store test grade -- Define variables representing answers to test questions set answer1 to "" set answer2 to "" set answer3 to "" set answer4 to "" set answer5 to "" -- Execute code that controls the display of the drawer window if title of theObject is "View Instructions" then tell drawer "InstructionDrawer" to open drawer -- Open drawer set title of theObject to "Hide Instructions" -- Change title text else if title of theObject is "Hide Instructions" then
140
AppleScript Studio Programming for the Absolute Beginner
tell drawer "InstructionDrawer" to close drawer –- Close drawer set title of theObject to "View Instructions" -- Change title text end if -- Execute code that collects player’s answers to test questions if title of theObject is "Begin Exam" then tell drawer "InstructionDrawer" to close drawer -- Close drawer --Reset the progress indicator back to zero set content of progress indicator "pgbLevel" to 0 --Ask 1st test question set answer1 to the button returned of (display dialog ¬ "Question 1:
The laws that govern the actions of Star " & ¬
"Fleet personnel are referred to as Prime Directives." ¬ buttons {"True", "False"}) -- Increment progress bar to show that the first of five -- answers has been collected tell progress indicator "pgbLevel" to increment by 20 --Ask 2nd test question set answer2 to the button returned of (display dialog ¬ "Question 2: When initially beaming down to an unknown " & ¬ "planet, the correct setting for phaser weapons is: " ¬ buttons {"Stun", "Kill"}) -- Increment progress bar to show that two of five -- answers have been collected tell progress indicator "pgbLevel" to increment by 20 --Ask 3rd test question set answer3 to the button returned of (display dialog ¬ "Question 3: What is the appropriate speed of travel when" & ¬ " a star ship is leaving space dock? " ¬ buttons {"Warp 10", "Light", "Impulse"}) -- Increment progress bar to show that three of five -- answers have been collected tell progress indicator "pgbLevel" to increment by 20
Chapter 4 • Working with Values, Variables, and Classes
--Ask 4th test question set answer4 to the button returned of (display dialog ¬ "Question 4: The neutral zone is a term that refers to " & ¬ "an area of space where any space traveler is free to go." ¬ buttons {"True", "False"}) -- Increment progress bar to show that four of five -- answers have been collected tell progress indicator "pgbLevel" to increment by 20 --Ask 5th test question set answer5 to the button returned of (display dialog ¬ "Question 5: According to existing Federation treaties, " & ¬ "are star ships permitted to use cloaking technology?" ¬ buttons {"Yes", "No"}) -- Increment progress bar to show that five of five -- answers have been collected tell progress indicator "pgbLevel" to increment by 20 --Analyze test results if answer1 = "True" then -- If the player selected "True" set noCorrect to noCorrect + 1 -- Answer is correct else -- Otherwise the answer is incorrect set noIncorrect to noIncorrect + 1 -- Answer is correct end if if answer2 = "Stun" then -- If the player selected "Stun" set noCorrect to noCorrect + 1 -- Answer is correct else -- Otherwise the answer is incorrect set noIncorrect to noIncorrect + 1 -- Answer is correct end if if answer3 = "Impulse" then -- If the player selected Impulse" set noCorrect to noCorrect + 1 -- Answer is correct else -- Otherwise the answer is incorrect set noIncorrect to noIncorrect + 1 -- Answer is correct end if
141
142
AppleScript Studio Programming for the Absolute Beginner
if answer4 = "False" then -- If the player selected "False" set noCorrect to noCorrect + 1 -- Answer is correct else -- Otherwise the answer is incorrect set noIncorrect to noIncorrect + 1 -- Answer is correct end if if answer5 = "No" then -- If the player selected "No" set noCorrect to noCorrect + 1 -- Answer is correct else -- Otherwise the answer is incorrect set noIncorrect to noIncorrect + 1 -- Answer is correct end if -- Determine whether the player passed the exam if noCorrect • 3 then -- Three or more correct answers passes set grade to "Passed" else --Less than three correct answers fails set grade to "Failed" end if -- Displays the test results display dialog "Number correct: " & noCorrect & ¬ "Number incorrect: " & noIncorrect & ¬ "Test Results: " & grade buttons {"OK"} end if end tell end clicked
SUMMARY In this chapter you began learning how to formulate AppleScript code statements. This included learning how to work with a number of commands. You learned about different classes supported by AppleScript and how to coerce a data type from one type to another. You also learned how to formulate compound or code block statements. Finally, you learned how to create, access, and manipulate the contents of variables as a means of storing data during script execution.
Chapter 4 • Working with Values, Variables, and Classes
143
Before you move on to Chapter 5, why don’t you set aside a few extra minutes to improve the Star Trek Trivia game by addressing the following list of challenges.
CHALLENGES 1.
2.
3.
As is it currently written, the user interface for the Start Trek Trivia game is a little sparse. Add additional text and graphics to give it a more complete appearance. Currently, the test administered by the game consists of five questions. Make the test more challenging by adding additional questions. Do not forget to add the corresponding programming statements required to analyze and grade the additional exam questions. Modify the code statements that are responsible for automating the activity of the game’s progress indicator control so that it increments appropriately based on the number of questions that you add to the game.
This page intentionally left blank
5
C H A P T E R
APPLYING CONDITIONAL LOGIC AND BUILDING LOOPS ne of the fundamental operations performed in most AppleScript Studio applications is the ability to analyze data and make decisions based on the result of that analysis. In AppleScript this is accomplished using the if statement. By analyzing data, you can develop scripts that vary their execution based on the context of the current situation. Another core operation frequently used in AppleScripts is the use of loops to repeat the execution of a given set of programming statements in order to process large amounts of data or to perform a particular task repeatedly. In AppleScript, loops are created using the repeat statement. This chapter will teach you how to work with different variations of the if and repeat statements. In addition, you will learn how to create a new computer program, the Guess a Number game.
O
Specifically, you will learn how to • Use the if statement to define logical tests and control program flow • Use relational operators to test different types of conditions • Use the repeat statement to create different types of loops
146
AppleScript Studio Programming for the Absolute Beginner
PROJECT PREVIEW: THE GUESS A NUMBER GAME In this chapter’s game project, you will learn how to create a number guessing game that challenges players to guess a randomly generated number in the range of 1 to 100. Players enter their guesses using a slider control located in the middle of the game window, as shown in Figure 5.1.
FIGURE 5.1 The player must guess a randomly generated number between 1 and 100.
Game play begins when the player clicks on the New Game button, activating the slider control and readying the game to accept the player’s first guess, as shown in Figure 5.2.
FIGURE 5.2 The New Game button is disabled and remains that way until the end of the current game.
Chapter 5 • Applying Conditional Logic and Building Loops
147
A hint is provided in the text field control located at the bottom of the game window after each player guess. Using this information, the player can gradually close in on the correct answer, as demonstrated in Figure 5.3.
FIGURE 5.3 The player entered a guess that was too low.
The game keeps count of the number of guesses made by the player, allowing the player to keep track of his progress, as demonstrated in Figure 5.4.
FIGURE 5.4 The player’s guess was too high.
148
AppleScript Studio Programming for the Absolute Beginner
Game play ends when the player successfully guesses the game’s secret number. To notify the player, the slider control is disabled and a message of “Winner!” is displayed in the text field located at the bottom of the window, as demonstrated in Figure 5.5.
FIGURE 5.5 The player guessed the game’s secret number in eight guesses.
Game instructions can be viewed at any point during game play. To access these instructions, the player only needs to click on the Instructions tab at the top of the window, as shown in Figure 5.6.
FIGURE 5.6 A tab view control is used to toggle the player between the Play and Instructions views.
Chapter 5 • Applying Conditional Logic and Building Loops
149
IMPLEMENTING CONDITIONAL LOGIC As has been stated, conditional logic provides you with the ability to alter the logical execution flow within AppleScripts. In AppleScript, conditional logic is implemented using the if statement. To see how the if statement works, consider the following example. if the car costs $20,000 then I’ll buy it I’ll drive it straight to my girlfriend’s apartment end if
This English-like or pseudo-code outline provides you with a simple demonstration of the structure and operation of the if statement. As the example shows, the if statement is used to define a code block that begins with the if keyword and ends with end if. If the tested condition evaluates as being true, then all of the statements located inside the if statement code block are executed. Otherwise, if the tested condition evaluates as being false, the if statement code block is skipped, and execution continues at the statement following the code block. HIN
T
Pseudo-code is an English-like outline of the logic that makes up all or part of a script or application. If you develop a pseudo-code version of the programming logic you plan to implement in a script, you organize your thoughts prior to beginning coding. As a result, you are less likely to make logical mistakes.
The if Statement The if statement is used to build conditional tests. There are two basic forms of the if statement. The first is a single line version, which is used in situations where the logic required to write the statement is small enough to fit on a single line. The syntax for this form of the if statement is outlined here. if expression then statement expression is a placeholder representing any valid expression. statement is a placeholder rep-
resenting any valid AppleScript statement. An example of this form of the if statement is shown here. if x = 5 then display dialog "The value of x is five."
In this example the value of a variable named x is checked to see if it is equal to 5. If it is, a popup dialog is displayed using the display dialog command. If it is not equal to 5, the popup dialog is not displayed. An advantage of this form of the if statement is that it lets you define
150
AppleScript Studio Programming for the Absolute Beginner
a simple test and then execute a single code statement only if the test proves true using a minimum of space. The second form of the if statement is used to create if statement code blocks. Its basic syntax is outlined here. if expression then statements end if
If you want, you could rewrite the single line if statement example shown earlier as an if statement code block. if x = 5 then display dialog "The value of x is five." end if
Note that unlike single line if statements, an if statement code block can contain any number of AppleScript statements.
The if…else Statement Sometimes you will want to specify a different course of action to be taken in the event that the expression tested by an if statement is false. One way to do this is to use two if statement code blocks, as demonstrated here. --Apple and orange example if x = "apple" then display dialog "My Favorite." and if if x = "orange" then display dialog "No thanks." end if
You can save a little time and a few keystrokes by rewriting this example using the if…else form of the if statement. The syntax for an if…else code block is outlined here. if expression then statements else statements end if
Using this form of the if statement, the previous example could be rewritten like this.
Chapter 5 • Applying Conditional Logic and Building Loops
151
--Apple and orange example if x = "apple" then display dialog "My Favorite." else display dialog "No thanks." end if
As you can see, this example is slightly smaller, requiring one less statement. It also helps to clarify the overall logic used to guide logical flow within a script.
The if…else if Statement Another form of the if statement allows you to use even more complex logic when developing conditional tests. By adding the else if keywords, you can expand an if statement code block to test any number of different conditions. The syntax for this form of the if statement code block is outlined here. if expression then statements else if expression then statements else if expression then statements . . . else statements end if
Using this form of the if statement code block, you can test for as many conditions as necessary. By adding the optional else keyword, you can even provide for a course of action in the event that none of the tested expressions evaluate as being true. As an example, take a look at the following statements. --Apple, oranges and pairs example if x = "apple" then display dialog "My Favorite." else if x = "orange" then display dialog "No thanks." else
-- x equals pear
152
AppleScript Studio Programming for the Absolute Beginner
display dialog "Maybe just one." end if
Here the value of x is checked to see if it equals apple. If it does, then the embedded display dialog command executes, after which the code block is done, and the next statement immediately following the code block is executed. Otherwise, the first else if statement inside the code block is tested. If its tested expression evaluates as being true, its embedded display dialog command is executed, and the code block stops executing. Otherwise, the display dialog command associated with the example’s else statement is executed.
Nested if Statements An if statement code block can contain any number of embedded, or nested, AppleScript statements. These statements might also include other if statement code blocks. By embedding one code block within another, you can build complex programming logic, as demonstrated here. set today to (current date)
-- Stores the current date
set dayOfWeek to weekday of today as string
-- Stores day of the week
set dayOfMonth to day of today as integer --Stores numeric day of the month if dayOfWeek = "Saturday" then
-- Tasks to complete on Saturdays
if dayOfMonth = 5 then display dialog "Give the dog a bath." else display dialog "Take the dog to the park" end if else if dayOfWeek = "Sunday" then
-- Tasks to complete on Saturdays
display dialog "Remember to go to church today." else
-- Tasks to complete on weekdays display dialog "Sorry, it is another work day."
end if
In this example, three variables are defined. today is used to store the current date and time as stored on the computer. dayOfWeek stores the day of the week and dayOfMonth stores the numeric date for the month. An if…else if code block then determines what tasks needs to be performed based on the day of the week (e.g., Saturday, Sunday, or Monday–Friday). A nested if…else code block is used to select between either of two possible tasks that are performed only on Saturdays.
Chapter 5 • Applying Conditional Logic and Building Loops
153
DIFFERENT TYPES OF COMPARISONS So far, all of the conditional evaluations that you have seen in this chapter use the equals (=) operator to compare two conditions. AppleScript also provides a host of relational operators that you can use to perform different types of comparisons. Like the equals operator, each of these comparison operators is used to compare two values and results in a Boolean value of either true or false. AppleScript supports both symbolic and English-like versions of these comparison operators, as shown in Table 5.1. TRI
Actually, there are considerably more English-like operators available than those listed in Table 5.1. For example, instead of writing the following statement
CK
if x is greater than y then display dialog "Yikes!"
You could write if x comes after y then display dialog "Yikes!"
As an example of how to use the operators, consider the following example. if x > y then statements end if
Here, a statement embedded within an if statement code block is executed when the value of a variable named x is greater than the value assigned to a variable named y. Likewise, the following statement demonstrates the use of the ≠ operator. if x ≠ y then display dialog "Houston , we have a problem!"
TABLE 5.1
APPLESCRIPT RELATIONAL OPERATORS
Operator
English Equivalent
=
is is equal to equals is not is not equal to is greater than is greater than or equal to is less than is less than or equal to
≠ > ≥ < ≤
154
AppleScript Studio Programming for the Absolute Beginner
TRI
To type the 실, 싨, or 싩 characters, hold down the Option key when pressing the , characters.
CK
If you prefer, you can use the English-like equivalents of any of the operators shown in Table 5.1, as demonstrated below. if x is not equal to y then display dialog "Houston , we have a problem!"
The use of either the symbolic or English-like operators is entirely a matter of personal preference. For readability and consistency, I strongly recommend that you choose one type of operator (symbolic or English-like) and stick with it.
TIP
BUILDING COMPOUND TESTS As you have seen, you can build complex conditional logic by nesting if statement code blocks within one another. As an alternative, you can use any of the compound operators outlined in Table 5.2 to build complex conditional logic. As an example of how to use AppleScript’s compound operators, consider the following instance. if dayOfWeek = "Saturday" then if dayOfMonth = 5 then display dialog "Take the dog to the park" end if end if
As you can see, this example uses two if statement code blocks (one embedded within another) to test two conditions, and if both evaluate to true then a popup dialog is displayed. As an alternative, you could rewrite this example using the and compound command as shown here.
TABLE 5.2
APPLESCRIPT COMPOUND OPERATORS
Operator
Description
and or not
Results in a value of true if both expressions evaluate to true. Results in a value of true if either expression evaluates to true. Inverts or negates the value of an expression
Chapter 5 • Applying Conditional Logic and Building Loops
155
if dayOfWeek = "Saturday" and dayOfMonth = 5 then display dialog "Take the dog to the park" end if
As you can see, not only does using the and compound operator result in fewer lines of code, but it also makes the resulting code statements easier to read and understand. TRI
CK
The and operator, like the or operator, increases its efficiency by shortcircuiting. What this means is that the and operator will skip the evaluation of the expression on the right-hand side of the operator when the expression on the left-hand side evaluates to false. Remember, if either expression evaluates to false, the end results of the overall comparison will ultimately evaluate to false.
An example of the or operator is provided next. As you can see, the statements embedded within the if statement code block will be executed if either of the two tested expressions proves true. if x = 1 or y = 2 then statements end if
The not operator is different from the and and or operators, inverting or negating the value of the tested expression as it evaluates it. if not (x is equal to 100) then statements end if
Note the use of the parentheses. The parentheses used in this example are not required but were added for clarity, in order to clearly identify the expression to be negated and evaluated.
ITERATIVE PROCESSING Like conditional logic, iterative processing or looping is another key programming technique used in most AppleScripts. A loop is a logical construct that provides you with the ability to repeat the execution of a collection of programming statements. For example, you might set up a loop to execute a set of script statements that rename every file located in a folder or perform a set of commands an arbitrary number of times. In AppleScript, loops are created using different variations of the repeat statement, as listed here.
156
AppleScript Studio Programming for the Absolute Beginner
• repeat • repeat x times • repeat while • repeat until • repeat with • repeat with…in Each of these variations of the repeat statement is explained further in the sections that follow.
Creating an Endless Loop The simplest form of the repeat statement creates a code block that runs forever. It is therefore up to you to provide a means to terminate loop execution. The syntax for this form of the repeat statement code block is outlined here. repeat statements end repeat
As you can see, the loop begins with the repeat keyword and ends with the end repeat statement. All statements embedded in between are executed each time the loop repeats or iterates. As an example of how to put this form of loop into action, take a look at the following statements. set x to 1 repeat display dialog "Now looping – Iteration # " & x if x > 2 then exit repeat end if set x to x + 1 end repeat
Here, a variable named x is defined and assigned an initial value of 1. Next, a repeat statement code block is defined, which repeatedly displays a popup dialog. Upon each iteration of the loop, the value of x is incremented by 1 and displayed in the popup dialog, as demonstrated in Figure 5.7.
Chapter 5 • Applying Conditional Logic and Building Loops
157
FIGURE 5.7 The value assigned to the variable named x is displayed each time the loop iterates.
Note the inclusion of the exit repeat statement in the middle of the loop. This statement is wrapped inside an if statement code block and is executed when the value of x exceeds 2 (e.g. upon the third iteration of the loop). When executed, the exit repeat statement terminates the execution of the loop, allowing control to pass onto the next statement after the loop.
Iterating a Set Number of Times The repeat statement can also be used to set up a loop that executes a specified number of times using the following syntax. repeat x times statements end repeat
Using this syntax, the repeat code block executes a specific number of times based on the value of x, as demonstrated in the following example. set x to 1 repeat 3 times display dialog "Now looping – Iteration # " & x set x to x + 1 end repeat
In this example, a variable named x is defined and assigned a starting value of 1. A repeat statement code block is then executed, running three times. Upon each iteration of the loop, the value of x is displayed and then incremented by one.
Looping While a Condition Proves true Another variation of the repeat statement allows you to set up a loop that executes while a tested condition remains true. The syntax for this form of the repeat code block is outlined here.
158
AppleScript Studio Programming for the Absolute Beginner
repeat while expression statements end repeat
As you can see, the while keyword has been added, followed by the expression that is evaluated before each execution of the loop. As long as the value of expression evaluates as being true, the loop iterates. The first time that value of expression evaluates to false, the loop stops executing, allowing control to pass onto the next statement after the loop. An example of this form of the repeat statement code block is provided here. set userInput to "" repeat while userInput is not equal to "quit" set userInput to text returned of ¬ (display dialog "Type quit to exit." default answer "") end repeat
In this example, a variable named userInput is defined. Next, a repeat statement code block executes, assigning the value supplied by the user to the userInput variable. The loop continues to execute as long as the value supplied by the user is not equal to quit.
Looping Until a Condition Proves true The repeat statement also accepts the use of the until keyword, setting up a loop that executes as long as a specified expression evaluates as being false (e.g. the opposite of a repeat statement code block created using the while keyword). The syntax for this form of the repeat code block is outlined here. repeat until expression statements end repeat
As the following example shows, you can use this form of the repeat statement code block in place of the while version by simply inverting the conditional test—in this case, from not equal to to equal to. set userInput to "" repeat until userInput is equal to "quit" set userInput to text returned of ¬ (display dialog "Type quit to exit." default answer "") end repeat
Chapter 5 • Applying Conditional Logic and Building Loops
159
Controlling Loop Execution with a Counter Yet another variation of the repeat statement is the creation of a loop that executes a set number of times using a starting and ending value. The syntax for this form of loop is outlined here. repeat with variablename from start to end [by counter] statements end repeat
Here, variablename is a placeholder for a variable that will be used to control the loop’s execution. When first executed, the value of start and end are evaluated. The value of start is then assigned to variablename. Each time the loop iterates, the value of variablename is incremented by one, unless the optional by counter parameter is specified. If specified, the value of counter is added to variablename upon each iteration of the loop. The loop continues to execute until the value of variablename becomes equal to the value of end. As an example of how to set up this version of a repeat statement code block, take a look at the following example. repeat with x from 1 to 9 by 2 display dialog x end repeat
Here the loop has been set up to execute five times. The first time the loop executes, the value of x is set to 1. On the second execution of the loop, the value of x becomes 3. Upon the fifth execution, the value of x becomes 9, and the loop stops execution. This form of loop is quite flexible. If you want, you can even specify a negative number to be used to decrement the value of x, as demonstrated here. repeat with x from 9 to 1 by –2 display dialog x end repeat
Here, the value of x begins at 9 and is reduced by 2 upon each iteration, until it finally reaches a value of 1 and the loop stops executing.
Processing List Contents A final variation of the repeat statement code block allows you to set up a loop that iterates through the contents of a list. The syntax for this form of loop is outlined here. repeat with variablename in list
160
AppleScript Studio Programming for the Absolute Beginner
The following statements demonstrate how to iterate through each element in a list. repeat with x in {"Molly", "William", "Alexander"} display dialog x end repeat
In this example, a loop is set up that iterates through a list made up of three elements displaying the contents of each list element. As the loop executes, the value of x is implicitly referenced and displayed as x. More information on how to work with lists is available in Chapter 6, “Working with Strings, Lists, and Records.”
BACK TO THE GUESS A NUMBER GAME Okay, let’s turn our attention back to the development of the Guess a Number game. The primary point of focus for this game is the application of the conditional logic required to control game execution and evaluate player guesses. As you work on the Guess a Number game, you will get another chance to work with the slider control. You will also learn how to work with the tab view control. I will also show you a little trick that you can use when testing the execution of your new game. As with all of the applications in this book, the Guess a Number game will be created in five steps, as outlined here. 1. Starting Xcode and creating a new AppleScript Studio application. 2. Designing the application’s graphical user interface. 3. Configuring the game’s menu, window, and control attributes and attaching interface controls to event handlers. 4. Adding the required AppleScript code statements. 5. Compiling and testing the application.
Step 1: Creating a New Project If you have not done so yet, go ahead and start Xcode. Create a new AppleScript Studio project as outlined here. 1. Click on the File menu and then select New Project. Xcode starts an Assistant, displaying a list of application templates. 2. Select AppleScript Application template and then click on Next. 3. When prompted, specify Guess a Number as the file name for the application and then specify the appropriate location where the project should be stored. 4. Click on Finish.
Chapter 5 • Applying Conditional Logic and Building Loops
161
Step 2: Creating the User Interface Now it is time to development the Guess a Number game’s graphical user interface, as outlined in the following procedure. 1. Locate the MainMenu.nib file located in the Resources group and then double-click on it to start the Interface Builder. 2. Drag and drop an instance of the tab view control onto the application’s window. Resize the control so that it takes up the entire window. 3. By default, the tab view control displays two tabs. Double-click on the first tab and change its title to Play. Double-click on the second tab and enter Instructions. 4. Making sure that the Play tab is selected, drag and drop an instance of the small system font text control to the upper left-hand corner of the tab view control. Double-click on it and change its title to read N o. of Guesses made:. 5. Add a text field control just to the right of the small system font text control, reducing its width to about one-half its default size. 6. Add a button control to the upper right-hand side of the tab view control, aligning it with the text field control. Double-click on the button control and change its title to New Game. 7. Next, drag and drop a horizontal box control onto the tab view control. Place it about a half inch below the control already added and resize it to be almost the entire width of the tab view area. 8. Add another small system font text control to the tab view control. Center it about a quarter inch below the horizontal box control and then change its title to Guess. 9. Add a text field control immediately under the small system font text control. Reduce its width to approximately one inch and then change its height to approximately a half inch. 10. Drag and drop another text field control onto the tab view control and place it somewhere to the right of the previous text field control. 11. Add a slider control to the middle of the tab view control. Resize it so that it is approximately five inches wide. 12. Add another button control just under the slider control, and change its title to Check Move. 13. Drag and drop another horizontal box control onto the tab view control, placing it about a quarter inch below the last button control, resizing it to be almost the entire width of the tab view control. 14. Add another small system font text control in the bottom left-hand corner of the tab view control and change its title to Results:.
162
AppleScript Studio Programming for the Absolute Beginner
15. Drag and drop a text field control to the bottom of the tab view control and resize it so that it takes up the remainder of space to the right-hand side of the small system font text control. 16. At this point, the tab view control labeled Play should look like the example shown in Figure 5.8.
FIGURE 5.8 The layout of the Play view of the Guess a Number game.
17. Next, click on the Instructions tab and then drag and drop a small system font text control onto it. Resize this control so that it takes up most of the available space and then enter the following text into it: The objective of this game is to guess the game’s randomly generated secret number i n as few guesses as possible. The range of possible choices is between 1 and 100. Use the slider control to specify a guess. Once you have selected your guess, click on the Check Move button. Your guess will then be evaluated, and the result of this a nalysis will be displayed in the Results text field at the bottom of the game window. Game play ends once the secret number has been guessed. 18. At this point, the Instructions tab should look like the example shown in Figure 5.9.
Chapter 5 • Applying Conditional Logic and Building Loops
163
FIGURE 5.9 The layout of the Instructions tab of the Guess a Number game.
The user interface for the Guess a Number game is complete, and you are ready to begin customizing various control properties.
Step 3: Customizing Control Properties To finish up the configuration of the Guess a Number game, you will need to configure its window and menu system and then various control attributes, as outlined in the next several sections.
Menu Customization To customize its menu system, you will need to remove a number of unnecessary menus and menu items that Xcode automatically adds to your application. Begin by clicking on the Help menu and pressing the Delete key. Delete all of the menu items under the Window menu except for the Minimize menu item. Next, select the Edit menu and press Delete to remove it and its contents. Next click on the File menu and remove everything but the Close menu item. Lastly, you need to customize the Application menu as outlined here. 1. 2. 3. 4.
Double-click on the Application menu and replace its name with Number Guess. Modify the About Application menu item to read About Number Guess. Modify the Hide Application menu item to read Hide Number Guess. Modify the Quit Application menu item to read Q uit Number Guess.
164
AppleScript Studio Programming for the Absolute Beginner
Setting Control Attributes As with the previous AppleScript Studio applications that you have worked on, you must make a number of modifications to this game’s window and interface controls. These changes are outlined in Table 5.3 and must be made from the Inspector window’s AppleScript and Attribute views. Note that the name assigned to the tab view control is tbvDisplay. This control has two tabs, each of which has its own view. Click on the Play tab and assign it a name of p layGame and then click on the Instructions tab and assign it a name of g ameInstructions.
Setting Up Event Handler Connections Like every GUI you have worked on in this book, you need to configure certain interface controls so that they will trigger events when the player uses them. Specifically, in the Guess a Number application, you will need to set up both of the game’s button controls so that they
TABLE 5.3
MODIFICATIONS TO THE APPLICATION WINDOW ITS INTERFACE CONTROLS
Object
Attribute
Modification
Window
Name Window Title Zoom Name Name Editable Selectable Name Name Editable Selectable Name Minimum Maximum Current Name Name Editable Selectable
main Guess a Number Disable tbvDisplay txtCount Disabled Disabled newGame txtGuess Disabled Disabled sdrGuess 1.0 100.0 1.0 checkMove txtResults Disabled Disabled
Tab View Text Field
Button Text Field
Slider
Button Text Field
AND
Chapter 5 • Applying Conditional Logic and Building Loops
165
will trigger the on clicked event handler. In addition, you will also need to configure the slider control’s action event handler (from the AppleScript view in the Inspector window).
Step 4: Adding a Little Programming Logic Now it is time to begin adding the AppleScript statements required to make the Guess a Number game work. In doing so, you will learn a number of new AppleScript programming tricks, including how to manage controls located on different views of a tab view control and the steps involved in interacting with the slider control. In addition, you will learn how to generate random numbers using the random number command. TR
AP
Before adding the code statements provided in this section, it is assumed that you have already configured the clicked event for both of the applications’ button controls and the action event for the slider control. As a result, the application’s AppleScript file should already contain the following statements. -- Number Guess.applescript -- Number Guess --
Created by Jerry Ford on 8/7/06.
--
Copyright 2006 __MyCompanyName__. All rights reserved.
on clicked theObject (*Add your script here.*) end clicked on action theObject (*Add your script here.*) end action
Adding Code to the on clicked Event Handler Let’s begin by working on the code belonging to the on clicked event handler. For starters, modify the code for this event handler as shown here. on clicked theObject tell window of theObject --Execute when the button labeled New Game is clicked if name of theObject is "newGame" then
166
AppleScript Studio Programming for the Absolute Beginner
end if --Execute when the button labeled Check Move is clicked if name of theObject is "checkMove" then end if end tell end clicked
As you can see, this event handler has been organized into two major parts. The first part is an if code block that executes when the player clicks on the button control named newGame (e.g., the Start Game button). The second part is an if control block that executes when the player clicks on the button control named checkMove (e.g. the Check Move button). In addition, both of these if code blocks have been embedded inside a tell block that directs all commands to the application’s window. Now that you have this high-level structure in place, it is time to get busy keying in the rest of the application’s code. Start by adding the following statements inside the if statement control block for the newGame button control. --Generate a random number between 1 and 100 set randomNo to random number from 1 to 100 as integer --Reset text field that displays the number of guesses made set contents of text field "txtCount" ¬ of tab view item "playGame" of tab view "tbvDisplay" to 0 --Reset text field that displays the slider's default value set contents of text field "txtGuess" ¬ of tab view item "playGame" of tab view "tbvDisplay" to 1 --Assign the random number to the secret text field set contents of text field ¬ "txtCheat" of tab view item "playGame" ¬ of tab view "tbvDisplay" to randomNo --Reset the text field labeled Results set contents of text field ¬ "txtResults" of tab view item "playGame" ¬ of tab view "tbvDisplay" to " " --Reset the slider control to a default value of one
Chapter 5 • Applying Conditional Logic and Building Loops
167
set contents of slider "sdrGuess" ¬ of tab view item "playGame" of tab view "tbvDisplay" to 1 set enabled of slider "sdrGuess" of tab view item ¬ "playGame" of tab view "tbvDisplay" to true set enabled of button "newGame" of tab view item ¬ "playGame" of tab view "tbvDisplay" to false set enabled of button "checkMove" of tab view item ¬ "playGame" of tab view "tbvDisplay" to true
This code begins by generating a random number. This is accomplished using the random number command. By default, this command generates a random number between 0 and 1. However, by specifying upper and lower limits, as in this example, you can select a range of any size. The value returned by the random number command is a real number, which means that it includes a decimal point. Since the game requires an integer value, the value generated by the random number command is then converted to an integer and assigned to a variable named randomNo. The next statement displays the number of guesses made so far by the player. Since a new game is being started, this value is set to 0. Since the game and its instructions are presented using a tab view control, a little extra effort is required in order to identify the location of the text field control. Specifically, the text field control is located on the playGame view of the tbvDisplay tab view control. The next command assigns a value of 1 to the text field control that is used to display the slider control’s current value, which you may remember you set to 1.0 from the Inspector window. Next, the game’s random number is displayed as a text field control named txtCheat. I have added this feature to help simplify the testing of the game. As you will see, it will be a lot easier to validate the game’s proper operation when you know what the secret number is during testing. TRI
CK
Later, once you are done testing the Guess a Number game, you can remove the txtCheat text field control and the code that refers to it. Better yet, you can keep it and enable its Hidden attribute to keep it from being seen. This way, if you later come back and make a change to the game, all that you will have to do is clear the Hidden attribute and you’re ready to test again.
The rest of the statement in this code finishes setting and displaying default text field values and then enables and disables button and slider controls as required to start game play. Next, add the following set of code statements to the if statement control block associated with the checkMove control.
168
AppleScript Studio Programming for the Absolute Beginner
--Declare a variable and use it to store the player's guess set playerGuess to contents of slider "sdrGuess" ¬ of tab view item "playGame" of tab view "tbvDisplay" ¬ as integer --Declare a variable and use it to store a random number set secretNo to contents of text field ¬ "txtCheat" of tab view item "playGame" ¬ of tab view "tbvDisplay" as integer --Retrieve value representing the number of guesses made so far --and store it in a variable named x set x to contents of text field ¬ "txtCount" of tab view item "playGame" ¬ of tab view "tbvDisplay" as integer --Increment x by one set x to x + 1 --Store the value of x back in the text field that displays the --total number of player guesses set contents of text field ¬ "txtCount" of tab view item "playGame" ¬ of tab view "tbvDisplay" to x
The first statement sets the value of a variable named playerGuess to the value currently specified by the slider control. The next statement sets the value of a variable named secretNo equal to the game’s randomly generated secret number (which is stored in the txtCheat text field). Next, you need to add the programming logic that addresses the actions that need to be taken when the player correctly guesses the game’s secret number. To do so, add the following set of code statements to the bottom of the if statement control block associated with the checkMove control. Next, a variable named x is assigned a value representing the number of guesses made so far (which is stored in the txtCount text field). The value of x is then incremented, and the contents of the txtCount field are updated by reassigning the updated value of x back to it, in effect updating the display of the number of guess made so far. Now, add the following set of code statements immediately after the preceding set of statements (e.g., to the bottom of the if statement control block associated with the checkMove control).
Chapter 5 • Applying Conditional Logic and Building Loops
169
if playerGuess = secretNo then --The player's guess was correct --Disable the slider control set enabled of slider ¬ "sdrGuess" of tab view item "playGame" ¬ of tab view "tbvDisplay" to false --Disable the button control labeled New Game set enabled of button ¬ "newGame" of tab view item "playGame" ¬ of tab view "tbvDisplay" to true --Disable the button control labeled Check Move set enabled of button ¬ "checkMove" of tab view item "playGame" ¬ of tab view "tbvDisplay" to false --Display a message telling the user the game’s over set contents of text field ¬ "txtResults" of tab view item "playGame" ¬ of tab view "tbvDisplay" to "Winner!" end if
The opening if statement checks to see if the player has guessed the game’s secret number. If he has, all the statements in the if statement code block execute. The first of these statements disables the slider control, thus stopping game play. The next statement enables the New Game button, allowing the player to start a new round of play. Next, the Check Move button is disabled, and then a text string of “Winner!” is posted in the text field located at the bottom of tab view control’s playGame tab. Now let’s add programming logic to address the actions that need to be taken when the player’s guess is too low. To do so, add the following set of code statements to the bottom of the if statement control block associated with the checkMove control. if playerGuess < secretNo then --The player's guess is too low --Display a helpful hint in the text field labeled Results set contents of text field ¬ "txtResults" of tab view item "playGame" of tab view ¬ "tbvDisplay" to "Your guess was too low." end if
As you can see, the only action that needs to be taken when the player’s guess is too low is to update the display of the text string in the txtResults text field control in order to give the player a helpful hint.
170
AppleScript Studio Programming for the Absolute Beginner
Now let’s add programming logic to address the actions that need to be taken when the player’s guess is too high. To do so, add the following set of code statements to the bottom of the if statement control block associated with the checkMove control. if playerGuess > secretNo then --The player's guess is too high --Display a helpful hint in the text field labeled Results set contents of text field ¬ "txtResults" of tab view item "playGame" of tab view ¬ "tbvDisplay" to "Your guess was too high." end if
These statements execute when the player’s guess is too high. All that is required here is to update the display of the text string in the txtResults text field control in order to give the player a helpful hint. This ends the code required to complete the development of the on clicked event handler for both of the GUI’s button controls. Next, you must provide the code required to help manage the execution of the slider control.
Adding Code to the action Event Handler The last bit of AppleScript code needed to finish up the Guess a Number application is shown next. This code goes in the slider control’s action event handler, which should already be defined within your AppleScript file. The action event handler executes every time the slider control’s thumb is moved, thus providing instantaneous feedback of the slider’s current value or setting. tell window of theObject --Focus stays on the window named main --Display the slider control's current value in the text field --control immediately above it set contents of text field ¬ "txtGuess" of tab view item "playGame" of tab view ¬ "tbvDisplay" to contents of slider "sdrGuess" of tab view item ¬ "playGame" of tab view "tbvDisplay" as integer end tell
The sole purpose of this code is to manage the process of displaying the slider control’s current value in the text field control immediately above it. This is accomplished in a single statement, which sets the value of the txtGuess text field control equal to the contents of the sdrGuess slider control, located on the playGame view of the tbvDisplay tab view control.
Chapter 5 • Applying Conditional Logic and Building Loops
171
Step 5: Testing the Execution of the Guess a Number Game Your new AppleScript studio game is now complete. Go ahead and click on Xcode’s Build and Go button and see if it runs. If you receive any errors, use the error information provided to track and find out where you may have made typos. Once everything appears to be running correctly, play a few rounds. Remember that the value of the randomly generated number is displayed in the text field control named txtCheat. Knowing what this number is will help you test your game more quickly and validate that the guesses you are providing are being correctly interpreted. Once you are confident that everything is as it should be, select the txtCheat text field control, open the Inspector window, and modify the control by deselecting the control’s Hidden attribute. Recompile the application and test it one more time before sharing copies of it with your friends.
SUMMARY In this chapter you learned how to apply conditional logic in order to create scripts that alter their execution based on an analysis of the data being worked with. You learned how to use different relational operators to define different types of comparisons. You also learned how to use compound operators in order to perform evaluations using two or more logical comparisons. In addition, you learned how to create loops using a number of different variations of the repeat statement. Before you move on to Chapter 6, why don’t you set aside a few extra minutes to add a few improvements to the Guess a Number game by addressing the following list of challenges.
CHALLENGES 1.
2.
As currently written, the Guess a Number game provides only two types of hints to the user after each guess, “too high” or “too low.” Add additional logic to your application to indicate when the player is beginning to get warmer or colder. Modify the Guess a Number game so that it prompts the player to specify different ranges of numbers from which the player can guess. For example, you might let the player select from ranges of 1 to 10, 1 to 100, or 1 to 1,000.
172
3.
4.
AppleScript Studio Programming for the Absolute Beginner
Consider adding an optional Quit button to your application to provide players with the ability to stop playing in the middle of a game. Also, you might want to display the game’s secret number at the end of each game. Another option to consider is to limit the number of guesses allowed and to declare the game over in the event the user does not guess the secret number within that specified number of guesses.
6
C H A P T E R
WORKING WITH STRINGS, LISTS, AND RECORDS n Chapter 4, “Working with Values, Variables, and Classes,” you learned how to store and retrieve individual pieces of data using variables. You also learned a few basic techniques for working with strings, including how to concatenate strings and extend them over multiple lines. In this chapter, you will expand upon this information by learning how to work with collections of data stored in lists and records. You will learn a number of different ways in which you can control the format of strings. You will also learn how to manipulate string contents. On top of all this, you will learn how to work with a number of new interface controls and to leverage the power of the Mac OS X built-in speech synthesizer. Finally, to wrap things up, you will learn how to create your next computer game, Alexander’s Tall Tale.
I
Specifically, you will learn how to • Create and work with lists • Define and store data using records • Perform a number of string manipulation techniques • Work with the text view, switch, and popup button controls • Use the say command to make your applications talk
174
AppleScript Studio Programming for the Absolute Beginner
PROJECT PREVIEW: ALEXANDER’S TALL TALE In this chapter you will learn how to create the Alexander’s Tall Tale game. When first started, the screen shown in Figure 6.1 is displayed.
FIGURE 6.1 The game’s story is displayed using a text view control.
When the player clicks on the Tell Story button, the text of the story is displayed in a text view control that takes up most of the window, as demonstrated in Figure 6.2. The game’s storyline consists of a number of paragraphs into which variables have been inserted at key points. Each time the player clicks on the Tell Story button, the values of these variables are replaced with different randomly selected strings, thus telling a slightly different story each time.
FIGURE 6.2 The story is told in a slightly different way each time it is told.
Chapter 6 • Working with Strings, Lists, and Records
175
Because the story is rather lengthy, you have to scroll down to read the end of the story. If you prefer to save your eyes a little work, you can have the game read the story to you using any of three built-in Mac OS X voice synthesizer voices. These voices are selected from the popup button control located at the bottom of the window, as demonstrated in Figure 6.3.
FIGURE 6.3 The player can customize the game by selecting the voice used to read the story.
Once a voice has been selected, the player must enable the option to have the game read the story aloud. This is done by selecting the Talk (switch) control before clicking on the Tell Story button, as shown in Figure 6.4.
FIGURE 6.4 To have the game read the story aloud, the Talk option must first be selected.
176
AppleScript Studio Programming for the Absolute Beginner
MANIPULATING STRINGS Somewhere along the line you are going to run into a situation where you need to exercise detailed control over the strings managed by your AppleScript Studio applications. For example, you may want to create an application that renames all of the files in a folder, by either changing their file extension or perhaps adding date information to the end of their file names. Alternatively, you may be interested in searching for information within strings, in order to extract a particular piece of information. Fortunately, AppleScript provides you with several ways of examining and extracting information about strings.
Assigning Strings to Variables As has already been stated, a string is a sequence of one or more characters enclosed within a matching pair of double quotation marks, as demonstrated here. set myName to "Jerry"
There is no practical limit to the size of a string. In addition, you can assign a variable a null string value by assigning it an empty string as demonstrated here. set x to ""
Getting Information About a String Using the count command, you can retrieve a value representing the number of characters that make up a string. The count command has the following syntax. count string string represents a string or a variable containing a string. As an example of how to use the count command, take a look at the following example. set message to “IT WAS THE BEST OF TIMES, IT WAS THE WORST OF TIMES” display dialog “The string:” & message & “contains” & ¬ (count message) & “characters.”
When executed, this example displays a count of the number of characters in a string assigned to the message variable, as demonstrated in Figure 6.5.
FIGURE 6.5 Displaying a count of the number of characters in a string.
Chapter 6 • Working with Strings, Lists, and Records
177
Concatenating Strings Using the & concatenation operator, you can join together any two strings to create a new string, as demonstrated here. set message to “Happy ” & “Birthday!”
Here two strings are concatenated and assigned to a variable named message. As the following example shows, you can concatenate as many strings as necessary. set myName to “Jerry” & “ ” & “Ford”
Here three strings have been concatenated into one string, which is then assigned to a variable named myName.
Controlling String Format AppleScript provides you with a means of specifying how you would like to format a string by providing you with access to a small collection of escape characters. An escape character is a special sequence of characters beginning with the \ character and followed by a letter that AppleScript recognizes and replaces with its ASCII equivalents. Table 6.1 lists the escape characters recognized by AppleScript.
TABLE 6.1
APPLESCRIPT ESCAPE CHARACTERS
Escape Characters
English Equivalent
Description
\r \n \t \\
End of line Newline Tab Backslash
\"
Double quotation mark
Adds an ASCII end of line marker Adds an ASCII newline character Inserts a tab space into the string Inserts a single backslash character into a string Inserts a double quotation mark into a string
The \r and the \n escape characters produce the same results. The \n escape character is used on Unix, while \r is often used on Mac OS X. Both are perfectly valid, though in this book you will see only \n used. The following three statements demonstrate how to use the \n, \t, and \" escape characters. display dialog “ALERT!\n\nThis is a test message” display dialog “ALERT!\t\tThis is a test message” display dialog “ALERT! \“This is a test message\””
178
AppleScript Studio Programming for the Absolute Beginner
The output for each of these three statements is shown in Figures 6.6, 6.7, and 6.8.
FIGURE 6.6 Using the \n escape characters to format a string over two lines.
FIGURE 6.7 Using the \t escape characters to format a string by inserting a tab.
FIGURE 6.8 Using the \" escape characters to embed double quotation marks inside a string.
TR
AP
Do not be surprised when, after compiling your application, escape characters disappear from your AppleScripts, and your strings are reformatted. This is just the way things work. The compiler reformats the strings according to the instructions you provide via escape characters.
Advanced Comparisons You have learned that you can compare strings, for example, to see if they are equal. AppleScript supports two other statements that give you additional control over how certain parts of strings are interpreted during a comparison. • considering. Specifies one or more attributes to be considered when performing a comparison. • ignoring. Specifies one or more attributes to be ignored when performing a comparison. These two statements are used to set up code blocks, within which string comparisons are made. For example, by default, AppleScript ignores case when comparing strings. As a result, the strings “jerry” and “JERRY” are, by default, equivalent. However, as the following example demonstrates, you can change this behavior by enabling case-sensitivity.
Chapter 6 • Working with Strings, Lists, and Records
179
set x to “jerry” set y to “JERRY” considering case if x = y then display dialog “Match!” end considering
In this example, a case attribute is added to the end of the opening considering statement, thus setting up a code block within which all string comparisons are subject to casesensitivity. As a result, since case-sensitivity is now in effect, AppleScript will not evaluate the value of x and y as being equal. AppleScript supports a number of other attributes that can be applied to both considering and ignoring code blocks, as outlined in Table 6.2.
TABLE 6.2
ATTRIBUTES SUPPORTED BY IGNORING BLOCKS
CONSIDERING AND
Attribute
Description
case white space punctuation hyphens
All lowercase and uppercase characters Any white space, including spaces, tabs, and the newline and return characters Any punctuation characters, including ,.?\’”`;: The hyphen (-) character
By default, AppleScript automatically considers all of the attributes listed in Table 6.2, except for case. If you want, you can disable the considering of any of these attributes by using the ignoring statement, as demonstrated here. set x to “Once upon a time.” set y to “Once upon a time” ignoring punctuation if x = y then display dialog “Match!” end ignoring
In this example, a match results even though the first string contains a period that is not present in the second string. If you want, you can set up a code block that specifies more than one attribute, as shown here. set x to “Once upon a time.” set y to “Once upon a time” considering case but ignoring hyphens, punctuation and white space if x = y then display dialog “Match!” end considering
180
AppleScript Studio Programming for the Absolute Beginner
Note that in this example, the but keyword allows you to combine considering and ignoring statements. In addition, you can specify more than one attribute by separating them with commas. The last attribute must be separated from the other attributes using the and keyword.
Working with Characters, Words, and Paragraphs AppleScript allows you to reference different parts of strings using different string elements, as defined here. • character. An individual character within a string. • word. A continuous set of characters within a string, typically separated from other characters by a blank space. • paragraph. A set of characters demarcated by a return or newline character. Using these string elements, along with the element specifiers outlined in Table 6.3, you can perform a host of operations on the contents of strings.
TABLE 6.3
STRING ELEMENT SPECIFIERS
Specifier
Description
first, second, etc. item 1, item 2, etc. 1st, 2nd, etc. some every last end items x through z
Specifies an item within a string Specifies an item within a string Specifies an item within a string Specifies a randomly selected item within a string Specifies every item within a string Specifies the last item within a string Specifies the last item within a string Specifies a range of items within a string
For example, the following statement can be used to extract the fifth word from a string. set x to “Once upon a time there was a little girl named Molly.” set y to fifth word of x
-- y equals there
Similarly, you could retrieve the last word in a string, as demonstrated here. set x to “Once upon a time there was a little girl named Molly.” set y to last word of x
-- y equals Molly
Chapter 6 • Working with Strings, Lists, and Records
181
The string element specifiers listed in Table 6.3 also work with characters and paragraphs attributes. For example, you can extract a range, or substring, of characters from a string as shown here. set x to “Once upon a time there was a little girl named Molly.” set y to characters 1 through 11 x
-- y equals Once upon a
Later, when you develop the Alexander’s Tall Tale game, you’ll see an example of how to use the some item specifier to randomly extract a paragraph from a list of paragraphs.
DEFINING AND ACCESSING LISTS In Chapter 4, you learned how to store and retrieve individual pieces of data using variables. While certainly a powerful programming technique, there are times when working with individual pieces of data is not always easy. For example, suppose you wanted to write an AppleScript Studio application that was designed to collect a list of names from the user. If the user entered just a few names, this would not be too bad. But what if the user decides to enter 10 or 20 names? That is a lot of variables to have to define and keep track of. An easier way of storing and keeping track of groups of related data is through lists. A list is an ordered collection of values, which are referred to as items. Lists can be used to store any type of data type. Lists are defined by placing comma-delimitated values inside a pair of matching curly braces, as demonstrated here. {1, 2, 3, 4, 5} HIN
T
A list is AppleScript’s equivalent to an array in other programming languages.
Working with Lists Here a list has been created that contains three strings. Lists, of course, can be assigned to variables. set nameList to {“Alexander”, “William”, “Molly”}
Above, a list made up of strings is assigned to a variable named nameList. Lists can contain any combination of data types. They can also be empty, as shown next. set emailList to {}
182
AppleScript Studio Programming for the Absolute Beginner
A list can contain any number of elements. You can use the count command to retrieve a value representing the number of elements in the list as shown here. set nameList to {“Alexander”, “William”, “Molly”} set x to count of nameList TIP
-- x equals 3
If necessary, you can use the & concatenation operator to create a new list out of two existing lists as demonstrated here. set x to {1, 2, 3} set y to {3, 4, 5} set z to x & y
-- z equals {1, 2, 3, 4, 5, 6}
Retrieving Elements from a List Back in Chapter 5, “Applying Conditional Logic and Building Loops,” you learned how to work with different variations of the repeat statement in order to iterate through and process the contents of a list. As a reminder, consider the following example. repeat with x in {“Molly”, “William”, “Alexander”} display dialog x end repeat
Here, a repeat statement has been set up that iterates through a list made up of three strings. Upon each iteration, the value of one of the strings is assigned to a variable named x, which is then displayed by a display dialog command. In addition to using the repeat loop to step through a list and examine or manipulate its contents, you can use any of the item specifiers listed in Table 6.4 to access items stored in a list. As an example of how to extract items from a list, take a look at the following examples. set nameList to {“Alexander”, “William”, “Molly”} set x to first item in nameList set x to every item in nameList set x to last item in nameList
-- x equals “Alexander” -- x equals {“Alexander”, “William”, “Molly”} -- x equals “Molly”
set x to items 2 through 3 in nameList
-- x equals {“William”, “Molly”}
The comments on the right-hand side of each statement show the output generated from each statement.
Chapter 6 • Working with Strings, Lists, and Records
TABLE 6.4
ITEM SPECIFIERS THAT CAN BE USED
TO
183
ACCESS LISTS
Specifier
Description
First item, second item, etc. item 1, item 2, etc. 1st item, 2nd item, etc. some item every item beginning middle item last item end items x through z
Specifies an item within a list. Specifies an item in a list. Specifies an item in a list. Specifies a randomly selected item in a list. Specifies every item in a list. Specifies the first item in a list. Specifies the middle item in a list. Specifies the last item in a list. Specifies the last item in a list. Specifies a range of items within a list.
Making Changes to Lists AppleScript provides you with the ability to make specific types of changes to lists. These changes include: • Changing an item • Inserting an item at the beginning of the list • Adding an item to the end of a list You can use the set command to modify any item in a list by specifying its location within the list and a replacement value, as demonstrated here. set nameList to {“Alexander”, “William”, “Molly”} set item 2 in nameList to “William the Great”
You can add a new item to the beginning of any list using the beginning specifier, as demonstrated here. set nameList to {“Alexander”, “William”, “Molly”} set beginning of nameList to “Mary”
Similarly, you can add an item to the end of any list, as shown here. set nameList to {“Alexander”, “William”, “Molly”} set end nameList to “Jerry”
184
AppleScript Studio Programming for the Absolute Beginner
TRI
CK
Unfortunately, AppleScript does not provide you with a command for deleting items from a list. However, if you know the location of the item that you would like to delete, you can work around this limitation. One way of doing so is to extract the range of items before the item to be deleted and the range of items that follow that item and then concatenate these two ranges back together, as demonstrated here. set x to {1, 2, 3, 4, 5, 6} set x to items 1 through 3 of x & items 5 through 6 of x
Here the range of items 1–3 is concatenated to the range of items 5–6 and then assigned back to x, The end result of this operation is that the fourth item in the list has now been removed.
STORING AND RETRIEVING DATA USING RECORDS Lists are ordered collections of data. As such, you can use a loop to iterate through them. You can also access list contents by specifying the location of list items. Another way to work with and manage collections of data is through records. A record is a collection of properties, each of which is assigned a label and a value. HIN
T
A record is AppleScript’s equivalent to a hash or dictionary in other programming languages.
The format of a record is outlined here. {label: value, label: value ….} label is a placeholder representing the name assigned to a specific property, and value is a
placeholder for the data associated with a given property. As you can see, data in a record is stored in label: value pairs.
Creating and Accessing Records As demonstrated next, a record can contain any number of label: value pairs. set childsName to {name: “Alexander”, age: 9, hobby: “Beyblading”}
Once it is set, you can extract any property from a record by referencing its label, as demonstrated here. set x to the name of childsName – x equals Alexander
If necessary, you can retrieve more than one record property at a time, as demonstrated here.
Chapter 6 • Working with Strings, Lists, and Records
185
set myList to {name, age} of childsName –- myList contains {“Alexander”, 9}
Whether you have realized it or not, you have worked with records on a number of occasions in this book. The display dialog command has been used in numerous examples to collect data returned by the user, either by determining the button that the user clicked or by collecting the string that the user entered into the resulting popup dialog. Both the button and text returned by the display dialog command are collected in the form of a record. In Chapter 4, as part of the Star Trek Trivia game, you displayed a popup dialog that displayed two buttons, as shown here. set answer1 to the button returned of (display dialog ¬ “Question 1:
The laws that govern the actions of Star ” & ¬
“Fleet personnel are referred to as Prime Directives.” ¬ buttons {“True”, “False”})
In this example, you determine which button the user clicked on by using the set command to assign a value to a variable named answer1. Take note of the bold portion of this example. It extracts a record property named button returned from a record generated by the display dialog command. Likewise, in the following example, the value keyed in by the user is assigned to a variable named answer by extracting a record property named text returned. set answer to the text returned of (display dialog ¬ “What is your name?” default answer ””)
Modifying Record Property Values You can use the set command to modify the value stored in a given record property. To do so, you must specify the property whose value is to be changed and then supply a new value, as demonstrated here. set childsName to {name: “Alexander”, age: 9, hobby: “Beyblading”} set age of childsName to 10
Here, a value of 10 is assigned to the age property for the record named childsName.
Working with a List of Records By themselves, individual records are of limited value. However, if you group them together in a list, records take on a greater role in helping to organize and retrieve large collections of data. As an example, check out the AppleScript statements shown here.
186
AppleScript Studio Programming for the Absolute Beginner
set childNames to {¬ {name:“Alexander”, age:9, hobby:“beyblading”}, ¬ {name:“William”, age:7, hobby:“beyblading”}, ¬ {name:“Molly”, age:5, hobby:“beyblading”}} set nameList to {} repeat with x in childNames set end of nameList to name of x end repeat
Here, a list made up of three records has been set up. Each record contains information about a different person. Since the records are stored in a list, it is possible to loop through each record and extract data. In the case of this example, a list of names was generated. Although this example is rather small, the real power of working with lists and records occurs as the amount of information stored in records grows and as the number of records stored in the list grows. For example, a company’s list of customer information might include names, addresses, phone numbers, email addresses, and so on and might consist of hundreds of records, each representing a different customer. By organizing customer records into a list and then processing them via a loop, you can quickly extract and process any of the data that you have stored.
BACK TO ALEXANDER’S TALL TALE Now it is time to begin the development of Alexander’s Tall Tale. The primary point of focus for this game is on the application of string manipulation techniques, including concatenation, continuation, and the generation of random paragraph selections. You will also want to pay close attention to the manner in which new controls are managed and how the say command is used. Alexander’s Tall Tale will be created in five steps. 1. Use Xcode to create a new AppleScript Studio application named Alexander’s Tall Tale. 2. Use the Interface Builder to design the application GUI. 3. Configure the game’s menu, window, and interface control attributes and then set up connections to event handlers. 4. Add the script statements required to make the application work. 5. Compile and test the application.
Chapter 6 • Working with Strings, Lists, and Records
187
Step 1: Creating a New Project Start Xcode if it is not already running and create a new AppleScript Studio project using the procedure outlined here. 1. Click on the File menu and select New Project. An Assistant is launched, displaying a list of application templates. 2. Select AppleScript Application template and click on Next. 3. When prompted, specify Alexander’s Tall Tale as the file name for the application and select the location where you want to store the game. 4. Click on the Finish button.
Step 2: Creating the User Interface The next step in the development of Alexander’s Tall Tale is to put together its graphical user interface, as outlined in the following procedure. 1. Locate the MainMenu.nib file located in the Resources group. Double-click on it to start the Interface Builder. 2. Drag and drop an instance of the text view control on to the application’s window and then resize the text view control so that it takes up almost all of the window, except for two-thirds of an inch at the bottom of the window, as demonstrated in Figure 6.9.
FIGURE 6.9 Most of the game’s user interface is taken up by the text view control.
3. Drag and drop an instance of a button control onto the lower left-hand portion of the application’s window. Align it with the left-hand side of the text view control.
188
AppleScript Studio Programming for the Absolute Beginner
4. Drag and drop an instance of the popup button control onto the lower right-hand side of the application’s window and align it with the right-hand side of the text view control. 5. Finally, drag and drop an instance of the switch (checkbox) control onto the application’s window, placing it just to the right of the popup button control, as demonstrated in Figure 6.10.
FIGURE 6.10 At this point, all of the game’s interface controls should be in place.
Okay, at this point the user interface for Alexander’s Tall Tale is now complete. The next step in the development of this game is the customization of its application menus, window, and interface controls.
Step 3: Customizing Control Properties Now that the overall construction of the user interface is complete, let’s begin work on configuring the application’s menus, window, and interface control attributes as outlined in the next three sections.
Menu Customization In order to customize the application’s menu system, you must remove a number of unnecessary menus and menu items. Start by deleting the Edit and Help menu by selecting them and pressing the Delete key. Delete all of the menu items located on the Window menu except for the Minimize menu item. Next, select the File menu and remove everything but the Close menu item. Lastly, customize the Application menu as outlined here.
Chapter 6 • Working with Strings, Lists, and Records
189
1. Double-click on the Application menu and replace its name with Alexander’s Tall Tale. 2. Modify the About Application menu item to read About Alexander’s Tall Tale. 3. Modify the Hide Application menu item to read Hide Alexander’s Tall Tale. 4. Modify the Quit Application menu item to read Q uit Alexander’s Tall Tale.
Modifying Window and Control Attributes In order to complete the development of Alexander’s Tall Tale, a number of modifications need to be made to the game’s window and its interface controls. These modifications are outlined in Table 6.5 and must be made from the Inspector window’s AppleScript and Attribute views.
TABLE 6.5
MODIFICATIONS TO THE APPLICATION WINDOW INTERFACE CONTROLS
Object
Attribute
Modification
Window
Name Window Title Zoom Name Editable Selectable Name Title Title Name
main Alexander’s Tall Tale Disabled textViewForStory Disabled Disabled scrollViewForStory Tell Story Talk computerVoices
Text View
Button Switch Popup Button
AND
Note that Table 6.5 contains two name entries for the text view control. The first entry represents the text area or text view portion of the text view control that accepts and displays text. To access it and configure its attributes, select the text view control, open the Inspector window, and then double-click on the text view control. You can now assign a name of textViewForStory to this portion of the control. The text view portion of the text view control is accessed and addressed separately from the scroll view portion, which represents the area of the control that does not accept and display text, including its scroll bar. To assign the required name to the scroll view portion of this control, with the Inspector window still open, click on a different area in the window in order to remove the focus from the text view control and then single-click on the text view control
190
AppleScript Studio Programming for the Absolute Beginner
again. You can now assign a name of scrollViewForStory to the scroll view portion of the control. As you will see later, in the code portion of the application, you must be able to distinguish between and refer to each of these two components separately. In order to finish the development of the game’s user interface, you need to populate the popup button control with a list of three voices, each of which represents a different voice supported by the Mac OS X voice synthesizer. To add these three entries, double-click on the popup button control. When you do so, a list of three default items for the control is displayed. Double-click on the first entry and type Vicki. Double-click on the second entry and type Victoria. Double-click on the third entry and type G ood News. TRI
CK
FIGURE 6.11 Testing Mac OS X’s built-in voice synthesizer.
Mac OS X comes fully equipped with a built-in voice synthesizer, which you can easily incorporate into your AppleScript Studio applications, as demonstrated through the creation of Alexander’s Tall Tale. To experiment with Mac OS X’s voice synthesizer, click on the Apple menu and select System Preferences. This displays the System Preferences window from which you can double-click on the Speech icon to view the Speech window shown in Figure 6.11.
Chapter 6 • Working with Strings, Lists, and Records
191
To view and select from the list of available built-in voices, click on the System Voice popup button and make a selection from the list of available choices. To listen to the sound of the selected voice, click on the Play button. You can expand the list of voices available in Alexander’s Tall Tale by adding any of the voice names listed in the System Voice popup control.
Setting Up Event Handler Connections Alexander’s Tall Tale only requires that you configure its one button control’s click event in order to set up its on clicked event handler (from the AppleScript view in the Inspector window). Once you have completed this task, you can move on to the next section and begin the code development portion of the application.
Step 4: Adding a Little Program Code It is time to add the code to enable the proper execution of Alexander’s Tall Tale. As you add the code statements outlined in the sections that follow, pay extra attention to the statements that interface with and control the text view control. Also, take note of the manner in which the AppleScript checks on the status of the switch control and determines the currently selected value for the popup button control. Assuming that you have already set up the game’s button control to react when clicked, the following code statements should be visible in your application’s AppleScript file. -- Alexander's Tall Tale.applescript -- Alexander's Tall Tale -- Created by Jerry Ford on 8/8/06. -- Copyright 2006 - Jerry Lee Ford, Jr. All rights reserved. on clicked theObject end clicked
All of the code required by this application will be written inside the on clicked event handler. For openers, add the following code statements inside the on clicked event handler. --Define a variable made up of a string made up of three paragraphs set lineOne to “bravest person in the world fastest man in all the land the most skilled soldier to ever live”
192
AppleScript Studio Programming for the Absolute Beginner
As you can see, a comment precedes the declaration of a variable named lineOne, which is made up of three separate paragraphs. I have separated each paragraph by pressing the Return key. Later in the script, you will add the programming logic required to randomly select one of these three paragraphs in order to supply a string that will be plugged into the game’s main storyline. In total, the game has four storyline plug-ins, thus giving the story a small element of unpredictability. To define the remaining plug-ins, add the following code statements to the end of the on clicked event handler. --Define a variable made up of a string made up of three paragraphs set lineTwo to “overrun and destroyed captured and imprisoned slaughtered like sheep” --Define a variable made up of a string made up of three paragraphs set lineThree to “slain over twenty enemy solders slaughtered a hundred enemy warriors wiped out most of the enemy's forces” --Define a variable made up of a string made up of three paragraphs set lineFour to “stopped fighting and laid down their weapons disappeared in a puff of smoke turned into stone statues”
Next you need to add the program logic required to make random paragraph selections from each of the preceding variables. This is accomplished by adding the following statements to the end of the on clicked event handler. --Randomly select a paragraph from each of the following variables set reputation to some paragraph of lineOne set armyStatus to some paragraph of lineTwo set fightResults to some paragraph of lineThree set soldierStatus to some paragraph of lineFour
As you can see, one statement has been written for each variable to be processed. In this first statement, a variable named reputation is randomly assigned a string value by extracting one of the paragraphs that make up the lineOne variable. Note the use of the some keyword, which is responsible for making the random selection. some is an AppleScript element specifier that provides the ability to make a random selection of a character, word, or paragraph string element.
Chapter 6 • Working with Strings, Lists, and Records
193
Next, you need to lay out the text for the game’s storyline. This is accomplished by adding the following statements to the end of the on clicked event handler. --Define a variable and assign it a string containing the story --Insert randomly generated variable values into the story set storyText to “Once upon a time there was a young man ” & ¬ “named Alexander the Great. Alexander was known far ” & ¬ “and wide as the ” & reputation & “. Whenever ” & ¬ “there was any trouble, the king always called upon ” & ¬ “Alexander to come to his rescue.\n\nOne day, not ” & ¬ “long ago a great army from the east attacked the outer ” & ¬ “regions of the kingdom. The king sent all his armies out ” & ¬ “to fight this mysterious army but they were quickly
” & ¬
armyStatus & “. In desperation, the king ” & ¬ “called upon Alexander to once again save the day. The ” & ¬ “king gave Alexander his best horse and sword and ” & ¬ “sped him on his way. After a hard day's ride, ” & ¬ “Alexander came across the enemy army's encampment. ” & ¬ “Without rest or sleep, Alexander attacked. Within ” & ¬ “hours he had ” & fightResults & “. Alexander fought his ” & ¬ “way to the center of the encampment where he was sure” & ¬ “the enemy leader would be found.\n\nSure enough, as he ” & ¬ “approached the center of the enemy army’s encampment ” & ¬ “he found the tent of the commander of these dark ” & ¬ “forces. Despite the odds, Alexander fought ” & ¬ “his way up to the front of the tent.\n\nSuddenly, ” & ¬ “a loud and commanding voice could be heard ” & ¬ “giving the order to stop fighting. To his astonishment ” & ¬ “the soldiers that stood between Alexander ” & ¬ “the tent ” & soldierStatus & “.\n\n” & ¬ “\”I see that the king has finally “ & ¬ “sent someone worthy out to meet me\”, said a voice ” & ¬ “from inside the tent. \"Please, come in\" said the voice. ” & ¬ “Once inside, Alexander finally saw that his ” & ¬ “enemy was none other than......\n\nTO BE CONTINUED.”
As you can see, a variable named storyText has been defined and assigned a string that contains the game’s story text. Note that four variables have been embedded within the assigned string, representing four randomly selected strings generated earlier in the script.
194
AppleScript Studio Programming for the Absolute Beginner
The last bit of code needed to finish up the game is provided below. Add the code statements to the end of the on clicked event handler. tell window “main” --Send all commands to the application’s window --Display the story text inside the text view control set contents of text view ¬ “textViewForStory” of scroll view “scrollViewForStory” to storyText --Perform the following tasks if the player elects to listen --to the story if state of button “chkTalk” is 1 then --Allow the player to select a voice from the popup menu set voice to (the title of popup button “computerVoices”) as string --tell the story using the operating system built-in voice synthesizer say storyText using voice end if end tell
The opening tell statement directs all Apple event messages back to the application’s main window. Next, the game’s storyline, as stored within the storyText variable, is displayed inside the application’s text view control. Note that in order to properly target the text view control, you first have to point to the text view (textViewForStory) and then to the scroll view (scrollViewForStory). The rest of the code just shown consists of an if statement code block that is responsible for determining whether to call upon the Mac OS X voice synthesizer using the say comment. This decision is made by checking the value of the switch control named chkTalk. By default, this control is not selected. In order to have the story read aloud, the user must select this control. If selected, the evaluation of the control returns a value of 1. If this is the case, the next statement checks the Title attribute of the popup button control to see which voice the user has selected. This selection is assigned to a variable named voice, which is then used by the say command that follows in order to specify the voice for the Mac OS X voice synthesizer to use when reading the story.
Chapter 6 • Working with Strings, Lists, and Records
195
Step 5: Testing the Execution of Alexander’s Tall Tale Game The development of Alexander’s Tall Tale is now complete. Assuming that you carefully followed each step in the development of this game and that you did not make any typos when keying in the required program code, everything should work as advertised. Go ahead and click on Xcode’s Build and Go button and see what happens. If you receive any errors, use the error information provided to track down and fix them.
SUMMARY In this chapter you learned how to work with a number of interface controls, including the text view, switch, and the popup button controls. You also learned how to make your AppleScript Studio applications talk using the say command to play back text using the many voices supported by the Mac OS X voice synthesizer. This chapter showed you how to work with and manipulate strings and how to store and access collections of data using lists and records. As a wrap up, you developed the Alexander’s Tall Tale game. Before you move on to Chapter 7, “Organizing Scripts with Handlers,” I suggest you take a few extra minutes to enhance Alexander’s Tall Tale by implementing the following list of challenges.
CHALLENGES 1.
2.
3.
As currently written, Alexander’s Tall Tale does not have an ending. Why not finish up the story by adding your own epic ending? As you have already seen, Mac OS X supports over 20 different voices. Enhance the game by giving the player additional voices to choose from. Make the story even more dynamic by introducing additional random paragraph insertions into the story.
This page intentionally left blank
7
C H A P T E R
ORGANIZING SCRIPTS WITH HANDLERS n previous chapters you learned how to store data in variables, lists, and records. You also learned how to apply conditional logic and create loops. In this chapter you will learn how to reorganize your AppleScripts using custom handlers in order to help make them more modular. This will help to improve the overall organization of your AppleScript files and make them easier to read and understand. Another benefit of custom handlers is the ability to create reusable code that can be called upon and executed over and over again from different parts of the script, thus reducing the overall size of your applications while creating more maintainable code.
I
Specifically, you will learn how to • Create custom handlers • Set up handlers that accept and process arguments • Create handlers that return results to calling statements • Distinguish between local and global variable scope
198
AppleScript Studio Programming for the Absolute Beginner
PROJECT PREVIEW: THE ROCK, PAPER, SCISSORS GAME This chapter’s game project is the Rock, Paper, Scissors game. It is based on the classic children’s game in which two players attempt to outguess each other based on the following rules. • Rock crushes scissors to win • Paper covers rock to win • Scissors cut paper to win • Matching moves result in a tie In this implementation of Rock, Paper, Scissors, the player competes against the computer. Figure 7.1 shows how the Rock, Paper, Scissors game looks when first started.
FIGURE 7.1 Game play occurs when the player clicks on the Play button.
The player makes moves by selecting one of the items listed in the popup button control, as demonstrated in Figure 7.2. At the end of each round of play, graphic images are displayed representing the player’s and the computer’s moves, as demonstrated in Figure 7.3.
Chapter 7 • Organizing Scripts with Handlers
199
FIGURE 7.2 After selecting a move, the player clicks on Play to view the computer’s move and the results of the game.
FIGURE 7.3 The results of each round of play are summarized in the text field control located in the bottom righthand corner of the game window.
As game play continues, statistics are accumulated and displayed, showing the number of games that the player has won, lost, and tied, as demonstrated in Figure 7.4.
200
AppleScript Studio Programming for the Absolute Beginner
FIGURE 7.4 The game keeps track of player wins, losses, and ties.
WORKING WITH EVENT HANDLERS Up to this point in the book, all of the program code that you have written has been organized inside event handlers located in AppleScript files. A handler is a subroutine defined within a script file. Using event handlers, you have been able to build your script files in a modular fashion. For example, in Chapter 5, “Applying Conditional Logic and Building Loops,” the Guess a Number game was made up of two event handler, on clicked and on action. This allowed you to separate and organize script statements separately for each event handler. The problem with relying on event handlers as the primary means of modularizing your AppleScript code is that scripts sometimes consist of a great deal of code but only a limited number of event handlers. For example, in Chapter 6, “Workings with Strings, Lists, and Records,” the Alexander’s Tall Tale game consisted of a single on clicked event handler. Developing your AppleScripts in a modular fashion has numerous benefits. For starters, in addition to helping improve the overall organization of your scripts, modular code helps make scripts easier to read and maintain by separating the logic used to perform discrete tasks into separate areas. Handlers also facilitate code reuse, allowing you to execute all the code located in a given handler by simply calling upon it. While you can rely exclusively on event handlers as a means of developing modular code, I recommend against it. To be truly modular, you need to break down your code statements into even tighter groupings. Fortunately, to help you achieve this goal, AppleScript allows you to develop your own custom handlers.
Chapter 7 • Organizing Scripts with Handlers
HIN
T
201
If you have worked with other programming languages, you can equate the term handler with the term function.
Creating Custom Event Handlers The most commonly used event handler that you have worked with in this book is the on clicked handler as shown below. on clicked (*Add your script here.*) end clicked
This event handler has been automatically created for you each time you have used the Inspector window to connect a button control to your application’s AppleScript file. To finish off the development of event handlers, you have entered the appropriate code statements inside the on clicked handler’s opening and closing statements. You can create your own custom handlers in your AppleScripts using the syntax shown here. on handlername() statements end handlername
Like event handlers, custom handlers begin with the on keyword followed by the name assigned to the handler. Custom handlers end with the implementation keyword followed by the name of the handler. In between these two statements you place any statements that you want executed as part of the handler. Note the presence of the () characters on the handler’s opening statement. These parentheses are required and are used to define one or more optional, comma-separated parameters representing values passed to the handler for processing.
Defining and Calling Handlers As an example of a small custom handler, consider the following example. on DisplayGreetingMsg() display dialog "Hello World!" end DisplayGreetingMsg
Here a handler named DisplayGreetingMsg() has been defined. The handler does not accept any arguments nor does it return an explicit result.
202
AppleScript Studio Programming for the Absolute Beginner
HIN
T
You can place customer handlers anywhere you want within your AppleScripts (but not inside event handlers). However, I recommend grouping them all together at the beginning or end of the script file. This will make your custom handlers easier to find and maintain.
Merely adding a handler to an AppleScript file does not make it execute. To execute, a handler must be explicitly called, which you can do by typing its name and any required arguments using the syntax outlined here. handlername()
As you can see, there is not much to it. For example, to execute a custom handler named DisplayGreetingMsg(), you would type the following somewhere in your script file. DisplayGreeting Name()
Some handlers return a result back to the statements that call them when they are done executing. To capture the value returned by the handler, you use the set command to assign the value to a variable using the syntax outlined here. set variablename to handlername()
Here, variablename is the name of the variable used to store the value returned by the handler.
Passing Arguments to Handlers One feature of handlers is the ability to accept data passed to them as arguments. This is accomplished by defining parameters within the parentheses at the beginning of the handler definition, as demonstrated here. on AddNumbers(x, y) set z to x + y display dialog z end AddNumbers
In this example, a custom handler named AddNumbers() has set up that adds together two arguments passed to it. It does so by defining two parameters, x and y. AppleScript automatically assigns the first argument passed to the handler to the temporary variable named x. Likewise, AppleScript assigns the second argument passed to the handler to the temporary variable named y. Once arguments have been mapped to parameters and temporary variables are assigned, the statements inside the handler are executed. Note the temporary variables x and y are local to the handler and exist only for as long as the handler executes.
Chapter 7 • Organizing Scripts with Handlers
203
Whenever you pass arguments to a handler, you need to be aware of the number of arguments that the handler requires. If, for example you create a handler that expects to receive two arguments, and later in your script you call that handler, passing it too few or too many arguments, an error will occur. TR
AP
You can pass any type of data as an argument into an event handler. AppleScript does not allow you to declare, much less enforce, the type of data a handler can receive. Therefore, it is up to you to validate the type of data passed to your handlers and to react to it accordingly. For example, in some circumstances you may be able to convert it from one data type to another using the as operator. In other cases you may want to reject it and terminate the execution of your application with an error message. Of course, you might also substitute a default value. Regardless of how you choose to proceed, you can check on the data type of any value using the class command, as was discussed in Chapter 4, “Working with Values, Variables, and Classes.” As a reminder of how to work with the class command and how this command might be applied within the context of validating handler arguments, consider the following example. on DoTheMath(x) if class of x is integer or class of x is real then return x + 1 else return 0 end if end DoTheMath
Here, the handler expects to receive a number of some type. Therefore a check is made to ensure that the argument passed to the handler is either an integer or a real number. If it is, the value of the argument is increased by one and then returned back to the calling statement. If the argument is not an integer or a real number, a default value of zero is returned instead.
By default, when you pass a variable to a handler, the variable is passed by value. What this means is that a copy of the variable is passed to the handler. This way, if the handler does something that changes its value, the change in value is reflected only in the handler’s copy of the data and not in the rest of the script. However, if you pass a list or a record to a handler, the list or record is passed by reference, meaning that any changes to the data within the handler are made directly to the list or record that was passed. Thus, a change to a list or record passed as a parameter will be reflected both inside the custom handler as well as outside of it. Because of this default behavior, you must be careful when passing lists and records as argument to handlers. One way to prevent handlers from making changes to lists
204
AppleScript Studio Programming for the Absolute Beginner
and records received as arguments is to make a copy of the list or record that is passed and then to work with the copy instead of the original, as demonstrated by the following. on AddNumbers(x) set y to x statements end AddNumbers AddNumbers{1, 2, 3}
In this example, a custom handler named AddNumber() has been defined. It accepts a single argument (a list of numbers). The first statement inside the handler makes a copy of the list passed to it as an argument. Any statements that follow inside the customer handler should then refer to y and not to x. As a result of this simple modification to the handler, any changes made to the list within the handler are not reflected to the list outside the handler, since the value of x was never modified.
Returning a Result from an Event Handler In addition to accepting arguments and mapping them to parameters for processing within the handler, a custom handler can also be set up to return a result back to the statement that calls it. There are two ways that a custom handler can return a value to a calling statement, implicitly and explicitly.
Implicitly Returning a Result from a Handler To return a value implicitly, you do not have to do anything. AppleScript will automatically return the value of the last expression executed within the handler. For example, consider the following statements. on IncrementNumber(x) set x to x + 1 end IncrementNumber set x to IncrementNumber(5)
In this example, a handler name IncrementNumber() is called and passed a value of 5. The handler then increments the value of x by 1 and ends, returning control back to the statement that called it. In addition, a value of 6 is returned to the calling statement, which is then assigned to a variable named x.
Chapter 7 • Organizing Scripts with Handlers
HIN
T
205
If you are going to develop a handler that returns a result back to calling statements, I recommend against implicitly returning a value. Doing so results in code that is more difficult to read and understand. Instead, I strongly recommend that you explicitly return results from your handlers, as outlined in the next section.
Explicitly Returning a Result from a Handler In order to explicitly return a result from a custom handler, you must use the return command, as demonstrated here. on IncrementNumber(x) set x to x + 1 return x end IncrementNumber set x to IncrementNumber(5)
The return command accepts a single parameter, the value to be returned to the calling statement. Note that you can use the return command to pass back a number or a string to a calling statement. In addition, you can also return lists and records, thus sending back collections of values.
UNDERSTANDING SCOPE One important concept that you need to understand about working with handlers involves variable scope. The term scope refers to the location in a script where a variable can be seen and accessed. Variable scope varies, depending on how and where variables are declared.
Local Scope By default, any variables declared inside of an event handler are local in scope. A local variable is one that can only be accessed within its current scope. Therefore, a variable that is local to a handler cannot be accessed from outside that handler. If you want, you can explicitly declare a variable as local using the local keyword, as demonstrated by the following. local x
Here, a variable named x has been declared as a local variable. Of course, before it can be used, you must assign a value to the variable, as demonstrated here.
206
AppleScript Studio Programming for the Absolute Beginner
local x set x to 10 HIN
T
Variables declared within code block, such as inside an if statement or a repeat statement code block are local in scope to those code blocks. As such, can you further refine a variable’s scope and limit access to it.
As an example of the localization of variables within a handler, consider the following statements. on handlerOne() set x to 1 end handlerOne on handlerTwo() set y to x end handlerTwo handlerOne() handlerTwo()
In this example, two handlers have been defined. The first handler declares a local variable named x and assigns it a value of 1. The second handler, when called, attempts to assign the value of x to a variable named y. The last two statements call each handler. When executed, this example results in an error because variable x is not accessible to the second handler. Because a variable declared within a handler is, by default, local to its handler, you can assign any variable name you want, even if that variable name has been used elsewhere in the script. However, as a general rule you should avoid overdoing the reuse of variable names inside your handlers, except in situations where it is explicitly clear what is going on.
Global Scope By default, any variable that is declared outside of an event handler is considered to be a global variable. However, a handler cannot access any variables declared outside of it unless these variables have first been declared using the global keyword, as demonstrated here. global x
By declaring a variable in this manner and then assigning a value to it, the variable becomes accessible to handlers throughout the script, as demonstrated here.
Chapter 7 • Organizing Scripts with Handlers
207
global x set x to 1 on myHandler() set x to x + 1 return x end handler set y to myHandler()
Here, a variable is declared as a global variable and assigned a value of 1. The variable x has been defined outside of any handlers. As such, it can be accessed from within any handler in the script. In an interesting twist on things, AppleScript allows you to declare a variable global within the handler that wants to access it, as demonstrated by the following. set x to 1 on myHandler() global x set x to x + 1 return x end handler set y to myHandler()
As you can see, the variable is still declared and assigned an initial value outside of any event handler. However, it is not until later, in the myHandler() handler, that the variable x is declared global. Personally, I recommend against declaring variables as global in this manner and suggest that you declare them global when they are first defined. This will help make your code more intuitive and easier to follow along. TR
AP
As a somewhat confusing twist on the previous discussion regarding the accessibility of global variables from within handlers, consider the following example. on handlerOne() set x to 1 end handlerOne on handlerTwo() set y to x
208
AppleScript Studio Programming for the Absolute Beginner
end handlerTwo handlerOne() handlerTwo()
In this example, a variable named x is declared in a handler as a global variable. However, if you run this example, you will get an error stating that the variable x is undefined when the second handler attempts to access the value of x and assign it to y. To resolve this situation, you might try using the global keyword to explicitly declare x as a global variable in either of the two handlers. Doing so still results in an error. However, if you declare the variable x as global in both handlers, the variable becomes available in both handlers, as demonstrated here. on handlerOne() global x set x to 1 end handlerOne on handlerTwo() global x set y to x end handlerTwo handlerOne() handlerTwo()
BACK TO THE ROCK, PAPER, SCISSORS GAME Let’s turn our attention back to the development of the Rock, Paper, Scissors game. The primary focus of this game is on the use of custom handlers to help organize the AppleScript in a modular and structured manner. Pay special attention to the relationship of code statements that are grouped together into handlers and to the manner in which handlers are executed and data is passed between then. As you work on this game, you will also learn how to work with the combo box control and to change the display of images displayed in image view controls on the fly.
Chapter 7 • Organizing Scripts with Handlers
209
The development of the Rock, Paper, Scissors game will be performed in the following five steps. 1. Use Xcode to create a new AppleScript Studio application named Rock, Paper, Scissors. 2. Design the application’s GUI using Interface Builder. 3. Configure the game’s menu, window, and interface control attributes and then set up connection to event handlers. 4. Add the required AppleScript code statements. 5. Compile and test the application.
Step 1: Creating a New Project Make sure that Xcode has been started and then create a new AppleScript Studio project, as outlined in the following procedure. 1. Click on the File menu and select New Project. An Assistant is launched, displaying a list of application templates. 2. Select AppleScript Application template and click on Next. 3. When prompted, specify Rock, Paper, Scissors as the file name of the application and then specify the location where you want to store this AppleScript Studio application. 4. Click on the Finish Button.
Step 2: Creating the User Interface The next step in the development of the Rock, Paper, Scissors game is to assemble its graphical user interface, as outlined in the following procedure. 1. Locate the MainMenu.nib file located in the Resources group and then double-click on it to start the Interface Builder. 2. Modify the size of the default window so that it is approximately 5 inches wide by 5.5 inches tall. 3. Drag and drop an instance of the image view control to the upper left-hand corner of the game’s window and resize the control so that it is approximately 1.3 inches wide by 1.3 inches tall. This control will be used to depict the computer’s move during game play. 4. Drag and drop another instance of the image view control to the upper right-hand corner of the game’s window and resize the control so that it is approximately 1.3 inches wide by 1.3 inches tall. This control will be used to depict the player’s move during game play. 5. Add an instance of the mini system font text control beneath the left-most image view control and double-click on it. Enter Computer’s Move as its Title attribute.
210
AppleScript Studio Programming for the Absolute Beginner
6. Add an instance of the mini system font text control beneath the right-most image view control and double-click on it. Enter Player’s Move as its Title attribute. 7. Drag and drop an instance of the combo box control onto the window and place it about an inch below the left-most image view control. 8. Add an instance of the mini system font text control just above the combo box control and double-click on it. Enter Select a Move: as its Title attribute. 9. Add an instance of the button control to the right-hand side of the window, directly across from the combo box control. Double-click on the button control and assign Play as its Title attribute. 10. Drag and drop an instance of the vertical box control just under the combo box control and the button control and resize it so that it extends almost the entire width of the game window. 11. Drag and drop three instances of the text field control to the bottom of the game window, stacking them on top of one another. 12. Drag and drop three instances of the mini system font text control to the game window, placing one just to the left of each of the three text field controls. Assign the top-most control a title of Wins:. Assign the middle control a title of Losses: and assign the lower control a title of Ties:. 13. Finally, drag and drop one more text field control onto the game window. Resize it so that it takes up the remaining space in the lower right-hand side of the game window, as demonstrated in Figure 7.5.
FIGURE 7.5 At this point all of the controls that make up the game’s interface are now in place.
Chapter 7 • Organizing Scripts with Handlers
211
Step 3: Customizing Control Properties The overall construction of the game’s user interface is now complete. It is time to configure the application’s menu system and window and control attributes and associate the game’s button control with the on clicked event handler, as outlined in the next several sections.
Menu Customization The first step in customizing the application’s menu system is to remove a number of unnecessary menus and menu items. Start by deleting the Edit and Help menus. Delete all of the menu items located on the Window menu, except for Minimize. Next, select the File menu and remove everything but the Close menu item. Finally, customize the Application menu as outlined here. 1. Double-click on the Application menu and replace its name with Rock, Paper, Scissors. 2. Modify the About Application menu item to read About Rock, Paper, Scissors. 3. Modify the Hide Application menu item to read Hide Rock, Paper, Scissors. 4. Modify the Quit Application menu item to read Q uit Rock, Paper, Scissors.
Interface Window and Control Attributes To finish up the user interface for the Rock, Paper, Scissors game, you must make a number of changes to the game’s window and its interface controls. These changes are outlined in Table 7.1 and must be made from the Inspector window’s AppleScript and Attribute views. Note that to assign the values of Rock, Paper, and Scissors to the combo box control, as listed in Table 7.1, you need to select the control and open the Attributes view of the Inspector window and then modify the Visible Items field by entering a value of 3 . You can then enter the three text entries by typing them one at a time in the text field control at the bottom of the Inspector window and then clicking on the Plus button just to the right of the text field control. If you make a typo when entering one of the entries, select the entry and click on the minus button and add the entry again.
Setting Up Event Handler Connections The Rock, Paper, Scissors game only requires that you configure its button control’s click event in order to set up an on clicked event handler in its AppleScript file (from the AppleScript view in the Inspector window). Once you have completed this task, you are ready to begin adding the code required to make the Rock, Paper, Scissors application work.
212
AppleScript Studio Programming for the Absolute Beginner
TABLE 7.1
MODIFICATIONS TO THE APPLICATION WINDOW INTERFACE CONTROLS
Object
Attribute
Modification
Window
Name Window Title Zoom Name Name Name Visible items
main Rock, Paper, Scissors Disabled imvComputer imvPlayer cbxMoves 3 Rock Paper Scissors Play Tink txtWins 0 Enabled Disabled Disabled txtLosses 0 Enabled Disabled Disabled txtTies 0 Enabled Disabled Disabled txtStats Enabled Word Wrap Disabled Disabled
Image View Image View ComboBox
Button Text View
Text View
Text View
Text View
Title Sound Name Title Rounded Editable Selectable Name Title Rounded Editable Selectable Name Title Rounded Editable Selectable Name Wraps Line Breaking Editable Selectable
AND
Step 4: Adding a Little Programming Logic Okay, let’s get to work on the code portion of the Rock, Paper, Scissors game. Assuming that you have already set up the clicked event for the game’s button control, the game’s AppleScript file should already contain code statements similar to those outlined here.
Chapter 7 • Organizing Scripts with Handlers
213
-- Rock-Paper-Scissors.applescript -- Rock-Paper-Scissors --
Created by Jerry Ford on 8/8/06.
--
Copyright 2006 - Jerry Lee Ford, Jr. - All rights reserved.
on clicked theObject end clicked
Using the information presented in this chapter regarding the use of custom handlers, the development of this AppleScript will follow a modular design, breaking code statements down into small related groups in order to make the code easier to understand and maintain. In total, six custom handlers will be developed, each designed to perform a specific task. The overall logic that will call upon these custom handlers and execute them is located in the script’s on clicked event handler. All of the remaining code in the script file will be stored in individual handlers and will be called upon to execute from statements located in the on clicked event handler. So, let’s being by adding the following code statements to the on clicked event handler. --Call handler that retrieves the player's move set playerMove to GetPlayerMove() --Call handler that displays a graphic image representing the player's move DisplayPlayerMove(playerMove) --Call handler that retrieves a random number set randomNo to GetRandomNo() --Call handler that assigns the computer's move set computerMove to DisplayComputerMove(randomNo) --Call handler that determines whether the player or computer won set {message, gameResult} to AnalyzeResults(playerMove, computerMove) --Call handler that displays the results DisplayStats(message, gameResult)
214
AppleScript Studio Programming for the Absolute Beginner
As you can see, the on clicked event handler contains six code statements, along with accompanying comments. The first statement executes the GetPlayerMove() handler. This handler is responsible for collecting the player’s move each time a new round is played. The move chosen by the player, as specified using the game’s combo box control, is stored in a variable named playerMove. Next, the DisplayPlayerMove() handler is executed. This handler is responsible for displaying a graphic image that reflects the player’s move (e.g., a picture of a rock, a piece of paper, or a pair of scissors). Note that the playerMove variable is passed as an argument to the handler. Next, the game retrieves a random number between 1 and 3. This is accomplished by calling the GetRandomNo() handler. When done, the GetRandomNo() handler returns a value, which is stored in a variable name randomNo. Next, the variable containing the randomly generated number is passed to the DisplayComputerMove() handler, which is responsible for displaying a graphic image that reflects the computer’s move. Next, the AnalyzeResults() handler is called and passed two variables, playerMove and computerMove. Statements located in this handler are responsible for determining whether the player or the computer has won the current round of play. When done, the AnalyzeResults() handler returns a list made up of two elements: a message string and a string specifying whether the player has won, lost, or tied. The last statement shown above calls upon the DisplayStats() handler, passing it the string returned by the previous handler. The DisplayStats() handler uses these two strings to update the display of the status information displayed at the bottom of the game window. At this point, you have laid out statements that control the overall execution of the game. All that remains is to develop the code statements that make up each of the custom handlers. Remember, each of these handlers must be manually added to the script file, outside of the on clicked event handler. I recommend adding them to the end of the script file, in the order presented here.
Creating the GetPlayerMove Handler The code for the GetPlayerMove() handler is outlined below. The first statement uses the tell command to set the game’s window as the target for all commands. Next, a set statement is used to assign a value to a variable named playerMove. This value is assigned by retrieving the contents of the combo box control named cbxMoves. The value assigned to the playerMove variable is then returned to the statement that called this handler. --This handler returns a value representing the player's move on GetPlayerMove()
Chapter 7 • Organizing Scripts with Handlers
215
tell window "main" --Target the window named main --Retrieve the player's move by checking the currently selected --item in the combo box control set playerMove to contents of combo box "cbxMoves" return playerMove --Return the player's move end tell end GetPlayerMove HIN
T
Note that the playerMove variable used in the GetPlayerMove() handler is a local variable and is not the same variable used in the on clicked event handler. Ordinarily, you should not assign variable names to variables inside handlers that match variable names used elsewhere in your AppleScripts. However, I use the same variable name in this example in order to demonstrate the point that two different variables with the same name can be used.
Creating the DisplayPlayerMove Handler The code for the DisplayPlayerMove() handler is outlined next. The first statement uses the tell command to set the game’s window as the target for all commands. Next, a series of three if statement code blocks are executed in order to determine which graphic image should be displayed in the image view control named imvPlayer. This is achieved by comparing a string passed to the handler as an argument to strings of Rock, Paper, and Scissors. --This handler displays a graphic image representing the player's move on DisplayPlayerMove(playerMove) tell window "main" --Target the window named main if playerMove = "Rock" then -- Player selected rock -- Display an image of a rock set image of image view "imvPlayer" to load image "Rock.bmp" end if if playerMove = "Paper" then -- Player selected paper -- Display an image of a piece of paper set image of image view "imvPlayer" to load image "Paper.bmp" end if
216
AppleScript Studio Programming for the Absolute Beginner
if playerMove = "Scissors" then -- Player selected scissors -- Display an image of a pair of scissors set image of image view "imvPlayer" to load image "Scissors.bmp" end if end tell end DisplayPlayerMove
Once a match is found, a graphic image is displayed in the imvPlayer control using the set command by setting the image view control’s image attribute (in order to load the appropriate bitmap file). HIN
T
You will find copies of the rock, paper, and scissors bitmap images on this book’s companion website (www.courseptr.com/downloads). To add them to your application, drag and drop them into the Resources group located in the Xcode Editor’s Groups & Files pane. You can then drag and drop copies of the bitmap files from the Resources group onto the Images view of the Interface Builder’s MainMenu.nib window, thus making them available to your application when needed.
Creating the GetRandomNo Handler The code for the GetRandomNo() handler is outlined next. This handler consists of two statements. The first statement generates a random number between 1 and 3 and assigns it to a variable named randomNo. Note that the as operator has been added to the end of the first statement in order to coerce the value generated into an integer. The second statement returns the randomly generated number back to the statement that called the handler. --This handler retrieves a random number on GetRandomNo() set randomNo to random number from 1 to 3 as integer -- Range is 1 - 3 return randomNo -- Pass the number back to the calling statement end GetRandomNo
Creating the DisplayComputerMove Handler The code for the DisplayComputerMove() handler is outlined next. The first statement uses the tell command to set the game’s window as the target for all commands. Next, a series of if statement code blocks have been defined in order to determine which move should be
Chapter 7 • Organizing Scripts with Handlers
217
assigned to the computer. For example, if the number passed to the handler is equal to 1, then the computer is assigned a move of rock. A value of 2 equates to a move of paper, and a value of 3 equates to a move of scissors. A string representing the move assigned to the computer is then assigned to a variable named computerMove, and a set statement is used to display a graphic file in the image view control representing the player’s move. The handler ends by returning the value of the computerMove variable back to the statement that called it. --This handler displays a graphic image representing the computer's move on DisplayComputerMove(randomNo) tell window "main" --Target the window named main if randomNo = 1 then -- The number 1 equates to a move of rock set computerMove to "rock" -- Assign the computer's move -- Display an image of a rock set image of image view "imvComputer" to load image "Rock.bmp" end if if randomNo = 2 then -- The number 2 equates to a move of paper set computerMove to "paper" -- Assign the computer's move -- Display an image of a piece of paper set image of image view "imvComputer" to load image "Paper.bmp" end if if randomNo = 3 then -- The number 3 equates to a move of scissors set computerMove to "scissors" -- Assign the computer's move -- Display an image of a pair of scissors set image of image view "imvComputer" to load image "Scissors.bmp" end if -- Pass the computer's move back to the calling statement return computerMove end tell end DisplayComputerMove
218
AppleScript Studio Programming for the Absolute Beginner
Creating the AnalyzeResults Handler The code for the AnalyzeResults() handler is outlined next. A series of if statement code blocks is used to determine whether the player or the computer won the current round of play. By comparing the player’s and the computer’s moves, passed to the handler as arguments, to string values of "Rock", "Paper", and "Scissors", the handler determines who won the game. A string representing the results of the game is then assigned to a variable named gameResult, and a variable named message is assigned a string that provides an explanation of the game results. These two variables are returned back to the calling statement in the form of a list. --This handler determines whether the player or the computer won on AnalyzeResults(playerMove, computerMove) --Compare the computer's move to the player's move when the player has --selected Rock if playerMove = "Rock" then if computerMove = "Rock" then set gameResult to "tie" set message to "Rock equals rock: You tie!" end if if computerMove = "Paper" then set gameResult to "lose" set message to "Paper covers rock: You lose!" end if if computerMove = "Scissors" then set gameResult to "win" set message to "Rock breaks scissors: You win!" end if end if --Compare the computer's move to the player's move when the player has --selected Paper if playerMove = "Paper" then if computerMove = "Rock" then set gameResult to "win" set message to "Paper covers rock: You win!" end if if computerMove = "Paper" then
Chapter 7 • Organizing Scripts with Handlers
219
set gameResult to "tie" set message to "Paper equals paper: you tie!" end if if computerMove = "Scissors" then set gameResult to "lose" set message to "Scissors cut paper: You lose!" end if end if --Compare the computer's move to the player's move when the player has --selected Scissors if playerMove = "Scissors" then if computerMove = "Rock" then set gameResult to "lose" set message to "Rock breaks scissors: You lose!" end if if computerMove = "Paper" then set gameResult to "win" set message to "Scissors cut paper: You win!" end if if computerMove = "Scissors" then set gameResult to "tie" set message to "Scissors equals scissors: You tie!" end if end if return {message, gameResult} end AnalyzeResults
Creating the DisplayStats Handler The code for the DisplayStats() handler is outlined next. Note that the handler has been set up to process two strings passed to it as arguments. The first string contains a value representing the result of the last round of play (win, loss, or tie), and the second string contains text explaining the game’s result. The first statement uses the tell command to set the game’s window as the target for all commands. Next, a series of three if statement code blocks is defined in order to determine which text field control to update. For example, if result equals win, then the value stored in
220
AppleScript Studio Programming for the Absolute Beginner
the txtWins text field control is incremented by 1. Similarly, the values stored in the txtLosses and txtTies text field controls are incremented when appropriate. --This handler updates and displays game statistics on DisplayStats(msg, result) tell window "main" --Target the window named main set contents of text field "txtStats" to msg --Post game results --Increment the number of games won if the player won if result = "win" then set contents of text field "txtWins" to ¬ (contents of text field "txtWins") + 1 end if --Increment the number of games lost if the player lost if result = "lose" then set contents of text field "txtLosses" to ¬ (contents of text field "txtLosses") + 1 end if --Increment the number of games tied if a tie occurred if result = "tie" then set contents of text field "txtTies" to ¬ (contents of text field "txtTies") + 1 end if end tell end DisplayStats
Step 5: Testing the Execution of the Rock, Paper, Scissors Game The development of the Rock, Paper, Scissors game is now complete. As long as you did not make any typos and you carefully followed each step outlined in the previous sections, the game should be ready to test. Click Xcode’s Build and Go button and see what happens. If an error is reported, use the error information provided to track down and fix it.
Chapter 7 • Organizing Scripts with Handlers
221
SUMMARY In this chapter you learned how to create custom handlers. This included learning how to develop handlers that can accept and process arguments as well as return a result back to calling statements. You also learned how to use handlers to make your code more modular. By using custom handlers, you can create AppleScripts that are easier to read and understand. In addition, using handlers helps make your AppleScripts more manageable and provides you with the ability to facilitate code reuse. Custom handlers will not only allow you to reduce the overall size of your AppleScript files, but it will also help make your script code easier to maintain. Finally, you learned about variable scope and the differences between local and global scope. Before you move on to Chapter 8, “Working with Drives, Files, and Folders,” I suggest that you take a few extra minutes to improve the Rock, Paper, Scissors game by working on the following list of challenges.
CHALLENGES 1.
2.
3.
As currently written, the Rock, Paper, Scissors game provides limited information regarding the results of each game. Consider adding logic that keeps track of the number of games won or lost in a row and reports this information in the txtOutput text field control when appropriate. Consider using the display dialog command to prompt the player to provide his name when the game is first started, and then use this information to customize the information displayed at the end of each game by modifying output messages in order to address the player by name. Even though the Rock, Paper, Scissors game is almost universally known, it is always possible that your may come across someone who does not know the rules of the game. To address this possibility, devise a method for providing the player with access to game instructions. Hint: Consider adding the Help menu back to the application’s menu system and then add an Instructions menu item, so that when clicked, it displays game instructions in a new window.
This page intentionally left blank
Part
III Advanced Topics
Chapter 8
Working with Files and Folders
Chapter 9
Controlling Other Applications
Chapter 10
Debugging and Error Handling
This page intentionally left blank
8
C H A P T E R
WORKING WITH FILES AND FOLDERS ow that you have learned the basics of working with Xcode and the Interface Builder and have completed your review of AppleScript programming, it is time to begin exploring specific tasks that you can accomplish through the development of AppleScript Studio applications. In this chapter, you will learn how to save and retrieve data stored in text files. In addition, using lists and records, you will learn how to create small database applications. On top of all this, you will learn how to create an AppleScript Studio Slot Machine game.
N
Specifically, you will learn how to: • Specify the location of files and folders • Open and close files • Write to and read from files • Create small databases using lists and records
PROJECT PREVIEW: THE SLOT MACHINE GAME This chapter’s game project is the development of a Las Vegas-inspired slot machine, as demonstrated in Figure 8.1.
226
AppleScript Studio Programming for the Absolute Beginner
FIGURE 8.1 Players begin the game with an account balance of $10.
To play, the player must click on the Spin button. To get instructions, the player clicks on the Instructions button. As Figure 8.2 shows, players are awarded $5 for a jackpot and lose $1 when no matching values occur. FIGURE 8.2 Money is automatically added to and removed from the player’s account based on the values generated at the end of each spin.
Possible values include oranges, apples, and cherries, as demonstrated in Figure 8.3. As Figure 8.4 shows, a matching pair is considered a tie, resulting in no addition or reduction of funds from the player’s account.
Chapter 8 • Working with Files and Folders
227
FIGURE 8.3 No matches results in the loss of a dollar.
FIGURE 8.4 A pair of apples is insufficient to receive a payoff.
Figure 8.5 provides an example of a jackpot. In this example, three cherries have been generated, resulting in a $5 award.
228
AppleScript Studio Programming for the Absolute Beginner
FIGURE 8.5 A jackpot occurs any time the player gets three cherries, three apples, or three oranges.
Game play continues as long as the player has a positive account balance. Upon going bust, the game ends and is automatically restarted, as demonstrated in Figure 8.6.
FIGURE 8.6 The player never really loses because the house replenishes her account each time she goes bust.
MAC AND POSIX PATHS Mac OS X is a Unix operating system. However, it was not always that way. Prior to Mac OS X, Mac computers ran a proprietary operating system developed by Apple. As a result of the transition from Mac OS 9 to Mac OS X, a lot of things changed. For example, MAC OS X, as a Unix operating system, now works with Unix-styled POSIX path names. However, MAC OS X still retains its support for Mac-style path names. As a result, you have the option of working with either style of path name when developing AppleScript code for your AppleScript Studio applications. HIN
T
POSIX is a Unix standard that was developed in the 1980s as a means of standardizing the differences in the many version of Unix available at the time.
Chapter 8 • Working with Files and Folders
229
Mac OS X works with both traditional Mac-styled paths as well as POSIX-styled paths. Traditional Mac path names separate drive, folder, and file names using the : character, as demonstrated here. Macintosh HD:Users:Jerry:Documents:Books:AppleScript_Studio.txt TR
AP
You must include a file extension as part of file names when defining paths to your files. Otherwise, you’ll get an error. This can sometimes be confusing because, depending on how you have configured your computer, Mac OS X may be hiding file extensions from view. Fortunately, you can view the file extension for any file that you might want to work with by selecting the file in Finder and then selecting the File menu’s Get Info option.
Macintosh HD is the name of the hard disk of my computer. Users is a standard Mac OS X folder where user home directories are stored. Jerry is the name of my personal directory. Documents is a standard MAC OS X folder created in my directory to store documents. Books is one of several subfolders that I created in my Documents folder to help organize my personal files. Finally, AppleScript_Studio.txt is just one of many text files that I have created and saved. POSIX paths use a slightly different format, substituting the / character for the : character. In addition, an opening / character at the beginning of a path specification represents the root or top-most level of the computer’s file system. For example, the following statement is the POSIX equivalent of the previous Mac-styled path. /Users/Jerry/Documents/Books/AppleScript_Studio.txt
To specify a folder, as opposed to a file, Mac OS X requires that you append a trailing : or / character to the end of the path. The following example references the folder containing the AppleScript_Studio.txt file using a traditional Mac path. Macintosh HD:Users:Jerry:Documents:Books:
Similarly, the following example references the folder containing the AppleScript_Studio.txt files using a POSIX path. /Users/Jerry/Documents/Books/
In practice, path names are generally used as strings enclosed within a pair of matching double quotation marks and are often assigned to variables, as demonstrated here.
230
AppleScript Studio Programming for the Absolute Beginner
set x to "Macintosh HD:Users:Jerry:Documents:Books:AppleScript_Studio.txt"
or set x to "/Users/Jerry/Documents/Books/AppleScript_Studio.txt"
FULL AND RELATIVE PATHS Mac OS X recognizes two types of paths, absolute and relative. An absolute path is one that specifies the full disk and folder structure required to identify the location of a file or folder. Absolute paths begin with a drive specification and include every folder required to reach the specified resource, as demonstrated here. Macintosh HD:Users:Jerry:Documents:Books:AppleScript_Studio.txt
A relative path, on the other hand, specifies the location of a file or folder relative to the current working directory. Unless changed, the current working directory is typically the folder where your AppleScript Studio application resides. For example, suppose I created a folder name AS_Studio in my personal Documents folder. Further, suppose that within the AS_Studio folder I added a file named UserNames.txt. If the script or application that I placed within my AS_Studio folder needed to refer to the UserNames.txt file, it could do so using an absolute path as shown here. Macintosh HD:Users:Jerry:Documents:AS_Studio:UserNames.txt
Or, using a relative path, you could instead refer to it as shown here. UserName.txt
Using an absolute path, you specify the precise location of the text file starting with the disk that stores it. Using a relative path, you specify the location of the text file relative to the current working directory. Since the text file and the application that accesses it reside in the same folder, no path information is needed. Unix operating systems, including Mac OS X, provide you with access to several shortcuts that facilitate working with relative paths. These shortcuts are represented by special characters, as shown in Table 8.1. As an example of how to use the shortcuts, consider the following example. ./Text_Files/UserNames.txt
In this example, the statement specifies a relative path that starts at the current directory (as specified by the . special character) and then specifies the subfolder where the UserName.txt file is stored.
Chapter 8 • Working with Files and Folders
TABLE 8.1
231
POSIX PATH REFERENCE CHARACTERS
Characters
Value
. .. ∼
Represents the current folder or directory Represents the parent folder or directory Represents the current user’s home directory or folder
ESTABLISHING A FILE REFERENCE When you use AppleScript to work with files, you typically do so by identifying the name of the file you want to work with and then setting up a file reference. To do so, you need to work with the file class. Using the file class, you set up an object reference to the specified file. Using this object reference, you can then refer back to the file within your program code whenever necessary, without having to repeatedly specify the name and path of the file. To use the file class to set up a reference to a particular file, you can insert the word file in front of a traditional file path, as demonstrated here. set textFile to file "Macintosh HD:Users:Jerry:Documents:Books:Sample.txt"
In this example, a variable named textFile is defined and used in conjunction with the file class to set up a reference to the Sample.txt file. Alternatively, you could use the POSIX version of this statement, as shown here. set textFile to POSIX file "/Users/Jerry/Documents/Books/Sample.txt"
Many times the files that you want to work with will reside in folders that were created automatically by the operating system. For example, you might want to access a file that is located on your desktop or in your Documents folder. Alternatively, you might want to access a file located in your music folder or in the operating system’s Applications folder. Because these folders and others like them are commonly accessed, AppleScript has defined a collection of arguments that you can use as shortcuts when specifying the location of these folders, rather than going through the trouble of identifying and specifying their actual path. A number of commonly used arguments that you will want to be familiar with are listed in Table 8.2. There are a number of advantages to working with these arguments when specifying the locations of files and folders. For one thing, they will save you time and keystrokes. Fewer keystrokes also means fewer typos and errors. In addition, using these arguments can help you write code that is more flexible and portable. For example, if you wanted to write an
232
AppleScript Studio Programming for the Absolute Beginner
TABLE 8.2
PATH COMMAND ARGUMENTS
Argument
Description
Applications folder Desktop trash startup disk system folder users folder utilities folder documents folder home folder library folder pictures folder movies folder music folder shared documents public folder scripts folder temporary items folder current application
"Macintosh HD:Applications:" "Macintosh HD:Users:username:Desktop:" "Macintosh HD:Users:username:Trash:" "Macintosh HD:" "Macintosh HD:System:" "Macintosh HD:Users:" "Macintosh HD:Applications:Utilities:" "Macintosh HD:Users:username:Documents:" "Macintosh HD:Users:username:" "Macintosh HD:Library:" "Macintosh HD:Users:username:Pictures:" "Macintosh HD:Users:username:Movies:" "Macintosh HD:Users:username:Music:" "Macintosh HD:Shared:" "Macintosh HD:Users:username:Public:" "Macintosh HD:Users:username:Library:Scripts:" "Macintosh HD:private:tmp:501:TemporaryItems:" Path to current execution script
AppleScript Studio application that processes all the text files in your Documents folder, you would need to tell the script just where your Documents folder resides. Rather than write set myDocsFolder to "Macintosh HD:User:Jerry:Documents:"
you could write set myDocsFolder to (path to documents folder)
Note that parentheses are used around the folder specification. Also note that when used, the arguments listed in Table 8.2 are used in conjunction with the path to command, thus setting up the path specification. By setting up the folder reference using the documents argument, you make your code portable, allowing anyone to run it, because when executed, it will automatically point to his personal Documents folder. Had you hardcoded in the path to your personal home directory, you would have lost this portability. TRI
CK
Whenever possible, use the arguments listed in Table 8.2 to specify the location of files and folders. This will help make your code more readable and easier to maintain.
Chapter 8 • Working with Files and Folders
233
As an example of how to take advantage of the arguments listed in Table 8.2, consider the following statement. set textFile to (path to documents folder as string) & "Books:Sample.txt"
Here, a path has been set to a file named Sample.txt located in a subfolder named Books, which is located in the user’s Documents folder. Note the addition of a string as part of the path specification. This is required because the value returned by the path to command is an alias and not a string representing the specified path. An alias is a reference to an object and not a copy of the object. In the case of a path specification, in order to append a string to the end of the path, you must first convert the alias to a string.
WORKING WITH TEXT FILES Now that you know how to work with both traditional and POSIX paths and how to use the file class to set up a reference to a particular file, let’s take a look at the steps involved in reading and writing to and from files. Doing so involves opening the file, reading or writing to or from it, and then closing the file when done using it.
Accessing Files and Folders The first step in working with a text file is to set up a reference to it as demonstrated here. set textFile to file "Macintosh HD:Users:Jerry:Documents:Books:Sample.txt"
Once this has been done, you can use the open for access command to open the specified file, as demonstrated here. set outputFile to open for access file textFile
When executed, this statement defines a variable named outputFile. This variable is assigned a reference number that represents the specified text file. This example assumes that textFile contains a traditional Mac path of the specified file. Alternatively, if textFile consists of a POSIX path, you must include the keyword POSIX just after the open for access command, as shown here. set outputFile to open for access POSIX file textFile
Either version of the above example is all that is required to open the specified file. Once it is opened, you can read or write to the specified text file. When you are done working with the file, you must close it. Closing any open files before allowing your AppleScript Studio application to close is considered to be a good programming practice. If you allow your AppleScript Studio application to stop executing without first explicitly closing any files that it may have opened, you run the risk of corrupting and locking the files. As a result, the next time you attempt to work with the text file, you may have trouble accessing it.
234
TR
AppleScript Studio Programming for the Absolute Beginner
AP
In order to access a file and to read from and write to it, you must first have the prerequisite security permissions; otherwise, an error will occur.
To close an open text file, use the close access command as demonstrated below. set textFile to file "Macintosh HD:Users:Jerry:Documents:Books:Sample.txt" set outputFile to open for access file textFile close access outputFile
In this example, the path to a text file named Sample.txt is assigned to a variable named textFile. Next, the open for access command is used to open the text file using its specified path. Lastly, the close access command is used to close the text file.
Reading from and Writing to Files Now that you know how to specify the path to a file and how to close it, it is time to learn about the steps involved in reading from and writing to files, which nicely enough is done using AppleScript read and write commands.
Reading from a File Before you learn how to read the contents of a file, you must have something to read. In the example that follows, let’s assume that a log file named x.log exists in my home directory and contains the following lines. 2006/07/06 20:29 Logfile starting. 2006/07/06 20:33 System check in progress. 2006/07/06 20:35 Memory - Good. 2006/07/06 20:36 Disk - Good. 2006/07/06 20:39 System check complete. 2006/07/06 20:43 Software initialization tasks executing. 2006/07/06 20:44 Main_z_Libraries loaded. 2006/07/06 20:45 Establishing remote connections. 2006/07/06 20:47 Establishing remote connections. 2006/07/06 20:55 Establishing remote connections. 2006/07/06 20:59 Remote connections established. 2006/07/06 20:59 Loopback test successful. 2006/07/06 20:59 Software initialization tasks complete.
Chapter 8 • Working with Files and Folders
TABLE 8.3
235
read COMMAND ARGUMENTS
Argument
Description
as type to offset for length from offset before character
Coerces the data into the specified data type Reads the file up to the specified character location Reads the specified number of characters Reads the file starting at the specified character position Reads the file up to the first instance of the specified character (the specified character is excluded) Reads the file up to the first instance of the specified character (the specified character is included) Specifies a delimiter character Specifies a list of delimiter characters
until character using delimiter character using delimiters list
The first step in preparing to read a text file is to specify its path and then to open it, as demonstrated here. set textFile to (path to users folder as string) & ":Jerry:x.log" set inputFile to open for access file textFile
The value assigned to the outputFile variable is assigned a reference number to the x.log file. By default, opening a file as demonstrated above readies the file for reading, which is performed using the read command. To use the read command, you must tell the command what file you want read. set fileContents to read inputFile as string
Here, the entire contents of the x.log file are read and assigned to fileContents. Once you are done reading the text file, it should be closed. close access inputFile
Since the content of x.log has been stored in a variable, you can do whatever you want with it. For example, the following statements display the file’s contents in a popup dialog. display dialog fileContents
As you can see, there really is not much involved in reading the entire contents of a text file. Of course, you may not always want to read files in their entirety, which is where the list of arguments outlined in Table 8.3 come in to play. These arguments are used in conjunction with the read command to specify exactly what portion of a file should be read.
236
AppleScript Studio Programming for the Absolute Beginner
As an example of how to use the arguments listed in Table 8.3, consider the following examples. set textFile to file "Macintosh HD:Users:Jerry:x.log" set inputFile to open for access file textFile set x to (read inputFile for 10) display x -- Displays 2006/07/06 set x to (read inputFile for 6) display x -- Displays 20:29 set x to (read inputFile until return as string) display x -- Logfile starting. set x to (read inputFile before return as string) display x -- 2006/07/06 20:33 System check in progress. close access outputFile
In addition to using the arguments to the read command as demonstrated above, you can also use them in combination as demonstrated below. set x to (read inputFile from 10 to 20) -- Skips the first 9 characters and then read the next 11
Writing to a File In order to write to a file you must use the write command. This command requires that you provide it with the reference number returned when the file is opened using the open for access command, using the following syntax. write data to filereference data represents the output that is written to the file specified by the filereference variable.
For example, the following statements demonstrate how to create a new text file named sample.txt on your desktop and to write a line of text in it. set myFile to (path of desktop folder as string) & "Sample.txt" set outputFile to open for access file myFile with write permission write "This is a test message." to outputFile close access outputFile
Note that in order to write to a file, that file must be opened with write permissions. This is accomplished by appending the with write permission clause to the end of the open for access command as shown above. Like the read command, the write command accepts arguments that affect how it works. These arguments are described in Table 8.4.
Chapter 8 • Working with Files and Folders
TABLE 8.4
237
write COMMAND ARGUMENTS
Argument
Description
as type for length starting at offset
Coerces the data that is written into the specified data type Writes the specified number of characters Specifies the character position where writing should begin
Overwriting Files AppleScript automatically creates a new file if you open the file for writing and that file does not already exist. On the other hand, if the specified file already exists, AppleScript will, by default, overwrite it. Unfortunately, if the amount of data being written to the file is less than the amount of data already stored in it, at least some of the original data will still remain in the file, which is probably not what you’ll want. To avoid this behavior and ensure that all pre-existing data in the file is removed before writing new data, you can use the set eof command. To use the set eof command, you must provide it with a reference to the file name and also provide it with a value, in bytes, that tells it how long to set the length of the file, thus deleting everything after the end of file. For example, to use the set eof command to erase everything stored in a file before writing to it, you would do this: set eof of outputFile to 0
By specifying a value of 0, you effectively delete all of the contents of the file, readying it to hold whatever new data you want to store in it.
Appending to Files Instead of overwriting the contents of a file, you may want to append new data to the end of a file. You can do so by telling the write command to begin writing at the end of the file. To do this you must first ascertain this information, which you can do using the get eof command, as demonstrated here. get eof outputFile
Here, a value is retrieved (in bytes) that identifies the location of the end of the file. Using this value, you can construct your write statements to write any new data past the end of the file, thus appending the new data as demonstrated here. set outputFile to (path to desktop folder as string) & "Sample.txt" set outputFile to open for access file textFile with write permission
238
AppleScript Studio Programming for the Absolute Beginner
write "Appending to file." to outputFile starting at (get eof outputFile) close access outputFile
CREATING SMALL DATABASE FILES You now know the basics of using AppleScript to create files and to read from and write to them. With this information in hand, you can create AppleScript Studio applications that generate reports and log files. Another neat trick that you can do with the tools at your disposal is create small database applications. This can be accomplished by combining the ability to create lists of records with the ability to read and write lists to and from files.
Creating and Saving the Database File As a demonstration of AppleScript’s ability to generate small databases and build database applications, let’s develop a pair of small applications. The first application will be called GenerateDefaultPartsList. It will consist of a small GUI interface that contains a single button control, as demonstrated in Figure 8.7.
FIGURE 8.7 A simple AppleScript Studio application that creates a small database file.
When clicked, the on clicked event handler of the button control labeled Generate List will execute. The code for this event handler is shown below. on clicked theObject --Build a small parts database set partNumbers to {¬ {part:12345, description:"3 pound hammer"}, ¬ {part:66666, description:"3-set pack of skrewdrivers"}, ¬ {part:99999, description:"Heavy duty drill set"}, ¬ {part:12127, description:"5 position power saw"} ¬ }
Chapter 8 • Working with Files and Folders
239
--Create a database file named dbFile. Store it in the document folder. set dbFile to (path to documents folder as string) & "PartsDB" --Open the file so that it can be written to set outputFile to open for access file dbFile with write permission --Write the contents of the database to dbFile write partNumbers to outputFile as list --Close dbFile close outputFile --Let the user know that the script is done display dialog "Default parts list has been created." buttons {"OK"} end clicked
As you can see, this is not a terribly complex application. It starts off by creating a small list of records that is assigned to a list named partNumbers, thus creating a small database. Next, a file named dbFile is created in the Documents folder. The contents of the partNumbers list is then written to dbFile, and the file is closed. At this point, all of the records that make up the parts database have been stored and are ready for retrieval and manipulation by other applications.
Retrieving and Accessing Database Records To demonstrate how easy it is to access the dbFile database and view its records, let’s create another AppleScript Studio application called DisplayParts. It will consist of a small GUI interface that contains a single button control, as demonstrated in Figure 8.8.
FIGURE 8.8 A simple AppleScript Studio application that provides access to a small database.
240
AppleScript Studio Programming for the Absolute Beginner
When clicked, the on clicked event handler associated with the button control labeled Display Parts List will execute. The code for this event handler is shown below. on clicked theObject --Identify the name and path of the database file set dbFile to (path to documents folder as string) & "PartsDB" --Open the database file for reading set inputFile to open for access file dbFile --Read the database file. Assign its records to a variable. set partNumbers to read inputFile as list --Close the database file close inputFile --Define an empty list set partNo to {} --Loop through each item in the list repeat with x in partNumbers --Extract the part item from each record in the list and append --it to the list set end of partNo to part of x end repeat --Display a list of part numbers and prompt the user to select a part set userChoice to choose from list partNo with prompt "Pick-a-Part" --Convert the selected record item to a string set userChoice to userChoice as string --Loop through the list of part numbers repeat with x in partNumbers --Define a temporary variable to hold the current part number set currentPartNo to part of x as string --See if the current part number equals the user’s part number
Chapter 8 • Working with Files and Folders
241
if currentPartNo = userChoice then --Retrieve the description record item set selectedItem to description of x as string end if end repeat --Display the description associated with the selected part number display dialog (("Part Number : " & userChoice as string) & ¬ "\n\nDescription: " & selectedItem) end clicked
As you can see, the code statements that make up this AppleScript begin by opening and reading the contents of the dbFile database. Next, a repeat loop is used to loop through the records in the database file (e.g., list) in order to build a new list made up of part numbers. The contents of this new list are then displayed in a popup dialog using the choose command. This popup dialog allows the user to select any part number located in the parts database and then view its description, which is retrieved by using another repeat loop to loop back through the records that make up the database and find the record whose part number matches the part number selected by the user. The description associated with that part is then retrieved and displayed. TRI
CK
The choose command provides the ability to display a popup window and use it to display the contents of a list. This command allows you to customize the popup window by specifying a message prompt. In addition, by assigning the result returned from the choose command to a variable, you can capture the selection made by the user. The choose command supports other options, including the ability to display a popup dialog that lets users select a file from a standard Open File dialog or choose a folder from a standard Choose Folder dialog.
Once executed, the DisplayParts application displays a list of part numbers similar to the example shown in Figure 8.9. The user can then select any part displayed in the list and click on the OK button to view the description associated with that part number, as demonstrated in Figure 8.10.
242
AppleScript Studio Programming for the Absolute Beginner
FIGURE 8.9 Displaying the part numbers stored in the database.
FIGURE 8.10 Retrieving the description for the selected part number from the database.
As you can see, it is relatively easy to use AppleScript to generate small database files and applications. In fact, using AppleScript Studio, you could easily modify the previous example by developing a front-end database application that allows the user to add and remove records from the database file and generate reports.
BACK TO THE SLOT MACHINE GAME Now it is time to turn your attention back to the development of the Slot Machine game. This game will demonstrate how to simulate the operation of a Las Vegas-styled slot machine, including the automated spinning of slot machine values each time a new spin is made. This graphical animation is generated using a repeat loop and the delay command, in order to control the display of bitmap image files. As with every other application you have worked on in this book, you will create this application in five steps, as outlined here. 1. Start Xcode and create a new AppleScript Studio application named Slot Machine. 2. Lay out the interface controls that make up the application’s GUI using Interface Builder. 3. Configure the game’s menu, window and drawer, and control attributes and then connect interface controls to the appropriate event handlers. 4. Enter the AppleScript code statements required to drive the application. 5. Compile and test the application.
Chapter 8 • Working with Files and Folders
243
Step 1: Creating a New Project To begin work on this application, you need to create a new AppleScript Studio application as outlined below. 1. Click on the File menu and select New Project. An Assistant is launched, displaying a list of application templates. 2. Select AppleScript Application template and click on Next. 3. When prompted, specify S lot Machine as the application name and then specify the location where you would like to store this AppleScript Studio application. 4. Click on the Finish Button.
Step 2: Creating the User Interface The next step in the development of the Slot Machine game is to assemble its graphical user interface, as outlined in the following procedure. 1. Locate the MainMenu.nib file located in the Resources group and then double-click on it to start the Interface Builder. 2. Resize the default application window so that it is approximately 5.75 inches tall by 4 inches wide. 3. Drag and drop three image view controls to the top of the application window, spacing them across the tops of the window about 2/3rds of an inch below the window’s titlebar. 4. Drag and drop a text field control to the middle of the application window, about 2/3rds of an inch below the image view control. Resize the text field control so that it is approximately 2/3rds of an inch tall and takes up most of the application window’s width. 5. Drag and drop an instance of the label font text control onto the application window, placing it just about the upper left-hand corner of the text field control. 6. Double-click on the label font text control and enter Result: as its title. 7. Drag and drop an instance of the button control to the application window, placing it 2/3rds of an inch below the left-hand side of the text field control. Double-click on the button control and enter Spin as its title and then resize the button control so that it is approximately 1.25 inches wide. 8. Drag and drop an instance of the button control to the application window, placing it 2/3rds of an inch below the right-hand side of the text field control. Double-click on the button control and enter Instructions as its title. 9. Drag and drop another instance of the text field control to the bottom center of the application window. 10. Finally, drag and drop an instance of the label font text control onto the application window, placing it just about the upper left-hand corner of the text field control, located
244
AppleScript Studio Programming for the Absolute Beginner
at the bottom of the application window. Double-click on the label font text control and enter Account Balance: as its title, as demonstrated in Figure 8.11.
FIGURE 8.11 All of the interface controls required to create the Slot Machine game are now in place.
Step 3: Customizing Control Properties At this point the overall construction of the Slot Machine game’s user interface is complete. The next set of tasks to be performed is the modification of the application’s menu system, window, and interface controls. After that, you will need to set up the connection between the application’s two button controls and the on clicked event handler, as outlined in the next several sections.
Menu Customization To configure the Slot Machine game’s menu system, you need to delete a number of unnecessary default menus and menu items. Begin by removing the Edit and Help menus. Next, delete all of the menu items located on the Window menu except for the Minimize menu item, and then select the File menu and remove everything but the Close menu item. Finally, customize the Application menu as outlined here. 1. 2. 3. 4.
Double-click on the Application menu and replace its name with S lot Machine. Modify the About Application menu item to read About Slot Machine. Modify the Hide Application menu item to read Hide Slot Machine. Modify the Quit Application menu item to read Quit Slot Machine.
Modifying Window and Control Attributes As with any AppleScript Studio desktop application, you need to make a few adjustments to the game’s window and interface controls. These modifications are outlined in Table 8.5.
Chapter 8 • Working with Files and Folders
TABLE 8.5
MODIFICATIONS TO THE APPLICATION WINDOW INTERFACE CONTROLS
Object
Attribute
Modification
Window
Name Window Title Zoom Name Name Name Name Editable Selectable Layout Line Breaking Name Name Name Title Editable Selectable Alignment
main Slot Machine Disabled imvSquare1 imvSquare2 imvSquare3 txtResult Disabled Disabled Wraps Word Wrap btnSpin btnInstructions txtBalance 10 Disabled Disabled Right
Image View Image View Image View Text View
Button Button Text View
245
AND
Setting Up Event Handler Connections The Slot Machine game has two button controls that you need to configure to work with the click event in order to set up an on clicked event handler in its AppleScript file. Once you have completed this task for both button controls, you will be ready to proceed to the next section, where you will begin working with the code statements that drive the overall operation of the Slot Machine game.
Step 4: Adding a Little Programming Logic Assuming that you have already set up the clicked event, as directed in the previous section, you should see the following statements when you first start editing your application’s AppleScript file (except for the copyright comment, which I have modified in the example shown here). -- Slot Machine.applescript -- Slot Machine
246
AppleScript Studio Programming for the Absolute Beginner
-- Created by Jerry Ford on 8/19/06. -- Copyright 2006 - Jerry Lee Ford, Jr. - All rights reserved. on clicked theObject
end clicked
The code for the AppleScript file is organized into five handlers. The programming statements that call upon the handlers and drive the overall logic for the AppleScript Studio application reside inside the on clicked event handler, as shown here. if name of theObject is "btnInstructions" then DisplayInstructions() -- Call handler that displays instructions else -- The button control named btnSpin was clicked --Call handler that simulates the display of mechanical operation --of a real slot machine DisplayRandomImages() --Call handler that generates random numbers representing slot --machines values set {firstNo, secondNo, thirdNo} to GetRandomNumbers() --Display the current set of slot machine values DisplaySlotMachineImages(firstNo, secondNo, thirdNo) --Analyze the current set of slot machine values and adjust the --player’s account accordingly AnalyzeAndDisplayResults(firstNo, secondNo, thirdNo) end if
As you can see, an if…else statement code block controls the overall execution of the statements in the on clicked event handler. The opening conditional test checks to see if the btnInstructions button has been clicked, and if it has, the DisplayInstructions() handler is
Chapter 8 • Working with Files and Folders
247
executed. Otherwise, it is assumed that the btnSpin button has been clicked. As a result, four handler calls are made in the order outlined here. • DisplayRandomImages(). Simulates the mechanical operation of a real slot machine. • GetRandomNumbers(). When executed, this handler passes back a list representing the slot machine’s randomly selected values. • DisplaySlotMachineImages(). This handler is passed three variables, representing the slot machine’s randomly selected values. It uses the variables to determine which bitmap graphic files are displayed. • AnalyzeAndDisplayResults(). This handler is passed three variables, representing the slot machine’s randomly selected values. It uses them to determine whether the player lost or won any money, adjusting the player’s account accordingly.
Creating the DisplayInstructions() Handler The code for the DisplayInstructions() handler, shown below, uses the display dialog command to display instructions on how to play the game in a popup window. --This handler is responsible for displaying the game’s instructions on DisplayInstructions() display dialog "Instructions: Each spin costs $1. You will win $5 " & ¬ "for each jackpot. Nothing is awarded for two of a kind. You " & ¬ "will lose $1 if no matches occur." buttons {"OK"} end DisplayInstructions
Creating the DisplayRandomImages() Handler The code statements that make up the DisplayRandomImages() handler are shown here. --This handler iterates through a sequence of images that simulate the --random display --of slot machine values on DisplayRandomImages() repeat 5 times --This look will execute a total of 5 times tell window "main" --All commands are directed to the game’s window
248
AppleScript Studio Programming for the Absolute Beginner
delay 0.3 --Pause for .03 seconds before continuing --Display a mixed set of images set image of image view "imvSquare1" to load image "Orange.bmp" set image of image view "imvSquare2" to load image "Cherries.bmp" set image of image view "imvSquare3" to load image "Apple.bmp" beep --Play a sound delay 0.3 --Pause for .03 seconds before continuing --Display a mixed set of images set image of image view "imvSquare1" to load image "Apple.bmp" set image of image view "imvSquare2" to load image "Orange.bmp" set image of image view "imvSquare3" to load image "Cherries.bmp" beep --Play a sound delay 0.3 --Pause for .03 seconds before continuing --Display a mixed set of images set image of image view "imvSquare1" to load image "Cherries.bmp" set image of image view "imvSquare2" to load image "Apple.bmp" set image of image view "imvSquare3" to load image "Orange.bmp" beep --Play a sound end tell end repeat end DisplayRandomImages
As you can see, a repeat statement code block has been set up to execute five times. A tell statement code block is used to direct all commands to the application’s main window. Three sets of statements are then executed. The first set of statements begins by executing the delay command. The delay command pauses script execution for a specified number of seconds. As you can see, a value of .3 is passed as an argument to the delay command, pausing the script for three tenths of a second. The next three statements display the orange.bmp, cherries.bmp, and apple.bmp graphic files in the game’s image view controls. Next, the beep command is executed, making a noise that signals the display of a new set of image files. The next two sets of statements are almost identical to the first set of statements, except that the graphic files that are displayed have been assigned to different image view controls. The
Chapter 8 • Working with Files and Folders
249
end result provided by the statements in the DisplayRandomImages() handler is to display a series of five sets of rotating image files over a period of 1.5 seconds.
Creating the GetRandomNumbers() Handler The code statements for the GetRandomNumbers() handler, shown below, are responsible for generating three random numbers, each within the range of 1–3. --This handler returns a list made up of three randomly generated numbers on GetRandomNumbers() --Random number as generated from a range of 1 to 3 and then --coerced into an integer data type set x to random number from 1 to 3 as integer set y to random number from 1 to 3 as integer set z to random number from 1 to 3 as integer return {x, y, z} --Return the list of numbers to the calling statement end GetRandomNumbers
As you can see, the three random numbers are then returned as a list to the statement that called the handler.
Creating the DisplaySlotMachineImages() Handler The DisplaySlotMachineImages() handler, whose code statements are shown below, is responsible for using three numbers, passed to it as arguments, to determine which of three bitmap image files to display. --This handler is responsible for displaying the current round of slot --machine numbers on DisplaySlotMachineImages(firstNo, secondNo, thirdNo) tell window "main" --All commands are directed to the game’s window --Display the image for the first slot machine image view control if firstNo = 1 then --Display a Cherry if the random number is 1 set image of image view "imvSquare1" to load image "Cherries.bmp" else if firstNo = 2 then --Display an Apple if the number is 2 set image of image view "imvSquare1" to load image "Apple.bmp" else --Otherwise the number must be 3 to display an Orange
250
AppleScript Studio Programming for the Absolute Beginner
set image of image view "imvSquare1" to load image "Orange.bmp" end if --Display the image for the second slot machine image view control if secondNo = 1 then --Display a Cherry if the random number is 1 set image of image view "imvSquare2" to load image "Cherries.bmp" else if secondNo = 2 then --Display an Apple if the number is 2 set image of image view "imvSquare2" to load image "Apple.bmp" else --Otherwise the number must be 3 to display an Orange set image of image view "imvSquare2" to load image "Orange.bmp" end if --Display the image for the third slot machine image view control if thirdNo = 1 then --Display a Cherry if the random number is 1 set image of image view "imvSquare3" to load image "Cherries.bmp" else if thirdNo = 2 then --Display an Apple if the number is 2 set image of image view "imvSquare3" to load image "Apple.bmp" else --Otherwise the number must be 3 to display an Orange set image of image view "imvSquare3" to load image "Orange.bmp" end if end tell end DisplaySlotMachineImages
The code statements for this handler are organized into three sets, all of which are enclosed inside a tell statement code block that directs all commands to the application’s main window. As you can see, each group of statements is organized into an if…else if statement code block. The first if…else if statement code block is responsible for determining which graphic file to load into the game’s image view control. If the value of firstNo equals 1, the Cherries.bmp file is loaded. If firstNo equals 2, then the Apple.bmp file is loaded. Otherwise, the Orange.bmp file is loaded. The next two if…else if statement code blocks use similar logic to load the appropriate bitmap images into the game’s second and third image view controls.
Chapter 8 • Working with Files and Folders
251
Creating the AnalyzeAndDisplayResults() Handler The code statements that make up the AnalyzeAndDisplayResults() handler, shown below, are responsible for displaying the results of the game and adjusting the player’s account balance. --This handler determines the results of the current round of play and --updates the player’s account accordingly on AnalyzeAndDisplayResults(firstNo, secondNo, thirdNo) tell window "main" --All commands are directed to the game’s window --Add all the random numbers together set resultTotal to firstNo + secondNo + thirdNo --Set a variable representing player’s current account balance set playerBalance to contents of text field "txtBalance" --A total value of 3 indicates 3 cherries. A total value of 9 --indicates 3 apples. if resultTotal = 3 or resultTotal = 9 then --Display analysis of result and update player’s account balance set contents of text field "txtResult" to "JACKPOT! You win $5." set contents of text field "txtBalance" to playerBalance + 5 else if resultTotal = 6 then --A total value of 6 indicates either 3 oranges or one --of each value if firstNo = secondNo then -- 3 Oranges --Display analysis of result and update player’s account balance set contents of text field "txtResult" to "JACKPOT! You win $5." set contents of text field "txtBalance" to playerBalance + 5 else --1 cherry, 1 apple and 1 orange --Display analysis of result and update player’s account balance set contents of text field "txtResult" to "You Lose! " & ¬
252
AppleScript Studio Programming for the Absolute Beginner
"$1 has been removed from your account." set contents of text field "txtBalance" to playerBalance - 1 end if else --Display analysis of result. set contents of text field "txtResult" to "Tie." end if --The current game ends if the player runs out of money if contents of text field "txtBalance" = 0 then display dialog "GAME OVER. You have gone bust. Since you " & ¬ "are a preferred customer, the house has extended your " & ¬ "credit. Please keep playing!" buttons {"OK"} --Reset GUI controls back to initial default values set contents of text field "txtResult" to "" set contents of text field "txtBalance" to 10 end if end tell end AnalyzeAndDisplayResults
The opening tell statement sets up a code block that directs all commands to the application’s main window. Next, the values of firstNo, secondNo, and thirdNo, passed to the handler as arguments, are added together and assigned to a variable named resultTotal. Then a variable named playerBalance is assigned the value stored in the txtBalance text field control (e.g., the amount of money in the player’s account). Next, an if…else if statement code block determines the results of the current spin. This is accomplished by comparing the value of the resultTotal to the values outlined in Table 8.6. HIN
T
Remember that a randomly generated value of 1 equates to a cherry. Therefore, if three cherries were generated, the value of resultTotal would be 3. Likewise, a randomly generated value of 2 equates to an apple, and a value of 3 equates to a value of orange.
Chapter 8 • Working with Files and Folders
TABLE 8.6
EVALUATION
OF
253
SLOT MACHINE VALUES
Value
Explanation
3 9 6 Other
Three cherries were generated. Three apples were generated. Either three oranges were generated or a cherry, apple, and orange were generated. Only two matching values were generated.
The last set of statements in the AnalyzeAndDisplayResults() handler checks the resulting value of the txtBalance text field control. If it is equal to zero, the player has gone bust and the game is restarted.
Step 5: Testing the Execution of the Slot Machine Game The development of your new Slot Machine game is now complete. Assuming that you didn’t make any mistakes when keying in the required program code and that you carefully followed each step outlined in the previous sections, the Slot Machine game works as advertised. Go ahead and click Xcode’s Build and Go button and put the game through its paces. If any errors are reported, use the error information provided to track down and fix them.
SUMMARY In this chapter you learned the basics of working with the Mac OS X file system. This included learning how to navigate the file system. You learned how to create and access text files and to read and write to and from them. You also learned how to use lists and records to create small database files. In the next chapter, you will learn how to create AppleScript Studio applications that access and automate the functionality provided by other Mac OS X applications, including Finder, which will provide you with access to powerful and more robust disk, file, and folder management capabilities. Before you move on to the next chapter, why don’t you take a few extra minutes and see what you can do to improve the Slot Machine game by addressing the following list of challenges.
254
AppleScript Studio Programming for the Absolute Beginner
CHALLENGES 1.
2.
As currently set up, the Slot Machine game only has three image values to work with (cherry, apple, and orange). As a result, typical game play results in a great deal of ties. Consider expanding the number of values supported by the game, thus increasing its level of difficulty. Use the information presented in this chapter to enhance the Slot Machine game so that it records the results of every game in a text file, thus creating an audit file that could be used as a record of game play. Include in this log date and time information, as well as the results of every game and an entry for every move that shows the player’s current account balance.
9
C H A P T E R
CONTROLLING OTHER APPLICATIONS s has been stated many times already in this book, in addition to providing a programming language for AppleScript Studio, AppleScript also facilitates the development of scripts that automate the execution of Mac OS X applications. In this chapter you will learn the basic steps involved in automating the execution of other applications. This will enable you to significantly extend the functionality of your AppleScript Studio applications. It will also allow you to create timesaving applications that present the user with a single user interface that can then execute scripted tasks designed to combine the functionality of numerous Mac OS X applications, resulting in an application that is greater than the sum of its parts.
A
Specifically, you will learn how to • Use the tell command to target Mac OS applications • Use application dictionaries to find the classes, elements, properties, and commands required to automate Mac OS X applications • Automate TextEdit, Finder, Safari, Mail, DVD, iTunes, Terminal, Help View, and numerous other Mac OS X applications
256
AppleScript Studio Programming for the Absolute Beginner
PROJECT PREVIEW: THE TIC-TAC-TOE GAME This chapter’s game project is an implementation of the classic children’s Tic-Tac-Toe game. In this implementation of the game, two players go head to head in an effort to outmaneuver each other by lining up three consecutive game board squares. When first started, the TicTac-Toe game board is blank, as demonstrated in Figure 9.1.
FIGURE 9.1 The Tic-Tac-Toe game board when the game first starts.
Game play begins when a player clicks on the Play button. Player X, the name assigned to the first player, is notified that it is his turn by a message displayed at the bottom of the game window, as demonstrated in Figure 9.2.
FIGURE 9.2 The Tic-Tac-Toe game automatically keeps track of each player’s turn.
Chapter 9 • Controlling Other Applications
257
Players take turns making moves. A move is made when a player clicks on one of the game’s nine game board squares. Each time a player moves, the game identifies the player's move by displaying a letter (X or O) representing the player on the selected square, as demonstrated in Figure 9.3.
FIGURE 9.3 The game disables access to game board squares once they have been selected to prevent them from being selected again.
Game play ends when either player manages to line up three consecutive moves, as demonstrated in Figure 9.4.
FIGURE 9.4 Players can win horizontally, vertically, or diagonally.
As Figure 9.5 demonstrates, not every game will result in a winner. Game play continues until a winner is declared or all nine game board squares have been selected. Once a game has
258
AppleScript Studio Programming for the Absolute Beginner
ended, the results of the game are displayed at the bottom of the window, and the Play button is re-enabled to allow players to start a new round of play.
FIGURE 9.5 A game that has resulted in a tie.
AUTOMATING MAC OS X APPLICATIONS In this chapter you will learn how to develop AppleScript Studio applications that can boss around other Mac OS X applications. By this I mean that you will learn how to start and then control the actions of other applications in order to perform specific tasks. In demonstrating this programming capability, I have elected not to provide in-depth coverage of how to automate any one particular Mac OS X application. Instead, I have decided to provide you with a series of small examples that demonstrate how to interact with and control a wide range of Mac OS X applications. Hopefully the examples will inspire you to learn more about these applications and experiment with different ways that you can automate their execution and ultimately develop AppleScript Studio applications that leverage the capabilities these applications provide.
ACCESSING APPLICATION TERMINOLOGY As you will learn in this chapter, you can use AppleScript to automate any number of scriptable Apple and third-party applications. Often, you can perform powerful application automation using just a few lines of code. In order to give you a broad sense of this capability, this chapter will present you with a large set of examples. While these examples will not be particularly large or complex, they should more than suffice to get your imagination racing as to the many different possibilities that are awaiting you.
Chapter 9 • Controlling Other Applications
259
Application Dictionaries As you learned back in Chapter 1, “AppleScript Studio Basics,” you can access the terminology exposed by application dictionaries and use it to access and control the applications. The information stored in an application’s dictionary defines the classes, properties, and commands that the application supports. No two applications are the same. Therefore, no two applications have the same terminology. In order to learn how to programmatically interact with and control a particular application, you will need to spend time examining its dictionary. As you learned in Chapter 2, “The AppleScript Studio Application Development Environment,” Xcode provides you with the ability to access any application’s dictionary by clicking on the Open Dictionary option located on the Xcode File menu. For example, Figure 9.6 shows the dictionary for the TextEdit application.
FIGURE 9.6 Viewing the contents of the TextEdit dictionary.
In order to work with an application’s dictionary, you will usually want to begin by locating the application class entry, which as you might guess, represents the application. From here you typically want to look up the elements associated with the application class. For example, TextEdit is a small word-processing application supplied with Mac OS X. TextEdit has an element named document. To tell TextEdit to do pretty much anything, you have to work with this element.
260
AppleScript Studio Programming for the Absolute Beginner
TABLE 9.1
UNIVERSAL APPLICATION TERMINOLOGY COMMANDS
Command
Description
activate
Starts the application (if necessary) and brings it to the front of any other open applications Closes the application Starts the application without bringing it to the front
quit launch
You can learn about each element by reading its definition. Next you can look at the properties belonging to each element to learn what application attributes you can configure and control. For example, as Figure 9.6 shows, the document element has properties named modified, name, and path. Lastly, you should review the list of commands accepted by each application. For example, TextEdit supports a command named make. If you examine the dictionary entry for the make command, you will see that is has one required argument, the new keyword. As an initial example of how to automate the execution of a Mac OS X application, consider the following code statements. tell application “TextEdit” activate make new document at the front set text of front document to "See Ma, no hands!" end tell HIN
T
When examining the dictionary belonging to the TextEdit command, you may have noticed that there was no entry for the activate command. activate is one of three universal commands accepted by every Mac OS X application. Table 9.1 defines each of these universal commands.
Here, the TextEdit application is targeted. Next, the activate command is executed. This command starts TextEdit if it is not already running and brings it to the forefront so that you can see it. Next, the make command is executed. This command creates a new document. Note the use of the new keyword. Also take note that at the front has been added to the end of the make command. This instructs TextEdit to display the new document window in front of any other text windows that might happen to be open. When executed, this set of statements will start TextEdit, open a new window, and write the specified text string to it.
Chapter 9 • Controlling Other Applications
261
Using tell to Direct Messages to Application Targets In the previous example, you learned how to automate the TextEdit application. This included starting TextEdit, creating a new window, and writing a text string to it. The trick to making TextEdit follow your instructions is the tell code block in which the statements were embedded. In previous chapters you have seen the tell command used to direct commands to specific windows within your AppleScript Studio applications. However, the tell command can be used to target other resources, including Mac OS X applications. When used to target applications, a tell code block has the following syntax. tell application appname … end tell application is a required keyword, and appname represents the name of the application to which event messages should be sent. Statements inside the tell code block are directed as messages to the specified application. The targeted application will then attempt to process these messages based on the terminology defined in its dictionary. However, if you make an error, for example by sending an application a command that it does not support, the application will not be able to process the command. As a result, the application will leave it to AppleScript to react to and process the command. If AppleScript cannot process the command, an error is returned.
AUTOMATING MAC OS X APPLICATIONS In the sections that follow, I will present you with a number of small examples that demonstrate how to automate different Mac OS X applications. The examples that you will see automate applications supplied as part of Mac OS X. These examples represent only a small fraction of the applications that are supplied with Mac OS X. In addition, there are tons of third-party Mac OS X applications that are also scriptable. To learn more about how to work with the applications presented in this chapter or any other scriptable applications, consult each application’s dictionary.
TextEdit As you already know, TextEdit is a word processing application supplied with Mac OS X. As such, it supports the use of different fonts and font sizes like any modern word processor. The following example expands on the earlier example, demonstrating how to format font size and type. tell application “TextEdit” activate
262
AppleScript Studio Programming for the Absolute Beginner
make new document at the front set text of front document to “Once upon a time in a far ” & ¬ “away land...” & return & return & “THE END” set font of first paragraph of the front document to “Arial” set size of first paragraph of the front document to “to 18” end tell
In this example, the document class’s text property is used to write a text string to the TextEdit document. The text string includes two embedded return keywords, which act as carriage returns. Next, the paragraph class’s font property is used to specify the font used to display text in the first paragraph. Then the paragraph class’s size property is used to set the font size of the text in the first paragraph to 18. If executed, this example would generate the results shown in Figure 9.7.
FIGURE 9.7 Automating the creation of a TextEdit document.
TRI
CK
There is a lot more to scripting Mac OS X applications than just sending commands to them. By interweaving these commands into your programming logic, you can, for example, develop complex automated procedures. Most scriptable applications also provide you with access to a number of application properties, which you can retrieve and sometimes modify. For example, most scriptable applications, including TextEdit, have a property named version that you can use to retrieve the application’s version number. tell application “TextEdit” set x to get version end tell
Chapter 9 • Controlling Other Applications
263
Finder In Chapter 8, “Working with Files and Folders,” you learned how to create and read from and write to text files using AppleScript. However, AppleScript has limited capabilities when it comes to working with files. For example, AppleScript cannot rename, delete, copy, or move files. However, the Finder application can. The following example demonstrates how to automate Finder in order to copy a file from the current working directory to the user’s Documents folder. tell application “Finder” copy file "sample.txt" to folder (path to documents folder) end tell
As you can see, Finder’s copy command was used in this example. You will find a great many useful commands in Finder’s dictionary, including move, sort, find, delete, make, and print. Note that in this example I did not include the activate command; therefore, Finder will not appear when the example is executed.
iTunes iTunes is a multimedia application supplied with Mac OS X. iTunes is a full-featured music management system that stores all your music and audio files. iTunes also lets you play your music and create custom playlists. Using the iTunes play command, you can play the song most recently listened to, as demonstrated here. tell application “iTunes” play end tell
You can easily modify this example to play a specific song in any playlist you designate, as demonstrated in the following example. tell application "iTunes" play track 3 of playlist "LeesList" set visible to true end tell
This example plays the third track (song) located in the LeesList playlist. Using this terminology, you could, for example, develop an AppleScript Studio front-end application to manage and play your own playlists by leveraging the features provided by iTunes.
264
AppleScript Studio Programming for the Absolute Beginner
Terminal The Terminal application provides command-line access to the Unix command prompt, where you can enter commands that interact with and control the operating system and other resources. The following example demonstrates how to open a Terminal window and submit a Unix command to it. tell application "Terminal" activate do script "ls" end tell HIN
T
The do script command provides you with the ability to execute Unix commands and script files.
In this example, the Unix command ls is executed. This command displays the contents of the current working directory, as demonstrated in Figure 9.8.
FIGURE 9.8 Using the Terminal application to execute Unix commands.
DVD Another application that you may want to experiment with is the Mac OS X DVD Player. This application is a built-in DVD player supplied with Mac OS X. The following example demonstrates how to start the DVD player in full screen mode, hide its controller, and play whatever DVD is in the computer’s DVD drive.
Chapter 9 • Controlling Other Applications
265
tell application “DVD Player” activate set viewer size to max set controller visibility to false play dvd end tell
In this example, the application class’s viewer size property is set to max, and its controller visibility property is set to false, thus hiding the initial display of the DVD controller. Lastly, the play command is executed in order to play the currently loaded DVD.
Address Book The Address Book application is a Mac OS X application that is used to store personal contact information, including names, email addresses, and phone numbers. You can develop an AppleScript Studio front-end for the Address Book, using the Address Book as a behind the scenes database. For example, the following statements demonstrate how to access the Address Book application and display all of the Address Book entries for individuals whose first name is Mike. tell application “Address Book” activate set tempList to people whose first name is “Mike” repeat with x in tempList display dialog (first name of x as string) & “” & ¬ (last name of x as string) end repeat end tell
In this example, a list named tempList is created and assigned all of the Address Book entries whose first name is Mike. Next, a repeat code block is set up that iterates through each Address Book entry, displaying the first and last names of all people named Mike.
Safari Safari is an Internet browser supplied as a free application with Mac OS X. It is by far the most popular Internet browser used by Mac users. Using AppleScript, you can easily start up Safari and load any URL, as demonstrated here. tell application “Safari” activate
266
AppleScript Studio Programming for the Absolute Beginner
open location "http://www.amazon.com" end tell
In this example the open command is used to locate and display the specified URL. If you want, you can open additional URLs by specifying more than one open command. As you can see, it does not take much to open Safari and display a specified web page. You might find this capability a useful way to provide access to web-based help in your AppleScript Studio applications.
Mail Mail is Mac OS X’s built-in email application. The following example demonstrates how to create and send an outgoing email message. tell application “Mail” set msgText to make new outgoing message tell msgText to make new to recipient set sender of msgText to “
[email protected]” set subject of msgText to “Happy Birthday!” set content of msgText to “Best wishes on your 40th birthday.” set address of recipient of msgText to “
[email protected]” send msgText end tell
In order to send an email, you must begin creating a new outgoing message. This is done using the make command. You must then use the tell command to target a recipient object. Once this is done, all that remains is to assign the sender, subject, content, and address entries.
System Events On Mac OS X, a special application referred to as System Events runs quietly behind the scenes at all times. This application is responsible for managing the execution of other applications and for starting the operating systems at system startup. You can use AppleScript to automate various system operations. For example, the following tell command code block demonstrates how to instruct the System Event application to put the computer to sleep. tell application “System Events” sleep end tell TRI
CK
By substituting the restart command in place of the sleep command, you can tell System Events to restart the computer. Likewise, you can shut down the computer by substituting the shut down command.
Chapter 9 • Controlling Other Applications
267
By automating functionality provided by the System Events application, you can perform a host of tasks and access various types of information about the system’s current status. For example, the following tell command code block demonstrates how to instruct the System Events application to provide you with a list of all the processes currently running on the computer. tell application “System Events” set x to processes end tell
Help Viewer Help Viewer is a Mac OS X application that you can use to perform a search of Mac OS X’s Help system, as demonstrated in the following example. tell application “Help Viewer” activate search looking for "printing" end tell
If you run this example on your computer, you should see results similar to those shown in Figure 9.9.
FIGURE 9.9 Using Help Viewer to search for help information.
268
AppleScript Studio Programming for the Absolute Beginner
You can use this example as the basis for adding Mac OS X Help to your AppleScript Studio applications. For example, you might place a Help button on an application window in order to provide access to a specific help topic, or you might even allow the user to enter his own search string.
BACK TO THE TIC-TAC-TOE GAME At this point it is time to turn your attention back to the development of the Tic-Tac-Toe game. This game is a computerized, two-player implementation of the classic Tic-Tac-Toe children’s game in which each player attempts to outwit the other by lining up three consecutive game board squares in a row. Players win by lining up three moves vertically, horizontally, or diagonally. In developing this game, you will get your first chance to work with the bevel button control, using the control to represent game board squares. As with every other application you have worked on in this book, you will create this application in five steps, as outlined below. 1. Start Xcode and create a new AppleScript Studio application named T ic-Tac-Toe. 2. Assemble the controls required to create the application’s user interface. 3. Configure the game’s menu, window, and control attributes and then attach interface controls to event handlers. 4. Add the code statements required to control the operation of the game. 5. Compile and test the application.
Step 1: Creating a New Project If necessary, go ahead and start Xcode and then create a new AppleScript Studio project by following the steps outlined here. 1. Click on the File menu and then select New Project. Xcode launches an Assistant, which displays a list of application templates. 2. Select AppleScript Application template and then click on the Next button. 3. Enter Tic-Tac-Toe as the file name for the application and then specify the location where you want to store this new AppleScript Studio application. 4. Click on the Finish Button.
Step 2: Creating the User Interface The next step in the development of the Tic-Tac-Toe game is to design and assemble its user interface, as outlined in the following procedure.
Chapter 9 • Controlling Other Applications
269
1. Locate the MainMenu.nib file located in the Resources group and then double-click on it to start the Interface Builder. 2. Change the size of the default application window so that it is approximately 4 inches wide and 5.25 inches tall. 3. Drag and drop nine instances of the bevel button control onto the window, resizing each control so that they are approximately 1.2 inches wide by 1.2 inches tall. Organize these control into three rows, starting from the upper left-hand corner of the application window. 4. Drag and drop an instance of the button control to the lower left-hand side of the application window. Double-click on the button control and enter Play as its title. 5. Drag and drop an instance of the button control to the lower right-hand side of the application window. Double-click on the button control and enter Instructions as its title. 6. Drag and drop an instance of the text field control to the bottom of the application window, just beneath the two button controls. At this point the basic layout of your application’s GUI is complete. It should look like the example shown in Figure 9.10.
FIGURE 9.10 The layout of the Tic-Tac-Toe game’s GUI is now complete.
Step 3: Customizing Control Properties The overall construction of the game’s user interface is now complete. It is now time to configure the application’s menu system, modify its window and control attributes, and associate
270
AppleScript Studio Programming for the Absolute Beginner
the game’s two button and nine bevel button controls with the on clicked event handler, as outlined in the next several sections.
Menu Customization To configure the Tic-Tac-Toe game’s menu system, you will need to delete a number of unnecessary menus and menu items. For starters, remove the Edit and Help menus and then delete all the menu items on the Window menu except for the Minimize menu item. Next, select the File menu and remove each menu item except for the Close menu item. Finally, customize the Application menu as outlined here. 1. 2. 3. 4.
Double-click on the Application menu and replace its name with Tic-Tac-Toe. Modify the About Application menu item to read About Tic-Tac-Toe. Modify the Hide Application menu item to read Hide Tic-Tac-Toe. Modify the Quit Application menu item to read Quit Tic-Tac-Toe.
Modifying Window and Control Attributes In order to finish up the graphical user interface for the Tic-Tac-Toe game, you must make a number of modifications to the game’s window and interface controls. These modifications are outlined in Table 9.2.
TABLE 9.2
MODIFICATIONS TO THE TIC-TAC-TOE WINDOW INTERFACE CONTROLS
Object
Attribute
Modification
Window
Name Window Title Zoom Name Sound Type Icon Pos Enabled Name Sound Type Icon Pos Enabled Name Sound
main Tic-Tac-Toe Disabled btnA1 Tink Square Button Centered graphic Disabled btnA2 Tink Square Button Centered graphic Disabled btnA3 Tink
Bevel Button
Bevel Button
Bevel Button
AND
Chapter 9 • Controlling Other Applications
Bevel Button
Bevel Button
Bevel Button
Bevel Button
Bevel Button
Bevel Button
Button Button Text Field
Type Icon Pos Enabled Name Sound Type Icon Pos Enabled Name Sound Type Icon Pos Enabled Name Sound Type Icon Pos Enabled Name Sound Type Icon Pos Enabled Name Sound Type Icon Pos Enabled Name Sound Type Icon Pos Enabled Name Name Name Editable Backgrnd Color
Square Button Centered graphic Disabled btnB1 Tink Square Button Centered graphic Disabled btnB2 Tink Square Button Centered graphic Disabled btnB3 Tink Square Button Centered graphic Disabled btnC1 Tink Square Button Centered graphic Disabled btnC2 Tink Square Button Centered graphic Disabled btnC3 Tink Square Button Centered graphic Disabled btnPlay btnInstructions txtStatus Disabled Mercury
271
272
AppleScript Studio Programming for the Absolute Beginner
T
There are six possible values that you can select from when configuring the Icon Pos attribute for a bevel button control. These choices are represented by six icons located at the bottom of the Inspector window when a bevel button control is selected. Each of these icons represents a different configuration, with different combinations of text and graphics. For the Tic-Tac-Toe application, you will want to select the middle icon on the top row, which results in a bevel button that displays only a graphic image.
CK
The background color of the game’s text field control is set to Mercury, which is a variation of the color gray. To set this value you must click on the color well control located toward the top of the Inspector window when the text field control is selected. Doing so displays the Colors window. This window allows you to select a color from any of five different views, which are selected by clicking on icons located at the top of the Colors window. You will find the selection for Mercury located on the Color Palettes view, as demonstrated in Figure 9.11.
HIN
TRI
FIGURE 9.11 Assigning a new background color to the game’s text field control.
Setting Up Event Handler Connections The Tic-Tac-Toe game has two button controls and nine bevel button controls that you need to configure to react to the click event. The end result will be a single on clicked event handler in the application’s AppleScript file that reacts each time one of these buttons is clicked. Once this task is completed, you will be ready to begin the coding portion of this application.
Chapter 9 • Controlling Other Applications
273
Step 4: Adding a Little Programming Logic Now it is time to get to work on the AppleScript programming part of the Tic-Tac-Toe application. Assuming that you have set up the clicked event for each of the application’s button controls, code statements similar to the following should already be present in the application’s script file. -- Tic-Tac-Toe.applescript -- Tic-Tac-Toe --
Created by Jerry Ford on 8/21/06.
--
Copyright 2006 - Jerry Lee Ford, Jr. - All rights reserved.
on clicked theObject end Clicked
As you can see, I have modified the copyright comment statement. Otherwise, everything else should be pretty standard stuff to you by now. The Tic-Tac-Toe AppleScript file will use a number of global variables, which will be used in various handlers throughout the script. Let’s begin by identifying these variables as global by adding the following statements after the copyright comment and just before the opening on clicked event handler. --Set up the following variables as global within the script global currentPlayer, noMoves, a1, a2, a3, b1, b2, b3, c1, c2, c3
The currentPlayer variable will be used to keep track of whose turn it is (Player X or Player O). The noMoves variable will be used to keep count of the number of moves that are made during game play. Variables a1 through a3 represent the squares (bevel button controls) that make up the Tic-Tac-Toe game board. Next, it is time to add the overall controlling logic for the script. To do so, the following statements need to be placed inside the on clicked event handler. if name of theObject is "btnPlay" then --The Play button PrepareGameBoard() --Reset the game board StartNewGame() --Reset variable default values else if name of theObject is "btnInstructions" then --Instructions button
274
AppleScript Studio Programming for the Absolute Beginner
tell application "Safari" --Display on-line help activate --Display Safari open location "http://www.yourwebsite.com" --Load specified URL end tell else AssignMove(name of theObject) --Assign game board square to player set gameBoardStatus to AnalyzeBoard() --Look for consecutive squares SwitchPlayers() --Toggle between player X and Player O set gamePlay to SeeIfGameOver(gameBoardStatus) --Look for a winner if gamePlay = "gameOver" then --Disable game board at end of game DisableSquares() end if end if
These statements are organized into an if…else if statement code block. The first two embedded statements execute when the user clicks on the Play button. The first statement is a call to the PrepareGameBoard() handler, which is responsible for preparing the game board for a new round of play. The next statement calls on the StartNewGame () handler, which resets the starting values of the game’s global variables. The else if portion of the code block executes when the player clicks on the Instructions button. Its embedded statements consist of a tell code block, which opens Safari and displays a URL. HIN
T
For this portion of the script to work as intended, you will need to replace http:// www.yourwebsite.com with a URL of your own.
Next, the else portion of the code block is defined. The statements in this section of the code block execute whenever a player clicks on one of the nine game board squares (bevel button controls). The AssignMove() handler identifies which square the player selected and displays a graphic image of an O or an X, depending on whose turn it is. Next, the AnalyzeBoard()
Chapter 9 • Controlling Other Applications
275
handler is executed. This handler looks to see if the current player has managed to line up three consecutive game board squares, returning a value of X, O, or InProgress. This value is then assigned to a variable named gameBoardStatus. Next, the SwitchPlayers() handler runs, toggling the value of the currentPlayer variable between X and O. The SeeIfGameOver handler is then called and passed the gameBoardStatus variable. This handler will return a value of gameOver if it determines that one of the players has won the game or if the game has ended in a tie. An if statement code block is then used to conditionally execute the DisableSquares() handler, which prevents either player from clicking on additional game board squares once the current game has been finished. The rest of the code statements that make up the AppleScript file are organized into the event handlers discussed above. Each of these handlers is reviewed in the sections that follow.
Creating the PrepareGameBoard() Handler The code statements that make up the PrepareGameBoard() handler are shown next. This handler is responsible for preparing the game board for a new round of play. --This handler readies the game board for a new round of play on PrepareGameBoard() tell window "main" --Direct commands to the "main" window --Load default images into each game board square set image of button "btnA1" to load image "_.jpg" set image of button "btnA2" to load image "_.jpg" set image of button "btnA3" to load image "_.jpg" set image of button "btnB1" to load image "_.jpg" set image of button "btnB2" to load image "_.jpg" set image of button "btnB3" to load image "_.jpg" set image of button "btnC1" to load image "_.jpg" set image of button "btnC2" to load image "_.jpg" set image of button "btnC3" to load image "_.jpg" --Enable each game board square (button control) set enabled of button "btnA1" to true set enabled of button "btnA2" to true set enabled of button "btnA3" to true set enabled of button "btnB1" to true set enabled of button "btnB2" to true
276
AppleScript Studio Programming for the Absolute Beginner
set enabled of button "btnB3" to true set enabled of button "btnC1" to true set enabled of button "btnC2" to true set enabled of button "btnC3" to true --Disable the button labeled Play set enabled of button "btnPlay" to false end tell end PrepareGameBoard
The first set of statements in this handler load the _.jpg file into the btnA1–btnC3 bevel button controls. The _.jpg file is a blank image (e.g., an image without an X or an O on it). Bevel button controls are able to display graphics, text, or both. Bevel button controls are also designed to accept click events and can be configured to display with square edges, making them a perfect substitute for a game board square. The last statement in the handler disables the Play button, which stays disabled until the end of the current round of play.
Creating the StartNewGame() Handler The code for the StartNewGame() handler is shown below. This handler is responsible for resetting the game’s global variables to default values at the start of each new round of play. --This handler sets variables to default values at the start of the game on StartNewGame() tell window "main" set content of text field "txtStatus" to "Player X's Turn" set currentPlayer to "X" set noMoves to 0 set a1 to "" set a2 to "" set a3 to "" set b1 to "" set b2 to "" set b3 to ""
Chapter 9 • Controlling Other Applications
277
set c1 to "" set c2 to "" set c3 to "" end tell end StartNewGame
Creating the AssignMove() Handler The code for the AssignMove() handler is shown next. This handler accepts a single argument, representing the current player’s move (game square selection). on AssignMove(gameSquare) tell window "main" --Direct commands to the "main" window set noMoves to noMoves + 1 --Keep count of the number of moves made --Assign a selected game board piece to the appropriate player if gameSquare = "btnA1" then set a1 to currentPlayer if gameSquare = "btnA2" then set a2 to currentPlayer if gameSquare = "btnA3" then set a3 to currentPlayer if gameSquare = "btnB1" then set b1 to currentPlayer if gameSquare = "btnB2" then set b2 to currentPlayer if gameSquare = "btnB3" then set b3 to currentPlayer if gameSquare = "btnC1" then set c1 to currentPlayer if gameSquare = "btnC2" then set c2 to currentPlayer if gameSquare = "btnC3" then set c3 to currentPlayer if currentPlayer = "X" then --Display an "X" for Player X --Display graphic file representing Player X set image of button (gameSquare as string) to load image "x.jpg" else --Display an "O" for Player O --Display graphic file representing Player X set image of button (gameSquare as string) to load image "o.jpg"
278
AppleScript Studio Programming for the Absolute Beginner
end if --Disable the selected game board square (button control) set enabled of button (gameSquare as string) to false end tell end AssignMove
This handler begins by incrementing the value of noMoves, which is used to keep track of the total number of moves made by both players. Next, a series of if statements are executed in order to assign the selected game board square to the appropriate player (e.g., by assigning an X or an O to a variable representing the square—e.g., a1–c3). Next, an if…else statement code block executes. If it is Player X’s turn (e.g., currentPlayer = "x"), the x.jpg image file is loaded into the selected game board square. Otherwise, the o.jpg image file is loaded. Lastly, the selected bevel button control is disabled, preventing either player from selecting it again during the current round of play.
Creating the AnalyzeBoard() Handler The code statements for the AnalyzeBoard() handler are shown next. When called, this handler checks to see if the current player has successfully lined up three consecutive game board squares (horizontally, vertically, or diagonally). --This handler determines when a player has been able to select three --consecutive squares on AnalyzeBoard() tell window "main" --Direct commands to the "main" window --Look for three consecutive Xs after Player X makes a move if currentPlayer = "X" then --Check horizontally if a1 = "X" and a2 = "X" and a3 = "X" then return "X" if b1 = "X" and b2 = "X" and b3 = "X" then return "X" if c1 = "X" and c2 = "X" and c3 = "X" then return "X" --Check vertically if a1 = "X" and b1 = "X" and c1 = "X" then return "X"
Chapter 9 • Controlling Other Applications
279
if a2 = "X" and b2 = "X" and c2 = "X" then return "X" if a3 = "X" and b3 = "X" and c3 = "X" then return "X" --Check diagonally if a1 = "X" and b2 = "X" and c3 = "X" then return "X" if a3 = "X" and b2 = "X" and c1 = "X" then return "X" else --Look for three consecutive Os after Player O makes a move --Check horizontally if a1 = "O" and a2 = "O" and a3 = "O" then return "O" if b1 = "O" and b2 = "O" and b3 = "O" then return "O" if c1 = "O" and c2 = "O" and c3 = "O" then return "O" --Check vertically if a1 = "O" and b1 = "O" and c1 = "O" then return "O" if a2 = "O" and b2 = "O" and c2 = "O" then return "O" if a3 = "O" and b3 = "O" and c3 = "O" then return "O" --Check diagonally if a1 = "O" and b2 = "O" and c3 = "O" then return "O" if a3 = "O" and b2 = "O" and c1 = "O" then return "O" end if return "InProgress" --Unable to find three consecutive Xs or Os end tell end AnalyzeBoard
As you can see, if the current player is Player X, a value of X is returned in the event the player has managed to line up three consecutive game board squares. Likewise, a value of O is returned if Player O is the current player and three consecutive O squares have been lined up. In the event that the current player has not been able to line up three squares, a value of InProgress is returned.
280
AppleScript Studio Programming for the Absolute Beginner
Creating the SwitchPlayers() Handler The code for the SwitchPlayers() handler is outlined next. --This handler controls whose turn it is on SwitchPlayers() tell window "main" --Direct commands to the "main" window if currentPlayer = "X" then --If Player X just moved --Make it Player O's turn set currentPlayer to "O" --Display message that identifies whose turn it is set content of text field "txtStatus" to "Player " & ¬ currentPlayer & "'s Turn" else --If Player O has just moved --Make it player X's turn set currentPlayer to "X" --Display message that identifies whose turn it is set content of text field "txtStatus" to "Player " & ¬ currentPlayer & "'s Turn" end if end tell end SwitchPlayers
The SwitchPlayers() handler is responsible for controlling whose turn it is. This is controlled by changing the value of currentPlayer from X to O or O to X as appropriate. Also take note that each time the current player is switched, the text field control located at the bottom of the game window is updated by displaying a text string that identifies whose turn it is.
Creating the SeeIfGameOver() Handler The code for the SeeIfGameOver() handler is outlined below. This handler accepts one argument, which represents the player that has won the game or a value of InProgress, in which case the game may or may not be over.
Chapter 9 • Controlling Other Applications
--This handler determines when the current round of play has ended on SeeIfGameOver(gameWinner) tell window "main" --Direct commands to the "main" window if gameWinner = "X" then --Player X has won --Display message that identifies Player X as the winner set content of text field "txtStatus" to "Player X wins!" set enabled of button "btnPlay" to true --Enable the Play button say "Player X wins!" using "Victoria" --Announce winner return "GameOver" --Return value indicating the end of the game else if gameWinner = "O" then --Player O has won --Display message that identifies Player X as the winner set content of text field "txtStatus" to "Player O wins!" set enabled of button "btnPlay" to true --Enable the Play button say "Player O wins!" using "Victoria" --Announce winner return "GameOver" --Return value indicating the end of the game else if noMoves = 9 then --A tie has occurred --Display message that identifies a tied game set content of text field "txtStatus" to "Tie." set enabled of button "btnPlay" to true --Enable Play button say "Tie. There is no winner." using "Victoria" --Announce winner return "GameOver" --Return value indicating the end of the game end if end if return "" --Return value indicating that the game is not over
281
282
AppleScript Studio Programming for the Absolute Beginner
end tell end SeeIfGameOver
This handler is organized using an if…else if code block, which itself resides inside a tell code block. The first condition tested is whether the argument passed to the handler is X. If it is, Player X is declared the winner, the Play button is enabled, the text message Player X wins! is displayed, and a value of GameOver is returned. The next condition tested is whether the value of gameWinner is O. In the event that neither Player X nor Player O has won the game, the value of noMoves is checked to see if it is equal to 9. If this is the case, then all nine game board squares have been selected without either player winning. In this circumstance, a tie is declared. If neither Player X nor Player O has won the game and a tie has not occurred, an empty string is returned to the calling statement and game play continues.
Creating the DisableSquares() Handler The code for the DisableSquares() handler is outlined next. When called, this handler disables all of the game board squares in order to prevent the players from being able to select them until a new round of play is started. --This handler disables all game board squares (button controls) to --prevent players from clicking on them when the game is over on DisableSquares() tell window "main" --Direct commands to the "main" window --Disable all game board squares (button controls) set enabled of button "btnA1" to false set enabled of button "btnA2" to false set enabled of button "btnA3" to false set enabled of button "btnB1" to false set enabled of button "btnB2" to false set enabled of button "btnB3" to false set enabled of button "btnC1" to false set enabled of button "btnC2" to false set enabled of button "btnC3" to false
Chapter 9 • Controlling Other Applications
283
end tell end DisableSquares
Step 5: Testing the Execution of the Tic-Tac-Toe Game Okay, at this point you should have all the required code statements written for the Tic-TacToe game. As long as you don’t have any typos lying around, you should be good to go. Go ahead and crank up the game and see how it works. In the next chapter you will learn how to perform advanced error handling and debugging. For now, if any errors are reported, you will have to rely on the error information provided to track down and fix any typos that you may have made. Once any typos have been corrected, you can begin testing your new game. When testing it, be sure that you validate that both Player X and Player O can win the game and that ties are correctly detected.
SUMMARY In this chapter you learned how to use the tell command to create AppleScript Studio applications that can take control of and automate the execution of Mac OS X applications. As a result, you now know how to use application dictionaries to find the classes, elements, properties, and commands needed by your AppleScript Studio applications to build new applications that combine the capabilities of many different applications under a single, consolidated user interface. Using the information provided in this chapter, you can now develop applications that automate repetitive tasks, saving you time and simplifying the execution of complex tasks. Among the list of applications that you learned how to work with are TextEdit, Safari, iTunes, Finder, Mail, DVD, Help View, and Terminal. Before you move on to Chapter 10, “Debugging and Error Handling,” why don’t you take a few extra minutes to improve the Tic-Tac-Toe game by implementing the following list of challenges.
284
AppleScript Studio Programming for the Absolute Beginner
CHALLENGES 1.
2.
3. 4.
5.
As currently written, the Tic-Tac-Toe game’s Instructions button launches Safari but does not point to an actual website. Supply the URL of your personal website. Alternatively, surf the web and supply the URL of a website that explains the rules of Tic-Tac-Toe. Consider expanding the size of the Tic-Tac-Toe window in order to make room for game statistics that show players the number of games won, lost, and tied. If you feel up to a real challenge, try creating a player versus computer version of the Tic-Tac-Toe game. The Tic-Tac-Toe game displays information at the bottom of the window that identifies whose turn it is as well as when a game is won or tied. Consider expanding the information provided here to include an explanation of how games are won. For example, you might modify the output text to state that Player O has won horizontally, on the first row. In order to make winning results easier to identify, consider creating a new set of X and O image files that have a different background color. You can then display whichever of these files is appropriate at the end of the game in place of the three bevel button controls that identify the winning moves.
10 C H A P T E R
DEBUGGING AND ERROR HANDLING ongratulations on making it to the last chapter of this book. This chapter helps to round out your programming foundation by teaching you how to find and fix errors in your AppleScript Studio applications. In doing so, you will learn how to work with the Xcode debugger. This tool provides you with everything that you need to pause script execution to view and even modify variable values or to take control of execution flow. You will also learn how to use the try statement to develop error handling logic and implement Help Tips and use the Help button control as a way of providing users with access to application help. On top of all this, you will learn how to create your final AppleScript Studio game, the Poker Dice game.
C
Specifically, you will learn how to • Handle errors using the try statement • Run your AppleScript Studio applications using the Xcode debugger • Set breakpoints that pause application execution • View variable values and monitor script execution
286
AppleScript Studio Programming for the Absolute Beginner
PROJECT PREVIEW: THE POKER DICE GAME This book’s final game project is the Poker Dice game. This game is loosely based on the popular card game. Winning hands include three, four, or five of a kind and a full house, as well as a high straight and a low straight. Instead of cards, this game is played with five virtual dice. When first started, the Poker Dice game board displays five image view controls representing each of the game dice, as shown in Figure 10.1.
FIGURE 10.1 The player clicks on the Roll button to generate her initial hand.
The Poker Dice game displays help information in the form of Tool Tips when the player moves the pointer over text field and button controls. Figure 10.2 shows an example of a Tool Tip that is displayed when the player moves the pointer over the game’s text field control.
FIGURE 10.2 Help Tags offer programmers the ability to provide the player with information about the functionality provided by interface controls.
Chapter 10 • Debugging and Error Handling
287
Help is also made available to the player via a Help button located at the bottom left-hand corner of the game window. When clicked, the Poker Dice Help window is opened. As demonstrated in Figure 10.3, the player can navigate and read the information stored in this window using the scroll bar located on the right-hand side of the window.
FIGURE 10.3 Help is just a button click away.
Figure 10.4 provides an example of a typical first roll. As you can see, the player has two pair, which is not a winning hand in Poker Dice.
FIGURE 10.4 Each die represents a randomly generated value between 1 and 6.
288
AppleScript Studio Programming for the Absolute Beginner
After the first roll, the player can elect to hold or roll again. Before rolling an optional second time, the player has the opportunity to hold onto as many existing dice (rolls) as she wishes by selecting the switch control just under the die to be retained, as demonstrated in Figure 10.5.
FIGURE 10.5 In this example the pair of fives is being held.
At the end of the second roll, the game reviews the player’s final hand and displays the results in the text view control located at the bottom of the game window, as demonstrated in Figure 10.6.
FIGURE 10.6 The player’s second roll has resulted in a losing hand.
Chapter 10 • Debugging and Error Handling
289
Figure 10.7 shows an example of a winning hand. At the end of the player’s second roll, she has managed to get four 4s. Note that before the first roll, only the game’s Roll button is enabled, and after the second roll, this button is disabled, and the Hold and Roll Again buttons are enabled, thus ensuring that the player always knows which options are valid at any point in the game.
FIGURE 10.7 An example of a winning hand.
FINDING WAYS OF HANDLING ERRORS As you continue to spend time developing AppleScript Studio applications, you are going to be developing more and more powerful and complex applications. As a result, you will inevitably run into errors. There are a number of good programming practices that you can follow to help keep your errors to a minimum, including: • Taking extra time to plan out the design of your application code before you begin writing it • Designing simple and straightforward user interfaces • Making sure that you provide plenty of instruction and help for your users • Including additional logic that validates and forces the user to supply acceptable input • Developing your AppleScript files in a modular fashion using custom handlers • Using consistent naming schemes for variables and handlers • Anticipating places within your AppleScript files where errors may occur and adding additional programming logic to deal with potential errors • Thoroughly testing your applications, making sure that you test every piece of functionality
290
AppleScript Studio Programming for the Absolute Beginner
HIN
T
Application errors are sometimes referred to as bugs. It’s your job as a programmer to locate and eliminate all bugs from your AppleScript Studio applications.
DIFFERENT TYPES OF ERRORS Like any modern programming language, AppleScript Studio applications are subject to three types of errors, as listed here. • Syntax errors • Logical errors • Runtime errors Each of these three types of errors is examined in the sections that follow.
Syntax Errors There is no doubt that syntax errors are by far the most common type of error. Syntax errors occur whenever programmers fail to follow AppleScript’s rules when writing script statements. For example, a syntax error will occur if you mistype an AppleScript keyword or omit a required command parameter. One of the most common causes of syntax errors is typos, which can obviously be eliminated by carefully keying in your script statements. Syntax errors are generally easy to identify because Xcode will not be able to compile your AppleScript Studio applications if they contain syntax errors. Instead, Xcode will flag syntax errors by displaying error messages. You will know that your AppleScript Studio application has an error when it fails to compile and instead displays a red X at the bottom right-hand corner of the Xcode Project and Code Editor windows. You can view these errors by either double-clicking on the red X icon or by expanding the Errors and Warning entry in the Groups & Files pane in the Xcode Project editor. Each error message that Xcode displays includes a brief description as well as the line number of the statement where the error occurred. You go immediately to the statement where the error resides by double-clicking on the error message. Unfortunately, while Xcode does a really good job of identifying errors, the error messages that are displayed are often less than helpful, usually displaying an error description message that is difficult to understand. Still, being able to locate the area within your AppleScript file responsible for syntax errors is extremely helpful and is often all that you will need to track down and fix your syntax errors.
Chapter 10 • Debugging and Error Handling
291
Logical Errors A logical error occurs when a programmer makes a mistake in the way the code for an application is designed. For example, a logical error would occur if you were to write a code statement that was supposed to multiply two values but instead subtracted one number from another. Obviously, the end result could be a value that is significantly different from what was intended. Another example of a logical error is an endless loop, in which you fail to provide a way to terminate the loop’s execution. For example, consider the following example. set x to 1 repeat until x > 5 set x to x - 1 end repeat
Here, the intent was to create a loop that would execute five times and then stop. However, instead of incrementing the value of x by 1 upon each iteration of the loop, the value of x was accidentally set to decrement by 1. Unfortunately, logical errors are not caught when your AppleScript Studio application is compiled because from the compiler’s point of view, nothing is wrong. However, when executed, your application will behave in an unexpected manner. The best way to deal with logical errors is to prevent them from occurring in the first place by carefully planning out the logic of your AppleScript file before you begin keying in your script statements. Even the most experienced programmer will run into logical errors from time to time. Fortunately, as you will see later in this chapter, you can use Xcode’s built-in debugger to track down and correct logical errors. The Xcode debugger allows you to monitor the logical flow of your script statements and to keep on eye on variable values in order to make sure that they are being modified as you’d expect.
Runtime Errors Runtime errors occur when an AppleScript statement attempts to perform an illegal action. For example, the following statement would result in a runtime error. set x to 5 + "five"
In this example, AppleScript in unable to coerce the string "five" to a numeric value. By the same token, a similar type of error would occur if you used the display dialog command to collect and add together two numeric values that were supposed to be provided by the user and the user instead entered a text string in place of one of the numeric values. As you can see, it is very important that you include additional logic to your AppleScript Studio
292
AppleScript Studio Programming for the Absolute Beginner
applications to validate, as best possible, any user input. Fortunately, as you will see later in this chapter, you can add error handling to your AppleScript files to deal with many different types of runtime errors. Like logical errors, the compiler will not be able to flag runtime errors in your AppleScript Studio applications. Runtime errors only make themselves known when the application executes. A runtime error will result in an error message and will most likely cause your application’s immediate termination. Since you obviously do not want your users to experience runtime errors for any applications that you develop, you will want to make sure that you spend plenty of time testing your applications to make sure that you identify and fix any potential runtime errors. One way of doing so is developing your AppleScript files in a modular fashion, using custom handlers, and thoroughly testing each handler as it is developed. When testing, make sure that you execute your application as you intend for it to be run. In addition, spend time testing in ways that you do not intend for it to be run. By this I mean, for example, that you should try entering invalid data to see how your application deals with it. Another way of preventing runtime errors is to spend time running it using Xcode’s built-in debugger in order to validate that everything is executing as you expect. You will learn how to run your AppleScript Studio application using Xcode’s debugger later in this chapter.
HANDLING ERRORS As has been stated, runtime errors occur for all kinds of reasons. For example, the user may provide an unexpected type input, or a needed file or drive may be missing. In order for your AppleScript Studio applications to handle these types of situations, you must anticipate areas within your AppleScript where errors may occur and then add code that attempts to prevent these errors from creating havoc. Of course, not all errors can be prevented. Still, its it your job as a programmer to keep errors to a bare minimum. For example, you might add programming logic to validate user input, rejecting any input that does not satisfy the application’s requirements. You might alternatively substitute default values.
Using the try Statement to Catch Errors One major tool provided by AppleScript for combating errors is the try command. This command lets you create a code block within which any errors that occur are caught, thus preventing them from crashing your application. For example, consider the following example.
Chapter 10 • Debugging and Error Handling
293
set x to "five" set y to 5 set z to 0 set z to x + y display dialog z HIN
T
In this example and the examples that follow, the value of x is hardcoded as the first statement in the example. However, the value of x could just as easily be collected by prompting the user to key it in as a response to a popup, in which case the user might or might not provide valid input.
Here three variables are defined and assigned initial values. Next, x and y are added together and assigned to z. However, x is a string value that AppleScript is not able to coerce into a number. When executed, an error occurs and is displayed in a popup dialog. The text of the error message that is displayed is Can’t make "five" into type number. (- 1700). After the error message is dismissed, your application will stop executing. As a result, the final display dialog statement never executes. One way of dealing with this type of error is to wrap up the statement that generates the error inside a try code block, as demonstrated here. set x to "five" set y to 5 set z to 0 try set z to x + y end try display dialog z
In this example, the error still occurs but is not displayed. As a result, the closing display dialog statement executes, displaying a value of 0 (e.g., its initial value is displayed since it
was never modified as a result of the error). TRI
CK
You may enclose as many programming statements as you wish within a try code block. The first statement within the try block to produce an error is caught, and all statements that follow are skipped, even if they also contain errors.
294
AppleScript Studio Programming for the Absolute Beginner
While the previous example prevents the error that occurred from being displayed or crashing the application, it does not really handle the error. One way of handling an error in a simple example like this one is to provide a substitute value. To accomplish this feat, you must expand the try code block by adding the on error keywords. When added, any statements that follow on error are executed in the event an error occurs in any statement that follows the opening try statement and occurs before the on error keywords. For example, consider the following example. set x to "five" set y to 5 set z to 0 try set z to x + y on error set x to 0 set z to x + y end try display dialog z
In this example, the variable x is set equal to 0 in the event of an error. Next, the statement that failed is re-executed. Assuming that no errors occur when the statement is re-executed, the final statement is then executed, displaying a value of 5. TRI
CK
Another useful application of the try command is to prevent the display dialog command from prematurely terminating your application in the event the user clicks on the default Cancel button instead of the OK button. For example, consider the following statements. set userName to "" try set userName to the text returned of ¬ (display dialog "Enter your name: " default answer "") end try display dialog "Hello " & userName
The expectation here is that the user will key in her name and click on OK, at which point a popup dialog greeting the user by name will be displayed.
Chapter 10 • Debugging and Error Handling
295
However, if instead of clicking on the default OK button, the user clicks on the Cancel button, the script catches the resulting error, preventing it from terminating the application. The user is then greeted by a generic Hello message.
Catching Specific Types of Errors AppleScripts are subject to many different types of errors. Each of these errors has a specific error message and error number associated with it. You may find it helpful to capture and display this information. This can be done by adding additional arguments to the on error keywords as demonstrated in the next example. set x to "five" set y to 5 set z to 0 try set z to x + y on error errorMessage number errorNumber display dialog "Error: " & errorMessage & return & "Number: " & ¬ errorNumber buttons {"OK"} set x to 0 set z to x + y end try display dialog z
Here, the error message and error number generated by the first error that occurs within the try portion of the code block are assigned to variables named errorMessage and errorNumber and then displayed by a display dialog statement. If you want, you can also develop error recovery logic that executes only if a specific type of error occurs by specifying an error number as an argument to the on error keywords, as demonstrated in the following example. set x to "five" set y to 5 set z to 0 try set z to x + y on error number -1700
296
AppleScript Studio Programming for the Absolute Beginner
display dialog "Error: Invalid input! Default value used." buttons {"OK"} set x to 0 set z to x + y end try display dialog z
In this example, the on error portion of the try code block executes only if an error message with an error number of –1700 is generated.
KEEPING A WATCHFUL EYE ON YOUR APPLESCRIPT STUDIO APPLICATIONS As with any programming language, it is important that you follow a disciplined and consistent style when developing your applications. For example, it’s a good idea to assign names to any object with which you may need to programmatically interact. This includes any application windows and most interface controls. For example, in every example in this book, the application’s main window has been named main. In addition, I have tried to be consistent in naming application interface controls. For example, I have frequently applied a threecharacter prefix to each interface control. I used btn as the prefix for button control names, txt as the prefix for text file control names, and imv as the prefix for image view control names, just to name a few examples. By applying a consistent name standard, you can eliminate lots of simple syntax errors as well as make your code more self-documenting. Still, even the most disciplined programmer is going to run into errors. Fortunately, there are plenty of ways that you can keep an eye out for problems so that you can identify and fix them before your users see them. These debugging techniques are discussed in the sections that follow.
Writing Output to the Log You’ll notice the appearance of the Xcode Run Log window when you build and run an AppleScript Studio application. For the most part, this window does not provide any information that you need to pay attention to. However, using the log statement, you can display any text string in the Run Log window. Thus, by inserting log statements at key points within your scripts, you can display messages indicating when key events occur. For example, to monitor execution flow within your script, you might include a log statement at the beginning or end of each handler in your application. You might also use log statements to display the values of specific variables every time they change. In this way, you can keep an eye on key aspects of your applications while they run.
Chapter 10 • Debugging and Error Handling
297
The log statement has the following syntax. log message message is a placeholder representing any text string you want to display in the Run Log
window. For example, the following statement provides an example of how to write a message to the Run Log window. Figure 10.8 shows the results of executing this statement. Log "Error – Invalid user input supplied"
FIGURE 10.8 Displaying a text message inside Xcode’s Run Log window.
Unfortunately, as useful as the log statement can be, it is really only practical for small AppleScript Studio applications. As your applications grow longer and more complex, it becomes too much of a burden to log too much information to the Xcode Run Log. Fortunately, this is where the Xcode debugger comes into play, providing you with a tool that is tailor made for debugging even the most complex AppleScript applications.
Displaying Useful Information in Popup Dialogs In addition to writing text output to the Xcode Run Log window, you can also use the display dialog command as a convenient way to display small amounts of data when developing and testing out different parts of your application. For example, instead of writing a text string to the Xcode Run Log window, as was demonstrated in the previous example, you could just as easily use the display dialog command to display the same information in a popup dialog, as demonstrated in Figure 10.9.
298
AppleScript Studio Programming for the Absolute Beginner
FIGURE 10.9 The display dialog command can be used to display small amounts of information that aid in tracking execution flow and variable values.
Using Sound to Indicate when Key Events Occur The problem with using the Xcode Run Log window to keep an eye on key events that you have chosen to monitor when testing your AppleScript Studio applications is that you have to make room for it on your screen in order to be able to see it when running your applications. While the display dialog command does not require you to set aside room for an extra window, it does require you to keep clicking on the OK button to dismiss popup windows to allow your application to keep running. Another option that you might consider is to inset the beep command in place of the log or display dialog command, thus providing you with an audio indication of when a specific event has occurred. Admittedly, the beep command has limited usefulness in debugging; however, if all that you want to do is get notified when a particular type of event occurs, the beep command can be particularly handy. Another alternative to the beep command is the say command, which triggers the Mac OS X voice synthesizer to recite any text messages that you might otherwise have displayed.
Reviewing Error Messages Another way to keep track of what is happening in your applications is to pay close attention to error messages that are generated whenever Xcode is unable to compile your AppleScript Studio applications. Error messages provide a brief description of the error that has occurred and the line number associated with the error. As you have already seen, error messages are not always easy to understand. In addition, error numbers do not always indicate the exact line where an error has occurred. However, on the occasions that error numbers do not point you to the exact lines, they usually get you close enough to help you locate your errors. The first indication that something has gone wrong is when your application does not appear or start executing after you have told Xcode to compile and run it. When this happens, a red X will be displayed in the bottom right-hand corner of the code editor, as demonstrated in Figure 10.10, letting you know that one or more errors have been found.
Chapter 10 • Debugging and Error Handling
299
FIGURE 10.10 A small red X icon located in the lower right-hand corner of the code editor window lets you know when an error has occurred.
To view these errors, double-click on the red X. In response, Xcode will display its Debugger window and show you the errors that have been flagged, as demonstrated in Figure 10.11.
FIGURE 10.11 Viewing script errors using Xcode’s built-in debugger.
300
AppleScript Studio Programming for the Absolute Beginner
To view additional information about an error, you can click on the disclosure triangle just to the left of the error message. Another way to view error messages is from the Errors and Warning entry in the Groups & Files pane of the Xcode Project window, as shown in Figure 10.12. Xcode populates the Errors and Warning entry with any errors discovered during the build process.
FIGURE 10.12 Viewing errors from within the Xcode Project window.
DEBUGGING YOUR APPLESCRIPT STUDIO APPLICATIONS While you can locate and fix many different types of bugs using the techniques already discussed in this chapter, there will be times when you need to dig deeper and monitor your applications at a more detailed level. Fortunately, Xcode provides you with access to a worldclass debugger that you can use to track down and fix applications bugs. The Xcode debugger provides many advanced features, including the ability to • Pause execution at predefined breakpoints • Monitor and change variable values • Control step-by-step statement execution
Running Your AppleScript Studio Applications in the Debugger To begin a debugging session, you can click on the Build and Debug option located on the Build menu or click on the Debugger option located under the Debug menu. In response, the Xcode Debugger window is displayed, as demonstrated in Figure 10.13.
Chapter 10 • Debugging and Error Handling
301
Toolbar Thread View
Variable View
Editor
FIGURE 10.13 Using the Xcode debugger to run your AppleScript Studio application.
The Xcode debugger is organized into four major parts. The Thread view shows a history indicating which handlers have been executed. The Variable view lets you view and modify variable values. The editor lets you view and modify your code. The toolbar provides easy access to commands that provide you with detailed control over the execution of your application. The icons listed below represent each toolbar command. • Build and Debug. Loads the current project into the debugger and starts a debug session. • Terminate. Stops the current debugging session. • Fix. Compiles a single fix, allowing the debug session to continue without starting over. • Restart. Restarts the debug session. • Pause. Pauses the debug session. • Continue. Continues a paused debug session. • Step Over. Runs the remaining statements in the current handler, stopping at the beginning of the next handler. • Step Into. Runs a single statement and then pauses within the current handler. • Step Out. Finishes running the remaining statements in the current handler and then pauses at the beginning of the next handler. • Breakpoints. Adds or removes a breakpoint at the current line. • Breakpoints (window). Opens the Breakpoints window, where you can view and configure breakpoint settings. • Console. Opens the Debug Console, allowing command-line debugger access.
302
AppleScript Studio Programming for the Absolute Beginner
Setting Breakpoints A breakpoint is a marker that identifies a statement or handler at which the application execution halts. The debugger executes the last line of code just before the breakpoint and pauses. The debugger identifies breakpoints by placing a red arrow just to the right of the statement or handler in an area of the editor known as the gutter. When running an application, the debugger automatically pauses at and highlights the first breakpoint it finds, as demonstrated in Figure 10.14.
FIGURE 10.14 The debugger highlights the current breakpoint when it pauses execution.
To set a breakpoint, click on the gutter area just to the right of a statement or handler. Alternately, place the cursor somewhere on the statement or handler where you want to add a breakpoint and click on the first Breakpoints icon in the debugger toolbar. To remove a breakpoint, Control+click on it and select Remove Breakpoint or place the cursor somewhere on the statement or handler where the breakpoint resides and click on the first Breakpoints icon in the debugger toolbar. When debugging, you will want to place breakpoints at statements within your AppleScript file where you think a problem may occur. When you click on the Build and Debug icon in the debugger toolbar, the application will start and run until it reaches a breakpoint, at which time execution pauses. While paused, you can view the contents of the Thread view and
Chapter 10 • Debugging and Error Handling
303
Variable view in order to see what handler is being executed and the values of any variables used in the handler. This way, you can verify that variable values are being set correctly. HIN
T
The contents of the Variable view are organized into different categories, which you can view by clicking on the disclosure triangle to the left of each category.
By setting breakpoints at the right locations within your AppleScript files and then reviewing information provided in the Thread view and Variable view, you can observe the order in which your script’s execution flow has proceeded and validate the contents of variables. As a result, you can track down and fix errors that might not be easily revealed using the other debugging tricks mentioned in this chapter.
Controlling Statement Execution Once a breakpoint has been reached and your application pauses, you continue script execution by clicking on the Continue icon in the debugger toolbar. Execution resumes and continues until either another breakpoint is reached or the application finishes executing. However, many times you will want to take control of how the debugger executes your application, so that you can continue to pause its execution and keep an eye on handler execution and the values of your variables. This is accomplished by clicking on any of the following toolbar icons. • Step Over. Executes all of the statements in a handler, pausing execution again before the execution of the next handler. • Step Into. Executes the next statement within the current handler and then pauses script execution again. • Step Out. Executes the remaining statements in the current handler and pauses script execution at the beginning of the next handler. TRI
CK
Errors can occur for all kinds of reasons within AppleScript Studio applications. There may be times when you are unable to determine the source of a particular error. In these situations, you may find that you need to turn to a more experienced programmer for help. However, one trick that you might try first is a clean operation. Among other things, a clean operation tells Xcode to remove temporary files created by Xcode. This is often all that is needed to correct a mysterious behavior. To clean your project, click on the Clean All Targets option located under the Build menu.
304
AppleScript Studio Programming for the Absolute Beginner
BACK TO THE POKER DICE GAME Now it is time to turn your attention back to the development of the Poker Dice game. As you work on this game, you will learn two new programming techniques, including how to set up Tool Tips and how to use the Help button to display a customized help window. You will also learn how to connect the game’s Help window to the Help button in order to display the Help window without having to write any program code.
Step 1: Creating a New Project If you are ready to begin, let’s start by creating a new AppleScript Studio project, as outlined by the following procedure. 1. Click on the File menu and select New Project. An Assistant is launched, displaying a list of application templates. 2. Select AppleScript Application template and click on Next. 3. When prompted, specify Poker Dice as the file name for the application and then specify the folder where you would like to store this AppleScript Studio application. 4. Click on the Finish Button.
Step 2: Creating the Game’s Windows The Poker Dice game is made up of two windows, the game’s main window and a Help window. Instructions on how to set up these two windows are provided in the next two sections.
Setting Up the Main Window The next step in the development of the Poker Dice game is to create the graphical user interface for its main window, as outlined in the following procedure. 1. Locate the MainMenu.nib file located in the Resources group and then double-click on it to start the Interface Builder. 2. Resize the default window so that it is approximately 4.25 inches wide by 4.5 inches tall. 3. Drag and drop five image view controls onto the window, placing them side by side horizontally at the top of the window. 4. Drag and drop five switch controls to the window, placing the switch controls immediately beneath the game’s image view controls. Double-click on each switch control and enter Hold as their title attributes. 5. Drag and drop three button controls to the window, aligning them horizontally across the middle of the window. Double-click on each button control and enter Roll, Hold, and Roll Again as their title attributes. 6. Drag and drop an instance of the text field control to the window, resizing it so that it takes up most of the width of the window and can display approximately five lines of
Chapter 10 • Debugging and Error Handling
305
text. Leave about two-thirds of an inch between the bottom of the text field control and the bottom of the window. 7. Drag and drop an instance of the system font text control to the window, placing it just above the upper left-hand corner of the text field control. Double-click on the control and enter R esults: as its title attribute. 8. Finally, drag and drop an instance of the Help button control to the lower left-hand corner of the window. At this point the basic construction of the game’s main window is complete and should resemble the example shown in Figure 10.15.
FIGURE 10.15 The user interface for the game’s main window is now complete.
HIN
T
By convention and according to the Aqua guidelines, the Help button control should be placed in the lower left-hand side of the window.
Setting Up the Help Window The Poker Dice game provides the player with access to a Help window where instructions for playing the game are displayed. The steps required to set up this window are outlined here. 1. Drag and drop an instance of a regular window from the Cocoa Windows view of the Interface Builder’s Controls palette to the MainMenu.nib folder. 2. Double-click on the new window to open it. 3. Drag and drop an instance of the text field control onto the new window.
306
AppleScript Studio Programming for the Absolute Beginner
4. Resize the text field control so that it takes up most of the available room on the window, as demonstrated in Figure 10.16.
FIGURE 10.16 The game’s Help window consists of text displayed inside a text field control.
5. Double-click on the text field control and enter the following text: INSTRUCTIONS: Poker Dice is played with five virtual dice and is loosely based on the card game Poker. You are permitted a maximum of two rolls per play. Click on the Roll button to make your first roll. The results of that roll are then displayed at the top of the game window. You may stick with your current hand by clicking on the Hold button or roll again by clicking on the Roll Again button. If you wish, you may select one or more die from your first roll to hold onto before making your second roll by selecting the checkbox control located under each die that you wish to keep. The results of each round of play are displayed at the bottom of the game window. The following combinations of values constitute winning hands: • Five of a kind • Four of a kind • Three of a kind • Full house • Low straight • High straight Any other combinations of values result in a losing hand. At this point, the basic construction of the game’s Help window is complete.
Chapter 10 • Debugging and Error Handling
307
Step 3: Customizing Control Properties Before you start the coding process, you need to spend a few moments configuring the application’s menu system, windows, and interface control attributes. In addition, you need to configure each of the game’s three button controls to respond to click events. You also need to set up the display of the game’s Help window.
Customizing Application Menus To set up the Poker Dice game’s menu system, you will need to delete a number of unnecessary menus and menu items. For starters, remove the Edit and Help menus and then delete all the menu items on the Window menu except for the Minimize menu item. Next, select the File menu and remove each menu item except for the Close menu item. Finally, customize the Application menu as outlined here. 1. 2. 3. 4.
Double-click on the Application menu and replace its name with Poker Dice. Modify the About Application menu item to read About Poker Dice. Modify the Hide Application menu item to read Hide Poker Dice. Modify the Quit Application menu item to read Q uit Poker Dice.
Modifying Window and Interface Control Attributes The last step in setting up the game’s user interface is to configure the game’s window and interface controls. The modifications required for these objects are outlined in Table 10.1.
TABLE 10.1
MODIFICATIONS TO THE POKER DICE WINDOWS INTERFACE CONTROLS
Object
Attribute
Modification
Window
Image View
Name Window Title Zoom name
Image View
Enabled name
Image View
Enabled name
main Poker Dice Disabled imvDie1 _.bmp Disabled imvDie2 _.bmp Disabled imvDie3 _.bmp Disabled
Enabled
AND
308
AppleScript Studio Programming for the Absolute Beginner
Image View
name
Image View
Enabled name
Switch Switch Switch Switch Switch Button Button
Button
Text Field
Help Button Window
Text Field (Help window)
TRI
CK
Name Name Name Name Name Name Sound Name Sound Enabled Name Sound Enabled Name Editable Selectable Layout Line Breaking Name Name Window Title Zoom Visible at launch time Selectable Editable
imvDie4 _.bmp Disabled imvDie5 _.bmp chkHold1 chkHold2 chkHold3 chkHold4 chkHold5 btnRoll Tink btnHold Tink Disabled btnRollAgain Tink Disabled txtResults Disabled Disabled Wraps Word Wrap Help help Poker Dice Help Disabled Disabled Disabled Disabled
One new feature demonstrated in the Poker Dice game is the inclusion of Tool Tips for the switch, button, and text field controls. These Tool Tips display a short text string that players will see when they move and hold the pointer over one of these controls for a few moments. Tool Tips provide programmers with the opportunity to display small bits of information regarding what individual controls do.
Chapter 10 • Debugging and Error Handling
309
Tool Tips are easy to set up. Simply select a control, open the Inspector window, select the Help view, and key in the appropriate text in the Tool Tip field. Table 10.2 shows the text strings that you should configure for each of the Poker Dice game’s controls.
TABLE 10.2
TOOL TAG MESSAGES
FOR THE
Control
Help Tag
chkDie1 chkDie2 chkDie3 chkDie4 chkDie5 chkDie6 btnRoll bthHold btnRollAgain txtResults btnHelp
Hold onto die Hold onto die Hold onto die Hold onto die Hold onto die Hold onto die Roll the dice Hold all dice Roll non-selected dice again View game results Poker Dice help
POKER DICE GAME
Configuring Event Handlers The Poker Dice game has three button controls that you need to associate with the click event. As a result, each of the game’s three button controls will be able to initiate the execution of code statements in the game’s AppleScript file.
Controlling the Display of the Game’s Help Window While you can certainly add program code to the application’s AppleScript file in order to control the display of the game’s Help window, there is a quicker and easier way to set up the process. Specifically, you can Control+draw a link from the Help button control on the main window to the title bar of the Help window. In order to accomplish this task, both windows must be visible. Figure 10.17 demonstrates how things will look once the Help button and the Help windows have been linked together. TRI
CK
To Control+draw the link required above, click on the Help button while simultaneously holding down the Control key. While still holding the Control key, move the mouse over to the title bar of the other window and then release the Control button. As you perform this action, you see that a shaded line follows your mouse, visually identifying the link you are establishing.
310
AppleScript Studio Programming for the Absolute Beginner
FIGURE 10.17 Control+drawing a link between the game’s Help button and the Help window.
Once this link is established, the Inspector window opens, displaying its Connections view. Click on the Target/Action tab and select the orderFront entry and then click on Connect as demonstrated in Figure 10.18. This will ensure that the Help window is opened each time the user clicks on the main window’s Help button.
FIGURE 10.18 Configuring the display of the Help window.
Chapter 10 • Debugging and Error Handling
311
Step 4: Adding a Little Programming Logic The next step in the development of the Poker Dice game is the development of the AppleScript code required to operate the game. Assuming that you have already set up the connection to the on clicked event handler for each of the game’s three button controls, your application’s AppleScript file should resemble the following statements as you prepare to begin the coding process. -- Poker Dice.applescript -- Poker Dice --
Created by Jerry Ford on 8/29/06.
--
Copyright 2006 - Jerry Lee Ford, Jr. All rights reserved.
on clicked theObject end clicked
The Poker Dice game is played using five dice. These dice are represented by five variables. These variables’ values are used by various handlers throughout the script. To make access to the variables easy, let’s make them global by inserting the following statements into the script file just before the on clicked theObject statement. --Define global variables global die1, die2, die3, die4, die5
Next, let’s assemble the overall controlling logic for the AppleScript. The statements that make up this portion of the script file, shown below, must be placed inside the on clicked event handler. if name of theObject is "btnRoll" then --The player clicked on Roll set {die1, die2, die3, die4, die5} to FirstRoll() --Roll die DisplayFirstRoll() --Display results of first roll end if if name of theObject is "btnHold" then --The player clicked on Hold ResetButtonControls() --Reset button controls to default settings
312
AppleScript Studio Programming for the Absolute Beginner
ClearSwitches() --Reset Switch control to default settings CheckGameResults() --Determine whether the player won or lost end if --The layer clicked on Roll Again if name of theObject is "btnRollAgain" then set {die1, die2, die3, die4, die5} to SecondRoll() --Roll die again DisplaySecondRoll() --Display results of second roll ResetButtonControls() --Reset button controls to default settings ClearSwitches() --Reset Switch control to default settings CheckGameResults() --Determine whether the player won or lost end if
As you can see, the script’s controlling logic is organized into three separate if statement code blocks. The first if statement code block executes when the player clicks on the Roll button. It is responsible for executing the FirstRoll() handler, which generates the values for the player’s first roll of the dice. This handler returns a list representing the dice rolls, which are then assigned to the script’s five global variables. Next, the DisplayFirstRoll() handler is called. This handler displays the results of the first roll in the five image view controls on the game’s main window. The second if statement code block executes when the player clicks on the Hold button. It calls three custom handlers, which are executed in the order outlined here. • ResetButtonControls(). This handler is responsible for resetting the game’s three button controls back to their starting status. • ClearSwitches(). This handler clears out all five of the game’s switch controls. • CheckGameResults(). This handler analyzes the player’s hand and determines whether the player wins or loses.
Chapter 10 • Debugging and Error Handling
313
The third if statement code block executes when the player clicks on the Roll Again button. It begins by calling on the SecondRoll() handler, which re-rolls any dice not held by the player. The dice values are then returned as a list. Next, the remainder of the third if statement code block executes, calling on the following handlers in the order listed below. • DisplaySecondRoll(). This handler is responsible for displaying the player’s final hand. • ResetButtonControls(). This handler is responsible for resetting the game’s three button controls back to their starting status. • ClearSwitches(). This handler clears out all five of the game’s switch controls. • CheckGameResults(). This handler analyzes the player’s hand and determines whether the player wins or loses. The rest of the AppleScript file consists of all the custom handlers discussed in this chapter. These handlers are explained in detail in the sections that follow.
The FirstRoll() Handler The code statements that make up the FirstRoll() handler are shown below. This handler is responsible for generating the player’s opening roll. --This handler is responsible for generating the results of the first roll on FirstRoll() --Generate 5 random numbers in the range of 1 - 6 set roll1 to random number from 1 to 6 as integer set roll2 to random number from 1 to 6 as integer set roll3 to random number from 1 to 6 as integer set roll4 to random number from 1 to 6 as integer set roll5 to random number from 1 to 6 as integer --Return the results of the roll as a string to the calling statement return {roll1, roll2, roll3, roll4, roll5} end FirstRoll
As you can see, each of five rolls is generated using the Random Number command. A number in the range of 1–6 represents each roll. The results of each roll are then returned as a list to the statement that called this handler.
314
AppleScript Studio Programming for the Absolute Beginner
The DisplayFirstRoll() Handler The code statements that make up the DisplayFirstRoll() handler are shown next. This handler is responsible for displaying the results of the player’s initial roll by displaying graphic dice images in each of the five image view controls located at the top of the main game window. --This handler displays the results of the first roll on DisplayFirstRoll() tell window "main" --Direct commands to the window named main --Display bitmap images representing each die that was rolled set image of image view "imvDie1" to load image ¬ (die1 & ".bmp" as string) set image of image view "imvDie2" to load image ¬ (die2 & ".bmp" as string) set image of image view "imvDie3" to load image ¬ (die3 & ".bmp" as string) set image of image view "imvDie4" to load image ¬ (die4 & ".bmp" as string) set image of image view "imvDie5" to load image ¬ (die5 & ".bmp" as string) --Disable the Roll button and enable the Hold & Roll Again buttons set enabled of button "btnRoll" to false set enabled of button "btnHold" to true set enabled of button "btnRollAgain" to true --Clear out any text stored in the txtResults text field control set contents of text field "txtResults" to "" end tell end DisplayFirstRoll
As you can see, the graphic image that is loaded for each die is determined by the value stored in the game’s five global variables. Each of these values is concatenated to a string of ".bmp". For example, if the value of die1 were 5, then the resulting image loaded would be 5.bmp. Next, the Roll button is disabled and the Hold and Roll Again buttons are enabled, thus
Chapter 10 • Debugging and Error Handling
315
helping to guide the player’s next move. Lastly, the txtResutls text field control is cleared out. HIN
T
You will find copies of the Poker Dice game’s bitmap images on this book’s companion website. To add them to your application, drag and drop them into the Resources group located in the Xcode Editor’s Groups & Files pane. You can then drag and drop copies of the bitmap files from the Resources group onto the Images view of the Interface Builder’s MainMenu.nib window, thus making them available to your application when needed.
The ResetButtonControls() Handler The code statements that make up the ResetButtonControls() handler are shown next. This handler is responsible for resetting the game’s three button controls back to their initial status, thus allowing the player to begin a new round of play. --This handler resets button controls to their default settings on ResetButtonControls() tell window "main" --Direct commands to the window named main --Disable the Roll button and enable the Hold & Roll Again buttons set enabled of button "btnRoll" to true set enabled of button "btnHold" to false set enabled of button "btnRollAgain" to false end tell end ResetButtonControls
As you can see, the Roll button is re-enabled, and the Hold and Roll Again buttons are disabled.
The SecondRoll() Handler The code statements that make up the SecondRoll() handler are shown next. This handler is responsible for re-rolling any dice not held onto by the player. --This handler is responsible for generating the results of the second roll on SecondRoll() tell window "main" --Direct commands to the window named main
316
AppleScript Studio Programming for the Absolute Beginner
if state of button "chkHold1" is 0 then --Exclude the first die set roll1 to random number from 1 to 6 as integer --Roll again else set roll1 to die1 --Leave value of first roll as is end if if state of button "chkHold2" is 0 then --Exclude the second die set roll2 to random number from 1 to 6 as integer --Roll again else set roll2 to die2 --Leave value of first roll as is end if if state of button "chkHold3" is 0 then --Exclude the third die set roll3 to random number from 1 to 6 as integer --Roll again else set roll3 to die3 --Leave value of first roll as is end if if state of button "chkHold4" is 0 then --Exclude the fourth die set roll4 to random number from 1 to 6 as integer --Roll again else set roll4 to die4 --Leave value of first roll as is end if if state of button "chkHold5" is 0 then --Exclude the fifth die set roll5 to random number from 1 to 6 as integer --Roll again else set roll5 to die5 --Leave value of first roll as is end if end tell --Return updated list of rolls as a string return {roll1, roll2, roll3, roll4, roll5} end SecondRoll
Chapter 10 • Debugging and Error Handling
317
As you can see, this handler consists of a series of five if…else statements and a return statement. The first if…else statement examines the state of the first switch control to see if the player has selected it to indicate that that die should be held and not re-rolled. If the switch has been selected (e.g., the state of button "chkHold1" is false or 0), the Random Number command is used to generate a new value between 1–6 to represent the die’s new roll. Otherwise, the die is not re-rolled, and instead it is reassigned its existing value. HIN
T
The reason the die is reassigned its existing value (e.g., set roll1 to die1) is because the calling statement expects to receive a complete list of all five die values so that they can be redisplayed. If the value of the die was not returned, then a placeholder value would have had to be returned in its place, leaving it to the calling statement to later remove it. Alternatively, the result returned by this handler could be returned as a record, but then the calling statement and the statements that follow it would have to be modified to work with records in place of a list. As a result, additional logic would be required to tell the script what to do for each die not returned as a record (e.g., held by the user).
The next four if…else statements process the remaining dice, ensuring that only dice not held by the player are rolled a second time. Finally, the handler’s last statement returns a complete list representing the current stats of the player’s hand.
The DisplaySecondRoll() Handler The code statements that make up the DisplaySecondRoll() handler are shown next. This handler is responsible for displaying the player’s hand after the player either has elected to hold onto her first hand or has rolled a second time. --This handler updates the display of the dice after the second roll on DisplaySecondRoll() tell window "main" --Direct commands to the window named main --Update the display of any die that was rolled again set image of image view "imvDie1" to load image (die1 & ".bmp" as string) set image of image view "imvDie2" to load image (die2 & ".bmp" as string) set image of image view "imvDie3" to load image (die3 & ".bmp" as string) set image of image view "imvDie4" to load image (die4 & ".bmp" as string) set image of image view "imvDie5" to load image (die5 & ".bmp" as string)
318
AppleScript Studio Programming for the Absolute Beginner
end tell end DisplaySecondRoll
This handler consists of six if statements that load the appropriate bitmap image for each die in the game’s image view controls based on the values stored in the game’s five global variables.
The ClearSwitches() Handler The code statements that make up the ClearSwitches() handler are shown next. This handler is responsible for clearing out the five switch controls that are used by the player to specify which, if any, dice are to be held before the dice are rolled an optional second time. --This handler clears out the selection of all switch controls on ClearSwitches() tell window "main" --Direct commands to the window named main --Unselected each of the games switch controls set state of button "chkHold1" to 0 set state of button "chkHold2" to 0 set state of button "chkHold3" to 0 set state of button "chkHold4" to 0 set state of button "chkHold5" to 0 end tell end ClearSwitches
As you can see, each of these statements sets the state of each of the switch button controls to 0 (false).
The CheckGameResults() Handler The code statements that make up the CheckGameResults() handler are shown next. This handler is responsible for analyzing the results of the player’s final hand in order to determine whether the player has won or lost. --This handler is responsible for analyzing the player’s final hand and --determining whether it is a winning or losing hand on CheckGameResults()
Chapter 10 • Debugging and Error Handling
--Set values of variables representing possible rolls to zero set ones to 0 set twos to 0 set threes to 0 set fours to 0 set fives to 0 set sixes to 0 --Analyze possible results for the first die if die1 = 1 then set ones to ones + 1 if die1 = 2 then set twos to twos + 1 if die1 = 3 then set threes to threes + 1 if die1 = 4 then set fours to fours + 1 if die1 = 5 then set fives to fives + 1 if die1 = 6 then set sixes to sixes + 1 --Analyze possible results for the second die if die2 = 1 then set ones to ones + 1 if die2 = 2 then set twos to twos + 1 if die2 = 3 then set threes to threes + 1 if die2 = 4 then set fours to fours + 1 if die2 = 5 then set fives to fives + 1 if die2 = 6 then set sixes to sixes + 1 --Analyze possible results for the third die if die3 = 1 then set ones to ones + 1 if die3 = 2 then set twos to twos + 1 if die3 = 3 then set threes to threes + 1 if die3 = 4 then set fours to fours + 1 if die3 = 5 then set fives to fives + 1 if die3 = 6 then set sixes to sixes + 1 --Analyze possible results for the fourth die if die4 = 1 then set ones to ones + 1 if die4 = 2 then set twos to twos + 1 if die4 = 3 then set threes to threes + 1 if die4 = 4 then set fours to fours + 1
319
320
AppleScript Studio Programming for the Absolute Beginner
if die4 = 5 then set fives to fives + 1 if die4 = 6 then set sixes to sixes + 1 --Analyze possible results for the fifth die if die5 = 1 then set ones to ones + 1 if die5 = 2 then set twos to twos + 1 if die5 = 3 then set threes to threes + 1 if die5 = 4 then set fours to fours + 1 if die5 = 5 then set fives to fives + 1 if die5 = 6 then set sixes to sixes + 1 tell window "main" --Direct commands to the window named main --Check for five of a kind if ones = 5 or twos = 5 or threes = 5 or fours = 5 or fives = 5 ¬ or sixes = 5 then set contents of text field "txtResults" to "You Win! Five of a kind." --Check for four of a kind else if ones = 4 or twos = 4 or threes = 4 or fours = 4 ¬ or fives = 4 or sixes = 5 then set contents of text field "txtResults" to "You Win! Four of a kind." --Check for a three of a kind or a full house else if ones = 3 or twos = 3 or threes = 3 or fours = 3 ¬ or fives = 3 or sixes = 3 then if ones = 2 or twos = 2 or threes = 2 or fours = 2 or fives = 2 ¬ or sixes = 2 then set contents of text field "txtResults" to "You Win! Full house." else set contents of text field "txtResults" to "You Win! " & ¬ "Three of a kind." end if --Check for a low straight else if ones = 1 and twos = 1 and threes = 1 and fours = 1 ¬ and fives = 1 then set contents of text field "txtResults" to "You Win! Low straight." --Check for a high straight else if twos = 1 and threes = 1 and fours = 1 and fives = 1 ¬ and sixes = 1 then set contents of text field "txtResults" to "You Win! High straight."
Chapter 10 • Debugging and Error Handling
321
else --If none of the above tests evaluate as true, the player has lost set contents of text field "txtResults" to "Sorry. You lose." end if end tell end CheckGameResults
This handler begins by defining six local variables, which will be used to keep a count of the number of occurrences of any of the possible six values (e.g., the number of 1s, 2s, 3s, 4s, 5s, and 6s). Next, a set of six if statements are executed that examine the value assigned to the die1 global variable in order to increment the value of one of the handler’s local variables, depending on the value of the global variable. In other words, should the value assigned to die1 be 5, then the value of the local variable fives is incremented by 1. Similar sets of if statements have been established for each die. Once each die has been analyzed, an if…else if statement is executed. This code block begins by checking to see if the user got five of a kind, which would be the case if all five dice were set equal to 5. If this is not the case, then the code block checks to see if the user got four of a kind, which would be the case if any four of the dice were assigned the same value. Next, the code block looks to see if the user has three of a kind or a full house. If any of these hands is found, the hand is declared a winner and a text string is displayed at the bottom of the game window in the text field control. The code block then checks to see if the player has a high straight or a low straight. Finally, if none of the above conditions prove true, the player’s hand is declared a loser.
Step 5: Testing the Execution of the Poker Dice Game That’s it. You have finished the development of the Poker Dice game. In the event that you made a mistake or two when keying in the program code for the game, you should now be equipped to track down and fix your mistakes using the debugging information presented earlier in this chapter. In fact, even if you have not made any mistakes, it is still a good idea for you to run the game using Xcode’s debugger a few times just so you can track and validate that your event handlers and program code are executing in the order expected and that variables are being correctly set at each stage of program execution.
SUMMARY In this chapter you learned how to debug your AppleScript Studio applications using the Xcode debugger. In doing so, you learned how to set breakpoints and control the execution of your AppleScript using the Step Over, Step Into, and Step Out commands. You learned how
322
AppleScript Studio Programming for the Absolute Beginner
to check on variable values and to monitor the execution flow of your AppleScripts. In addition, you learned how to develop error-handling logic to allow your applications to recover from certain types of errors. You also learned how to add Tool Tips to your interface controls and to use the Help button to display help information in custom windows. Before you put this book down, take a few extra minutes to tackle one last set of challenges in order to enhance the Poker Dice game.
CHALLENGES 1.
2.
3.
4.
5.
As it is currently written, the game’s five switch controls are available at all times during the game. However they are really only needed after the first roll and before the second roll. While the player can select these controls before the first roll, they are ignored by the game until the second roll is made. To prevent this from confusing the reader, you might want to disable them before first roll occurs, enabling them again once the player’s first roll has been made. To make the game more interesting, consider setting up a fictional account balance for the player and then associating a dollar value for the different kinds of winning hands and losing hands. You could then add or subtract dollars from the user account based on the results of each game and end the game if the player goes bust. Another option you might want to consider is animating the rolling of the dice in a manner similar to what you did to automate the display of spins in the Slot Machine game. As currently written, the game only recognizes six different types of hands as winners. Make the game more realistic by modifying it to recognize other winning combinations. For example, you might make two pairs a winning hand or a single pair a tying hand. Finally, it probably would not hurt to make the messages displayed during game play a little more verbose. You might even try to offer the player tips on what to hold and not hold before making her second roll.
Part
IV Appendices
Appendix A
What’s on the Companion Website?
Appendix B
What Next?
This page intentionally left blank
A
A P P E N D I X
WHAT’S ON THE COMPANION WEBSITE? s is the case with any programming language, in order to become a proficient AppleScript Studio application developer, you must spend time working with AppleScript and AppleScript Studio. This means writing lots of Mac OS X applications, experimenting and learning as you go. In order to get off to a good start, it helps to have a collection of sample code with which you can study and experiment.
A
If you have created each of the AppleScript Studio applications presented in this book, then you already have a good collection of sample code with which to begin. However, if you have not had the opportunity to create some or all of the applications presented in this book, you are in luck. I have added copies of each application to this book’s companion website, where they are now sitting, waiting for you to download. If you read this book from cover to cover, you should already be familiar with each of the book’s sample applications. However, if you have skipped around in your reading or if you are beginning the book by checking out this appendix, you’ll find the following summary review of the book’s sample AppleScript Studio applications helpful.
326
AppleScript Studio Programming for the Absolute Beginner
THE BOOK’S SOURCE CODE In addition to the hundreds of small code snippets presented throughout, this book also demonstrates how to create 10 different AppleScript Studio applications. An overview of each of these AppleScript Studio applications is provided in Table A.1.
TABLE A.1
APPLESCRIPT STUDIO APPLICATIONS LOCATED COMPANION WEBSITE
ON THE
Chapter
Application
Description
Chapter 1
Knock-Knock
Chapter 2
Fortune Teller
Chapter 3
Typo-matic Typing Test
Chapter 4
Star Trek Trivia
Chapter 5
Guess a Number
Chapter 6
Alexander’s Tall Tale
Chapter 7
Rock, Paper, Scissors
Chapter 8
Slot Machine
Chapter 9
Tic-Tac-Toe
Chapter 10
Poker Dice
This application serves as your initial introduction to AppleScript Studio application development. It demonstrates how to build an interactive computer game that tells the player a knock-knock joke. This application teaches you how to collect user input and to generate random output. This application tests the player’s typing skill by testing her ability to correctly retype a series of sentences that grow in complexity and length. This application stores and manipulates data in variables in a trivia game that presents the player with a series of questions and assigns a ranking based on the results of the test. This application demonstrates how to apply conditional logic and loops to build a number guessing game. This application demonstrates how to format and display strings and to store and retrieve data from lists through the creation of a mad-lib styled computer game. This application demonstrates how to improve the organization of your program code by grouping it into custom handlers. This application demonstrates how to create a computer game version of a Las Vegas slot machine that allows the player to accumulate vast riches or to play until going broke. This application modernizes the classic children’s Tic-Tac-Toe game by turning it into a two-player computer game. This application helps to tie together all of the programming concepts demonstrated in this book through the development of a poker-styled dice game.
B
A P P E N D I X
WHAT NEXT?
s you have learned in this book, AppleScript Studio utilizes a powerful collection of application development technologies, including AppleScript, Xcode, Interface Builder, and the Cocoa framework. Each of these software development tools is worthy of coverage in books of their own. In short, there is plenty more to learn.
A
Hopefully you have found this book a useful first step in learning how to develop Mac OS X applications using AppleScript Studio. Don’t think of this book as the end of your AppleScript Studio education; rather, think of it as the beginning. Apple is constantly improving and making changes to both AppleScript and AppleScript Studio. To become an effective AppleScript Studio programmer, you need to keep reading and continue to look for new sources of information. To help keep your momentum going, I have created this appendix, listing additional books, websites, and mailing lists that you may want to explore as you learn to become an AppleScript Studio application development guru.
RECOMMENDED READING There is no shortage of books covering AppleScript. Unfortunately, these books cover AppleScript while providing only limited coverage, if any, of AppleScript
328
AppleScript Studio Programming for the Absolute Beginner
Studio. In fact, at the time this book was written, there were no other AppleScript Studio books. Fortunately, Apple provides both AppleScript Studio Programming Guide and AppleScript Studio Terminology Reference as additional sources of AppleScript Studio information. Regrettably, the user guide is a bit skimpy, and the reference guide is rather dry, capable of putting even the most determined reader to sleep. Still, both of these guides provide valuable information for AppleScript Studio programmers. This section provides information on these two guides, as well as information on other books from which you can learn more about AppleScript, Xcode, and the Interface Builder. Introduction to AppleScript Studio Programming Guide by Apple Computer, Inc. Available as a PDF file at http://developer.apple.com/documentation/AppleScript/Conceptual/StudioBuildingApps/ StudioBuildingApps.pdf. AppleScript Studio Terminology Reference by Apple Computer, Inc. Available as a PDF file at http://developer.apple.com/documentation/AppleScript/Reference/StudioReference/ studi oreference.pdf. AppleScript: The Definitive Guide by Matt Neuburg ISBN 0596102119, O’Reilly Media, 2006 This book covers general AppleScript development and is an excellent resource for more experienced AppleScript programmers. Beginning Xcode by James Bucanek ISBN 047175479X, Wrox, 2006 This book covers Xcode programming and is a good source for learning about different programming languages such as C, C++, Objective-C, and AppleScript. In addition, this book is a good source for learning more about the Interface Builder.
Appendix B • What Next?
329
Beginning Mac OS X Programming by Michael Trent and Drew McCormack ISBN 0764573993, Wrox, 2005 This book covers C, Objective-C, and AppleScript programming and includes good coverage of Xcode and the Interface Builder.
LOCATING APPLESCRIPT STUDIO RESOURCES ONLINE There are plenty of other places where you can learn about AppleScript Studio besides just books. The Internet is teaming with websites about AppleScript Studio and AppleScript. One excellent source of information is online articles provided by Mac magazines and journals. For example, you can always find articles at websites like www.macworld.com and www.mactech.com. In addition, there are a number of other notable websites that regularly provide information on AppleScript Studio that is essential to any serious AppleScript Studio programmer.
Apple’s AppleScript Studio Web Pages Apple provides access to tons of information about AppleScript Studio at its AppleScript Studio web pages, which you can find at http://www.apple.com/applescript/studio/, as shown in Figure B.1.
330
AppleScript Studio Programming for the Absolute Beginner
FIGURE B.1 Apple’s AppleScript Studio web pages are the first place to look for AppleScript Studio information.
Apple’s AppleScript Web Pages Apple also provides access to tons of information about AppleScript at its AppleScript web pages, located at http://www.apple.com/macosx/features/applescript/, as shown in Figure B.2.
Appendix B • What Next?
331
FIGURE B.2 Apple’s AppleScript web pages contain links to numerous AppleScript resources and documentation.
MacScripter.net Another great source for AppleScript Studio and AppleScript information is MacScripter, located at http://macscripter.net/ and shown in Figure B.3.
332
AppleScript Studio Programming for the Absolute Beginner
FIGURE B.3 The MacScripter website is brimming with information useful to both beginner and professional programmers.
Cocoa Dev Central You will also find no shortage of information on AppleScript Studio and AppleScript at Cocoa Dev Central, located at http://cocoadevcentral.com. This website, shown in Figure B.4, is dedicated exclusively to promoting application development on the Mac.
Appendix B • What Next?
333
FIGURE B.4 The Cocoa Dev Central website is dedicated to providing programmers with access to information on all major Apple development languages.
APPLESCRIPT STUDIO MAILING LISTS While you can certainly find plenty of good information in the books and websites listed earlier in this appendix, sometimes programmers need to talk with other programmers in order to collaborate and solve problems. Mailing lists provide just such a forum, allowing you to post questions and receive help and guidance from other AppleScript Studio programmers. Mailing lists provide you with the ability to introduce yourself and become an active member of the AppleScript Studio community. There is no shortage of AppleScript and AppleScript Studio mailing lists for you to explore. As a starting point, I suggest you investigate the following mailing lists to find which ones suit your needs and interests.
Apple’s Applescript-Studio Mailing List As you’d expect, Apple sponsors a number of mailing lists covering a variety of Apple technologies. One such mailing list is Applescript-studio, which you’ll find at http:// lists.apple.com/mailman/listinfo/applescript-studio, as shown in Figure B.5.
334
AppleScript Studio Programming for the Absolute Beginner
FIGURE B.5 Applescriptstudio is a mailing list sponsored by Apple to promote information sharing among AppleScript Studio programmers.
Apple’s Applescript-implementors Mailing List Another Apple-sponsored mailing list is Applescript-implementors, which you’ll find at http:// lists.apple.com/mailman/listinfo/applescript-implementors, as shown in Figure B.6.
Appendix B • What Next?
335
FIGURE B.6 Applescriptimplementors is a mailing list sponsored by Apple for professional programmers to discuss technical problems and issues.
Apple’s Applescript-users Mailing List Applescript-users is yet another Apple-sponsored mailing list. You will find this mailing list at http://lists.apple.com/mailman/listinfo/applescript-users, as shown in Figure B.7.
336
AppleScript Studio Programming for the Absolute Beginner
FIGURE B.7 Applescript-users is a mailing list sponsored by Apple for everyday users and hobbyists to discuss and share answers and solutions.
MacScripter’s AppleScript Studio and Xcode Mailing List You should also check out MacScripter’s AppleScript Studio and Xcode mailing list at http:// bbs.applescript.net/viewforum.php?id=3, as shown in Figure B.8.
Appendix B • What Next?
337
FIGURE B.8 MacScripter sponsors a very popular AppleScript Studio mailing list.
Yahoo! Groups: AppleScript Mailing List Yahoo! also sponsors a popular AppleScript list at http://groups.yahoo.com/group/applescript/, as shown in Figure B.9.
338
AppleScript Studio Programming for the Absolute Beginner
FIGURE B.9 The AppleScript mail list at Yahoo! Groups is a general-purpose mail list where you can post your AppleScript and AppleScript Studio questions.
The Applescript Studio – How to Mailing List One final mailing list that you might want to keep an eye on is mac-help.com’s Applescript Studio – How to mailing list, located at http://www.mac-help.com/forums/showthread.php? t=207, as shown in Figure B.10.
Appendix B • What Next?
339
FIGURE B.10 The Applescript Studio – How to mailing list allows users to address any type of AppleScript Studio question.
This page intentionally left blank
GLOSSARY
Absolute path. A path that specifies the full disk and folder structure required to identify the location of a file or folder, starting with a drive specification and including every folder required to reach the specified resource. Address Book. A Mac OS X application used to stored personal contact information, including names, email addresses, and phone numbers. Alias.
A reference to an object as opposed to a copy of the object.
Append.
Adding to the end of a file instead of overwriting it.
Apple Developer Reference Library. Provides access to Apple’s programmer documentation, release notes, sample code, and much more. Apple events. Messages sent between Mac OS X applications in order to support inter-application communication. Apple Human Interface Guidelines. A set of standards that specify the guidelines for designing graphical user interfaces for Mac OS X applications. Apple menu. A menu built and maintained by the Mac OS X operating system that provides access to computer information and system preferences, as well as access to commands to shut down the system or put it to sleep.
342
AppleScript Studio Programming for the Absolute Beginner
.applescript. A file extension assigned by Xcode as the file extension to the default script file for each new AppleScript project. AppleScript. An English-like scripting language supplied as part of Max OS X that also serves as the programming language used to build AppleScript Studio applications. AppleScript Studio. An application development tool that supports the creation of native Mac OS X applications with graphical user interfaces. Application menu. A menu that displays items that affect an entire application, including menu items such as About, Hide, and Quit. Application modal window. A type of window that prevents users from interacting with other parts of the application until it is closed. Application window. A default application window for AppleScript Studio applications created using the AppleScript Studio Application template. Aqua. Standards for Mac OS X applications that define the appearance and operation of interface elements such as windows, menus, and controls. Argument. Array.
A value passed to a handler or statement for processing.
A term used in various programming languages that is roughly equivalent to a list.
Assistant. A utility that is designed to guide users through the steps required to perform a given task. Attribute. A property associated with an object such as a window or interface control that describes some aspect of the object. Bevel button control. A Cocoa control that defines a button control with beveled edges and a three-dimensional look. Bevel buttons can be configured to work like standard buttons or grouped in collections and treated like checkboxes or radio button controls. Bevel buttons can also display text, icons, or images. Boolean class.
A class that represents a value that is either true or false.
Box. A Cocoa container control used to set up an area in a window that will be used to store and organize a group of related controls. Box controls. A Cocoa interface control that displays horizontal and vertical lines whose purpose is to help organize and group other interface elements.
Glossary
343
Breakpoint. A marker that identifies a point in a script file where Xcode’s debugger will pause when executing the script in order to provide programmers with the ability to examine the application’s status. Browser view. A Cocoa data view control used to display a list of data organized in a hierarchical fashion. Bugs.
A term commonly used to describe an application error.
Button control. Carbon. Character.
A Cocoa control used to initiate an immediate action.
An application development framework used to develop Mac OS X applications. An individual character within a string.
Checkbox control. A Cocoa control that provides the ability to prompt the user for input value that is limited to one of two states. Class. A template used to instantiate and define the characteristics and attributes of a particular type of object, such as a window, button, or slider control. Cocoa. A powerful collection of resources grouped together in an application programming interface or API that supports the creation of AppleScript Studio applications. Cocoa controls. Predefined interface controls used as building blocks for developing graphical user interfaces using a simple drag and drop approach. Cocoa Controls palette. A collection of user interface controls, organized by category, which are used to create graphical interfaces using drag and drop interface design. Code block. A group of statements, sometimes referred to as a compound statement, that are executed as a unit. Code Sense. An Xcode editing feature that monitors programmer keystrokes and provides suggestions for completing code statements. Color well. A Cocoa control used to display and modify the current color setting for a specific resource. Combo box control. A Cocoa control that is a combination of a text field and a popup control, allowing users either to enter in text or to select from a predefined set of entries. Command. A keyword that performs a specific task. Commands are used in the formulation of statements. Comment. A statement embedded within a script file in order to document its contents but that is ignored by the compiler.
344
AppleScript Studio Programming for the Absolute Beginner
Compiling. The process of converting application code statements into a format that can be efficiently executed by the operating system. Concatenation.
The process of joining together two or more strings to create a new string.
Current working directory. The folder or directory that is currently being accessed or that is the target of file operations. Custom view. A Cocoa container control used to define an area in a window where custom graphics can be programmatically drawn. Database. data.
A collection of records that is used for the purpose of organizing and storing
Date class.
A class that is used to store and manipulate date and time data.
Date picker control. A Cocoa control that is used to display and collect date and time information. It can be configured to display either in a simple text field or graphically as a calendar and clock. Debugger. An application execution environment that provides control over the execution of an application, allowing the application to be paused at predefined points in order to inspect the value of variables and to trace the order in which statements are executing. Dialog. user.
Specialized popup windows designed to retrieve a specific form of input from the
Dictionary.
Documents the terminology supported by a given Mac OS X application.
Disclosure triangle. A Cocoa control that is used to control the display of additional information or controls on windows. Document modal window. A type of window that prevents the user from doing anything to the document it is associated with until the document modal window is closed. Document window. A window used to display the contents of files such as text documents and spreadsheets. Document windows are used by default in applications created using the AppleScript Document-based Application template. Drawer. A window that slides out from under a parent window in an animated fashion, often used to display controls or information that, while useful, is not used enough to justify making it readily available on the parent window. DVD.
A Mac OS X application that plays DVDs.
Glossary
345
Edit menu. A menu that provides access to commands that facilitate editing operations and the movement of data between applications, including commands like all lowercase. Embedded. Endless loop.
A statement that has been nested inside another statement or code block. A loop that does not have a programmatic way of stopping its own execution.
Escape character. A special sequence of characters beginning with the \ character and followed by a letter that AppleScript recognizes and replaces with its ASCII equivalent. Event handlers. A type of control block used to organize groups of code statements that are called upon to execute as a unit. File class. A class used to define an object reference to a particular file, which then provides the ability to programmatically refer back to the file within your program code. File menu. A menu typically used to display items that control operations like Save, Print, Open, and Close. Finder.
A Mac OS X application that provides detailed control over disks, folders, and files.
Find menu. A menu that provides access to commands that are used to perform search operations within a window. Focus. A term used to identify the interface element that is the target for keystrokes. Users set focus by clicking on or selecting window controls. Font menu. A menu that provides access to commands used to control the display of text, including Bold, Italic, and Underline. Format menu. A menu that provides access to commands that control the formatting and presentation of text. Form Fields.
Cocoa controls that are designed to be used to help build forms.
Function. A term used in other programming languages that is roughly equivalent to a handler within AppleScript. Global variable.
A variable that can be accessed from any location within a script file.
Gutter. An area on the Xcode Editor that is used to display optional line numbers, breakpoints, and errors. Handler. A subroutine defined within a script file that supports modular code development.
346
AppleScript Studio Programming for the Absolute Beginner
Help button control. information. Help viewer. Help system.
A Mac OS X application that you can use to perform a search of the Mac OS X
Home directory. stored. HyperTalk.
A Cocoa control that is used to provide users with access to help
A folder assigned to each user of a system where personal files can be
A precursor language to AppleScript created by Bill Atkinson in the late 1980s.
Image view control. A Cocoa container control used to define an area in a window where a graphic can be displayed. This control can also be used to display images that are dropped and dragged on to it at runtime. Inspector window. An Xcode window used to define object attributes and associate control events with specific types of event handlers. Instance. An object that inherits characteristics and attributes from the class it is based on. Integer class. A numeric data type that represents whole number (e.g., numbers without a decimal point). Interapplication Communication. An underlying architecture on Mac OS X that allows AppleScript to send messages to other applications in order to automate specific application functions. Interface Builder. A software application that assists in the creation of graphical user interfaces that adhere to Aqua standards. Interface element. Cocoa controls that provide AppleScript Studio application with access to predefined classes such as menus, controls, and windows. Iterate.
The process of looping through the items that make up a collection.
iTunes. A Max OS X music management application that is used to store and play music and audio files. Key Modifier key. Keyboard keys (Shift, Option, Control, Command) that can be used in combination with another key to initiate a specific application command. Level indicator control. A Cocoa control that displays a graphical depiction regarding the level of a particular process. List.
An ordered collection of values, which are referred to as items.
Local variable.
A variable accessible only within its current scope.
Glossary
347
Logical error. An error that occurs when a programmer makes a mistake in the way the code for an application is designed. Looping. A loop is a logical construct that provides the ability to repeatedly execute a collection of one or more programming statements. Mail.
An application supplied as part of Mac OS X.
MainMenu.nib. A file used to store information about the state of the various components that make up an application’s user interface (windows, controls, menus, sound files, images, etc.). Menu. A key component of most Mac OS X applications that provides users with access to lists of menu items and submenus containing application commands. Menu item.
An entry on a menu that provides access to a command or resource.
Metal button control. A Cocoa control used to initiate immediate actions within AppleScript Studio applications made up of metal windows. Metal buttons can display text, graphics, or icons. Modeless window. A type of window that allows users to interact with other parts of the application while the window is displayed. Nested.
A statement that has been embedded inside another statement or code block.
Null string.
An empty string (e.g., "").
Number and date formatter control. A Cocoa control used in conjunction with text field controls to store and format a specified type of data. Object. Anything to which AppleScript can send an Apple event message, including things like windows and interface controls. Object-oriented programming. A programming methodology whereby objects, as well as object data and the program code that manipulates the object and its data, are stored together as a unit. Outline view. Paragraph.
A Cocoa data view control used to display hierarchical data. A set of characters demarcated by a return or newline character.
POSIX. A Unix standard developed in the 1980s as a means of standardizing the differences in the many versions of Unix available at the time. Progress bar control. operation.
A Cocoa control used to indicate the status or length of a process or
348
AppleScript Studio Programming for the Absolute Beginner
Pseudo-code. application.
An English-like outline of the logic that makes up all or part of a script or
Radio button control. A Cocoa control used in groups of two or more in order to allow users to make a selection from a list of available choices. Real class.
A class used to represent a numeric data type (representing real numbers).
Real number. Record.
A number that includes a decimal point, such as 10.5.
An unordered collection of data stored in name/value pairs.
Relative path. directory. Root.
Specifies the location of a file or folder relative to the current working
The top-most level of the computer’s file system.
Round button control. A Cocoa control that is a round-shaped button control, typically used to build navigation controls. Runtime error. An error that occurs when an AppleScript statement attempts to perform an illegal action. Safari.
An Internet browser supplied as a free application with Mac OS X.
Scope.
Refers to the location in a script where a variable can be seen and accessed.
Scriptable application. Script Editor. AppleScripts.
An application that accepts Apple events.
A script editor supplied with Mac OS X that is commonly used to develop
Search field control. A Cocoa text field control into which users type a text string in order to initiate a search. Search fields display a small magnifying class icon and have distinct rounded edges. Segmented control. A Cocoa control used to present users with access to two or more choices, the results of which affect the view or mode of the applications. Separator bar. A graphic separator line inserted between menu components in order to visually organize and group menu items and submenus. Sheet.
A document modal window that is attached on top of another window.
Slider control. A Cocoa control that provides the user with the ability to select from a range of values by dragging the thumb to a different location on the slider bar. Statement.
A line of program code.
Glossary
Static text field control. to label other controls.
349
A Cocoa control that displays read-only text and is typically used
Step Into. A debugger command used to execute a breakpoint statement and then pause before the execution of statements that follow. Step Out. A debugger command used to execute the remainder of statements in a handler and then return control to the calling procedure, where program flow is again paused. Step Over. A debugger command used to execute all of the statements within a handler before once again pausing before script execution at the beginning of the next handler. Stepper control. ment a value. String.
A Cocoa control used to give the user the ability to increment or decre-
A series of characters enclosed within a set of matching double quotation marks.
String class. Submenu.
A class representing a string value. A menu located under another menu.
Syntax error. An error that occurs when programmers fail to follow AppleScript’s rules when writing script statements. System Events. A special Mac OS X application that runs quietly behind the scenes and that is responsible for managing the execution of other applications and for starting the operating systems at system startup. Tab view control. A Cocoa container control used to define an area in a window that consists of two or more views. These views can only be seen one at a time based on the currently selected tab. Table view control. Target.
A Cocoa data view control used to display records in a table format.
An object to which Apple event messages can be passed.
Terminal application. Unix command.
A Mac OS X application that provides command-line access to the
Terminology. The information stored in an application’s dictionary that defines the classes, properties, and commands that the application supports. TextEdit. A Mac OS X word processing application that supports the use of different fonts and font sizes like any modern word processor. Text field control.
A Cocoa control that allows users to enter text.
350
AppleScript Studio Programming for the Absolute Beginner
Text view field control. A Cocoa control that supports multi-line text entry and displays a built-in slider control when the amount of text entered exceeds the display area of the control. Token field control.
A Cocoa control that builds a token based on the text entered into it.
Undefined variable.
A variable that has not been assigned a value.
Utility window. A window typically used to provide access to commands or tools that affect other parts of an application. Utility windows typically float on top of other windows, making them visible at all times. Variable.
A pointer to a location in memory where data is stored.
Window.
Provides the foundation for creating an application’s graphical user interface.
Window menu. A menu that provides access to commands that control the display of application windows, generally including commands like Minimize and Zoom. Word. A continuous set of characters within a string, typically separated from other characters by a blank space. WYSIWYG. (What you see is what you get.) A term used to describe the development of a graphical user interface that appears exactly the same in development as it will appear when executed. Xcode. An application development tool that provides editing and debugging capabilities for Mac OS X applications, including AppleScript Studio applications.
INDEX SYMBOLS () (parentheses), 232 = (equals) operator, 153
a About window, 86 accessing application terminology, 258 dictionaries, 15–17, 48–49 files, 231, 233–234 folders, 233–234 lists, 181–184 Open Dictionary window, 17 projects, 35 records, 184–185, 239–242 Action button, 38 activate command, 260 Active Target menu, 38 adding button controls, 23, 53 code Alexander’s Tall Tale game, 191–194 to controls, 29 event handlers, 165–170 drawers, 87–90 menus, 70–72 programming logic Poker Dice game, 311–321 Rock, Paper, Scissors game, 212–220 Slot Machine game, 245–253 Tic-Tac-Toe game, 273–282 Typo-matic Typing Test game, 56–57 submenus, 70–72 text, 24 windows, 66, 85–93 Xcode to Dock, 7 Address Book application, 265 Alexander’s Tall Tale game, 174–175, 186–195 AnalyzeAndDisplayResults() event handler, 251–253 AnalyzeBoard() event handler, 278–279
AnalyzeResults() event handler, 218–219 appending files, 237–238 Apple Developer Reference Library, 50–51 AppleScript Fortune Teller game, 32–33, 51–58 Applescript-implementors mailing list, 334 Applescript-users mailing list, 335 Application menu, 69 applications Address Book, 265 Alexander’s Tall Tale game, 174–175, 186–195 AppleScript, overview of, 6–8, 10 companion website, 325–326 creating, 19–21, 34 debugging, 296–303 development, 11–12 dictionaries, 15–17, 259–260 DVD, 264–265 errors, 289. See also errors files, 232. See also files; folders Finder, 263 Guess a Number game, 146–148, 160–171 GUIs, 21–25, 63–68. See also GUIs Help Viewer, 267–268 Interface Builder, integration, 48 iTunes, 263 Knock-Knock, 4–6, 17–30 Mac OS X, automating, 258–268 menus, customizing, 307 modal windows, 84 naming, 35 Poker Dice game, 286–289, 304–321 Rock, Paper, Scissors game, 198–200, 208–220 running, 30 saving, 35 Slot Machine game, 225–228, 242–253 Star Trek Trivia game, 109–111, 124–142 System Events, 266–267 Terminal, 264 terminology, accessing, 258 TextEdit, 259, 261–262
352
AppleScript Studio Programming for the Absolute Beginner
Tic-Tac-Toe game, 256–258, 268–283 Typo-matic Typing Test game, 60–63, 95–105 windows, 83 applying controls, 65 event handlers, 200–205 lists, 181–182 Aqua, 63. See also GUIs arguments event handlers, passing to, 202–204 files, 231 read commands, 235 assigning keystrokes, 73 strings to variables, 176 AssignMove() event handler, 277–278 Assistant, 19, 35 associating controls, 27 Atkinson, Bill, 7 attaching controls to event handlers, 25–28, 55–56 parameters, 92 sheets to windows, 91–93 attributes Alexander’s Tall Tale game, 189–191 controls configuring, 98 modifying, 25–28 interfaces, modifying, 53 Poker Dice game, 307–309 Rock, Paper, Scissors game, 211 Slot Machine game, 244–245 Tic-Tac-Toe game, 270–272 Title, 116 Typo-matic Typing Test game, 97–100 Visible at Launch Time, 90 audio DVD application, 264–265 iTunes, 263 automating applications. See also applications execution, 260 functionality, 11 Mac OS X, 258–268 workflows, 7
b backgrounds AppleScript Fortune Teller game, 54 modifying, 272 bevel buttons, 76
blocks, code, 115–116. See also code Bookmarks menu, 42 Boolean class, 124 box controls, 79–80 Box view, 95 breakpoints, 43, 302–303 Breakpoints icon, 301 Breakpoints menu, 42 browsers. See interfaces Browser view, 93 Build and Debug icon, 301 Build and Go button, 38 Build and Go icon, 22 Build button, 38 button control, 23 buttons, 74–75. See also controls; icons Action, 38 bevel, 76 Build, 38 Build and Go, 38 Close, About window, 86 customizing, 24 Editor, 38 Fonts and Colors, 43 help, 76 Info, 38 Lock Status, 42 metal, 75 Next, 42 Previous, 42 round, 75 Tasks, 38
c calling event handlers, 201–202 case sensitivity, 119–120 characters, 44 escape, 177 strings, 180–181 viewing, 176 checkbox controls, 77 CheckGameResults() event handler, 318–321 checking syntax, 41 classes, 8 Boolean, 124 Date, 122–124 file, 231 Integer, 121 Real, 121 variables, 121–124
Index
ClearSwitches() event handler, 318 Close button, About window, 86 Cocoa Container Views controls, 94–95 Cocoa Controls, 65–66 Cocoa Dev Central website, 332 Cocoa framework, 8 Assistant, 19 controls, 8, 74–83 indicators, 74–83 interface elements, 68–84 menus, 68–74 object-oriented programming, 8–9 text, 80–83 views, 93–95 windows, 83–93 code Alexander’s Tall Tale game, 191–194 blocks, 115–116 colors, 14 compiling, 12–13 controls, adding to, 29 editing, 28–30 errors. See errors event handlers, adding to, 165–170 highlighting, 12 review, Star Trek Trivia game, 139–142 saving, 15 Code Sense, 45–46 colors coding, 14 statements, 44 syntax, 41 text, 54 Colors window, 272 color well controls, 75 combo box controls, 82–83 command-line debugging, 50. See also debugging commands, 115 activate, 260 applications, scripting, 262 copy, 263 count, 176 dictionaries, 15–17 display dialog, 149 make, 260 open, 115, 266 path arguments, 232 play, 263 read arguments, 235 restart, 266
shut down, 266 tell, 115, 261 try, 292–295 Unix, 264 comments, 44 types of, 55 companion website, 325–326 comparisons strings, 178–180 types of, 153–154 compiling, 13 applications, 30 code, 12 completion, code, 45–46 components dictionaries, 15–17 overview of, 6 windows, 84–85 compound operators, 154–155 compound statements, 115 concatenating strings, 177 conditional logic, implementing, 149–152 conditions false, 158 true, 157–158 configuring breakpoints, 302–303 controls attributes, 98 Star Trek Trivia game, 128–129 event handlers, 98–100, 309 folders references, 232 Help windows, 305–306 menus, 73–74 text colors, 54 windows, 304–306 Xcode preferences, 36–37 connections (event handlers) Alexander’s Tall Tale game, 191 configuring, 98–100 Guess a Number game, 164–165 Poker Dice game, 309 Rock, Paper, Scissors game, 211–212 Slot Machine game, 245 Star Trek Trivia game, 128–129 Tic-Tac-Toe game, 272 Console icon, 301 contact information, 265
353
354
AppleScript Studio Programming for the Absolute Beginner
contents, processing lists, 159–160 Continue icon, 301 controls associating, 27 attributes configuring, 98 modifying, 25–28 box, 79–80 button, 23 checkbox, 77 Cocoa Container Views, 94–95 Cocoa Controls, 65–66 Cocoa framework, 8, 74–83, 80–83 code, adding to, 29 color well, 75 combo box, 82–83 date picker, 82 event handlers, attaching, 25–28, 55–56 form field, 82 number and date formatter, 81 popup, 78 properties Alexander’s Tall Tale game, 188–191 Guess a Number game, 163–165 Poker Dice game, 307–310 Rock, Paper, Scissors game, 211–212 Slot Machine game, 244–245 Star Trek Trivia game, 128–129 Tic-Tac-Toe game, 269–272 radio button, 77–78 resize handle, 23 segmented, 79 slider, 76–77 Slot Machine game, 244–245 small system font text, 24, 51 static text field, 80 stepper, 76 text fields, 81 views, 82 text input field, 51 token field, 81 Typo-matic Typing Test game, 97–100 Zoom, 26 converting code, 13. See also compiling copy command, 263 count command, 176 counters, loops, 159 crashes, 292. See also errors; troubleshooting creating. See also configuring applications, 19–21, 34
email messages, 266 endless loops, 156–157 files in databases, 238–242 GUIs, 21–25, 63–68 instances in objects, 67 references in files, 231–233 utility windows, 90–91 customizing Alexander’s Tall Tale game, 188–191 buttons, 24 controls, 163–165 event handlers, 201 Poker Dice game, 307–310 properties, 128–129 Rock, Paper, Scissors game, 211–212 Slot Machine game, 244–245 Tic-Tac-Toe game, 269–272 Typo-matic Typing Test game, 97–100 Custom view, 95
d databases files, 238–242 records, 239–242 data using variables, managing, 116–117 Date class, 122–124 date picker controls, 82 debugging, 285 applications, 296–303 breakpoints, 43 executing, 300–301 popup dialogs, 297–298 Script Editor, 12 Xcode, 7, 48–49. See also Xcode default menus, 69 defining commands, 260 event handlers, 201–202 lists, 181–184 deleting menus, 69–70 design. See also configuring; games AppleScript Fortune Teller game, 51–58 Knock-Knock application, 18–30 Star Trek Trivia game, 124–142 Typo-matic Typing Test game, 95–105 Detail view (Xcode Project window), 40–41 development Apple Developer Reference Library, 50–51 applications, 11–12 Knock-Knock application, 18–30
Index
dialog boxes popup, 14 windows, 83 dictionaries accessing, 15–17, 48–49 applications, 259–260 Finder, 263 directing messages to application targets, 261 directories applications, 36 files, 230. See also files; folders DisableSquares() event handler, 282 disclosure triangles, 77 DisplayComputerMove() event handler, 216–217 display dialog command, 149 display dialog function, 51 display dialog statement, 295 DisplayerPlayerMove() event handler, 215–216 DisplayFirstRoll() event handler, 314–315 DisplayInstructions() event handler, 247 DisplayRandomImages() event handler, 247–249 DisplaySecondRoll() event handler, 317–318 DisplaySlotMachineImages() event handler, 249–250 DisplayStats() event handler, 219–220 Dock, adding Xcode to, 7 Documentation menu, 50 documents elements, 259 modal windows, 84 windows, 83 drawers, adding, 87–90 DVD application, 264–265
e editing code, 28–30 Code Sense, 45–46 Script Editor, 12–15 word processing applications, 261–262 Xcode, 7. See also Xcode Edit menu, 69 Editor button, 38 Editor window (Xcode Project window), 41–46 elements definitions, reading, 260 document, 259 interfaces, Cocoa framework, 68–84 lists, retrieving, 182–183
email, 266 endless loops, creating, 156–157 entering text, 24 equals (=) operator, 153 errors, 40, 285. See also debugging error-checking statements, 12 error handling practices, 289–290 handling, 292–296 logical messages, viewing, 298–300 runtime, 291–292 syntax, 290 types of, 290–292 viewing, 295–295 escape characters, 177 event handlers AnalyzeAndDisplayResults(), 251–253 AnalyzeBoard(), 278–279 applying, 200–205 arguments, passing to, 202–204 AssignMove(), 277–278 calling, 201–202 CheckGameResults(), 318–321 ClearSwitches(), 318 on clicked, 92 code, adding, 165–170 connections Alexander’s Tall Tale game, 191 configuring, 98–100 Guess a Number game, 164–165 Poker Dice game, 309 Rock, Paper, Scissors game, 211–212 Slot Machine game, 245 Tic-Tac-Toe game, 272 controls, attaching, 25–28, 55–56 customizing, 201 defining, 201–202 DisableSquares(), 282 DisplayFirstRoll(), 314–315 DisplayInstructions(), 247 DisplayRandomImages(), 247–249 DisplaySecondRoll(), 317–318 DisplaySlotMachineImages(), 249–250 FirstRoll(), 313 formatting, 201 AnalyzeResults(), 218–219 DisplayComputerMove(), 216–217 DisplayerPlayerMove(), 215–216 DisplayStats(), 219–220 GetPlayerMove(), 214–215 GetRandomNo(), 217
355
356
AppleScript Studio Programming for the Absolute Beginner
GetRandomNumbers(), 249 PrepareGameBoard(), 275–276 ResetButtonControls(), 315 results, returning from, 204–205 scope, 205–208 SecondRoll(), 315–317 SeeIfGameOver(), 280–282 StartNewGame(), 276–277 Star Trek Trivia game, 128–129 SwitchPlayers(), 280 Typo-matic Typing Test game, 97–100 events, 27 executing. See also starting Alexander’s Tall Tale game, 195 AppleScript Fortune Teller game, 57–58 Guess a Number game, 171 loops, controlling with counters, 159 Rock, Paper, Scissors game, 220 scripts, breakpoints, 43 Star Trek Trivia game, 138 Typo-matic Typing Test game, 104–105 execution applications, automating, 260 debugging, 300–301 iTunes, 263 Poker Dice game, 321 Slot Machine game, 253 statements, 303 System Events application, 266 Tic-Tac-Toe game, 283 existing menus, adding submenus, 72 expressions, 149 extensibility, languages, 112–113 extensions, files, 229. See also files
f false conditions, looping, 158 features, languages, 113–116 fields, Search, 38 File menu, 69 File Name menu, 42 File Owner icon, 67 files accessing, 233–234 appending, 237–238 databases, creating, 238–242 Groups and Files (Xcode Project window), 38–40 overwriting, 237 paths, full/relative, 230–231
POSIX paths, 228–230 reading from, 234–238 references, creating, 231–233 saving, 47 text, 233–238 viewing, 21 writing to, 234–238 Finder application, 263 First Responder icon, 67 FirstRoll() event handler, 313 Fix and Continue feature, 49 Fix icon, 301 focus, 67 folders accessing, 233–234 paths, full/relative, 230–231 POSIX paths, 228–230 references, configuring, 232 Resources, 22 Scripts, 21 Fonts and Colors button, 43 formatting. See also configuring event handlers, 201 AnalyzeResults(), 218–219 DisplayComputerMove(), 216–217 DisplayerPlayerMove(), 215–216 DisplayStats(), 219–220 GetPlayerMove(), 214–215 GetRandomNo(), 217 interfaces, 26 records, 184–185 strings, 177–178 form field controls, 82 frameworks, 39 full paths, 230–231 functionality, automating, 11 Function menu, 42 functions, display dialog, 51
g games Alexander’s Tall Tale, 174–175, 186–195 AppleScript Fortune Teller, 32–33, 51–58 Guess a Number, 146–148, 160–171 Knock-Knock application, 4–6 Poker Dice, 286–289, 304–321 Rock, Paper, Scissors, 198–200, 208–220 Slot Machine, 225–228, 242–253 Star Trek Trivia, 109–111, 124–142
Index
Tic-Tac-Toe, 256–258, 268–283 Typo-matic Typing Test, 60–63, 95–105 General view, 46 GetPlayerMove() event handler, 214–215 GetRandomNo() event handler, 217 GetRandomNumbers() event handler, 249 global scope, 206–208 Go To Counterpart menu, 42 graphical user interfaces. See GUIs Groups and Files (Xcode Project window), 38–40 Groups & File pane, 22 Guess a Number game, 146–148, 160–171 GUIs (graphical user interfaces) Cocoa Controls, 65–66 creating, 21–25, 63–68 MainMenu.nib window, 67
h handling errors. See errors events. See event handlers help buttons, 76 Help menu, 50, 69 Help Viewer application, 267–268 Help window, 305–306, 309–310 Hide Others option, 23 highlighting code, 12 history of AppleScript Studio, 6 home directory, saving applications to, 36 How to mailing list, 338–339 HyperTalk, 7
i icons Breakpoints, 301 Build and Debug, 301 Build and Go, 22 Console, 301 Continue, 301 File Owner, 67 First Responder, 67 Fix, 301 MainMenu, 67 Pause, 301 Restart, 301 Run, 13 Script, 42 Step Into, 301 Step Out, 301
Step Over, 301 Terminate, 301 Window, 67 if…else if statements, 151–152, 274 if…else statements, 150–151 if statements, 149–150, 152 Image view, 95 implementing conditional logic, 149–152 Included Files menu, 42 indenting statements, 12, 45 indicators Cocoa framework, 74–83 level, 78 progress bar, 79 Info button, 38 Info window (Xcode Project window), 46–47 Inspector window, 25 instances, creating objects, 67 Integer class, 121 Interface Builder, 8 Cocoa Controls, 65–66 GUIs, creating, 63–68 integration, 48 MainMenu.nib window, 67 starting, 22, 64 windows, 65, 85–93 interfaces Alexander’s Tall Tale game, 187–188 AppleScript Fortune Teller game, 52–54 Cocoa framework elements, 68–84 Guess a Number game, 161–163 GUIs, 21–25. See also GUIs modifying, 53 Poker Dice game, 307–310 Rock, Paper, Scissors game, 209–210 Safari, 265–266 Slot Machine game, 243–244 Star Trek Trivia game, 125–128 terminology browser, 48–49 Tic-Tac-Toe game, 268–269 Typo-matic Typing Test game, 96–97 items (menus) adding, 70–72 configuring, 73–74 deleting, 69–70 iterative processing, 155–156 iTunes, 263
j JavaScript, 7
357
358
AppleScript Studio Programming for the Absolute Beginner
endless, creating, 156–157 false conditions, 158 iterative processing, 155–156 true conditions, 157–158
k key event notification, 298 keystrokes, assigning, 73 keywords, 44 errors, 295–296 new, 260 return, 262 until, 158 Knock-Knock application, 4–6, 17–30
l labels, entering text, 24 languages case sensitivity, 119–120 extensibility, 112–113 features, 113–116 programming, overview of, 9–11 layouts, Xcode Project window, 37 level indicators, 78 libraries, Apple Developer Reference Library, 50–51 line-based statements, 114–15 lists applying, 181–182 contents, processing, 159–160 defining, 181–184 elements, retrieving, 182–183 modifying, 183–184 records, 185–186 local scope, 205–206 locations, files. See paths Lock Status button, 42 logic conditional, implementing, 149–152 programming adding, 56–57 Guess a Number game, 165–170 Poker Dice game, 311–321 Rock, Paper, Scissors game, 212–220 Slot Machine game, 245–253 Star Trek Trivia game, 129–138 Tic-Tac-Toe game, 273–282 Typo-matic Typing Test game, 100–104 logical errors, 291 logs output, 296–297 statements, 296 loops counters, controlling execution with, 159
m Mac OS X applications, automating, 258–268 POSIX paths, 228–230 MacScripter.net, 331 Mail application, 266 mailing lists, 333–339 MainMenu icon, 67 MainMenu.nib window, 8 make command, 260 managing data using variables, 116–117 files full/relative paths, 230–231 POSIX paths, 228–230 manipulating strings, 176–178 markers, breakpoints, 43 menus Active Target, 38 adding, 70–72 Alexander’s Tall Tale game, 188–189 Application, 69 Bookmarks, 42 Breakpoints, 42 Cocoa framework, 68–74 configuring, 73–74 customizing, 97–98 default, 69 deleting, 69–70 Documentation, 50 Edit, 69 File, 69 File Name, 42 Function, 42 Go To Counterpart, 42 Guess a Number game, 163–165 Help, 50, 69 Included Files, 42 New Project, 19 Poker Dice game, 307 Slot Machine game, 244–245 Tic-Tac-Toe game, 270 Typo-matic Typing Test game, 97–100 Window, 69
Index
messages applications, directing to targets, 261 email, 266 errors, viewing, 298–300 metal button, 75 methods, 8 modeless windows, 84 modifying backgrounds, 272 controls, 25–28 interfaces, 53 lists, 183–184 records, 185 text, 66 Tic-Tac-Toe game, 270–272 windows, 66 multimedia DVD application, 264–265 iTunes, 263 multiple statements, 13. See also statements music DVD application, 264–265 iTunes, 263
n naming applications, 35 paths, 229 variables, 118–119 nested if statements, 152 new keyword, 260 New Project menu, 19 Next button, 42 notification, key event, 298 number and date formatter controls, 81 numbers, 44
o object-oriented programming. See OOP objects, creating instances, 67 on clicked event handler, 92 OOP (object-oriented programming), 8–9 open command, 115, 266 Open Dictionary window, 16 opening projects, 34 operators compound, 154–155 equals (=), 153
Other Sources, 39 Outline view, 93 output, logs, 296–297 overwriting files, 237
p panes, Groups & File, 22 paragraphs, strings, 180–181 parameters, 92 parentheses (), 232 passing arguments to event handlers, 202–204 paths command arguments, 232 full/relative, 230–231 POSIX, 228–230 Pause icon, 301 Perl, 7 play command, 263 playlists, iTunes, 263 Poker Dice game, 286–289, 304–321 popup controls, 78 popup dialog boxes, 14, 297–298 portability, folders, 232 POSIX paths, 228–230 preferences, Xcode, 36–37. See also customizing PrepareGameBoard() event handler, 275–276 Previous button, 42 processing iterative, 155–156 list contents, 159–160 products, 39 programming errors. See errors languages, overview of, 9–11 logic adding, 56–57 Guess a Number game, 165–170 Poker Dice game, 311–321 Rock, Paper, Scissors game, 212–220 Slot Machine game, 245–253 Star Trek Trivia game, 129–138 Tic-Tac-Toe game, 273–282 Typo-matic Typing Test game, 100–104 object-oriented, 8–9 progress bar indicators, 79 projects accessing, 35 Alexander’s Tall Tale game, 174–175, 186–195 AppleScript Fortune Teller game, 32–33, 51–58
359
360
AppleScript Studio Programming for the Absolute Beginner
creating new, 19 Guess a Number game, 146–148, 160–171 Knock-Knock application, 4–6. See also Knock-Knock application Poker Dice game, 286–289, 304–321 Rock, Paper, Scissors game, 198–200, 208–220 Slot Machine game, 225–228, 242–253 Star Trek Trivia game, 109–111, 124–142 templates, 33–36 Tic-Tac-Toe game, 256–258, 268–283 Typo-matic Typing Test game, 60–63, 95–105 Project window, Xcode, 37–47 properties, 8 controls Alexander’s Tall Tale game, 188–191 Guess a Number game, 163–165 Poker Dice game, 307–310 Rock, Paper, Scissors game, 211–212 Star Trek Trivia game, 128–129 Tic-Tac-Toe game, 269–272 size, 262 text, 262 values, modifying, 185 version, 262 Python, 7
q
registration, Open Dictionary window, 16 relative paths, 230–231 repeat statements, 155–157 ResetButtonControls() event handler, 315 Resize control, 23 resizing, 53 resources. See also websites mailing lists, 333–339 websites, locating, 329 Resources folder, 22 Resources Group, 39 restart command, 266 Restart icon, 301 results, event handlers, 204–205 retrieving elements from lists, 182–183 records, 184–186, 239–242 variables, 117 returning results from event handlers, 204–205 return keyword, 262 review, code, 139–142 Rock, Paper, Scissors game, 198–200, 208–220 round button, 75 Ruby, 7 Run icon, 13 Run Log window, 296 running. See execution runtime errors, 291–292
Quite Interface Builder option, 26
s r radio button controls, 77–78 reading element definitions, 260 from files, 234–238 recommended, 327–329 Real class, 121 recommended reading, 327–329 records accessing, 184–185, 239–242 lists, 185–186 modifying, 185 storing, 184–186 references, 327–329 Apple Developer Reference Library, 50–51 files creating, 231–233 text, 233 folders, configuring, 232
Safari, 265–266 saving applications, 35 code, 15 database files, 238–239 files, 47 scope, event handlers, 205–208 Script Editor, 12–15 Script icon, 42 scripts applications, automating, 258–269 breakpoints, 43 languages, 9–11. See also programming Scripts folder, 21 Scripts Group, 39 Search field, 38 searching Finder, 263 Help Viewer application, 267–268
Index
SecondRoll() event handler, 315–317 SeeIfGameOver() event handler, 280–282 segmented controls, 79 selecting project templates, 34 sending email, 266 setting. See configuring sheets, attaching windows, 91–93 shortcuts, files, 231 Show Inspector option, 25 shut down command, 266 size property, 262 sizing, 53 slider controls, 76–77 Slot Machine game, 225–228, 242–253 small system font text control, 24, 51 sound key event notification, 298 music. See music specifying files/folders, 229 starting Assistant, 19 Interface Builder, 22, 64 Safari, 265 Script Editor, 12 Xcode, 19 StartNewGame() event handler, 276–277 Star Trek Trivia game, 109–111, 124–142 statements colors, 14, 44 comments, 55. See also comments compound, 115 display dialog, 295 error-checking, 12 execution, 303 if, 149–150, 152 if…else, 150–151 if…else if, 151–152, 274 indenting, 12, 45 line-based, 114–115 log, 296 repeat, 155, 156–157 wrapping, 44–45 static text field controls, 80 Step Into icon, 301 Step Out icon, 301 Step Over icon, 301 stepper controls, 76 storing, 47. see also saving records, 184–186 values in variables, 116–117
strings, 44 characters, 180–181 comparing, 178–180 concatenating, 177 formatting, 177–178 getting information about, 176 manipulating, 176–178 variables, assigning, 176 submenus adding, 70–72 configuring, 73–74 SwitchPlayers() event handler, 280 syntax, 113–114 checking, 41 errors, 290 System Events application, 266–267
t Table view, 93 Tab view, 95 targets, 40, 261 Tasks button, 38 tell command, 115, 261 templates Assistant, 19 projects, 33–36 Terminal application, 264 Terminate icon, 301 terminology, 258. See also dictionaries terminology browser, 48–49 testing Alexander’s Tall Tale game, 195 AppleScript Fortune Teller game, 57–58 Guess a Number game, 171 Poker Dice game, 321 Rock, Paper, Scissors game, 220 Slot Machine game, 253 Star Trek Trivia game, 138 Tic-Tac-Toe game, 283 Typo-matic Typing Test game, 104–105 text adding, 24 Code Sense, 45–46 colors, configuring, 54 controls, 80–83 files, 233–238 modifying, 66 TextEdit application, 259, 261–262 text field controls, 81
361
362
AppleScript Studio Programming for the Absolute Beginner
Text Input Field control, 51 text property, 262 text view controls, 82 third-party applications. See also applications automating, 258–269 dictionaries, 16 Tic-Tac-Toe game, 256–258, 268–283 Title attribute, 116 token field controls, 81 toolbars, Xcode Project window, 38 tracking, Code Sense, 45–46 triangles, disclosure, 77 troubleshooting. See also errors Help Viewer application, 267–268 System Events application, 266–267 true conditions, looping, 157–158 try command, 292–295 types of comments, 55 of comparisons, 153–154 of errors, 290–292 Typo-matic Typing Test game, 60–63, 95–105
viewing character strings, 176 dictionaries, 259 error messages, 298–300 errors, 295–295 files, 21 Groups and Files, 38–40 Info window (Xcode Project window), 46–47 popup dialogs, 297–298 windows, 25, 66 views Box, 95 Browser, 93 Cocoa framework, 93–95 Custom, 95 Detail (Xcode Project window), 40–41 General, 46 Image, 95 Outline, 93 Tab, 95 Table, 93 Visible at Launch Time attribute, 90
u
w
undefined variables, 120 Unix Shell scripting, 7 Terminal application, 264 until keyword, 158 user interfaces, 52–54. See also interfaces utility windows, 83–84, 90–91
warnings, 40 websites. See also mailing lists AppleScript Studio, 329 Cocoa Dev Central, 332 companion, 325–326 MacScripter.net, 331 resources, locating, 329 Window icon, 67 Window menu, 69 windows, 8 About, 86 adding, 66 Alexander’s Tall Tale game, 189–191 applications, 83 Cocoa framework, 83–93 Colors, 272 components, 84–85 creating, 22 dialog boxes, 83 documents, 83 Help, 305–306, 309–310 Hide Others option, 23 Inspector, 25 Interface Builder, 65, 85–93 MainMenu.nib, 8, 67 modifying, 66
v values properties, modifying, 185 variables retrieving, 117 storing, 116–117 variables classes, 121–124 managing, 116–117 naming, 118–119 paths, 229 strings, assigning, 176 undefined, 120 values retrieving, 117 storing, 116–117 version property, 262
Index
Open Dictionary, 16 Poker Dice game, 304–306 Project, 37–47 Rock, Paper, Scissors game, 211 Run Log, 296 sheets, attaching, 91–93 Slot Machine game, 244–245 Terminal, 264 Tic-Tac-Toe game, 270–272 utility, 83–84, 90–91 viewing, 66 words strings, 180–181 word processing applications, 261–262 workflows automated, 7 creating, 11 wrapping statements, 44–45 writing AppleScript, 11 to files, 234–238 output to logs, 296–297
x Xcode, 7 applications, creating, 19–21 debugging, 299. See also debugging errors, 290. See also errors Interface Builder, starting, 22 mailing lists, 335 preferences, configuring, 36–37 Project window, 37–47 starting, 19 templates, 33–36
y Yahoo! Groups AppleScript mailing list, 337
z zoom control, 26
363