| stack do
| button("Hello")
| label(" word")
| flow { button("x") ; label("y") }
| end
|------------------------|
|<buttoni >|
|<labeli >|
|<--------------------- >|
|< >|
|< button >|
|< >|
|<--------------------- >|
|< >|
|< label >|
|< >|
|<--------------------- >|
|<buttoni >|
|------------------------|
::DynVar
support a single value and the observer pattern.def component()
stack do
htoolbar {
toolbar_button("open","Open file...") {
fload(ask_file_to_read(".","*.rb"),nil)
}
toolbar_button("Save","Save buffer to file...") {
@file=ask_file_to_write(".","*.rb") unless File.exists?(@file)
@title.text=@file
content=@edit.buffer.text
File.open(@file,"wb") { |f| f.write(content) } if @file && content && content.size>2
}
}
stack_paned(800,0.7) {
flow_paned(900,0.4) do
stack {
@title=sloti(label("Edit"))
@edit=source_editor(:lang=> "ruby", :font=> "Courier new 12").editor
sloti(button("Test...") { execute() })
}
stack {
@canvas= canvas(400,400) {
on_canvas_draw { |w,cr| redraw(w,cr) }
}
}
end
notebook do
page("Error") { @error_log=text_area(600,100,{:font=>"Courier new 10"}) }
page("Canvas Help") { make_help(text_area(600,100,{:font=>"Courier new 10"})) }
end
}
buttoni("reload canvas.rb...") do
begin
load (__FILE__)
rescue StandardError => e
error(e)
end
end
end
end
def redraw(w,ctx)
return if @redraw_error
return unless @blk
begin
@redraw_error=false
@error_log.text=""
begin
dde_animation=CanvasBinding.eval_in(@cv,ctx,@blk)
GLib::Timeout.add([dde_animation,50].max) { @canvas.redraw ; false } if dde_animation && dde_animation>0
rescue Exception => e
@redraw_error=true
error("Error in evaluate script :\n",e)
end
rescue Exception => e
@redraw_error=true
trace(e)
end
end
def execute()
content=@edit.buffer.text
@blk= content
File.open(@filedef,"w") {|f| f.write(content)} if content.size>30
@redraw_error=false
@canvas.redraw
rescue Exception => e
trace(e)
end
def log(*e)
@error_log.text+=e.join(" ")+"\n"
end
def trace(e)
@error_log.text=e.to_s + " : \n "+ e.backtrace[0..3].join("\n ")
end
def make_help(ta)
ta.text=DrawPrimitive.help_text
end
def make_example(ta)
src=File.dirname(__FILE__)+"/test.rb"
content=File.read(src)
ta.text=content.split(/(def component)|(end # endcomponent)/)[2]
end
def fload(file,content)
if File.exists?(file) && content==nil
content=File.read(file)
end
return unless content!=nil
@file=file
@mtime=File.exists?(file) ? File.mtime(@file) : 0
@content=content
@edit.buffer.text=content
end
end
#=====================================================================================
# Draw Primitives
#=====================================================================================
module DrawPrimitive
def error(*t) Message.error(*t) end
####################################### Simple drawing
def line(li,color="#000000",ep=2)
color=Ruiby.cv_color_html(color)
$ctx.set_line_width(ep)
$ctx.set_source_rgba(color.red/65000.0, color.green/65000.0, color.blue/65000.0, 1)
pt0,*poly=*li
$ctx.move_to(*pt0)
poly.each {|px| $ctx.line_to(*px) }
$ctx.stroke
end
def fill(li,color="#000000",ep=2)
color=Ruiby.cv_color_html(color)
$ctx.set_line_width(ep)
$ctx.set_source_rgba(color.red/65000.0, color.green/65000.0, color.blue/65000.0, 1)
pt0,*poly=*li
$ctx.move_to(*pt0)
poly.each {|px| $ctx.line_to(*px) }
$ctx.fill
end
def update(ms=20) @canvas.redraw ; sleep(ms*0.001) end
def tradu(l) l.each_slice(2).to_a end
def scale(l,sx,sy=nil) l.map {|(x,y)| [x*sx,y*(sy||sx)]} end
def trans(l,dx,dy) l.map {|(x,y)| [x+dx,y+dy]} end
def rotat(l,angle) sa,ca=Math.sin(angle),Math.cos(angle); l.map {|(x,y)| [x*ca-y*sa,x*sa+y*ca]} end
def crotat(l,x,y,angle) trans(rotat(trans(l,-x,-y),angle),x,y) end
def cscale(l,x,y,cx,cy=nil) trans(scale(trans(l,-x,-y),cx,cy),x,y) end
def rotation(cx,cy,a,&blk) grotation(cx,cy,a,&blk) end
def grotation(cx,cy,a,&blk)
if a==0
yield
return
end
$ctx.translate(cx,cy)
$ctx.rotate(a)
yield rescue error $!
$ctx.rotate(-a)
$ctx.translate(-cx,-cy)
end
def gscale(cx,cy,a,&blk)
if a==0
yield
return
end
$ctx.translate(cx,cy)
$ctx.scale(a,a)
yield rescue error $!
$ctx.scale(1.0/a,1.0/a)
$ctx.translate(-cx,-cy)
end
def pt(x,y,color="#000000",ep=2)
line([[x,y-ep/4],[x,y+ep/4]],color,ep)
end
def axe(min,max,pas,sens)
x0=20
x1=15
l=[]; l << [x0,x0]
(min+2*x0).step(max,pas) { |v|
l << [sens==0 ? v:x0, sens==1 ? v: x0 ]
l << [sens==0 ? v:x1, sens==1 ? v: x1 ]
l << [sens==0 ? v:x0, sens==1 ? v: x0 ]
}
line(l)
end
def axes(x0,maxx,maxy,pasx,pasy)
axe(x0,maxx,pasx,0)
axe(x0,maxy,pasy,1)
end
def plot_yfx(x0,pas,&b)
l=[]
x0.step(700,pas) { |x| y= b.call(x) ; l << [20+x,20+y] }
line(l)
end
def plot_xyft(t0,tmax,pas,xy,color="#000000",ep=2,&b)
l=[]
t0.step(tmax,pas) { |t|
t1= b.call(t)
l << [xy[0].call(t1)+20,xy[1].call(t1)+20]
}
line(l,color,ep)
pt(*l.first,"#AAAAFF",4)
pt(*l.last,"#FFAAAA",4)
end
def text(x,y,text,scale=1)
$ctx.set_line_width(1)
$ctx.set_source_rgba(0, 0 ,0, 1)
if scale==1
$ctx.move_to(x,y)
$ctx.show_text(text)
else
gscale(x,y,scale) { $ctx.move_to(0,0); $ctx.show_text(text) }
end
end
def def_animate(ms)
@dde_animation= ms
end
def self.help_text()
h=<<EEND
pt(x,y,color,width)
draw a point at x,y. color and stroke width optional
line([ [x,y],....],color,width)
draw a polyline. color and stroke width optional
fill([ [x,y],....],color,width)
draw a polygone. color and stroke width optional
tradu(l) [0,1,2,..] ===> [[0,1],[2,3],...]
scale(l,sx,sy=nil) scale by (sx,sy), form 0,0
trans(l,dx,dy) transmate by dx, dy
rotat(l,angle) rotation by angle from 0,0
crotat(l,x,y,angle) rotation by angle from cener x,y
cscale(l,x,y,cx,xy=nil) scake by cx,cy from center c,y
grotation(cx,cy,a) { instr } execute instr in rotated context (for text/image)
gscale(cx,cy,a) { instr } execute instr in scaled context (for text/image)
def_animate( n ) ask to reexecute this script n millisencondes forward
axes((xy0,maxx,maxy,stepx,stepy)
draw plotter"s axes (to be well done...)
plot_yfx(x0,step) { |x| f(x) }
draw a funtion y=f(x)
plot_xyft(t0,step) { |t| t=Math::PI/(t/700) ; [fx(x),fy(t)] }
draw a parametric curve
text(x,y,"Hello")
draw a text
text(x,y,"Hello",coef)
draw a text scaled by coef
def_animation( ms )
ask to rexecute this script aech ms millisecondes
Examples
0.step(100,10) { |x| pt( rand*x, rand*x ,"#000",4)
line([ [0,0],[100,0],[100,100],[0,1000],[50,50],[0,0]],"#FF0000",4)
axes(20,800,800,20,10)
plot_yfx(10,3) { |x| 20+100+100*Math.sin(Math::PI*x/40)}
EEND
end
end
Ruiby.start_secure { RubyApp.new }
def component()
stack {
frame("") { table(2,10,{set_column_spacings: 3}) do
row { cell_left label "c1" ; cell_left label "c2" ; cell label "c3" ; cell label "c4" ;}
row { cell_right label "c1" ; cell_left label "c2" ; cell label "c3" ; cell label "c4" ;}
row { cell_right label "c1" ; cell_hspan(3,button("hspan 3")) }
row { cell_vspan_top(2,button("vspan 2")) ; cell label "c2" ; cell label "c3" ; cell label "c4" ;}
row { cell_pass; cell label "c2" ; cell_hspan_right(2,pan("hspan 2")) }
end }
flow {
frame("List") {
stack {
@list=list("Demo",0,200)
flow {
button("s.content") { alert("Selected= #{@list.selection()}") }
button("s.index") { alert("iSelected= #{@list.index()}") }
}
}
}
frame("Grid") {
stack {
@grid=grid(%w{nom prenom age},100,200)
flow {
button("s.content") { alert("Selected= #{@grid.selection()}") }
button("s.index") { alert("iSelected= #{@grid.index()}") }
}
}
}
}
button("Exit") { exit! }
}
######### Populate list & grid
10.times { |i| @list.add_item("Hello #{i}") }
@grid.set_data([["a",1,1.0],["b",1,111111.0],["c",2222222222,1.0],["c",2222222222,1.0],["c",2222222222,1.0]])
Thread.new() do 5.times {
sleep(1)
gui_invoke { @grid.add_row([Time.now.to_s,Time.now.to_i,Time.now.to_f]) }
} end
end
def pan(t)
box { button(t) ; button("2 lines") }
end
end
Ruiby.start do
window = RubyApp.new
end
def component()
stack do
flow {
stack { @lab=stacki { } }
separator stack { @fr=stacki { } }
}
sloti( button("Exit") { exit! })
end
end # endcomponent
def run1
@ss=0
sleep 2
loop do
sleep(0.2)
gui_invoke_wait { @ss=@lab.children.size }
if @ss<20
gui_invoke { append_to(@lab) {
sloti(label(Time.now.to_f.to_s)) } }
else
gui_invoke { @lab.children[0..3].each { |w| delete(w) } }
end
end
end
def run2
ii=0
sleep 30
loop {
Open3.popen3("ping 10.177.235.1") { |si,so,se|
while str=(so.gets || se.gets)
if ii>10
gui_invoke_wait {
@fr.children[0..-3].each { |w| delete(w) }
}
ii=3
end
log str gui_invoke { append_to(@fr) { sloti(label(str.chomp)) } }
ii+=1
end
}
}
end
end
Ruiby.start do RubyApp.new end
#!/usr/bin/ruby
# encoding: utf-8
# Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
# LGPL
require_relative '../lib/Ruiby'
#require 'Ruiby'
Ruiby.app(title: "Text Animation", width: 900, height: 300) do
l,size=nil,40
stack { l=label("Hello Ruiby...",font: "Arial bold #{1}",bg: "#05A") }
after(500) do
anim(20) do
size=size>100 ? 10 : size+0.2
options={
font: "Arial bold #{size}",
fg: "#%02X%02X%02X" % [50+(200-size%200),50+size%200,50+size%200]
}
apply_options(l, options)
end
end
end
def component()
systray(1000,850, icon: "media/angel.png") do
syst_icon HAPPY_ICON
syst_add_button "Reload" do |state| load(__FILE__) rescue log $! ; end
syst_add_button "Execute Test" do |state| move(100,100);show; update() end
syst_quit_button true
end # end
#!/usr/bin/ruby
# encoding: utf-8
# Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
# LGPL
###########################################################
# multi_window_threading.rb :
# test threading :
# gui_invoke() and gui_invoke_in_window()
###########################################################
require_relative '../lib/Ruiby'
def run(lapp)
loop {
app=lapp[rand(lapp.length)]
gui_invoke_in_window(app) { @wdata.append "CouCou\n" }
gui_invoke { @wdata.append "CouCou in first window\n" }
p "appended to #{app.class}"
sleep 1
}
end
class RubyApp < Ruiby_gtk
def component
stack {
stacki {
label "window #{self.class}"
button "top" do
@wdata.append Time.now.to_s+"\n"
end
}
@wdata= text_area(400,100,:text=>"Hello\n")
buttoni("exit") { destroy(self) }
}
threader(10)
end
end
class RubyApp1 < RubyApp ; end
class RubyApp2 < RubyApp ; end
class RubyApp3 < RubyApp ; end
Ruiby.start do
l=[RubyApp1.new("1",400,100),RubyApp2.new("2",300,100),RubyApp3.new("3",200,100)]
Ruiby.update
Thread.new(l) { |lapp| run(lapp) }
end
#!/usr/bin/ruby
# encoding: utf-8
# Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
# LGPL
require_relative '../lib/Ruiby'
class Win < Gtk::Window
include Ruiby
def initialize(t,w,h)
super()
add(@vb=Gtk::Box.new(:vertical, 3))
show_all
add_a_ruiby_button()
signal_connect "destroy" do Gtk.main_quit ; end
end
def add_a_ruiby_button()
ruiby_component do
append_to(@vb) do
button("Hello Word #{@vb.children.size}") {
add_a_ruiby_button()
}
end
end
end
end
Ruiby.start do Win.new("application title",350,10) end
# Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
# LGPL
################################################################################
# select * from netstat join tasklist where *.to_s like '%1%' ;)
################################################################################
raise("not windows!") unless RUBY_PLATFORM =~ /in.*32/
require 'gtk3'
require_relative '../lib/Ruiby'
$fi=ARGV[0] || "LISTENING"
$filtre=Regexp.new($fi)
class Ruiby_gtk
def make_list_process()
hpid={}
%x{tasklist}.split(/\r?\n/).each { |line|
ll=line.chomp.split(/\s+/)
next if ll.length<5
prog,pid,_,_,*l=ll
hpid[pid]= [prog,l.join(" ")]
}
hpid
end
def net_to_table(filtre)
hpid=make_list_process()
ret=[]
%x{netstat -ano}.split(/^/).each { |line|
_,src,dst,flag,pid=line.chomp.strip.split(/\s+/)
prog,s = hpid[pid]||["?","?"]
ret << [flag,src,dst,prog,pid.to_i,s] if [flag,src,dst,prog,pid,s].inspect =~ filtre
}
ret.sort { |a,b| a[4]<=>b[4]}
end
end
Ruiby.app(:width => 0, :height => 0, :title => "NetProg #{$fi}") do
@periode=2000
stack do
@grid=grid(%w{flag source destination proc pid proc-size},500,100)
@grid.set_data(net_to_table($filtre))
buttoni("Refresh") { @grid.set_data(net_to_table($filtre)) }
flowi do
button("Filter") { prompt("Filter ?",$fi) { |value| $fi=value;$filtre=Regexp.new($fi) } }
button("Periode") {
prompt("periode (ms) ?",@periode.to_s) { |value|
delete(@ann)
@periode=[1000,20000,value.to_i].sort[1]
@ann=anim(@periode) {
Thread.new {
d=net_to_table($filtre) ; gui_invoke { @grid.set_data(d) }
} unless @active.active?
}
}
}
@active=check_button("Freese",false)
end
end
@ann=anim(@periode) {
Thread.new {
d=net_to_table($filtre) ; gui_invoke { @grid.set_data(d) }
} unless @active.active?
}
end
def component()
(puts "\n\n####define style...####\n\n" ; def_style "* { background-image: -gtk-gradient(linear, left top, left bottom, from(#AAA), to(@888));border-width: 3;}") if ARGV.size>0 && ARGV[0]=~/css/i
after(1000) {puts "\n\n\n" ; Gem.loaded_specs.each {|name,gem| puts " #{gem.name}-#{gem.version}"} }
mlog 'before Component'
stack do
htoolbar_with_icon_text do
button_icon_text("document-open","Open...") { edit(__FILE__) }
button_icon_text("document-save","Save.."){ alert("Save what ?")}
button_icon_text("sep")
button_icon_text("edit-undo","Undo") { alert( "undo")}
button_icon_text("edit-redo","Redo") { alert("redo") }
end
flowi do
end
separator
flow do
@left=stack {
test_table
test_canvas
}
separator
stack do
test_notebook
flowi {
button("Test dialogs...") { do_special_actions() }
button("Exit") { ruiby_exit }
}
end
end # end flow
mlog 'after Component'
end # end global stack
end # end def Component
def test_table
frame("Forms",margins: 10,bg: "#FEE") { table(2,10,{set_column_spacings: 3}) do
row { cell_right(label "state") ; cell(button("set") { alert("?") }) }
row { cell_right label "speed" ; cell(entry("aa")) }
row { cell_right label "size" ; cell ientry(11,{:min=>0,:max=>100,:by=>1}) }
row { cell_right label "feeling" ; cell islider(10,{:min=>0,:max=>100,:by=>1}) }
row { cell_right label "speedy" ; cell(toggle_button("on","off",false) {|ok| alert ok ? "Off": "On" }) }
row { cell label "acceleration type" ; cell hradio_buttons(%w{aa bb cc},1) }
row { cell label "mode on" ; cell check_button("",false) }
row { cell label "mode off" ; cell check_button("",true) }
row { cell_left label "Attribute" ; cell combo({"aaa"=>1,"bbb"=>2,"ccc"=>3},1) }
row { cell_left label "Color" ; cell box { color_choice() {|c| alert(c.to_s)} } }
end
}
end
def test_canvas()
flow do
stack do
button("Color") {
@color=ask_color()
}
tooltip("Please choose the <b>drawing</b> <i>color</i>...")
@epaisseur=islider(1,{:min=>1,:max=>30,:by=>1})
tooltip("Please choose the <b>drawing</b> pen <i>width</i>...")
end
@ldraw=[] ; @color= html_color("#FF4422");
canvas(200,100) do
on_canvas_draw { |w,cr|
@ldraw.each do |line|
next if line.size<3
color,ep,pt0,*poly=*line
cr.set_line_width(ep)
cr.set_source_rgba(color.red/65000.0, color.green/65000.0, color.blue/65000.0, 1)
cr.move_to(*pt0)
poly.each {|px| cr.line_to(*px) }
cr.stroke
end
}
on_canvas_button_press{ |w,e|
pt= [e.x,e.y] ; @ldraw << [@color,@epaisseur.value,pt] ; pt
}
on_canvas_button_motion { |w,e,o|
if o
pt= [e.x,e.y] ; (@ldraw.last << pt) if pt[0]!=o[0] || pt[1]!=o[1] ; pt
end
}
on_canvas_button_release { |w,e,o|
pt= [e.x,e.y] ; (@ldraw.last << pt)
}
end
stacki {
label("Popup test...")
popup(canvas(50,200) { }) {
pp_item("copy") { alert "copy.." }
pp_item("cut") { alert "cut..." }
pp_item("past") { alert "pasting.." }
pp_separator
pp_item("Save") { alert "Saving.." }
}
}
end
end
##############################################################
# N o t e b o o k
##############################################################
def test_notebook
notebook do
page("","#go-home") { test_page }
page("Source") {
if ed=source_editor(:width=>200,:height=>300,:lang=> "ruby", :font=> "Courier new 8",:on_change=> proc { edit_change })
@editor=ed.editor
@editor.buffer.text='def comp'+'onent'+File.read(__FILE__).split(/comp[o]nent/)[1]
end
}
page("Cv") { test_canvas_draw }
page("Grids") { test_list_grid }
page("Divers") { test_dialog }
page("Prop.") { test_properties(0) }
page("Menu") { test_menu }
page("Scrol.") { test_pan_scroll}
end # end notebook
end
def test_page
stack(margins: 40) {
image(Ruiby::DIR+"/../media/ruiby.png")
label("A Notebook Page with icon as button-title",{font: "Arial 18"})
buttoni("Test css defininition...") {
ici=self
dialog_async("Edit Css style...",:response => proc {def_style(@css_editor.editor.buffer.text);false}) {
@css_editor=source_editor(:width=>500,:height=>300,:lang=> "css", :font=> "Courier new 12")
@css_editor.editor.buffer.text="* { background-image: \n -gtk-gradient(linear, left top, left bottom, \n from(#AAA), to(@888));\n border-width: 3;\n}"
}
}
buttoni("Test Crud...") { test_crud }
}
end
def test_canvas_draw()
stack do
canvas(400,300) do
on_canvas_draw do |cv,cr|
cv.draw_pie(
200,300,70,
[
[1,"#F00","P1e"],[2,"#00F","P2"],[3,"#0F0","P3"],
[1,"#F00","P1"],[2,"#00F","P2"],[3,"#0F0","P3"],
[4,"#F00","P1"],[5,"#00F","P2"],[6,"#0F0","P3"]
],
true)
cv.draw_pie(100,70,15,[1,8,3,2])
cv.draw_image(400,10,"#{Ruiby::DIR}/../samples/media/angel.png")
cv.scale(400,200,0.5) {
w=80
cv.draw_rectangle(w+10,0,w+20,2*w+20,20,"#000","#0E0",1)
cv.draw_image(0,0,"#{Ruiby::DIR}/../samples/media/angel.png")
cv.draw_rectangle(0,0,w,2*w,0,"#000",nil,4)
}
# polyline and polygone...
cv.draw_line([1,10,100,10,100,10,100,110],"#0A0",1)
cv.draw_polygon([1,110,100,110,100,110,100,210,1,110],"#0AA","#A00",1)
# horizontal text
cv.draw_line([200,0,200,120],"#000",1)
cv.draw_text(200,70,"Hello !",6,"#000")
cv.draw_text(200,90,"Hello, with bg",2,"#000","#EEE")
cv.draw_text_left(200,100,"Right aligned",0.8,"#000")
cv.draw_text_center(200,130,"centered aligned ✈",2,"#000","#CAA")
# not horizontal text
cv.rotation(290,100,1.0/16) {
cv.draw_point(0,0,"#066",3)
cv.draw_text(0,0,"1234567890",1,"#000")
}
# gant chart
x0,y0,x1,y1=600,130,800,130
vmin,vmax=0,10
cv.draw_rectangle(x0,y0-5,x1-x0,55,0,"#000","#050",1)
cv.draw_varbarr(x0,y0,x1,y1 ,vmin,vmax,[[0,0],[2,0]],10) {|value| "#F00"}
cv.draw_varbarr(x0,y0+10,x1,y1+10 ,vmin,vmax,[[2,0],[3,0]],10) {|value| "#0FF"}
cv.draw_varbarr(x0,y0+20,x1,y1+20 ,vmin,vmax,[[3,0],[4,0]],10) {|value| "#F0F"}
cv.draw_varbarr(x0,y0+30,x1,y1+30 ,vmin,vmax,[[5.5,0],[7.5,0]],10) {|value| "#FF0"}
cv.draw_varbarr(x0,y0+40,x1,y1+40 ,vmin,vmax,[
[0,2],[1,2],[1,0],[2,0],[3,1],[4,1],[5,2],[6,2],[8,3],[10,3]
],10) {|value| blue='%01X' % (value*5) ; "#A090#{blue}0" }
15.times { |c| 15.times { |l| cv.draw_point(600+c*10,200+l*10,"#000",2)} }
cv.draw_arc( 500,200,30,0.1,0.3,0,"#F00","#0F0")
cv.draw_arc2(520,210,30,0.1,0.3,0,"#F0F","#00F")
4.times { |f|
cv.draw_arc2(530,290,20,
0.1+0.25*f,0.1+0.25*(f+1),
0,"#F0F","#0AA" )
}
end
end
pl=plot(200,100,{
"a"=> { data: aleacurve(2) , color: "#A0A0FF" , maxlendata: 100},
"b"=> { data: aleacurve(3) , color: "#FFA0A0"}
},{
bg: "#383"
}
)
end
end
def test_list_grid()
flow {
stack {
frame("CB on List") {
stacki{
@list0=list("callback on selection",100,200) { |li| alert("Selections are : #{li.join(',')}") }
@list0.set_data((0..100).to_a.map(&:to_s))
buttoni("set selection no2") { @list0.set_selection(1) }
}
}
frame("Grid") {
stack { stacki {
@grid=grid(%w{nom prenom age},100,150)
flow {
button("s.content") { alert("Selected= #{@grid.selection()}") }
button("s.index") { alert("iSelected= #{@grid.index()}") }
}
} }
}
}
stack {
frame("List with getter") {
@list=list("Demo",0,100)
flowi {
button("s.content") { alert("Selected= #{@list.selection()}") }
button("s.index") { alert("iSelected= #{@list.index()}") }
}
}
frame("TreeView") {
tr=tree_grid(%w{month name prename 0age ?male},100,200)
tr.set_data({
janvier: {
s1:["aaa","bbb",22,true],
s2:["aaa","bbb",33,false],
s3:["aaa","bbb",111,true],
s4:["aaa","bbb",0xFFFF,true],
},
fevrier: {
s1:["aaa","bbb",22,true],
s2:["aaa","bbb",33,false],
},
})
}
}
}
10.times { |i| @list.add_item("Hello #{i}") }
@grid.set_data((1..30).map { |n| ["e#{n}",n,1.0*n]})
end
def test_dialog()
stack do
stacki {
frame("Buttons in frame") {
flow { sloti(button("packed with sloti()") {alert("button packed with sloti()")})
@bref=sloti(button("bb")) ; button("packed with slot()") ;
}
}
frame("regular size sub-widget (homogeneous)") {
flow {
regular
5.times { |i| button("**"*(1+i)) ; tooltip("button <b>#{i+1}</b>") }
}
}
}
sloti(button_expand("Test button_expand()") {
flow { 2.times { |c| stack { 5.times { |a| label("#{c}x#{a}",{font: "arial 33"}) } } } }
})
buttoni("dailog...") do
rep=dialog("modal window...") {
label("eee")
list("aa",100,100)
}
alert("Response was "+rep.to_s)
end
space
buttoni("dailog async...") do
dialog_async("modal window...",{response: proc {|a| alert(a);true}}) {
label("eee")
list("aa",100,100)
}
end
end
end
def test_properties(no)
flowi {
sloti(button("#weather-severe-alert") { alert("image button!")})
tt={int: 1,float: 1.0, array: [1,2,3], hash: {a:1, b:2}}
properties("props editable",tt,{edit: true}) { |a| log(a.inspect);log(tt.inspect) }
properties("props show",tt)
}
h={};70.times { |i| h[i]= "aaa#{i+100}" }
properties("very big propertys editable",h,{edit: true,scroll: [100,200]}) { |a| log(a.inspect);log(h.inspect) }
end
def test_crud()
stack do
$gheader=%w{id first-name last-name age}
$gdata=[%w{regis aubarede 12},%w{siger ederabu 21},%w{baraque aubama 12},%w{ruiby ruby 1}]
i=-1; $gdata.map! { |l| i+=1; [i]+l }
a=PopupTable.new("title of dialog",400,200,
$gheader,
$gdata,
{
"Delete" => proc {|line|
$gdata.select! { |l| l[0] !=line[0] || l[1] !=line[1]}
a.update($gdata)
},
"Duplicate" => proc {|line|
nline=line.clone
nline[0]=$gdata.size
$gdata << nline
a.update($gdata)
},
"Create" => proc {|line|
nline=line.clone.map {|v| ""}
nline[0]=$gdata.size
$gdata << nline
a.update($gdata)
},
"Edit" => proc {|line|
data={} ;line.zip($gheader) { |v,k| data[k]=v }
PopupForm.new("Edit #{line[1]}",0,0,data,{
"Rename" => proc {|w,cdata| cdata['first-name']+="+" ; w.set_data(cdata)},
"button-orrient" => "h"
}) do |h|
$gdata.map! { |l| l[0] ==h.values[0] ? h.values : l}
a.update($gdata)
end
},
}
) { |data| alert data.map { |k| k.join ', '}.join("\n") }
end
end
def test_menu
stack {
menu_bar {
menu("File Example") {
menu_button("Open") { alert("o") }
menu_button("Close") { alert("i") }
menu_separator
menu_checkbutton("Lock...") { |w|
w.toggle
append_to(@f) { button("ee #{}") }
}
}
menu("Edit Example") {
menu_button("Copy") { alert("a") }
}
}
frame("Accordeon") {
accordion do
("A".."G").each do |cc|
aitem("#{cc} Flip...") do
5.times { |i|
alabel("#{cc}e#{i}") { alert("#{cc} x#{i}") }
}
end
end
end
label "x"
}
calendar()
}
end
def test_pan_scroll()
stack do
sloti(label("Test scrolled zone"))
stack_paned 300,0.5 do
vbox_scrolled(-1,20) {
30.times { |i|
flow { sloti(button("eeee#{i}"));sloti(button("eeee")) }
}
}
vbox_scrolled(-1,20) {
30.times { |i|
flow { sloti(button("eeee#{i}"));sloti(button("eeee"));sloti(button("aaa"*100)) }
}
}
end
end
end
def aleacurve(pas=1)
l=[[50,0]]
200.times { l << [[0,300,l.last[0]+rand(-pas..pas)].sort[1],l.last[1]+1] }
l
end
def edit_change()
alert("please, do not change my code..")
end
def do_special_actions()
10.times { |i| log("#{i} "+ ("*"*(i+1))) }
dialog("Dialog tests") do
stack do
labeli " alert, prompt, file chosser and log "
c={width: 200,height: 40,font: "Arial old 12"}
button("Dialog",c) {
@std=nil
@std=dialog_async "test dialog" do
stack {
a=text_area(300,200)
a.text="ddd dd ddd ddd dd\n ddd"*200
separator
flowi{ button("ddd") {@std.destroy}; button("aaa") {@std.destroy}}
}
end
}
button("alert", c) { alert("alert is ok?") }
button("ask", c) { log ask("alert is ok?") }
button("prompt", c) { log prompt("test prompt()!\nveuillezz saisir un text de lonqueur \n plus grande que trois") { |reponse| reponse && reponse.size>3 }}
button("file Exist",c) { log ask_file_to_read(".","*.rb") }
button("file new/Exist",c) { log ask_file_to_write(".","*.rb") }
button("Dir existant",c) { log ask_dir_to_read(".") }
button("Dir new/Exist",c) { log ask_dir_to_write(".") }
button("dialog...") do
dialog("title") {
stack {
fields([["prop1","1"],["prop1","2"],["properties1","3"]]) {|*avalues| alert(avalues.join(", "))}
separator
}
}
end
button("dialog async...") do
dialog_async("title",:response=> proc { ask("ok") }) {
stack {
label "without validations.."
fields([["prop1","1"],["prop1","2"],["properties1","3"]])
separator
}
}
end
button("Timeline",c) { do_timeline() }
end
end
end
def do_timeline()
dialog("ruiby/gtk startup timestamps") do
lline=[[10 ,180]]
ltext=[]
xmin, xmax= $mlog.first[0], $mlog.last[0]
a,b,ot = (400.0-20)/(xmax-xmin) , 10.0 , 0
$mlog.each_with_index {|(time,text),i|
pos=a*time+b
h=50+i*15
lline << [pos,180] ;lline << [pos,h] ;lline << [pos,180]
ltext << [[pos+5,h],text+ "(#{time-ot} ms)"]
ot=time
}
labeli("Total time : #{xmax} milliseconds")
canvas(500,200) {
on_canvas_draw { |w,cr|
w.init_ctx("#774433","#FFFFFF",2)
w.draw_line(lline.flatten)
ltext.each { |(pos,text)| w.draw_text(*pos,text) }
}
}
end
end
#end
# encoding: utf-8
# Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
# LGPL
require_relative '../lib/Ruiby.rb'
def make_data(xmin,xmax,vmin,vmax)
last=(vmax+vmin)/2
p=(vmax-vmin)/50.0
xmin.step(xmax,2).map {|x|
y=[vmin,vmax,last+p*rand(-1..1)].sort[1]
last=y
[y,x]
}
end
$curves={
a: {
data: make_data(200 ,1300 ,100,1000), name:"Regis",
color: "#FAA",xminmax: [0,1300],yminmax: [100,1000]
},
b: {
data: make_data(0 ,1000 ,10,100), name:"Alonso",
color: "#AAF",xminmax: [0,1300],yminmax: [10,100]
}
}
Ruiby.app width: 800,height: 300, title: "Plot curves" do
flow do
stacki do
$curves.values.each {|d| labeli d[:name],bg: d[:color]}
label("",bg:"#333")
end
c=plot(800,300,$curves,{
bg: "#333",
tracker: [proc {|x| "Date: #{Time.at(Time.now.to_i+x)}"},proc {|name,y| "#{name}: #{y} $"}]
})
lb1=([[0,0]]+$curves[:a][:data]).each_cons(2).each_with_object([]) {|((y0,x0),(y1,x1)),l|
c1=y0<300 ? "#F00" : y0>500 ? "#0F0": "#444"
c2=y1<300 ? "#F00" : y1>500 ? "#0F0": "#444"
(l << [x0,c1]) if c1!=c2
(l << [x1,c2]) if c1!=c2
}
c.add_bar("rules a",[[0,"#00F"]]+lb1+[[1300,"#FFF"]])
end
end
# Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
# LGPL
require_relative '../lib/Ruiby.rb'
################################ App test ###################################
Ruiby.app do
stacki {
labeli( <<-EEND ,font: "Arial 14",bg: "#004455", fg: "#CCCCCC")
Test variables binding for entry/slider/CheckButton/toggleButton/radioButton/label.
Observer pattern :
widget can be observer of a variable,
so variable modification will be showing in all widget observer,
and a edition by a observer widget will be notified to all widget concerned.
EEND
v1=DynVar.stock("v1",1)
v2=DynVar.stock("v2","99")
v3=DynVar.stock("v3",true)
v4=DynVar.stock("v4",1)
flow {
framei("Int value",margins: 20) {
framei("Dyn widget") {
flowi { labeli "dyn label: " ; label v1,bg: "#FFCCCC" ; bourrage 10 }
flowi { labeli "dyn entry : " ; entry v1 }
flowi { labeli "dyn radiobutton: " ; hradio_buttons(["FALSE","TRUE","two"],v1) }
flowi { labeli "dyn show/edit slider: " ; islider v1 }
flowi { labeli "dyn show slider: " ; islider v1 do end}
flowi { labeli "dyn checkButton: " ; check_button "!= 0",v3 }
flowi { labeli "dyn toggle: " ; toggle_button "FALSE","TRUE",v3 }
}
flowi { labeli "editor (not dyn) :" ; entry("") { |v| v1.value=v.to_i } }
flowi {
labeli "+/- button :"
button("v1++") { v1.value=v1.value+1}
button("v1--") { v1.value=v1.value-1}
}
}
framei("String value",margins: 20) {
framei("Dyn widget") {
flowi { labeli "dyn entry : " ; entry v2 }
}
flowi { labeli "editor (not dyn) :" ; entry("") { |v| v2.value=v } }
flowi { labeli "+/- button :" ; button("v2++") { v2.value=v2.value+"a"}; button("v2--") { v2.value=v2.value[0..-2] } }
}
framei("Boolean value",margins: 20) {
framei("Dyn widget") {
flowi { labeli "dyn check button: " ; check_button "True", v3 }
flowi { labeli "dyn check button: " ; check_button "True", v3 }
}
labeli(v3)
separator
flowi { button("set tot true ") { v3.value=true}; button("set to false") { v3.value=false } }
}
}
flow {
Lieu=make_DynClass({"adresse" => "unknown" , "ville" => "Rouen" })
l1=Lieu.new({"adresse" => "1 route du chemin vert", "ville" => "Caen"})
framei("ObjectBinding",margins: 20) {
flowi { labeli "adresse : " ,width: 200; entry l1.adresse}
flowi { labeli "ville : ",width: 200 ; entry l1.ville}
flowi { regular
button(" Validation ") { alert l1.to_h }
button(" Reset ") { l1.adresse.value=""; l1.ville.value="" }
}
}
Lieu2=make_StockDynClass({"adresse" => "unknown" , "ville" => "Rouen" })
l2=Lieu2.new("add",{"adresse" => "2 route du chemin vert", "ville" => "Caen"})
framei("Stoked ObjectBinding",margins: 20) {
flowi { labeli "adresse : " ,width: 200; entry l2.adresse }
flowi { labeli "ville : ",width: 200 ; entry l2.ville }
flowi {
regular
button("Validation") { alert l2.to_h }
button("Reset") { l2.adresse.value=""; l2.ville.value="" }
}
}
}
buttoni("Normal Exit") { ruiby_exit } # will save l2 data at exit time, (not done on exit!(0) )
}
end
# Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com>
# LGPL
require_relative '../lib/Ruiby.rb'
Ruiby.app width: 300,height: 200,title:"Calc" do
chrome(false)
@calc=make_StockDynObject("calc",{"res"=> 0,"value" => "0" , "stack" => [] })
@calc.stack.value=eval @calc.stack.value
stack do
flowi {
sloti(toggle_button("D",false) {|v| chrome(v)})
frame("Calculator",margins: 20) do
flowi { labeli "Resultat: " ,width: 200 ; entry(@calc.res) ; button("reset") { @calc.res.value="" ; @calc.stack.value=["0","reset"]}}
flowi { labeli "Value: " ,width: 200 ; entry(@calc.value) ; button("reset") { @calc.value.value="" }}
flowi do
regular
'+ - * / syn cos'.split(' ').each { |op| button(op) { ope(op,@calc.res,@calc.value) } }
end
end
}
flowi {
regular
button("Reset") { @calc.stack.value=["0","reset"] ; @calc.res.value="0" ; @calc.value.value=""}
button("Trace") { alert((@calc.stack.value.slice(-20..-1)||@calc.stack.value).each_slice(2).map {|b,a| "%s %10.5f" % [a,b]}.reverse.join("\n")) }
button("Exit") { ruiby_exit }
}
end
def ope(ope,dvRes,dvVal)
return if dvVal.value==""
expr=ope.size==1 ? "#{dvRes.value.to_f.to_s} #{ope} #{dvVal.value.to_f.to_s}" : "Math.#{ope}(#{dvRes.value.to_f.to_s})"
res= eval(expr).to_f
@calc.stack.value.push(dvVal.value)
@calc.stack.value.push(ope)
(ope.size==1 ? dvRes : dvVal).value=res.to_s
#dvVal.value=""
rescue Exception
alert("Expretion exotique : #{expr}")
end
end
No example for : install, install_composant, force_update, on_canvas_resize, on_canvas_key_press, canvasOld, clear, clear_append_to, show_all_children, slot_append_before, slot_append_after, snapshot, log_as_widget, get_selection, vradio_buttons, fentry, field, progress, panel_progress, out, text_area_dyn, spacei, show_source, label_clickable, fslider, progress_bar, levelbar, clickable, pclickable, pclickablie, var_box, var_boxi, sentence, sentenci, current_layout, accept, spacing, right, autoslot, razslot, backgroundi, haccordion, panel_async, on_delete, panel, scrolled_win, popup_clear_append, get_image, get_pixmap, get_stockicon_pixbuf, get_icon, get_image_from, get_pixbuf, exe, next_row, cell_vspan, cell_hvspan, cell_span, cell_hspan_left, cell_top, cell_bottom, cell_vspan_bottom, save_stock, set_name, observ, do_notification, set_as_bool, get_as_bool, set_trace, button_list, wtree, message, dialog_chooser, promptSync, aaa_generalities, get_current_container, get_config, css_name, attribs, color_conversion, widget_properties, toolbar_separator, button_left_icon_text, show_methods, video, tv, append_and_prompt, replace_current, get_history, set_history, get_line, terminal, init_threader, on_idle, gui_async_pending_size, gui_async_wait_size, syst_add_sepratator, syst_add_check, systray_setup, show_app, hide_app, close_dialog, on_resize, on_destroy, set_window_icon, rposition