Hi Alex, Igor and others,
this discussion is interesting to follow. GUI frameworks are hard... Le 03/04/2016 16:58, Aliaksei Syrel a écrit : > And you lost me here.. That is complete nonsense.. from any perspective. > Can i unsee this code, please? :) > > > If I would say that we have defaultShape method and it can be overridden as: > > defaultShape > ^ BlShape new > fillPaint: (BlColorPaint new color: (Color yellow)); > path: BlRectanglePath new > > would it make you happy? If you don't tell me there is a cost for creating a shape in athens, I'll wonder if you're not asking me to optimise by caching a shape; and that is over-engineering. > > .. to me it feels like: okay, what we need to do, to prevent > overrides of our beloved default #drawOn: method. > > You are wrong concerning preventing to override drawOn :) I wonder if that "shape" thing is not something like the difference between Roassal and Trachel: RT vs TR objects. And, yes, for me, the RT/TR hierarchy is a reimplementation of objects over Athens, and the end result is that it is easy to compose existing objects in Roassal and hard to extend it. > Don't forget that there was a customer *requirement* concerning bloc: > > Can we change how morph looks on fly? Can we create a rectangle morph > and change it's shape from rectangle to circle? Because it can nicely > show while presenting that *Pharo is live system*. I'm pretty sure Stef > said it once ago. If that is your requirement, then this is bad. It's a demo requirement with costly consequences. Does it apply in real life in a system where recreating a complete Morph is so cheap (witness FastTable!)? I'd say no. > Do you see how bloc story can nicely be told: > > We have basic UI elements and each element has shape that can be > easily changed live. Shape is defined by a path which can be filled > or stroked using a paint. Complex elements can be created as > composition of elements with basic shapes (rectangle, circle). > > > Isn't it beautiful? :) It is, but it tells of complexity: UI behavior composition (not only graphics). Extending elements may also require extending shapes and understanding how they interact and compose. Regards, Thierry |
In reply to this post by Aliaksei Syrel
On 3 April 2016 at 19:23, Aliaksei Syrel <[hidden email]> wrote:
I would not say it like that. WIth decent effort you can do it. But the right question here: do you really need it? You missing some features for shapes? Good.. make new one(s) , just teach them how to draw themselves on Athens canvas and you done. For instance, for using shape in UI test it missing, #containsPoint: behavior. And for clipping, it missing clipOn: aCanvas during: aBlock behavior. So, you can choose to either extend basic protocol in Athens by implementing this feature(s) for all existing shapes, or introduce own shapes, polymorphic with AthensShape(s) but in addition implementing these protocols. Then you can use same shape for drawing, clipping and UI testing. Job done. You basically missing those two methods and you are done. And instead you inventing something that not only solves the problem, but puts a lot of restrictions on what you can draw using Block and how.
Well, a root morph cannot put any assumptions how his subclasses would want to draw themselves.. So, really, no assumptions means empty method. Sounds good to me. Well, it is empty, and just server as a placeholder indicating a protocol and a point of customization, nothing else. (Stef will most probably force you to put a nice comment there ;)
That's what i proposing. What i think i already wrote in this thread :) It is up to you to accept or reject the idea. Or propose something even better and simpler. Or by any other participants of discussion. And why you surrender so fast? What if i am wrong? What is going on? Lets make it as best as we can, not 'as Igor says'. :)
Best regards,
Igor Stasenko. |
In reply to this post by stepharo
Le 03/04/2016 17:33, stepharo a écrit :
> If you want to change clicking behaviour you need to override one single > method. >> >> Everything you wrote with unreadable amount of characters is >> for nothing. >> >> I see clearly point of Igor. And for me it feels very logical. >> With such design you can lively change clipping area and >> interaction area for any morph (element) on screen. >> >> >> In short, i see only two cases where indeed, morph requires a nothing >> of shapes to define: >> - clipping region(s) >> - ui interaction region(s) >> >> but for drawing? nooooo... really? who cares what you draw there? >> draw anything, in any possible way you see fit.. compose, decompose, >> recombine, blend and mix.. that's the whole purpose of drawing and be >> artistic and be able to express yourself in any possible way you want :) >> Why nailing and formalizing things that are tend to be hardly >> formalizable and more than that, unnecessary. >> That's my main concern about current design. > > I agree. > I do not see why people are forced to create a submorph just to change > the rendering. > If you want to change it dynamically you can for example pass a > different shape. I don't see the problem with subclassing a morph. The reverse: I feel like current Morphs are huge monsters of configurability and parameter blocks and properties and intricated code and thousands of methods so that one doesn't has to subclass... Simpler, "subclassable" morphs suits me a lot better. Bloc looks like its taking some of the bad aspects of Morphic. Regards, Thierry |
On 3 April 2016 at 19:48, Thierry Goubier <[hidden email]> wrote: Le 03/04/2016 17:33, stepharo a écrit : Me neither. But do you confusing subclassing and submorph compositing? The reverse: I feel like current Morphs are huge monsters of configurability and parameter blocks and properties and intricated code and thousands of methods so that one doesn't has to subclass... Agree, the Morph protocol is bloated. And i don't like it too. That is a result of lifting features and properties up in inheritance chain. And i can imagine how it happens over time: - we have a morph.. - hurray! - can we have a morph with a border? - yes! Here BorderedMorph for you! - nice.. but can i use border in another subclass of Morph? - yes! Here borderStyle: property for you.. (and BorderedMorph is now useless) Or take a layout.. We could have , say, MorphWithLayout class. That introducing layouts. While other, simpler morph don't. Really, what layout you need in a morph that contains a plain rectangle fully covering its bounds? Or even 'having submorphs'. We could have MorphWithSubmorphs. Which could introduce submorphs concept. Separation of concerns. Good way to go. But if you need to have a morph that both has layout and border, then you are in trouble: you forced to do one of following: - make own Morph subclass, duplicating features of both.. or make a composition of submorphs that will represent both features, or... lift both features to the top of inheritance chain, getting bloat as result. Most of the times, most of things are achiveable through composition.. but some of them.. like drawing - apparently not. In any case i agree, that many features, that Morph proposing out of the box needs review and validation in terms, what if we isolate certain feature(s) in separate subclass and provide them via composition. Simpler, "subclassable" morphs suits me a lot better. One step at a time. You cannot fix all the problems of parent at once. The way how Bloc born, i think (i may be mistaken), it is a 'clean and lean' port of Morphic. But of course Morphic is huge monster, and porting such monster while rewriting its complex logic at the same time could be daunting hard. In any case, i think it is better. Let us hope, it will be even better. Regards, Best regards,
Igor Stasenko. |
In reply to this post by Thierry Goubier
On 3 April 2016 at 19:43, Thierry Goubier <[hidden email]> wrote: Hi Alex, Igor and others, Of course, creating shapes has own cost, as anything else. But, guess what, you having caching mechanism in Athens out of the box, if you don't happy with performance.
Sad. Sarcasm tries to flow from my tongue. But i will keep my mouth shut. No comments :)
That is road to nowhere. You already having morphs for composition. No need to introduce 'elements' to compose something inside composition of morphs.. If you cannot do something out of composition of morphs, what makes you think that you can do it introducing another layer of composition? Maybe you shall think that composition is a wrong tool in that case?
Best regards,
Igor Stasenko. |
In reply to this post by Igor Stasenko
Le 03/04/2016 19:12, Igor Stasenko a écrit :
> > > On 3 April 2016 at 19:48, Thierry Goubier <[hidden email] > <mailto:[hidden email]>> wrote: > > Le 03/04/2016 17:33, stepharo a écrit : > > If you want to change clicking behaviour you need to override > one single > method. > > > Everything you wrote with unreadable amount of > characters is > for nothing. > > I see clearly point of Igor. And for me it feels very > logical. > With such design you can lively change clipping area and > interaction area for any morph (element) on screen. > > > In short, i see only two cases where indeed, morph requires > a nothing > of shapes to define: > - clipping region(s) > - ui interaction region(s) > > but for drawing? nooooo... really? who cares what you draw > there? > draw anything, in any possible way you see fit.. compose, > decompose, > recombine, blend and mix.. that's the whole purpose of > drawing and be > artistic and be able to express yourself in any possible way > you want :) > Why nailing and formalizing things that are tend to be hardly > formalizable and more than that, unnecessary. > That's my main concern about current design. > > > I agree. > I do not see why people are forced to create a submorph just to > change > the rendering. > If you want to change it dynamically you can for example pass a > different shape. > > > I don't see the problem with subclassing a morph. > > Me neither. But do you confusing subclassing and submorph compositing? Let me return you the question then: do you do a composition of submorphs if you're trying to get a different drawOn:? Oh, ok, that's true FastTable does it for the selection... changing background color by encapsulating a row in another Morph with the right background color. > The reverse: I feel like current Morphs are huge monsters of > configurability and parameter blocks and properties and intricated > code and thousands of methods so that one doesn't has to subclass... > > Agree, the Morph protocol is bloated. And i don't like it too. > That is a result of lifting features and properties up in inheritance chain. > And i can imagine how it happens over time: > - we have a morph.. > - hurray! > - can we have a morph with a border? > - yes! Here BorderedMorph for you! > - nice.. but can i use border in another subclass of Morph? > - yes! Here borderStyle: property for you.. (and BorderedMorph is now > useless) > > Or take a layout.. We could have , say, MorphWithLayout class. That > introducing layouts. While other, simpler morph don't. Really, what > layout you need in a morph that contains a plain rectangle fully > covering its bounds? > Or even 'having submorphs'. We could have MorphWithSubmorphs. Which > could introduce submorphs concept. > > Separation of concerns. Good way to go. But if you need to have a morph > that both has layout and border, then you are in trouble: you forced to > do one of following: > - make own Morph subclass, duplicating features of both.. or make a > composition of submorphs that will represent both features, or... lift > both features to the top of inheritance chain, getting bloat as result. > Most of the times, most of things are achiveable through composition.. > but some of them.. like drawing - apparently not. > In any case i agree, that many features, that Morph proposing out of the > box needs review and validation in terms, what if we isolate certain > feature(s) in separate subclass and provide them via composition. Yes, I do think you're right. > Simpler, "subclassable" morphs suits me a lot better. > > Bloc looks like its taking some of the bad aspects of Morphic. > > One step at a time. You cannot fix all the problems of parent at once. > The way how Bloc born, i think (i may be mistaken), it is a 'clean and > lean' port of Morphic. But of course Morphic is huge monster, and > porting such monster while rewriting its complex logic at the same time > could be daunting hard. > In any case, i think it is better. Let us hope, it will be even better. I do hope. Certain points really require switching to Athens (sub-pixel rendering of large fonts is extremely slow), and Bloc will be the toolkit we'll have to live with. Regards, Thierry |
>Let me return you the question then: do you do a composition of submorphs if you're trying to get a different drawOn:? >Oh, ok, that's true FastTable does it for the selection... changing background color by encapsulating a row in another Morph with the right background color. Did, not anymore. FTTableRowMorph>>#selectionColor: Best regards, Henrik |
In reply to this post by Thierry Goubier
On 3 April 2016 at 20:51, Thierry Goubier <[hidden email]> wrote: Le 03/04/2016 19:12, Igor Stasenko a écrit : Who, me? No. Maybe i was just misunderstood your reply. Because what i was tried to demonstrate in previous post(s) that there's simply no easy way to expose all possible drawing operations via composition of morphs (or composition of any other kind of elements), unless, of course you will lift full feature set of Athens to the level of composition.. As result you will get a full feature set that Athens provides, plus extra complexity. Sounds like thing to do, no? :) Oh, ok, that's true FastTable does it for the selection... changing background color by encapsulating a row in another Morph with the right background color. Well, i don't know what is FastTable beast are.. so i cannot comment on this one.
Best regards,
Igor Stasenko. |
In reply to this post by Henrik Nergaard
Le 03/04/2016 20:00, Henrik Nergaard a écrit :
> >> Let me return you the question then: do you do a composition of >> submorphs if you're trying to get a different drawOn:? > >> Oh, ok, that's true FastTable does it for the selection... changing >> background color by encapsulating a row in another Morph with the >> right background color. > > Did, not anymore. > > FTTableRowMorph>>#selectionColor: Had to check the following code to be sure: (highligtedRowIndexes includes: rowIndex) ifTrue: [ row selectionColor: (self owner colorForSelection: primarySelectionIndex = rowIndex) ]. Was there a measurable inpact when changing that? Because I have now three ways of doing this, and all of them have trade-offs. For example the one above suppose that row items are a specific kind of Morph, i.e. FTTableRowMorph; one could do without a dedicated Morph subclass for rows and display the selection as a transparent colored rectangle over the row; this is what I do. Thierry |
In reply to this post by Aliaksei Syrel
Le 3/4/16 18:23, Aliaksei Syrel a
écrit :
I have the impression that this is a good solution.
|
In reply to this post by Thierry Goubier
I changed it mostly because it was messing up the color when you did mouse-over (required to check the owner color to set it correctly when there was a selection, the code was ugly and with corner cases).
Encapsulating a morph with another morph just for a background color is kind of waste IMO. Causing unnecessary overhead for rendering/layout/eventHandling etc... Mesurable? Don’t think I checked, but in the long run there is less allocations, less layout etc.. I would also argue that ------------------ (highligtedRowIndexes includes: rowIndex) ifTrue: [ row selectionColor: (self owner colorForSelection: primarySelectionIndex = rowIndex) ]. ----------------- Is better than ----------------- rowSubviews add: ((highligtedRowIndexes includes: rowIndex) ifTrue: [ "IMPORTANT: I need to set owner to nil because otherwise it will trigger an invalidation of the owner when adding morph to selectionMorph, causing an infinite loop" self toSelectionRow: (row privateOwner: nil) primary: primarySelectionIndex = rowIndex ] ifFalse: [ row ]) ]. ----------------------- Selection could be and drawn by the container, but then again you would need much more code and special logic (updating the damageRecorder with correct rectangles when selection changes for example) than to just extend and specialize one morph to be a row. I would much rather prefer one specialized morph doing its thing, than encapsulate it. Best regards, Henrik -----Original Message----- From: Pharo-dev [mailto:[hidden email]] On Behalf Of Thierry Goubier Sent: Sunday, April 3, 2016 8:58 PM To: Pharo Development List <[hidden email]> Subject: Re: [Pharo-dev] [bloc] shape size? Le 03/04/2016 20:00, Henrik Nergaard a écrit : > >> Let me return you the question then: do you do a composition of >> submorphs if you're trying to get a different drawOn:? > >> Oh, ok, that's true FastTable does it for the selection... changing >> background color by encapsulating a row in another Morph with the >> right background color. > > Did, not anymore. > > FTTableRowMorph>>#selectionColor: Had to check the following code to be sure: (highligtedRowIndexes includes: rowIndex) ifTrue: [ row selectionColor: (self owner colorForSelection: primarySelectionIndex = rowIndex) ]. Was there a measurable inpact when changing that? Because I have now three ways of doing this, and all of them have trade-offs. For example the one above suppose that row items are a specific kind of Morph, i.e. FTTableRowMorph; one could do without a dedicated Morph subclass for rows and display the selection as a transparent colored rectangle over the row; this is what I do. Thierry |
In reply to this post by Igor Stasenko
Le 03/04/2016 20:01, Igor Stasenko a écrit :
> > > On 3 April 2016 at 20:51, Thierry Goubier <[hidden email] > <mailto:[hidden email]>> wrote: > > Le 03/04/2016 19:12, Igor Stasenko a écrit : > > > > On 3 April 2016 at 19:48, Thierry Goubier > <[hidden email] <mailto:[hidden email]> > <mailto:[hidden email] > <mailto:[hidden email]>>> wrote: > > Le 03/04/2016 17:33, stepharo a écrit : > > If you want to change clicking behaviour you need to > override > one single > method. > > > Everything you wrote with unreadable amount of > characters is > for nothing. > > I see clearly point of Igor. And for me it > feels very > logical. > With such design you can lively change > clipping area and > interaction area for any morph (element) on > screen. > > > In short, i see only two cases where indeed, morph > requires > a nothing > of shapes to define: > - clipping region(s) > - ui interaction region(s) > > but for drawing? nooooo... really? who cares what > you draw > there? > draw anything, in any possible way you see fit.. > compose, > decompose, > recombine, blend and mix.. that's the whole purpose of > drawing and be > artistic and be able to express yourself in any > possible way > you want :) > Why nailing and formalizing things that are tend to > be hardly > formalizable and more than that, unnecessary. > That's my main concern about current design. > > > I agree. > I do not see why people are forced to create a submorph > just to > change > the rendering. > If you want to change it dynamically you can for > example pass a > different shape. > > > I don't see the problem with subclassing a morph. > > Me neither. But do you confusing subclassing and submorph > compositing? > > > Let me return you the question then: do you do a composition of > submorphs if you're trying to get a different drawOn:? > > Who, me? No. Maybe i was just misunderstood your reply. > Because what i was tried to demonstrate in previous post(s) that there's > simply no easy way to expose all possible drawing operations via > composition of morphs (or composition of any other kind of elements), > unless, of course you will lift full feature set of Athens to the level > of composition.. > As result you will get a full feature set that Athens provides, plus > extra complexity. > Sounds like thing to do, no? :) Agreed :) > Oh, ok, that's true FastTable does it for the selection... changing > background color by encapsulating a row in another Morph with the > right background color. > > Well, i don't know what is FastTable beast are.. so i cannot comment on > this one. I think FastTable is something you should have a look at. Esteban did something really interesting there. In FT, Submorphs are only created when they are about to be displayed: Pharo can easily create hundreds of morphs on every redraw cycle. So FT performance is O(k) where k is the number of rows to display on screen (typical k is ~25), and is O(1) regarding the length of the list (almost: there is a point, for very large tree-like structures, where just iterating over the structure becomes the main performance limitation: see FTTree). A FTTableContainerMorph recreates all its submorphs on every drawOn:. I've played with different variants (do not recreate all submorphs, for example) but you don't see any performance difference (on the time needed for a drawOn:). Regards, Thierry |
>A FTTableContainerMorph recreates all its submorphs on every drawOn:.
Not correct. Submorphs are only recreated when the view of the list has changed #canRefreshValues, ie if the variable "needsRefreshExposedRows" is set to true. If this is false nothing will happen in #drawOn: If changes is necessary the drawOn: will recreate submorphs for the current view (showIndex) and set the "needsRefreshedExposedRows" to false signalling that it is correctly laid out. Best regards, Henrik -----Original Message----- From: Pharo-dev [mailto:[hidden email]] On Behalf Of Thierry Goubier Sent: Sunday, April 3, 2016 9:32 PM To: Pharo Development List <[hidden email]> Subject: Re: [Pharo-dev] [bloc] shape size? I think FastTable is something you should have a look at. Esteban did something really interesting there. In FT, Submorphs are only created when they are about to be displayed: Pharo can easily create hundreds of morphs on every redraw cycle. So FT performance is O(k) where k is the number of rows to display on screen (typical k is ~25), and is O(1) regarding the length of the list (almost: there is a point, for very large tree-like structures, where just iterating over the structure becomes the main performance limitation: see FTTree). A FTTableContainerMorph recreates all its submorphs on every drawOn:. I've played with different variants (do not recreate all submorphs, for example) but you don't see any performance difference (on the time needed for a drawOn:). Regards, Thierry |
In reply to this post by Henrik Nergaard
Hi Henrik,
Le 03/04/2016 21:32, Henrik Nergaard a écrit : > I changed it mostly because it was messing up the color when you did > mouse-over (required to check the owner color to set it correctly when > there was a selection, the code was ugly and with corner cases). Ok. > Encapsulating a morph with another morph just for a background color > is kind of waste IMO. Causing unnecessary overhead for > rendering/layout/eventHandling etc... Rendering maybe a bit. Layout, maybe a bit. Event handling? Oh well, row morphs contents are already a tree of morphs at least 3 deep, what will be the effect of one more doing nothing? > Mesurable? Don’t think I checked, but in the long run there is less allocations, less layout etc.. I guess that, given how FT works, it is hidden in the number of Morph creation per drawOn: :) > I would also argue that > ------------------ > (highligtedRowIndexes includes: rowIndex) ifTrue: [ > row selectionColor: (self owner colorForSelection: > primarySelectionIndex = rowIndex) ]. > ----------------- > Is better than > ----------------- > > rowSubviews add: ((highligtedRowIndexes includes: rowIndex) > ifTrue: [ > "IMPORTANT: I need to set owner to nil because otherwise it will trigger an > invalidation of the owner when adding morph to selectionMorph, causing an > infinite loop" > self > toSelectionRow: (row privateOwner: nil) > primary: primarySelectionIndex = rowIndex ] > ifFalse: [ row ]) ]. > ----------------------- I like the game with #privateOwner: in the FT code. Tells you a lot about ownership in Morphic :) At the same time, your new code isn't very clear. It is written just as the setting of a theme property where in fact it is setting the row as selected. > Selection could be and drawn by the container, but then again you > would need much more code and special logic (updating the damageRecorder > with correct rectangles when selection changes for example) than to just > extend and specialize one morph to be a row. I'm doing the selection draw by container, and, honestly, there is none of the complexity you describe. Selection is a model operation anyway, so it usually triggers a redraw (because selection may move you elsewhere, if the model so chooses); if you have some caching in place (that FT hasn't), you gain a bit upon redraw, but nothing noticeable. There is another reason for moving it into the container, but that reason is not public. > I would much rather prefer one specialized morph doing its thing, than encapsulate it. I think the FTTableRowMorph has other duties anyway, so giving him that additional role is fine. Regards, Thierry > Best regards, > Henrik > > -----Original Message----- > From: Pharo-dev [mailto:[hidden email]] On Behalf Of Thierry Goubier > Sent: Sunday, April 3, 2016 8:58 PM > To: Pharo Development List <[hidden email]> > Subject: Re: [Pharo-dev] [bloc] shape size? > > Le 03/04/2016 20:00, Henrik Nergaard a écrit : >> >>> Let me return you the question then: do you do a composition of >>> submorphs if you're trying to get a different drawOn:? >> >>> Oh, ok, that's true FastTable does it for the selection... changing >>> background color by encapsulating a row in another Morph with the >>> right background color. >> >> Did, not anymore. >> >> FTTableRowMorph>>#selectionColor: > > Had to check the following code to be sure: > > (highligtedRowIndexes includes: rowIndex) ifTrue: [ > row selectionColor: (self owner colorForSelection: > primarySelectionIndex = rowIndex) ]. > > Was there a measurable inpact when changing that? > > Because I have now three ways of doing this, and all of them have trade-offs. For example the one above suppose that row items are a specific kind of Morph, i.e. FTTableRowMorph; one could do without a dedicated Morph subclass for rows and display the selection as a transparent colored rectangle over the row; this is what I do. > > Thierry > |
In reply to this post by Thierry Goubier
On 3 April 2016 at 22:32, Thierry Goubier <[hidden email]> wrote: Le 03/04/2016 20:01, Igor Stasenko a écrit : Sounds like right way to do it. There's no point to keep million UI elements for million items in list, since you never render them all at once on the screen. So, practical approach is to create as many UI elements as fits on the screen, but not as many you have in list. A FTTableContainerMorph recreates all its submorphs on every drawOn:. I've played with different variants (do not recreate all submorphs, for example) but you don't see any performance difference (on the time needed for a drawOn:). Yeah, i did similar thing in TxText - also create morph(s) only for part of text which is currently displayed.. and basically it is same idea for TxText itself: it calculates layout only for a portion of text, the portion that currently displayed, but never for whole text, which can be megabytes long. Thus, it guarantees that overall performance are bound to the area, covered by UI control that displays the text, but not to text size. Regards, Best regards,
Igor Stasenko. |
In reply to this post by Henrik Nergaard
Le 03/04/2016 21:51, Henrik Nergaard a écrit :
>> A FTTableContainerMorph recreates all its submorphs on every >> drawOn:. > Not correct. Ok. I stand corrected. This is why it is done in #drawOn: and not #drawSubmorphsOn: > Submorphs are only recreated when the view of the list has changed > #canRefreshValues, ie if the variable "needsRefreshExposedRows" is > set to true. If this is false nothing will happen in #drawOn: > > If changes is necessary the drawOn: will recreate submorphs for the > current view (showIndex) and set the "needsRefreshedExposedRows" to > false signalling that it is correctly laid out. What is interesting, still, is that submorphs rebuilding (deleting and recreating them) happens during a #drawOn: call, and that it is fast enough not to register on the time needed for a world redraw. And so I still think it is interesting for Igor to have a look at FT :) Regards, Thierry |
In reply to this post by Igor Stasenko
I think that Cocoa list does that. When a list item goes out of the screen it’s sent to a pool, and when a new one has to be displayed they take any one from that pool and re-initialize.
|
In reply to this post by Thierry Goubier
On 3 April 2016 at 23:00, Thierry Goubier <[hidden email]> wrote: Le 03/04/2016 21:51, Henrik Nergaard a écrit : Only for review purpose, i guess. From what you described, as i wrote in previous post this is not new to me. I think i seen some kind of morph(s) that was using same technique in the past. it may be different in details, of course, but overall idea was same: create and use as many UI elements, as many fits on the screen, not as many items in the list(s) Regards, Best regards,
Igor Stasenko. |
In reply to this post by Igor Stasenko
Le 03/04/2016 21:58, Igor Stasenko a écrit :
> > > On 3 April 2016 at 22:32, Thierry Goubier <[hidden email] > <mailto:[hidden email]>> wrote: > > Le 03/04/2016 20:01, Igor Stasenko a écrit : > > > > On 3 April 2016 at 20:51, Thierry Goubier > <[hidden email] <mailto:[hidden email]> > <mailto:[hidden email] > <mailto:[hidden email]>>> wrote: > > Le 03/04/2016 19:12, Igor Stasenko a écrit : > > > > On 3 April 2016 at 19:48, Thierry Goubier > <[hidden email] > <mailto:[hidden email]> > <mailto:[hidden email] > <mailto:[hidden email]>> > <mailto:[hidden email] > <mailto:[hidden email]> > > <mailto:[hidden email] > <mailto:[hidden email]>>>> wrote: > > Le 03/04/2016 17:33, stepharo a écrit : > > If you want to change clicking behaviour you > need to > override > one single > method. > > > Everything you wrote with > unreadable amount of > characters is > for nothing. > > I see clearly point of Igor. And for > me it > feels very > logical. > With such design you can lively change > clipping area and > interaction area for any morph > (element) on > screen. > > > In short, i see only two cases where > indeed, morph > requires > a nothing > of shapes to define: > - clipping region(s) > - ui interaction region(s) > > but for drawing? nooooo... really? who > cares what > you draw > there? > draw anything, in any possible way you see > fit.. > compose, > decompose, > recombine, blend and mix.. that's the > whole purpose of > drawing and be > artistic and be able to express yourself > in any > possible way > you want :) > Why nailing and formalizing things that > are tend to > be hardly > formalizable and more than that, unnecessary. > That's my main concern about current design. > > > I agree. > I do not see why people are forced to create a > submorph > just to > change > the rendering. > If you want to change it dynamically you can for > example pass a > different shape. > > > I don't see the problem with subclassing a morph. > > Me neither. But do you confusing subclassing and submorph > compositing? > > > Let me return you the question then: do you do a composition of > submorphs if you're trying to get a different drawOn:? > > Who, me? No. Maybe i was just misunderstood your reply. > Because what i was tried to demonstrate in previous post(s) that > there's > simply no easy way to expose all possible drawing operations via > composition of morphs (or composition of any other kind of > elements), > unless, of course you will lift full feature set of Athens to > the level > of composition.. > As result you will get a full feature set that Athens provides, plus > extra complexity. > Sounds like thing to do, no? :) > > > Agreed :) > > Oh, ok, that's true FastTable does it for the selection... > changing > background color by encapsulating a row in another Morph > with the > right background color. > > Well, i don't know what is FastTable beast are.. so i cannot > comment on > this one. > > > I think FastTable is something you should have a look at. Esteban > did something really interesting there. > > In FT, Submorphs are only created when they are about to be > displayed: Pharo can easily create hundreds of morphs on every > redraw cycle. So FT performance is O(k) where k is the number of > rows to display on screen (typical k is ~25), and is O(1) regarding > the length of the list (almost: there is a point, for very large > tree-like structures, where just iterating over the structure > becomes the main performance limitation: see FTTree). > > Sounds like right way to do it. There's no point to keep million UI > elements for million items in list, since you never render them all at > once on the screen. So, practical approach is to create as many UI > elements as fits on the screen, but not as many you have in list. > > A FTTableContainerMorph recreates all its submorphs on every > drawOn:. I've played with different variants (do not recreate all > submorphs, for example) but you don't see any performance difference > (on the time needed for a drawOn:). Well, as Henrik pointed out, not everytime ;) > Yeah, i did similar thing in TxText - also create morph(s) only for part > of text which is currently displayed.. and basically it is same idea for > TxText itself: it calculates layout only for a portion of text, the > portion that currently displayed, but never for whole text, which can be > megabytes long. > Thus, it guarantees that overall performance are bound to the area, > covered by UI control that displays the text, but not to text size. I'm interested to know how you handle scrolling then: how do you define the step, the length and the position: relative to the number of characters displayed / start character of the current UI / and knowing the number of characters in the whole text, so that you are independent of the layout? Regards, Thierry |
In reply to this post by Igor Stasenko
Le 03/04/2016 22:26, Igor Stasenko a écrit :
> > > On 3 April 2016 at 23:00, Thierry Goubier <[hidden email] > <mailto:[hidden email]>> wrote: > > Le 03/04/2016 21:51, Henrik Nergaard a écrit : > > A FTTableContainerMorph recreates all its submorphs on every > drawOn:. > > Not correct. > > > Ok. I stand corrected. This is why it is done in #drawOn: and not > #drawSubmorphsOn: > > Submorphs are only recreated when the view of the list has changed > #canRefreshValues, ie if the variable "needsRefreshExposedRows" is > set to true. If this is false nothing will happen in #drawOn: > > If changes is necessary the drawOn: will recreate submorphs for the > current view (showIndex) and set the "needsRefreshedExposedRows" to > false signalling that it is correctly laid out. > > > What is interesting, still, is that submorphs rebuilding (deleting > and recreating them) happens during a #drawOn: call, and that it is > fast enough not to register on the time needed for a world redraw. > > And so I still think it is interesting for Igor to have a look at FT :) > > Only for review purpose, i guess. From what you described, as i wrote in > previous post this is not new to me. I think i seen some kind of > morph(s) that was using same technique in the past. it may be different > in details, of course, but overall idea was same: create and use as many > UI elements, as many fits on the screen, not as many items in the list(s) Yes, probably. Regards, Thierry |
Free forum by Nabble | Edit this page |