Ruiby DSL Documentation
Ruiby Version: 3.23.3
Generated at : 2017-11-28 19:12:38 +0100
See code example
Search :




generalities
All Ruiby commands correspond of
  • a object creation (container, widget), see later,
  • complement set propertie to current/alst widget created : css_name(), space(), tooltip()
  • a immediate dialog (modal) command :

  • a immediate command, the can be used in callback code: gui manipulation... :



    2 kinds of objects :
  • container

    Containers organyze children widget, but show (almost) nothing.
    Children must be created in container bloc, container can contains widget and container :
     
    | stack do
    | button("Hello")
    | label(" word")
    | flow { button("x") ; label("y") }
    | end

  • widgets

    Widget must be placed in a container.
    2 kinds of placement :
  • sloted : widget take all disponible space ( gtk: pack(expand,fill) ), share
    space with other sloted widget in same container
  • slotied : widget take only necessary place ( gtk: pack(no-expand , no-fill) )


    |------------------------|
    |<buttoni >|
    |<labeli >|
    |<--------------------- >|
    |< >|
    |< button >|
    |< >|
    |<--------------------- >|
    |< >|
    |< label >|
    |< >|
    |<--------------------- >|
    |<buttoni >|
    |------------------------|


    by default, all widgetcontainer are sloted !
    widget name ended by 'i' ( buttoni, labeli, stacki , flowi ...) are slotied

    slot() command is deprecated. sloti() command must be use if *i command
    do not exist : w=sloti( widgetname() {...} )
    space() can be used for slot a empty space.

    Attachement to a side of a container is not supported. You must put empty sloted widget
    in free space:
  • scoth xxxx in top of frame : >stack { stacki { xxx } ; stack { } }
  • scoth xxxx in bottom of frame : >stack { stack { } ; stacki { xxx } }
  • scoth xxxx in left of frame : >flow { flowi { xxx } ; stack { } }

    Dynamique variables bindings
    The class ::DynVar support a single value and the observer pattern.
    So widgets can be associate with an dynamique value :
  • if the value change, the widget change the view accordingly to the new value,
  • if the view change by operator action, the value change accordingly.
  • Threading is care : widget updates will be done in maint thread context

    Widgets which supports DynVar are :
  • entry,ientry,
  • label,
  • islider,
  • check_button

    This list will be extende to combo_button, toggle_button, list, grid ...

    'make_DynClass' and 'make_StockDynClass' can be use for creation of Class/object
    which contain DynVar : as OStruct, but data members are DynVar.

  • @calc=make_DynObject({"resultat"=> 0,"value" => "0" , "stack" => [] })
    @calc.resultat => @calc.resultat.value="X" ; x= @calc.resultat.value

  • @calc=make_StockDynObject("name",{"resultat"=> 0,"value" => "0" , "stack" => [] })
    create a object, name him for Stock, give default values if object does not exists
    in current stock.

    ex
  • accept
    def accept?(t)
    mock class which can be push to layout stack : they accept some
    specific type of commands
    ex
    accordion
    def accordion()
    Accordion
    create a accordion menu.
    must contain aitem() which must containe alabel() :
    accordion { aitem(txt) { alabel(lib) { code }; ...} ... }
    ex
    add
    def add(s)
    ex
    after
    def after(n,&blk)
    as anim, but one shot, after some millisecs
    no threading: the bloc is evaluated by gtk mainloop in main thread context
    ex
    aitem
    def aitem(txt,&blk)
    a button menu in accordion
    bloc is evaluate for create/view a list of alabel :
    aitem(txt) { alabel(lib) { code }; ...}
    ex
    alabel
    def alabel(txt,&blk)
    create a button-entry in a accordion menu
    bloc is evaluate on user click. must be in aitem() bloc :
    accordion { aitem(txt) { alabel(lib) { code }; ...} ... }
    ex
    alert
    def alert(*txt)
    alert(txt): modal popup with text (as in html)
    ex
    anim
    def anim(n,&blk)
    ex
    append
    def append(text)
    ex
    append and prompt
    def append_and_prompt(text)
    ex
    append to
    def append_to(cont,&blk)
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    append the result of bloc parameter to a contener (stack or flow)
    thread protected
    Usage :
    @stack= stack {}
    . . . .
    append_to(@stack) { button("Hello") }
    ex
    apply options
    def apply_options(w,options)
    apply some styles property to an existing widget.
    options are :size, :width; :height, :margins, :bg, :fg, :font
    apply_options(w,
    :size=> [10,10],
    :width=>100, :heigh=>200,
    :margins=> 10
    :bg=>'FF00AA",
    :fg=> Gdk::Color:RED,
    :tooltip=> "Hello...",
    :font=> "Tahoma bold 32"
    )
    ex
    ask
    def ask(*txt)
    show a modal dialog, asking yes/no question, return boolean response
    ex
    ask color
    def ask_color()
    modal dialog asking a color
    ex
    ask dir to read
    def ask_dir_to_read(initial_dir=nil)
    ask a existent dir name
    ex
    ask dir to write
    def ask_dir_to_write(initial_dir=nil)
    ask a dir name
    ex
    ask file to read
    def ask_file_to_read(dir,filter)
    File dialog
    ask a existent file name
    ex
    ask file to write
    def ask_file_to_write(dir,filter)
    ask a filename for creation/modification
    ex
    attribs
    def attribs(w,options)
    Commands
    common widget property applied for (almost) all widget.
    options are last argument of every dsl command, see apply_options
    ex
    autoslot
    def autoslot(w=nil)
    slot() precedently created widget if not sloted.
    this is done by attribs(w) which is call after construction of almost all widget
    ex
    background
    def background(color,options={},&b)
    set a background color to current container
    Usage : stack { background("FF0000") { flow { ...} } }
    ex
    backgroundi
    def backgroundi(color,options={},&b)
    ex
    bourrage
    def bourrage(n=1)
    ex
    box
    def box(sens=:vertical)
    box { } container which manage children widget without slot (pack())
    in parent container.
    Use it for cell in table, notebook : table { row { cell(box { });... }; ... }
    ex
    button
    def button(text,option={},&blk)
    create button, with text (or image if txt start with a '')
    block argument is evaluate at button click
    ex
    button expand
    def button_expand(text,initiale_state=false,options={},&b)
    a button which show a sub-frame on action
    ex
    button icon text
    def button_icon_text(icon,text="",options={},&b)
    a button with icon+text verticaly aligned,
    can be call anywhere, and in htool_bar_with_icon_text
    option is label options and isize ( option for icon size, see label())
    ex
    button left icon text
    def button_left_icon_text(icon,text="",options={},&b)
    ex
    button list
    def button_list()
    ex
    buttoni
    def buttoni(text,option={},&blk)
    create button, with text (or image if txt start with a '')
    block argument is evaluate at button click, slotied :
    packed without expand for share free place
    ex
    calendar
    def calendar(time=Time.now,options={})
    calendar
    Month Calendar with callback on month/year move and day selection :
    calendar(Time.now-24*3600, :selection => proc {|day| } , :changed => proc {|widget| }
    calendar respond to
  • set_time(time) ; set a selected date from a Time object
  • get_time() ; return Time of selected day
    ex
  • canvas
    def canvas(width,height,option={})
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    Create a drawing area, for pixel/vectoriel draw
    for interactive actions see test.rb fo little example.

    @cv=canvas(width,height,opt) do
    on_canvas_draw { |w,ctx| myDraw(w,ctx) }
    on_canvas_button_press {|w,e| [e.x,e.y] } must return a object which will given to next move/release callback
    on_canvas_button_motion {|w,e,o| n=[e.x,e.y] ; ... ; n }
    on_canvas_button_release {|w,e,o| ... }
    on_canvas_keypress {|w,key| ... }
    end

    for drawing in canvas, this commands are usable.
    basic gtk commands can still be uses ( move_to(), line_to()... )
    def myDraw(w,ctx)
    w.init_ctx(color_fg="000000",color_bg="FFFFFF",width=1)
    w.draw_point(x1,y1,color,width)
    w.draw_polygon([x,y,...],colorFill,colorStroke,widthStroke)
    w.draw_circle(cx,cy,rayon,colorFill,colorStroke,widthStroke)
    w.draw_rectangle(x0,y0,w,h, r,widthStroke,colorFill,w)
    cv.draw_rounded_rectangle(x0,y0,w,h,ar,colorStroke,colorFill,widthStroke)
    w.draw_pie(x,y,r,l_ratio_color_label)
    w.draw_arc(x,y,r,start,eend,width,color_stroke,color_fill=nil) camenber
    w.draw_arc2(x,y,r,start,eend,width,color_stroke,color_fill=nil) circle fraction
    w.draw_varbarr(x0,y0,x1,y1,vmin,vmax,l_date_value,width) {|value| color}
    w.draw_image(x,y,filename,sx,sy)
    cv.ctx_font(name,size) choose font name and size for next draw_text...
    w.draw_text(x,y,text,scale,color,bgcolor=nil)
    w.draw_text_left(x,y,text,scale,color,bgcolor=nil)
    w.draw_text_center(x,y,text,scale,color,bgcolor=nil)
    lxy=w.translate(lxy,dx=0,dy=0) move a list of points
    lxy=w.rotate(lxy,x0,y0,angle) rotate a list of points
    cv.rotation(cx,cy,a) { draw... }
    w.scale(10,20,2) { w.draw_image(3,0,filename) }
    >> draw in a transladed/scaled coord system
    >> image will be draw at 16/20 (10+3*2)/(20+0*2)
    , and size doubled

    end
    gradient can be use for recangle and polygone, see samples/gradients.rb
    in place od String bg-color, say Array : w{type direction color1 color2 ...}
    type = linear/radial direction : tb Top->Bottom, bu Bottom->Up , lr: Left->Right, ..., trb -> TopLeft -> BottomRight
    ex
    canvasOld
    def canvasOld(width,height,option={})
    DEPRECATED; Create a drawing area, for pixel draw
    option can define closure :mouse_down :mouse_up :mouse_move
    for interactive actions
    ex
    cell
    def cell(w)
    a cell in a row/table. take all space, centered
    ex
    cell bottom
    def cell_bottom(w)
    create a cell in a row/table, bottom aligned
    ex
    cell hspan
    def cell_hspan(n,w)
    a cell in a row/table. take space of n cells, horizontaly
    ex
    cell hspan left
    def cell_hspan_left(n,w)
    create a hspan_cell in a row/table, left justified
    ex
    cell hspan right
    def cell_hspan_right(n,w)
    create a hspan_cell in a row/table, right justified
    ex
    cell hvspan
    def cell_hvspan(n,m,w)
    a cell in a row/table. take space of n x m cells, horizontaly x verticaly
    ex
    cell left
    def cell_left(w)
    create a cell in a row/table, left justified
    ex
    cell pass
    def cell_pass(n=1)
    keep empty n cell consecutive on current row
    ex
    cell right
    def cell_right(w)
    create a cell in a row/table, right justified
    ex
    cell span
    def cell_span(n=2,w)
    a cell in a row/table. take space of n cells, horizontaly
    ex
    cell top
    def cell_top(w)
    create a cell in a row/table, top aligned
    ex
    cell vspan
    def cell_vspan(n,w)
    a cell in a row/table. take space of n cells, verticaly
    ex
    cell vspan bottom
    def cell_vspan_bottom(n,w)
    a cell_vspan aligned on bottom
    ex
    cell vspan top
    def cell_vspan_top(n,w)
    a cell_vspan aligned on top
    ex
    center
    def center()
    center { } container which center his content (auto-sloted)
    TODO : tested!
    ex
    check button
    def check_button(text="",value=false,option={},&blk)
    create a checked button
    state can be read by cb.active?
    ex
    chrome
    def chrome(on=false)
    show or supress the window system decoration
    ex
    clear
    def clear()
    ex
    clear append to
    def clear_append_to(cont,&blk)
    clear a container (stack or flow) and append the result of bloc parameter to this
    container
    thread protected
    ex
    clickable
    def clickable(method_name,&b)
    specific to gtk : some widget like label can't support click event, so they must
    be contained in a clickable parent (EventBox)

    Exemple: clickable(:callback_click_name) { label(" click me! ") }

    click callback is definied by a method name.
    see pclickable for callback by closure.
    ex
    close dialog
    def close_dialog)
    ex
    color choice
    def color_choice(text=nil,options={},&cb)
    create a button wich will show a dialog for color choice
    if bloc is given, it with be call on each change, with new color value as parameter
    current color is w.get_color()
    ex
    color conversion
    def color_conversion(color)
    ex
    combo
    def combo(choices,default=nil,option={},&blk)
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    Inputs widgets
    combo box.
    Choices are describes with:
  • a Hash choice-text => value-of-choice
  • or an array of string : value of choice is the index of choice in array

    default: initiale choice, String (text of choice) or index of choice in array/hash of choices
    bloc : called when a choice is selected, with text and value

    methods defined:
  • cb.get_selection() >> [text-selected, value-of-selected] or ['',-1]

    Usage :
    combo(%w{aa bb cc},"bb") { |text,index| alert("{text} at {index}") }
    w=combo({"aa" => 20, "bb"=> 30, "cc"=> 40},0) { |text,index| alert("{text} at {index}") }
    w.get_selection() ==> ["aa",20]
    ex
  • component
    def component)
    ex
    css name
    def css_name(name)
    give a name to last widget created. Useful for css style declaration
    ex
    current layout
    def current_layout()
    ex
    cv
    def cv.rotate(lxy,x0,y0,angle)
    ex
    def style
    def def_style(string_style=nil)
    define a set of css style, to be apply to every widget of main window
    if noparameter, load a file .rc
    ex
    delete
    def delete(w)
    delete a widget or a timer
    thread protected
    ex
    destroy
    def destroy()
    ex
    dialog
    def dialog(title="")
    Dialog contents is build with bloc parameter.
    call is bloced until action on Ok/Nok/delete button
    return true if dialog quit is done by action on OK button

    dialog("title") {
    flow { button("dd") ... }
    }
    ex
    dialog async
    def dialog_async(title,config={},&b)
    Dialog
    Dialog content is build with bloc parameter.
    Action on Ok/Nok/delete button make a call to :response bloc.
    dialog is destoy if return value of :response is true

    dialog_async("title",:response=> bloc {|dia,e| }) {
    flow { button("dd") ... }
    }
    ex
    dialog chooser
    def dialog_chooser(title, action, button)
    ex
    do notification
    def do_notification()
    ex
    edit
    def edit(filename,&blk)
    File Edit
    dialog showing code editor,
    call back is called on exit button,
    edit("x.txt") { |content| compile(content) ? true : (alert("error!");false) }

    ex
    entry
    def entry(value,size=10,option={},&blk)
    create a text entry for keyboard input
    if block defined, it while be trigger on eech of (character) change of the entry
    ex
    error
    def error(*txt)
    modal popup with text and/or ruby Exception.
    ex
    exe
    def exe(cmd,to=nil)
    execute a asynchonous system command, as done in a shell.
    output goes to log, pid of process is in $ruiby_script_pid
    on linux/unix host, exe() use PTY gem , on Windows it use popen3
    to parameter is timeout of IO.select which wait for stdout output.
    ex
    execute
    def execute(line=nil)
    ex
    fentry
    def fentry(value,option={},&blk)
    create a integer text entry for keyboed input
    option must define :min :max :by for spin button
    ex
    field
    def field(tlabel,lwidth,value,option={},&blk)
    show a label and a entry in a flow. entry widget is returned
    see fields()
    ex
    fields
    def fields(alabel=[["nothing",""]],option={},&blk)
    show a stack of label/entry and buttons validation/annulation
    on button, bloc is invoked with the list of values of entrys
    ex
    flow
    def flow(config={},add1=true,&b)
    container : horizontal box, take all space available, sloted in parent by default
    ex
    flow paned
    def flow_paned(size,fragment,&blk)
    create a container which can containe 2 widgets, separated by movable bar
    block invoked must create 2 widgets,horizonaly disposed
    ex
    flowi
    def flowi(config={},add1=true,&b)
    container : horizontal box, take only necessary space , sloted in parent
    ex
    force update
    def force_update(canvas)
    update a canvas
    ex
    frame
    def frame(t="",config={},add1=true,&b)
    a box with border and texte title, take all space
    ex
    framei
    def framei(t="",config={},add1=true,&b)
    a box with border and texte title, take only necessary space
    ex
    fslider
    def fslider(value=0,option={},&b)
    ex
    get as bool
    def get_as_bool()
    ex
    get config
    def get_config(w)
    get a Hash aff all properties of a gtk widget
    ex
    get current container
    def get_current_container()
    ex
    get history
    def get_history(n=-1)
    ex
    get icon
    def get_icon(name)
    obsolete
    ex
    get image
    def get_image(name)
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    raster images access
    ex
    get image from
    def get_image_from(name,size=:button)
    get a Image widget from a file or from a Gtk::Stock or famfamfam/crystal embeded in Ruiby.
    image can be a filename or a predefined icon in GTK::Stock or a famfamfam/crystal icon name (without .png)
    for file image, whe can specify a sub image (sqared) :
    filename.png[NoCol , NoRow]xSize
    filename.png[3,2]x32 : extract a icon of 32x32 pixel size from third column/second line
    see samples/draw.rb
    ex
    get line
    def get_line()
    ex
    get pixbuf
    def get_pixbuf(name)
    ex
    get pixmap
    def get_pixmap(name)
    ex
    get selection
    def get_selection()
    ex
    get stockicon pixbuf
    def get_stockicon_pixbuf(name)
    ex
    grid
    def grid(names,w=0,h=0,options={})
    create a grid of data (as list, but multicolumn)
    use set_data() to put a 2 dimensions array of text
    same methods as list widget
    all columnes are String type
    ex
    gui async pending size
    def gui_async_pending_size()
    return the number of traitment waiting to be executed by main window
    ex
    gui async wait size
    def gui_async_wait_size(size=0)
    wait that number of traitment waiting to be inferior or equal a a reference
    ex
    gui invoke
    def gui_invoke(&blk)
    Invoke HMI from anywhere
    if threader() is done by almost one window,
    evaluate (instance_eval) the bloc in the context of this window
    async: bloc will be evaluate after the return!
    ex
    gui invoke in window
    def gui_invoke_in_window(w,&blk)
    ex
    gui invoke wait
    def gui_invoke_wait(&blk)
    if threader() is done by almost one window,
    evaluate (instance_eval) the bloc in the context of this window
    sync: bloc will be evaluate before the return. Warining! : imlementation is stupid
    ex
    haccordion
    def haccordion()
    create a horizontral accordion menu.
    must contain aitem() which must containe alabel() :
    accordion { aitem(txt) { alabel(lib) { code }; ...} ... }
    ex
    hide app
    def hide_app)
    ex
    hradio buttons
    def hradio_buttons(ltext=["empty!"],value=-1)
    as vradio_buttons , but horizontaly disposed
    ex
    html color
    def html_color(str)
    parse color from RRggBB html format Ruiby_dsl.html_color
    ex
    htoolbar
    def htoolbar(options={})
    horizontal toolbar of icon button and/or separator
    if icon name contain a '/', second last is tooltip text
    Usage:
    htoolbar { toolbat_button("text/tooltip" { } ; toolbar_separator ; ... }
    ex
    htoolbar with icon text
    def htoolbar_with_icon_text(conf={})
    horizontal toolbar of (icone+text)

    htoolbar_with_icon_text do
    button_icon_text "dialog_info","text info" do alert(1) end
    button_icon_text "sep"
    end

    if icone name start with 'sep' : a vertical separator is drawn in place of touch
    see sketchi

    ex
    ientry
    def ientry(value,option={},&blk)
    create a integer text entry for keyboed input
    option must define :min :max :by for spin button
    ex
    image
    def image(file,options={})
    create a icon with a raster file
    option can specify a new size : :width and :height, or :size (square image)
    ex
    init threader
    def init_threader)
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    implictly called by Ruiby window creator
    initialize multi thread engine
    ex
    initialize
    def initialize()
    ex
    install
    def install(cur)
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    class father of all component
    is 'like' a Window class : it delagate DSL words to @win member
    ex
    install composant
    def install_composant(window,componant)
    helper for install a component.
    when use a component, define in Ruiby_dsl word:
    def component_name(*args)
    c=install_composant(self,ClassCompenent.new(*args))
    end
    ClassCompenent must inherit from AbstractComposant and define
    component method (as a window)
    class XX < AbstractComposant
    def component
    stack { .... }
    end
    end
    ex
    islider
    def islider(value=0,option={},&b)
    create a slider
    option must define :min :max :by for spin button
    current value can be read by w.value
    if bloc is given, it with be call on each change, with new value as parameter
    if value is a DynVar, slider will be binded to the DynVar : each change of the var value will update the slider,
    of no block given,each change of the slider is notifies to the DynVar, else change will
    only call the block.
    ex
    label
    def label(text,options={})
    create label, with text (or image if txt start with a '')
    spatial option : isize : icon size if image (menu,small_toolbar,large_toolbar,button,dnd,dialog)
    ex
    label clickable
    def label_clickable(text,config={},&b)
    a label clikable
    label_button("hello") { alert(Time.now.to_s) }
    ex
    labeli
    def labeli(text,options={})
    ex
    left
    def left(&blk)
    TODO : not tested!
    ex
    levelbar
    def levelbar(start=0,options)
    ex
    list
    def list(title,w=0,h=0,options={})
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    List
    create a verticale liste of data, with scrollbar if necessary
    define methods:
  • list() : get (gtk)list widget embeded
  • model() : get (gtk) model of the list widget
  • clear() clear content of the list
  • set_data(array) : clear and put new data in the list
  • selected() : get the selected items (or [])
  • index() : get the index of selected item (or [])
  • set_selection(index) : force current selection do no item in data
  • set_selctions(i0,i1) : force multiple consecutives selection from i1 to i2

    if bloc is given, it is called on each selection, with array
    of index of item selectioned

    Usage : list("title",100,200) { |li| alert("Selections is : {i.join(',')}") }.set_data(%w{a b c d})

    ex
  • log
    def log(*txt)
    Logs
    put a line of message text in log dialog (create and show the log dialog if not exist)
    ex
    log as widget
    def log_as_widget(width=nil,height=nil,opt={})
    ex
    make DynClass
    def make_DynClass(h={"dummy"=>"?"})
    Object binding
    As Struct, but data member are all DynVar
    see samples/dyn.rb
    ex
    make StockDynClass
    def make_StockDynClass(h={"dummy"=>"?"})
    make_DynClass, but data are saved at exit time.
    see samples/dyn.rb
    ex
    make StockDynObject
    def make_StockDynObject(oname,h)
    ex
    menu
    def menu(text)
    a vertial drop-down menu, only for menu_bar container
    ex
    menu bar
    def menu_bar()
    Menu
    create a application menu. must contain menu() {} :
    menu_bar {menu("F") {menu_button("a") { } ; menu_separator; menu_checkbutton("b") { |w|} ...}}
    ex
    menu button
    def menu_button(text="?",&blk)
    create an text entry in a menu
    ex
    menu checkbutton
    def menu_checkbutton(text="?",state=false,&blk)
    create an checkbox entry in a menu
    ex
    menu separator
    def menu_separator()
    ex
    message
    def message(style,*txt)
    ex
    name
    def name()
    ex
    next row
    def next_row()
    ex
    notebook
    def notebook()
    notebooks
    create a notebook widget. it must contain page() widgets
    notebook { page("first") { ... } ; ... }
    nb.page=page> => active no page
    ex
    observ
    def observ(&blk)
    ex
    on canvas button motion
    def on_canvas_button_motion(&blk )
    define action on mouse button motion on current canvas definition
    ex
    on canvas button press
    def on_canvas_button_press(&blk)
    define action on button_press
    action must return an object whici will be transmit to motion/release handler
    ex
    on canvas button release
    def on_canvas_button_release(&blk)
    define action on mouse button press on current canvas definition
    ex
    on canvas draw
    def on_canvas_draw(&blk)
    define the drawing on current canvas definition
    ex
    on canvas key press
    def on_canvas_key_press(&blk)
    define action on keyboard press on current **window** definition
    ex
    on canvas resize
    def on_canvas_resize(&blk)
    ex
    on delete
    def on_delete(&b)
    Arm a callback on window/dialog closed
    must return false for close the dialog
    dialog { stack {.... ; on_delete { @isclosed=true ; false} } }
    ex
    on destroy
    def on_destroy(&blk)
    define action when window is closed
    ex
    on idle
    def on_idle(&blk)
    shot peridicly a bloc parameter
    no threading: the bloc is evaluated by gtk mainloop in main thread context
    return handle of animation. can be stoped by delete(anim) // NOT WORK!, return a Numeric...
    ex
    on resize
    def on_resize(&blk)
    define a action when window is resized
    ex
    out
    def out.get_color()
    ex
    page
    def page(title,icon=nil)
    a page widget. only for notebook container.
    button can be text or icone (if startin by '', as label)
    ex
    panel
    def panel(title="")
    ex
    panel async
    def panel_async(title)
    panel_async: a dialog without button
    ex
    panel progress
    def panel_progress(text="",&blk)
    show a dialog with a progress bar, actualised by a Dynvar value
    dv=panel_progress("Loading xxxxx.rb...")
    anim(100) { fract=Time.now.to_i%60/60.0 ; dv.value=fract }
    after(10000) { dv.value=-1 }
    dv=panel_progress("Starting...") { |value|
    "Advance: %d " % ((value*100).to_i " }
    }
    ex
    pclickable
    def pclickable(aproc=nil,options={},&b)
    specific to gtk : some widget like label can't support click event, so they must
    be contained in a clickable parent (EventBox)

    Exemple: pclickable(proc { alert true}) { label(" click me! ") }

    bloc is evaluated in a stack container
    ex
    pclickablie
    def pclickablie(aproc=nil,options={},&b)
    as pclickable, but container is a stacki
    pclickablei(proc { alert("e") }) { label("click me!") }
    ex
    plot
    def plot.init()
    ex
    popup
    def popup(w=nil)
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    Popup
    create a dynamic popup.
    popup block can be composed by pp_item and pp_separator
    Exemple :
    popup { pp_item("text") { } ; pp_seperator ; pp_item('Exit") { exit!(0)} ; ....}
    popup can be rebuild by popup_clear_append(w)
    ex
    popup clear append
    def popup_clear_append(pp)
    clear a existant popup, rebuild it by bloc eval
    popup_clear_append(@pp) { pp_item(..) ; pp_separator() ....}
    ex
    pp item
    def pp_item(text,&blk)
    a button in a popup
    ex
    pp separator
    def pp_separator()
    a bar separator in a popup
    ex
    progress
    def progress(value=0,text=nil,option={})
    Progress bar
    w=progress(0.5,"Hello")
    w.set_fraction(0.99)
    show a progress bar. progresion is updated by set_fraction(0.0..1.0)
    w=progress(0.5,"Hello")
    w.set_fraction(0.99)
    ex
    progress bar
    def progress_bar(start=0,options)
    Show the evolution if a numeric value. Evolution is a number between 0 and 1.0
    w.progress=n force current evolution
    ex
    prompt
    def prompt(txt,value="")
    show a modal dialog, asking question, active bloc closure with text response
    in parameters
    prompt("Age ?") { |n| alert("Your age is {n-1}, bravo !")
    ex
    promptSync
    def promptSync(txt,value="")
    ex
    properties
    def properties(title,hash,options={:edit=>false, :scroll=>[0,0]})
    create a property shower/editor : vertical liste of label/entry representing the ruby Hash content
    Edition: Option: use :edit => true for show value in text entry, and a validate button,
    on button action, yield of bloc parameter is done with modified Hash as argument
    widget define set_data()methods for changing current value
    ex
    propertys
    def propertys(title,hash,options={:edit=>false, :scroll=>[0,0]},&b)
    deprecated: see properties
    ex
    razslot
    def razslot()
    forget precedent widget oconstructed
    ex
    regular
    def regular(on=true)
    Some other layouts
    set homogeneous contrainte on current container :
    all chidren whill have same size
  • stack : children will have same height
  • flow : children will have same width
    ex
  • replace current
    def replace_current(text)
    ex
    right
    def right(&blk)
    TODO : not tested!
    ex
    row
    def row()
    create a row. must be defined in a table closure
    Closure argment should only contain cell(s) call.
    many cell type are disponibles : cell cell_bottom cell_hspan cell_hspan_left
    cell_hspan_right cell_left cell_pass cell_right cell_span cell_top cell_vspan
    cell_vspan_bottom cell_vspan_top
    row do
    cell( label("ee")) ; cell_hspan(3, button("rr") ) }
    end
    ex
    rposition
    def rposition(x,y)
    change position of window in the desktop. relative position works only in *nix
    system.
    ex
    ruiby component
    def ruiby_component()
    can be included by a gtk windows, for use ruiby.
    do an include, and then call ruiby_component() with bloc for use ruiby dsl
    ruiby_component() must be call one shot for a window,
    it initialise ruiby.
    then append_to(),append_before()... can be use fore dsl usage
    ex
    ruiby exit
    def ruiby_exit()
    ex
    save stock
    def save_stock )
    ex
    script
    def script(caption="Parameters",nb_column=2,hctx=nil)
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    script
    define a hmi corresponding to a script command.
    see samples/script.rb
    the layout created contains three zones:
  • parameters : a set of entry, created with a DynObject which descriptor is hctx
  • button zone : a table of widgets. widget are created with bloc traitment,
  • a log zone : scolling area on text, appended with log() commande
  • bottom fixed buttons : clear log and exit.
    ex
  • scrolled
    def scrolled(width,height,&b)
    Scrollable stack container
    create a Scrolled widget with a autobuild stack in it
    stack can be populated
    respond to : scroll_to_top; scroll_to_bottom,
    ex
    scrolled win
    def scrolled_win.index()
    ex
    self
    def self.html_color(str)
    ex
    sentence
    def sentence(config={},add=true,&b)
    container manage children has sentence flow widgets
    ex
    sentenci
    def sentenci(config={},add=true,&b)
    ex
    separator
    def separator(width=1.0)
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    create a bar (vertical or horizontal according to stack/flow current container)
    ex
    set as bool
    def set_as_bool(v)
    ex
    set history
    def set_history(n=-1)
    ex
    set name
    def set_name(name)
    ex
    set trace
    def set_trace(on)
    ex
    set window icon
    def set_window_icon(filename)
    set taskbar icon for current window
    filename must have absolute path
    ex
    show all children
    def show_all_children(c)
    ex
    show app
    def show_app()
    ex
    show methods
    def show_methods(obj=nil,filter=nil)
    show methods of a object/class in log window
    ex
    show source
    def show_source)
    a button for show source code of application.
    usefule for demos app
    ex
    slider
    def slider(start=0.0,min=0.0,max=1.0,options={})
    Create a horizontal bar with a stick which can be moved.
    block (if defined) is invoked on each value changed
    w.proess=n can force current position at n

    ex
    slot
    def slot(w)
    pack widget in parameter, share space with prother widget
    this is the default: all widget will be sloted if they are not slotied
    this is done by attribs(w) which is call after construction of almost all widget
    ex
    slot append after
    def slot_append_after(w,wref)
    append the widget w after anotherone wref)
    thread protected
    ex
    slot append before
    def slot_append_before(w,wref)
    append the widget w before another one wref
    thread protected
    ex
    sloti
    def sloti(w)
    pack widget in parameter, take only necessary space
    ex
    snapshot
    def snapshot(filename=nil)
    make a snapshot raster file of current window
    can be called by user.
    Is called by mainloop if string 'take-a-snapshot' is present in ARGV
    only for Windows !!!
    ex
    source editor
    def source_editor(args={},&blk)
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    source editor
    a source_editor widget : text as showed in fixed font, colorized (default: ruby syntaxe)
    from: green shoes plugin
    options= :width :height :on_change :lang :font
    @edit=source_editor().editor
    @edit.buffer.text=File.read(@filename)
    ex
    space
    def space(n=1)
    create a one-character size space, (or n character x n line space)
    ex
    spacei
    def spacei(n=1)
    ex
    spacing
    def spacing(npixels=0)
    set space between each chidren of current box
    ex
    stack
    def stack(config={},add1=true,&b)
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    Slot : H/V Box or Frame
    container : vertical box, take all space available, sloted in parent by default
    ex
    stack paned
    def stack_paned(size,fragment,&blk)
    Panned :
    create a container which can containe 2 widgets, separated by movable bar
    block invoked must create 2 widgets, vertivaly disposed
    ex
    stacki
    def stacki(config={},add1=true,&b)
    container : vertical box, take only necessary space , sloted in parent
    ex
    stock
    def stock(name,defv)
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    Variable binding for widget : (shower/editor widget) <==> (int/float/string/bool variable)
    ex
    syst add button
    def syst_add_button(label,&prc)
    ex
    syst add check
    def syst_add_check(label,&prc)
    ex
    syst add sepratator
    def syst_add_sepratator()
    ex
    syst icon
    def syst_icon(file)
    ex
    syst quit button
    def syst_quit_button(yes)
    ex
    systray
    def systray(x=nil,y=nil,systray_config={})
    ex
    systray setup
    def systray_setup(config)
    ex
    table
    def table(nb_col=0,nb_row=0,config={})
    Creative Commons BY-SA : Regis d'Aubarede
    LGPL
    table
    create a container for table-disposed widgets. this is not a grid!
    table(r,c) { row { cell(w) ; .. } ; ... }
    or this form :
    table { cell(w) ; cell(w2) ; next_row ; cell(w3), cell(w4) }
    ex
    terminal
    def terminal(title="Terminal")
    create a terminal window INTO the process : gtk terminal
    for acces to internal state of the current process
    type help command.
    ex
    text
    def text=(s)
    ex
    text area
    def text_area(w=200,h=100,args={})
    multiline entry
    w=text_area(min_width,min_height,options)

    Some binding are defined :
  • w.text_area ; get text area widdget (w is a ScrolledWindow)
  • w.text="" ; set content
  • puts w.text() ; get content
  • w.append("data \n") ; append conent to the end of current content
  • w.text_area.wrap_mode = :none/:word
    ex
  • text area dyn
    def text_area_dyn(dynvar,w=200,h=100,args={})
    multiline entry on dynvar

    ex
    threader
    def threader(per)
    must be created by application (in initialize, after super), active the tread engine for
    caller window.
    if several windows, last created is the winner : gtk_invoke will throw to last treaded() window!
    ex
    toggle button
    def toggle_button(text1,text2=nil,value=false,option={},&blk)
    two state button, with text for each state and a initiale value
    value can be read by w.active?
    value can be changed by w.set_active(true/false)
    callback is called on state change, with new value as argument
    ex
    toolbar button
    def toolbar_button(name,tooltip=nil,&blk)
    ex
    toolbar separator
    def toolbar_separator()
    ex
    tooltip
    def tooltip(value="?")
    give a tooltip to last widget created.
    ex
    tr
    def tr(old,neww)
    ex
    trace
    def trace(*txt)
    travce() : like alert(), but with a warning icone
    ex
    tree grid
    def tree_grid(names,w=0,h=0,options={})
    create a tree view of data (as grid, but first column is a tree)
    use set_data() to put a Hash of data
    same methods as grid widget
    a columns Class are distinges by column name :
  • raster image if name start with a ''
  • checkbutton if name start with a '?'
  • Integer if name start with a '0'
  • String else
    ex
  • tv
    def tv.terminal(term=nil)
    @tv.override_font( Pango::FontDescription.new("courier bold 10"))
    ex
    update
    def update(data)
    ex
    value
    def value()
    ex
    var box
    def var_box(sens,config={},add1=true,&b)
    container : vertical or horizontal box (stack/flow, choice by first argument),
    sloted in parent by default
    ex
    var boxi
    def var_boxi(sens,config={},add1=true,&b)
    container : vertical or horizontal box (stacki/flowi, choice by first argument),
    sloted in parent by default
    ex
    vbox scrolled
    def vbox_scrolled(width,height,&b)
    ex
    video
    def video(url=nil,w=300,h=200)
    Show a video in a gtk widget.
  • if block is defined, it is invoked on each video progression (from 0 to 1.0)
  • w.play
  • w.stop
  • w.uri= "file:///foo.avi"
  • w.uri= "rtsp:///host:port/video"
  • .progress=n force current position in video (0..1)
    see samples/video.rb and samples/quadvideo.rb
    ex
  • vradio buttons
    def vradio_buttons(ltext=["empty!"],value=-1)
    create a liste of radio button, vertically disposed
    value is the indice of active item (0..(n-1)) at creation time
    define 2 methods:
  • get_selected get indice of active radio-button
  • set_selected(indice) set indice of active radio-button
    ex
  • w
    def w.options(config)
    p options if options && options.size>0
    ex
    widget
    def widget.get_data()
    ex
    widget properties
    def widget_properties(title=nil,w=nil)
    ex
    window
    def window(title="",sync=false)
    a dialog without default buttons
    can be synchrone (block the caller until wndow destroyed)
    ex
    wtree
    def wtree(w)
    ex
    Code of samples/canvas.rb


    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 }
    
    
    



    Code of samples/table2.rb


    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
    



    Code of samples/testth.rb


    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
    



    Code of samples/animtext.rb


    #!/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



    Code of samples/test_systray.rb


    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 



    Code of samples/multi_window_threading.rb


    #!/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
    



    Code of samples/test_include.rb
    #!/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
    



    Code of samples/netprog.rb


    # 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
    



    Code of samples/test.rb


    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 



    Code of samples/plot_curve.rb


    # 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



    Code of samples/dyn.rb


    # 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
    
    
    



    Code of samples/minicalc.rb


    # 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


    made by samples/make_doc.rb