binding to drawn text for use with gradient panels

Hello. I'm attempting to make widgets with labels look good and work
well while sitting on panels that have a gradient background.

Specifically, I would like to get the following three conditions to
work compatibly, cross platform:

(1) widgets with labels (static text) next to them (such as wx.Choice
with a label next to it).

(2) able to bind the static text to an event handler, so that mousing
over it focuses the widget.

(3) the label must *not have a background*, such that a gradient that
the panel it sits on shows through.

I'd been using (1) + (3) to draw (non-interactive) text on gradients,
but now I thought it might be nice to allow that text to serve as
additional "hit area" for a widget it labels. Getting conditions (1)
+ (2) are fine--I'm stuck once I include (3). I can draw text over a
gradient where the wxStaticText was, but then I don't know how to make
it such that I can bind events to that drawn text--and I'm not sure
that's possible. Is it?

If not, is there a way I can make the location on the screen where the
drawn text is serve as the "hit area", such that mousing over it would
send an event?

Or is there a better approach?

Thanks for any insight,
Che

Hi Che,

Hello. I'm attempting to make widgets with labels look good and work
well while sitting on panels that have a gradient background.

Specifically, I would like to get the following three conditions to
work compatibly, cross platform:

(1) widgets with labels (static text) next to them (such as wx.Choice
with a label next to it).

(2) able to bind the static text to an event handler, so that mousing
over it focuses the widget.

(3) the label must *not have a background*, such that a gradient that
the panel it sits on shows through.

I'd been using (1) + (3) to draw (non-interactive) text on gradients,
but now I thought it might be nice to allow that text to serve as
additional "hit area" for a widget it labels. Getting conditions (1)
+ (2) are fine--I'm stuck once I include (3). I can draw text over a
gradient where the wxStaticText was, but then I don't know how to make
it such that I can bind events to that drawn text--and I'm not sure
that's possible. Is it?

If not, is there a way I can make the location on the screen where the
drawn text is serve as the "hit area", such that mousing over it would
send an event?

If you draw the label yourself, the static text is not a real widget:
so you can just bind events like wx.EVT_MOTION, wx.EVT_LEFT_DOWN and
wx.EVT_LEFT_UP to your panel (i.e., the panel that would be the label
parent if the label was a real widget) and then highlight/redraw your
label if certain conditions are met. For example (pseudo-code,
untested):

def OnMotion(self, event):

    pos = event.GetPosition()

    if self.labelRect.Contains(pos):

        if self.labelStatus == "hover":
            # nothing to do, we are already hovered by the mouse
            return

        self.labelStatus = "hover"
        # Redraw the label with a "hover" appearance
        self.RedrawLabel()

    else:

        if self.labelStatus == "normal":
            # nothing to do, we are already in normal state
            return

        self.labelStatus = "normal"
        # Redraw the label with a "normal" appearance
        self.RedrawLabel()

Where "labelRect" is your label wx.Rect rectangle and "labelStatus"
can be anything you need to make your label nice: you'll decide the
label appearance in the RedrawLabel() method (which will redraw the
part of the screen where the label sits) depending on the value of
"labelStatus".

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

==> Never *EVER* use RemovalGroup for your house removal. You'll
regret it forever.
The Doomed City: Removal Group: the nightmare <==

···

On 18 August 2010 05:52, C M wrote:

Thanks, Andrea! I was able to get a test version of your approach to
work. I have a little flickering of the screen (and yes, using double
buffering) but I have just started to try it so I can probably get
that worked out. I'm glad to add it to the set of approaches I have
for dealing with gradient backgrounds.

Che

···

On Wed, Aug 18, 2010 at 3:00 AM, Andrea Gavana <andrea.gavana@gmail.com> wrote:

Hi Che,

On 18 August 2010 05:52, C M wrote:

Hello. I'm attempting to make widgets with labels look good and work
well while sitting on panels that have a gradient background.

Specifically, I would like to get the following three conditions to
work compatibly, cross platform:

(1) widgets with labels (static text) next to them (such as wx.Choice
with a label next to it).

(2) able to bind the static text to an event handler, so that mousing
over it focuses the widget.

(3) the label must *not have a background*, such that a gradient that
the panel it sits on shows through.

I'd been using (1) + (3) to draw (non-interactive) text on gradients,
but now I thought it might be nice to allow that text to serve as
additional "hit area" for a widget it labels. Getting conditions (1)
+ (2) are fine--I'm stuck once I include (3). I can draw text over a
gradient where the wxStaticText was, but then I don't know how to make
it such that I can bind events to that drawn text--and I'm not sure
that's possible. Is it?

If not, is there a way I can make the location on the screen where the
drawn text is serve as the "hit area", such that mousing over it would
send an event?

If you draw the label yourself, the static text is not a real widget:
so you can just bind events like wx.EVT_MOTION, wx.EVT_LEFT_DOWN and
wx.EVT_LEFT_UP to your panel (i.e., the panel that would be the label
parent if the label was a real widget) and then highlight/redraw your
label if certain conditions are met. For example (pseudo-code,
untested):

def OnMotion(self, event):

pos = event.GetPosition()

if self.labelRect.Contains(pos):

   if self\.labelStatus == &quot;hover&quot;:
       \# nothing to do, we are already hovered by the mouse
       return

   self\.labelStatus = &quot;hover&quot;
   \# Redraw the label with a &quot;hover&quot; appearance
   self\.RedrawLabel\(\)

else:

   if self\.labelStatus == &quot;normal&quot;:
       \# nothing to do, we are already in normal state
       return

   self\.labelStatus = &quot;normal&quot;
   \# Redraw the label with a &quot;normal&quot; appearance
   self\.RedrawLabel\(\)

Where "labelRect" is your label wx.Rect rectangle and "labelStatus"
can be anything you need to make your label nice: you'll decide the
label appearance in the RedrawLabel() method (which will redraw the
part of the screen where the label sits) depending on the value of
"labelStatus".

Andrea.

Hi Che,

Hi Che,

Hello. I'm attempting to make widgets with labels look good and work
well while sitting on panels that have a gradient background.

Specifically, I would like to get the following three conditions to
work compatibly, cross platform:

(1) widgets with labels (static text) next to them (such as wx.Choice
with a label next to it).

(2) able to bind the static text to an event handler, so that mousing
over it focuses the widget.

(3) the label must *not have a background*, such that a gradient that
the panel it sits on shows through.

I'd been using (1) + (3) to draw (non-interactive) text on gradients,
but now I thought it might be nice to allow that text to serve as
additional "hit area" for a widget it labels. Getting conditions (1)
+ (2) are fine--I'm stuck once I include (3). I can draw text over a
gradient where the wxStaticText was, but then I don't know how to make
it such that I can bind events to that drawn text--and I'm not sure
that's possible. Is it?

If not, is there a way I can make the location on the screen where the
drawn text is serve as the "hit area", such that mousing over it would
send an event?

If you draw the label yourself, the static text is not a real widget:
so you can just bind events like wx.EVT_MOTION, wx.EVT_LEFT_DOWN and
wx.EVT_LEFT_UP to your panel (i.e., the panel that would be the label
parent if the label was a real widget) and then highlight/redraw your
label if certain conditions are met. For example (pseudo-code,
untested):

def OnMotion(self, event):

pos = event.GetPosition()

if self.labelRect.Contains(pos):

   if self\.labelStatus == &quot;hover&quot;:
       \# nothing to do, we are already hovered by the mouse
       return

   self\.labelStatus = &quot;hover&quot;
   \# Redraw the label with a &quot;hover&quot; appearance
   self\.RedrawLabel\(\)

else:

   if self\.labelStatus == &quot;normal&quot;:
       \# nothing to do, we are already in normal state
       return

   self\.labelStatus = &quot;normal&quot;
   \# Redraw the label with a &quot;normal&quot; appearance
   self\.RedrawLabel\(\)

Where "labelRect" is your label wx.Rect rectangle and "labelStatus"
can be anything you need to make your label nice: you'll decide the
label appearance in the RedrawLabel() method (which will redraw the
part of the screen where the label sits) depending on the value of
"labelStatus".

Andrea.

Thanks, Andrea! I was able to get a test version of your approach to
work. I have a little flickering of the screen (and yes, using double
buffering) but I have just started to try it so I can probably get
that worked out. I'm glad to add it to the set of approaches I have
for dealing with gradient backgrounds.

Glad to be of help :slight_smile: .

During the past months, I have seen you tried to implement this
specific feature (gradient backgrounds on widgets) using different
approaches; I would say that it would be extremely nice if, at some
point, you could consider packaging up your approaches in a module (or
something like that) and contribute it back to wxPython. It won't be
confessed by anyone here, but I believe if the feature of having
widgets showing cleanly on a gradient background was available, the
wxPython users/developers would really benefit from it and it will be
another customization level for wxPython. I'd be more than happy to
have it inside AGW itself, or in alternative inside wx.lib if you find
it more appropriate.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

==> Never *EVER* use RemovalGroup for your house removal. You'll
regret it forever.
The Doomed City: Removal Group: the nightmare <==

···

On 18 August 2010 21:53, C M wrote:

On Wed, Aug 18, 2010 at 3:00 AM, Andrea Gavana <andrea.gavana@gmail.com> wrote:

On 18 August 2010 05:52, C M wrote:

Glad to be of help :slight_smile: .

During the past months, I have seen you tried to implement this
specific feature (gradient backgrounds on widgets) using different
approaches; I would say that it would be extremely nice if, at some
point, you could consider packaging up your approaches in a module (or
something like that) and contribute it back to wxPython. It won't be
confessed by anyone here, but I believe if the feature of having
widgets showing cleanly on a gradient background was available, the
wxPython users/developers would really benefit from it and it will be
another customization level for wxPython. I'd be more than happy to
have it inside AGW itself, or in alternative inside wx.lib if you find
it more appropriate.

Good suggestion, Andrea. Yes, I will think about a good way to do
this, and may have questions at some point for the list about it. I'm
not sure my solutions have been all that effective, but at least it
has shown me that there are workarounds to get nearly everything I
have wanted with gradients. At least that's a start toward getting
something more well thought out available.

Thanks,
Che