Re: [Visualoberon-win32] Port of XCal to new VO
Status: Beta
Brought to you by:
tteuling
From: Stewart G. <sgr...@ip...> - 2001-06-06 05:25:07
|
Tim Teulings wrote: > > For your amusement, here a Model/View for displaying graphs. As an > > experiment, I ported some of my code from Blackbox. Its not finished, but > > you'll get the idea. > > I will do some comments to your code, so perhaps you might understand > some concepts better, but first of all: It is c00l (I should write it > in fat letters: *c00l*). It already looks very nice. Since it is ported > code (anotehr language another visualisation system). Was it difficult? This is the third incarnation of this widget. First was written in C++ in my "Pastel" GUI framework. Second was written in Component Pascal for Blackbox Component Framework. In porting this to VO, I split one module into a separate modules for View and Model. Translating to Oberon-2 was not too hard. Language issues: - Remove procedure attributes (eg. NEW). - Replace IN/OUT parameters with VAR - Convert INTEGER to LONGINT - Convert POINTER TO RECORD ... END to separate POINTER and RECORD declarations. - Implement MIN(a,b), MAX(a, b). These are built in procedures in Component Pascal. Framework issues: - Use RealMath in place of Math. Implement ceiling. - Convert Blackbox types to VO types. Color -> Color. Font -> Font. Frame -> DrawInfo. Most of the associated methods are different, although there seems to be equivalent functionality. - Draw and HandleMouseEvent had to be significantly redone, but it was not too hard. The greatest difference is that Blackbox mouse tracking is modal: once a mouse press is detected the program must enter a polling loop to read mouse motion events. > VO uses parmeterless Init methods. I like them better. So for > Graphodel one should initialise later on. The same for GraphView. But > that is just style... You do not need to hand an instance of > VO:Base:Diplay.Display to controls. There is only one instance and it > always exists (but may of coure not always valid). So you can access it > directly. Of couse you do not need to call Draw for a refresh you can > make your own optimized version for updates and model changes. This > will give you a cleaner and smoother refresh. > > There is also functionality for double buffering. So WireFrame for > that. You just allocate a bitmap of the specified size, draw into it > (the bitmap has a DrawInfo instance) and then copy it back to the > window. This will avoid flickerr even more. Both previous versions had this feature, but I haven't implemented it here yet. > The rest is OK fromt he first view (to much code to look into detail > yet). It seems like already deep into VO :-) IF you have any comments > regarding implementation details, nice or not that nice stuff, feel > free to speak. Here are a few initial comments that come to mind. 1) The semantics of Draw are rather complicated. If I understand it correctly, Draw may be called on a region that does not actually include the object. It may also be called when the object does not need to draw itself (visible=FALSE). The object needs to translate all coordinates to its own x,y position and ensure that it does not draw outside its own bounds. Under Blackbox a Frame is a rider on a Port; the Port encapsuates the actual OS device handle. The Restore procedure is passed a Frame which has a zero origin and automatically translates the coordinates of draw operations. It also has the clip region already installed, so that an object cannot draw outside its own bounds. AWT does something similar. This makes client code simpler and less error prone. I prefer this approach. I guess there may be a small performance penalty. VO allows user code to call Draw directly. I don't have a problem with this, and it makes some things easier to do. For example, if a user manipulates a Model, the view's Resync can call Draw so each view can be updated interactively. Under Blackbox, a view's HandleModelMsg can call Update but that does not redraw the object. It schedules an update which is done later by the framework. Because mouse tracking is modal, you can only directly update the view that is handling the mouse input. Separating Update and Restore does have the advantage that the redrawing of an object can be deferred in the situation where views are updated rapidly. 2) I expected to be able to PushFont(f : Font), but there seem to be two different types of font handle (Font and id). Do I have to store them both? 3) VO has DrawArc and FillArc. It has FillRectangle and FillPolygon. For symmetry, there should probably be DrawRectangle and DrawPolygon. It might also be nice to have DrawEllipse / FillEllipse, although I notice that DrawArc calls the GDI Ellipse code when it gets 0..360*64. 4) It looks like Prefs are used for setting global parameters that control the way a class of objects is displayed. It would be nice if this could also be used to control local (per-object) preferences. For example, a pop-up menu for an object could use a Prefs-style dialog to control the look of that particular object. The previous version of my GraphView object used Blackbox Properties objects to do this. Here, the framework controls properties of via Properties.EmitMsg and Properties.CollectMsg control messages. Blackbox uses meta-programming and a mapping file to look up a dialog for the dynamic type of the emitted property object. It looks like something similar could be done with Prefs. A Prefs object already has an associated dialog, so this part is probably neater. If there were a method for emitting/collecting Prefs from an object this could be used as the basis of a nice properties dialog mechanism. > X11 uses INTEGER for XPoint (you know that point stuff in > VO:Base:Display) so I had to add six SHORT casts for Unix. But we have > to fix that nevertheless (also open for solutions/implementations for > that part). Since VO uses LONGINT coordinates, it would make sense if PointDesc.x, y were also LONGINT. This means that point arrays may have to be translated for some implementations (X11?). - Stewart |