The Artima Developer Community
Sponsored Link

Agile Buzz Forum
How To Create A Custome Widget - Drop Down Window

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 Custome Widget - Drop Down Window Posted: Oct 6, 2004 1:27 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 Custome Widget - Drop Down Window
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

Today we add behavior to the Calendar button to open our "drop down" and we display it. But first, a bug fix:

	TransientWindow>>hasBorder
		^self artist hasBorder

Configure The Button Action

The first step is to configure the button (the action part) to call a method when it is pressed. This method will then open the drop down calendar window. We do this with a single line of code we'll add to the #createActionPart method in CalendarArtist:

	CalendarArtist>>createActionPart
		...
		actionPart addComponent: self calendarButtonImage.
		actionPart setEnclosingPane: pane.
		actionPart 
			when: #pressed
			send: #openCalendarWindow
			to: self agent

This uses the trigger event framework, to set up a message, that will be sent to an object (the 'to:') when the target widget triggers an event. Buttons trigger the #pressed event when the mouse is released in a button after the mouse was pressed in that button.

If we open our tester now (CalendarTest new openWindowWithCalendar) and press the button part, we will get a Does Not Understand error, saying that CalendarAgent does not understand #openCalendarWindow. This comes as no surprise of course.


Calendar Drop Down

Before we get into actually writing our #openCalendarWindow, let's cover what we'll want it to do. When the #openCalendarWindow method is called, we want to open a pane immediately below the area covered by the input field and button combination of our Calendar. This is the same general behavior that occurs when we press the button part of a Drop Down List or a Menu Button. What we do in fact is open a window. This is a special kind of window, sometimes named a popup or menu window, that has no inherent border or title bar... Basically a totally undecorated window. In Pollock this is an instance of TransientWindow. Wrapper has it's own TransientWindow class not to be confused with Pollock's.

The notion of a window being transient is that it's life span is limited relative to the window that launches it, and unlike either Dialog or Application windows, automatically close whenever there is a click outside the window. The API to create a new Transient window is:

	TransientWindow class>>newPopUpIn: <aRectangle> from: <aPane>

Here the first parameter is a rectangle that is relative to overall screen (not the main window's origin). The second parameter is the pane that is launching the pane. In this case, it will be our Calendar. Don't be confused by the term "PopUp" in the message name even though our window will seem to "drop down," it's just a technicality of perception, not of behavior.

We can easily determine the origin for our pane, we just use the bottom left corner of the Calendar pane. All that's left for us to decide is the size of the drop down. Right now it's hard to figure out what the best size for that will be. This is because when we later design what is in that drop down, the ability to show all we want to show, the navigation, title and actual calendar display, depends a lot on the size of the seven columns of the calendar grid, and the ability to easily read the information in the drop down.

For now, we'll just take the width of the current Calendar pane, and open a square drop down right below it.

We'll also create an instance variable to hold our drop down, so we can talk to it after we create and open it, if we need to.


Creating The Drop Down

First, we'll create the dropDown instance variable for CalendarAgent:

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

Now we'll add our #openCalendarWindow method

	CanendarAgent>>openCalendarWindow
		| calendarRectangle screenOffset |
		calendarRectangle := self frameVisibleRectangle.
		screenOffset := self topPane globalOrigin.
		dropDown := TransientWindow
			newPopUpIn: (calendarRectangle bottomLeft + screenOffset extent: calendarRectangle width asPoint)
			from: pane.
		dropDown open

Here, we start by getting the rectangle that describes the area of the main pane. Then, we ask the #topPane for it's global origin. In Pollock any pane (or agent or artist) can send the topPane message, and get the window that is the outermost host for the pane we are working with. Note that when a pane is in a TransientWindow, as we are building, that message sent by a pane hosted in that window will answer the TransientWindow.

Next were asking a pane hosted in the main window... #globalOrigin answers the position of the upper left hand corner of all the drawable area of the window. Note here that it isn't the origin of the window including it's borders or title. The global origin here is as if we stripped all that window dressing off, leaving only the drawable area as our concern... which of course, is just that, our only concern.

We then call the #newPopUpIn:from: method on TransientWindow which will give us an unopened window, all ready for us to later fill in with our calendar display. Our last step is to send #open the result.

So, let's open our tester, and press the button.... and.... hmmm... looks like nothing is happening! But looks can be deceiving. The reason is that the popup is by default the same color as the window behind it. So, like adding a little dye to a running stream to see it's current, let's, for now, add a bit of color to the background of our popup so we can see it:

	CanendarAgent>>openCalendarWindow
		| calendarRectangle screenOffset |
		calendarRectangle := self frameVisibleRectangle.
		screenOffset := pane topPane globalOrigin.
		dropDown := TransientWindow
			newPopUpIn: (calendarRectangle bottomLeft + screenOffset extent: calendarRectangle width asPoint)
			from: pane.
		dropDown background: ColorValue pink.
		dropDown open

Let's open our tester again and press the button... Yes! Now we see it as a pink square right below the drop down. We can play with it now... click anywhere inside the pink popup, and nothing happens, click anywhere outside that popup, and the window automatically disappears.


Getting Fancy

Before we go, let's do one more thing, since it's so simple to do. The original design we're copying has a ridged border around popup. We can add that easily (and we'll remove the pink since the border will make it now easy to see where our popup is):

	CanendarAgent>>openCalendarWindow
		| calendarRectangle screenOffset |
		calendarRectangle := self frameVisibleRectangle.
		screenOffset := pane topPane globalOrigin.
		dropDown := TransientWindow
			newPopUpIn: (calendarRectangle bottomLeft + screenOffset extent: calendarRectangle width asPoint)
			from: pane.
		dropDown border: #ridged.
		dropDown open.

Now when we open our drop down, we see the border (don't forget the bug fix at the top of this). Next year we're changing the name of #border: to #borderType:, which more accurately describes what we're asking for.

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

Next time we'll start the design and implementation of the calendar drop down contents.


And So It Goes
Sames

Read: How To Create A Custome Widget - Drop Down Window

Topic: Speaking of Innovation Previous Topic   Next Topic Topic: The dynamic languages meme spreads

Sponsored Links



Google
  Web Artima.com   

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