Table of Contents ------------------------------------------------------------------- Chapter 1: How to Design an Application Well Target Audience Primary and Secondary User Tasks General Implementation Actual Implementation Chapter 2: Qualities of a Good Application Forgiveness Implementation != Interface Focuses on User Needs Use of everyday language Proper use of controls Natural layout of controls Difficult to make errors Proper error handling Plenty of feedback Chapter 3: OS Conventions Application Settings and User Preferences Maintain Application Responsiveness Avoid Hardcoded File Paths Make Your App's Look Fit in with Others Live Updates Translators Queries Attributes System Tray MIME handling File picker Message Handling File extensions Getting Input from the User Mouse vocabulary keymaps Keyboard accelerators Focus locking Keyboardability Conventions for choosing accelerators Fitts' Law Drag and Drop What is it Appropriate use drag feedback drop feedback clippings Use of drag handles Replicants BShelf Use of Text in the GUI Labels Controls Use of Fonts Error messages Ellipses Colons Capitalization Icons Conventions Designing a good icon Packaging an icon Recongnizability Cursors Predefined Use of Animation Menus, Menu Bars, and Menu Fields Grouping of items Titling / Naming conventions Use of submenus Use of marked items vs toggled names Explanation of common menus and their contents Windows Modality Appropriate use of styles Placement / positioning Resizability whenever possible Use of Alert windows Good window titles Minimizing / Showing Resizing / Moving / Zooming Use of B_ACCEPTS_FIRST_CLICK Scrolling (automatic and manual) About window design Find windows Preferences window design Open / Save panels Controls Radio Buttons Buttons Checkboxes Control Groups (BBox) Sliders BTextControl / BTextView ListViews Tabs Scrollbars Color Pickers Progress Meters Toolbars Installation and Updates Zip files SoftwareValet packages Chapter 1: How to Design an Application Well 1) Determine the Target Audience If you know what general kind of application you would like to create, you also need to determine who the application is meant for. This can be as general as 'desktop users' to something as specific as 'Haiku Web Developers'. Knowing who the main users of your application will be allows you to make certain assumptions about what your users know. You can't necessarily expect a musician to understand how to effectively use a 3D modelling program as advanced as, say, 3D Studio Max. Depending on how concerned you are about details, you may want to create a user profile -- a fictional idea of an example user. This can be consist of one or two sentences or can be several paragraphs. A short user profile contains the person's first name, occupation, level of expertise, and what kinds of things they want to be able to do with their computer. One thing to be sure of is to make the user profile believable -- like a person you might know. In fact, when you design your app, it may be helpful if you know someone who fits into the target audience. You don't want to design you app for that person specifically, but, rather, someone just like them. 2) Determine Primary and Secondary User Tasks Please remember that the reason that most people will use your application is to get work done. Your users are not unintelligent, but, rather, very busy. Remember how busy most people are and how valuable their time is to them when you are designing your application. In order to make doing work with your program easier, you need to prioritize what kinds of work they will do in order of how often the work is done. Divide these tasks into primary and secondary tasks. Primary tasks are those things which the user does all the time. In a word processor, this would include typing in text, changing font sizes and styles, and adjusting margins. Secondary tasks are those which the user does occasionally. Notice that there is no mention of features that the user 'might' need to have. In order for your application to be as simple to use as possible, complexity must be minimized. One primary way this is done is by avoiding features which are used only in remote instances. Design your application to meet the needs of 80 percent of your target audience. With added features comes added complexity. Also, all the features which the user needs may or may not be required for the first version. Releasing a product often is good for business. 3) Construct a General Implementation Once you know what kind of person for whom you're writing your application and what kinds of things he will be doing with it, you will need to figure out the general way that the user will do it. This does not imply what the application will actually look like – just how they will be done. In a home finance application, one of the user's primary tasks will be entering in transactions. The user will need to type in the data for each transaction or download them from their bank over the Internet. 4) Devise the Actual Implementation The actual implementation of the application is determined last. Note that what technologies will be used to create the application have not been mentioned yet, and even now they are not discussed. Technology is the means to an end – a tool – and not the end itself. This is where the general usage of the application is determined. For example, the user will have a form to enter transactions into an account. The form should have text fields for each of the different kinds of data, such as the payee, the amount, and the check number. Somewhere nearby, the user will be able to see all a list of all the transactions in the current account. Because this is where the actual building of the look of the program takes place, it is crucial at this point in development to know and understand what makes software truly easy to use, so this is what we will examine next. Chapter 2: Qualities of a Good Application When it comes to software, the proof is in the usage. If a piece of software requires significant time to learn, the user will only invest the time in learning it if (a) the user has no other choice but to use that particular software and (b) the importance of the need filled by the software is much greater than the importance of the user's time. Good Applications Focus on a User Actual Needs In Chapter 1, it was mentioned that your application should meet the needs of 80 percent of your target audience. It is impossible to meet the needs of all users in the same software and still retain some semblance of being easy to use. Sometimes a user doesn't even know that he needs or doesn't need a feature and it is up to the designer and developer to figure out what is needed. Most often, it is better to have a small collection of more specialized tools than one which does everything. Good Software Uses Everyday Language Positions in Information Technology are almost always professional positions. One aspect which makes IT a profession is that it has its own body of knowledge and terms to go with it. Most people have only a rudimentary 'computerese' vocabulary, like the fact that the thing that they look at when at the computer is called a monitor or just 'the screen', that the little arrow on the screen is called the cursor, and that the thing they type with is called a keyboard. Few users know (or care) what a 'file format' is and fewer still do not know what an 'invalid sector' on a floppy disk might be. Good applications use regular language instead of technical terms. For file management software, 'volumes' are really disks – even though the term isn't quite accurate, a normal person associates a disk with 'a place you put stuff on'. Images are 'pictures'. A person doesn't 'kill' a application that has 'hung' - - he 'forces a frozen program to quit'. Details like this may seem minor, but many small improvements in a program's usability can have a profound effect overall. Good Applications Do Not Expose Their Implementation Good applications do what they do in a certain way because it is the best way to be done, not because the code was written in a certain way. An example of this would be if a music composition program has a maximum song size because because the storage used for holding it can't store any more than that fixed size. The actual code written and the architecture used when it was written should have as little effect as possible on what the user sees and works with when using your software. Good Applications Use Graphical Controls Properly GUI controls were meant to be used in certain ways, and when a program does not use them in that particular way, it is confusing to the user. Check boxes, for example, are commonly used in lists where a value can be turned on or off. Sometimes, however, they are used for choosing one option in a list. Radio buttons were meant for this task. Text boxes should not be used for labelling other controls. This might seem to be common sense for most, but, rest assured, there are many programs which do not do something as simple as this. Good Applications have a Natural Layout to their Controls When performing certain tasks, people have a logical order that they follow, and good applications place their GUI controls in a manner that reflects this. When entering an address in the United States, the natural order is Name, Street and Number, City, State, and Zip Code. Following any other order would not only frustrate the user, but it would also lead to more mistakes in entering the proper data. Good Applications Give Plenty of Feedback Picture this: you have just started changing the format of a movie file. You hit the button marked 'Go' and wait... and wait.. and wait. Nothing seems to have happened. Did something go wrong? You don't know, and the reason you don't know is that the program didn't tell you what it was doing. Everything was going well and was just taking a while. Good software does something that effective people do – communicate well with others. Good feedback means making sure that the user knows what your program is doing at any given time – especially if the program is busy doing something which prevents the user from doing anything else in your program. CD and DVD burning programs tell the user how much is left before they are finished making a CD or DVD. File management programs tell how many files are left to copy or move. Good Applications Make Errors Hard It should be difficult for users to mess up. If, for example, the user needs to enter in some text and certain characters are not allowed, then disable those characters for the text box it needs to be entered in. Build constraints into your application which prevent errors. This would be why 3 ” floppy disks have a notch in one side – it can be inserted into a drive only one way. Good Applications Handle Errors Gracefully It is impossible to make an application entirely foolproof because fools are so ingenious, but it is possible for a program to handle errors in a way that doesn't leave the user wondering what happened. When code is written, errors of all sorts need to be anticipated and handled, such as lack of memory, lack of disk space, permissions errors, and loss of network connectivity. If an error condition can be forseen, it needs to be compensated for. Doing so greatly improves the perception of your software by the outside world. Crashes are unacceptable in all cases. Error messages, for example, need to describe in non-technical terms what happened and suggest what the user can do to remedy the situation. In the worst case, the program needs to provide an easy way for the user to send technical information about the problem back to you via e-mail or some other means. In all cases, the user's data is to be preserved. Good Applications are Forgiving Computers are excellent tools for people because they are good at many things that people are not. From a perspective which focuses on technology, humans are imprecise, illogical, disorganized, and make mistakes frequently. They are, however, excellent at forming habits and matching patterns, two things computers have a difficult time doing. Make commands undoable whenever possible and when it is not possible, be sure to inform the user that such is the case. Summary Good software takes genuine effort to produce. It is not for the stereotypical 'lazy programmer.' However, in creating something of significant value to customers, good software creates a positive image for a company and loyal customers who will do your own advertising for you. Chapter 3: OS Conventions When Be Inc. was still developing BeOS, it set precedents which were copied by other operating systems for years to come. Along with innovation came certain ways of performing tasks, some of which developed out of deliberate choice, some out of necessity, and some out of sheer accident. In this chapter we will take a look at some of these conventions. Application Settings and User Preferences While there are a myriad of ways to store user settings and preferences and the exact method was debated by engineers employed by Be, the preferred method of saving preferences is through placing them in a BMessage and flattening it to a file. This reduces the code needed to load, save, and parse settings files and frees developers to work on other tasks. The exact location used to store settings files depends on the number of files needed. If your software needs only one file and will only ever need one, then it is permissible to place it in the user's config/settings folder. Should more than one file be necessary, they may be placed in either home/config/settings/your_app_name or home/config/settings/your_company_name/your_app_name. Maintain Application Responsiveness Probably the best-known quality about Haiku as an operating system is its speed and responsiveness. This comes from the widespread multithreading used in applications. Note that responsiveness does not necessarily imply that your application should allow the user to do anything he/she wishes at any time. A common experience encountered by Linux and Windows users is the "blanking out" of a window or windows when the application is busy doing some other task. This comes from the thread responsible for drawing the window contents being used for other tasks, such as encoding an MP3 or some other time-consuming work. In cases like this, utilize another thread to do the actual processing and keep synchronization between the processing thread and the window by way of messages, semaphores, or some other means. This gives the user the perception that your application is still running properly and has not frozen. Avoid Hardcoded File Paths Whenever your application needs to specify a particular area on the system, make use of the find_directory() function to generate it. If and when the day comes that Haiku supports multiple users, your application will make a smooth transition to the new architecture. This will also allow for backward compatibility with older versions of BeOS, such as the change in locations for B_COMMON_FONTS_DIRECTORY being in a different place for Haiku than on R5. find_directory() is supported in both C and C++ environments. Make Your App's Look Fit in with Others Certain function calls have been provided in the API to aid in making sure that your software shares the same general look as other applications and allow the user to make customizations to the system at the same time. Unless there is a very good reason for it, utilize ui_color() and the constants which go with it to set colors for the views in your application. Determine the size of your controls dynamically - use the ResizeToPreferred and GetPreferredSize for system controls and calculate the size of your own controls based on font sizes obtained from the system instead of hardcoded values. All of this will allow better ease-of-use for the user who prefers tiny fonts to increase use of desktop real estate and also for older users who need larger font sizes to accomodate weaker visual acuity. Graphics are an important part of a program's look, but don't reimplement the look of the buttons and other standard controls just to make your application stand out from the rest. By keeping visual consistency with the rest of the operating system, you avoid confusing the user with buttons that do not look like you can click on them, strange-acting menus, and so forth. Live Updates One way to make sure that your application communicates effectively with the user is to provide "live" updates to information in it. This mostly relates to files in the system. A good example of live updates is an address book program which automatically removes and adds entries when new People files are added to the People folder. The information doesn't even have to be data that is outside your program -- it could just be as simple as updating an entry in a list of items as the user types makes changes to it in a form in a different part of the GUI. Responsiveness like this in a program helps the user feel more in control of the work he is doing. Translators Haiku comes with quite a bit of technology that allows lazy programmers to be lazy and still have their programs be good ones. One of those ways is with the Translation Kit. Merely by including the library and making use of even something as simple as the BTranslationUtils class will help to ensure that at least this portion of your code is free of bugs. Squeezing the Most out of BFS: Queries, Attributes, and File Types The filesystem that Be created was nothing short of amazing at the time. Even with the gradual evolution of other operating systems having progressed since then, it is still one of the most powerful around. Attributes are one means Queries Attributes File extensions System Tray MIME handling File picker Message Handling