The Artima Developer Community
Sponsored Link

Agile Buzz Forum
How To Create A Custom Widget - Starting The MacOSX Look Version

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 - Starting The MacOSX Look Version Posted: Jan 19, 2005 3:15 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 - Starting The MacOSX Look Version
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

Ok, today we start working on making our Calendar look good in the MacOSX look. Before we start, we need to fix one bug.


Bug Fix

	MacOSXDropDownListButtonArtist>>macOSXInternalButtonRectangle
		^self frameDisplayableRectangle

Simple Things First

Let's open our look chooser window (PollockWorkspaceWork new openLookSwitcherWindow) select the MacOSX look, and then open our tester (CalendarTest new openWindowWithCalendar) As we did with the Motif look, we'll start with an Artist:

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

Then we tell the MacOSXLookPolicy to use this as our artist for the calendar.

	Pollock.MacOSXLookPolicy class>>calendarArtistClass
		^Pollock.MacOSXCalendarArtist

And a test to make sure we got it right:

	CalendarTest>>testInitialArtistMacOSXLook
		self shouldnt: [Pollock.MacOSXLookPolicy installLookPreferences] raise: Error.
		self openWindowWithCalendar.
		self should: [calendar artist class == MacOSXCalendarArtist]

Decorations

We haven't added any new behavior, yet, but we will. Next we want to remove the interior decoration that is around the whole pane. In the MacOSX look, only the input field part has an interior decoration. This is basically the same as in the Motif look. So, we add a #calendarDecoration to the MacOSXBorderPolicy:

	MacOSXBorderPolicy class>>calendarDecoration
		^nil

Now if we open our Calendar, we properly get no total interior decoration. However, the input field has no decoration... and we do want one. So...

	MacOSXBorderPolicy class>>calendarInputFieldDecoration
		^self inputFieldDecoration

Special Artists

Now it looks better, but hardly perfect. The button (Action Part) is bigger vertically than the input field. There is a subtle reason for this. In MacOSX, if you start editing or otherwise activate an InputField, a blue "haze" appears around it. That "haze" takes up 2 pixels of the size of the widget. In other words, it's a kind of hidden, implicit decoration. If w click inside the input field, we'll see this blue haze. But in doing this, we see the haze surrounds only the InputField, not the whole widget. We'll start with just telling the widget to NOT have the haze around it by using a special artist that already knows how to do this. Doing good reuse, we'll use the same artist that the DropDownList uses, and is available by the #dropDownListInputFieldArtistClass or our Look policies:

	Calendar>>createDisplayPart
		displayPart := InputField new.
		displayPart frame: (FractionalFrame 
			fractionLeft: 0
			top: 0
			right: 1
			bottom: 1).
		displayPart frame rightOffset: [self artist buttonWidth negated].
		displayPart setArtist: (self widgetPolicy dropDownListInputFieldArtistClass on: displayPart).
		displayPart interiorDecoration: self borderPolicyClass calendarInputFieldDecoration.
		displayPart setEnclosingPane: self.
		self isOpen
			ifTrue: [displayPart setupKeyboardFor: self]
			ifFalse: [self configure: #setupKeyboardFor: for: displayPart argument: self].
		displayPart when: #clicked send: #triggerEvent: to: self with: #clicked.
		displayPart when: #rightClicked send: #triggerEvent: to: self with: #rightClicked.
		displayPart when: #doubleClicked send: #triggerEvent: to: self with: #doubleClicked.
		displayPart when: #aboutToLoseFocus send: #triggerEvent: to: self with: #aboutToLoseFocus.
		displayPart when: #losingFocus send: #triggerEvent: to: self with: #losingFocus.
		displayPart agent doNotIncludeInTabList.
		self when: #gettingFocus send: #activate to: displayPart.
		self when: #losingFocus send: #deactivate to: displayPart

Clearing The Haze

That's much better. However, if we click on our calendar widget button, a "haze" circle is painted inside the button. This is yet another selection issue. Buttons, by default, when selected, show a blue haze around them also. We're using a special artist, but now we need to tell the button/action part, to never show any haze, since the haze it wants to paint is inside the button. Fortunately, Pollock has an API for that too! It is however, a fairly private one, and really only used by pane developers. It is on the agent of a button, and we name it #showSelected:.

But first, we need to have a value we can send it that is associated with the artist. So, we'll create a #showSelected method first on CalendarArtist

	CalendarArtist>>showSelected
		^false

But we're not done yet, it turns out that in Motif, we DO want to show selected for those buttons. So...

	MotifCalendarArtist>>showSelected
		^true

The hard work is done, now we just have to use the information:

	CalendarArtist>>createActionPart
		actionPart := #{Pollock.Button} value new.
		actionPart frame: (FractionalFrame fractionLeft: 1 top: 0 right: 1 bottom: 1).
		actionPart frame leftOffset: [self buttonWidth negated].
		actionPart setArtist: (pane widgetPolicy dropDownListButtonArtistClass on: actionPart).
		actionPart interiorDecoration: pane borderPolicyClass dropDownListButtonDecoration.
		actionPart addComponent: self calendarButtonImage.
		actionPart agent showSelected: self showSelected.
		actionPart setEnclosingPane: pane.
		actionPart 
			when: #pressed
			send: #openCalendarWindow
			to: self agent

Now everything looks pretty good.

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

Next time, we'll deal with the fact that the actual Calendar, when active should have a haze around the whole widget, and all that entails.


And So It Goes
Sames

Read: How To Create A Custom Widget - Starting The MacOSX Look Version

Topic: Re: Why Word hates you Previous Topic   Next Topic Topic: A question on priorities

Sponsored Links



Google
  Web Artima.com   

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