Button on the canavas. Ruby Tk - ruby

Is there any way to put button(TK) on the TkCanavas widget ? I need to capture mouse button actions on diffrent parts of canavas to do a little TicTacToe game. I used TkCanavas because of drawing field lines and putting objects on exact coordinates
require 'tk'
class Window
##xs = [60,145,235,60,145,235,60,145,235]
##ys = [140,140,140,225,225,225,315,315,315] #coordinates of circles and crosses
def run
root = TkRoot.new { title 'TicTacToe' }
root.geometry("300x400+300+300")
img = TkPhotoImage.new(:file => 'cross.gif')
cv = TkCanvas.new(root)
cv.place(:height => 400, :width => 300)
cv.create(TkcImage, ##xs[2], ##ys[2], :image => img)
cv.create(TkButton, 60, 140,120,200 ) #
cv.create(TkcLine, 20, 180, 280, 180) #
cv.create(TkcLine, 20, 270, 280, 270) #Field lines
cv.create(TkcLine, 100, 100, 100, 360) #
cv.create(TkcLine, 190,100, 190, 360) #
TkcText.new(cv, 140, 30, :font => 'Arial 14',
:text => 'TicTacToe', :anchor => 'center')
Tk.mainloop
end
end

Try using TkcRectangle instead of TkButton. You can bind events to the rectangle like you can to the button.

Related

Ruby Tkinter scrollbar doesn't appear in its frame and allows scrolling past canvas bounds. What am I doing wrong?

I've been fighting with Tkinter in ruby to try and get a proper scrollable frame working.
I've had the most success with this tutorial: https://www.youtube.com/watch?v=VmlgrrXAqb4
I have translated what he does in the video into ruby and it "works", but only kinda. When I run the application I get a window similar to his with all of the buttons, but the scrollbar handle doesn't appear in it's frame and I can scroll past the content of the frame in both directions.
I'm trying to build an application that has a heavy use of scrolling, but I can't get past this. I am posting as a last resort. I've tried most of the examples I can find online, but I keep getting unexpected behavior. It is worth noting that I am on MacOS in case someone tries the code on Windows or Linux and it works for some reason.
require 'tk'
require 'tkextlib/tkimg'
win = TkRoot.new
win.geometry "500x500"
win.resizable false,false
wrapper1 = Tk::Tile::Frame.new win
wrapper2 = Tk::Tile::Frame.new win
mycanvas = TkCanvas.new wrapper1
mycanvas.pack :side => "left", :fill => "both", :expand => "yes"
yscrollbar = TkScrollbar.new :parent => wrapper1, :command => Proc.new {|*args| mycanvas.yview *args}
yscrollbar.pack :side => "left", :fill => "y"
mycanvas.configure(:yscrollcommand => Proc.new {|*args| yscrollbar.set *args })
mycanvas.bind "<Configure>", Proc.new {mycanvas.scrollregion = mycanvas.bbox("all")}
myframe = Tk::Tile::Frame.new mycanvas
TkcWindow.new(mycanvas, 0, 0, :anchor => "nw", :window => myframe)
wrapper1.pack :fill => "both", :expand => "yes", :padx => 10, :pady => 10
wrapper2.pack :fill => "both", :expand => "yes", :padx => 10, :pady => 10
for i in 0..50
button = TkButton.new(myframe)
button.text = "Button " + i.to_s
button.pack
end
Tk.mainloop
I figured out what was wrong.
#The line of code below where the Configure event is bound needs to be:
mycanvas.bind "Configure" #...
#instead of:
mycanvas.bind "<Configure>" #...

Ruby Shoes Hover element

Hover element dosen't work. Where is problem? How fix it?
Shoes.app :width => 635, :height => 410 do
background image "http://PATH_TO_IMAGE"
a = stack :width => 360, :height => 200, :margin_left => 250, :margin_top => 200 do
hover do
a.clear { para "Some Text qwe qwe qwerty", :stroke => black }
end
leave do
a.clear { background image "http://PATH_TO_IMAGE" }
end
end
end
I think in principle you cannot use image as the argument for background.
I also am not sure if that is effect you want to achieve but it shows what you did wrong:
Shoes.app :width => 635, :height => 410 do
a = stack :width => 360, :height => 200 do
image "http://PATH_TO_IMAGE"
hover do
a.clear {para "Some Text qwe qwe qwerty", :stroke => black }
end
leave do
a.clear { image "http://PATH_TO_IMAGE" }
end
end
end

Can't align middle a list_box

I can't align middle a list_box in ruby shoes. I have test a few things, including :right => "50" or :left => "50", but it still not work.
Shoes.app do
stack :width => "100%", :height => "45%" do
a = list_box :items => ["lol","b"], :width => 50, :align => "center"
end
end
I did not find a direct way but you can use this hack
module Shoes::Types
def centr
left=(self.parent.width-self.style[:width])/2
self.move(left,self.top)
end
def middle
top=(self.parent.height-self.style[:height])/2
self.move(self.left,top)
end
end
Shoes.app do
#c=stack :width=>50, :height=>30 do
a=list_box :items => ["lol","b"], :width => 50, :height=>30
end
#c.centr.middle
end
What is done is actually first to extend the functionality of slots so that you can place them in the center or middle of the containing slot. Then you wrap your listbox in a tiny slot, which you center.

Line not rendering

I am developing some prawn reports and running into an issue where any line I draw with a code like the following will render only in the last page.
horizontal_line(0, 200, :at => y)
It is called once per page.
My code is relatively complex now so I tried to isolate the problem to post here, the isolated code follows
require 'prawn'
a = Prawn::Document.new(:page_size => 'A4', :margin => [20,20,20,20])
a.font('Times-Roman')
a.horizontal_line(10, 400, :at => 140)
a.text_box('Test Text', :size => 50, :at => [2, 100], :width => 400)
puts a.render
For my surprise, it didnĀ“t work even with a single page document. Only the "Test Text" is being rendered. It makes me think I am doing something wrong in the page setup or something like that.
Fond out the problem.
The correct use would be:
require 'prawn'
a = Prawn::Document.new(:page_size => 'A4', :margin => [20,20,20,20])
a.font('Times-Roman')
a.stroke do
a.horizontal_line(10, 400, :at => 140)
end
a.text_box('Test Text', :size => 50, :at => [2, 100], :width => 400)
puts a.render

How can I get vertical alignment in flow slot in Shoes?

The default vertical alignment in a flow slot is apparently to top-align the elements. Here's a sample:
Shoes.app (:title => "Vertical Alignment", :width => 300, :height => 150) do
background "#DFA"
flow :margin => 30 do
title "BIG"
tagline "MEDIUM"
inscription "SMALL"
end
end
How do I get the flow slot to center-align its elements short of calculating a :rise value for each element? I would have expected a vertical-alignment style for flow slots and a horizontal-alignment style for stack slots, but I don't see anything like that. What did I miss?
To my knowledge, there's no style for vertical alignment. There is horizontal alignment which is useful in stacks:
Shoes.app (:title => "Horizontal Alignment", :width => 300, :height => 150) do
background "#DFA"
stack :margin => 30 do
title "BIG", :align => 'center'
tagline "MEDIUM", :align => 'center'
inscription "SMALL", :align => 'center'
end
end
Keep in mind that Shoes is very much still a work in progress, so _why will probably get around to it eventually.

Resources