Hello, I have a problem with Cairo and Expose events. I am trying to make a custom widget. I need a canvas ta draw on. If there's a different way to achieve it, please, tell me. First, the example in http://www.go-mono.com/docs/monodoc.ashx?link=T%3aCairo.Context seems not to work, when I hide and un-hide the app it works correctly, but move a smaller window over it and it doesn't re-draw itself. Is this a problem in my workstation, does anybody else see this same problem? Based on that example and on a Python implementation of the same thing I wrote the code (at the bottom) that draws a pentagram. This has a deeper problem. It redraws itself incorrectly. It seems like when. It seems like if the part exposed gets re-drawn, but the coordinate system is moved from 0,0 to x,y where x,y is where the exposing starts. It's hard to explain, I'll attach a screenshot. Any help is appreciated. -- Pupeno <[EMAIL PROTECTED]> (http://pupeno.com)
PS: The code:
namespace ScoreReadingTrainer {
public enum Clef {
G, F, C3, C4
}
public class Score: Gtk.DrawingArea {
// Margin, in %, on the left of the score (right has no margin).
readonly private byte margin = 2;
readonly private byte steps = 24;
private Clef clef;
public Score() {
this.clef = Clef.G;
this.ExposeEvent += Draw;
}
void Draw(object o, Gtk.ExposeEventArgs e) {
Score score = o as Score;
if(score != null) { // Either it is a Score or we are
in problems.
Cairo.Context context =
Gdk.Context.CreateDrawable(score.GdkWindow);
this.Draw(context, e.Event.Area.X,
e.Event.Area.Y, e.Event.Area.Width,
e.Event.Area.Height);
}
}
void Draw(Cairo.Context context, int x, int y, int width, int
height) {
context.Rectangle(x, y, width, height);
context.Clip();
this.Draw(context);
}
void Draw(Cairo.Context context) {
int width = this.Allocation.Width;
int height = this.Allocation.Height;
int realMargin = this.margin * width / 100;
Console.WriteLine("{0}: width={1}, height={2}",
System.DateTime.Now, width,
height);
// Paint a white background.
context.Save();
context.Color = new Cairo.Color(1,1,1);
context.Paint();
context.Restore();
// Draw the pentagram.
context.Save();
context.Color = new Cairo.Color(0, 0, 0); // TODO:
maybe use 0.2, 0.2, 0.2.
context.LineWidth = height / 200; // Make a
relative line width so
we don't end up with a lines too fat or too thin.
if(context.LineWidth < 1) { // Ensure
that lines
context.LineWidth = 1; // are
at least one pixel wide.
}
for(int line = -2; line <= 2; line++) {// line in
self.lines:
double y = this.stepToPixels(line);
if(context.LineWidth == 1) { //
Ensure that if lines are one
pixel wide
y += 0.5;
// they will be one full pixel and
not two half pixels: http://cairographics.org/FAQ
}
Console.WriteLine("{0}: Line {1} at {2} of
width {3}.",
System.DateTime.Now, line, y, context.LineWidth);
context.MoveTo(realMargin, y);
context.LineTo(width, y);
context.Stroke();
}
context.Restore();
}
int stepToPixels(int step) {
// """ Having the step number, return the pixel. A step
is the minimum
possible separations between notes, vertically."""
int height = this.Allocation.Height;
int middle = height / 2;
int stepDistance = height / this.steps;
return middle - step * stepDistance;
}
}
}
namespace Gdk {
public class Context {
//Use [DllImport("libgdk-win32-2.0-0.dll")] for Win32
[DllImport("libgdk-x11-2.0.so")]
internal static extern IntPtr
gdk_x11_drawable_get_xdisplay(IntPtr raw);
[DllImport("libgdk-x11-2.0.so")]
internal static extern IntPtr
gdk_x11_drawable_get_xid(IntPtr raw);
[DllImport("libgdk-x11-2.0.so")]
internal static extern IntPtr
gdk_drawable_get_visual(IntPtr raw);
[DllImport("libgdk-x11-2.0.so")]
internal static extern IntPtr
gdk_x11_visual_get_xvisual(IntPtr raw);
public static Cairo.Context CreateDrawable(Gdk.Drawable
drawable) {
IntPtr x_drawable = IntPtr.Zero;
int x_off = 0, y_off = 0;
int x, y, w, h, d;
((Gdk.Window)drawable).GetGeometry(out x, out y, out w,
out h, out d);
if(drawable is Gdk.Window) {
((Gdk.Window)
drawable).GetInternalPaintInfo(out drawable, out x_off, out
y_off);
}
x_drawable = drawable.Handle;
IntPtr visual = gdk_drawable_get_visual(x_drawable);
IntPtr Xdisplay =
gdk_x11_drawable_get_xdisplay(x_drawable);
IntPtr Xvisual = gdk_x11_visual_get_xvisual(visual);
IntPtr Xdrawable = gdk_x11_drawable_get_xid(x_drawable);
Cairo.XlibSurface s = new Cairo.XlibSurface(Xdisplay,
Xdrawable, Xvisual,
w, h);
Cairo.Context g = new Cairo.Context(s);
if(drawable is Gdk.Window){
g.Translate(-(double)x_off,-(double)y_off);
}
return g;
}
}
}
correct.png
Description: PNG image
scrambled.png
Description: PNG image
pgpnRZrI5XZKi.pgp
Description: PGP signature
_______________________________________________ Mono-list maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-list
