Hi Karl,
Didn't you like my solution? Seems to work well for what you need here...
Winforms, GDI+ and basic conceptual fightings
Re: Winforms, GDI+ and basic conceptual fightings
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
Re: Winforms, GDI+ and basic conceptual fightings
Hi Karl
I'd be interested in how you get on. Whatever you find easiest is the main thing.
Had you said 6 or any number of "Viewports on a Canvas" rather than "Panels on a Canvas" - that would have worked in just the way you were thinking (I think!).
And yes I know there was a lot of ill-informed comment doing the rounds a few years back - still is I suspect.
Best Regards
Terry
I'd be interested in how you get on. Whatever you find easiest is the main thing.
Had you said 6 or any number of "Viewports on a Canvas" rather than "Panels on a Canvas" - that would have worked in just the way you were thinking (I think!).
And yes I know there was a lot of ill-informed comment doing the rounds a few years back - still is I suspect.
Best Regards
Terry
Re: Winforms, GDI+ and basic conceptual fightings
Hi Chris,
(and again i lost my answer, needing too much time to write it. May i say, i hate this site's editor?)
sorry, had a very busy time and could only throw a quick glance to your code, before other tasks teared me away…
Yes, that should work. Hadn’t thought about tackling the job backwards, dividing big rectangles into small squares.
Again, i learned by typing my questions, for what i didn’t understand in the code below:
So, is it correct to say, the oGraphics operations move the origin from the left upper corner of the rectangle to its middle, rotate it, then retranslates the origin, preserving the rotation, so that subsequent drawings of divisions and letters has not to bother with angles?
So far, i thought i got it, but that can’t be the whole truth, as the container helds not the rectangle, but the whole client screen - so…??
Thx for your patience!
(and again i lost my answer, needing too much time to write it. May i say, i hate this site's editor?)
sorry, had a very busy time and could only throw a quick glance to your code, before other tasks teared me away…
Yes, that should work. Hadn’t thought about tackling the job backwards, dividing big rectangles into small squares.
Again, i learned by typing my questions, for what i didn’t understand in the code below:
Code: Select all
METHOD DoPaint(oGraphics AS Graphics) AS VOID
LOCAL oContainer AS System.Drawing.Drawing2D.GraphicsContainer
LOCAL oRect AS Rectangle
oRect := Rectangle{SELF:x - (SELF:boxes * size / 2) , SELF:y - size / 2, SELF:boxes * size, size}
oContainer := oGraphics:BeginContainer()
oGraphics:TranslateTransform(SELF:x,SELF:y)
oGraphics:RotateTransform(SELF:rotation)
oGraphics:TranslateTransform(-SELF:x,-SELF:y)
oGraphics:DrawRectangle(oPen, oRect)
FOR LOCAL n := 1 AS INT UPTO SELF:boxes
oGraphics:DrawLine(oPen, oRect:Left + n * size, oRect:Top, oRect:Left + n * size, oRect:Bottom)
oGraphics:DrawString(n:ToString(), oFont , oBrush, oRect:Left + n * size - size / 2, oRect:Top + size / 4)
NEXT
oGraphics:EndContainer(oContainer)
RETURNSo, is it correct to say, the oGraphics operations move the origin from the left upper corner of the rectangle to its middle, rotate it, then retranslates the origin, preserving the rotation, so that subsequent drawings of divisions and letters has not to bother with angles?
So far, i thought i got it, but that can’t be the whole truth, as the container helds not the rectangle, but the whole client screen - so…??
Thx for your patience!
Regards
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
Re: Winforms, GDI+ and basic conceptual fightings
Chris,
i reset the location of the picture box to {0,0}, to make it easier to view. Now using only your first BigBox and giving it a 30°rotation, part of the box is outside the client screen. So there is still some misunderstanding on my side, i fear.
i reset the location of the picture box to {0,0}, to make it easier to view. Now using only your first BigBox and giving it a 30°rotation, part of the box is outside the client screen. So there is still some misunderstanding on my side, i fear.
Regards
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
Karl
(on Win8.1/64, Xide32 2.20, X#2.20.0.3)
Re: Winforms, GDI+ and basic conceptual fightings
Hi Karl,
The way I wrote the code, the x,y coordinates you pass for each (big) box represent the position of the _middle_ of the box (not it's upper left corner), in order to make it easier to position it. So if the box is very close to the edge and it is rotated, then it makes sense that part of it goes out of the edge.
Yes, the code works exactly how you described it regarding rotation. Basically the BeginContainer/EndContainer thing is only used to reset the whole viewport of the Graphics object (which is used for drawing multiple boxes) to its original setting, so when you start drawing another big box, you will not have to take into account also previous rotations (for previously drawn boxes). You can remove both calls to those methods and instead restore the viewport to its original state by doing the reverse transformations at the end:
Using the same approach, you can also do a similar transformation to rotate back the viewport before drawing the numbers, so they are drawn always "level". I'm sure there's a better (with less code) way to do this, but this also works :
The way I wrote the code, the x,y coordinates you pass for each (big) box represent the position of the _middle_ of the box (not it's upper left corner), in order to make it easier to position it. So if the box is very close to the edge and it is rotated, then it makes sense that part of it goes out of the edge.
Yes, the code works exactly how you described it regarding rotation. Basically the BeginContainer/EndContainer thing is only used to reset the whole viewport of the Graphics object (which is used for drawing multiple boxes) to its original setting, so when you start drawing another big box, you will not have to take into account also previous rotations (for previously drawn boxes). You can remove both calls to those methods and instead restore the viewport to its original state by doing the reverse transformations at the end:
Code: Select all
oGraphics:TranslateTransform(SELF:x,SELF:y)
oGraphics:RotateTransform(-SELF:rotation)
oGraphics:TranslateTransform(-SELF:x,-SELF:y)
Code: Select all
USING System.Windows.Forms
USING System.Drawing
USING System.Collections.Generic
[STAThreadAttribute];
FUNCTION Start( ) AS VOID
DrawForm{}:ShowDialog()
CLASS DrawForm INHERIT System.Windows.Forms.Form
PROTECT oPictureBox1 AS System.Windows.Forms.PictureBox
PROTECT aBoxes AS List<BigBox>
CONSTRUCTOR()
SUPER()
SELF:oPictureBox1 := System.Windows.Forms.PictureBox{}
SELF:ClientSize := System.Drawing.Size{704 , 448}
SELF:oPictureBox1:Location := System.Drawing.Point{0 , 0}
SELF:oPictureBox1:Size := System.Drawing.Size{679 , 422}
SELF:oPictureBox1:Paint += SELF:PictureBox1_Paint
SELF:Controls:Add(SELF:oPictureBox1)
SELF:aBoxes := List<BigBox>{}
SELF:aBoxes:Add(BigBox{3,80,80,0})
SELF:aBoxes:Add(BigBox{5,200,200,0})
SELF:aBoxes:Add(BigBox{5,300,100,45})
SELF:aBoxes:Add(BigBox{10,400,200,-30})
RETURN
METHOD PictureBox1_Paint(sender AS System.Object , e AS System.Windows.Forms.PaintEventArgs) AS VOID
FOREACH oBox AS BigBox IN SELF:aBoxes
oBox:DoPaint(e:Graphics)
NEXT
END CLASS
CLASS BigBox
PROTECT x,y,boxes AS INT
PROTECT rotation AS REAL4
STATIC PROTECT size := 40 AS INT
STATIC PROTECT oPen := Pen{Color.Black} AS Pen
STATIC PROTECT oFont := Font{"Arial", size/2} AS Font
STATIC PROTECT oBrush := SolidBrush{Color.Black} AS SolidBrush
CONSTRUCTOR(nBoxes AS INT, x AS INT, y AS INT, nRotation AS REAL4)
SELF:boxes := nBoxes
SELF:x := x
SELF:y := y
SELF:rotation := nRotation
RETURN
METHOD DoPaint(oGraphics AS Graphics) AS VOID
LOCAL oContainer AS System.Drawing.Drawing2D.GraphicsContainer
LOCAL oRect AS Rectangle
LOCAL oFormat AS StringFormat
oFormat := StringFormat{}
oFormat:Alignment := StringAlignment.Center
oFormat:LineAlignment := StringAlignment.Center
oRect := Rectangle{SELF:x - (SELF:boxes * size / 2) , SELF:y - size / 2, SELF:boxes * size, size}
oGraphics:TranslateTransform(SELF:x,SELF:y)
oGraphics:RotateTransform(SELF:rotation)
oGraphics:TranslateTransform(-SELF:x,-SELF:y)
oGraphics:DrawRectangle(oPen, oRect)
FOR LOCAL n := 1 AS INT UPTO SELF:boxes
oGraphics:DrawLine(oPen, oRect:Left + n * size, oRect:Top, oRect:Left + n * size, oRect:Bottom)
LOCAL nTextX,nTextY AS INT
nTextX := oRect:Left + (n-1) * size + size / 2
nTextY := oRect:Top + size / 2
// reverse rotate for the numbers
oGraphics:TranslateTransform(nTextX,nTextY)
oGraphics:RotateTransform(-SELF:rotation)
oGraphics:TranslateTransform(-nTextX,-nTextY)
oGraphics:DrawString(n:ToString(), oFont , oBrush, nTextX , nTextY, oFormat)
// restore previous rotation
oGraphics:TranslateTransform(nTextX,nTextY)
oGraphics:RotateTransform(SELF:rotation)
oGraphics:TranslateTransform(-nTextX,-nTextY)
NEXT
// restore original rotation (none)
oGraphics:TranslateTransform(SELF:x,SELF:y)
oGraphics:RotateTransform(-SELF:rotation)
oGraphics:TranslateTransform(-SELF:x,-SELF:y)
RETURN
END CLASS
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu

