Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Thu, 19 Apr 2012 19:39:01 +0200 Graeme Geldenhuys wrote: > On 19 April 2012 19:29, Sven Barth wrote: > > > > The DestRect property/function of TImage that is the reason of this thread > > was moved to public and this property doesn't even exist in Delphi (like the > > OnPaint event for TImage)... > > > And as you should very well know, the core developers of the Lazarus > project do not live by the same rules as everybody else. They don't > need to justify any of the changes they make. > > And if you read this thread in detail, other developers raised concern > over Mattias's change - yet he still sees nothing wrong with it, so > his change will probably stay. I proposed a change and waited for comments. Marc pointed out that Delphi does not have that feature and it might be a can of worms. So I checked the can. Custom painting on a TImage was always possible, for example by overriding Paint. The OnPaint is just making it easier. TImage.OnPaint exists since many years and many people use it, so it is useful and should be kept. As discussed in the other thread, there is no big difference between public and protected. I didn't found any discussions about TImage problems, except for TPicture and the two Canvas. I didn't found a clue that DestRect will open a can of worms, so I made it public. Same happened with many of my concerns. Raising a concern is not a veto. > Different rules for different people. But this is not my project, so > my opinion is worth nothing here. I'll give this thread a rest now. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Reimar Grabowski schrieb: On Thu, 19 Apr 2012 10:08:23 +0200 Hans-Peter Diettrich wrote: The VCL and LCL contains many classes with a too restrictive design :-( First I don't care if the VCL is too restrictive or what Delphi in general does. This is not a Delphi list. Second if you think that some LCL classes are too restrictive you can always change them (as you have the source) and provide a patch. If your argument is reasonable the Lazarus developers will surely apply your patch. When I wanted to implement an alternative DragManager, I found this almost impossible outside of the Controls unit, due to very many references to protected members of TControl and TWinControl. Do you honestly believe that all these members will ever be made public, only for the sake of another DragManager implementation? Hint: look at the many patches I already supplied, and how many of them have been accepted :-( DoDi -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Martin Schreiber schrieb: May I repeat the idea of "friend units"? While designing a complex framework like Lazarus, fpGUI or MSEgui there constantly is the need to access low level functions from other classes. Now one has the options to write the whole framework in a single unit (ex. db.pas), to make most of the class elements public or to use local alias type definitions. This also requires to modify the existing classes. If every user can do that, encapsulation *really* has gone away :-( The introduction of "friend units" would be a simple solution. In "friend units" the protected class members would be visible. So if you build a framework and you know what you do, list the base units of the framework as friends of higher level units of the same framework. See "framework" as an special case of what a user wants to achieve. Where will you draw a boundary between *acceptable* and *unwanted* breaking of visibility, by using friends, class helpers or any other means? DoDi -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Thu, 19 Apr 2012 19:19:39 +0200 Graeme Geldenhuys wrote: > On 19 April 2012 14:39, Reimar Grabowski wrote: > > It is possible to access members that should be hidden but you must enable > > access to every protected/private member you want to access explicitly. > > And this is exactly what I have done in Object Pascal. Not quite. You have granted access to ALL protected members and not explicitly for single members. That's quite a difference. Either you fail to understand the difference between your 'hack' and what Java reflection does or you ignore it. Either way your way and the Java way are not 'exactly' the same. Nothing wrong with your code if it does what you need but your above statement is just not correct. R. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On 19 April 2012 19:29, Sven Barth wrote: > > The DestRect property/function of TImage that is the reason of this thread > was moved to public and this property doesn't even exist in Delphi (like the > OnPaint event for TImage)... And as you should very well know, the core developers of the Lazarus project do not live by the same rules as everybody else. They don't need to justify any of the changes they make. And if you read this thread in detail, other developers raised concern over Mattias's change - yet he still sees nothing wrong with it, so his change will probably stay. Different rules for different people. But this is not my project, so my opinion is worth nothing here. I'll give this thread a rest now. -- Regards, - Graeme - -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On 19.04.2012 19:18, Graeme Geldenhuys wrote: On 19 April 2012 14:06, Reimar Grabowski wrote: First I don't care if the VCL is too restrictive or what Delphi in general does. This is not a Delphi list. Second if you think that some LCL classes are too restrictive you can always change them (as you have the source) and provide a patch. If your argument is reasonable the Lazarus developers will surely apply your patch. Many years ago, I thought the same way as you do. Unfortunately it was made clear to me that the LCL's goal is to be a Delphi VCL clone! Delphi dictates what LCL is allowed to do - simple as that. Patches to the contrary will not be accepted. Sad but true - hence I moved on to greener pastures. The DestRect property/function of TImage that is the reason of this thread was moved to public and this property doesn't even exist in Delphi (like the OnPaint event for TImage)... Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On 19 April 2012 14:39, Reimar Grabowski wrote: > It is possible to access members that should be hidden but you must enable > access to every protected/private member you want to access explicitly. And this is exactly what I have done in Object Pascal. I see to problem with what I have done. But yes, everybody is entitled to their own opinion. -- Regards, - Graeme - ___ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On 19 April 2012 14:06, Reimar Grabowski wrote: > First I don't care if the VCL is too restrictive or what Delphi in general > does. This is not a Delphi list. > Second if you think that some LCL classes are too restrictive you can always > change them (as you have the source) and provide a patch. If your argument is > reasonable the Lazarus developers will surely apply your patch. Many years ago, I thought the same way as you do. Unfortunately it was made clear to me that the LCL's goal is to be a Delphi VCL clone! Delphi dictates what LCL is allowed to do - simple as that. Patches to the contrary will not be accepted. Sad but true - hence I moved on to greener pastures. -- Regards, - Graeme - ___ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Thu, 19 Apr 2012 10:21:12 +0200 Graeme Geldenhuys wrote: > C# in .NET > and Java etc all have support for what is now know as Reflection. They > have full access to everything defined in a class. At least in Java reflection does not grant you access to everything defined in a class in the general case. And its primary purpose is not to access members that are protected/private. You are correct that it can be done using reflection but you must be very explicit about it. In general reflection does not change standard Java visibility rules. Normally you use getField/getMethod which only grant you access to visible members. If you need more information you call getDeclaredField/getDeclaredMethod which gives you information even about protected/private members but does not enable you to access them. Only when you call setAccessible(true) on this member you disable Javas access checks for this member. So in general reflection does not violate OOP principles and it is used like this most of the time for example to dynamicaly instantiate classes by name. It is possible to access members that should be hidden but you must enable access to every protected/private member you want to access explicitly. You are still working outside of OOP principles if you do this and are forced to jump through some hoops before Java grants you access to what should be hidden. R. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Thu, 19 Apr 2012 10:08:23 +0200 Hans-Peter Diettrich wrote: > The VCL and LCL contains many classes with a too restrictive design :-( First I don't care if the VCL is too restrictive or what Delphi in general does. This is not a Delphi list. Second if you think that some LCL classes are too restrictive you can always change them (as you have the source) and provide a patch. If your argument is reasonable the Lazarus developers will surely apply your patch. R. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
michael.vancann...@wisa.be schrieb: type // Friend class to get access to protected methods THackCustomEdit = class(TCustomEdit); The Hack says it all. Here you are working outside regular OOP rules. It's only working around OPL deficiencies, for which e.g. C++ offers different OOP means (friend...). Without the introduction of means, upon which above hack is based, the OPL (and VCL/LCL) would be much less useful. DoDi -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Alberto Narduzzi schrieb: But often (depending on the compiler) the mere declaration of an empty derived class allows to access protected members of the base class. What does depending on the compiler mean? The compiler is obviously FPC. If it is really true that you can access protected members in that way (like Svens message suggests) I consider this a bug. Like Mattias said, protected is of no real use in that case and we can just declare all non private members public. I guess this must be considered a bug. It's not a bug, it's a feature (of Delphi ;-) You can indeed access protected members of parent classes, but only from within the (your derived) class members themselves, not from the outer world. At least this I believe to e the meaning of having protected (me and my friends only), together with public (everybody) and private (me and only me). Apropos "friends": the C++ visibility model is different from the Delphi model. In Delphi classes the visibility applies to *unit level*, i.e. *all* code in the same unit can access protected (and private?) members of the declared classes. This behaviour can be modified with the later added "strict private/protected" visibility, which applies to *class* level. Similar to C++, where "friend" classes can be added to a class declaration, a dummy declaration of a derived class makes all protected members of the base class visible in the same *unit*. Similar but not identical. DoDi -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Reimar Grabowski schrieb: On Wed, 18 Apr 2012 09:58:56 +0200 Hans-Peter Diettrich wrote: But often (depending on the compiler) the mere declaration of an empty derived class allows to access protected members of the base class. What does depending on the compiler mean? The compiler is obviously FPC. The implementation can vary in Delphi versions, whereupon it's unclear what FPC implements in which version. DoDi -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Reimar Grabowski schrieb: On Wed, 18 Apr 2012 09:50:16 +0200 Hans-Peter Diettrich wrote: It should be mentioned that class helpers do not solve all problems, Not being able to access a member that you should not access is not a problem. It's what visibility in OOP is ment to do. It is by design that you cannot access that member. Even designers are humans, and they can err. The VCL and LCL contains many classes with a too restrictive design :-( DoDi -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Thu, 19 Apr 2012 10:46:20 +0200 Marc Weustink wrote: >[...] > >>> TImage has a published OnPaint event. Painting some overlays makes > >>> sense. And for this you need to know where the image is on the canvas. > >> > >> Who has added this ? Delphi has no OnPaint event. > >> > >> Yes, if we have an event, we should provide a way to paint. > >> But to me this is a can of worms, since stretching is handled internally > >> while the user event draws on the canvas, independent of the stretching. > >> If you ask me, I wouldn't have added it. > > > > I don't see many worms in the can, so I made it public. > > It's a useful feature that costs us not much. > > On scaled images there is no way to tell which source pixel corresponds > to a destination pixel. So? Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Mattias Gaertner wrote: On Tue, 17 Apr 2012 17:06:47 +0200 Marc Weustink wrote: Mattias Gaertner wrote: On Tue, 17 Apr 2012 12:12:21 +0200 Marc Weustink wrote: Mattias Gaertner wrote: Reimar Grabowski hat am 16. April 2012 um 16:42 geschrieben: > Hi, > > I load a TLazIntfImage from disk, manipulate it and show it on my form in a TImage. Center, Proportional and Stretch properties of the TImage are set to true. > Now I want to draw some overlays onto it (drawing to the canvas in the OnPaint event). Therefor I obviously need the origin and dimensions of the loaded image in 'canvas space', but I did not find a way to retrieve this information. Do I have to calculate them myself or can the TImage give me the needed information? The image is painted to the area defined by the protected method DestRect. Maybe this can be made public. At the moment you have to descend your own TImage class to access it or write a hack class (e.g. via a class helper). TImage is not meant to draw to. If you want to custom paint your image, use a TPaintbox A TImage is for display only. TImage has a published OnPaint event. Painting some overlays makes sense. And for this you need to know where the image is on the canvas. Who has added this ? Delphi has no OnPaint event. Yes, if we have an event, we should provide a way to paint. But to me this is a can of worms, since stretching is handled internally while the user event draws on the canvas, independent of the stretching. If you ask me, I wouldn't have added it. I don't see many worms in the can, so I made it public. It's a useful feature that costs us not much. On scaled images there is no way to tell which source pixel corresponds to a destination pixel. Marc -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Thu, 19 Apr 2012, Martin Schreiber wrote: On Thursday 19 April 2012 09:52:30 michael.vancann...@wisa.be wrote: On Thu, 19 Apr 2012, Graeme Geldenhuys wrote: On 19 April 2012 00:04, Alberto Narduzzi wrote: An interface to a class (or its concept, anyway) is there for a reason. And you should adhere to. I may also say that if you need to access a protected, or private for what is worth, member of a (library...) class, then you should revise your code... because either you're using the wrong class, or your problem can be solved in a different, possibly more elegant, and surely more OO compliant way ;-) I totally disagree... :) type // Friend class to get access to protected methods THackCustomEdit = class(TCustomEdit); The Hack says it all. Here you are working outside regular OOP rules. The correct way would have been an implementation for each descendent of TCustomEdit. You just took a shortcut. Nothing wrong with that by itself, but basing an argument about general OOP rules on a shortcut implementation is incorrect reasoning. In a system with stricter rules, you would have had to solve it differently. May I repeat the idea of "friend units"? You can already use class helpers. Michael. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Thursday 19 April 2012 09:52:30 michael.vancann...@wisa.be wrote: > On Thu, 19 Apr 2012, Graeme Geldenhuys wrote: > > On 19 April 2012 00:04, Alberto Narduzzi wrote: > >> An interface to a class (or its concept, anyway) is there for a reason. > >> And you should adhere to. I may also say that if you need to access a > >> protected, or private for what is worth, member of a (library...) class, > >> then you should revise your code... because either you're using the > >> wrong class, or your problem can be solved in a different, possibly more > >> elegant, and surely more OO compliant way ;-) > > > > I totally disagree... :) > > type > > // Friend class to get access to protected methods > > THackCustomEdit = class(TCustomEdit); > > The Hack says it all. Here you are working outside regular OOP rules. > > The correct way would have been an implementation for each descendent of > TCustomEdit. > > You just took a shortcut. Nothing wrong with that by itself, but basing an > argument about general OOP rules on a shortcut implementation is incorrect > reasoning. > > In a system with stricter rules, you would have had to solve it > differently. > May I repeat the idea of "friend units"? While designing a complex framework like Lazarus, fpGUI or MSEgui there constantly is the need to access low level functions from other classes. Now one has the options to write the whole framework in a single unit (ex. db.pas), to make most of the class elements public or to use local alias type definitions. For me public class elements should be "user suitable" and safe. I don't think it is a good idea to place elements the user of the framework normally should not touch to public. And I don't think that in a project of that dimension it is possible to maintain a completely clean OOP structure with an acceptable effort. The introduction of "friend units" would be a simple solution. In "friend units" the protected class members would be visible. So if you build a framework and you know what you do, list the base units of the framework as friends of higher level units of the same framework. Users of the framework don't need friend units and can use the public class elements in a save manner. Martin -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On 19 April 2012 09:52, wrote: > > The Hack says it all. The "Hack" part is just a name. I could very well have named that TCustomEditFriend. > Here you are working outside regular OOP rules. Saying that, then how does the new Delphi/FPC "friend class" language feature fit into that statement of yours. Or how does Delphi's new RTTI which can access private and protected class data fit into this. Delphi is not the only language with that "RTTI" feature. C# in .NET and Java etc all have support for what is now know as Reflection. They have full access to everything defined in a class. If there wasn't a need for sometimes "breaking the class visibility rules", the RTTI or Reflection would never have been implemented in the various programming languages. > The correct way would have been an implementation for each descendent of > TCustomEdit. Have you got any idea how many TCustomEdit descendants there are? Delphi supplied ones and 3rd party ones? All I can say is, there are a lot, and having to modify the tiOPF framework for every new 3rd party or delphi component is nuts. There goes the rule of OOP code reuse. And my example applies to all standard components and their descendants, not just TCustomEdit. As you might know, I am a big proponent of OOP, but I would be lying to myself if I said OOP is perfect. There are valid cases where OOP rules need to be bent ever so slightly. Reflection, the new Delphi RTTI and the concept of "friend classes" are all proof of this. Also, as I mentioned, this is one example. There are many other cases too. Maybe they will make even better arguments, but we would never know. -- Regards, - Graeme - ___ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Thu, 19 Apr 2012, Graeme Geldenhuys wrote: On 19 April 2012 00:04, Alberto Narduzzi wrote: An interface to a class (or its concept, anyway) is there for a reason. And you should adhere to. I may also say that if you need to access a protected, or private for what is worth, member of a (library...) class, then you should revise your code... because either you're using the wrong class, or your problem can be solved in a different, possibly more elegant, and surely more OO compliant way ;-) I totally disagree... :) type // Friend class to get access to protected methods THackCustomEdit = class(TCustomEdit); The Hack says it all. Here you are working outside regular OOP rules. The correct way would have been an implementation for each descendent of TCustomEdit. You just took a shortcut. Nothing wrong with that by itself, but basing an argument about general OOP rules on a shortcut implementation is incorrect reasoning. In a system with stricter rules, you would have had to solve it differently. Michael. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On 19 April 2012 00:04, Alberto Narduzzi wrote: > > An interface to a class (or its concept, anyway) is there for a reason. And > you should adhere to. I may also say that if you need to access a protected, > or private for what is worth, member of a (library...) class, then you > should revise your code... because either you're using the wrong class, or > your problem can be solved in a different, possibly more elegant, and surely > more OO compliant way ;-) I totally disagree... :) There are valid use cases where developers need access to protected methods. Here is a case in point (and I have many other examples too). I implemented the Model-GUI-Mediator (MGM) design pattern to make any standard components (non-db) "object aware" for the tiOPF persistence framework. MGM allows me to bind object data to any standard components, and have two-way updating, without the need to create even more custom or descendant GUI components (this replaces the need for DB-aware components). Some of the mediators are implemented in a generic fashion, using base classes of GUI components so that that same mediator could be used for any descendant classes of that component (view). eg: Below is some code for a TCustomEdit mediator. This mediators applies to any TCustomEdit descendants - and there are many of those. In the case below, we needed access to the ReadOnly property of TCustomEdit, but it was defined as protected (which was the correct thing to do for TCustomXXX components). In the code below, View is the component instance we are working with and is defined as TCustomEdit type - thus and can hold a reference to any TCustomEdit descendant. type // Friend class to get access to protected methods THackCustomEdit = class(TCustomEdit); class function TtiCustomEditMediatorView.ComponentClass: TClass; begin Result := TCustomEdit; end; function TtiCustomEditMediatorView.GetCurrentControlColor: TColor; begin if THackCustomEdit(View).ReadOnly then result := ColorToRGB(ControlReadOnlyColor) else result := inherited GetCurrentControlColor; end; There is NO other way to implement this, except to create a mediator for each and every TCustomEdit descendants. Implementing the alternative would have been lots and lots of code duplication, and new mediators for each new TCustomEdit descendant that arrives in the market. Using the "friend class hack" means MUCH less code, and things still work perfectly. -- Regards, - Graeme - ___ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On 18 April 2012 23:36, Reimar Grabowski wrote: > What does depending on the compiler mean? The compiler is obviously FPC. > If it is really true that you can access protected members in that way (like > Svens message suggests) I consider this a bug. > Like Mattias said, protected is of no real use in that case and we can just > declare all non private members public. Framework and Component developers cannot foresee all possible use-cases. So they might have thought protected is fine. I have numerous cases where I had to use the "class helper hack" (before the class helper or friend class features was introduced into FPC or Delphi). This doesn't mean protected is of no use any more, or that all protected methods should now become public, but it is often the case where one method needs to be accessed. If you really want concrete examples, I can search my code for where I use the "class helper hack". -- Regards, - Graeme - ___ fpGUI - a cross-platform Free Pascal GUI toolkit http://fpgui.sourceforge.net -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
It should be mentioned that class helpers do not solve all problems, Not being able to access a member that you should not access is not a problem. It's what visibility in OOP is ment to do. It is by design that you cannot access that member. Having an official way to do this is IMHO bad. People will use it. And not just in special situations. They will use it as integral part of their software design and that is not a good idea. totally agree. An interface to a class (or its concept, anyway) is there for a reason. And you should adhere to. I may also say that if you need to access a protected, or private for what is worth, member of a (library...) class, then you should revise your code... because either you're using the wrong class, or your problem can be solved in a different, possibly more elegant, and surely more OO compliant way ;-) Cheers, A. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Wed, 18 Apr 2012 19:52:46 +0200 Mattias Gaertner wrote: > I don't see many worms in the can, so I made it public. > It's a useful feature that costs us not much. Thanks, much better than this class helper stuff. R. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
But often (depending on the compiler) the mere declaration of an empty derived class allows to access protected members of the base class. What does depending on the compiler mean? The compiler is obviously FPC. If it is really true that you can access protected members in that way (like Svens message suggests) I consider this a bug. Like Mattias said, protected is of no real use in that case and we can just declare all non private members public. I guess this must be considered a bug. You can indeed access protected members of parent classes, but only from within the (your derived) class members themselves, not from the outer world. At least this I believe to e the meaning of having protected (me and my friends only), together with public (everybody) and private (me and only me). Let alone published, there for IDE designers only. Cheers, A. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Wed, 18 Apr 2012 09:50:16 +0200 Hans-Peter Diettrich wrote: > It should be mentioned that class helpers do not solve all problems, Not being able to access a member that you should not access is not a problem. It's what visibility in OOP is ment to do. It is by design that you cannot access that member. Having an official way to do this is IMHO bad. People will use it. And not just in special situations. They will use it as integral part of their software design and that is not a good idea. R. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Wed, 18 Apr 2012 09:58:56 +0200 Hans-Peter Diettrich wrote: > But often (depending on the compiler) the mere declaration > of an empty derived class allows to access protected members of the base > class. What does depending on the compiler mean? The compiler is obviously FPC. If it is really true that you can access protected members in that way (like Svens message suggests) I consider this a bug. Like Mattias said, protected is of no real use in that case and we can just declare all non private members public. R. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Tue, 17 Apr 2012 17:06:47 +0200 Marc Weustink wrote: > Mattias Gaertner wrote: > > On Tue, 17 Apr 2012 12:12:21 +0200 > > Marc Weustink wrote: > > > >> Mattias Gaertner wrote: > >>> > >>> Reimar Grabowski hat am 16. April 2012 um 16:42 > >>> geschrieben: > >>> > >>> > Hi, > >>> > > >>> > I load a TLazIntfImage from disk, manipulate it and show it on my > >>> form in a TImage. Center, Proportional and Stretch properties of the > >>> TImage are set to true. > >>> > Now I want to draw some overlays onto it (drawing to the canvas in > >>> the OnPaint event). Therefor I obviously need the origin and dimensions > >>> of the loaded image in 'canvas space', but I did not find a way to > >>> retrieve this information. Do I have to calculate them myself or can the > >>> TImage give me the needed information? > >>> > >>> The image is painted to the area defined by the protected method DestRect. > >>> > >>> Maybe this can be made public. > >>> > >>> At the moment you have to descend your own TImage class to access it or > >>> write a hack class (e.g. via a class helper). > >> > >> TImage is not meant to draw to. If you want to custom paint your image, > >> use a TPaintbox > >> > >> A TImage is for display only. > > > > TImage has a published OnPaint event. Painting some overlays makes > > sense. And for this you need to know where the image is on the canvas. > > Who has added this ? Delphi has no OnPaint event. > > Yes, if we have an event, we should provide a way to paint. > But to me this is a can of worms, since stretching is handled internally > while the user event draws on the canvas, independent of the stretching. > If you ask me, I wouldn't have added it. I don't see many worms in the can, so I made it public. It's a useful feature that costs us not much. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Am 17.04.2012 22:32, schrieb Reimar Grabowski: On Tue, 17 Apr 2012 22:19:45 +0200 Sven Barth wrote: type TMyHackImage = class(TImage) public function DestRect: TRect; end; var MyImage: TImage; r: TRect; begin // let's suppose that MyImage contains a TImage instance r := TMyHackImage(MyImage).DestRect end; How should that work? What does the DestRec function look like? IMHO to access DestRec TMyHackImage must be derived from TCustomImage and in that case the cast won't work. Yes, sorry. I've now tested the following example which is different from your original problem, but it illustrates the hacky mechanism: === source begin === program hacktest; {$mode objfpc} uses Classes; type TMyStrings = class(TStringList) end; var s: TStringList; begin s := TStringList.Create; s.Add('Test'); Writeln(TMyStrings(s).GetCount); // "GetCount" is protected in "TStringList" end. === source end === Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Reimar Grabowski schrieb: On Tue, 17 Apr 2012 22:19:45 +0200 Sven Barth wrote: type TMyHackImage = class(TImage) public function DestRect: TRect; end; var MyImage: TImage; r: TRect; begin // let's suppose that MyImage contains a TImage instance r := TMyHackImage(MyImage).DestRect end; How should that work? What does the DestRec function look like? You're right, above code should not work. The DestRect function has to be omitted from above declaration, so that the DestRect of the base class is used. The elevation of visibility only works for *properties*, i.e. public property DestRect; should work. But often (depending on the compiler) the mere declaration of an empty derived class allows to access protected members of the base class. DoDi -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Mattias Gaertner schrieb: On Tue, 17 Apr 2012 19:46:08 +0200 Sven Barth wrote: [...] Well... class helpers are at least an officially supported hackish approach unlike other forms of making a protected member visible. I wonder what protected is still good for when you can use class helpers to access protected members from anywhere. The VCL design often hides properties (as protected), which should be accessible by user code, under certain circumstances. The classic workaround for such cases was the declaration of a dummy class, derived from an existing VCL class, what allows to access the protected members of the *base* class in that unit. Such situations now can be handled by reusable class helpers, with better encapsulation of the added features; they can allow access to *selected* protected members of the class, still hiding other protected members. The downside of the Delphi model: it's hard to determine, which class helper is *currently* used in some code, because the unit order in the uses clause(s) is involved hereby. That's why I would add my class helpers to every unit in which they are used, to eliminate that uncertainty. DoDi -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Reimar Grabowski schrieb: On Tue, 17 Apr 2012 19:46:08 +0200 Sven Barth wrote: Well... class helpers are at least an officially supported hackish approach unlike other forms of making a protected member visible. Deriving my own class is certainly more work (as in more to type) but it is officially supported and I fail to see the hackish part. That's okay when you *can* create instances of your classes. But often a user has to deal with an object of an *predefined* type, so that deriving a class; which is never instantiated; is of no use. And that's where the hack enters the scene: The mere declaration of a derived class, or a typecast of a given object into a derived class, allows the user to access members which are not accessible in the actual (dynamic) type of that object. It should be mentioned that class helpers do not solve all problems, e.g. when a TStrings parameter is passed to a subroutine, in which it's *assumed* that it actually is of type TStringList. Then a typecast of that parameter is required, before a class helper for TStringList can be used with it. Failing to use an *checked* typecast here, what's common practice , may result in any kind of trouble. DoDi -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Tue, 17 Apr 2012 22:19:45 +0200 Sven Barth wrote: > type >TMyHackImage = class(TImage) >public > function DestRect: TRect; >end; > > var >MyImage: TImage; >r: TRect; > begin >// let's suppose that MyImage contains a TImage instance >r := TMyHackImage(MyImage).DestRect > end; How should that work? What does the DestRec function look like? IMHO to access DestRec TMyHackImage must be derived from TCustomImage and in that case the cast won't work. R. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On 17.04.2012 20:22, Reimar Grabowski wrote: On Tue, 17 Apr 2012 19:46:08 +0200 Sven Barth wrote: Well... class helpers are at least an officially supported hackish approach unlike other forms of making a protected member visible. Deriving my own class is certainly more work (as in more to type) but it is officially supported and I fail to see the hackish part. If you are able to derive it, like in the case of TImage, that's indeed the best solution. But there are cases in code where you have some kind of "hack class" that makes a protected member or (yes, I've seen such) even a private one accessible (by utilizing the memory layout of the class) without making an instance of that class. For your example this would be (I don't know whether this exact example would work, but I've seen similar working ones): type TMyHackImage = class(TImage) public function DestRect: TRect; end; var MyImage: TImage; r: TRect; begin // let's suppose that MyImage contains a TImage instance r := TMyHackImage(MyImage).DestRect end; Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Tue, 17 Apr 2012 19:46:08 +0200 Sven Barth wrote: > Well... class helpers are at least an officially supported hackish > approach unlike other forms of making a protected member visible. Deriving my own class is certainly more work (as in more to type) but it is officially supported and I fail to see the hackish part. R. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Tue, 17 Apr 2012 19:46:08 +0200 Sven Barth wrote: >[...] > Well... class helpers are at least an officially supported hackish > approach unlike other forms of making a protected member visible. I wonder what protected is still good for when you can use class helpers to access protected members from anywhere. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On 17.04.2012 16:26, Reimar Grabowski wrote: On Tue, 17 Apr 2012 12:26:13 +0200 Sven Barth wrote: I personally don't consider them strange, but that might be, because I implemented them in FPC ^^ Considering that they were a hackish workaround to marry Delphis VCL and .NET and Delphi users were warned not to use them because they should not be used outside the VCL now seeing them in FPC is strange. Yes, they were described as "only used inside the VCL", but if I consider that class helpers are used without big care on one of Germany's biggest Delphi forums (Delphi-PRAXiS), I've come to the conclusion that they are a rather nice feature to have and once I have the time (and have stabilized the generics and worked on my Native NT port) I'll revisit the helpers to improve them more (e.g. helpers for objects and interfaces, having multiple helpers active for one type and maybe even support for helpers for primitive types...). So I personally consider helpers a fully fledged feature of FPC. I don't care whether they are "don't use" in Delphi or not. In FPC you can consider them as "use them if you see a need for them", the same as for the old TP style objects, operator overloading, generics, etc. Their main purpose should be considered to add functionality to classes/records without inheriting from them (which might not always be possible, because records can not inherit or you have e.g. the class hierarchy of the LCL which you can't trivially change). That's the information I gathered from reading different articles about them but there were also problems mentioned because class helpers can hide each other (only one may be active). So I'd rather not use them in code which is meant for other people to use as they may cause problems by just adding a unit (2 helpers for the same type in 2 different units). Correct me if my assumptions are wrong. Yes, helpers currently have that restriction, but as I wrote above I'd like to remove that (at least optionally by using a modeswitch). For the task at hand they work, nonetheless they feel quite hackish to me. Well... class helpers are at least an officially supported hackish approach unlike other forms of making a protected member visible. Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Mattias Gaertner wrote: On Tue, 17 Apr 2012 12:12:21 +0200 Marc Weustink wrote: Mattias Gaertner wrote: Reimar Grabowski hat am 16. April 2012 um 16:42 geschrieben: > Hi, > > I load a TLazIntfImage from disk, manipulate it and show it on my form in a TImage. Center, Proportional and Stretch properties of the TImage are set to true. > Now I want to draw some overlays onto it (drawing to the canvas in the OnPaint event). Therefor I obviously need the origin and dimensions of the loaded image in 'canvas space', but I did not find a way to retrieve this information. Do I have to calculate them myself or can the TImage give me the needed information? The image is painted to the area defined by the protected method DestRect. Maybe this can be made public. At the moment you have to descend your own TImage class to access it or write a hack class (e.g. via a class helper). TImage is not meant to draw to. If you want to custom paint your image, use a TPaintbox A TImage is for display only. TImage has a published OnPaint event. Painting some overlays makes sense. And for this you need to know where the image is on the canvas. Who has added this ? Delphi has no OnPaint event. Yes, if we have an event, we should provide a way to paint. But to me this is a can of worms, since stretching is handled internally while the user event draws on the canvas, independent of the stretching. If you ask me, I wouldn't have added it. Marc -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Tue, 17 Apr 2012 12:27:09 +0200 Mattias Gaertner wrote: > On Tue, 17 Apr 2012 12:12:21 +0200 > Marc Weustink wrote: > > TImage is not meant to draw to. If you want to custom paint your image, > > use a TPaintbox > > > > A TImage is for display only. > > TImage has a published OnPaint event. Painting some overlays makes > sense. And for this you need to know where the image is on the canvas. This. And to me it looks like this method is officially supported by Lazarus as you can see here: http://wiki.freepascal.org/Developing_with_Graphics#Painting_on_the_volatile_visual_area_of_the_TImage R. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Tue, 17 Apr 2012 12:26:13 +0200 Sven Barth wrote: > I personally don't consider them strange, but that might be, because I > implemented them in FPC ^^ Considering that they were a hackish workaround to marry Delphis VCL and .NET and Delphi users were warned not to use them because they should not be used outside the VCL now seeing them in FPC is strange. > Their main purpose should be considered to add functionality to > classes/records without inheriting from them (which might not always be > possible, because records can not inherit or you have e.g. the class > hierarchy of the LCL which you can't trivially change). That's the information I gathered from reading different articles about them but there were also problems mentioned because class helpers can hide each other (only one may be active). So I'd rather not use them in code which is meant for other people to use as they may cause problems by just adding a unit (2 helpers for the same type in 2 different units). Correct me if my assumptions are wrong. For the task at hand they work, nonetheless they feel quite hackish to me. R. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Tue, 17 Apr 2012 12:12:21 +0200 Marc Weustink wrote: > Mattias Gaertner wrote: > > > > Reimar Grabowski hat am 16. April 2012 um 16:42 > > geschrieben: > > > > > Hi, > > > > > > I load a TLazIntfImage from disk, manipulate it and show it on my > > form in a TImage. Center, Proportional and Stretch properties of the > > TImage are set to true. > > > Now I want to draw some overlays onto it (drawing to the canvas in > > the OnPaint event). Therefor I obviously need the origin and dimensions > > of the loaded image in 'canvas space', but I did not find a way to > > retrieve this information. Do I have to calculate them myself or can the > > TImage give me the needed information? > > > > The image is painted to the area defined by the protected method DestRect. > > > > Maybe this can be made public. > > > > At the moment you have to descend your own TImage class to access it or > > write a hack class (e.g. via a class helper). > > TImage is not meant to draw to. If you want to custom paint your image, > use a TPaintbox > > A TImage is for display only. TImage has a published OnPaint event. Painting some overlays makes sense. And for this you need to know where the image is on the canvas. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Am 17.04.2012 03:17, schrieb Reimar Grabowski: At the moment you have to descend your own TImage class to access it or write a hack class (e.g. via a class helper). Class helpers are a new concept to me and IMHO quite a strange one. I can understand why you call this a hack but at least it works. Thanks. It looks like they aren't fully supported by the code tools with regard to code completion. I personally don't consider them strange, but that might be, because I implemented them in FPC ^^ Their main purpose should be considered to add functionality to classes/records without inheriting from them (which might not always be possible, because records can not inherit or you have e.g. the class hierarchy of the LCL which you can't trivially change). Regards, Sven -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Mattias Gaertner wrote: Reimar Grabowski hat am 16. April 2012 um 16:42 geschrieben: > Hi, > > I load a TLazIntfImage from disk, manipulate it and show it on my form in a TImage. Center, Proportional and Stretch properties of the TImage are set to true. > Now I want to draw some overlays onto it (drawing to the canvas in the OnPaint event). Therefor I obviously need the origin and dimensions of the loaded image in 'canvas space', but I did not find a way to retrieve this information. Do I have to calculate them myself or can the TImage give me the needed information? The image is painted to the area defined by the protected method DestRect. Maybe this can be made public. At the moment you have to descend your own TImage class to access it or write a hack class (e.g. via a class helper). TImage is not meant to draw to. If you want to custom paint your image, use a TPaintbox A TImage is for display only. Marc -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
On Mon, 16 Apr 2012 18:12:32 +0200 (CEST) Mattias Gaertner wrote: > The image is painted to the area defined by the protected method DestRect. > Maybe this can be made public. Sounds like a good idea to me, as it is very useful information. > At the moment you have to descend your own TImage class to access it or write > a > hack class (e.g. via a class helper). Class helpers are a new concept to me and IMHO quite a strange one. I can understand why you call this a hack but at least it works. Thanks. It looks like they aren't fully supported by the code tools with regard to code completion. R. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Re: [Lazarus] TImage - Getting image properties in 'canvas space'
Reimar Grabowski hat am 16. April 2012 um 16:42 geschrieben: > Hi, > > I load a TLazIntfImage from disk, manipulate it and show it on my form in a > TImage. Center, Proportional and Stretch properties of the TImage are set to > true. > Now I want to draw some overlays onto it (drawing to the canvas in the OnPaint > event). Therefor I obviously need the origin and dimensions of the loaded > image in 'canvas space', but I did not find a way to retrieve this > information. Do I have to calculate them myself or can the TImage give me the > needed information? The image is painted to the area defined by the protected method DestRect. Maybe this can be made public. At the moment you have to descend your own TImage class to access it or write a hack class (e.g. via a class helper). Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
[Lazarus] TImage - Getting image properties in 'canvas space'
Hi, I load a TLazIntfImage from disk, manipulate it and show it on my form in a TImage. Center, Proportional and Stretch properties of the TImage are set to true. Now I want to draw some overlays onto it (drawing to the canvas in the OnPaint event). Therefor I obviously need the origin and dimensions of the loaded image in 'canvas space', but I did not find a way to retrieve this information. Do I have to calculate them myself or can the TImage give me the needed information? Greetings R. -- ___ Lazarus mailing list Lazarus@lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus