How to implement a blur event for Ruby Shoes

I am experimenting with Ruby Shoes. I want the controls to be edited when you focus on them, and become text again when they lose 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

is used

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 that if you click multiple controls, they will both be edit fields.

What I was hoping for was a blur event that allowed me to change the management to "show." It does not exist, therefore ... how would you implement it?

Suppose I write a bunch of more controls, and they all must abide by this β€œone focused control” rule

** for bonus points explains why I can not bet:

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

in initialization and get @ed to be hidden.

+5
source share
1 answer

How about this?

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
+2
source

All Articles