Re: Volunteer for developement of presentation tools




On Sun, 17 Jan 1999, Miguel de Icaza wrote:
> 
> Could you include a status report on EzPaint and a TODO list?
> 

Okie, it's in CVS. I've attached it too, to facilitate reading/discussion.
As you can see there's really a lot to do. I have some design notes in
there too, and some notes about how PowerPoint works.

The summary is that right now I've implemented decent base classes for the
new framework, and I have one prototype concrete class (a rectangle
object). Some things don't work but the basics are there. There are lots
of additional features to add, and all the actual objects need to be
rewritten. The old objects are still in CVS and some of them have a lot of
code to copy (for example all the wacky math in the arrow object will
carry over to the new arrow object, and the rubberband object basically
just need renaming). 

The 'ezpaint' test program does almost nothing right now, I deleted most
of it to start over on the library. All you can do is test the rectangle
object, none of the buttons do anything. 

Havoc


If you change existing stuff, please do a ChangeLog entry so we know
what's going on, even though there are no ChangeLog entries yet. Also,
it's nice to add a demo of your feature to the ezpaint.c test program.

Note: in the src directory, the gnome-canvas-handle* files are
obsolete and are just there so I can recycle some code; the ez* files
are the new version of the library.

Library Overview
================

EZPaint has or will have two major components:

 - A set of editable canvas items designed to work together; essentially
   these are widgets for the canvas. They emit signals when the user 
   manipulates them, and you app can receive the signals, etc.

 - Convenient Gtk stuff to go with the canvas items; for example, pixmaps 
   for different drawing tools, line style selector, etc.

The Gtk stuff is/will be pretty self-explanatory to anyone who's
already hacking libezpaint internals, so I won't talk about that.

The editable canvas items:

An initial warning - EZPaint is implemented in terms of the Canvas,
but is different enough from passive Canvas rendering that we're
overriding much of the standard CanvasItem behavior. You should try to
use only EZPaint functions and features to manipulate the EZPaint
objects.

For example, GnomeCanvasGroup was sort of in the way, and its behavior
is often not what we want. But it isn't really practical to not use
it. So the EZPaste and EZItem objects are GnomeCanvasGroup subclasses,
but they do *not* necessarily behave like a GnomeCanvasGroup, and you
should not try to use the GnomeCanvasGroup aspect directly. 

Anyway, keep your eyes open for that in the source.

Here's an overview of the classes involved.

EZPaste is a "pasteboard" item. It is a special GnomeCanvasGroup. It
optionally draws a background/grid lines (it can also be invisible).
To use EZPaint, you must create at least one pasteboard item.

EZItem is an editable canvas item.

EZContainer is an EZItem that can contain other EZItems. For example,
if you "group" items, there will be an EZGroup object to hold
them. Also, just like PowerPoint, you'll be able to put text inside a
rectangle or arrow or whatever.

An EZItem can be a toplevel item; these are treated sort of specially
since they have no parent. If an EZItem is not toplevel, it has to be
placed inside a container. Much like Gtk, when items are initially
created they are "floating"; you either have to explicitly make them
toplevel, or add them to a container. (Since items can't be unparented
from GnomeCanvasGroup, floating items are hidden children of an
EZPaste.)

EZItem is a subclass of GnomeCanvasGroup to simplify things like
rectangles with grab handles, or items made up of several canvas
primitives. Also, children of EZContainer are added to the EZContainer
group.

We bypass the canvas event system, because we want to do it
backward. The correct EZPaint behavior is that the container gets the
event first, then passes it to the child if it doesn't want it, and so
on. Think about grouped items in Excel etc. and "opening" or "closing"
them to see why. The canvas does it the other way around, where the
children get the event, then parents, etc. So: whenever an EZItem
subclass gets an event, it ignores it and just passes it up to the
EZPaste, and EZPaste handles it the way we want.

EZHandle is a helper class used in EZItem implementations.

That's the overview.

Administrivia TODO
================

+ do an ezpaint-config and ezpaint.m4

+ Install the pixmaps, this is a simple thing in src/Makefile.am

+ Documentation (a bit premature right now though)

Library-wide TODO
================

+ Consistently use item coordinates instead of world coordinates, I'm
  in the process of fixing this

+ Finish up the container workings: scaling is a part of this.

+ Implement constrained movement/resizing; basically children of certain
  (but not all) containers should not be able to leave their parents
  area.

+ Fix EZPaste bounds; if EZPaste has a background/grid, then it children 
  should be contrained as mentioned above; if not, then EZPaste bounds
  need to be reported in the GnomeCanvasGroup way instead of as a 
  rectangle the way they are now.

+ Implement snapping to grid and snapping with an arbitrary function. 
  There are maybe some complicated issues here, because different
  EZItem subclasses will snap in different ways. However for now we can
  just do it the way the old libezpaint did, a function that returns the 
  closest snapped point to the actual mouse position.

+ Implement contrain-ratio and constrain-to-regular-shape features

+ Resolve "restore pointer" problem; if we set the pointer, how do we restore 
  Gnumeric's cross pointer (for example)

+ Fix incredible slowness of second update of EZPaste when the grid is on. 
  (to see this, in ezpaint.c uncomment the grid-related arguments where 
  the EZPaste is created, then run ezpaint and zoom one notch.)

+ Complex items like text and polygon will need two editing
  modes. "closed" just has 8 handles, allowing resize;
  "open" allows you to change the geometry of the polygon, or the text.

+ Object rotation; libart_lgpl will be handy here.

+ Drop shadow for all objects; probably this should be an option for the static
  canvas objects, then used in ezpaint. Excel has about a million different
  kinds of drop shadow, and the drop shadow behaves properly if the object
  is rotated.

+ Implement stuff from PowerPoint manual, see below.

+ Add pixmaps. We need toolbar pixmaps for all objects in both filled
  and unfilled form. We need pixmaps for "line styles", to put in the 
  "line style" dialog; this should include dashed lines, various line 
  weights, maybe double or triple lines. Dashing and weight are ideally 
  separate, i.e. any dash interval can go with any weight. Also need 
  pixmaps for "no arrow," "arrow on left," "arrow on right," and "arrow 
  on both ends," these are options for the line item. If we have fill 
  patterns we need a pixmap for each of those. We also need a "drawing mode" 
  pixmap, in Excel this is a circle,  square, and triangle of three different 
  colors. 
  (This item is partially done; we have some toolbar pixmaps.)

+ Can even make widgets using these pixmaps - line style selector, 
  fill pattern selector, etc.

+ Figure out how to XOR with libart_lgpl, or add this feature to it, so 
  we can do the handles/rubberband

+ Port GnomeCanvasRubberband thingy over to EZ namespace and antialiased 
  canvas

+ Need to implement object creation in a nice way (EZItem needs a class
  function which takes a user's click on the canvas and starts the initial 
  item-creation drag.) In the old gnome-canvas-handled stuff, it's 
  gnome_canvas_handled_create().

+ Consider whether to provide an Gdk mode of operation, right 
  now I've only bothered to implement items for the AA canvas. Adding 
  Gdk is pretty easy, unless we use object transforms (for example, 
  to permit object rotation). The advantage of Gdk is that AA seems 
  a little bit sluggish sometimes for interactive use.

Missing/Incomplete objects
================

Basically all of them right now, there's only an EZRect prototype.

+ EZRect needs to emit signals for color, outline, etc. changed 
  and export ways to change them. Don't want to require directly
  accessing the GnomeCanvasRect implementation.

+ Ellipse, basically a cut-and-paste of EZRect

+ Line

+ Arrow

+ Text object; can be hacked with GtkEntry for now, a la IconList, but 
  ultimately IconList and this should share some sort of engine. Better yet
  we fix X fonts with t1lib and Raph's stuff. The other main problem with 
  the text object is scaling. 

+ Arc; a 90 degree section of an ellipse. Should have two handles, one
  on either end of the arc. Also Filled Arc.

+ Polygon/Multiline: Just a bunch of connected lines; if the end of
  the last line nears the beginning of the first line, it should snap 
  and allow you to close the polygon.

+ Freehand: This is pretty much just multiline, but instead of manually 
  clicking for each line segment, you get a new segment on each motion_notify.

+ Bezier: Excel and PowerPoint don't have this, probably because it's kind of 
  complicated to learn. But we could have it anyway, as long as the simpler Arc
  is also available.

+ Image: User can specify a filename to load.

+ Object groups, scaling for groups.

+ High-level objects, which could be implemented in terms of simpler ones:
  Trapezoid, diamond, triangle, horizontally/vertically constrained arrows,
  star, rectangle with rounded corners, cartoon speech bubble, hexagon. These
  are important for Achtung, PowerPoint has them.

Notes on UI, from PowerPoint 4 manual
=====================================

+ There is a distinction between container-like AutoShapes, and arc/line. The 
  AutoShapes always have 8 handles like the HandleBox; these let you scale 
  (optionally with the aspect ratio constrained). You can "open" the item to 
  change its shape if it's a polygon or whatever. To open an item, you double 
  click it. arc/line just have a handle on each end. 

+ When editing text inside an object (i.e. the object has keyboard focus), 
  the object handles are connected by fuzzy lines.

+ To require a perfect circle, square, equilateral polygon, etc., you hold 
  down shift while dragging.

+ When you drag to create a shape, then release the button, the shape 
  automatically has the typing focus so you can add text to it.

+ To make the start of the drag the *center* of the object, instead of the 
  corner, hold down control as you begin the initial click

+ The above control-to-center trick also works for Arc and Line

+ Hold *both* shift and control before starting an Arc drag, and the initial 
  mouse click represents the center of the circle this arc is a segment of.
  Holding just control, the initial click is the center of the arc itself.

+ control-click on a polygon adds or deletes vertices (depending on whether 
  there's one under the pointer - handle should emit a "remove me" signal 
  if it gets control-click, polygon should add a vertex if it gets the event 
  and connect to the handle signal for removing.


Initial Design Notes (stuff I wrote before writing the EZ* classes,
may be useful to understand what I was thinking) 
==================

The below items are all sort of dated. What I want to do now is
basically start over (hey, you have to do that at least once per
programming project, right?). I want to do things in a more
intelligent OO way; the current way is sort of a bunch of stupid hacks
that evolved over time. Here are some initial thoughts.

Gtk+ will be used as a model; basically I'll be implementing a
"toolkit" for interactive canvas items, instead of a toolkit for
interactive widgets.

At the root of the hierarchy, we'll have EZItem; EZItem will be
directly descended from GnomeCanvasItem.

Under EZItem we will have EZContainer->EZBin, a container object. Most
items will be containers; for example, a rectangle can have text in
it. Containers just draw their children on top of themselves and
resize the children when they are resized. Also, children are confined
within the bounds of the container.

There will probably be an EZCanvas which is a toplevel container
holding multiple children. Its features will be set_background, etc.,
and maybe show/hide grid lines. Like other containers, children are
confined to the EZCanvas, and must stay above it.

Within each container, only the container or a single child can be
editable at any one time. Since all items are in a toplevel EZCanvas
container, only a single child is being edited at any time. By
"edited" we mean "responding directly to mouse events."

Probably EZCanvas will keep a pointer to the item currently being edited.

Grouping: EZGroup will be another container type. It works naturally 
with the container system, since we want to either be editing the whole
group, or a single sub-item. Scaling and confinement to group bounds 
happens naturally in the same way it does for other containers.

Selection: We want to allow selection and deselection of EZItems. To
this end, they will all need to be able to draw themselves in a
"selected" state; this should be distinct from the "editing" state.
Perhaps we can provide an EZSelection object, which is not a canvas
item, just an object that monitors select, unselect, and delete events
and keeps up with the currently selected items.

Handles: Items implement their own handles as part of the "editable"
state. Therefore only one object has handles at a time. Handles are
invisible to library user.

Actions: We need a way to map from clicks and drags and keys to
actions. Containers will play an important role in deciding which item
finally handles each event; we will probably need to do something like
GnomeCanvas's pick_current_item code. The current editable item should
get events first and consider using them; if an item is not editable
or does not want the event, the event should be passed up to the
container. If an event makes it all the way to EZCanvas, EZCanvas will
do something smart with it. 

As events trickle up, we'll want to carry info on which item last saw
the event, and which item was actually clicked. The last-seen-by
pointer is so containers always get a pointer to one of their children
and can select it or make it editable. That is, each container will
get events marked with a pointer to one of their children or NULL if
the event was not on a child. The clicked-item pointer reflects the
object the canvas sent the event to; this may be useful in some cases.

We will probably provide some centralized code to map from events to 
semantics like "select," "raise," "lower," so that UI can be changed 
later if we want.

Items must support scaling, and constrained ratio scaling. This will
be through class functions, so groups can scale their children.

  ===== end new thoughts


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]