Recent

Author Topic: How do you make this go?  (Read 1397 times)

JLWest

  • Hero Member
  • *****
  • Posts: 845
How do you make this go?
« on: August 09, 2020, 10:01:41 pm »
@winni
It compiles fine.

I think something in the events of the timer Activate property probably needs to be be added but not sure what.

Is Go a valid command?

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes,  Controls, Dialogs, Forms,Graphics, ExtCtrls,
  9.   SysUtils, Math;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Image1: TImage;
  17.     Timer1: TTimer;
  18.  
  19.     procedure FormCreate(Sender: TObject);
  20.     procedure Image1Paint(Sender: TObject);
  21.     Procedure Timer1Timer (Sender : TObject);
  22.  
  23.  
  24.   private
  25.    AHour : Word;
  26.    AMin : Word;
  27.    ASec : Word;
  28.   public
  29.   end;
  30.  const Deg2Rad = pi/180;
  31.  var
  32.   Form1: TForm1;
  33.  
  34. implementation
  35.  
  36. {$R *.lfm}
  37.  
  38.  procedure TForm1.FormCreate(Sender: TObject);
  39.   begin
  40.    Timer1Timer(Nil);
  41.  end;
  42.  
  43.  Procedure TForm1.Timer1Timer (Sender : TObject);
  44.   var junk : word;
  45.   begin
  46.    DecodeTime(Now,AHour,AMin,ASec,Junk);
  47.    Image1.Invalidate;
  48.  end;
  49.  
  50.  // analog clock, image 90 x 90
  51.  procedure TForm1.Image1Paint(Sender: TObject);
  52.   const ro=20;    // Minutenzeiger
  53.         centerX=45;
  54.         centerY=47;
  55.   var x,y,x1,y1,x2,y2 : integer;
  56.       h,degH, degMin, degSec, sinus, cosinus : single;
  57.   begin
  58.   // hours
  59.     h := Ahour;
  60.     if h >=12 then h := h - 12;
  61.        h := h + AMin/60;
  62.        degH :=  h* 30 - 90;   // Uhr (Nord) fängt 90° vor Lazarus (Ost) an
  63.        math.sincos(degH*Deg2Rad, sinus, cosinus);
  64.        x := round (cosinus*ro*0.75)+centerX;
  65.        y := round (sinus *ro*0.75) +CenterY;
  66.        // minutes
  67.        degMin :=  Amin*6 -90;
  68.        math.sincos(degMin*Deg2Rad, sinus, cosinus);
  69.        x1 := round (cosinus*ro)+centerX;
  70.        y1 := round (sinus*ro)+centerY;
  71.        // seconds
  72.        degSec := ASec*6 -90;
  73.        math.sincos(degSec*Deg2Rad, sinus, cosinus);
  74.        x2 := round (cosinus*ro*1.15)+centerX;
  75.        y2 := round (sinus*ro*1.15)+centerY;
  76.        with Image1.Canvas do begin
  77.           pen.width := 5;
  78.           pen.Color := clBlack;
  79.           pen.EndCap :=   pecRound;
  80.           line(centerX, centerY,x,y);  // hours
  81.           line(centerX, centerY,x1,y1);   // minutes
  82.           pen.width := 1;
  83.           brush.Color := clLime;
  84.           EllipseC(x,y,3,3);    // radium, luminous lime-green, very 60th
  85.           EllipseC(x1,y1,3,3);
  86.           pen.Color := clRed;
  87.           line(centerX, centerY,x2,y2);    // seconds
  88.           pen.Color := clBlack;
  89.           Brush.color := clSilver;
  90.           EllipseC (centerX, centerY,3,3);
  91.        end;
  92.     end;
  93. end.
  94.  
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

MaxCuriosus

  • Full Member
  • ***
  • Posts: 111
Re: How do you make this go?
« Reply #1 on: August 09, 2020, 10:21:47 pm »
I think you need to add "Image1Paint" as "OnTimer" event handler in your timer.
« Last Edit: August 09, 2020, 10:23:50 pm by MaxCuriosus »

TRon

  • Hero Member
  • *****
  • Posts: 535
Re: How do you make this go?
« Reply #2 on: August 09, 2020, 10:24:24 pm »
Sorry as I am not called winni

I think something in the events of the timer Activate property probably needs to be be added but not sure what.
You should enable the timer and make sure the interval is set to 1000 milliseconds (= 1 second) or less for the clock to be (re)drawn at least every second.

TRon

  • Hero Member
  • *****
  • Posts: 535
Re: How do you make this go?
« Reply #3 on: August 09, 2020, 10:31:41 pm »
I think you need to add "Image1Paint" as "OnTimer" event handler in your timer.
Ontimer events are usually named TimerXTimer by codetools/inspector, where x stands for the number (in case you have multiple timer controls situated on your form).

The timer event in the code is calling the method Invalidate of the image control, which in turn should trigger a paint event (for that image).

JLWest

  • Hero Member
  • *****
  • Posts: 845
Re: How do you make this go?
« Reply #4 on: August 09, 2020, 10:32:12 pm »
Sorry TRon

Yea, the timer is enabled and set to 1000
Needs something more.


Sorry as I am not called winni

I think something in the events of the timer Activate property probably needs to be be added but not sure what.
You should enable the timer and make sure the interval is set to 1000 milliseconds (= 1 second) or less for the clock to be (re)drawn at least every second.
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

Blaazen

  • Hero Member
  • *****
  • Posts: 2905
  • POKE 54296,15
    • Eye-Candy Controls
Re: How do you make this go?
« Reply #5 on: August 09, 2020, 10:52:03 pm »
Try to replace TImage with TPaintBox. It worked for me. But still, there is something wierd with TImage, it should work too.
Lazarus 2.1.0 r63881 FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

TRon

  • Hero Member
  • *****
  • Posts: 535
Re: How do you make this go?
« Reply #6 on: August 09, 2020, 11:07:11 pm »
It worked for me. But still, there is something wierd with TImage, it should work too.
It did not for me. The paint event does not seem to be triggered by the invalidate from the timer. Refresh also wasn't able to do the trick for me. There definitely seems something weird going on there unless I completely misunderstood the workings of TImage.

In case it matters, linux, gtk2, laz 2.0.8

@JLWest,
Sorry , there seems to be something wrong there. Best would be to try to follow blaazen's advice to work around the problem by using a paintbox.

JLWest

  • Hero Member
  • *****
  • Posts: 845
Re: How do you make this go?
« Reply #7 on: August 09, 2020, 11:14:00 pm »
Thanks, I was thinking I did something wrong.
FPC 3.2.0, Lazarus IDE v2.0.4
 Windows 10 Pro 32-GB
 Intel i7 770K CPU 4.2GHz 32702MB Ram
GeForce GTX 1080 Graphics - 8 Gig
4.1 TB

MaxCuriosus

  • Full Member
  • ***
  • Posts: 111
Re: How do you make this go?
« Reply #8 on: August 10, 2020, 12:12:07 am »

Ontimer events are usually named TimerXTimer by codetools/inspector, where x stands for the number (in case you have multiple timer controls situated on your form).

The timer event in the code is calling the method Invalidate of the image control, which in turn should trigger a paint event (for that image).

TRon,
Thank you for your explanation.
I had recently built a similar analog clock whitout using the "Timer1Timer" procedure.

TRon

  • Hero Member
  • *****
  • Posts: 535
Re: How do you make this go?
« Reply #9 on: August 10, 2020, 12:24:46 am »
Just for the record, you can't just copy-paste the code as shown. You must use the object inspector to create/link the events to their corresponding implementations in code.

@MaxCurious:
You're welcome  :)

For sure there are other methods to 'update' for example an analogue clock. OnIdle is another event that could be used for that (to not over-abuse OnIdle you should check if the time differs from the previous drawn time and only actually draw it when there need to do so).

How did you end up updating/(re)drawing your clock ?

TRon

  • Hero Member
  • *****
  • Posts: 535
Re: How do you make this go?
« Reply #10 on: August 10, 2020, 12:54:30 am »
Splendid.... whatever you try, casting to an ancestor or whatever, not able to draw the image whatsoever.

However, when calling onpaint event manually, the onpaint event gets invoked and the image draws itself ...... twice  %)

winni

  • Hero Member
  • *****
  • Posts: 1762
Re: How do you make this go?
« Reply #11 on: August 10, 2020, 01:30:37 am »
Hi!

I don't know what you gonna do.
Are some procedures  not connected to some events?

The code is part of my  self made alarm clock and it works since years.
Exact the way it is shown by me an JLWest.
And it survided fpc and Lazarus updates.

Just made a screenshot to convince you.
No PaintBox, no update - just as I wrote it.

Winni

jamie

  • Hero Member
  • *****
  • Posts: 3515
Re: How do you make this go?
« Reply #12 on: August 10, 2020, 02:07:16 am »
I think the issue is that you need a Picture loaded of the same size as the drawing surface to start with.
 Without this there is no drawing surface size.. the Canvas has none...

 I just set the Picture.Bitmap.SetSize(Width,Height); in the FormOnCreate and that creates a black background image.

 Then the OnPaint seems to be getting called..

 Using the canvas of the control you are drawing on the surface not the Bitmap.

 If you want it to be fixed in the image then Picture.Bitmap.Canvas…..
etc

The only true wisdom is knowing you know nothing

TRon

  • Hero Member
  • *****
  • Posts: 535
Re: How do you make this go?
« Reply #13 on: August 10, 2020, 02:14:09 am »
Just made a screenshot to convince you.
I post one in return to convince you and tell you that I am not convinced  :P

Not calling the onpaint handler manually does not invoke it, in any way. Calling it manually invokes it twice. I seem to missing your platform/lazversion and used widgetset.

jamie

  • Hero Member
  • *****
  • Posts: 3515
Re: How do you make this go?
« Reply #14 on: August 10, 2020, 02:27:11 am »
Well, I did the test over here and without the image the OnPaint event does not get called using a Invalidate, up etc.

But after setting the size of the bitmap to something that exists it does now..

Personally I don't see why they limit this but that is the way its done..

Also, it could be possible the cliprect is not yet set.

Platform is Windows 10
The only true wisdom is knowing you know nothing

 

TinyPortal © 2005-2018