rob "sleeps on the floor during lecture" fitzpatrick (gtg085g)
mark ramirez sponsler (gtg662a)
james "seriously guys, i can code" gaines (gtg131g)
jeremy scott hampton (gt57870)
(send fanmail to firstname.lastname@example.org)
being seen makes us happy, and dressing up is fun
Here's our final project for the pda. fileIn the entire changeset, go to a workspace, type "Calendar show" and alt+d it. m5turninWithSampleICAL.zip
Our particular squeaky adventure does not seem as if it would be entirely helpful to future squeak pilgrims. The offer we make is a veritiable cornucopia, overflowing with the smalltalk equivalents of maize and turkey. Wooo. Get out the Allan Kay commemorative napkin rings and wash your hands. The feast is Squeak.
Stop our young cs friends from hating their lives quite as much as we did.
Unearth the useful features of squeak which are hidden in some deep and dark chasm of the computing underworld.
Provide code snippits that you can lay down on the chopping block and carve into a rocking 16th century gui.
Provide the full source, because not enough of these things do, and squeak code is impossible to find.
1. Moving code around the group. sigh.
Changesets are fairly reasonable, and at times convenient. First get your basic image. Clean out all the junk that irritates you (the mouse, for example... you alt+leftClick it and then hit that X that appears top left in the halo). Once it's stripped down, save the whole image again (left click the background, save), and use that to load up squeak from now on.
Now you make a blank changeset. Left click, changes, create new change set. If you choose a useless name, you can rename the files (whatever.cs) after you file them out. Write your code for the day, left click on the background, changes, file out current change set. you can now close squeak without saving.
To load your code back in, load up your blank image, then drag the changeset file onto the squeak background thing. A purple box shows up. Right click. Filein entire file. That'll put you right back where you were when you filed out. If you want to merge your code with someone else's, filein all of your code, then drag their changeset on, and right click, changelist browser. You'll see a lot of confusing lines of garbage. Have your buddy sitting beside you tell you exactly which functions he changed, scan down until you see those function names, click them all, and then file in selections.
Never have more than one person working on the same function, or even class if possible, because combining code will become a hellish inferno of terrible pain.
Combining code should be a group activity. Have one person get everyone's latest changesets, combine them all, and set them back out to everyone. Don't work while code is being combined. Wait until everyone has fresh versions. Don't let everyone try to combine code. Just one guy. It's his job. He's the changeset guy. Ours was Mark.
Once you've brought in all the changesets, test it, file out a changeset, and pass that out to everyone. They can blindly file it all in to a blank squeak image and if the changeset guy was on the ball, everything will work fine.
1 1/2. A very good feature. in squeak
Squeak has the best feature ever. Seriously. For real.
In the browser where you are diligently coding, there's a button that says "versions". You click it, and every saved copy of that function ever made is there in its pristine state, before you went and exploded it. You'll notice that my dynamic and modular numbering system allowed me to slip this one in here after the fact. Thats the sort of design prowess you can expect to control yourself after just a semester (or, to my everlasting shame, two semesters) of squeaking.
Another great feature is the hierarchy button on the browser. If you are using a ScrollPane (or whatever else) and need to know if it has functions to do whatever, hit the hierarchy button and browse the classes above it. They might be holding what you need.
2. Convincing something to appear on the screen
You can type this in the workspace, highlight it all, and hit alt+d to see what is going on. Or put it in a class function and run that.
This makes a system window, which is akin to a typical microsoft window. It has minimize and kill buttons and a title bar. You can say newWithoutLabel instead of new to get just the bare bones without that fluff at the top.
First, the '_' will look like a little arrow in squeak. It's the assignment operator.
A semicolon chains messages. So openInWorld gets called on win, then height with a parameter of 300 is called on win, then width, then color, and so on. You can't chain off of the first line BC its an assignment, not a message. You could also end each line with a period and stick a 'win' before every message.
Colors. Capital 'Color', lower case 'blue', or 'white', or whatever else. 'transparent' is a color. Remember that one.
Single quotes are strings, double quotes are comments.
topleft. horizontalOffset@verticalOffset from top left corner of squeak's world. Stuff holds its own position data, so you tell it where to be, and then you open it, or add it to something, and it will pop up at the right place, rather than trying to place it onto something as you open it.
3. Hooking up buttons
tempButton _ SimpleButtonMorph new label: dayNum printString;
color: Color red;
borderColor: Color black;
arguments: (Array with: dayNum).
win addMorph: tempButton
dayNum is an int. You have to printString it, or asString it.
The bottom three (target, actionSelector, arguments) are for making the buttons do things.
The button calls a function. Target is the class that contains that function. I always used self, and made simple clickWhatever functions in that class to support the button.
actionSelector is the function that will be called. Precede it with a # sign. The colon means it will have one parameter. If it had two parameters, it might look like... actionSelector: #clickADay:inMonth:;
Arguments are the parameters you will be sending to the function. You send them in as one array stuffed with all the values, and then the function can use them as if they were called normally (it disregards the array). To continue the two parameter example... arguments: (Array with: dayNum with: monthNum).
Then just add the button morph to the window. It's already placed correctly thanks to topLeft, so just slap it on there.
Top left is always in terms of the squeak window, so if your systemWindow that you made has been dragged elsewhere, the button will still appear at the top left of the main squeak environment window, even if thats not on your system window at all (fixes for this later).
I think SimpleButtonMorphs are the most usable, because they don't have some of their potential set in stone like the more specific subclasses do. It was the easiest for me to get looking just the way i wanted it to.
addMorph the image as a morph. Yea, thats intuitive. You could add it to anything. Morphs, whatever. Do it the same way.
addMorph: frame: is one command, so no semicolon. This ensures itll pop up wherever the system window is and stretch to fill the whole thing. Although squeak's stretching mechanisms are shady at best. might want to size things on your own. Also, do this last when you are adding stuff to your guis, because stuff seems to be added to system windows behind everything thats already there. So if you put the background image on first, all the buttons won't appear because when you add them, they're behind it.
Prepare your riot gear, because you are about to be swarmed by blazing hot chicks who want your manhood after seeing this jamming demonstration of untouchable virility and picture placing prowess.
Good built in functions that handle wrapping around months and years and such all on their own.
weekdayIndex will give you a number that lets you figure out whether a day is monday, tuesday, etc.
aSecondDate _ aDate asString asDate.
Make a clean copy of a date by going off of its string value instead of just pointing at the same thing.
Important note: You may have noticed the use of asString and asDate above. These are very useful when working with Squeak's built in objects. It turns out when you want something as something else, it's usually very easily done. If you have trouble with asString, try asText.
Changesets are a huge pain if people are stepping on eachother's toes and working all over the place.
Squeak guis take a long time to learn
Squeak passes everything by reference. We were passing around a date and then tinkering with it and it became a debugging nightmare. Most array types have a "copy" command. A lot of squeak objects do. Make your own for your classes.
Include each person's name in their changeset names, so you know whose code is where and what you are filing in.
Work on entirely separate chunks, or work together. Integration is really easy if the code is cleanly separated. You'll have to code all over the place sometimes, and then you should probably have everyone together.
The first gui assignment (m2 for us) took 3 of us working together for about 20 hours. Most of that time was trying to figure out how to do things like place buttons by pixel instead of percent and change font size and read from text fields. It's stupid stuff, but it takes a while.
The projects are all weighted the same. The ones at the beginning are worth as much as the ones at the end =/.
Squeak guis are ugly by nature. If you get yours to look crisp and clean, youll have a leg up on the other folks. Not that doing extra stuff counts for anything in this class. The grading criteria seems pretty rigid.
Parenthesis are a pain in squeak. It conditions you not to use them by deleting them whenever you save, but occasionally they are neccessary when it doesnt look like they should be. topleft: x/10@y/5. That won't work. Uou need to wrap the x/10 in parenthesis, although the y/5 can be left without them. I recommend overwrapping. These bugs are a pain to catch too, but will usually throw errors much further down the line about type inconsistency, if you are lucky enough to get an error at all. Otherwise your buttons just dont appear, because they are 10,000 pixels offscreen or something stupid.
Select will get you an array filled with the elements that met your condition. Collect will give you an array filled with true/false values.
The laptops my team was using wouldn't come out of hibernation when squeak was running. Which means if we hadn't filed out, and our computers went to sleep, we had to reboot and lost our work.
alt+s saving is not the same as filing out. To get back your work if squeak crashes (which it will) youll have to dig through the master change set, which we never learned to do right.
alt+period will break you out of an infinite loop
Transcript writing slows down program execution a lot.
To do all the boolean comparisons, you only need to overload and =. The other ones will pop up to their parent classes which know to use a combination of the two you defined. and =.
'=' and '==' can do different things, but they usually dont. Don't let your crazy groupmates tell you otherwise. They are different operators, but in basic Object functionality, one just calls the other.
Doing random stuff
Transparency. Set color to 'Color transparent'
Font. fontName: 'NewYork' size: 20. you can change the size, not the name. watch the spacing and capitalization of 'NewYork'.
Semi-transparency. tempColor _ Color red. tempColor _ tempColor alpha: 0.3. make sure you have the leading zero on floats. alpha is 0.0 to 1.0.
tempColor _ tempColor darker darker. or you can use lighter. you can chain as many of them together as you like to get the shade you want. or tempColor _ Color blue lighter lighter lighter lighter. whatever.
Plain system window. win _ SystemWindow newWithoutLabel. Although then you might as well just use a RectangleMorph...
How to use our project as a reference
The three categories are down at the bottom in the left most pane of the browser. milestone1, m2, and icalendar. m2 has all the gui stuff in it. thats probably what will be the most helpful to you.
YearGUI: Transparent buttons, a text field, some writing
MonthGUI: Semi-transparent colored buttons, more buttons, some writing, background image.
WeekGUI: Same sort of button action as MonthGUI
DayViewGUI: A one way scroll pane with an image in it, a scrolling list that does stuff when its clicked. Some buttons. This GUI is structured a little differently than the others. The components are declared as instance variables, and then are given their values across a couple functions. They are built in initialize:date:window:monthView:, and are added to the morphs and placed in addMorphs.
The list is a PluggableListMorph. The important things in the code for DayViewGUI are the todoList and todoSelectedIndex instance variables, which are an array holding the things in the list and the currently selected index (starts at 1). Then the methods todoListIndex methods which are used to get and set the value of the selected index. Particular useful is todoListIndex: for taking a particular action when a new selection is made.
DayViewGUI's makeScheduleMorph function: here you get the code to make a beautiful one way scrollpane (there's a sweet ass builtin addMorph inATwoWayScrollPane or something function if you dont mind a bar on the bottom too) with a picture and a lot of different types of buttons (completely invisible, semi transparent, opaque, etc) being made on the fly. Some are hooked up with click events and others are just there for aesthetics.
ICalendarFormat class in the ICalendar category writes to file and reads from file. It's a lot of code, but the info is all in there. There's also a simple pop up box with a text entry field morph with an OK and cancel button in here somewhere.
ToDoMorph & ScheduledEventMorph: Some buttons and a lot of text field action. Most of the gui code is in editToDo and editScheduledEvent functions.
Milestone1 has some inheritence example, with ScheduledEvent and ToDoItem both inheriting from parent class CalendarEvent, and CalendarEvent shows how to overload boolean operators (, =, etc).
Calendar isUnusualContext: has some good examples of conditional branching and looping.
We use arrays all over the place in M2 and Calendar class in M1.
The bulk of the logic code is in Calendar in the methods whose names involve the world "unusual".
Link to this Page
Cases last edited on 30 July 2011 at 2:33 am by r59h132.res.gatech.edu