Skip to main content
Topic: Spider Monkey Panel (foo_spider_monkey_panel) (Read 16361 times) previous topic - next topic
0 Members and 2 Guests are viewing this topic.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #175
Update: the above solution is okay if the objects are separate, but it gets buggy when they overlap.
I'm late

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #176
Unless I'm missing something, RepaintRect just clips the area that is currently drawn to the screen. So if I draw a rectangle from 0,0,100,100 to the gr buffer, and I'm only painting the region from (50,50 -> 100,100), the next time a full repaint is done, the rectangle will be completely drawn from 0,0 -> 100,100.

Also, it's my understanding that RepaintRect isn't something that causes a draw to happen immediately. It just specifies the region which will be drawn to the screen and that region is the union of the outermost extants of the region on the next draw cycle. So if I do RepaintRect(10,10,20,20) and then another RepaintRect(1000,1000,20,20) before the contents are actually drawn, when the drawcycle occurs it'll actually draw (10,10) -> (1020,1020). I'm assuming the underlying gdi stuff hasn't changed for Spidermonkey.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #177
Unless I'm missing something, RepaintRect just clips the area that is currently drawn to the screen. So if I draw a rectangle from 0,0,100,100 to the gr buffer, and I'm only painting the region from (50,50 -> 100,100), the next time a full repaint is done, the rectangle will be completely drawn from 0,0 -> 100,100.

Yes, unless you do this:
Code: [Select]
var myRegion = new PaintRegion(50, 50, 100, 100)


function on_paint(gr){
    myRegion.paint(gr);
}


function PaintRegion(x, y, w, h){
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.repainting = false;
    this.repaint_done = false;
    this.paint = (gr) => {
        if (this.repainting) {
            gr.FillSolidRect(0,0, window.Width, window.Height,0xFF000000);  // these are just examples,any other
            gr.DrawEllipse(80, 30, 200, 200, 2, 0xFFFFFFFF)                 // GdiGraphics method goes here.
            this.repaint_done = true;
            this.repainting = false;
        };
        if (!this.repaint_done) {
            this.repainting = true;
            window.RepaintRect(this.x, this.y, this.w, this.h);
            this.repaint_done = false;           
        };
    }
}

The full paint is done only if the repainting property is true, but this is set to false by default and it is not touched when a full paint is called. It is turned to true only for the RepaintRect method to reference it, and than back to false right after its execution. The repaint_done property works the other way round, in order to prevent a RepaintRect loop.
The above code works, but in my new project I built a system of nested objects, that pass the paint action (any action actually) on to their content, and that's where it gets tricky, but it's a very specific problem for that script.

Anyway, I'd prefer, and I'm still looking for (I still did not look into the Catrox scripts!  :-[ ), an alternative method that doesn't use the on_paint() callback to trigger the RepaintRect() method, for obvious safety reasons, but also because it would probably work in my nested objects chain.



Also, it's my understanding that RepaintRect isn't something that causes a draw to happen immediately.

I'm not sure about that. From what I read in the docs, it behaves like the Repaint() method. Doesn't that call an immediate window repaint?
I'm late

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #178
Sorry, I just realized the last line of code which resets the repaint_done property to false, must not be in the conditional section, but right after:
Code: [Select]
var myRegion = new PaintRegion(50, 50, 100, 100)


function on_paint(gr){
    myRegion.paint(gr);
}


function PaintRegion(x, y, w, h){
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.repainting = false;
    this.repaint_done = false;
    this.paint = (gr) => {
        if (this.repainting) {
            gr.FillSolidRect(0,0, window.Width, window.Height,0xFF000000);  // these are just examples,any other
            gr.DrawEllipse(80, 30, 200, 200, 2, 0xFFFFFFFF)                 // GdiGraphics method goes here.
            this.repaint_done = true;
            this.repainting = false;
        };
        if (!this.repaint_done) {
            this.repainting = true;
            window.RepaintRect(this.x, this.y, this.w, this.h);    
        };
       this.repaint_done = false;  // <---------
    }
}

I don't really understand why, though. It seems that the RepaintRect method aborts the execution of the previously called on_paint() function that triggered it. Is that correct?
I'm late

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #179
I don't really understand why, though. It seems that the RepaintRect method aborts the execution of the previously called on_paint() function that triggered it. Is that correct?

Alright, I think I understand now what @MordredKLB was telling me in his previous reply: the new paint event called by the RepaintRect() method is queued and executed only when the first paint event that triggered it is popped off the stack. Right?
I'm late

 

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #180
Alright, I think I understand now what @MordredKLB was telling me in his previous reply: the new paint event called by the RepaintRect() method is queued and executed only when the first paint event that triggered it is popped off the stack. Right?
Not exactly. Say you have a function that calls window.RepaintRect() twice in a row so that two buttons are repainted. It's my understanding that your on_paint method will only be called once the next time a WM_PAINT message is received by the foobar window, and that the cliprect for the area drawn will be the union of the exterior bounds (although that I'm less sure on).

Basically the Javascript is single-threaded, but the operating system isn't, and it queues up the areas that will be drawn.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #181
I finally found out how @TheQwertiest managed to solve the above issue in his CatRox theme. It's pretty straightforward actually, but it took me a few days because it was buried in thousands of code lines. So, for who's interested, here is a proper and more reasonable way than the one I came up with:

Code: [Select]
var myRegion = new PaintRegion(100, 100, 200, 200)


function on_paint(gr){
    myRegion.paint(gr);
}


function PaintRegion(x, y, w, h){
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.paint = (gr) => {
        var clipImg = gdi.CreateImage(this.w, this.h)
        var grClip = clipImg.GetGraphics();
        grClip.DrawEllipse(100, 50, 200, 200, 2, 0xFF000000)
        clipImg.ReleaseGraphics(grClip);
        gr.DrawImage(clipImg, this.x, this.y, this.w, this.h, 0, 0, this.w, this.h)
    }
}
I'm late

 
SimplePortal 1.0.0 RC1 © 2008-2019