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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With