tags:

views:

110

answers:

2

I want to setup a rect/slot, that when hovered over, creates a little window hovering off the side of the rect/slot (a little overlapping).

I'd also like to fit some buttons in the little menu. I'd like the little menu to be longer (width-wise) than the original rect/slot, in order to fit many buttons, which means I can't use slot.hover, because the menu goes away if I move from the rect to the button thats off the rect... Any help?

A: 

Sounds like you need to use some extra stuff to keep that rect open and visible while on a button as well as while over the slot.

That should keep the menu there while over anything.

jim
+1  A: 

Here is an example that should show you the logic you need in order to accomplish this. It would obviously get out of hand if you had a bunch of these menus:

Shoes.app :title => "Test", :width => 1000, :height => 600 do
  @menu_hover = false
  @zone_hover = false
  @menu = nil
  @zone = stack :width => 200, :height => 100 do
    background '#DFA'
  end
  @zone.hover do
    @zone_hover = true
    app.append do
      break if not @menu.nil?
      @menu = stack :width => 230, :height => 35, :top => 50, :left => 150 do
        background '#F00'
        flow :margin => 5 do 
          button 'OK'
          button 'Cancel'
          button 'Ponies!'
        end
      end
      @menu.hover {@menu_hover = true}
      @menu.leave do
            @menu_hover = false
            break if @menu.nil? or @menu_hover or @zone_hover
            @menu.remove
            @menu = nil
      end
    end
  end

  @zone.leave do
    @zone_hover = false
    break if @menu.nil? or @menu_hover or @zone_hover
    @menu.remove
    @menu = nil
  end
end

Here is a riff on the above solution which extends the Shoes::Stack and Shoes::App classes to add a hover? method to stacks (which I think they ought to support by default). In your case, I'd consider creating a custom Widget instead, but this shows the sort of structure you might be able to use.

class Shoes::Stack
  def hover?
    @hover ||= false
  end

  alias_method :default_hover, :hover
  alias_method :default_leave, :leave

  def hover(*args, &block)
    new_block = lambda { @hover = true; block.call }
    default_hover(*args, &new_block)
  end

  def leave(*args, &block)
    new_block = lambda { @hover = false; block.call }
    default_leave(*args, &new_block)
  end
end

class Shoes::App
  alias_method :default_stack, :stack
  def stack(*args, &block)
    s = default_stack(*args, &block)
    s.hover {}
    s.leave {}
    s
  end
end

Shoes.app :title => "Test", :width => 1000, :height => 600 do
  @menu = nil
  @zone = stack :width => 200, :height => 100 do
    background '#DFA'
  end
  @zone.hover do
    app.append do
      break if not @menu.nil?
      @menu = stack :width => 230, :height => 35, :top => 50, :left => 150 do
        background '#F00'
        flow :margin => 5 do 
          button 'OK'
          button 'Cancel'
          button 'Ponies!'
        end
      end
      @menu.leave do
            break if @menu.nil? or @menu.hover? or @zone.hover?
            @menu.remove
            @menu = nil
      end
    end
  end

  @zone.leave do
    break if @menu.nil? or @menu.hover? or @zone.hover?
    @menu.remove
    @menu = nil
  end
end
Pesto