Hey Eric, Le 20 juil. 09 à 21:12, Eric Wasylishen a écrit :
> Hey Quentin, > I was playing with EUI last week and started to write a basic > paintbrush tool - here's the current (very early and hacky) code. It > only works in OS X for now because I'm using NSGradient. Very cool :-) I played a bit with it and it works pretty well. Having NSGradient on GNUstep would be nice, but it looks like a quite substantial task to implement it. > I made a ETShape subclass called ETDrawingStrokeShape which stores the > path of the drawing stroke, and currently the tablet pressure at each > point in the path. I'm planning to extend it to store more info, such > as timestamp of each event and parameters for fancy tablets (angle, > rotation, etc.). As we discussed it on the silc channel, I would make the tool more dumb, by moving the logic related ETDrawingStrokeShape into an ETActionHandler category. Something like: - (BOOL) canBrushStrokeOnItem: - (id) beginBrushStrokeAtPoint: onItem: withTouch: color: // returns a brush stroke object (an ETDrawingStrokeShape in the default implementation) - (void) continueBrushStroke: atPoint: ontItem: withTouch: color: - (void) endBrushStroke: onItem: This way both are decoupled and we can more easily handle the persistency with CoreObject. To provide stylus-related infos, you can declare an ETTouchAction protocol with methods like -pressure, -tilt etc. and makes ETEvent adopts it (see ETKeyInputAction as an example). Then in the action handler, you can receive the event as a touch action without exposing the event itself, and without declaring too many parameters or having to add more later. The idea is that you pass the action expressed as several parameters usually, but you can reify it (partially or not) when that makes sense. Action handlers should never receive events in parameter, because a tool might later be extend to support events from another input device, or even combine events from multiple input devices into a single action. However some EUI tools such as ETSelectTool currently don't implement this separation very cleanly and needs to be improved. > ETDrawingStrokeShape then has another stlye, as an ivar, which it > delegates the actual drawing to. I wrote two styles which work here, > ETBrushStyle, a bitmap brush, and ETPenStyle, a vector brush. Sounds excellent. You might want to introduce an ETBrushDab class which stores all the infos you need at each point in the path. Each instance would be stored in an array and this would replace the pressure array you currently have in ETDrawingStrokePath. ETBrushDab can have a factory method, which makes easy to create a dab in -continueBrushStroke:, like - (ETBrushDab *) dabWithTouch: (ETTouchAction *)aTouch Later ETBrushDab could also be used to cache the brush shape that gets stamped at each point on the path. e.g. with a natural painting application such as Painter, the brush shape gets potentially deformed with each dab and this needs to be computed before stamping it on the brush stroke path. > I'm not too comfortable with the graphics coordinates yet, so I may be > doing many things wrong. The code looks correct at first sight. I'll check what's going with -convertRect:toItem: vs - convertRect:fromItem:. I don't use -convertRect:toItem: anywhere and I wrote no tests for it unlike -convertRect:fromItem:. > One bug is that if you start drawing on top of an existing layout item > (rather than the window background) the drawing is offset vertically > by 10 or 15 pixels. I'll take a look at that. There are still some bugs in the event handling that remain to be fixed. > Anyway, it was exciting to get this working very quickly. :) :-) Cheers, Quentin. _______________________________________________ Etoile-dev mailing list Etoile-dev@gna.org https://mail.gna.org/listinfo/etoile-dev