I'm creating an application for fun to learn ruby and shoes, but it seems that I cannot accomplish what I'm trying to do...
I have a stack with some text inside and, under certain circumstances, I want to change the background of that stack, but for some reason all the text inside the stack is deleted.
How can I avoid that? I just want to change the background color.
Sample code to show the problem:
Shoes.app do
#first_stack = stack do
background orange
#title = title "my title"
#subtitle = subtitle "my subtitle"
end
button ("change background") {
#first_stack.background gold
}
end
Seems background creates a fill which means your text is still there just nested under the fill. Here is a work around
Shoes.app do
def change_color(back)
#first_stack.clear
#first_stack.background back
#first_stack.title #title
#first_stack.subtitle #subtitle
end
#first_stack = stack do
background orange
#title = title "my title"
#subtitle = subtitle "my subtitle"
end
button ("change background") do
change_color(gold)
end
end
This just clears the first stack and recreates it with a new color. Still looking into a more eloquent method.
EDIT
Found a solution:
Shoes.app do
#first_stack = stack do
#fs_background = background orange
#title = title "my title"
#subtitle = subtitle "my subtitle"
end
button ("change background") do
#fs_background.remove
#first_stack.before(#title) {#fs_background = background gold}
end
end
This will work the way you want as it places a background layer on top of the original background layer but before #title.
Assuming you make the background the first element:
Shoes.app do
#f = stack do
background blue
title "my title"
subtitle "my subtitle"
end
button ("change background") do
#f.children.first.remove
#f.before(#f.children.first) {
background gold
}
end
end
in Shoes3.3.1 you can do it that way
Shoes.app do
#first_stack = stack do
background orange
#title = title "my title"
#subtitle = subtitle "my subtitle"
end
button ("change background") {
#first_stack.contents[0].fill = gold
#first_stack.refresh_slot
}
end
Related
I've got this as my code
openAll = File.open('N:\Josh\Blondie\db.txt')
allNumbers = Array.new
allNumbers=[]
openAll.each_line {|line|
allNumbers.push line
}
puts allNumbers
and I'd like to be able to display the output of this code in a new window with Ruby Shoes, I can't seem to get it to display anything though. The contents of the file are names and phone numbers.
Any ideas?
Here's an example of outputting text to a shoes window. Using a puts statement just outputs to the shell, not to the Shoes app.
Shoes.app :title => "GUI RAW file converter, for the CLI challenged",
:resizable => true do
background white
stack do
flow {
background gray, :height => 30
caption "Caption", :margin => 8, :stroke => white
stack {
para 'This is a fancy line I just printed to the window'
####### Here's an example line you could use to put out the array...
allNumbers.each do |number|
para "#{number}"
end
}
}
end
end
I guess you should use the method Kernel#alert instead of Kernel#puts.
http://shoesrb.com/manual/Built-in.html
I want to run a program which changes the background depending on which gender you choose in a edit list.
Shoes.app do
para "your gender"
list_box :items => ["female", "male"],
width => 120, :choose => "weiblich" do |list|
#gender.text = list.text
end
#gender = para "#{#gender}"
button "change colours" do
if #gender ="female"
background (deeppink)
else #gender ="male"
background (dodgerblue)
end
end
end
The problem is - whatever I do, if I use the if-statement, suddenly always "female" is in the variable and my background is pink, altough when I pick "male". If I just do
...
button "change colours" do
para #gender
end
....
the right gender is in the variable #gender. Does anybody know what the problem is?
You need if #gender == "female" and if #gender == "male" - note the two = symbols.
You're performing an assignment, not testing equality.
Shoes.app do
flow do
file = "something with variable length"
para "Loading #{file}: "
progress :width => -300
end
end
As you can see from the code I am trying to display a progress bar that goes from the end of the text until the right edge of the application window.
When the text has a fixed length this solution works but it doesn't once the text changes length in the above fragment: there will be either too little or too much space for the progress bar.
Is there a solution to this problem?
I tried asking the para element it's width but it is 0???
As I mentioned before, you have to get the width of the textblock after it is calculated. Try this:
Shoes.app do
flow do
file = "something with variable length"
#p = para "Loading #{file}: "
#prog = progress
start do
#prog.width = #prog.parent.width - #p.width
end
end
button 'Change text!' do
text = #p.text
#p.text = text + '1'
#prog.width = #prog.parent.width - #p.width
end
end
In Shoes, I'd like to create a button that is initially hidden. I've tried passing :hidden => true as part of the button style, as well as calling #button.hide() after creating it, but it remains obstinately visible.
I've been able to work around this by not creating the button until I want it shown, but that requires checking to see if it already exists, rather than just using it.
Not at present. Buttons are still fairly unreliable in Shoes, especially on Windows. You can work around the issue by putting the button in a slot and hiding or showing the slot, but you may discover that the button won't hide again once it has been clicked once:
Shoes.app do
para 'This is some text.'
#flow = flow :width => 50, :hidden => true do
button 'a' do |btn|
alert 'Hello, World!'
end
end
button 'toggle' do
#flow.toggle
end
para 'Blah blah blah'
end
Luckily, there is a way out: slots. Slots can be given a click event, which makes them behave much as a button does. In fact, you can make fairly decent buttons out of slots.
Here's something I cobbled together. It lets you use the pesto_button method to generate buttons built on flows. You can modify it to fit your needs, including such things as using an image as the background, modifiable text (with auto-expanding width?), ability to change styles on the fly, etc:
class PestoButton < Widget
def initialize (text, opts = {})
#border_color = opts[:border_color] || gray
#border_width = opts[:border_width] || 3
#color = opts[:up_color] || gainsboro
#click_color = opts[:down_color] || #border_color
#width = opts[:width] || 80
#click = block_given? ? Proc.new { yield } : nil
#text = text
#visible = true
#flow = flow :width => #width do
background #color
border #border_color, :strokewidth => #border_width
para #text, :align => 'center'
end
#flow.click do
#flow.clear
#flow.append do
background #click_color
border #border_color, :strokewidth => #border_width
para #text, :align => 'center'
end
end
#flow.release do
#flow.clear
#flow.append do
background #color
border #border_color, :strokewidth => #border_width
para #text, :align => 'center'
#click.call if #click
end
end
end
def click
#click = block_given? ? Proc.new { yield } : nil
end
def show
#flow.show
end
def toggle
#flow.toggle
end
def hide
#flow.hide
end
end
Shoes.app do
para 'This is some text.'
#btn = pesto_button 'Click me!' do
alert 'Hello, World!'
end
button 'toggle' do
#btn.toggle
end
button 'new block' do
#btn.click do
alert 'Goodbye, World!'
end
end
button 'no block' do
#btn.click #Clears the click method
end
para 'Blah blah blah'
end
I want to use shoes to be able to download the body of a website that a user enters in an edit_line. How can I make this work? Can anyone help explain why the below code does not work? It just pops up a new window, and does not download the site from the text entered....
Here's my code thus far:
Shoes.app do
stack (:left => 175, :top => 200) do
para "Enter a url:"
flow do
#url = edit_line
button "OK" do
window do
stack do
title "Searching site", :size => 16
#status = para "One moment..."
# Search site for query and print body
download #url.text do |site|
#status.text = "Body: " + site.response.body.inspect
end
end
end
end
end
end
end
Nevermind - I figured it out. I just didn't pop to a new window and it downloads and prints the body fine. : )