[Gambas-user] Scrollarea Graphics

Fabien Bodard gambas.fr at ...626...
Mon Nov 17 18:50:24 CET 2014


ouch ... i've a problem with your patch... it allow me to just ugrade
the .project file...

2014-11-17 18:05 GMT+01:00 Tobias Boege <taboege at ...626...>:
> On Mon, 17 Nov 2014, Sean Sayandeep Khan wrote:
>> Hello, I have the folloing setup (See attached image,
>> UI1.png). The Canvas is a scrollarea. I want to add text
>> commands, such as "ADDTILE 10,10 40,60 hello" in the
>> textbox called Command. I expect as output (on clicking
>> the button "exec") a tile of width 40 and height 60 to
>> appear with top left being 10, 10 in the canvas. Here is
>> my code :
>>
>> --8<-- Snip --8<--
>>
>> Public Sub _new()
>>
>> func = "_new"
>> Canvas.ResizeContents(400, 400)
>> Canvas.Refresh()
>> End
>>
>> --8<-- Snip --8<--
>>
>> Public Sub Canvas_Draw()
>>
>>    Dim a As Variant[]
>>    a = Canvas.Children
>>    Object.Call(Me, func)
>>
>>    Canvas.Refresh()
>> End
>>
>>
>
> Did you notice that your program has a very high input latency? Above is the
> reason why: _new() calls Canvas.Refresh() which triggers Canvas_Draw()
> (during the next event loop?) which again calls _new(), and so on.
>
> On a second glance, there is yet another loop: Canvas.Refresh() from inside
> Canvas_Draw() triggers a (useless) new Canvas_Draw() event immediately after
> this one finished.
>
> So these two loops (only one after you executed the first command) spin in
> the background drawing the same thing every free moment of your process'
> life.
>
> Note that the Draw event for ScrollAreas is triggered once when the program
> starts, so Canvas.Refresh() in _new() is superfluous. The proper code would
> be:
>
>   Public Sub _new()
>     Canvas.ResizeContents(400, 400)
>   End
>
>   Public Sub Canvas_Draw()
>     If Not func Then Return
>     Object.Call(Me, func)
>   End
>
> Also note that (at least in more recent Gambas versions) Canvas.Children is
> a virtual object so assigning it to a Variant[] variable a will produce an
> error.
>
>>
>> You see, if I drop the canvas.refresh() in subroutine
>> canvas_draw() , then only the first tille would be drawn,
>> and all subsequent ADDTILE .... calls will be ignored,
>> i.e. no new tile is drawn.
>> If I keep the refresh() then only the last tile is drawn,
>> and the previous tiles are erased.
>>
>> However, I want to keep on adding tiles, and keep the
>> previously added tiles.
>>
>
> OK, I guess you don't understand the Draw event concept.
>
> The Draw event of the Canvas object is raised whenever the interpreter deems
> it necessary that the contents of Canvas be redrawn. Before each such redraw,
> the Canvas is entirely cleared. You can force a Draw event by calling
> Canvas.Refresh().
>
> This explains both problems you stated above: if you drop Canvas.Refresh()
> in Canvas_Draw(), then there are no new Draw events. How could the Canvas,
> or the interpreter for that matter, know that someone entered a new command
> and that this command has anything to do with drawing?
>
> Solution: call Canvas.Refresh() when you received the command and want it to
> be drawn, like in:
>
>   Public Sub execute()
>     Dim commands As String[]
>
>     ' Your stuff as it was...
>     Canvas.Refresh()
>   End
>
> This gets us immediately to the second problem you mentioned above. You only
> see the outcome of your last command because the ScrollArea contents are
> fleeting in the sense that whenever a Draw event is raised (like when you
> force one with Canvas.Refresh() above), the entire ScrollArea is cleared for
> you to redraw the image from scratch.
>
> This behaviour is sometimes useful and always more efficient, memory-wise,
> because we need to store only what is visible in the ScrollArea at a time,
> not the whole (potentially arbitrarily large) virtual content through which
> you can scroll.
>
> Your application, however, needs a more persistent storage for your drawings,
> right? I've heard artists used to paint "pictures". Maybe we can also try
> that? :-) The basic idea is that your command interpreter does not paint
> onto the (fleeting) Canvas directly but on an Image object. There, you can
> draw sequentially, on top of what you drew before. Then you call Refresh()
> and in Canvas_Draw() you simply put that Image onto the Canvas.
>
>> Also, how do I remove a particular tile added, say as the
>> second one, in the sequence, of say, five tiles, and
>> retain the other four?
>>
>
> What sequence do you mean? :-) To talk about a sequence of commands, you
> need to save a sequence of commands in your program, let's say in an array.
> You can then loop through that array of commands to create a painting.
>
> To remove some command from the sequence, remove the corresponding element
> of the array and recreate the painting from the remaining elements.
>
> If that's too inefficient for your needs (I'd guess the border is around a
> few thousand commands here?), you can still paint over that tile with the
> background colour. In any case, you need to somehow save the specification
> of your tiles if you want to be able to remove them.
>
> I will attach you a patch for your project which implements all the things
> I discussed here, so you can play around with it. If your Gambas is recent
> enough (I guess it is 3.5.4?), you can apply this patch via the IDE, menu
> Project -> Patch -> Apply. [ And sorry, I couldn't help but tidy your code
> up a bit on the way -- using my personal definition of "tidying up". ]
>
> There is a demo button, labelled "TEST" for a quick tour of what the code
> can do now.
>
> Regards,
> Tobi
>
> --
> "There's an old saying: Don't change anything... ever!" -- Mr. Monk
>
> ------------------------------------------------------------------------------
> Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
> from Actuate! Instantly Supercharge Your Business Reports and Dashboards
> with Interactivity, Sharing, Native Excel Exports, App Integration & more
> Get technology previously reserved for billion-dollar corporations, FREE
> http://pubads.g.doubleclick.net/gampad/clk?id=157005751&iu=/4140/ostg.clktrk
> _______________________________________________
> Gambas-user mailing list
> Gambas-user at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/gambas-user
>



-- 
Fabien Bodard




More information about the User mailing list