Re: [Lazarus] PostMessage return value
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
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 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
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
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
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
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
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
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
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
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
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
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
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
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 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
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 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
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
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
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
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
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
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
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
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
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
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
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