Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

On 09/17/2014 04:51 PM, Xiangrong Fang wrote:
2014-09-17 16:09 GMT+08:00 Michael Schnell mschn...@lumino.de 
mailto:mschn...@lumino.de:



Here you are.


It is strange that it works on one computer but does not work (or 
partially work) on another -- causing SIGSEGV.  Both running same 
environment - Ubuntu 14.04 x86_64 fpc 2.6.4 laz1.2.4.

That in fact is strange.
Of course here (Linux x86_32, newest svn version of fpc and Lazarus)  it 
does work, otherwise I would not have posted it.


Did you try the unmodified project ?



I don't understand how the critical section works.
TCriticalSection is a straight forward semaphore. (- 
https://en.wikipedia.org/wiki/Semaphore_%28programming%29 )


Of course there are several kinds of semaphores out there:
 - binary and counting: TCriticalSection is binary
 - blocking or not blocking when a Thread/Task tries to take it while 
it already holds it: TCriticalSection does not block
 - allowing or disallowing a Thread/Task to free it even though it is 
helt by another Thread/Task: TCriticalSection disallows this.




I try to write a test program, which does the following:

The main thread create a predefined number of threads, which start 
running on creation. The thread's wait for a critical section 
variable, when acquired, try to crack a given integer, see if it is 
prime number or not, report back to main thread about the result and 
get the next number to crack from main thread.  The main thread output 
crack result of every thread in a memo box.
Are you sure that only the main thread does anything related to the GUI 
? This is strictly forbidden for worker threads and results in SIGSEGV. 
This is why TThreadPool offers events OnReady events that are run in the 
main thread. (synchronized).


I simply don't know how to coordinate the threads. And got many 
strange errors like


Semaphore init failed (maybe too many running threads)?
I never saw such an error. Anyway, I suppose you will do multithreading  
just for sake of performance. Here running more threads than 
CPUs/Hardware Threads does not make sense, as it will slow down the 
calculation due to unnecessary time slice related task switches which 
result in local cache misses (Linux tries to keep a thread on the same 
CPU if possible, but this is only possible when there are not much more 
active threads than CPUs). So there will never be too many threads.


In any case start with simple stuff (e.g. using my example and replacing 
the Tasks with first simple and then more complex Execute procedures.




something wrong in raise.c, laz asked me if I want to locate myself, 
blahblah.

I have no idea what raise.c is supposed to be.



May I send you my source, or you can write a demo for me?  Thanks a lot!


I already did provide you with a demo. I can enhance this for you if you 
have a certain request.


-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

On 09/18/2014 12:13 AM, Graeme Geldenhuys wrote:
I haven't followed this whole thread, but I can add that the tiOPF 
project (on SourceForge) has had a threadpool class for many years. 
Well unit tested too.

Great ! Thanks. I'll take a look.

I did the TThreadPool class just for fun. I'll compare the two thingies 
and come back with some comments.


Maybe finally it might be nice to add something like this to the fpc rtl 
(I on purpose did in in a way that does not require LCL, but allows for 
using it) or create a Lazarus package from it to be provided in a 
fpc/Lazarus related location.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Xiangrong Fang
2014-09-18 16:13 GMT+08:00 Michael Schnell mschn...@lumino.de:


 I did the TThreadPool class just for fun. I'll compare the two thingies
 and come back with some comments.


​I don't quite understand the logic or difference between critical section ​

​and events. My feeling is that to do synchronization you will have to use
event (I will do some test to verify that).  Because when you use critical
section, like in your ThreadPool:

procedure TThreadPoolThread.Execute;
begin
  while not Terminated do begin
Wait.Aquire;
...
  end;
end;

You are actively try to aquire the CS.  i.e. After you finish this loop and
notify the main thread, how do you ensure which thread will get this CS
next? The main thread or this worker thread?

​But if you use something like this (I don't know if the syntax or usage is
correct, just show my thinking):

procedure TThreadPoolThread.Execute;
begin
  while not Terminated do begin
RTLEventWaitFor(Wait);
...
  end;
end;
​
​Then, you are PASSIVELY wait for the event which will be set/reset from
OUTSIDE this working thread.

That's what confused me how can you use a CS for the purpose of thread
synchronization!

Yesterday I read your ThreadPool source code, and cannot understand how you
control which thread can get the Wait CS, rather than just let the 2
thread compete for it. Could you please explain the logic behind this?

Thanks!

Xiangrong​
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

You said that you in fact did need or do an OnReady Event  for each thread.

I just added that feature to TThreadPool: now each user Task (TTask 
class) can be provided an OnReady Notify function.


Let me know if you want the extended code.

-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

On 09/18/2014 10:32 AM, Xiangrong Fang wrote:




I don't quite understand the logic or difference between critical section
and events.


They have nothing in common.

TCriticalSection is a Semaphore (see Wikipedia)

An event is a callback procedure - 
https://en.wikipedia.org/wiki/Callback_%28computer_programming%29


Sorry, but you will not be able to do such a project unless you 
understand such basic computer science primitives.


-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

On 09/18/2014 10:32 AM, Xiangrong Fang wrote:


how can you use a CS for the purpose of thread synchronization!


Thread synchronization is the only cause why TCriticalSection has been 
invented (and provided with Delphi decades ago by Borland).


-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

On 09/18/2014 10:32 AM, Xiangrong Fang wrote:


2014-09-18 16:13 GMT+08:00 Michael Schnell mschn...@lumino.de 
mailto:mschn...@lumino.de:



I did the TThreadPool class just for fun. I'll compare the two
thingies and come back with some comments.


I don't quite understand the logic or difference between critical section
and events.


In what extent is this an answer to the phrase cited  ?

-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

On 09/18/2014 10:32 AM, Xiangrong Fang wrote:


Yesterday I read your ThreadPool source code, and cannot understand 
how you control which thread can get the Wait CS, rather than just 
let the 2 thread compete for it. Could you please explain the logic 
behind this?



Each worker Thread (i.e. the TThreadPoolThread instance) has it's own 
Wait semaphore (TCriticalSection instance).


The semaphore is owned by the main thread while the worker thread is 
supposed to do hold off, waiting to be assigned any work by setting the 
appropriate element of the Tasks property.


The semaphore is owned by the worker thread when it is working (as 
easily seen in the Execute procedure.


-Michael


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Sven Barth
Am 18.09.2014 11:03 schrieb Michael Schnell mschn...@lumino.de:

 On 09/18/2014 10:32 AM, Xiangrong Fang wrote:




 ​I don't quite understand the logic or difference between critical
section ​

 ​and events.


 They have nothing in common.

 TCriticalSection is a Semaphore (see Wikipedia)

 An event is a callback procedure -
https://en.wikipedia.org/wiki/Callback_%28computer_programming%29

 Sorry, but you will not be able to do such a project unless you
understand such basic computer science primitives.

You are wrong. A critical section is a mutex and an event in this context
is a binary semaphore.

Regards,
Sven
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

On 09/18/2014 11:36 AM, Sven Barth wrote:
A critical section is a mutex 


OK. (but a mutex is constructed from a semphore, anyway, even if this 
might be done in the OS). (I did this when doing my own special purpose 
multitasking OS (in C), some 20 Years ago.)


and an event in this context is a binary semaphore. 


Here, you seem to be speaking of a TEvent instance not of a Object 
pascal language Event (such as OnCreate) which is something 
completely unrelated (and which I provide as OnReady in the code I 
posted).


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

On 09/18/2014 10:32 AM, Xiangrong Fang wrote:


I don't quite understand the logic or difference between critical section
and events.


Sorry for my previous rude reply.

Sven made me know that by event you did not mean an object pascal 
language Event (i.e. a callback), but a TEvent instance.


Here, of course you can use both a TCriticalSection instance (i.e. a 
Mutex) as a TEvent Instance (i.e. a semaphore) for thread synchronizing.


(It's a shame that the creators of our brand of the Object Pascal 
Language once chose to invent new notions for commonly use concepts 
(Callback - Event, Mutex - CriticalSection, TEvent - Semaphore, array 
of Boolean - Set, (object for a kind of class (i.e. a type), instead 
of an instance of same is not used any more...)


-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Mattias Gaertner
On Thu, 18 Sep 2014 11:55:09 +0200
Michael Schnell mschn...@lumino.de wrote:

[...]
 (It's a shame that the creators of our brand of the Object Pascal 
 Language once chose to invent new notions for commonly use concepts 
 (Callback - Event, Mutex - CriticalSection, TEvent - Semaphore, array 
 of Boolean - Set, (object for a kind of class (i.e. a type), instead 
 of an instance of same is not used any more...)

In Free Pascal an Event is a special callback, a CriticalSection is a
special mutex, a TEvent is a special Semaphore, a Set is not an array
of boolean and object has at least two different meanings.

Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

On 09/18/2014 12:10 PM, Mattias Gaertner wrote:

a Set is not an array of boolean
A set is an array (scientific English, not Pascal syntax) of bits 
(i.e. boolean values) supported by special operators.


(Remember: Boolean Algebra and Logical Algebra are mathematically 
equivalent).


The Set stuff is correctly done and nice in Pascal, but in most cases 
I know, set type variables s are used not to represent real-world  sets 
but real world arrays of logical  values.


-Michael

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

On 09/18/2014 12:34 PM, Michael Schnell wrote:

Boolean Algebra and Logical Algebra are mathematically equivalent.

Sorry:
Set Algebra and Logical Algebra are mathematically equivalent.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Mattias Gaertner
On Thu, 18 Sep 2014 12:34:30 +0200
Michael Schnell mschn...@lumino.de wrote:

 On 09/18/2014 12:10 PM, Mattias Gaertner wrote:
  a Set is not an array of boolean
 A set is an array (scientific English, not Pascal syntax) of bits 
 (i.e. boolean values) supported by special operators.

On planet Melmac an array of boolean is a stew of cats.
In Free Pascal a Set is not an array of boolean. You can neither
assign nor typecast them to each other.
Of course you are free to use any analogy you like to explain
Sets and arrays, but then you should not blame Free Pascal, that
your analogy does not work well.

Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Xiangrong Fang
2014-09-18 17:55 GMT+08:00 Michael Schnell mschn...@lumino.de:


 Sven made me know that by event you did not mean an object pascal
 language Event (i.e. a callback), but a TEvent instance.


Sorry, I mean *neither*.  I mean an RTLEvent. See this page:

http://www.freepascal.org/docs-html/rtl/system/rtleventcreate.html

What I need help to understand is, repeating my previous email:

While using ACriticalSection.Acquire, two threads are COMPETING for a
token to do certain task, hence you do not know WHICH thread eventually
get that token, although statistically each thread have the same chance of
getting the token in the long run.

While calling RTLeventWaitFor(), the calling thread gives up
chance to run, blocked until another thread calls RTLeventSetEvent() to
notify it.

If the above understanding is correct, then I believe only RTLEvent can
synchronize threads, i.e., let them run in a *determined* order. While
CriticalSection ONLY provide a way to protect a shared resource is not
accessed simultaneously.

Alternatively, I have another design:

procedure TMyThread.Execute;
begin
  while not Terminated do begin
if FCondition = true then begin
  //do the job...
end;
  end;
end;

In the code above, I do not use event or critical section is it enough to
let this thread wait there, without wasting cpu time, until FCondition is
set (externally by the main thread)?

Thanks!

Xiangrong
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

On 09/18/2014 01:06 PM, Xiangrong Fang wrote:



What I need help to understand is, repeating my previous email: ...


I think, in the other mail, I did explain how Wait is supposed to work 
in TThreadPool.


(And of course with some appropriate modifications of the source code, 
you can use RTLeventSetEvent instead of TCriticalSection if you like. )(


-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Xiangrong Fang
2014-09-18 19:34 GMT+08:00 Michael Schnell mschn...@lumino.de:


 I think, in the other mail, I did explain how Wait is supposed to work
 in TThreadPool.


Initially, when the threadpool is created, Wait is hold by the main thread,
so the worker just wait there, no problem, but after the worker thread get
the CS, it started working, then RELEASE the CS.

This is when the problem arise: after worker release the CS, how do you
ensure it is the MAIN thread who will get the CS next, NOT the worker
thread again?

That is my question, which I don't think you answered.

Thanks,
Xiangrong
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Michael Schnell

On 09/18/2014 01:46 PM, Xiangrong Fang wrote:
2014-09-18 19:34 GMT+08:00 Michael Schnell mschn...@lumino.de 
mailto:mschn...@lumino.de:



I think, in the other mail, I did explain how Wait is supposed
to work in TThreadPool.


Initially, when the threadpool is created, Wait is hold by the main 
thread, so the worker just wait there, no problem, but after the 
worker thread get the CS, it started working, then RELEASE the CS.


This is when the problem arise: after worker release the CS, how do 
you ensure it is the MAIN thread who will get the CS next, NOT the 
worker thread again?


The Thread uses synchronize(NotifyStopped) to call a procedure that is 
run in the main thread (and it waits until this procedure is done). In 
this synchronized procedure, the main thread Acquires wait again, and 
hence the worker thread will block at the start of the next main loop turn.


-Michael
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Fuzzy translations ignored

2014-09-18 Thread Giuliano Colla
I compiled, and that's how your graphs look like under Linux (both Gtk2 
and Qt WS, it doesn't make a difference):


http://www.bononiadocta.it/Lazarus/Pochecker.png

It would appear that FloodFill is rather broken under Linux!

I had in mind a different approach (components instead of just pictures, 
to be able to operate on them) so I implemented an alternative, which at 
first sight was not so bad, under Linux, with Qt WS:


http://www.bononiadocta.it/Lazarus/Pochecker1.png

But, to my dismay, that's how it looks both under Linux Gtk2 and Windows:

http://www.bononiadocta.it/Lazarus/Pochecker2.png

It would appear that at the moment we don't have a reliable 
multiplatform way to draw our pies.


If nobody else is interested (I saw that some graphic things date back 
from 2002!) I can take care of revising the basic tools needed to 
display proper pies. After all it's a common way to show data, and 
Lazarus should provide professional looking pies.

Later I'll open a new thread on lazarusdev on that subject.
Then, when we have the proper tools available, we may continue.

Giuliano


Il 14/09/2014 16:26, Bart ha scritto:

I started a graphical smmary in r46230.

Please check it out and comment on it.

Bart

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Fuzzy translations ignored

2014-09-18 Thread Mattias Gaertner
On Thu, 18 Sep 2014 14:35:33 +0200
Giuliano Colla giuliano.co...@fastwebnet.it wrote:


 I had in mind a different approach (components instead of just pictures, 
 to be able to operate on them) so I implemented an alternative, which at 
 first sight was not so bad, under Linux, with Qt WS:
 
 http://www.bononiadocta.it/Lazarus/Pochecker1.png
 
 But, to my dismay, that's how it looks both under Linux Gtk2 and Windows:
 
 http://www.bononiadocta.it/Lazarus/Pochecker2.png
 
 It would appear that at the moment we don't have a reliable 
 multiplatform way to draw our pies.

Are you saying, that Canvas.Pie is broken?

Mattias

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Fuzzy translations ignored

2014-09-18 Thread Bart
On 9/18/14, Mattias Gaertner nc-gaert...@netcologne.de wrote:

 Are you saying, that Canvas.Pie is broken?

Since I am unfamilliar with graphics and I did not get how to use
Canvas.Pie, I tried to emulate it myself.

I calcuate where the lines need to be drawn using basic goniometry,
then fill in the sections I created with FloodFill.
I couldn't get a grip on Canvas.Pie, Canvas.Arc, Canvas.RadialPie etc. etc.

If Canavs.Pie is the way to go, then all the better.

However, how to do that then?

I start of with a circle with radius Radius, and with origo Origo (TPoint).

Now if I want to draw a Pie-slice of fraction X, starting from the X-axis:
(OrigoX+Radius, Origo.Y)
and going counter clockwise to:
(Origo.X + Round(Cos(X * (2 * pi)) * Radius, Origo.Y - Round(Sin(X *
(2 * pi)) * Radius)

what do I need to do to make that work using Canvas.Pie
And the same Q for a fraction Y, starting of from section X?

PS. You'll note the code for the GraphStat form is rather clumsy.
Currently I'm about to convert it by using a ListView with an
ImageList and create Bitmap's at runtime.
This will make anchoring/aligning that much easier.

Bart

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Fuzzy translations ignored

2014-09-18 Thread Giuliano Colla


Il 18/09/2014 14:55, Mattias Gaertner ha scritto:

Are you saying, that Canvas.Pie is broken?

In short, yes.

Canvas.RadalPie on GTK2 and Windows works only clockwise, but provides a 
very poor image (more like a portion of an octagon that a portion of a 
circle).

Counterclockwise it generates the image of my previous e-mail.

Only on Qt I provided a patch to take advantage of the native 
QT_Painter, and RadialPie works properly, but by overriding 
Canvas.RadialPie (or, to be precise, TWidgetset.RadialPie).


Plain Canvas.Pie works differently for each widgetset: it is offset with 
respect to an Ellipse with the same parameters, but by a different 
amount depending on the widgetset. This is rather annoying, if you want 
to show the full circle, as it's usual.


I'd like to avoid code like this:

{$IFDEF LCLQt}
Pie(PaintRect.Left, PaintRect.Top, W-2, H,
Integer(Round(MiddleX * (1 - Cos(Angle,
Integer(Round(MiddleY * (1 - Sin(Angle, MiddleX, 0);
{$ELSE}
   Pie(PaintRect.Left, PaintRect.Top, W-1, H-1,
   Integer(Round(MiddleX * (1 - Cos(Angle,
   Integer(Round(MiddleY * (1 - Sin(Angle, MiddleX, 0);
{$ENDIF}


What I'd like to do, if nobody else wants to take care of the matter, is 
to try to put things in order, and achieve a consistent and predictable 
behavior with all widgetsets, starting from GraphMath.


Most likely it happened a number of time what I've done recently: 
RadialPie wasn't working in a satisfactory way, and I've just taken 
advantage of the native Qt implementation, but maybe I've broken 
something else in the process, because Pie was just using RadialPie.


I'm not a fan of Delphi compatibility, but in that case, as there a 
number of arbitrary decisions to take, I'd take Delphi look as a 
guideline: a Pie, RadialPie, Arc, etc. should just look, with the same 
parameters, the same as it looks in Delphi.


Another thing that I'd like to do is to add to Canvas support for 
antialiasing, which provides a more pleasant look to lines, circles, 
ellipses etc. as expected by modern users, accustomed to modern graphic 
look.


Of course, unless someone else wants to do it.

Giuliano



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Fuzzy translations ignored

2014-09-18 Thread Howard Page-Clark

On 18/09/2014 17:41, Giuliano Colla wrote:


Canvas.RadalPie on GTK2 and Windows works only clockwise, but provides a
very poor image (more like a portion of an octagon that a portion of a
circle).
Counterclockwise it generates the image of my previous e-mail.


On Windows here, Pie (RadialPie) works counterclockwise well, using the 
following code example.
I'm sure if you added anitaliasing to improve the rendering quality this 
would be welcomed.


Howard

== code ==

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics;

type

  { TForm1 }

  TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
  private
  end;

  TPieRec = record
percentage: integer; // give pie segments as percentag of whole pie
color: TColor;
  end;

  TPieArray = array of TPieRec;

  procedure DrawPie(aCanvas: TCanvas; aCircleRect: TRect; pa: TPieArray);

var
  Form1: TForm1;

implementation

procedure DrawPie(aCanvas: TCanvas; aCircleRect: TRect; pa: TPieArray);
var
  angles: array of integer;
  lastAngle: integer = 0;
  i: Integer;
begin
  SetLength(angles, Length(pa));
  for i:=0 to High(pa) do begin
angles[i]:=trunc(pa[i].percentage * 57.60);
aCanvas.Brush.Color:=pa[i].color;
aCanvas.RadialPie(aCircleRect.Left, aCircleRect.Top, 
aCircleRect.Right, aCircleRect.Bottom,

  lastAngle, angles[i]);
Inc(lastAngle, angles[i]);
  end;
end;

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  example: TPieArray;
  circleRect: TRect;
begin
  circleRect:=Rect(10,10,110,110);
  SetLength(example, 4);
  example[0].percentage:=30; example[0].color:=clBlue;
  example[1].percentage:=10; example[1].color:=clRed;
  example[2].percentage:=20; example[2].color:=clYellow;
  example[3].percentage:=40; example[3].color:=clMoneyGreen;
  DrawPie(Canvas, circleRect, example);
end;

end.



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Fuzzy translations ignored

2014-09-18 Thread Giuliano Colla


Il 18/09/2014 19:16, Howard Page-Clark ha scritto:

On 18/09/2014 17:41, Giuliano Colla wrote:


Canvas.RadalPie on GTK2 and Windows works only clockwise, but provides a
very poor image (more like a portion of an octagon that a portion of a
circle).
Counterclockwise it generates the image of my previous e-mail.


On Windows here, Pie (RadialPie) works counterclockwise well, using 
the following code example.
I'm sure if you added anitaliasing to improve the rendering quality 
this would be welcomed.




Sorry, my mistake. I mixed up my clocks! It's the opposite: it works 
only counterclockwise.
To sort things: it works properly with positive values, it doesn't work 
(makes a mess) with negative values.

Please test again just changing the sign of your angles.

Giuliano


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Fuzzy translations ignored

2014-09-18 Thread Giuliano Colla


Il 18/09/2014 16:00, Bart ha scritto:


what do I need to do to make that work using Canvas.Pie
And the same Q for a fraction Y, starting of from section X?

Pie and RadialPie are quite easy to use.

RadialPie works with resolution of 1/16 degree (meaning that a full 
circle is 360*16 = 5760).
Takes as parameters the coordinates of the top left (x1,y1) and bottom 
right of the rectangle containing you ellipse (circle), the starting 
angle and the angular length (both in units of 1/16 degree).


Here are some fractions of code, just to see in practice how to use it:

  Total := FTranslated + FUntranslated + FFuzzy;

  Circle := 360 * 16;
  TranslatedAngle := FTranslated * Circle div Total;
  UntranslatedAngle   := FUntranslated * Circle div Total;
  FuzzyAngle  := FFuzzy * Circle div Total;
  ObsoleteAngle   := FObsolete * Circle div Total;

  if FuzzyAngle  0 then begin
Canvas.Brush.Color:= FFuzzyColor;
if FFuzzy = Total then
  Canvas.Ellipse(FPieRect)
else Canvas.RadialPie(FPieLeft,1,FPieRight,FPieHeight,0,FuzzyAngle);;
  end;

  if UntranslatedAngle  0 then begin
Canvas.Brush.Color:= FUnTranslColor;
if FUntranslated = Total then
  Canvas.Ellipse(FPieRect)
else 
Canvas.RadialPie(FPieLeft,1,FPieRight,FPieHeight,FuzzyAngle,UntranslatedAngle);;
  end;

And, for Pie, that's the Lazarus Help description:

/  procedure TCanvas.Pie(EllipseX1, EllipseY1, EllipseX2, EllipseY2,//
//  StartX, StartY, EndX, EndY: Integer); //

//  The pie is part of an ellipse between the points EllipseX1, 
EllipseY1, EllipseX2, EllipseY2.//
//  The values StartX, StartY and EndX, EndY represent the starting and 
ending//

//  radial-points between which the Bounding-Arc is drawn.//
/
and here a portion of code using it, where /PercentDone/ is a value 
between 0 and 100, /MiddleX/ and /MiddleY/ are the coordinates of the 
center, /W/ and/H /are Width and Height of the Paint Rectangle.


Angle := (Pi * ((PercentDone / 50.0) + 0.5));
Pie(PaintRect.Left, PaintRect.Top, W, H,
Integer(Round(MiddleX * (1 - Cos(Angle,
Integer(Round(MiddleY * (1 - Sin(Angle, MiddleX, 0);

I hope that it helps.

Giuliano



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Fuzzy translations ignored

2014-09-18 Thread Giuliano Colla


Il 18/09/2014 16:00, Bart ha scritto:


PS. You'll note the code for the GraphStat form is rather clumsy.
Currently I'm about to convert it by using a ListView with an
ImageList and create Bitmap's at runtime.
This will make anchoring/aligning that much easier.


Just for your reference (it's work in progress) I enclose a patch which 
includes what I've done. The Button in the main page does nothing, while 
the one added in the stats form shows a thumbnails form.
You should undefine COUNTER_CLOCKWISE in pothumbnails.pas to see 
reasonable images.
You'll see that a hint is shown with the relevant numbers. Clicking on a 
tumbnail just changes its size, but the idea would be to open the file 
in an editor.


Giuliano



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] PostMessage return value

2014-09-18 Thread Mark Morgan Lloyd

Michael Schnell wrote:

On 09/18/2014 12:10 PM, Mattias Gaertner wrote:

a Set is not an array of boolean
A set is an array (scientific English, not Pascal syntax) of bits 
(i.e. boolean values) supported by special operators.


I suggest calling it a vector (supported by special operators) since 
that sidesteps the question of whether it can be indexed.


/You/ might think that your command of scientific English is good 
enough, but in a public forum where there are plenty of users with less 
experience and poorer English using array in this context will cause 
problems.


--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Fuzzy translations ignored

2014-09-18 Thread Bart
I've got thiscode now (from your example).
It creates a bitmap.

After that I add the bitmap to an imagelist that is set as the
largeIcons properties of a TListView.

function TForm1.CreateBitmap2(AStat: TStat): TBitmap;
const
  FullCircle = 16 * 360;
var
  Bmp: TBitmap;
  Translated16Angle, UnTranslated16Angle, Fuzzy16Angle: Integer;
  PieRect: TRect;
begin
  Bmp := TBitmap.Create;
  Bmp.SetSize(BmpWH,BmpWH);
  //Bmp.Width := BmpWH;
  //Bmp.Height := BmpWH;
  //PieRect := Rect(1,1,BmpWH-1, BmpWH-1);
  PieRect := Rect(0,0,BmpWH, BmpWH);
  with Bmp do
  begin
//Draw background
Canvas.Brush.Color := clBack;
//Canvas.FillRect(0,0,BmpWH,BmpWH);
Canvas.FillRect(PieRect);
Canvas.Pen.Color := clBack;
//All angles in 16th of a degree
Translated16Angle := Round(AStat.FracTranslated *
FullCircle);// div Total;
UnTranslated16Angle   := Round(AStat.FracUntranslated *
FullCircle);// div Total;
Fuzzy16Angle  := Round(AStat.FracFuzzy * FullCircle);// div Total;

//writeln('TranslatedAngle   = ',Translated16Angle:3,'
[',Translated16Angle div 16,']');
//writeln('UnTranslatedAngle = ',UnTranslated16Angle:3,'
[',UnTranslated16Angle div 16,']');
//writeln('FuzzyAngle= ',Fuzzy16Angle:3,' [',Fuzzy16Angle
div 16,']');
//writeln('TotalAngle=
',Translated16Angle+UnTranslated16Angle+Fuzzy16Angle:3, '
[',(Translated16Angle+UnTranslated16Angle+Fuzzy16Angle) div 16,']');
//writeln('FullCircle= ',FullCircle,' [',FullCircle div 16,']');


if Translated16Angle  0 then
begin
  Canvas.Brush.Color:= clTrans;
  if Translated16Angle = FullCircle then
Canvas.Ellipse(PieRect)
  else

Canvas.RadialPie(PieRect.Left,PieRect.Top,PieRect.Right,PieRect.Bottom,0,Translated16Angle);;
end;

if UnTranslated16Angle  0 then
begin
  Canvas.Brush.Color:= clUnTrans;
  if UnTranslated16Angle = FullCircle then
Canvas.Ellipse(PieRect)
  else

Canvas.RadialPie(PieRect.Left,PieRect.Top,PieRect.Right,PieRect.Bottom,Translated16Angle,UnTranslated16Angle);;
end;

if Fuzzy16Angle  0 then
begin
  Canvas.Brush.Color:= clFuzzy;
  if Fuzzy16Angle = FullCircle then
Canvas.Ellipse(PieRect)
  else

Canvas.RadialPie(PieRect.Left,PieRect.Top,PieRect.Right,PieRect.Bottom,Translated16Angle+UnTranslated16Angle,Fuzzy16Angle);
end;
  end;
  Result := Bmp;
end;

I attached one of the resulting images.

Some antialiassing code would be very nice though!

Bart
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus