On 27.07.2011, at 09:04, Christian Haider wrote: > Albeit the progress is painfully slow - 4 years after dropping > Widgetry, which started 6 years before that, having similar goals > based on similar reasoning.... That's a matter of human resources and priorities, and the general decision to stay backwards compatible at all cost doesn't make it easier. No idea if it helps, but at least concerning graphics display, the following rules have proven to be very helpful, if strictly followed: => There is no drawing except in #displayOn: for each visual => The latter is triggered exclusively by the UI thread's event loop (as a result all drawing always happens on the same thread) => During execution of a new "frame", physical display updates are suspended/buffered => Execution frequency is limited to a certain "frame rate" (ensures that constant invalidation or animation does not block the application) => There is an option to suspend/accumulate redisplay during complex operations to minimize updates. If it were consistently implemented this way, that would already be a big step forward. It helps to think of a GUI as an animation rendered in frames (albeit at a very slow framerate most of the time). The responsibility for rendering a frame is totally out of the scope of a widget AND the application. The real question however is how to build and alter the view hierarchy and how to reference items in it. That's what Travis seems to be working at currently. Andre _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
In reply to this post by Travis Griggs-4
Thanks Travis. I appreciate your accounting of the history and state of the VW GUI.
I cut my teeth on the MVC framework way back in ST/V DOS. It was called model/pane/dispatcher but it was really the same thing. I was able to wrap my brain around that one easily enough. Of course the entire system was only about 150 classes and 1500 methods, so it was possible to know everything about that version of Smalltalk. My own efforts for Liberty BASIC 5 are restarting after a long hiatus and I'm porting from Widgetry. I've always hand coded all the Liberty BASIC GUIs. This was the first thing I needed to know how to do. Michael got me started at STS by showing how to script with a builder. On the face of it that's not too hard, but someone had to show me how because it wasn't written down. So that might be the first thing you can try writing about. I also had trouble figuring how to make menus and toolbars work but that was using the UI painter. Of course there was creating a scrolling graphics drawing part. And there were some other things that I couldn't seem work out without asking here. Some of these things aren't hard once you know how. ;-) Looking forward to reading all about it! Thanks again, -Carl Gundel Liberty BASIC for Windows - http://www.libertybasic.com Run BASIC, easy web programming - http://www.runbasic.com On Jul 26, 2011, at 7:25 PM, Travis Griggs <[hidden email]> wrote: > Great suggestion Carl. If nothing else ever comes of this, I want to at least explain some things and try to set some terms straight. And throw in some history. I'll probably bug Steve Dahl to read this and throw in his two cents if he cares to, since I have a huge respect for his historical insight to the process over the years. Hopefully it helps shed some light. I expect it may get longish. > > - Let's try to get a definition on what "Wrapper" is > > The VisualWorks GUI framework is often labeled "Wrapper" in whole. I do not think this is correct, and I think it further confuses the pitfalls. Before VisualWorks existed, there was ObjectWorks. ObjectWorks had a GUI/Widget framework that was based on the simple idea of a view tree (views with subviews, panes with sub panes, windows with sub windows, it's an old idea across many environments that we put different names on). It had two particular specializations beyond the everyday view tree implementation found in many languages and tool kits. > > It took an interesting approach to nesting in the view tree. Rather than doing as X or other environments had done and say "every thing is a window, and windows have child windows", it had refined class types for different tree element types. Tree elements that had multiple arbitrary children, were reified with CompositePart. Those that were terminal or leaf nodes, usually fell under the View type. And there was a special type for elements that held one distinguished child, for which the element provided a service for. These fell under the type of Wrapper. At the time, there was actually really only two particular types of Wrapper use cases. The first was that "layout" information was provided by a Wrapper object. So a view tree that had a parent and some arbitrary children, would include a Wrapper around each child to provide its layout facilities for the parent. The other was that it was used to put borders around widgets (BorderedWrappers were actually usually LayoutWra! pp! > ers as well). This was specialization one. > > The other was the use of the MVC pattern as prototyped by Trygve Reenskaug. It is interesting to note that what MVC means bounces all over the place as you move from language to language, even sometimes from Smalltalk to Smalltalk. The ObjectWorks one, for better or worse, really is about as close as you get to what Trygve originally did at Xerox PARC in 1979. This was specialization two. > > The above is what I think of as Wrapper. > > In ObjectWorks, we built user interfaces programmatically, with methods. You learned how the above worked, and made it do what you needed. It actually worked pretty well, for what it was. I recently did some support work for software I wrote in 1992 using this stuff. Large complex UIs doing engineering design work. It's actually still being used in production. > > -- Problems with Wrapper > > In retrospect, there were two general errors (IMO) that took place with what I've described as Wrapper. > > Error One was that so much excitement ensued over the MVC pattern and the change/update pattern that drove it, that *everything* was slowly beat into it. MVC demoes well. It solved/s the fun problem of shared state between widgets. You make a slider and an input field, and point them at the same model and "ta da! it's like magic! it just all works." But somewhere, the knowledge/wisdom/experience about how and where to apply the pattern died. It just became a way of life. Everything had to be expressed as an MVC triad. It meant lots of whiteboard diagrams, and asking yourself "now is that model, or is that view, or is that controller responsibility?" When you got the buckets right things worked out pretty well. But often, it's overkill too. And is more complicated to use than good ol' callback patterns. As widgets get composite and complex, the pattern doesn't scale that well. And many did not know how to say "ok, it's time to put that aside and use good ol' messages." The ! > ameworks obsession with the pattern certainly didn't help with this problem. > > The other was the use of Wrappers for layout. I'm not opposed to Wrappers in general. They're a general pattern that transcend widget trees. We create an object that "wraps" another object with additional state and behavior. But you don't generally want to split essential state of an object into delegatable parts with a linear wrapper pattern. Layout *IS* an essential state of where a widget lives in a view tree. It wasn't bad to split it into a separate object. It was bad to make it a Wrapper and abuse the view tree to retain a reference to it. An instance variable on VisualPart (the common superclass of all view tree elements) would have worked better and caused less confusion. The idea of placing one widget around another to provide additional decoration, say bordering, or scrolling, is not so bad. It was the use of it for layout that I think was the big error. It made the view tree instantly 2x the number of elements with 50% doing one job, and the 50% doing the other. > > Much of what I've been trying to mold in place is a departure from these ideas. I'm not trying to get rid of either of them, because a) backwards compatibility is important to customers b) they're not universally bad. The Panel work is an attempt to figure out how to do layout in the view tree, without using LayoutWrappers, and also have some more flexibility than we have today. And some of the new Announcement based widgets can use models, but aren't required to. > > -- What do we call the other stuff then? > > In the mid-late 90's, one of the biggest perceived threats to ParcPlace Smalltalk's existence, was the rapid hype around "4GLs". Delphi was one of the big ones I remember. VisualBasic of course. To compete in this arena, ParcPlace built a UI layer on top of the original Wrapper one. This is dramatically different. Where the above was a framework for programmers to program UIs, the new stuff was about visually laying stuff out, not really having to know much about what you were doing, and it all just working. ParcPlace wasn't alone in this, Digitalk tried it's own solution to the hype with "Parts". > > There are a couple of basic components that make what I would call "Builder." Builder was composed of a 3 basic things: ApplicationModels, UIBuilders, and Specs. The idea was that you could kind of throw some glue code in a bucket called your Application, and then other tools would be used to create various Spec objects. A UIBuilder would assemble the specs into a live incarnation of Wrapper derived objects wired to your Application. The hope was that as a programmer, the only realm you worked in was that of the ApplicationModel. The UIBuilder and Specs were meant to be a black box. > > Metaphorically, I find it instructional to think of the UIBuilder as a "compiler" and the Specs as "input files." > > Trevor Hopkins book was probably the most in depth exploration of how to approach the Builder framework. > > The "Builder" framework was a huge win for ParcPlace Smalltalk. The product was renamed as VisualWorks. And it allowed them to gain some rather large contracts (read, cash flow) because they could now compete in the 4GL space. > > -- Issues with "Builder" > > Over the years, I've drawn a couple of observations with Builder. Five main ones. > > One. The black box thing didn't work out so well. For a variety of reasons, it turned out that people basically had to get to know how Builders and Specs worked. The Builder wasn't written as a good example of reusable Smalltalk Objects. It wasn't supposed to have to. It was a black box compiler. When that didn't pan out, people began doing really interesting things with it. Lots of encapsulation violation. It's like what happens when people start doing interesting things in C programs to exploit some secret knowledge of how a particular compiler works. Except worse, because you could modify/extend/subclass the compiler in this case. > > Two. Applications hold Builders. The whole point of MVC was separation of model state and presentation. ApplicationModels didn't really follow that idea. And to accomplish it, they used what was left of the Builder after it had filled it's compiler role. This would be like writing a C program that referenced intermediate object files produced by the C compiler to figure out where data was and how to interact with it. It creates retention problems. It means the Builder has a schizophrenic life cycle (I'm a compiler! No, I'm really tripped out Dictionary!). > > Three. More Wrappers. The idea of using a wrapper pattern isn't bad. But when you build your design around the idea that for any of one set of objects to be real, they need another type of object to wrap them, in every single instance, it's not really a wrapper anymore. It's really just one glump of state that you've broken into two behaviors. We ended up with WidgetStateWrappers. Ideas which really should have just become APIs that all view tree elements responded to (enablement, visibility, etc), were implemented using another layer of Wrappers. These just made the view tree is unapproachable problem worse. > > Four. Wrapper was not kept up to date, but instead behavior was put in the Builder. For example, when the keyboard tab navigation stuff was added, it was not added to the original Wrapper framework. Instead, the implementors relied on Builder objects to get things set up correctly. Repeated choices like this, meant that it became more and more difficult to programmatically use core Wrapper objects, without at least reverse engineering how Builder was doing it. And Builder was a compiler, not meant as a human understandable set of Objects. Look at any of the UILookPolicy>>blahWidget:into: methods. They're all many lines long. Adding widgets to a view tree should never have been allowed to get this complex. Even if you reverse engineered what Builder was doing, you were left with a lot of work (reminds me of X11/Motif) to do to get standard things done. > > Five. Knowledge of how to use Wrapper programmatically faded. Over time, the amount of us that cut our teeth on ObjectWorks Wrapper naturally attritted. As docs were updated, various "how to" recipes were replaced with Builder equivalents. What this meant, was that you had a reduced amount of experience about when to put the Builder framework aside, and just use Wrapper directly. Wrapper is far easier (IMO) to manipulate programmatically than Builder. This leads to questions like Carls, where it's not clear that to do what he wants, he probably wants to avoid using Builders at all. Or how to take advantage of Builder when it makes sense and mix the two. > > The "skinned" widgets that we've done so far for the next VW release (whatever st11a ends up being called), attempt to fix some of these issues. They can be generated with Builder, because there's a huge investment in Specs that people have built up. But they don't use WidgetStateWrappers. They can be hooked to models (because that's what the Builder does), but don't have to be. And we write class side example methods for them that prove to ourselves that we can generate them relatively simply without needing builders and specs. They don't have controllers. > > We're also trying to make automatic some things, such as the KeyboardProcessor stuff that originally was bootstrapped from Builder. While the API is wider than I'd like on a widget basis, we were able to remove rafts of code in builder when this went in. Every blahWidget:into: was able to be trimmed down some. And you can programmatically assemble widgets without needing Builder and and the keyboard navigation will just work. > > -- Conclusion > My intent here was to paint a picture of what's happened and why we're where we're at. And hopefully to put some of the terms in a big picture of how the stuff fits together from a 10000 ft level. And own up to what we see as issues and want to fix. And indicate where we're trying to chip away at the issues. > > Carl, if you keep the questions coming, I'll be glad to try and make Blogs out of them. The small direct recipe questions (like your recent one) are the easiest to do such with. > > I don't mean to point any fingers at anyone with any of this. It is what it is. All programmers make mistakes, which are only obvious in hindsight. > > -- > Travis Griggs > Objologist > I multiply all time estimates by pi, to account for running around in circles. > > > > > _______________________________________________ > vwnc mailing list > [hidden email] > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
Free forum by Nabble | Edit this page |