SqueakMap Package Loader UI

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
25 messages Options
12
Reply | Threaded
Open this post in threaded view
|

SqueakMap Package Loader UI

Brian Rice
Hi all,

I spent yesterday evening demo'ing Squeak to a fellow who works with  
EdUbuntu and OLPC since he wanted to write his educational software  
in Squeak to save space on the laptop. His kids were there and really  
got into it after some of the capabilities were made more obvious.

I got some great feedback, and it's always cool for me to show off  
Squeak games (the RTS that Eddie Cottongim made years ago is perhaps  
the best of the non-EToys style) and coding to kids, since I don't  
regularly work with them and most developers are such sticks-in-the-
mud about the weird UI.

Anyway, it occurred to me that just a little bit of effort in the UI  
design department would quickly improve Squeak's draw. Since I know  
the SqueakMap package loader and it's Squeak's gateway to the  
community for newbies as they start up Squeak (or should be), I  
started there.

I've added some buttons to a toolbar at the top and stole  
MessageNames' search bar to be more clear about the UI.

Current Screenshot (doesn't reflect help-balloon cleanups):
http://briantrice.com/Images/Squeak/SMLoader1.jpeg
With a filter on:
http://briantrice.com/Images/Squeak/SMLoader1Filtered.jpeg

These are only incremental changes, since I don't want to take on a  
huge-scope project, and don't own this and other packages, so a huge  
fork would be politically difficult. The best application code I  
found for Morphic UI was actually the IRC client, although it is a  
bit spec-heavy.

What do people think of this idea? Particularly the package owners,  
like Göran, but also whoever is "in charge" of the overall UI face of  
Squeak (that is, whoever would complain loudest if I wanted to  
totally re-arrange the world menus).

Also, which projects make this kind of effort obsolete or easier? I  
know about and like the Services/Commands framework and UI, and  
Tweak's menubar system, but don't know what they seek to replace.  
What I don't know is whether there is a simple menu-bar or other such  
system for easily setting up some shared-styled UI features that get  
the salient features right in front of the user instead of burying  
them in context menus.

Okay, I'll stop here for now. Feedback welcome!

--
-Brian
http://briantrice.com




PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: SqueakMap Package Loader UI

Brian Rice
I fixed up some of the problems with the previous layout and buttons  
and added package-specific toolbar buttons:
http://briantrice.com/Images/Squeak/SMLoader2.jpeg

Monticello packages (rev. 40 is the relevant one) at:
http://briantrice.com/Squeak/

- Installed packages and releases are now marked in bold.
- All the main buttons that people need to see are in a button-bar  
that works.
- The code is set up so that if there's a better way (more standard)  
to construct the toolbar, it will be easy to refactor to that form.
- The search bar is obviously marked as such.
- Menu entries are more succinct, which means people might actually  
read them (balloon help explains so I allowed them to be terse).

That seems like it's Good Enough to not put people off.

Comments? Suggestions? Rants?

--
-Brian
http://briantrice.com




PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: SqueakMap Package Loader UI

Romain Robbes-2

What about putting the search bar on the top bar, with the buttons?
Otherwise it seems pretty good to me!

Romain

Il giorno Nov 22, 2006, alle ore 10:37 AM, Brian Rice ha scritto:

I fixed up some of the problems with the previous layout and buttons and added package-specific toolbar buttons:

Monticello packages (rev. 40 is the relevant one) at:

- Installed packages and releases are now marked in bold.
- All the main buttons that people need to see are in a button-bar that works.
- The code is set up so that if there's a better way (more standard) to construct the toolbar, it will be easy to refactor to that form.
- The search bar is obviously marked as such.
- Menu entries are more succinct, which means people might actually read them (balloon help explains so I allowed them to be terse).

That seems like it's Good Enough to not put people off.

Comments? Suggestions? Rants?

--
-Brian



--
Romain Robbes





Reply | Threaded
Open this post in threaded view
|

Re: SqueakMap Package Loader UI

David T. Lewis
In reply to this post by Brian Rice
On Wed, Nov 22, 2006 at 01:37:15AM -0800, Brian Rice wrote:
> I fixed up some of the problems with the previous layout and buttons  
> and added package-specific toolbar buttons:
> http://briantrice.com/Images/Squeak/SMLoader2.jpeg

This looks very nice to me. The buttons give a visual suggestion of
what can be done, which seems better for first time users who may
not know about hidden menus. A couple of suggestions:

On the filtered view (SMLoader1Filtered.jpeg), I don't see a visual
indication of the active filtering criteria. It would be good to
show this.

VMMakerTool and the Monticello browsers (and probably others that
I'm not thinking of) use a similar button-driven design, but the
button shapes and colors seem to vary. A consistent look would be
a good thing. Of the UIs that I can think of, I guess that consistency
between Monticello and SqueakMap would be the first priority, since
they both serve as package loaders from the point of view of user.

Nice work!

Dave


Reply | Threaded
Open this post in threaded view
|

Re: SqueakMap Package Loader UI

timrowledge
In reply to this post by Brian Rice

On 22-Nov-06, at 1:37 AM, Brian Rice wrote:

> I fixed up some of the problems with the previous layout and  
> buttons and added package-specific toolbar buttons:
> http://briantrice.com/Images/Squeak/SMLoader2.jpeg

I like what I see there. Now if only we could finally sort out the  
ancient paneColor related problems we were all discussing a while ago  
so that the package tool obeyed the user's colour settings it would  
really make an improvement!

Adding the search pane is an excellent move. I could see that being a  
useful thing to add to some other browsers as well.


tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
'Profanity: the universal programming language'





Reply | Threaded
Open this post in threaded view
|

Re: SqueakMap Package Loader UI

Damien Cassou-3
In reply to this post by Brian Rice
Hi Brian,

> Also, which projects make this kind of effort obsolete or easier? I know
> about and like the Services/Commands framework and UI, and Tweak's
> menubar system, but don't know what they seek to replace. What I don't
> know is whether there is a simple menu-bar or other such system for
> easily setting up some shared-styled UI features that get the salient
> features right in front of the user instead of burying them in context
> menus.

if you are using 3.9, you may want to have a look at TestRunner
(included in 3.9). Lukas Renggli wrote it and it is very good I think.
It uses the new tool framework, ToolBuilder. I think this is the right
new way of implementing tool. It should be compatible with new frameworks.

Tell me when you trust your implementation, I will include it in
Squeak-dev image.

Thanks for your work.


Bye

--
Damien Cassou

Reply | Threaded
Open this post in threaded view
|

Re: SqueakMap Package Loader UI

Brian Rice
In reply to this post by David T. Lewis

On Nov 22, 2006, at 6:16 AM, David T. Lewis wrote:

> On Wed, Nov 22, 2006 at 01:37:15AM -0800, Brian Rice wrote:
>> I fixed up some of the problems with the previous layout and buttons
>> and added package-specific toolbar buttons:
>> http://briantrice.com/Images/Squeak/SMLoader2.jpeg
>
> This looks very nice to me. The buttons give a visual suggestion of
> what can be done, which seems better for first time users who may
> not know about hidden menus. A couple of suggestions:
>
> On the filtered view (SMLoader1Filtered.jpeg), I don't see a visual
> indication of the active filtering criteria. It would be good to
> show this.
Hmmm. I'll see what I can do, but that might be more difficult to  
design and implement.

I actually don't use the filters at all in normal usage, just  
sticking with the search bar, but that could just be a result of the  
filter system not being approachable enough. It seems like the kind  
of thing that StarBrowser-style design was made for, which makes me  
think a bigger re-design is in order, something I'd like to avoid for  
now.

> VMMakerTool and the Monticello browsers (and probably others that
> I'm not thinking of) use a similar button-driven design, but the
> button shapes and colors seem to vary. A consistent look would be
> a good thing. Of the UIs that I can think of, I guess that consistency
> between Monticello and SqueakMap would be the first priority, since
> they both serve as package loaders from the point of view of user.

That's a good point about Monticello, especially since I know it  
greys out buttons and does other context-sensitive things. I'll try  
to make it consistent with that, at least.

If I can, I'll make both use ToolBuilder, as suggested by Damien.

--
-Brian
http://briantrice.com




PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: SqueakMap Package Loader UI

Brian Rice
In reply to this post by Damien Cassou-3

On Nov 22, 2006, at 10:44 AM, Damien Cassou wrote:

> Hi Brian,
>
>> Also, which projects make this kind of effort obsolete or easier?  
>> I know about and like the Services/Commands framework and UI, and  
>> Tweak's menubar system, but don't know what they seek to replace.  
>> What I don't know is whether there is a simple menu-bar or other  
>> such system for easily setting up some shared-styled UI features  
>> that get the salient features right in front of the user instead  
>> of burying them in context menus.
>
> if you are using 3.9, you may want to have a look at TestRunner  
> (included in 3.9). Lukas Renggli wrote it and it is very good I  
> think. It uses the new tool framework, ToolBuilder. I think this is  
> the right new way of implementing tool. It should be compatible  
> with new frameworks.
Good point. I'll take a look.

> Tell me when you trust your implementation, I will include it in  
> Squeak-dev image.
>
> Thanks for your work.

Thanks. This is my first Squeak contribution in a while.

--
-Brian
http://briantrice.com




PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: SqueakMap Package Loader UI

Brian Rice
In reply to this post by Romain Robbes-2

On Nov 22, 2006, at 6:01 AM, Romain Robbes wrote:

> What about putting the search bar on the top bar, with the buttons?
> Otherwise it seems pretty good to me!

I'm divided on that, since moving the search bar into the top bar  
would make more room vertically and make the search pane stand out a  
little more, but it's nice to see it stacked/grouped with the package  
list, since that's what it's associated with.

For now, I'll leave it where it is, but thanks for the idea.

--
-Brian
http://briantrice.com




PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: SqueakMap Package Loader UI

Chris Muller
In reply to this post by Brian Rice
> Comments? Suggestions? Rants?

I like the search bar, although if the search button and filter field were to switch places, the flow from left-to-right would feel more natural.  Besides the input, the entry field should also output the current search term (i.e., don't erase the last-used term).

However, I think the command buttons across the top are a step in the wrong direction.  Right-clicking is as important as left-clicking, not just in Squeak but in mainstream Windows too.  No one will get very far unless they know, "left click select, right click options".  

Squeak should give newbies a simple, consistent interface and just a little training.  By "simple consistent" I mean showing just the objects and then emphatically delineate the concept of "sending a message" by consistently letting the context menus represent a "message sending" mechanism.  Make Squeak "objects all the way up" so the mindset will be consistent when we dive through objects "all the way down".

So many interfaces today are focused on showing every single thing the user can click; for example, laden with long scrolling lists or drop-down lists.  Their usability is not scalable, and poor because they have the user _laboring_ with the computer to find something instead of vice-versa.

With scrolling lists we display every object in the list, now we want to add all possible command buttons for all possible object selections showing too.  Ok, not all commands, just few enough that we only *quadruple* the number of widgets the user is initially confronted with.  So in the end, the user still has to know to right-click, so this change hasn't really solved the original usability issue.

I prefer to present a simple, consistent, usable, well-executed, object-oriented interface.  Do so proudly, not apologetically, so that, along with some friendly, basic documentation right in the start-up image explaining how things work, we build appreciation not resentment for the differences.



Reply | Threaded
Open this post in threaded view
|

SMLoaderPlus and ToolBuilder (was Re: SqueakMap Package Loader UI)

Brian Rice
In reply to this post by Brian Rice
So, I've spent a day with the ToolBuilder. I'm mostly impressed, but  
there are some issues I'll describe as I explain what I've made.

Rev. 44 in the repository on my site (below) has the new  
functionality in mostly-working order:
http://briantrice.com/Squeak/SMLoader-btr.44.mcz

When the package loads, there are SMLoader and SMLoaderPlus. Both of  
them in their class-side #initialize methods, check for the presence  
of ToolBuilder, and SMLoader registers itself if ToolBulder isn't  
present, and otherwise, SMLoaderPlus registers itself. I think this  
setup will help publish SMLoader without problems in older Squeak  
versions. I still need to test this in various ways.

Here is a screenshot of SMLoaderPlus:
  http://briantrice.com/Images/Squeak/SMLoaderPlus1.jpeg

First, I'll state what I liked about ToolBuilder: it removed some  
grimy nuts-and-bolts-ness from the application code. I didn't have to  
specify dependents except by saying which selector a given widget  
should pay attention to. It was easy to specify buttons and their  
enabling/disabling. ToolBuilder uses some reasonable defaults for a  
lot of rendering, so my app looks like other ToolBuilder-using apps  
without any work, and I don't have to maintain that. And it'll  
presumably work on Tweak and even MVC if that part gets fixed.  
Despite the long rambling after this, I endorse ToolBuilder and think  
it is a good kind of way forward.

The search pane... hm, this gave me some grief. So, in this builder  
design pattern, you construct a tree of specification objects, pass  
it to the Builder object and tell it to build: them. This seems  
rather Java-inspired, but that's beside the point.
- One issue I had was trying to recreate the "Search" button that in  
the original, took the search field as its model and called #accept  
on it to kick off a search. In a builder interface, you can't do  
this, because you only get the specification objects and not the  
output. In fact, you're not supposed to be able to access the output.  
I thought about work-arounds, but they all involved propagating the  
search field text to the model on every keystroke and then having the  
button call a method on the model that uses that, or making a  
trampoline in the model that the search field would watch... except  
that it can't do that. So the search button had to go, because  
ToolBuilder can't do that easily.
- The other issue was that I couldn't add a help text to the text  
field. Why isn't #help an attribute of every specification element  
type? Who do I bother to get that change made to ToolBuilder? Every  
object in Squeak needs the ability to explain itself, even if the  
user turns all of it off (smarter help-showing strategies would  
probably make it less intrusive).
- Trying to layout the search pane *with* the buttons on the top bar  
was an exercise in frustration. Passing a fractionally-specified  
frame rectangle seems like it should be straightforward in semantics,  
but I couldn't get any layout to happen that corresponded with my  
intuition, and I still haven't figured out how exactly the builder  
code deals with those frame specifications. So I moved the search  
field back to the package-list pane. What am I missing?

PluggableTreeSpec is strange. It took me a while to figure out what  
kind of protocol I had to make to populate it, or what objects had to  
respond to the selectors (sometimes it's the item wrapper object,  
other times the model). Perhaps there should be a default protocol, a  
default name for most selectors and a little documentation saying  
what those are, and that they're override-able in the constructor or  
mutator methods. (This idea actually reminds me of Rails, and  
probably rightly so, as they are both builder patterns.) Particularly  
odd-seeming is how to update the selection programmatically, as  
happens when the search pane is used - if I call "self changed:  
#selectedItemWrapperPath", the selector that the package list is  
watching, it deadlocks trying to redraw until I hit <alt-period>, so  
I've left that out and the pane doesn't update on its own.

Finally, there doesn't seem to be any documentation on ToolBuilder  
that is better than the source of the apps created as examples on  
SqueakSource (not in the image). I learned the most when I found and  
loaded them. But the classes all have basic, informative comments.

On Nov 22, 2006, at 1:37 AM, Brian Rice wrote:

> I fixed up some of the problems with the previous layout and  
> buttons and added package-specific toolbar buttons:
> http://briantrice.com/Images/Squeak/SMLoader2.jpeg
>
> Monticello packages (rev. 40 is the relevant one) at:
> http://briantrice.com/Squeak/
>
> - Installed packages and releases are now marked in bold.
> - All the main buttons that people need to see are in a button-bar  
> that works.
> - The code is set up so that if there's a better way (more  
> standard) to construct the toolbar, it will be easy to refactor to  
> that form.
> - The search bar is obviously marked as such.
> - Menu entries are more succinct, which means people might actually  
> read them (balloon help explains so I allowed them to be terse).
>
> That seems like it's Good Enough to not put people off.
>
> Comments? Suggestions? Rants?
--
-Brian
http://briantrice.com




PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: SqueakMap Package Loader UI

Brian Rice
In reply to this post by Chris Muller
On Nov 22, 2006, at 5:44 PM, Chris Muller wrote:

>> Comments? Suggestions? Rants?
>
> I like the search bar, although if the search button and filter  
> field were to switch places, the flow from left-to-right would feel  
> more natural.  Besides the input, the entry field should also  
> output the current search term (i.e., don't erase the last-used term).
>
> However, I think the command buttons across the top are a step in  
> the wrong direction.  Right-clicking is as important as left-
> clicking, not just in Squeak but in mainstream Windows too.  No one  
> will get very far unless they know, "left click select, right click  
> options".
Unfortunately, I have been wrestling with ToolBuilder and Morphic  
mostly, and can't get this far ideologically with the interface. So  
I'm sticking with the button-bar for now on the grounds that it's an  
improvement.

> Squeak should give newbies a simple, consistent interface and just  
> a little training.  By "simple consistent" I mean showing just the  
> objects and then emphatically delineate the concept of "sending a  
> message" by consistently letting the context menus represent a  
> "message sending" mechanism.  Make Squeak "objects all the way up"  
> so the mindset will be consistent when we dive through objects "all  
> the way down".

I think we need to make it *easy* to produce simple, consistent,  
object-oriented interfaces in a single way that can be documented and  
moved-forward as a community. ToolBuilder is the closest to doing  
that, and it needs work.

Writing apps in Morphic is *hard* - granted, not as hard as some C++  
or Java frameworks, but that's not much of a comparison. It's easier  
to write a Seaside app than a Morphic app. We're a small community  
and need to have a scenario where a single casual Squeak hacker can  
crank out an interface in an afternoon. If we hand them a framework  
that lets them do that and the user gets simplicity and consistency  
and OO-ness for free, all the better.

> So many interfaces today are focused on showing every single thing  
> the user can click; for example, laden with long scrolling lists or  
> drop-down lists.  Their usability is not scalable, and poor because  
> they have the user _laboring_ with the computer to find something  
> instead of vice-versa.
>
> With scrolling lists we display every object in the list, now we  
> want to add all possible command buttons for all possible object  
> selections showing too.  Ok, not all commands, just few enough that  
> we only *quadruple* the number of widgets the user is initially  
> confronted with.  So in the end, the user still has to know to  
> right-click, so this change hasn't really solved the original  
> usability issue.
>
> I prefer to present a simple, consistent, usable, well-executed,  
> object-oriented interface.  Do so proudly, not apologetically, so  
> that, along with some friendly, basic documentation right in the  
> start-up image explaining how things work, we build appreciation  
> not resentment for the differences.
Yeah, I agree in principle, but right now that's too much work to do  
for any single Squeak app, so I'm going to make the one I've got a  
handle on a little better, and think about amp'ing up ToolBuilder  
next so that it can do this for the developer.

Let's face it - *none* of Squeak's contextual menus or interfaces are  
laid out with any sense of usability. If it's easier in Squeak to  
make a window with three unlabeled  rectangle panes with menus that  
just shove every control protocol into a list and call that an  
interface to an application, then it doesn't matter what principles  
we exhort, the developer who's squeezed for time (IOW all of us)  
isn't going to make a better interface.

--
-Brian
http://briantrice.com




PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

multi-widget accept/cancel (was Re: SMLoaderPlus and ToolBuilder)

Lex Spoon
In reply to this post by Brian Rice
Brian Rice <[hidden email]> writes:

> The search pane... hm, this gave me some grief. So, in this builder
> design pattern, you construct a tree of specification objects, pass
> it to the Builder object and tell it to build: them. This seems
> rather Java-inspired, but that's beside the point.
> - One issue I had was trying to recreate the "Search" button that in
> the original, took the search field as its model and called #accept
> on it to kick off a search. In a builder interface, you can't do
> this, because you only get the specification objects and not the
> output. In fact, you're not supposed to be able to access the output.
> I thought about work-arounds, but they all involved propagating the
> search field text to the model on every keystroke and then having the
> button call a method on the model that uses that, or making a
> trampoline in the model that the search field would watch... except
> that it can't do that.


This I think is a mis-designs in the Smalltalk accept/cancel style.  I
like accept/cancel in general, *except* that it should really apply at
the level of an entire pane [1], not at the level of individual widgets.

When I write Squeak dialogs by hand, the best approach I have found is
that each entire pane has a variable with a list of individual widgets
that need to be accepted before the pane can do its work.  Then, I
have a method that iterates through this list and calls acceptIfNeeded
(or whatever it is called).  Then, I call this method at the beginning
of every method that observes the input of those fields.

I implement this pattern repeatedly.  It would be a candidate for a
framework such as ToolBuilder.  (Of course, if ToolBuilder has another
approach to this problem, then just as well!)

For your search example, the model object behind the search-area
pane--or indeed the search-area pane itsealf--could have a variable
pointing back to the text widget where the user types in the search
phrase.  Then the "search" method would accept this pane before doing
the actual search.

By the way, always remember when doing this that an "accept" can fail
on invalid input!  These methods should return a boolean to indicate
whether the accept was successful, and if it was not, the calling
method should silently quit.

-Lex





[1] I started to write "window", but really what I write just applies
to contiguous portions of a window used for one purpose.  There is a
contingent of Squeak UI designers who prefer to have big
multi-function windows instead of the more classical single-purpose
windows.



Reply | Threaded
Open this post in threaded view
|

Re: SMLoaderPlus and ToolBuilder (was Re: SqueakMap Package Loader UI)

Brian Rice
In reply to this post by Brian Rice
I have fixed a bug in the #initialize code which I was somehow  
missing before. SMLoader seems to load fine now in 3.7-3.9 for me,  
modulo the oddities that are hopefully soon to be fixed in the use of  
ImageSegments for SqueakMap's database (you'll see those ByteSymbol/
ByteString/etc. notices). The new revision is 45.

On Nov 23, 2006, at 1:57 PM, Brian Rice wrote:

> Rev. 44 in the repository on my site (below) has the new  
> functionality in mostly-working order:
> http://briantrice.com/Squeak/SMLoader-btr.44.mcz
>
> When the package loads, there are SMLoader and SMLoaderPlus. Both  
> of them in their class-side #initialize methods, check for the  
> presence of ToolBuilder, and SMLoader registers itself if  
> ToolBulder isn't present, and otherwise, SMLoaderPlus registers  
> itself. I think this setup will help publish SMLoader without  
> problems in older Squeak versions. I still need to test this in  
> various ways.
>
> Here is a screenshot of SMLoaderPlus:
>  http://briantrice.com/Images/Squeak/SMLoaderPlus1.jpeg
--
-Brian
http://briantrice.com




PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: SMLoaderPlus and ToolBuilder (was Re: SqueakMap Package Loader UI)

Andreas.Raab
In reply to this post by Brian Rice
Brian Rice wrote:
> The search pane... hm, this gave me some grief. So, in this builder
> design pattern, you construct a tree of specification objects, pass it
> to the Builder object and tell it to build: them. This seems rather
> Java-inspired, but that's beside the point.

That's a funny comment given how little exposure I had to Java ;-)

> - One issue I had was trying to recreate the "Search" button that in the
> original, took the search field as its model and called #accept on it to
> kick off a search. In a builder interface, you can't do this, because
> you only get the specification objects and not the output. In fact,
> you're not supposed to be able to access the output. I thought about
> work-arounds, but they all involved propagating the search field text to
> the model on every keystroke and then having the button call a method on
> the model that uses that, or making a trampoline in the model that the
> search field would watch... except that it can't do that. So the search
> button had to go, because ToolBuilder can't do that easily.

Yes, that is true.

> - The other issue was that I couldn't add a help text to the text field.
> Why isn't #help an attribute of every specification element type? Who do
> I bother to get that change made to ToolBuilder? Every object in Squeak
> needs the ability to explain itself, even if the user turns all of it
> off (smarter help-showing strategies would probably make it less
> intrusive).

The best person to bother would be me. And I agree that text fields
should have a #help to be used with it. If you post a fix to mantis just
assign it to me.

> - Trying to layout the search pane *with* the buttons on the top bar was
> an exercise in frustration. Passing a fractionally-specified frame
> rectangle seems like it should be straightforward in semantics, but I
> couldn't get any layout to happen that corresponded with my intuition,
> and I still haven't figured out how exactly the builder code deals with
> those frame specifications. So I moved the search field back to the
> package-list pane. What am I missing?

Not sure. The layouts should work just as intuitively as you thought.
Can you send an example that didn't work the way you expected it?

> PluggableTreeSpec is strange. It took me a while to figure out what kind
> of protocol I had to make to populate it, or what objects had to respond
> to the selectors (sometimes it's the item wrapper object, other times
> the model).

Actually you seem to be misunderstanding something more fundamental
about the tree widgets here. From the programmer's point of view there
is no "wrapper object" (this is only part of the Morphic implementation
but doesn't exist in Tweak for example) and the messages are *always*
sent to the model and *always* pass the item along to query for. So, for
example, to query the children of an item the tree sends the
<getChildren> selector, a one-argument message passing the item
alongside it. This avoids the need for any of the wrappers. For example,
instead of using a hierarchy of FileDirectoryWrappers you would use
something like here:

MyFileList>>getDirectoryRoots
   "Answer the roots for the directory tree"
   ^Array with: FileDirectory root

MyFileList>>getChildrenOf: directory
   "Answer the children of the directory"
   ^directory directoryNames collect:[:str| directory directoryNamed: str]

MyFileList>>getLabelOf: directory
   "Answer the label for the directory"
   ^directory localName

etc. Again, the idea is to abstract away the current (Morphic)
implementation of trees and replace them with a set of pluggable
selectors that can be used to query for the relevant properties.

> Perhaps there should be a default protocol, a default name
> for most selectors and a little documentation saying what those are, and
> that they're override-able in the constructor or mutator methods. (This
> idea actually reminds me of Rails, and probably rightly so, as they are
> both builder patterns.) Particularly odd-seeming is how to update the
> selection programmatically, as happens when the search pane is used - if
> I call "self changed: #selectedItemWrapperPath", the selector that the
> package list is watching, it deadlocks trying to redraw until I hit
> <alt-period>, so I've left that out and the pane doesn't update on its own.

Yes, you'd be interfering with the Morphic implementation in this case.
What you want to use is <getSelectedPath> selector from the
PluggableTreeSpec, e.g.,

MyModel>>getSelectedDirectoryPath
   "Answer the path for the currently selected directory"
   ^selectedDirectory pathParts

and then:

MyModel>>changeDirectoryTo: newDirectory
   selectedDirectory := newDirectory.
   self changed: #getSelectedDirectoryPath.

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: SMLoaderPlus and ToolBuilder (was Re: SqueakMap Package Loader UI)

Brian Rice

On Nov 24, 2006, at 1:10 PM, Andreas Raab wrote:

> Brian Rice wrote:
>> So, in this builder design pattern, you construct a tree of  
>> specification objects, pass it to the Builder object and tell it  
>> to build: them. This seems rather Java-inspired, but that's beside  
>> the point.
>
> That's a funny comment given how little exposure I had to Java ;-)

Fair enough. It's just my reaction to "Builder build:" idioms where  
the Builder class is only there for that build: protocol and is  
stateless (okay, there's a #parent slot, but that wouldn't conflict  
with any other protocol except if the name clashed). It's "nouning a  
verb", if you will. Usually that means it's fine to move the protocol  
to another class; the concrete one that comes to mind is the  
UIManager, which notably already also is subclassed for each UI  
framework. In fact, I'd like to make that a concrete suggestion,  
tempered by the political expense of getting users of the protocol to  
switch (but that seems like one class reference per user, so probably  
not difficult).

To continue this mental experiment a little, I'd suggest:
- Moving ToolBuilder protocol and #parent instvar to UIManager (and  
recurse on subclasses).
- Changing users of ToolBuilder to UIManager.
- Changing associated SUnit classes to use UIManager in their names.
- Renaming ToolBuilderSpec to UISpec.

How does this sound? I can assist if appropriate.

>> - One issue I had was trying to recreate the "Search" button that  
>> in the original, took the search field as its model and called  
>> #accept on it to kick off a search. In a builder interface, you  
>> can't do this, because you only get the specification objects and  
>> not the output. In fact, you're not supposed to be able to access  
>> the output. I thought about work-arounds, but they all involved  
>> propagating the search field text to the model on every keystroke  
>> and then having the button call a method on the model that uses  
>> that, or making a trampoline in the model that the search field  
>> would watch... except that it can't do that. So the search button  
>> had to go, because ToolBuilder can't do that easily.
>
> Yes, that is true.
Maybe it can be fixed by detecting that a model is a Spec and then  
remembering that in an IdentityDictionary and then mapping it to the  
output. I don't know how feasible that is, but it's seems like it'd  
work reasonably.

>> - The other issue was that I couldn't add a help text to the text  
>> field. Why isn't #help an attribute of every specification element  
>> type? Who do I bother to get that change made to ToolBuilder?  
>> Every object in Squeak needs the ability to explain itself, even  
>> if the user turns all of it off (smarter help-showing strategies  
>> would probably make it less intrusive).
>
> The best person to bother would be me. And I agree that text fields  
> should have a #help to be used with it. If you post a fix to mantis  
> just assign it to me.
I'll do that, probably with enough of a changeset to start from.

>> - Trying to layout the search pane *with* the buttons on the top  
>> bar was an exercise in frustration. Passing a fractionally-
>> specified frame rectangle seems like it should be straightforward  
>> in semantics, but I couldn't get any layout to happen that  
>> corresponded with my intuition, and I still haven't figured out  
>> how exactly the builder code deals with those frame  
>> specifications. So I moved the search field back to the package-
>> list pane. What am I missing?
>
> Not sure. The layouts should work just as intuitively as you  
> thought. Can you send an example that didn't work the way you  
> expected it?
Okay, here's my explanation:
- I've got buildSearchPaneWith: to make the search pane, and  
buildButtonBarWith: that builds the buttons.
- Right now, buildWith: calls the search-pane code and composes it  
with the other top-level panes to make the whole window.
- If I move the buildSearchPaneWith: call into buildButtonBarWith:  
(before the buttons in my case), then frame: calls don't really work  
as well.
- Usually I get a search pane that is much taller than the buttons,  
and/or the buttons will not clear past the end of the search pane.
- When I had an extra search button, the button wouldn't size to fit  
its own text and I couldn't figure out what frame: call to get it to  
fit right.
- On the other hand, I was putting the search field and button into  
their own panel and then putting the panel into the button panel, but  
even without that extra wrapper, I had the problems with the search  
field on that row.

>> PluggableTreeSpec is strange. It took me a while to figure out  
>> what kind of protocol I had to make to populate it, or what  
>> objects had to respond to the selectors (sometimes it's the item  
>> wrapper object, other times the model).
>
> Actually you seem to be misunderstanding something more fundamental  
> about the tree widgets here. From the programmer's point of view  
> there is no "wrapper object" (this is only part of the Morphic  
> implementation but doesn't exist in Tweak for example) and the  
> messages are *always* sent to the model and *always* pass the item  
> along to query for. So, for example, to query the children of an  
> item the tree sends the <getChildren> selector, a one-argument  
> message passing the item alongside it. This avoids the need for any  
> of the wrappers. For example, instead of using a hierarchy of  
> FileDirectoryWrappers you would use something like here:
Aha. The old SMLoader code uses wrappers so I just didn't think I  
needed to disregard them. FileListPlus actually was the code that I  
was looking at as an example, but I didn't get this.

> MyFileList>>getDirectoryRoots
>   "Answer the roots for the directory tree"
>   ^Array with: FileDirectory root
>
> MyFileList>>getChildrenOf: directory
>   "Answer the children of the directory"
>   ^directory directoryNames collect:[:str| directory  
> directoryNamed: str]
>
> MyFileList>>getLabelOf: directory
>   "Answer the label for the directory"
>   ^directory localName
>
> etc. Again, the idea is to abstract away the current (Morphic)  
> implementation of trees and replace them with a set of pluggable  
> selectors that can be used to query for the relevant properties.
Gotcha. Thanks.

>> Perhaps there should be a default protocol, a default name for  
>> most selectors and a little documentation saying what those are,  
>> and that they're override-able in the constructor or mutator  
>> methods. (This idea actually reminds me of Rails, and probably  
>> rightly so, as they are both builder patterns.) Particularly odd-
>> seeming is how to update the selection programmatically, as  
>> happens when the search pane is used - if I call "self changed:  
>> #selectedItemWrapperPath", the selector that the package list is  
>> watching, it deadlocks trying to redraw until I hit <alt-period>,  
>> so I've left that out and the pane doesn't update on its own.
>
> Yes, you'd be interfering with the Morphic implementation in this  
> case. What you want to use is <getSelectedPath> selector from the  
> PluggableTreeSpec, e.g.,
>
> MyModel>>getSelectedDirectoryPath
>   "Answer the path for the currently selected directory"
>   ^selectedDirectory pathParts
>
> and then:
>
> MyModel>>changeDirectoryTo: newDirectory
>   selectedDirectory := newDirectory.
>   self changed: #getSelectedDirectoryPath.
Unfortunately, after making this refactoring, I still have the same  
problem. I'll elaborate:
- I removed any uses of ItemWrappers.
- I changed the #selectedItemWrapperPath to #selectedItemPath,  
returning an Array of the same labels used to build the tree to begin  
with.
- There was a variation in terms of bolding some strings, making them  
Texts, but removing this variation did not change the outcome  
(requiring a user-halt).

What I'm reading implicitly is that the path needs to be a sequence  
of the keys used to drill down to the item. That it is not the  
sequence of objects themselves stored with those keys. It seems to  
bear out with the usage, but maybe I'm way off base for reasons of  
misinterpretation.

When I call "self changed: #selectedItemPath", I get a lock-up which  
I have to halt which puts me in a stack with  
PluggableTreeMorph>>update: (on #selectedItemPath) and  
Array>>at:ifAbsent: at the top.

I've made my latest snapshot available at:
http://briantrice.com/Squeak/SMLoader-btr.46.mcz

Uncomment line 3 of SMLoaderPlus>>selectedItem: to see the bug. If  
someone could look at this with some Morphic knowledge, it'd probably  
be more effective than my analysis.

--
-Brian
http://briantrice.com




PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: multi-widget accept/cancel (was Re: SMLoaderPlus and ToolBuilder)

Brian Rice
In reply to this post by Lex Spoon

On Nov 24, 2006, at 1:04 AM, Lex Spoon wrote:

> Brian Rice <[hidden email]> writes:
>> The search pane... hm, this gave me some grief. So, in this builder
>> design pattern, you construct a tree of specification objects, pass
>> it to the Builder object and tell it to build: them. This seems
>> rather Java-inspired, but that's beside the point.
>> - One issue I had was trying to recreate the "Search" button that in
>> the original, took the search field as its model and called #accept
>> on it to kick off a search. In a builder interface, you can't do
>> this, because you only get the specification objects and not the
>> output. In fact, you're not supposed to be able to access the output.
>> I thought about work-arounds, but they all involved propagating the
>> search field text to the model on every keystroke and then having the
>> button call a method on the model that uses that, or making a
>> trampoline in the model that the search field would watch... except
>> that it can't do that.
>
> This I think is a mis-designs in the Smalltalk accept/cancel style.  I
> like accept/cancel in general, *except* that it should really apply at
> the level of an entire pane [1], not at the level of individual  
> widgets.
I agree about this perspective.

> When I write Squeak dialogs by hand, the best approach I have found is
> that each entire pane has a variable with a list of individual widgets
> that need to be accepted before the pane can do its work.  Then, I
> have a method that iterates through this list and calls acceptIfNeeded
> (or whatever it is called).  Then, I call this method at the beginning
> of every method that observes the input of those fields.

Huh. That does seem like a decent way to get the job done in morphic.

> I implement this pattern repeatedly.  It would be a candidate for a
> framework such as ToolBuilder.  (Of course, if ToolBuilder has another
> approach to this problem, then just as well!)

ToolBuilder doesn't do this - it just offers PluggableInputFieldSpec  
which is just a text input field. The spec could conceivably be  
extended with an action button and/or title, but it doesn't seem like  
an easy way to go.

UIManager of course has its dialog protocol, which to me sounds like  
a ChoiceSpec or something similar, but it's not the same as offering  
a non-modal open-input choice, or even a modal set of open-(or not)-
input choices. Certainly an InputSpec makes sense which would come  
with its own way to specify validators and sub-validators.

> For your search example, the model object behind the search-area
> pane--or indeed the search-area pane itsealf--could have a variable
> pointing back to the text widget where the user types in the search
> phrase.  Then the "search" method would accept this pane before doing
> the actual search.

The problem is that the model (that specifies what it wants built)  
only holds on to the /spec/ of the widget, not the widget itself. The  
point of the build process is to decouple that model from the actual  
structural details of the output, focussing only on the spec. If I  
reach into the "window" variable output and grab the specific morph  
in question, I've coupled my app not just to Morphic but to the way  
in which the ToolBuilder generates Morphic widgets.

But maybe what you're saying is that there needs to be a separate  
model, perhaps generated for every input field/set. That's  
interesting, but I don't know what to do with that idea.

> By the way, always remember when doing this that an "accept" can fail
> on invalid input!  These methods should return a boolean to indicate
> whether the accept was successful, and if it was not, the calling
> method should silently quit.

Yeah, that's a good point.

> [1] I started to write "window", but really what I write just applies
> to contiguous portions of a window used for one purpose.  There is a
> contingent of Squeak UI designers who prefer to have big
> multi-function windows instead of the more classical single-purpose
> windows.

There should probably be a term neutral to pane/window which  
specifies an activity or something. I'll give it some thought.

--
-Brian
http://briantrice.com




PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: multi-widget accept/cancel (was Re: SMLoaderPlus and ToolBuilder)

Lex Spoon
Brian Rice <[hidden email]> writes:

> On Nov 24, 2006, at 1:04 AM, Lex Spoon wrote:
> > When I write Squeak dialogs by hand, the best approach I have found is
> > that each entire pane has a variable with a list of individual widgets
> > that need to be accepted before the pane can do its work.  Then, I
> > have a method that iterates through this list and calls acceptIfNeeded
> > (or whatever it is called).  Then, I call this method at the beginning
> > of every method that observes the input of those fields.
>
> Huh. That does seem like a decent way to get the job done in morphic.
>
> > I implement this pattern repeatedly.  It would be a candidate for a
> > framework such as ToolBuilder.  (Of course, if ToolBuilder has another
> > approach to this problem, then just as well!)
>
> ToolBuilder doesn't do this - it just offers PluggableInputFieldSpec
> which is just a text input field. The spec could conceivably be
> extended with an action button and/or title, but it doesn't seem like
> an easy way to go.

One approach would be that all button specs optionally trigger this
"accept everything" behavior.  Buttons that have this option turned on
would have an intermediary between the ButtonMorph and the model.
This intermediary would accept all fields in the dialog before
invoking the user-specified method on the model.

This option could even be turned on by default!  It seems like the
common case, as well as the safer case.


> Certainly an InputSpec makes sense which would come
> with its own way to specify validators and sub-validators.

Yeah, that's another thing.  There are various levels of input
validation for dialogs, aren't there?  There's syntax of individual
inputs (that's not a valid date), things dependent on different fields
(your final date is earlier than yoru start date), and the overall
final request (you just tried to schedule an appointment at a time
that overlaps an existing one).  It would be nice to have a generic
way to specify these validators.



> > For your search example, the model object behind the search-area
> > pane--or indeed the search-area pane itsealf--could have a variable
> > pointing back to the text widget where the user types in the search
> > phrase.  Then the "search" method would accept this pane before doing
> > the actual search.
>
> The problem is that the model (that specifies what it wants built)
> only holds on to the /spec/ of the widget, not the widget itself. The
> point of the build process is to decouple that model from the actual
> structural details of the output, focussing only on the spec. If I
> reach into the "window" variable output and grab the specific morph
> in question, I've coupled my app not just to Morphic but to the way
> in which the ToolBuilder generates Morphic widgets.


Yes, this coupling is ugly.  The intermediary idea I described above
seems to avoid this problem, though.  The intermediary is part of the
UI stuff.


Anyway, one way around this is to make each dialog have its own morph
class.  Then the dialog object has the pointers to the individual
input widgets.  This way, you keep the UI and model parts separate.


By the way, thinking of these issues, I hope that ToolBuilder has a
way for users to add their own morph classes to a UI.  This is an
escape hatch for any feature a user wants that is not already covered
by the existing system.  Even businessy plain-gray UI's will
occasionally benefit from a custom widget here and there.

-Lex


Reply | Threaded
Open this post in threaded view
|

Re: SMLoaderPlus and ToolBuilder (was Re: SqueakMap Package Loader UI)

Brian Rice
In reply to this post by Brian Rice
On Nov 24, 2006, at 4:42 PM, Brian Rice wrote:

> On Nov 24, 2006, at 1:10 PM, Andreas Raab wrote:
>> Brian Rice wrote:
>>> - The other issue was that I couldn't add a help text to the text  
>>> field. Why isn't #help an attribute of every specification  
>>> element type? Who do I bother to get that change made to  
>>> ToolBuilder? Every object in Squeak needs the ability to explain  
>>> itself, even if the user turns all of it off (smarter help-
>>> showing strategies would probably make it less intrusive).
>>
>> The best person to bother would be me. And I agree that text  
>> fields should have a #help to be used with it. If you post a fix  
>> to mantis just assign it to me.
>
> I'll do that, probably with enough of a changeset to start from.
Filed as report #5522 with a changeset including Morphic-rendering  
support that seems to work. See:
  http://bugs.impara.de/view.php?id=5522

Thanks!

--
-Brian
http://briantrice.com




PGP.sig (193 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: SMLoaderPlus and ToolBuilder (was Re: SqueakMap Package Loader UI)

Brian Rice
In reply to this post by Brian Rice
The error turned out to be that the tree participates in the change-
update mechanism which causes infinite recursion. To wit:
- Calling #selectedItem: in the model tells the tree that  
#selectedItemPath has updated
- The tree updates its path and then *by design* sends #selectedItem:  
to the model

In order to avoid a deadlock, a ~~ test in #selectedItem: on the new-
and-old values guards against further change-notification.

I am unsure what better pattern to use, since none of the other  
ToolBuilder-using tools uses another widget to update their trees.  
Perhaps it is a bug?

In any case, I'll release my fixes shortly.

On Nov 24, 2006, at 4:42 PM, Brian Rice wrote:

> Unfortunately, after making this refactoring, I still have the same  
> problem. I'll elaborate:
> - I removed any uses of ItemWrappers.
> - I changed the #selectedItemWrapperPath to #selectedItemPath,  
> returning an Array of the same labels used to build the tree to  
> begin with.
> - There was a variation in terms of bolding some strings, making  
> them Texts, but removing this variation did not change the outcome  
> (requiring a user-halt).
>
> What I'm reading implicitly is that the path needs to be a sequence  
> of the keys used to drill down to the item. That it is not the  
> sequence of objects themselves stored with those keys. It seems to  
> bear out with the usage, but maybe I'm way off base for reasons of  
> misinterpretation.
>
> When I call "self changed: #selectedItemPath", I get a lock-up  
> which I have to halt which puts me in a stack with  
> PluggableTreeMorph>>update: (on #selectedItemPath) and  
> Array>>at:ifAbsent: at the top.
>
--
-Brian
http://briantrice.com




PGP.sig (193 bytes) Download Attachment
12