The Artima Developer Community
Sponsored Link

Agile Buzz Forum
How To Create A Custom Widget - Pane

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
James Robertson

Posts: 29924
Nickname: jarober61
Registered: Jun, 2003

David Buck, Smalltalker at large
How To Create A Custom Widget - Pane Posted: Aug 4, 2004 3:05 PM
Reply to this message Reply

This post originated from an RSS feed registered with Agile Buzz by James Robertson.
Original Post: How To Create A Custom Widget - Pane
Feed Title: Pollock
Feed URL: http://www.cincomsmalltalk.com/rssBlog/pollock-rss.xml
Feed Description: Pollock - the next VW GUI
Latest Agile Buzz Posts
Latest Agile Buzz Posts by James Robertson
Latest Posts From Pollock

Advertisement

There are several decisions that have to be made when creating a new widget for Pollock. They are: Deciding where in the Pane hierarchy to place your new Pane widget. Where in the Agent hierarchy to place your widget's Agent, or whether to use an existing Agent. Where in the Artist hierarchy to place you widget's Artist. And finally, which standard Pollock Controller should your widget use.


Where to subclass a new Pane

There are basically five points in the Pane hierarchy that can be for a new widget. These depend on the type of widget you want to create. All are in and of themselves abstract classes.

The common ancestor for all Panes is AbstractPane. This is the most general superclass that you could choose. You would subclass from this pane if you have a widget that does not contain other panes. In Pollock, the Divider and Slider are examples of panes that do not have the ability or need to host sub-panes.

The next place would be to subclass from ComponentPane. It adds behavior to allow an arbitrary number of sub-panes to be added, and knows how to manage them. In Pollock, the Form, MenuBar and Toolbar are examples of panes that contain other panes. Also in Pollock, Button is a subclass of ComponentPane. In theory, a ComponentPane can have any number of sub-panes, of any type. While the Button's main business is to host a DisplayLabel and/or a DisplayImage, it could be made to hold any number or kind of pane.

The third place is the EditingPane. The EditingPane is where you would subclass if you wanted to do some special kind of user input editor. The two existing subclasses of EditingPane are InputField and TextEdit. This class has a lot of support for doing things with the cursor, selecting, editing and managing text entry.

The forth place is the EnumerationPane. This pane is where you would subclass if you have a pane that wants to display an enumeration or list of some kind. The TreeView, ListBox and Grid are subclasses of this pane. This pane also has all the general plumbing needed to support scrollbars for any subclass.

Finally, there is the ActionDisplay. This is a special kind of ComponentPane, and itself subclasses from ComponentPane. Where a ComponentPane in general can have any number of subpanes, the ActionDisplay pane is designed on the idea that there is a basic "Action" pane, which is not a sub component, and a "Display" pane which is a sub-component. The simplest way to explain this pane is by example. The RadioButton and CheckBox are subclasses of the ActionDisplay. The Radio part of the RadioButton is the "Action" part, as is the box of the CheckBox. The optional label, which may be on either the left or right of the box or radio area, is the "Display" part.

This design was taken a step further, and was applied to the DropDownList, the MenuButton and the SpinButton. For these, the "Button" area is the "Action" part, and the input field is the "Display" part. True, the Display part of these are actually not static labels like the RadioButton or CheckBox, but active (or read only in the case of the MenuButton) input fields. So, the name, ActionDisplay doesn't quite stand up. Vassili suggested once that it might be called ActionAction. None the less, ActionDisplay it is, and various behavior have the word action or display in their names.


Calendar Pane

Our Calendar widget is very much like a DropDownList, except that instead of a List that drops down, it will be a pane with a calendar in it. So, we'll subclass from that. As an aside, there is an argument to be made that we could just subclass from DropDownList. There are some minor pros to that. But, since we're all about learning here, we'll go with subclassing from ActionDisplay.

Before we write a single stick of code, let's be uber XP and write our first Unit Test.

You'll need PollockTesting loaded, because we're going to write our test case as a subclass of a the special Pollock test case. Also, it is best if we all agree to load the RBSUnitExtensions as well as SUnit itself. The latter will have to be loaded in any case, since PollockTesting relies on it.

So, we'll start by creating our main TestCase subclass:

	Smalltalk.Pollock defineClass: #CalendarTest
		superclass: #{Pollock.PollockTestCase}
		indexedType: #none
		private: false
		instanceVariableNames: 'calendar eventValue secondEventValue '
		classInstanceVariableNames: ''
		imports: ''
		category: 'Pollock-Tests'

If you are using the RBSUnitExtension, as I suggest, as soon as you create that class, you'll see the bottom of the browser say: Not run: 0 tests.

We added instance variables named calendar, eventValue and secondEventValue. The former is where we can put our Calendar pane when we're writing tests. The last two are for testing trigger events for our pane, when we get to writing support for them.

To start, we'll write the following tests:

	testCalendarClassExistence
		self should: [#{Smalltalk.Pollock.Calendar} ifDefinedDo: [:value | true] elseDo: [false]].
		
	testCalendarClassHierarchy
		self should: [#{Smalltalk.Pollock.Calendar} ifDefinedDo: [:value | value superclass = ActionDisplay] elseDo: [false]].

If you run those (press the "Run" button in the RB, because of course, you do have the RBSUnitExtension loaded, right?), you'll see that they both fail, as they should. You'll note that we use the binding reference feature of VisualWorks. We could have written the tests using Pollock at: #Calendar. However, I like this form better.

In good XP form, we never let any test cases fail before we publish/integrate our code, so:

	Smalltalk.Pollock defineClass: #Calendar
		superclass: #{Pollock.ActionDisplay}
		indexedType: #none
		private: false
		instanceVariableNames: ''
		classInstanceVariableNames: ''
		imports: ''
		category: 'Pollock-Calendar'

Now, we run the tests, and bingo, a nice green bar. We're on our way!

The above is published as version 1.1 in the Package named "Pollock-Calendar" on the Cincom public repository.

Next time, we'll discuss the Artist, write a few more tests and then add our CalendarArtist.


And So It Goes
Sames

Read: How To Create A Custom Widget - Pane

Topic: Abused Hardware Stories Previous Topic   Next Topic Topic: Blog Boy Burst Bottoms out

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use