Page Index Toggle Pages: [1] 2  Send TopicPrint
Hot Topic (More than 10 Replies) Custom cell drawing (Read 8186 times)
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Custom cell drawing
Aug 31st, 2009 at 9:33am
Print Post  
Hello,

I need to custom draw the cells of my table nodes.
The problem I encounter is related (I think) with the Diagram.PageUnit which is set to the default millimeter in my app. And I want in my custom draw cell event handler to draw a line by 1 pixel width:

Code
Select All
e.Graphics.DrawLine(new Pen(e.Table.Pen.Color),
                   new PointF(e.Bounds.Left, e.Bounds.Bottom), new PointF(e.Bounds.Right, e.Bounds.Bottom));
 



But the drawn line appears to be 3 pixels wide. That's I abelive because the diagram has its PageUnit set to millimeter. A I can't change the diagram PageUnit (all distances are already set in code using millimeters), how can I draw 1 pixel wide lines here?

I've tried the following but the the lines were not properly positioned inside the table:

Code
Select All
                e.Graphics.PageUnit = GraphicsUnit.Pixel;

                float DpmX = e.Graphics.DpiX / MM_PER_INCH;
                float DpmY = e.Graphics.DpiY / MM_PER_INCH;

                float boundsLeftDots = e.Bounds.Left * DpmX;
                float boundsRightDots = e.Bounds.Right * DpmX;
                float boundsBottomDots = e.Bounds.Bottom * DpmY;

                e.Graphics.DrawLine(new Pen(e.Table.Pen.Color),
                    new PointF(boundsLeftDots, boundsBottomDots - 1), new PointF(boundsRightDots, boundsBottomDots - 1));
                e.Graphics.DrawLine(new Pen(Color.White),
                    new PointF(boundsLeftDots, boundsBottomDots), new PointF(boundsRightDots, boundsBottomDots));

                e.Graphics.PageUnit = GraphicsUnit.Millimeter;
 



where
Code
Select All
private const float MM_PER_INCH = 25.4F;
 



So, I've tried to convert all the dimensions from MM to pixels, draw the lines (I wand a shadow like border cell) and the return to the default PageUnit.
But it doesn't seems to work like this.

So, how can I draw in "pixel" mode in the custom draw event handler even the diagram's PageUnit is set to Millimeter?

Thanks,
Bogdan
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Custom cell drawing
Reply #1 - Aug 31st, 2009 at 10:10am
Print Post  
Hi,

If you set the pen.Width to 0, the control will interpret this as one pixel -wide pen, regardless of the current measure unit.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Re: Custom cell drawing
Reply #2 - Aug 31st, 2009 at 9:23pm
Print Post  
Hi Stoyan,

I've set the pen width to 0, the line width is smaller indeed but there are still some artifacts, the lines are sometimes 1 pixel width, sometime 2 pixels and the color is not preserved between all lines drawn with the same color. And there is a strange space between the 2 lines that should consist the cell custom border.

Code
Select All
 void Diagram_DrawCell(object sender, DrawCellEventArgs e)
        {
            Pen pen1 = new Pen(Color.Red, 0);
            Pen pen2 = new Pen(Color.Green, 0);

            e.Graphics.DrawLine(pen1,
                new PointF(e.Bounds.Left, e.Bounds.Bottom - 1), new PointF(e.Bounds.Right, e.Bounds.Bottom - 1));

            e.Graphics.DrawLine(pen2,
                new PointF(e.Bounds.Left, e.Bounds.Bottom), new PointF(e.Bounds.Right, e.Bounds.Bottom));

           }
 




Red and Green colors are test colors (are more visible), they should be a yellow and a white between it to show like a shadow.

So, the Red lines are not all 1 pixel width and also they are not all (255,0,0) (some xor between pixels?). The same issue appears to the green lines. And, more of that, the 2 lines do not appear one above the other (as the code suggest) but there are 2-3 pixels empty space between them.

Is there a workaround for this issue too? We really do want to paint a custom border that consist of 2 1px width lines.

Thanks,
Bogdan
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Custom cell drawing
Reply #3 - Sep 1st, 2009 at 7:24am
Print Post  
Quote:
I've set the pen width to 0, the line width is smaller indeed  but there are still some artifacts, the lines are sometimes 1 pixel width, sometime 2 pixels and the color is not preserved between all lines drawn with the same color.


This could happen because of antialiasing. Try drawing the lines with Graphics.SmoothingMode set to None.

Quote:
And, more of that, the 2 lines do not appear one above the other (as the code suggest) but there are 2-3 pixels empty space between them.


Bounds.Bottom - 1 is still at one millimeter distance from Bounds.Bottom. Perhaps you could call DocToClient to find the pixel coordinates of the cell, save the current graphics transform and call ResetTransform, and then draw in pixel coordinates.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Re: Custom cell drawing
Reply #4 - Sep 1st, 2009 at 9:29am
Print Post  
Hi Stoyan,

Thanks, if I set the graphics object's SmoothingMode to none, the first problem dissappears, the lines are correctly drawn.

Bu it seems I can't handle the second one (painting in pixels coordinate, instead of millimeters)

here is my code:

[code]
void Diagram_DrawCell(object sender, DrawCellEventArgs e)
{
SmoothingMode smoothingMode = e.Graphics.SmoothingMode;
e.Graphics.SmoothingMode = SmoothingMode.None;

Matrix t = e.Graphics.Transform;
e.Graphics.ResetTransform();

System.Drawing.Pen pen1 = (new MindFusion.Drawing.Pen(Color.Red, 0)).CreateGdiPen();
System.Drawing.Pen pen2 = (new MindFusion.Drawing.Pen(Color.Green, 0)).CreateGdiPen();

Point p1 = this.UnitToPixel(new PointF(e.Bounds.Left, e.Bounds.Bottom-1));
Point p2 = this.UnitToPixel(new PointF(e.Bounds.Right, e.Bounds.Bottom-1));

Point p3 = new Point(p1.X, p1.Y + 1);
Point p4 = new Point(p2.X, p2.Y + 1);

e.Graphics.DrawLine(pen1, p1, p2);
e.Graphics.DrawLine(pen2, p3, p4);

e.Graphics.Transform = t;

e.Graphics.SmoothingMode = smoothingMode;
}
[/code]

So, I've saved the Matrix, called the ResetTransform, then paint the two lines. But something is still wrong as I can't see the lines, or I see them incorrectly positioned.

Can you please detail a little bit how to properly reset the matrix in order to draw in pixel coordinates?

Thanks,
Bogdan

PS. I placed the [b]e.Graphics.ResetTransform();[/b] line before as well as after the [b]UnitToPixel[/b] methods call but same result.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Custom cell drawing
Reply #5 - Sep 1st, 2009 at 11:01am
Print Post  
What does Unit2Pixel do? Try calling view.DocToClient(e.Bounds) to get the pixel coordinates, before ResetTransform(). DocToClient will also provide for the current scroll position and zoom level.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Re: Custom cell drawing
Reply #6 - Sep 1st, 2009 at 11:41am
Print Post  
Hi Stoyan,

I've replaced Diagram.UnitToPixel with DiagramView.DocToClient and place ResetTransform after the DocToClient is called but same result, no line is drawn on table surface.

Code
Select All
  void Diagram_DrawCell(object sender, DrawCellEventArgs e)
        {
            SmoothingMode smoothingMode = e.Graphics.SmoothingMode;
            e.Graphics.SmoothingMode = SmoothingMode.None;

            System.Drawing.Pen pen1 = (new MindFusion.Drawing.Pen(Color.Red, 0)).CreateGdiPen();
            System.Drawing.Pen pen2 = (new MindFusion.Drawing.Pen(Color.Green, 0)).CreateGdiPen();

            DiagramView view = FormQuery.QueryDiagramPane.DiagramViewPanel.DiagramView;

          Rectangle rect = view.DocToClient(e.Bounds);

            Matrix t = e.Graphics.Transform;
            e.Graphics.ResetTransform();

            //e.Graphics.DrawLine(pen1, rect.Left, rect.Bottom - 1, rect.Right, rect.Bottom - 1);
            e.Graphics.DrawLine(pen2, rect.Left, rect.Bottom, rect.Right, rect.Bottom);

            e.Graphics.Transform = t;
}
 



Any help (new hints?) appreciated. Thanks!

Bogdan
  
Back to top
 
IP Logged
 
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Re: Custom cell drawing
Reply #7 - Sep 1st, 2009 at 11:47am
Print Post  
Just a thought: The line painting is done in the Diagram.DrawCell event handler but if DocToClient returns coordinates relative to the view, shouldn't this painting be done in the diagram view's paint event handler? Although I'd prefer to use the Diagram.DrawCell event handler.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Custom cell drawing
Reply #8 - Sep 1st, 2009 at 3:28pm
Print Post  
Seems ResetTransform doesn't reset the PageUnit, so you should also assign Pixel to it:

Code
Select All
Matrix t = e.Graphics.Transform;
e.Graphics.PageUnit = GraphicsUnit.Pixel;
e.Graphics.ResetTransform();

//e.Graphics.DrawLine(pen1, rect.Left, rect.Bottom - 1, rect.Right, rect.Bottom - 1);
e.Graphics.DrawLine(pen2, rect.Left, rect.Bottom, rect.Right, rect.Bottom);

e.Graphics.Transform = t;
e.Graphics.PageUnit = GraphicsUnit.Millimeter;
 



I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Re: Custom cell drawing
Reply #9 - Sep 2nd, 2009 at 7:42am
Print Post  
Thanks, now it's working!

In the custom cell drawing event handler I draw the text using the default DrawString method:

Code
Select All
g.DrawString(e.Cell.Text,
                    e.Cell.Font ?? e.Table.Font, Brushes.Black, e.Bounds, e.Cell.TextFormat);
 



Currently, only the first row has the text in bold. I've set the first cell's font to bold and therefore the text is drawn in bold.

But is there any solution to draw the formatted strings (as in the case of default drawing and EnableStyledText set to "true")? Is there a "Styled" drawing engine I can use for drawing custom formatted texts? I'd like to maintain the text formated as <b>This is a text </b> instead of setting the font bold because it is more flexible. (maybe in the future I'll must add a text half bold, half normal and this is more complicated without a formatted style)


Thanks and I appreciate your help,
Bogdan
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Custom cell drawing
Reply #10 - Sep 2nd, 2009 at 8:37am
Print Post  
Hi Bogdan,

The Diagram.DrawStyledText method does that.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Re: Custom cell drawing
Reply #11 - Sep 2nd, 2009 at 9:57am
Print Post  
Thanks, DrawStyledText does indeed draw the formatted text.

But the drawn text is now clipped in the right side event though the cell bound is large enough to fit the text. I used the same <b>e.Bounds</b> parameter as a I did when I used the classical DrawString method.

When drawing in classical way (by using the DrawString method) the text is correctly drawn, not clipped)

Code
Select All
//using DrawString
g.DrawString(e.Cell.Text,
                    e.Cell.Font ?? e.Table.Font, new SolidBrush(this.TextColor), e.Bounds, e.Cell.TextFormat);
            }
 



Code
Select All
//using DrawStyledText
this.DrawStyledText(g, e.Cell.Text, e.Cell.Font ?? e.Table.Font, e.Bounds, e.Cell.TextFormat);
 



Can this be an old version problem? I'm using MindFusion.Diagramming v 5.1.0.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Custom cell drawing
Reply #12 - Sep 2nd, 2009 at 2:32pm
Print Post  
What are the cell.Text and e.Bounds values with which you are seeing the text clipped?
  
Back to top
 
IP Logged
 
bogdip
Junior Member
**
Offline


I love YaBB 1G - SP1!

Posts: 70
Joined: Sep 8th, 2008
Re: Custom cell drawing
Reply #13 - Sep 3rd, 2009 at 8:20am
Print Post  
Hi Stoyan,

e.Cell.Text contains text like:

Annotation, CreatedBy, CreationTimeUtc, ModifiedBy, etc

The e.Bounds contains values like:

X:5.0 Y:12.0 W:50.0 H:6.0
-//- Y:18.0 -//- -//-
-//- Y: 24.0 -//- -//- etc.

The e.Cell.Font (same as e.Table.Font) is:

Name: Microsoft Sans Serif
Size: 2.9
Style: Regular
Bold, Italic, Underline: false
Unit: World


The drawings (both variants) are made in the default units (milimeter).

Even if I enlarge the tables width (e.g. from 50.0 to 160.0 - I made a test) the text remains clipped using the DrawStyleText method:

Annotation is drawn as Annotat
CreatedBy is drawn as Create
CreationTimeUtc is drawn as CreationTime
ModifiedBy is drawn as Modifie
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Custom cell drawing
Reply #14 - Sep 3rd, 2009 at 10:15am
Print Post  
Hi Bogdan,

I think the diagram uses diagram.MeasureUnit when font.Unit is set to World, so that problem could happen because the text layout is calculated for font's size in millimeters, but you draw it in pixels. Try using a Font whose unit is set to Pixel.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: [1] 2 
Send TopicPrint