Hi,
I am new to Dolphin and struggling with a drawing application (later perhaps a simplified "kind of" HotDraw package comes out). I just tried to paint (fill) regions as follows ): shell := Shell show. canvas := shell view canvas. canvas pen: (Pen color: Color yellow). brush := Brush color: Color gray. canvas backcolor: Color blue. canvas erase. canvas fillRectangle: (Rectangle center: 25@25 extent: 50@50) brush: (Brush color: Color red). canvas ellipse: (Rectangle origin: 100@100 extent: 50@30). myellipse:= canvas ellipse: (Rectangle origin: 100@100 extent: 50@30). myregion1:= Region rectangle: (Rectangle origin: 100@100 extent: 50@30). myregion2 := myregion1 intersection: myellipse. myregion3 := myregion1 exclude: myellipse. canvas fillRegion: myregion1 brush: (Brush color: Color gray). canvas paintRegion: myregion1. And it works fine. But if I try with maregion2, or myregion3 in the last 2 lines, (even after re-executing canvas erase.) I do not see anything. The display, or inspect give back true, so something not to bad happened... but what? Can you give some hints, how can I create more complicated graphic surfaces with region operations, like intersection: or exclude:, which I can then color? Many thanks, Janos |
Janos Kazsoki wrote:
> myellipse:= canvas ellipse: (Rectangle origin: 100@100 extent: 50@30). This is your first problem, Canvas>>ellipse: draws an ellipse on the canvas, and answers true to say that it has done so. That means that value of 'myellipse' is now true, not an elliptical region. I have no idea why using 'true' instead of a Region doesn't cause errors in the rest of your example -- I would have expected lots of walkbacks, but haven't investigated why they don't appear (something to do with Window's typeless 'handles' I suppose). So you need to create an instance of Region that corresponds to an ellipse. The second problem is that Dolphin doesn't come as standard with a full range of Region-creation methods, so you will need to add one (and possibly more later). Start by looking at class Region (on the class-side). You'll see that it has a #rectangle: method which creates a rectangular Region using the GDI function CreateRectRgnIndirect(). As it happens, GDI contains a similar function, CreateEllipticRgnIndirect(), which takes exactly the same parameters but creates an ellipse, so it should be easy to add a call to that. Create a new instance-creation method on Region =================== ellipse: aRectangle "Answer an elliptical region defined by aRectangle" ^self fromOwnedHandle: (GDILibrary default createEllipticRgnIndirect: aRectangle asParameter) =================== which is just the code for #rectangle with small mods to call a different function. Then you'll have to ensure that the GDILibrary class does actually define the method #createEllipticRgnIndirect:. In this case it turns out not to (sometimes you'll find that the lowest-level wrapper functons do exist even if they are not used by higher-level classes elsewhere in the image). So you need to add the following method to the instance-side of GDILibrary. =================== createEllipticRgnIndirect: aRECT "The CreateRectRgnIndirect function creates an elliptcal region. HRGN CreateEllipticRgnIndirect( CONST RECT *lprc // pointer to the rectangle );" <stdcall: handle CreateEllipticRgnIndirect RECT* > ^self invalidCall =================== which is, again, just the same code as #createRectRgnIndirect: with small modifications. With those two methods added, you should be able to say: myellipse:= Region ellipse: (Rectangle origin: 100@100 extent: 50@30). and the rest of your example should work. Googling for "CreateEllipticRgnIndirect" will quickly find the Microsoft documentation (on MSDN) for region functions, and that should help you find any other region-creation functions that you need for the rest of your project. BTW, if you are doing 2d work in Dolphin, then you may also want to look at the Gdiplus library, which I think is found at: http://www.mindspring.com/~lsumberg/Dolphin/Gdiplus/ It is a wrapper for the more advanced GDI+ library from MS. -- chris |
Chris,
many thanks for the excellent explanation. Now I can dive more deeply into the beautiful world of graphics, using Dolphin Smalltalk. I planned for my first simple experiences to use GDI, later extend it to GDI+ for more advanced graphical operations, and 3D. I got a Server Error, when sent the e-mail, so I attach the original, so other people also know, about what is this: "Hi, I am new to Dolphin Smalltalk, creating an application, which draws, and planning to create a base graphical package (later perhaps a "simplified version of HotDraw" package.). While experimenting with canvas methods, some Region operations do not work. If you try: shell := Shell show. canvas := shell view canvas. canvas pen: (Pen color: Color yellow). brush := Brush color: Color gray. canvas backcolor: Color blue. canvas erase. canvas fillRectangle: (Rectangle center: 25@25 extent: 50@50) brush: (Brush color: Color red). "canvas ellipse: (Rectangle origin: 100@100 extent: 30@50)." myellipse:= canvas ellipse: (Rectangle origin: 100@100 extent: 30@50). myregion1:= Region rectangle: (Rectangle origin: 100@100 extent: 50@30). myregion2 := myregion1 intersection: myellipse. myregion3 := myregion1 exclude: myellipse. canvas fillRegion: myregion1 brush: (Brush color: Color gray). canvas paintRegion: myregion1 It works fine. But the last 2 lines do not have any effect, if you use it with myregion2 or myregion3. SOmething not to bad happens, because displaying or inspecting them (with myregion2 and 3) shows true, only you do not see any effects, even if you execute them directly after a canvas erase. What I would wait is to color an area, which is the result of the logical (or mathematically set) operations of intersection and exclude. Many thanks, Janos" Thanks again Chris for the excellent explanation, Janos |
In reply to this post by Chris Uppal-3
Chris,
yes, the GDIPlus library contains all graphic operations and more... And te region operations (among others) are nearly "elementary" onesthere. Thank you, Janos |
In reply to this post by Chris Uppal-3
Chris,
many thanks for the excellent diagnose and explanation! It works now fine. Unfortunately the Google Beta swallowed my first e-mail (but you have got it somehow) and some of my answers as well. After installing the GDIPlus package, I am impressed. Now the follwoing questions arise: 1.) MSDN suggests to use GDI+ for the new application. Does this mean we have to forget GDI? 2.) Can you mix GDI and GDIplus drawings (I mean somehow on the same canvas)? Or this does not make sense at all... Thank you, Janos |
> 1.) MSDN suggests to use GDI+ for the new application. Does this mean
> we have to forget GDI? Not at all. Also, I'd take what MS says with a grain or two of salt. > 2.) Can you mix GDI and GDIplus drawings (I mean somehow on the same > canvas)? Or this does not make sense at all... You can mix the two, though if you can stay within GDI, I'd suggest you do so, since the Dolphin framework makes that easier. However, it's quite easy to mix them, and I've done that for some things that can be done with GDI+ which can't be done with GDI (or are just a lot easier to do with GDI+). In any view (e.g., in an #onPaintRequired: method), you can get a Gdiplus graphics object with graphics := GdiplusGraphics fromCanvas: self canvas and then draw stuff on the graphics object. -- Louis |
In reply to this post by Janos Kazsoki
Janos,
One recommendation is to write code that draws on a canvas given to it. Whether that goes in "the object itself" or in a separate rendering object specified by or for it is something you can decide on a per project basis. By writing code that draws on any canvas, you can start with a display-compatible bitmap. Your use of a view's canvas is (almost?) as safe, but the next step is to create your own view, and there, a walkback will be more trouble. I start with a bitmap, and initially make no arrangement to view it. When the code finally runs, then I display it in an ImagePresenter to see what else is wrong :) By the time I create a custom view, if it is even necessary, I have stable code that is unlikely to create walkbacks during presenter opening. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
Free forum by Nabble | Edit this page |