Bubble Assignment CS130

Purposes:

· practice mouse message handling, including dragging

· practice adding a new class

· practice using ColorDialog and FileDialog

· implement File Save As and File Open

· practice using a modal dialog

· practice using an ArrayList

· design your own user interface

Specifications [Note, the grading criteria are considered part of the specifications too. Read the whole assignment.]

1. The project should be called Bubble so the executable file will be Bubble.exe. The title bar should display Bubble2345, with your 4-digit student ID in place of 2345.

2. A bubble is, in this program, just a colored circle. It might be outlined or it might be filled, or both. When the user depresses the left mouse button or moves the mouse with the left button depressed, a new bubble is created with its center at the current cursor position. The radius, color, and other properties of the bubbles are controlled through the user interface elements discussed below. By default the radius of bubbles is 5 pixels and the color is dark blue, and the bubbles are outlined but not filled. Thus, when the user drags the mouse, a trail of (small) bubbles will mark the trail of the mouse; they will be closer together or farther apart depending on how fast the mouse moves. If you make a trail of bubbles cross over itself, the ones drawn later will be painted over the ones drawn earlier. Here’s a screen shot taken before the menu was created. Note that the window background is white.

3. When the mouse is moved off the window, new bubbles continue to be created, even though they are not visible. You can see these bubbles by making the window larger after making them. [You don’t have to do anything special to cause this—in fact, you would have to work to prevent it.]

4. There is a File menu (leftmost) on the menu bar, and on the File menu there are Save As, Save, and Open. The Save item is initially disabled, and is enabled as soon as Save As has been successfully used. Save As brings up a Windows Common Dialog to allow the user to select a file. When the dialog terminates successfully, the program saves all of its current data. When the file is subsequently opened (whether or not the program has been closed in the meantime), the state of the program is the same as when the file was saved. The default file extension for this program is .bbl. The file dialogs should have one filter reading Bubble files (*.bbl) and another filter reading All files (*.*). If the user does not supply a filename extension (with the filter set to *.bbl) then the program should append .bbl when saving, but with the filter set to All files, then it should not supply a filename extension. When you select an existing file in Save As, it should not ask you whether you want to overwrite the existing file—it should just go ahead and overwrite it. When you try to open a file that was not created by this program, it should gracefully inform you of that fact, not crash, and continue to be fully functional.

5. There is a Bubble menu on the menu bar, with a menu item Bubble Properties. Choosing this menu item brings up the Bubble Properties modal dialog. This dialog allows the user to specify the following bubble properties:

· fill color

· outline color

· whether bubble is to be outlined or filled or both

· radius of bubble (an integer, in pixels)

· percent transparency of the bubble. Zero means opaque, 100% means invisible. The default is opaque. This percentage affects both fill and outline colors. You cannot, in this program, specify different transparencies for the fill and outline.

These changes will affect only future bubbles, not bubbles already created. The screen shot below illustrates one possible design of the Bubble Properties dialog, but you are free to design a different dialog if you choose. You should, however, use a ColorDialog for choosing colors. In the design illustrated, the Change Fill Color button and the Change Outline Color button bring up a ColorDialog as shown in the lecture notes. The illustrated design uses a trackbar for the transparency (thus eliminating the need for data validation on that field) and a “numerical up-down control” for the radius (thus eliminating the need for data validation on that field). A more sophisticated design would show the user a sample of the bubble whose properties are being specified. This is not required for this assignment. Note how this design forces the user to have at least one of fill and outline. The ticks on the trackbar in the example dialog go from 0 to 90 by intervals of 10.

Here’s a screen shot showing three different styles of bubbles.

6. You can draw as many bubbles as you have time and energy to draw, at least several thousand.

7. Make sure that it is impossible to enter invalid data for the radius and transparency. The radius should be a positive integer between 2 and 50; the transparency must be between 0 and 90. You can do this as shown in the sample dialog, by choosing suitable controls to eliminate any need for data validation. Otherwise, for example if you use a text box, you must use proper data validation techniques, including an ErrorProvider.

8. If the user defines custom colors in a ColorDialog, those custom colors should be remembered the next time the color dialog comes up. There are actually three issues here: the custom colors should be (1) remembered for the lifetime of the BubbleDialog; (2) remembered as long as the program is running; (3) saved when a .bbl file is saved and reconstructed when the file is opened. Of these, (2) is required for this assignment, but not (3). However, if you still have energy after doing the A+ level work, you can read how to save the custom colors in Petzold and get an A++.

9. For an A+ , you have to implement an Undo menu item on the Bubble menu. Choosing this item removes all the bubbles drawn at the last “stroke”. A stroke begins with MouseDown and ends with the last MouseMove before MouseUp. The screen shot above shows three different strokes (but you can’t be sure by looking at the screen shot that there were only 3—there might have been more).

Test procedure to check your program. This is the procedure that will be followed when the program is graded.

a. Left-clicking creates new bubbles.

b. Depress left mouse button and drag. A trail of bubbles should follow the mouse.

c. There should be no flicker when new bubbles are created.

d. The menus appear as specified. When Bubble Properties is chosen, the Bubble Properties modal dialog should come up, allowing choices of size, colors, style, and transparency as described in the specifications. The currently selected values are initially shown (for example, if you used radio buttons, the correct button is selected).

e. The keyboard works correctly with this dialog: tab keys navigate correctly and arrow keys work to change radio buttons within a group.

f. Choices made in this dialog should affect subsequent bubbles, until a new choice is made. Previously drawn bubbles do not change size or color.

g. Cancel works correctly, i.e. if you change some data in the dialog and press Cancel, your colors and sizes don’t change, and when you bring the dialog up again, your changes don’t show.

h. OK works correctly, i.e., your changes take effect and when you bring the dialog up again, the changes show.

i. Create some custom colors, use them, then bring up the dialog box again and see if the custom colors are still there.

j. Save your document using File | Save As. Close the document and then open the saved file. Did it open correctly?

k. Save a document without supplying an extension: it should supply .bbl. [with file type filter set to bbl]

l. Save a document with only a period for extension: it should not supply .bbl. [with file type filter set to all files]

m. Save a document with an existing filename: it should silently overwrite it.

n. Attempt to open a non-Bubble file. You should get an error message, not a crash or impairment of function.

o. For the A+ level: Undo works as described in the specifications. As usual, you can only get an A+ if everything else works perfectly.

p. For an A++ (just kidding, no such grade really exists, but your work will be noticed!) see if custom colors come up in the dialog again after opening a saved file.

Grades will be determined this way: if everything works, it’s an A or an A+. A very minor defect will result in an A-; a not-so-minor defect will result in a B or B+; any major defect will result in a lower grade. There are so many features of this program that it isn’t practical to specify a point value for each feature; the grader will use some human judgement.

Programming Hints

1. Create a class Bubble. A bubble should have a center and radius, and other fields and/or properties enough to support specification 5. I suggest not including the transparency or opacity as a separate field; it’s enough to have the fillColor and outlineColor fields. Write a constructor to construct new bubbles with specified properties. If you intend to try for the A+, I suggest also including an integer field called stroke.

2. Write a Draw method in your Bubble class, that takes a Graphics argument and uses it to draw and/or fill a circle at the location and with the properties specified by the member variables of Bubble.

3. In your Form1 class, create member variables for the data mentioned in specification 5, and initialize them as specified. Also create an ArrayList called m_Bubbles that will be used to contain a list of Bubble objects. If you’re trying for the A+, also create an integer variable m_currentStroke, which you will increment on MouseDown. (No more hints about the A+ will be given.)

4. In Form1_Paint, write a short foreach loop that loops through m_Bubbles and has each bubble draw itself, using the Bubble.Draw method that you wrote in step 2. You can’t test it until after the next step.

5. Add handlers for MouseDown and MouseMove, and arrange that if the left mouse button is depressed, or the mouse is moved while the left button is down, that a new Bubble object is created and added to m_Bubbles. The new bubble should be created using the values of fill color, border color, transparency, radius, etc. that are specified in the member variables of Form1.

Now, you should be able to see the program working, with the default values of bubble properties. Observe that if you call Invalidate in MouseMove with no parameters, you will experience terrible flicker. If you call it correctly, there will be no flicker.

6. Next create the Bubble Properties dialog; by now you have created several modal dialogs, so this should be fairly routine, except for the color selections. You will have to solve the problem of using a ColorDialog to specify an opaque color and separately specifying the transparency. What is new here is having a button on your modal dialog that brings up another dialog (in this case a ColorDialog). Create your menu and make the Bubble Properties dialog come up as specified, and when it returns OK, set the member variables of Form1 specifying the current bubble properties.

Now you should be able to test this dialog, and see the new properties used in the next bubble drawn.

7. To deal with the issues of the lifetime of custom colors, make your ColorDialog objects static, rather than members of the dialog class or local. You will have to do that in source code as the drop-and-drag method using the Toolbox will make them members of the dialog class, so your custom colors will have lifetime limited to the lifetime of the Bubble Properties dialog, which is not good enough. You can, if you like, drag and drop them first and then move the initialization code from InitializeComponents to where the color dialog variables are declared, and change the declarations to static.

8. Returning to your Bubble class, write a method WriteBubble that takes a BinaryWriter and writes the bubble’s data. Write an additional constructor for your Bubble class that takes a BinaryReader argument and reads the bubble’s data, and then constructs a new Bubble object with that data. This constructor should read the data in the same order that WriteBubble writes it.

9. Implement File Save As and File Open following the lecture notes. When saving a file, just use foreach to loop through m_Bubbles and call each bubble’s WriteBubble method. Count the number of bubbles saved and then at the end, write that to the file too. When opening a file, first read out the number of bubbles stored, and then just start with an empty m_Bubbles and call the Bubble constructor that takes a BinaryReader argument the correct number of times. That way, you don’t have to test for end-of-file.

10. Test the program according to the test protocol above; check every detail.

11. Try for the A+.