How does OnPaint work? lazarus / 39-Graphics ---------------------------------------------------------------------- knifemod · 2014-05-31 10:41 Hello, So i got array BoardConnection[x1,y1,x2,y2] : boolean that says Coords stored in BoardCoords[x1,y1] are connected with line with another coords in BoardCoords[x2,y2] if and only if BoardConnection[x1, y1, x2, y2] = true More, BoardConnection is declared like this BoardConnection[1..16,1..16,1..16,1..16] so it's pretty small. and value true can appear in adjacent cells this is |x1-x2| <= 1 && |y1-y2| <= 1 so complexity of one OnPaint call is O(n^2) in this case n = 16 with some constant, so it's really small number for our computers. But there is a problem. When i put just one true value into BoardConnection table and iterate over it it indeed finds this value and enters this if statement where i call Canvas.Line, but Line doesn't appear on the screen. But if i take out this one value out of if statement then line appear on the screen. Here is small part of code to illustrate what i'm talking about : Code: [Select]procedure TFormGame.tryPainting(x, y, wx, wy : integer); var c1, c2 : TIndexShape; begin   if BoardConnection[x, y, wx, wy] = true then   begin        c1 := BoardDotArr[x, y].Circle;        c2 := BoardDotArr[wx, wy].Circle;        canvas.pen.width := 5;        Canvas.pen.color := clred;        Canvas.line(c1.left + c1.Width div 2,c1.top + c1.Height div 2,                    c2.left + c2.Width div 2,c2.top + c2.Height div 2);   end; end;  this code doesn't do anything. but i know i put one value true and got indexes 262,262,302,302 so this code appears to draw black line, but not red one (one from if statement), althought if i put ShowMessage into if statement i got confirmation that program indeed entered this if many many times... Code: [Select]procedure TFormGame.tryPainting(x, y, wx, wy : integer); var c1, c2 : TIndexShape; begin   Canvas.line(262,262,302,302);   if BoardConnection[x, y, wx, wy] = true then   begin        c1 := BoardDotArr[x, y].Circle;        c2 := BoardDotArr[wx, wy].Circle;        canvas.pen.width := 5;        Canvas.pen.color := clred;        Canvas.line(c1.left + c1.Width div 2,c1.top + c1.Height div 2,                    c2.left + c2.Width div 2,c2.top + c2.Height div 2);   end; end; I'd love to get some help on this, cause it really bugs me for many hours... ---------------------------------------------------------------------- Blaazen · 2014-05-31 10:49 You should say what platform you run: (Win or Linux). Qt and Carbon don'ŧ allow to paint out of OnPaint method, while Win and GTK2 allows it. Also what Canvas you are painting to? Form.Canvas ? Maybe PaintBox is better choice... ---------------------------------------------------------------------- circular · 2014-05-31 11:01 I would check the coordinates (c1.left + c1.Width div 2,c1.top + c1.Height div 2, c2.left + c2.Width div 2,c2.top + c2.Height div 2) to see if they are not out of bounds. You can put them in the ShowMessage, for example. ---------------------------------------------------------------------- knifemod · 2014-05-31 11:10 Thanks for answers circular: They are sure not out of bound, because i use c1.left and c1.top to draw shapes on the screen and more, i got those coords from ShowMessage Blaazen: I work on windows XP now, but i need to make it work on Linux too. Yes, by default it's form.canvas. It really buggs me why such thing is happening. I'd love to hear some suggestion how to make it work. It obviously doesn't have to be my way of course. Thank you in advance ---------------------------------------------------------------------- taazz · 2014-05-31 11:17 how is the trypainting method called? where it supposed to paint to ? ---------------------------------------------------------------------- User137 · 2014-05-31 11:26 Quote from: knifemod on May 31, 2014, 01:10:06 pmThey are sure not out of bound, because i use c1.left and c1.top to draw shapes on the screen and more, i got those coords from ShowMessage And what about the Width and Height values? You said that the black line draws, but not one in the If structure so it can only be a coordinate problem. Print out all these values c1.left + c1.Width div 2 c1.top + c1.Height div 2 c2.left + c2.Width div 2 c2.top + c2.Height div 2 Also comment away the if condition so to see that's not a reason. ---------------------------------------------------------------------- Blaazen · 2014-05-31 11:32 Can you make some basic test like this: Code: [Select]procedure TForm1.Button1Click(Sender: TObject); begin   Canvas.Line(0, 0, Width, Height); end;It works in Wine but maybe not in Win XP . ---------------------------------------------------------------------- knifemod · 2014-05-31 11:53 Quote from: User137 on May 31, 2014, 01:26:26 pmAnd what about the Width and Height values? You said that the black line draws, but not one in the If structure so it can only be a coordinate problem. Width and Height values are <= 10 Coordinates is for sure ok, cause when i used drag&drop i used this formula to join two shapes in OnDragDrop For second statement see my answer below. Quote from: taazz on May 31, 2014, 01:17:32 pmhow is the trypainting method called? where it supposed to paint to ? Code: [Select]procedure TFormGame.FormPaint(Sender: TObject); begin   //painting connections in the board   MakeConnections; end;  function TFormGame.inRange(x, y : integer) : boolean; begin   if (x in [1..16]) and (y in [1..16]) then      inRange := true   else      inRange := false; end; procedure TFormGame.tryPainting(x, y, wx, wy : integer); var c1, c2 : TIndexShape; begin   //   if BoardConnection[x, y, wx, wy] = true then   begin        c1 := BoardDotArr[x, y].Circle;        c2 := BoardDotArr[wx, wy].Circle;        canvas.pen.width := 5;        Canvas.pen.color := clred;        FormGame.Canvas.line(262,262,302,302); //ITS IN IF STATEMENT AND IT DOESN'T WORK EITHER        FormGame.Canvas.line(c1.left + c1.Width div 2,c1.top + c1.Height div 2,                    c2.left + c2.Width div 2,c2.top + c2.Height div 2);   end; end; procedure TFormGame.MakeConnections; var dx : array[1..3] of integer; var i, j, di, dj : integer; begin     dx[1] := -1;     dx[2] := 0;     dx[3] := 1;     for i := 1 to HeightOfMap do          for j := 1 to WidthOfMap do               for di := 1 to 3 do                    for dj := 1 to 3 do                    begin                         if (inRange(i+dx[di],j+dx[dj]) = true) then                         begin                            tryPainting(i,j,i+dx[di],j+dx[dj]);                         end;                    end; end;          That's my whole code for OnPaint, pretty straightforward. Forgive me if i did some major mistake, still learning. I would appreciate some help on this one Edit: I did those connections in OnDragDrop, but when i resize window or minimize it my connections disappear, so i had to put them into OnPaint method. ---------------------------------------------------------------------- taazz · 2014-05-31 12:25 I took a close look on the code I do not see a reason not to draw, the only thing I haven't looked at is 1) the assumption that it draws black lines, it might as well draw them I don't know. 2) the pen.style I assume is psSolid? 3) there is no other component on the form that hides the drawing. ---------------------------------------------------------------------- knifemod · 2014-05-31 16:00 Thank you guys for your time! I was missing +1 in one place in the code, it caused access violation, but it showed up when i tried to join all dots on the map! Thanks again!