Hi Chris,

Thanks for the uptake on this, and apologies for the slow response. From
the various replies (and looking at the wx code) it seems like the basic
situation is that lines aren't 'filled' and so can't have a gradient.
Initially I thought that DrawLineList might solve the problem (we could
pass in a 'gradated' list of pens), but it seems that it is currently
only supported by DC not GC, and so won't support the alpha channel (?).

Anyhow I'm quite keen on GC support in FloatCanvas, so I started poking
around with your test (see below).

On Wed, 2007-09-05 at 15:55 -0700, Christopher Barker wrote:

> I started poking into this last night. It looks doable. However, 
> unfortunately for the OP, it's going to be a trick to get a line to fade 
> out, as you can make a gradient brush, but not a gradient pen, so you'd 
> need to make a skinny polygon instead of a line (so there is something 
> to fill with the brush).
> 
> I started a bit of test code. It's in SVN:
> 
> Tests/GCTest.py
> Tests/AlphaLine.py
> 

I've attached a basic merging of the 'filled path' idea from GCTest into
AlphaLine. It works, and proves the concept of using GC with a
NavCanvas, albeit with a few flaws (Zoom is a bit clunky), but maybe
this I've done something wrong anyhow.

>From an interface perspective it works the same as the Line class, but
takes additional arguments 'StartAlpha', 'EndAlpha' and 'BorderColour'.
It's probably a bit of a hack, but it does seem to do the job.

I'm happy to help out with this in anyway I can, but I am fairly new to
Python and very new to wxPython and floatcanvas, so might initially drop
a few clangers!

best,

Jamie



-- 
www.postlude.co.uk
#!/usr/bin/env python

"""

A test to use a GraphicsContext to draw an object with Alpha blending

NOt far yet -- is there a GradientPen???

"""

import numpy as N
import sys,wx
sys.path.append("../")
from floatcanvas import FloatCanvas, NavCanvas

class AlphaLine(FloatCanvas.Line):
    """

    The AlphaLine class takes a list of 2 - 2-tuples, or a 2X2 NumPy Float array
    of point coordinates.

    It will draw a line. 
    """
    def __init__(self,Points,
                 LineColor = "Black",
                 LineStyle = "Solid",
                 LineWidth    = 1,
                 InForeground = True,
		 StartAlpha = 0,
		 EndAlpha = 255,
		 BorderColour = "White"):
        FloatCanvas.DrawObject.__init__(self, InForeground)

        self.Points = N.array(Points,N.float)
        self.CalcBoundingBox()

        self.LineColor = LineColor
        self.LineStyle = LineStyle
        self.LineWidth = LineWidth
	self.StartAlpha = StartAlpha
	self.EndAlpha = EndAlpha
	self.BorderColour = BorderColour

    def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):

	bcolour = self.BorderColour 

	Points = self.Points
        GC = wx.GraphicsContext.Create(dc)
        
	c = wx.Color()
	c.SetFromName(self.LineColor)
	r,g,b = c.Get()

        c1 = wx.Color(r, g, b, self.StartAlpha)
        c2 = wx.Color(r, g, b, self.EndAlpha)
        
        Path = GC.CreatePath()

	origin = Points[0]
        Path.MoveToPoint(origin)

	data = Points[1:]	

	for point in data:
	    Path.AddLineToPoint(point)

	data = Points[::-1]
	data[:,1] += self.LineWidth

	for point in data:
	    Path.AddLineToPoint(point)

	endpoint = origin
	endpoint[1] += self.LineWidth

	Path.AddLineToPoint(endpoint)

        GC.SetPen(wx.Pen(bcolour))
        GC.DrawPath(Path)

	m = Points[:,0].size - 1

        Brush = \
	    GC.CreateLinearGradientBrush(Points[0,0], \
		    Points[0,1], Points[m,0], Points[m,1], c1, c2)

        GC.SetBrush(Brush)
        GC.FillPath(Path)

        if HTdc and self.HitAble:
            HTdc.SetPen(self.HitPen)
            HTdc.DrawLines(Points)


class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        
	NC = NavCanvas.NavCanvas(self ,wx.ID_ANY ,(500,500),
                                          ProjectionFun = None,
                                          BackgroundColor = "WHITE"
                                          )

        self.Canvas = NC.Canvas
	self.DrawLine()
	self.DrawCurve()

	return None
	
    def DrawLine(self):

	data = ([100,50], [300,100])

	self.Canvas.AddObject(AlphaLine(data, 
		LineColor = "Red", 
		LineStyle = "Solid", 
		LineWidth    = 4, 
		InForeground = 1, 
		StartAlpha = 255, 
		EndAlpha = 0))

	self.Canvas.Draw()

    def DrawCurve(self):

	time = 2.0*N.pi*N.arange(100)/100.0
	data = 1.0*N.ones((100,2))
	data[:,0] = time * 100
	data[:,1] = N.sin(time) * 100 + 100

	self.Canvas.AddObject(AlphaLine(data, 
		LineColor = "Blue", 
		LineStyle = "Solid", 
		LineWidth    = 6, 
		InForeground = 1, 
		StartAlpha = 0, 
		EndAlpha = 255))


A = wx.App(0)
F = MyFrame(None)
F.Show()
A.MainLoop()
_______________________________________________
FloatCanvas mailing list
[email protected]
http://mail.mithis.com/cgi-bin/mailman/listinfo/floatcanvas

Reply via email to