[fxruby-users] custom widget (event) questions

eddy eddyhkim at gmail.com
Fri Apr 24 19:03:37 EDT 2009


Hi all,

First, kudos to Lyle for the nice work for the work bringing Fox to Ruby.

I'm trying to create a custom widget that looks and acts like a regular 
pushbutton with some additional look and behavior.  I don't think I can 
use a regular FXButton because I can't seem to style the text inside, or 
have bands of different colors.  Eventually it will flash when an alarm 
goes off.

I tried to create a custom widget like this:

class PushB < FXVerticalFrame
  include Responder

  attr_accessor :header, :footer, :main_text

  def initialize(parent, dialog, opts = {})
    @size = 100
    @header_text, @footer_text, @main_text = 
nil,opts[:timer_type],opts[:main]
    @child = []
    @dialog = dialog
    @o = opts

    super(parent,
      
:opts=>FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_Y|LAYOUT_CENTER_X|LAYOUT_CENTER_Y|LAYOUT_FIX_WIDTH|LAYOUT_FIX_HEIGHT,
      :width=>@size, :height=>@size, :padding=>0
    )
    FXMAPFUNC(SEL_LEFTBUTTONPRESS, 0, :on_left_click)

    @meta_button = self
    @meta_button.backColor = FXRGB(0,200,0)

    w = @size - 4
    base_disp_opts = 
LAYOUT_CENTER_X|LAYOUT_SIDE_TOP|LAYOUT_FIX_HEIGHT|LAYOUT_FIX_WIDTH
    @child << FXLabel.new(@meta_button, @header_text||"", :width=>w, 
:height=>25,
      :opts=>base_disp_opts|FRAME_RAISED
    )
    @child.last.connect(SEL_LEFTBUTTONPRESS, method(:on_left_click))
    
    @child << FXLabel.new(@meta_button, @main_text||"", 
:width=>w,:height=>55,
      :opts=>base_disp_opts
    )
    @child.last.connect(SEL_LEFTBUTTONPRESS, method(:on_left_click))

    @child << FXLabel.new(@meta_button, @footer_text||"", :width=>w, 
:height=>25,
      :opts=>base_disp_opts|FRAME_RAISED
    )
    @child.last.connect(SEL_LEFTBUTTONPRESS, method(:on_left_click))

    set_normal_state
    
    enable
  end
  def set_normal_state
    @child[0].backColor= FXRGB(100,150,0)
    @child[2].backColor= FXRGB(100,150,0)
  end
  def set_alarm_state
  end
  def toggle_state
  end
  def on_left_click(sender, sel, event)
    puts "XXX buttonpress - #{sender} #{sel} #{event}"
    @dialog.execute
  end
end

Lots of hardcoded stuff since I'm just experimenting right now.  Sorry 
for the horribly ugly code, but this is my first attempt at a FXRuby 
program. :)

The widget is a square "button", made up of three FXLabel instances.  
Unfortunately, I haven't hit upon how to make the entire widget respond 
as one to a mouse click.  The FXMAPFUNC call that I found in the list 
archives only works on the frame itself.  Since the child elements take 
up all the space, they intercept the mouse click.  So right now, each 
child is handling the event independently.

How would one get the child elements to pass the click event to their 
parent?

Then the major problem I haven't figured out yet... If I have more than 
one of these widgets, each one needs to know when it was clicked.  
Sounds like a good use for FXDataTarget, but passing :target to a label 
or frame causes mass panic and confusion :)   Unrecognized parameter 
target (ArgumentError)

What would the strategy be to get the target of the mouse click?  The 
event object that is passed to on_left_click handler contains an FXEvent 
which has co-ordinates.  That can't be right, but I haven't found any 
info on how to get the data target working for a fox object that is not 
expecting it.  Is there some way to pass self as a parameter when 
connecting?   ie. .connect(SEL_LEFTBUTTONPRESS, method(:xxx), self)

Any pointers or tips greatly appreciated.
TIA,
Ed



More information about the fxruby-users mailing list