Skip to main content
Topic: Spider Monkey Panel (foo_spider_monkey_panel) (Read 17631 times) previous topic - next topic
0 Members and 1 Guest 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

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #182
Hello,

I have a question about on_size event. It has two parameters and documentation indicates that it corresponds to panel size.
I have tested that and saw that it correspond to window size.
I did not do the test with JScript panel, but I would like to know if it the same with the JScript Panel ?

Kind regards,

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #183
I have a question about on_size event. It has two parameters and documentation indicates that it corresponds to panel size.
I have tested that and saw that it correspond to window size.
That is impossible - SMP currently does not have a way to find the size of fb2k window. on_size arguments ARE panel width and height respectively.
You can easily verify this by creating a layout with two resizeable SMP panels (e.g. in DUI) and replacing the following line in the default script:
Code: [Select]
gr.GdiDrawText(g_text, g_font, g_hot ? g_textcolour_hl : g_textcolour, 0, 0, ww, wh, DT_VCENTER | DT_CENTER | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
with
Code: [Select]
gr.GdiDrawText(`width: ${ww}, height ${wh}`, g_font, g_hot ? g_textcolour_hl : g_textcolour, 0, 0, ww, wh, DT_VCENTER | DT_CENTER | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
Each panel will display it's size, which will change when they are resized.

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #184
Thanks for you response.
I was already displaying width and height but is was the same for my for 4 panels.
After more testing, I decided to add a MinWidth and MaxWidth, idem with height. And it is not respected. I use CUI with horizontal and vertical splitter.
The thing is that a panel stretch to the size of the largest panel inside a column, even if larger than MaxWidth.
When you say 'resizeable SMP panel', do you mean that we can have them not resizeable?

Re: Spider Monkey Panel (foo_spider_monkey_panel)

Reply #185
MinWidth
After more testing, I decided to add a MinWidth and MaxWidth, idem with height. And it is not respected. I use CUI with horizontal and vertical splitter.
MinWidth and MaxWidth properties (and window dimensions adjustment functionality) are not provided by SMP component, but rather by foo_ui_hacks =)
You can use the following code though from my CaTRoX theme though: https://github.com/TheQwertiest/CaTRoX_QWR/blob/61eecfa4159e3714d58f53ae942d5f1861e83fb2/theme/Scripts/Panel_Menu.js#L1018
Note, that you have to change assignments like MinWidth=True to MinWidth.Enabled=True.

When you say 'resizeable SMP panel', do you mean that we can have them not resizeable
I mean smth like parent vertical/horizontal splitter in DUI/CUI that allows for panel size adjustment. There are components that provide panels for CUI/DUI, which allow having other panels inside, but don't allow their resizing.

 
SimplePortal 1.0.0 RC1 © 2008-2019