Forum > Graphics

How can I draw a rectangle onto an image of a ScrollBox?

(1/6) > >>

Tomi:
Hello!

I have a scrollbox with one or more images on it in my program. I would like to draw a rectangle onto image on place of mouse click.
I tried achieve this directly in OnPaint event of the scrollbox and then of the image, but I failed with my attempts: I could not see the rectangle.
So, I have the scrollbox, and some images: image[0], image[1], etc. on it. When I clicking one of these images, the program performs the

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---tile[i].invalidate;command and in the OnPaint event of the images I try draw a rectangle with simply the DrawFocusRect() function or so:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---therectangle:=TImage.Create(tile[actualtileimage]); therectangle.Left:=tile[actualtileimage].Left+4; //As a test, now I add the upper left corner coordinates of the image, therectangle.Top:=tile[actualtileimage].Top+4; //but I want to change this to mouse coordinates.  therectangle.Width:=tilewidth; therectangle.Height:=tileheight;            therectangle.canvas.drawfocusrect(Rect(therectangle.Left,therectangle.Top,therectangle.Left+tilewidth,therectangle.Top+tileheight));
but nothing happened. Maybe I add wrong coordinates or the scrollbox or the images are always cover the rectangle?
How can I solve this problem, if it possible?

TRon:
My apologies upfront in case I've read this wrong but I do not see a scrollbox canvas to which you draw onto ? You seem to draw to the rectangle canvas but the code that draws the image to the scrollbox or the image placed on the scrollbox seems missing ?

Tomi:
Hello TRon!

Originally I tried draw directly onto the canvas of the ScrollBox, but nothing happened, therefore I tried with that code I wrote in the first post.
So, I tried these in the OnPaint event of the ScrollBox:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---canvas.drawfocusrect(Rect(imgscrollbox.Left+20,imgscrollbox.Top+20,imgscrollbox.Left+20+tilewidth,imgscrollbox.Top+20+tileheight)); //As a test value, I tried draw at its corners +20and the other:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---canvas.drawfocusrect(Rect(ScreenToClient(mouse.cursorpos).X+imgscrollbox.HorzScrollBar.Position,ScreenToClient(mouse.cursorpos).Y+imgscrollbox.VertScrollBar.Position-imgscrollbox.Top,ScreenToClient(mouse.cursorpos).X+imgscrollbox.HorzScrollBar.Position+tilewidth,ScreenToClient(mouse.cursorpos).Y+imgscrollbox.VertScrollBar.Position-imgscrollbox.Top+tileheight));

Handoko:
If you have a scrollbox and 2 images inside it, you need to correctly decide which canvas you want to draw on.

Try this code below. You can't see a rectangle if you do not put the coordinates correctly. So I use lines instead.


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, Forms, Controls, Graphics, ExtCtrls, StdCtrls; type   { TForm1 }   TForm1 = class(TForm)    chkScrollBox: TCheckBox;    chkImage: TCheckBox;    Image1: TImage;    ImageList1: TImageList;    ScrollBox1: TScrollBox;    procedure CheckBoxChange(Sender: TObject);    procedure Image1Paint(Sender: TObject);    procedure ScrollBox1Paint(Sender: TObject);  private    procedure DrawLines(C: TCanvas);  end; var  Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.ScrollBox1Paint(Sender: TObject);begin  if chkScrollBox.Checked then    DrawLines(ScrollBox1.Canvas);end; procedure TForm1.Image1Paint(Sender: TObject);begin  if chkImage.Checked then    DrawLines(Image1.Canvas);end; procedure TForm1.CheckBoxChange(Sender: TObject);begin  ScrollBox1.Invalidate;end; procedure TForm1.DrawLines(C: TCanvas);const  len = 1000; // length of the linevar  r: Single; // angle in radianbegin  r := 0;  repeat    C.Line(0, 0, Round(Cos(r)*len), Round(Sin(r)*len));    r := r + 0.02;  until r > Pi/2;end; end.

TRon:
Thank you very much for the excellent example Handoko.


--- Quote from: Tomi on April 09, 2024, 02:23:24 pm ---So, I tried these in the OnPaint event of the ScrollBox:

--- End quote ---
As noted by Handoko, make sure the coordinates makes sense.

So far I can see that you seem to use profound way of calculating the coordinates of a rectangle but they make no sense as they are coordinates related to other components (or even the screen).

The coordinates of a rectangle inside a scrollbox/image are absolute to that same scrollbox/image. So left/top coordinate 0,0 means either 0,0 of the scrollbox canvas or the image canvas. Any coordinate/pixel that does not fit onto the canvas will be clipped. So i suspect that your rectangle isn't visible because you draw it outside the visible area of your image/scrollbox canvas.

Note how Handoko's example draw lines with a length of 1000 pixels but that the lines are 'cut-off' (because the pixels of the lines that are situated outside the (available) area of the canvas are clipped).

edit:
For example the onpaint event from Handoko's example can be adjusted to read:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.Image1Paint(Sender: TObject);begin  if chkImage.Checked then    DrawLines(Image1.Canvas);  Image1.Canvas.DrawFocusRect(Image1.Canvas.ClipRect);end; To draw a focused rectangle to the image canvas.

BTW: if you speak of images did you actually mean a TImage component or an image of a (bitmap) picture that you manually draw to the canvas of the scrolbox ?

attached a picture of a scrollbox withouth using components (just drawing).

Navigation

[0] Message Index

[#] Next page

Go to full version