Lazarus

Programming => LCL => Topic started by: jcdammeyer on April 25, 2021, 09:25:24 am

Title: TControl and TGraphic Control creation issue
Post by: jcdammeyer on April 25, 2021, 09:25:24 am
I ported a Delphi component over to Lazarus.  Ran fine on Windows.  But has issues on both the Pi and the Beaglebone.  That was many months ago and it's only this weekend that I've had a chance to try and chase down the issue.
I've added some screen shots to demonstrate what Lazarus is seeing.
The creation of the component and assignment with the value of 40 to the width which part of the TControl object.
Hovering with the cursor over the Width shows how/where it's been declared on the PC.
Notice the property is the same on the Beagle.
But run the program with a break point and suddenly the Width component is gone.   Since I'm limited to 4 JPGs I can add the one showing the PC does not have this problem on a follow up posting.
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on April 25, 2021, 09:32:32 am
So the question is why on the Beagle and the Pi is the Width parameter not initialized (random value) and marked as unknown while on the PC it has the value assigned in the create constructor.

The end result is that on the Pi or the Beagle the display the first digit is incorrect and in the wrong position and the other 3 are blank.  The calculation
  W := Width / 20;
  H := Height / 38;

sets W and H effectively to 0.  (a very small float number).

Don't know where to look next since the edit shows the correct linkage while the run time debug does not but only on the Beagle or Pi.  Not a PC.


Title: Re: TControl and TGraphic Control creation issue
Post by: jamie on April 25, 2021, 02:21:27 pm
You have different screen resolutions,  you need a scaler divider that is calculated via your screen X,Y resolution and not use fixed values..

Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on April 25, 2021, 05:19:19 pm
You have different screen resolutions,  you need a scaler divider that is calculated via your screen X,Y resolution and not use fixed values..

If the components were oddly shaped I could see that but the PC with 1080 and the Pi with 1080 have the same resolution.  The Beagle is stretched so circles aren't round but in either case the value of Width passed to TdsSevenSegmentDisplay.DrawSegment(s:Byte) should not be 0 since the value 40 was assigned to it inside the create constructor.

When I put a break point inside that constructor TdsSevenSegmentDisplay.Create(AOwner : TComponent) and look at Width it does indeed have 40 in it.

So why later when DrawSegment is called does it no longer have a value?  Lazarus under Windows does not have that issue so there's something different in the ARM family.  But what?
Title: Re: TControl and TGraphic Control creation issue
Post by: jamie on April 25, 2021, 05:35:17 pm
maybe bad compiler..

 There has been recent corrections made with the compiler for arm but I think you need to get the most recent truck for that and of course you will need to rebuild all of the LCL code etc with that compiler..

Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on April 25, 2021, 06:21:06 pm
maybe bad compiler..

 There has been recent corrections made with the compiler for arm but I think you need to get the most recent truck for that and of course you will need to rebuild all of the LCL code etc with that compiler..

Possibly.  But this seems too obvious a problem not to have shown up a long time ago.  I'll whack away at it for a bit.  I'd like to know why it's broken.  Not just blindly type something in to fix it.
Title: Re: TControl and TGraphic Control creation issue
Post by: jamie on April 25, 2021, 07:05:57 pm
I got looking at  your problem a little closer..

can you try instead of using "/" as the divider and use "DIV" instead ?

Also, I guess another question would be is did you use the IDE to design the class or are you doing this at the raw level ?

The IDE needs to read the values from the resource of the file which is attached at the end of the application file. This is done during the Construction period so that means you either need to use the OnCreate of the form there by allowing this process to complete or if you are overriding the constructor then you need to ensure you call the inherited first..

 But if you are doing this at RAW metal level, then of course these WIDTH, HEIGHT etc values will be 0 at start.

Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on April 25, 2021, 07:13:29 pm
Just headed out on doggy walk so I'll check when I get back. 

The odd thing is the exact same code works with Lazarus for Windows and I've just been through the files doing some tweaking and {$IFDEF} work so now it again compiles with Delphi 10.3 or Lazarus on the PC.  I'll copy that project folder back onto the Beagle and the Pi and give it another try.
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on April 26, 2021, 01:47:55 am
I just downloaded the folder with the project onto a LinuxCNC PC.  Had to install the dsLED component in order to get the form to show up.  And it shows up just like it does on the Beagle and that's different from the PC Lazarus or Delphi version.

Since it doesn't show up correctly as a form I think that's the first place to look.  Why is it that on a PC with Lazarus this form is correct while on Linux based systems it's not.  It implies the write once compile anywhere module is not working correctly.

I'll go through the tutorial along with this part
https://wiki.lazarus.freepascal.org/How_To_Write_Lazarus_Component#Step_3:_Create_icons_for_the_package
because the package icons show up correctly for WIN-10 Delphi but not Lazarus at all.

Baby steps I guess.

Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on April 28, 2021, 07:55:13 am
I broke the project down to be a bit simpler since I couldn't figure out why the 7 segment display was offset from the rectangle.  Quite by accident when I was moving things around on the form I stumbled on the underlying root of the problem.  Don't have a solution yet though.

I created a form with just the single 7 segment component created from scratch on the BBB with Lazarus 2.0.10.  I also added another component that has a 6 digit display and works properly; to try and figure out what's different...

Anyway, the basic component works wonderfully if the component is placed at 0,0.  Click the button and the Value is incremented each time the LED is switched to ON. 

But drag the component away from the 0,0 position and the segments remain in place and when recompiled still changed but not locked inside the rectangle.

This only happens on the Linux based BBB and Raspberry Pi.  The same code and component on a PC has the segments dragging with the rectangle.  Same code in Delphi too. 

So something deep inside the TGraphicControl doesn't work in either the IDE or in the running application. 

More when I figure it out.
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on April 28, 2021, 08:52:00 am
So I loaded the components into the windows version of Lazarus and absolutely no problem dragging the seven segment display around the form.

I also tried it on LinuxCNC and same as the Beagle.

I've attached the zip of the project and the two component lpk folders. 
Maybe someone else wants to try this?
Title: Re: TControl and TGraphic Control creation issue
Post by: PascalDragon on April 28, 2021, 08:55:32 am
Since it doesn't show up correctly as a form I think that's the first place to look.  Why is it that on a PC with Lazarus this form is correct while on Linux based systems it's not.  It implies the write once compile anywhere module is not working correctly.

Assuming that with "PC" you mean Windows-based then it could simply be that the widgetsets behave differently. Remember: on Windows the Windows API is used for the UI while on Linux it's either GTK (https://wiki.freepascal.org/GTK2_Interface) or Qt (https://wiki.freepascal.org/Qt5_Interface). It could be that you stumbled either upon a bug in the way the LCL interfaces with that widgetset or - worse - a bug in the widgetset itself. Best try to minimize your problem as much as possible (like you already started in your last post) and then to report a bug (https://bugs.freepascal.org). Also you could try if your widgetset is set to e.g. GTK to switch to Qt instead to see whether that solves the problem (or the other way round).
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on April 28, 2021, 09:14:46 am
I understood that at a certain level Lazarus as the IDE isolates us from those details.   The whole point of the Delphi style interface is that you plop components down onto the form and link to the various events.  Makes for easy graphical applications development.  Whether under the covers it's Windows, GTK or Qt should, to the applications programmer be irrelevant.

What I do not know yet, but appears I'm going to have to learn is how a component is shown on the form during development.  Seems as if the code that makes up the 'paint' function or 'change' or 'refresh' is also called by the IDE to display the components on the form during development.

Unlike Delphi the IDE needs to be rebuilt every time a component is added.  So what I really need to do is take a step back and create a canvas rectangle, set the brush and pen colours and create canvas polygons.  All without the IDE forms design side since then it's part of the IDE.

And because the BBB and Pi are painfully slow I'll have to do it on a Linux desktop (the LinuxCNC one) since unfortunately the Windows PC Lazarus works the in the expected way.

It may be a few days before I get to this.  Work-work unfortunately has to come first.
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 03, 2021, 06:36:08 pm
Alright.  Spent some time this weekend reducing this project down to as simple as possible.
1. I'm trying to create a component that I can debug where the TGraphicControl object is created at run time rather than design time. 

2. I don't want to continually add it to the IDE and recompile the IDE so I'm trying to follow the component creation instructions that say test, test, test before you install it into the IDE so that you don't crash the IDE.

3. The sample project allows me to debug and see that everything in the unit jdsevensegdisplay.pas works with one problem.

I cannot figure out how to get the MainForm  FormPaint() method to call the paint function of the unit and therefore nothing is displayed.  Moving the
    procedure Paint; override;
down into published and calling it as
   SevenSegDisplayImage.Paint;
crashes.

The same unit is installed as a component and displayed on the RHS of the form.  (see attached photo here) and increments on the press of the button.  At the moment I'd like the dynamically created TGraphicalControl on the LHS of the form but I'd also like to know how to position it anywhere on the form.

I have explored painting it into an TImage component.  That creates a black rectangle wherever the TImage is placed if the
  SevenSegDisplayImage.Value := CounterValue;
is done inside
with Image1.Canvas do   .. begin

I've attached a zip with the sample project and the component lpk or just remove the component from the form to avoid having to install it.

What am I missing when trying to dynamically create TGraphicControls at some XY location on the form?

Thanks
John
Title: Re: TControl and TGraphic Control creation issue
Post by: howardpc on May 03, 2021, 10:50:54 pm
The attached project makes a few adjustments to your main test program to create the component dynamically and exercise it.
To display a dynamically created control you need to set both its visual coordinates and its Parent (as well as any other relevant properties).
You don't need to explicitly call its Paint method. The LCL ensures that Paint is called whenever the OS needs to refresh the display.
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 03, 2021, 11:34:48 pm
The attached project makes a few adjustments to your main test program to create the component dynamically and exercise it.
To display a dynamically created control you need to set both its visual coordinates and its Parent (as well as any other relevant properties).
You don't need to explicitly call its Paint method. The LCL ensures that Paint is called whenever the OS needs to refresh the display.

Thank you.  I spent the entire weekend reading documents all the way back to my Borland Delphi 5 for Windows 98, 95 and NT.

The two major differences I see between my original and yours is the
      SetInitialBounds(10, 14, 130, 234);   // you had the LH point at 400

and
      Parent := Self;

I'm going to suspect that Parent is NIL on creation and that's why none of the Paint stuff worked properly.

It really appears to be that simple and perhap the SetInitialBounds is what is different between the Window Lazarus and the Linux Lazarus when it's installed as a component and dropped on the Form as shown in a previous posting.

Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 04, 2021, 12:09:33 am
I have one other related question to this issue of creating components.   I have the register proc and I created the jdled_icon.lrs file with three bitmaps in different sizes like the jdLED.bmp.  However, once the package is installed the icons for the component doesn't look like that as shown in the screen grab.


procedure Register;
begin
  {$I jdled_icon.lrs}
  RegisterComponents('LEDS',[TjdLED]);
end; 

Again it must be something really simple but what?

John

Oh and first two lines of the lrs file are:
LazarusResources.Add('jdLED','BMP',[
  'BM'#246#6#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#24#0#0#0#24#0#0#0#1#0#24#0#0#0#0#0

So correct BMP file was accessed.
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 04, 2021, 01:24:03 am
OK.  Bad news but it matches the installed component so that's good news I guess.
I changed this to to move the top corner down.
 SetInitialBounds(50, 50, 130, 234); 
Screen-3.jpg shows that it moved.  The form placed component is still on the far RHS.  All on Windows with Lazarus 2.0.10

Now onto Linux and here is where it still goes south but shows that some sort of parent XY location is not being inherited.

The 15-59-40.png shows the component placed on the far RHS just like on the windows system but the segments are missing.  If I drag it all the way to the left the segments show up as it's dragged across to the 0,0 position.  But for now I'll leave it on the RHS.

Next if I also set initial bounds to 50,50 as in the windows example, the component is rendered in that offset location as far as the TGraphicalControl XY position is concerned but the segments are still anchored at 0,0.  This is shown in the 16-06-56.png screen shot.

So now it's clear that under windows Lazarus does the drawing of polygons relative to the SetInitialBounds(50, 50, 130, 234); statement.  Under Linux  it does it relative to 0,0 and they don't show up unless the TGraphicalControl is in that position.

This is of course far more serious than the wrong ICON BMP placed on the component bar, which by the way, is the same on Linux and Windows.  Probably just doing something wrong there...

So.  Ideas?




Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 04, 2021, 03:17:36 am
In digging deeper I realized unlike the original Delphi component that I derived this code from, the background wasn't changing.  It used to.  I discovered that I had inadvertently deleted this line in the paint method:
Code: Pascal  [Select][+][-]
  1. -  Canvas.Rectangle(0, 0, Width, Height);
  2.  

That looks better now but unfortunately it didn't fix the issue on the Linux side. 

Diving way down into the GTK code it appears like the DC handle isn't correct.  But I'm not sure why.
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 04, 2021, 09:02:30 am
This screen shot is from the Linux Machine.  The two edit boxes show the top left hand corner of each TGraphicalComponent and they match what they've been set at.

But the segments which are polygons are drawn relative to the canvas 0,0 position of the main form rather than the canvas 0,0 of the component objects.

Here's the code that prints out the corners.
Code: Pascal  [Select][+][-]
  1. var aPnt1, aPnt2: TPoint;
  2. begin
  3.   aPnt1 := Point(0, 0);
  4.   aPnt2 := Point(0, 0);
  5.  
  6.   aPnt1 := SevenSegDisplayImage.ClientToParent( aPnt1, Form1 );  // the runtime created component
  7.   Edit1.Text := IntToStr(aPnt1.x) + ' ' + IntToStr(aPnt1.y);
  8.  
  9.   aPnt2 := SevenSegDisplay1.ClientToParent( aPnt2, Form1 );  // The component
  10.   Edit2.Text := IntToStr(aPnt2.x) + ' ' + IntToStr(aPnt2.y);
  11.  

Is this at the point where it's really a bug report and if so where or how would I file it?
Title: Re: TControl and TGraphic Control creation issue
Post by: wp on May 04, 2021, 11:26:21 am
I really don't know what's going on here, but when I changed the Left and Top coordinates of the seven-segment component it was moved correctly, but the segments were drawn at inverted positions (i.e. when I said Top = 40 the segments were moved up rather than down). This observation is for Ubuntu 20.10 and LMDE4 (gtk2). On Windows, Cocoa, gtk3  and qt5 everything is correct.

After playing with the component for some time I could find a workaround by re-writing the Canvas.Polygon in a different way:
Code: Pascal  [Select][+][-]
  1. procedure TjdSevenSegDisplay.DrawSegment(s: Byte);
  2. var
  3.   W, H: Double;
  4.   P: Array[0..5] of TPoint;
  5. begin
  6.   W := Width / 20;
  7.   H := Height / 38;
  8.  
  9.   case s of
  10.     0://top
  11.       begin
  12.         P[0] := Point(round(w*2), round(h*1));
  13.         P[1] := Point(round(w*18), round(h*1));
  14.         P[2] := Point(round(w*(18-FSegWidth)), round(h*(1+FSegWidth)));
  15.         P[3] := Point(round(w*(2 +FSegWidth)), round(h*(1+FSegWidth)));
  16.         canvas.Polygon(P, 4);
  17.       end;
  18.     1://upper left
  19.       begin
  20.         P[0] := Point(round(w*1), round(h*2));
  21.         P[1] := Point(round(w*1), round(h*18));
  22.         P[2] := Point(round(w*(1+FSegWidth)), round(h*(18-FSegWidth)));
  23.         P[3] := Point(round(w*(1+FSegWidth)), round(h*(2+FSegWidth)));
  24.         Canvas.Polygon(P, 4);
  25.       end;
  26.     2://upper right
  27.       begin
  28.         P[0] := Point(round(w*19), round(h*2));
  29.         P[1] := Point(round(w*19), round(h*18));
  30.         P[2] := Point(round(w*(19-FSegWidth)), round(h*(18-FSegWidth)));
  31.         P[3] := Point(round(w*(19-FSegWidth)), round(h*(2+FSegWidth)));
  32.         Canvas.Polygon(P, 4);
  33.       end;
  34.     4://lower left
  35.       begin
  36.         P[0] := Point(round(w*1), round(h*20));
  37.         P[1] := Point(round(w*1), round(h*36));
  38.         P[2] := Point(round(w*(1+FSegWidth)), round(h*(36-FSegWidth)));
  39.         P[3] := Point(round(w*(1+FSegWidth)), round(h*(20+FSegWidth)));
  40.         Canvas.Polygon(P, 4);
  41.       end;
  42.  
  43.     5://lower right
  44.       begin
  45.         P[0] := Point(round(w*19), round(h*20));
  46.         P[1] := Point(round(w*19), round(h*36));
  47.         P[2] := Point(round(w*(19-FSegWidth)), round(h*(36-FSegWidth)));
  48.         P[3] := Point(round(w*(19-FSegWidth)), round(h*(20+FSegWidth)));
  49.         canvas.Polygon(P, 4);
  50.       end;
  51.     6://bottom
  52.       begin
  53.         P[0] := Point(round(w*2), round(h*37));
  54.         P[1] := Point(round(w*18), round(h*37));
  55.         P[2] := Point(round(w*(18-FSegWidth)), round(h*(37-FSegWidth)));
  56.         P[3] := Point(round(w*(2+FSegWidth)), round(h*(37-FSegWidth)));
  57.         Canvas.Polygon(P, 4);
  58.       end;
  59.     3://middle
  60.       begin
  61.         P[0] := Point(round(w*2), round(h*19));
  62.         P[1] := Point(round(w*(2+FSegWidth/2)), round(h*(19-FSegWidth/2)));
  63.         P[2] := Point(round(w*(18-FSegWidth/2)), round(h*(19-FSegWidth/2)));
  64.         P[3] := Point(round(w*18), round(h*19));
  65.         P[4] := Point(round(w*(18-FSegWidth/2)), round(h*(19+FSegWidth/2)));
  66.         P[5] := Point(round(w*(2+FSegWidth/2)), round(h*(19+FSegWidth/2)));
  67.         Canvas.Polygon(P, 6);
  68.       end;
  69.   end;
  70. end;
Title: Re: TControl and TGraphic Control creation issue
Post by: wp on May 04, 2021, 02:13:21 pm
With the following test project I was able to further narrow the issue. The code draws two red rectangles inside a custom control's Paint method. The control is anchored to the right and bottom edges of the form; therefore, the control moves when the window size is changed. Both rectangles are expected to follow the control. But the left rectangle remains at its initial position. It is drawn by the Canvas.Polygon overload using the constant point array as parameter. The right rectangle behaves correctly, it is drawn by the Canvas.Polygon overload which gets the points as parameters.

The left rectangle behaves correctly when the define SHOW_BUG is deactivated - this simply switches the Pen.Style from psClear to psSolid. Therefore, I'd conclude that something is wrong inside the gtk2 widgetset's Polygon routine, when Pen.Style is psClear.

I filed a bug report (https://bugs.freepascal.org/view.php?id=38852).

Code: Pascal  [Select][+][-]
  1. unit unit2;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. {$DEFINE SHOW_BUG}
  6.  
  7. interface
  8.  
  9. uses
  10.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs;
  11.  
  12. type
  13.   TTestControl = class(TGraphicControl)
  14.   protected
  15.     procedure Paint; override;
  16.   end;
  17.  
  18.   { TForm1 }
  19.  
  20.   TForm1 = class(TForm)
  21.     procedure FormCreate(Sender: TObject);
  22.   end;
  23.  
  24. var
  25.   Form1: TForm1;
  26.  
  27. implementation
  28.  
  29. {$R *.lfm}
  30.  
  31. procedure TTestControl.Paint;
  32. var
  33.   P: Array[0..3] of TPoint;
  34. begin
  35.   {$IFDEF SHOW_BUG}
  36.   Canvas.Pen.Style := psClear;
  37.   {$ELSE}
  38.   Canvas.Pen.Style := psSolid;
  39.   {$ENDIF}
  40.   Canvas.Brush.Color := clWhite;
  41.   Canvas.FillRect(0, 0, Width, Height);
  42.  
  43.   Canvas.Brush.Color := clRed;
  44.   // This call is in error
  45.   Canvas.Polygon([Point(20, 20), Point(80, 20), Point(80, 80), Point(20, 80)]);
  46.  
  47.   // This call is correct
  48.   P[0] := Point(80, 20);
  49.   P[1] := Point(140, 20);
  50.   P[2] := Point(140, 80);
  51.   P[3] := Point(80, 80);
  52.   Canvas.Polygon(P, 4);
  53. end;
  54.  
  55. procedure TForm1.FormCreate(Sender: TObject);
  56. begin
  57.   with TTestControl.Create(Self) do
  58.   begin
  59.     SetBounds(0, 20, 180, 210);
  60.     Anchors := [akRight, akBottom];
  61.     Parent := Self;
  62.   end;
  63. end;
  64.  
  65. end.                  
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 05, 2021, 01:32:25 am
It's going to be a while before I can show the results for the Pi.  My Pi3 power supply had some sort of hiccup and destroyed the linux partition.  Couldn't read it on anything anymore. 

For some reason the Pi4 with the LinuxCNC OS dies halfway through installing fpcupdeluxe.  So I downloaded the latest Pi OS and created two micro SD cards, one for the Pi3 and one for the Pi4.  I've run the batch streams on both.  Just about to install fpcupdeluxe on the Pi3.  Not sure which version to put on the Pi4.

But in either case, thanks WP so much for finding that the compiler is screwing up with passing the TPoint set.  I've attached 3 screen shots to show that not only are the run time 7 segment displays in the correct spot but also the component installed into the IDE now drags the segments around with it on the form.  Took forever to recompile the IDE on the Beagle but once it was done it worked great.

John

Edit:  Added the Pi Screen shot now that that fpcupdeluxe has been installed.  Did forget to click the button to show the display positions but doesn't matter.  One is dynamic, the other placed on the form at design time.
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 05, 2021, 06:41:39 am
And what started it all was a time of day clock last summer with the idea that eventually the bit map would be streamed out the SPI port of a Pi or Beagle. The display using not the HDMI screen but a smaller LCD screen.  But with the code done in Lazarus rather than Python or C.

If the check box is ticked the screen blanks after 10 seconds. The Snooze button lights the time up for another 10 seconds.  It uses the dsLEDs library I ported from Delphi.  This will now still need a bit of work since it uses other line drawing that may also not work properly on the Linux side of things.

When the dsLEDs package is fully converted I'll post it here.
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 06, 2021, 07:10:22 am
So just a quick update and some code. 

WP had mentioned that using psSolid also solved the problem.  So I put in the {$IFNDEF ALTERNATE_POLYGON} to either use the original list of points passed inside the Polygon() method or else passing the array with the points.

Next I added either psSolid or psClear with the {$IFNDEF to select.

Now the 7 segments are correctly positioned but with a solid line around the polygons which is not what I wanted.  This screen was done on a Pi4.  Just forgot to change the form Title.

Thanks again to WP for finding the problem.  I've attached the source code for anyone who wants to play.
Title: Re: TControl and TGraphic Control creation issue
Post by: wp on May 06, 2021, 10:54:53 am
In the meantime Anton Kavalenka posted a patch to my bugreport, and the issue is fixed now in trunk (https://bugs.freepascal.org/view.php?id=38852). If you don't use trunk you can easily modify a single line in one of the gtk2 files of your installation:
Code: Pascal  [Select][+][-]
  1.   // create the PointsArray, which is a copy of Points moved by the DCOrigin
  2.   // only if needed
  3.   if (DevCtx.IsNullPen and (DevCtx.IsNullBrush or Winding)) then
  4.     PointArray := nil

Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 06, 2021, 08:55:17 pm
So far this works on LinuxCNC and the Beaglebone.  Haven't tried it yet on the Pi3 or Pi4.
However it does raise a few questions.
1. What is Winding?  A search shows up the usage of this is poorly or not documented at all.  Like a "if the moon is full" flag.
2. The definition of DevCtx.IsNullPen is in an included file and linkage to the actual function is also obscure.  Does IsNullPen return True if psClear is set for the pen?

The reason I ask is when I was single stepping through the program after WP posted the working version with an initialized array I stumbled into that code in the Polygon method.  In fact when I went to the LinuxCNC system to add this new fix that removes winding,  the file was already loaded and the cursor was right at that point.  So I'd gotten to the point where it was in fault.

But I got lost for the reasons stated above.  Couldn't find additional information and there wasn't any documentation that explained why  it was testing for this winding flag.  (Which BTW, was TRUE when stopped at this breakpoint).

Sure glad the problem is fixed.  I'll start a new thread on the component icon issue.

So again.  Thank you, thank you, thank you.
John
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 06, 2021, 10:08:59 pm
One other question.  Using fcpupdeluxe on a new device, what is selected to get this bug fix without editing the file again?

Or is this better asked on this thread?
https://forum.lazarus.freepascal.org/index.php?topic=46438.new;topicseen#new
Title: Re: TControl and TGraphic Control creation issue
Post by: wp on May 06, 2021, 10:20:10 pm
1. What is Winding?  A search shows up the usage of this is poorly or not documented at all. 
It is mentioned in https://wiki.lazarus.freepascal.org/Graphics_-_Working_with_TCanvas#Self-overlapping_polygons or in https://lazarus-ccr.sourceforge.io/docs/lcl/graphics/tcanvas.polygon.html:
Quote
Winding determines how the polygon is filled. When Winding is True, Polygon fills the shape using the Winding fill algorithm.
When Winding is False, Polygon uses the even-odd (alternative) fill algorithm.
But you may have to ask the internet to learn about these algorithms. It's about determining whether a point is inside a closed polygon or outside. Without going into detail, the effect of the winding parameter on a polygon fill can be seen in the attached demo project.

2. The definition of DevCtx.IsNullPen is in an included file and linkage to the actual function is also obscure.  Does IsNullPen return True if psClear is set for the pen?
Don't let these details confuse you. They are deep inside the heart of the gtk2 widgetset, and normally not needed by the application developer.
Title: Re: TControl and TGraphic Control creation issue
Post by: wp on May 06, 2021, 10:37:17 pm
Using fcpupdeluxe on a new device, what is selected to get this bug fix without editing the file again?
In the Lazarus Version listbox select the option "trunk" - this is the development version but you should be aware that it is not as stable as the fixes or numbered release versions. The patch has been put onto the merge request list for the Fixes branch (https://wiki.lazarus.freepascal.org/Lazarus_2.0_fixes_branch#Fixes_for_2.0.14), so after some time you will find it also in the "Fixes" item of the listbox.
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 06, 2021, 10:55:51 pm
Fascinating.   Great example.   I feel like I've been immersed in this for the last 2 days and I'm slowly trying to get a handle on this.

It's all so incredibly simple and yet also complicated.
Thanks for your patience.
John
Title: Re: TControl and TGraphic Control creation issue
Post by: jcdammeyer on May 08, 2021, 02:35:14 am
Using fcpupdeluxe on a new device, what is selected to get this bug fix without editing the file again?
In the Lazarus Version listbox select the option "trunk" - this is the development version but you should be aware that it is not as stable as the fixes or numbered release versions. The patch has been put onto the merge request list for the Fixes branch (https://wiki.lazarus.freepascal.org/Lazarus_2.0_fixes_branch#Fixes_for_2.0.14), so after some time you will find it also in the "Fixes" item of the listbox.
Downloaded a trunk version onto the Pi3.  Took forever but examination of the file shows that the "or winding" is gone completely.   Program compiled and ran without errors.

Although that solution worked I still wonder if it was the right one.   I guess I have issues with
Code: Pascal  [Select][+][-]
  1. if (DevCtx.IsNullPen and (DevCtx.IsNullBrush or Winding)) then

whether the Device Context should have a NullPen when the pen for the component was set.  This just seems like a problem waiting to show up elsewhere again.

I now have the correct ICONs showing up on the component bar.  There are still issues with switching back and forth between the ported 'delphi' component form .dfm and the lazarus .lfm.  Lazarus is text.  Rad Studio is creating binary.  I think if I want compatibility I need to figure out how to force Delphi to stay in text mode.

But that's for a different thread.
TinyPortal © 2005-2018