[Vala] Clutter gradient and text



Hello, I hate to bother you all with trivial stuff like this, but I am
having some serious trouble finding the error in my program.

Essentially, I want to render a shape with a gradient background and a
text label, so I created an actor that has a single Text actor as a
child.

The gradient is rendered using a method similar to
http://lists.o-hand.com/clutter/1787.html written in vala and adapted to
handle angles.  (Any improvements to this function would also be welcome
C: )

A screenshot of the incorrect behaviour is located at
http://sellyourvote.ca/Screenshot-test.png

I know it has something to do with the Text actor, since both rectangles
render properly if the text is turned off in both of them.

Thanks,
Sam

------------

// test.vala - Problem clutter file
// Should render two rounded rectangles with gradients,
// the left one without text, and the right one with text

// On my machine left box only has border, but right box
// is correct.

// Compile with valac --pkg=clutter-1.0 test.vala

using Clutter;
using Cogl;

struct Point
{
        float x;
        float y;

}

public class TestActor : Actor
{
        Text t = new Text.with_text(null, "Test");
        bool _text;
        
        construct
        {
                t.set_parent(this);
                t.set_size(40, 40);
                t.set_position(10, 10);
        }
        
        public TestActor(bool draw_text)
        {
                _text = draw_text;
        }
        
        private inline static void rotate_point(ref Point p,
                                                float angle)
        {
                float oldx = p.x, oldy = p.y;
                p.x = oldx*Math.cosf(angle) - oldy*Math.sinf(angle);
                p.y = oldy*Math.cosf(angle) + oldx*Math.sinf(angle);
        }
        
        private static void draw_gradient(float width,
                                          float height,
                                          Cogl.Color c1,
                                          Cogl.Color c2,
                                          float angle)
        {
                if (angle >= Math.PI)
                {
                        Cogl.Color temp = c1;
                        c1 = c2;
                        c2 = temp;
                }
        
                float sin_a = Math.sinf(angle);
                float cos_a = Math.cosf(angle);
        
                float A = sin_a*width;
                float B = cos_a*width;
        
                float C = sin_a*height;
                float D = cos_a*height;

                float s1 = A+D;
                float s2 = B+C;
        
                float x0 = -s2/2f, x1 = x0 + s2;
                float y0 = -s1/2f, y1 = y0 + s1;
        
                Point p[4];
        
                p[0] = {x0, y0};
                p[1] = {x0, y1};
                p[2] = {x1, y1};
                p[3] = {x1, y0};
                
                for (int i = 0; i < p.length; i++)
                {
                        rotate_point(ref p[i], angle);
                        p[i].x += width/2f;
                        p[i].y += height/2f;    
                }

                TextureVertex v[4];

                v[0] = {p[0].x, p[0].y, 0, 0, 0, c1};
                v[1] = {p[1].x, p[1].y, 0, 0, 0, c1};
                v[2] = {p[2].x, p[2].y, 0, 0, 0, c2};
                v[3] = {p[3].x, p[3].y, 0, 0, 0, c2}; 
        
                Cogl.polygon(v, true);
        }
        
        protected override void paint()
        {
                Geometry geom;
                get_allocation_geometry(out geom);
                
                Cogl.Color pri = {0, 255, 0, 255};
                Cogl.Color sec = {0, 0, 255, 255};
                
                Cogl.path_round_rectangle(0,
                                          0,
                                          geom.width,
                                          geom.height,
                                          5,
                                          (float)Math.PI_4/4f);

                Cogl.clip_push_from_path();

                draw_gradient(geom.width, geom.height,
                                          pri,
                                          sec,
                                          (float)Math.PI/4);
                
                Cogl.clip_pop();
                
                Cogl.path_round_rectangle(0,
                                          0,
                                          geom.width,
                                          geom.height,
                                          5,
                                          (float)Math.PI_4/4f);
                                                                  
                Cogl.set_source_color({128, 128, 128, 255});
                Cogl.path_stroke();
                
                if (_text)
                        t.paint();
        }
        
        protected override void pick(Clutter.Color c)
        {
                Geometry geom;
                get_allocation_geometry(out geom);
        
                Cogl.path_round_rectangle(0,
                                          0,
                                          geom.width,
                                          geom.height,
                                          5,
                                          (float)Math.PI_4/4f);
                
                Cogl.set_source_color({c.red,c.green,c.blue,c.alpha});
                Cogl.path_fill();
        
                t.paint();
        }
        
        protected override void map()
        {
                base.map();
                t.map();
        }
        
        protected override void unmap()
        {
                t.unmap();
                base.unmap();
        }
        
        protected override void allocate(ActorBox box,
                                         AllocationFlags flags)
        {
                base.allocate(box, flags);
                
                float x, y, width, height;
                t.get_size(out width, out height);
                t.get_position(out x, out y);
                t.allocate({x, y, width, height}, flags);
        }
}

void main(string[] args)
{
        if (Clutter.init(ref args) != 1)
                return;
        
        weak Stage s = Stage.get_default();
        s.color = {0, 0, 0, 255};
        s.set_size(230, 120);
        s.show_all();

        // Should render gradient, no text      
        TestActor off = new TestActor(false);

        // Should render gradient and text
        TestActor on = new TestActor(true);
                
        s.add_actor(off);
        s.add_actor(on);
        
        off.set_size(100, 100);
        off.set_position(10, 10);
        
        on.set_size(100, 100);
        on.set_position(120, 10);
        
        s.destroy.connect(() => { Clutter.main_quit(); });
        
        Clutter.main();
}

Attachment: smime.p7s
Description: S/MIME cryptographic signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]