Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a blur event for Ruby Shoes

Tags:

ruby

blur

shoes

I'm experimenting with Ruby Shoes. I want controls that become editable as you give them focus, and become text again when they loose it. So far I have the following...

class NameBox < Shoes::Widget
  def initialize(model, opts = {})
    @model = model
    @para = para(value)
    self.click{ 
      edit
    }
    self.keypress{|key|
      display if key==:enter
    }
  end

  def display
    @ed && @ed.hide
    @para.show
    @para.text = value
  end

  def edit
    @ed ||= edit_line(value) {|e|
      @model.rename(e.text)
    }
    @para.hide
    @ed.text = value
    @ed.show
  end

  def value
    @model.name
  end
end

used by

class Model
  attr_reader :name
  def initialize(name)
    @name = name
  end
  def rename(new_name)
    @name = new_name
  end
end

Shoes.app do
  @variable = Model.new("1 2 3")
  stack do
    10.times{ name_box(@variable) }
  end
end

This implementation means if you click on more than one control, they will both be edit boxes.

What I was hoping for was a blur event that would let me change the control back to 'display'. This doesn't exist, so.. how would you implement it?

Assume I will be writing a bunch more controls and they all have to abide by this rule of 'one focused control'

** for Bonus points explain why I can't put:

@ed ||= edit_line(value) {|e|
  @model.rename(e.text)
} 
@ed.hide()

in the initialize and get @ed to be hidden.

like image 530
Nigel Thorne Avatar asked Nov 03 '22 20:11

Nigel Thorne


1 Answers

How about this one?

class NameBox < Shoes::Widget
  def initialize(model, opts = {})
    @model = model
    @para = para(value)
    self.click{ 
      edit
    }
  end

  def display
    @ed && @ed.hide
    @para.show
    @para.text = value
  end

  def edit
    @ed ||= edit_box(value, height: 30) {|e|
      e.text[-1] == "\n" ? display : @model.rename(e.text)
    }
    @para.hide
    @ed.text = value
    @ed.show
  end

  def value
    @model.name
  end
end

class Model
  attr_reader :name
  def initialize(name)
    @name = name
  end
  def rename(new_name)
    @name = new_name
  end
end

Shoes.app do
  @variable = Model.new("1 2 3")
  stack do
    10.times{ name_box(@variable) }
  end
end
like image 165
ashbb Avatar answered Nov 14 '22 10:11

ashbb