Module: Ruiby_dsl

Includes:
Gtk, Ruiby_default_dialog
Included in:
Ruiby, Ruiby_dialog, Ruiby_gtk
Defined in:
lib/ruiby_gtk/dsl/table.rb,
lib/ruiby_gtk/systray.rb,
lib/ruiby_gtk/ruiby_dsl.rb,
lib/ruiby_gtk/dsl/canvas.rb,
lib/ruiby_gtk/ruiby_dsl3.rb,
lib/ruiby_gtk/ruiby_dsl3.rb,
lib/ruiby_gtk/dsl/pixmap.rb,
lib/ruiby_gtk/dsl/layouts.rb,
lib/ruiby_gtk/dsl/editors.rb,
lib/ruiby_gtk/dsl/commands.rb,
lib/ruiby_gtk/dsl/list_grid.rb,
lib/ruiby_gtk/dsl/form_fields.rb,
lib/ruiby_gtk/dsl/menus_popup.rb,
lib/ruiby_gtk/dsl/label_button_image.rb

Overview

Creative Commons BY-SA : Regis d'Aubarede <regis.aubarede@gmail.com> LGPL

Defined Under Namespace

Classes: HandlerContainer

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Ruiby_default_dialog

#_gooooooooooo, #alert, #ask, #ask_color, #ask_dir_to_read, #ask_dir_to_write, #ask_file_to_read, #ask_file_to_write, #dialog_chooser, #edit, #error, #message, #prompt, #trace

Class Method Details

.cv_color_html(html_color, opacity = 1) ⇒ Object

parse html color ( “#FF00AA” ) to rgba array, useful for canvas vectors styles



226
227
228
229
230
# File 'lib/ruiby_gtk/ruiby_dsl3.rb', line 226

def self.cv_color_html(html_color,opacity=1)
  c=::Gdk::Color.parse(html_color)
  #::Gdk::RGBA.new(c.red/65000.0,c.green/65000.0,c.blue/65000.0,1)
  [c.red/65000.0,c.green/65000.0,c.blue/65000.0,opacity>1 ? 1 : opacity<0 ? 0 : opacity]
end

Instance Method Details

#_Object



214
# File 'lib/ruiby_gtk/ruiby_dsl3.rb', line 214

def _() @current_widget end

#_accept?(type) ⇒ Boolean



59
60
61
62
# File 'lib/ruiby_gtk/dsl/layouts.rb', line 59

def _accept?(type)
  w=@lcur.last
  w.respond_to?(:accept?) ? w.accept?(type) : true
end

#_cbox(expand, box, config, add1) ⇒ Object

private: generic packer



70
71
72
73
74
75
76
77
78
79
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 70

def _cbox(expand,box,add1)
  autoslot()
  if add1
    expand ? @lcur.last.add(box) : @lcur.last.pack_start(box,false,false,3)
  end
  @lcur << box
  yield
  autoslot()
  @lcur.pop
end

#_check_append(name, w, wref) ⇒ Object



194
195
196
197
198
199
200
201
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 194

def _check_append(name,w,wref)
  raise("#{name}(w,r) : Widget ref not created!") unless wref
  raise("#{name}(w,r) : new Widget not created!") unless w
  parent=wref.parent
  raise("#{name}(w,r): r=#{parent.inspect} is not a XBox or Frame !") unless !parent || parent.kind_of?(Container)
  raise("#{name}(w,r): r=#{parent.inspect} is not a XBox or Frame !") unless parent.respond_to?(:reorder_child)
  parent
end

#_create_log_windowObject



1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1332

def _create_log_window() 
  return(@loglabel) if defined?(@loglabel) && @loglabel && ! @loglabel.destroyed?
  wdlog = Dialog.new("Logs : #{$0}",
    nil,
    0,
    [ Stock::OK, Dialog::RESPONSE_NONE ])
  Ruiby.set_last_log_window(wdlog)
  logBuffer = TextBuffer.new
  @loglabel=TextView.new(logBuffer)
  sw=ScrolledWindow.new()
  sw.set_width_request(800)	
  sw.set_height_request(200)	
  sw.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS)
  
  sw.add_with_viewport(@loglabel)
  
  wdlog.vbox.add(sw)
  wdlog.signal_connect('response') { wdlog.destroy }
  wdlog.show_all	
  @loglabel
end

#_dyn_check_button(text, var, option = {}) ⇒ Object



66
67
68
69
70
# File 'lib/ruiby_gtk/dsl/form_fields.rb', line 66

def _dyn_check_button(text,var,option={}) 
  w= block_given? ?  check_button(text,!! var.value,option) : check_button(text,!! var.value,option) { |v|  var.set_as_bool(v) }
  var.observ { |v|  w.set_active(var.get_as_bool())  }
  w
end

#_dyn_entry(var, size, options, slotied) ⇒ Object



144
145
146
147
148
149
150
151
152
153
# File 'lib/ruiby_gtk/dsl/form_fields.rb', line 144

def _dyn_entry(var,size,options,slotied) 
  size= var.value.to_s.size*2 unless size
  w= unless slotied
    (block_given? ? entry(var.value,size,options)  : entry(var.value,size,options) { |v| var.value=v })
  else
    (block_given? ? entry(var.value,size,options)  : entry(var.value,size,options) { |v| var.value=v })
  end
  var.observ { |v| w.text = v.to_s }
  w
end

#_dyn_ientry(var, options, slotied) ⇒ Object



171
172
173
174
175
176
177
178
179
# File 'lib/ruiby_gtk/dsl/form_fields.rb', line 171

def _dyn_ientry(var,options,slotied) 
  w= unless slotied
    (block_given? ? ientry(var.value,options)  : ientry(var.value,options) { |v| var.value=v })
  else
    (block_given? ? ientry(var.value,options)  : ientry(var.value,options) { |v| var.value=v })
  end
  var.observ { |v| w.text = v.to_s }
  w
end

#_dyn_islider(var, option, &blk) ⇒ Object



241
242
243
244
245
246
# File 'lib/ruiby_gtk/dsl/form_fields.rb', line 241

def _dyn_islider(var,option,&blk) 
  w=  block_given? ?  islider(var.value.to_i,option,&blk) : islider(var.value.to_i,option) { |v| var.value=v }
  var.observ { |v| w.set_value(v.to_i) }
  attribs(w,option)   
  w
end

#_dyn_label(var, option = {}) ⇒ Object



14
15
16
17
18
# File 'lib/ruiby_gtk/dsl/label_button_image.rb', line 14

def _dyn_label(var,option={}) 
  w=  label(var.value.to_s,option) 
  var.observ { |v| w.text = v.to_s }
  w
end

#_label(text, options = {}) ⇒ Object



306
307
308
309
310
311
312
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 306

def _label(text,options={})
  if text && text[0,1]=="#"
    get_image_from(text[1..-1]);
  else
    Label.new(text);
  end
end

#_make_prop_line(prop_current, options, k, v) ⇒ Object



657
658
659
660
661
662
663
664
665
666
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 657

def _make_prop_line(prop_current,options,k,v)
  if k.to_s =~/^sep\d+$/
      cell_span(2,HSeparator.new)
  else
    cell_right(label(" "+k.to_s+" : "))
    cell_left(options[:edit] ? 
      (prop_current[k]=entry(v.to_s)) : 
      label(v.to_s))
  end
end

#_nocodeeeeeeeeeeeObject

Slot : H/V Box or Frame



27
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 27

def _nocodeeeeeeeeeee() end

#_pack(parent, box, expand) ⇒ Object



132
133
134
135
136
# File 'lib/ruiby_gtk/dsl/layouts.rb', line 132

def _pack(parent,box,expand)
   parent.respond_to?(:pack_start) ? 
        parent.pack_start(box, :expand => expand, :fill => true): 
        parent.add(box) 
end

#_paned(horizontal, size, fragment) ⇒ Object



889
890
891
892
893
894
895
896
897
898
899
900
901
902
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 889

def _paned(vertical,size,fragment)
  paned = vertical ? HPaned.new : VPaned.new
  slot(paned)
  @lcur << paned
  frame1,frame2=*yield()
  @lcur.pop
  (frame1.shadow_type = Gtk::SHADOW_IN) rescue nil
  (frame2.shadow_type = Gtk::SHADOW_IN) rescue nil
  paned.position=size*fragment
  vertical ? paned.set_size_request(size, -1) : paned.set_size_request(-1,size)
  paned.pack1(frame1, true, false)
  paned.pack2(frame2, false, false)
  show_all_children(paned)
end

#_radio_buttons(sens, ltext = ["empty!"], value = -1)) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/ruiby_gtk/dsl/form_fields.rb', line 115

def _radio_buttons(sens,ltext=["empty!"],value=-1)
  # TODO Dyn
  b0=nil
  s=var_box(sens,{},false) {
    ltext.each_with_index {|t,i|
      b=if i==0
          b0=slot(RadioButton.new(t))
      else
          slot(RadioButton.new(b0,t))
      end
      if i==value
        b.toggled 
        b.set_active(true) 
      end
    }
  }
  # TODO: test!
  class << s
    ;  def get_selected()
      b0.group.each_with_index.map { |w,index| return(index) if w.active? }
    end
   ;  def set_selected(indice)
      b0.group.each_with_index.map { |w,index| w.active=true if indice==index }
    end
  end
  s
end

#_set_accepter(layout, *types) ⇒ Object

add a accept?() method to a layout (box). so children will check if they can be added to current layout by invoke

current_layout=@lcur.last
current_layout.accept?( <type-children> )


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ruiby_gtk/dsl/layouts.rb', line 44

def _set_accepter(layout,*types)
  if types.size==1
    layout.define_singleton_method(:accept?) do |type|  
       raise("No command   #{type} accepted here, accept=#{types}/") unless types.first==type 
    end
  elsif types.size==2
    layout.define_singleton_method(:accept?) do |type|  
      raise("No command #{type} accepted here, accept=#{types}/") unless types.first==type || types.last==type 
    end
  else
    layout.define_singleton_method(:accept?) do |type| 
      raise("No command  #{type}  accepted here, accept=#{types}/") unless types.any? { |a| a==type }
    end
  end
end

#_sub_image(name) ⇒ Object



245
246
247
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 245

def _sub_image(name)
  Image.new(get_pixbuf(name))
end

#aaa_generalitiesObject

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 : 
<ul>
    alert  ask ask_color ask_dir_to_read ask_dir_to_write ask_file_to_read  
    ask_file_to_write color_choice dialog dialog_async edit 
 </ul>
* a immediate command, the can be used in callback code: gui manipulation... : 
<ul>
    after  anim append_to apply_options  attribs autoslot chrome clear clear_append_to  
    color_conversion def_style def_style3 delete  force_update get_config  
    get_current_container get_icon get_image_from get_pixbuf get_stockicon_pixbuf 
    gui_invoke gui_invoke_in_window gui_invoke_wait  hide_app  log  on_destroy  
    rposition ruiby_component ruiby_exit  show_methods 
    slot_append_after slot_append_before sloti style threader  update 
 </ul>

2 kinds of objects :

  • container <ul>

       accordion box  center flow flow_paned flowi frame framei  grid haccordion notebook  
       pclickable popup stack stack_paned stacki systray table var_box var_boxi vbox_scrolled 
    </ul>
    Containers organyze children widget, but show (almost) nothing.
    Children must be created in container bloc, container can contains widget and container :
       <code><pre> 
       | stack do
       |   button("Hello")
       |   label(" word")
       |   flow { button("x") ; label("y") }
       | end
       </pre></code>
  • widgets <ul>

       aitem alabel box button  calendar canvas cell* center check_button  combo  dialog
       dialog_async  edit entry fentry field fields grid  haccordion  hradio_buttons htoolbar ientry image  
       islider label labeli list menu menu_bar menu_button menu_checkbutton menu_separator   page  
       pp_item pp_separator  properties   row   scrolled separator  show_methods  source_editor space 
       syst_add_button syst_add_check syst_add_sepratator syst_icon syst_quit_button 
       systray table text_area  toggle_button  tree_grid  vradio_buttons wtree
    </ul>
    Widget must be placed in a container.
    2 kinds of placement :
    <li>sloted  : widget take all disponible space ( gtk: pack(expand,fill) ), share
                 space with other sloted widget in same container
    <li>slotied : widget take only necessary place ( gtk: pack(no-expand , no-fill) )

<pre><code>

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

</code></pre>

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: <li> scoth xxxx in top of frame : >stack { stacki { xxx } ; stack { } } <li> scoth xxxx in bottom of frame : >stack { stack { } ; stacki { xxx } } <li> 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.

<li>@calc=make_DynObject({“resultat”=> 0,“value” => “0” , “stack” => [] }) <li>@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.



148
149
# File 'lib/ruiby_gtk/ruiby_dsl3.rb', line 148

def aaa_generalities()
end

#accordionObject

create a accordion menu. must contain aitem() which must containe alabel() : accordion { aitem(txt) { alabel(lib) { code }; …} … }



840
841
842
843
844
845
846
847
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 840

def accordion() 
  @slot_accordion_active=nil #only one accordion active by window!
  w=stack { stacki {
    yield
  }}
  separator
  w
end

#aitem(txt, &blk) ⇒ Object

a button menu in accordion

bloc is evaluate for create/view a list of alabel :
aitem(txt) { alabel(lib) { code }; ...}


858
859
860
861
862
863
864
865
866
867
868
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 858

def aitem(txt,&blk) 
  b2=nil
  button(txt) {
        clear_append_to(@slot_accordion_active) {} if @slot_accordion_active
        @slot_accordion_active=b2
        clear_append_to(b2) { 
          blk.call()
        }
  }
  b2=stacki { }
end

#alabel(txt, &blk) ⇒ Object

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 }; …} … }



871
872
873
874
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 871

def alabel(txt,&blk)
  l=nil
  pclickable(proc { blk.call(l) if blk} ) { l=label(txt) }
end

#append_to(cont, &blk) ⇒ Object

append the result of bloc parameter to a contener (stack or flow) thread protected Usage :

@stack= stack {}
  . . . . 
  append_to(@stack) { button("Hello") }


104
105
106
107
108
109
110
111
112
113
114
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 104

def append_to(cont,&blk)
  if $__mainthread__ != Thread.current
    gui_invoke { append_to(cont,&blk) }
    return
  end
  @lcur << cont
  yield 
  autoslot()
  @lcur.pop
  show_all_children(cont)
end

#apply_options(w, options) ⇒ Object

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"

)



200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/ruiby_gtk/ruiby_dsl3.rb', line 200

def apply_options(w,options)
    w.set_size_request(*options[:size])                                 if options[:size] 
    w.set_border_width(options[:margins])                               if options[:margins]  
    w.width_request=(options[:width].to_i)                              if options[:width]
    w.height_request=(options[:height].to_i)                            if options[:height]
    w.override_background_color(:normal,color_conversion(options[:bg])) if options[:bg] 
    w.override_color(:normal,color_conversion(options[:fg]))            if options[:fg] 
    w.override_font(Pango::FontDescription.new(options[:font]))         if options[:font]
    if options[:tooltip]
      w.set_tooltip_markup(options[:tooltip])
      w.has_tooltip=true
    end
    w
end

#attribs(w, options) ⇒ Object

common widget property applied for (almost) all widget. options are last argument of every dsl command, see apply_options



271
272
273
274
275
276
277
278
279
280
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 271

def attribs(w,options)
    w.set_size_request(*options[:size]) if options[:size]	
    w.width_request=(options[:width]) if options[:width]
    w.height_request=(options[:height]) if options[:height]
    w.modify_bg(Gtk::STATE_NORMAL,color_conversion(options[:bg])) if options[:bg] # not work on window
    w.modify_fg(Gtk::STATE_NORMAL,color_conversion(options[:fg])) if options[:fg] # not work on window
    w.modify_font(Pango::FontDescription.new(options[:font])) if options[:font]
    autoslot(w)  # slot() precedent widget if existe and not already sloted, and declare this one as the precedent
    w
end

#autoslot(w = nil) ⇒ Object

slot() precedently created widget if not sloted. this is done by attribs(w) which is call after construction of almost all widget



91
92
93
94
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 91

def autoslot(w=nil)
  (slot(@current_widget)) if @current_widget!=nil
  @current_widget=w 
end

#background(color, options = {}, &b) ⇒ Object

set a background color to current container Usage : stack { background(“#FF0000”) { flow { …} } }



156
157
158
159
160
161
162
# File 'lib/ruiby_gtk/dsl/layouts.rb', line 156

def background(color,options={},&b) 
  _accept?(:layout)
  eventbox = Gtk::EventBox.new
  ret=_cbox(true,eventbox,{},true,&b) 
  apply_options(eventbox,{bg: color}.merge(options))
  ret
end

#backgroundi(color, options = {}, &b) ⇒ Object



163
164
165
166
167
168
169
# File 'lib/ruiby_gtk/dsl/layouts.rb', line 163

def backgroundi(color,options={},&b) 
  _accept?(:layout)
  eventbox = Gtk::EventBox.new
  ret=_cbox(false,eventbox,{},true,&b) 
  apply_options(eventbox,{bg: color}.merge(options))
  ret
end

#bourrage(n = 1) ⇒ Object



56
# File 'lib/ruiby_gtk/dsl/label_button_image.rb', line 56

def bourrage(n=1) n.times { slot(label(" ")) }  end

#boxObject

box { } container which manage children widget without slot (pack()) in parent container. Use it for cell in table, notebook : table { row { cell(box { });… }; … }



40
41
42
43
44
45
46
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 40

def box() 
  box=VBox.new(false, 2)
  @lcur << box
  yield
  autoslot()
  @lcur.pop
end

#button(text, option = {}, &blk) ⇒ Object

create button, with text (or image if txt start with a '#') block argument is evaluate at button click



333
334
335
336
337
338
339
340
341
342
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 333

def button(text,option={},&blk)
  if text && text[0,1]=="#"
    b=Button.new()
    b.set_image(get_image_from(text[1..-1]))
  else
    b=Button.new(text);
  end
  b.signal_connect("clicked") { |e| blk.call(e) rescue error($!) } if blk
  attribs(b,option)
end

#button_expand(text, initiale_state = false, options = {}, &b) ⇒ Object

a button which show a sub-frame on action



1258
1259
1260
1261
1262
1263
1264
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1258

def button_expand(text,initiale_state=false,options={},&b) 
  expander = Gtk::Expander.new(text)
  expander.expanded = initiale_state
  frame=box(&b)
  expander.add(frame)
  attribs(expander,options)
end

#button_icon_text(icon, text = "", options = {}, &b) ⇒ Object

a button with icon+text vertivcaly aligned, can be call anywhere, and in htool_bar_with_icon_text option is label options and isize ( option for icon size, see label())



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/ruiby_gtk/dsl/label_button_image.rb', line 80

def button_icon_text(icon,text="",options={},&b)
     if icon !~ /^sep/
        spacei
        pclickablie(proc { b.call  }) { stacki { 
            label("#"+icon,{isize: (options[:isize] || :dialog) }) 
            label(text[0,15],options)
       } }
     else
        separator
     end
end

#buttoni(text, option = {}, &blk) ⇒ Object

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


347
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 347

def buttoni(text,option={},&blk) sloti(button(text,option,&blk)) end

#calendar(time = Time.now, options = {}) ⇒ Object

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



976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 976

def calendar(time=Time.now,options={})
  c = Calendar.new
  #c.display_options(Calendar::SHOW_HEADING | Calendar::SHOW_DAY_NAMES |  
  #        Calendar::SHOW_WEEK_NUMBERS )
  after(1) { c.signal_connect("day-selected") { |w,e| options[:selection].call(w.day)  rescue error($!) } } if options[:selection]
  after(1) { c.signal_connect("month-changed") { |w,e| options[:changed].call(w)  rescue error($!) } }if options[:changed]
  calendar_set_time(c,time)
  class << c
    def set_time(time)
      select_month(time.month,time.year)
      select_day(time.day)
    end
    def get_time()
      year, month, day= *date() 
      Time.local(year, month, day) 
    end
  end
  attribs(c,options)

end

#calendar_set_time(cal, time = Time.now) ⇒ Object

deprecated : change the current selection of a calendar, by Time object



998
999
1000
1001
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 998

def calendar_set_time(cal,time=Time.now)
  cal.select_month(time.month,time.year)
  cal.select_day(time.day)
end

#canvas(width, height, option = {}) ⇒ Object

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 offered. basic gtk comands can be uses to ( move_to(), line_to()… ) def myDraw(w,ctx)

w.init_ctx
w.draw_line([x1,y1,....],color,width)
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_recangle(x0,y0,w,h,colorFill,colorStroke,widthStroke)
w.draw_image(x,y,filename)
w.draw_text(x,y,text,scale,color)
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
w.scale(10,20,2) { w.draw_image(3,0,filename) } # draw in a transladed/scaled coord system
                     >> image with be draw at 16,20, and his size doubled

end



563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 563

def canvas(width,height,option={})
  autoslot()
  w=DrawingArea.new()
  w.set_size_request(width,height)
  w.events |= ( ::Gdk::Event::BUTTON_PRESS_MASK | ::Gdk::Event::POINTER_MOTION_MASK | ::Gdk::Event::BUTTON_RELEASE_MASK)
  w.signal_connect( 'expose-event'  ) { |w1,e| 
    cr = w1.window.create_cairo_context
    cr.save {
      cr.set_line_join(Cairo::LINE_JOIN_ROUND)
      cr.set_line_cap(Cairo::LINE_CAP_ROUND)
          cr.set_line_width(2)
          cr.set_source_rgba(1,1,1,1)
          cr.paint
      if option[:expose]
        begin
          option[:expose].call(w1,cr) 
        rescue Exception => e
         bloc=option[:expose]
         option.delete(:expose)
         after(1) { error(e) }
         after(3000) {  puts "reset expose bloc" ;option[:expose] = bloc }
        end  
      end
    }
  }
  @do=nil
  w.signal_connect('button_press_event')   { |wi,e| @do = option[:mouse_down].call(wi,e)  rescue error($!)              ; force_update(wi) }  if option[:mouse_down]
  w.signal_connect('button_release_event') { |wi,e| (option[:mouse_up].call(wi,e,@do)  rescue error($!)) if @do ; @do=nil ; force_update(wi) if @do }  if option[:mouse_up]
  w.signal_connect('motion_notify_event')  { |wi,e| (@do = option[:mouse_move].call(wi,e,@do) rescue error($!)) if @do     ; force_update(wi) if @do }  if option[:mouse_move]
  w.signal_connect('key_press_event')  { |wi,e| (option[:key_press].call(wi,e) rescue error($!)) ; force_update(wi) }  if option[:key_press]
  attribs(w,option)	
  def	w.redraw() 
    self.queue_draw_area(0,0,1000,1000)
  end
  w
end

#canvasOld(width, height, option = {}) ⇒ Object

DEPRECATED; Create a drawing area, for pixel draw option can define closure :mouse_down :mouse_up :mouse_move for interactive actions



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/ruiby_gtk/dsl/canvas.rb', line 237

def canvasOld(width,height,option={})
  puts "*** DEPRECATED: use canvas do end in place of canvasOld ***"
  autoslot()
  w=DrawingArea.new()
  w.width_request=width
  w.height_request=height
  w.events |=  ( ::Gdk::Event::Mask::BUTTON_PRESS_MASK | ::Gdk::Event::Mask::POINTER_MOTION_MASK | ::Gdk::Event::Mask::BUTTON_RELEASE_MASK)

  w.signal_connect(  'draw' ) { |w1,cr| 
    cr.save {
      cr.set_line_join(Cairo::LINE_JOIN_ROUND)
      cr.set_line_cap(Cairo::LINE_CAP_ROUND)
      cr.set_line_width(2)
      cr.set_source_rgba(1,1,1,1)
      cr.paint
      if option[:expose]
        begin
          option[:expose].call(w1,cr) 
        rescue Exception => e
         bloc=option[:expose]
         option.delete(:expose)
         after(1) { error(e) }
         after(3000) {  puts "reset expose bloc" ;option[:expose] = nil }
        end  
      end
    }
  }
  @do=nil
  w.signal_connect('button_press_event')   { |wi,e| @do = option[:mouse_down].call(wi,e)  rescue error($!)              ; force_update(wi) }  if option[:mouse_down]
  w.signal_connect('button_release_event') { |wi,e| (option[:mouse_up].call(wi,e,@do)  rescue error($!)) if @do ; @do=nil ; force_update(wi) if @do }  if option[:mouse_up]
  w.signal_connect('motion_notify_event')  { |wi,e| (@do = option[:mouse_move].call(wi,e,@do) rescue error($!)) if @do     ; force_update(wi) if @do }  if option[:mouse_move]
  w.signal_connect('key_press_event')  { |wi,e| (option[:key_press].call(wi,e) rescue error($!)) ; force_update(wi) }  if option[:key_press]
  attribs(w,option) 
  def w.redraw() 
    self.queue_draw_area(0,0,self.width_request,self.height_request)
  end
  w
end

#cell(w) ⇒ Object

a cell in a row/table. take all space, centered



42
# File 'lib/ruiby_gtk/dsl/table.rb', line 42

def  cell(w)  cell_hspan(1,w)   end

#cell_bottom(w) ⇒ Object

create a cell in a row/table, bottom aligned



76
# File 'lib/ruiby_gtk/dsl/table.rb', line 76

def cell_bottom(w)   razslot();w.set_alignment(0.5, 1.0)rescue nil ; cell(w) end

#cell_hspan(n, w) ⇒ Object

a cell in a row/table. take space of n cells, horizontaly



44
# File 'lib/ruiby_gtk/dsl/table.rb', line 44

def  cell_hspan(n,w) cell_hvspan(n,0,w) end

#cell_hspan_left(n, w) ⇒ Object

create a hspan_cell in a row/table, left justified



69
# File 'lib/ruiby_gtk/dsl/table.rb', line 69

def cell_hspan_left(n,w)   razslot();w.set_alignment(0.0, 0.5)rescue nil ; cell_hspan(n,w) end

#cell_hspan_right(n, w) ⇒ Object

create a hspan_cell in a row/table, right justified



71
# File 'lib/ruiby_gtk/dsl/table.rb', line 71

def cell_hspan_right(n,w)  razslot();w.set_alignment(1.0, 0.5)rescue nil ; cell_hspan(n,w) end

#cell_hvspan(n, m, w) ⇒ Object

a cell in a row/table. take space of n x m cells, horizontaly x verticaly



48
49
50
51
52
53
54
55
56
57
# File 'lib/ruiby_gtk/dsl/table.rb', line 48

def  cell_hvspan(n,m,w) 
  _accept?(:cell)
  razslot();
  @lcur.last.attach(w,
     @ltable.last[:col],@ltable.last[:col]+n,
     @ltable.last[:row],@ltable.last[:row]+m+1
  )  
  @ltable.last[:col]+=n
  @ltable.last[:row]+=m
end

#cell_left(w) ⇒ Object

create a cell in a row/table, left justified



64
# File 'lib/ruiby_gtk/dsl/table.rb', line 64

def cell_left(w)     razslot();w.set_alignment(0.0, 0.5) rescue nil; cell(w) end

#cell_pass(n = 1) ⇒ Object

keep empty n cell consecutive on current row



59
# File 'lib/ruiby_gtk/dsl/table.rb', line 59

def  cell_pass(n=1)  @ltable.last[:col]+=n end

#cell_right(w) ⇒ Object

create a cell in a row/table, right justified



66
# File 'lib/ruiby_gtk/dsl/table.rb', line 66

def cell_right(w)    razslot();w.set_alignment(1.0, 0.5)rescue nil ; cell(w) end

#cell_span(n = 2, w) ⇒ Object

a cell in a row/table. take space of n cells, horizontaly



61
# File 'lib/ruiby_gtk/dsl/table.rb', line 61

def  cell_span(n=2,w) cell_hspan(n,w) end

#cell_top(w) ⇒ Object

create a cell in a row/table, top aligned



74
# File 'lib/ruiby_gtk/dsl/table.rb', line 74

def cell_top(w)      razslot();w.set_alignment(0.5, 0.0)rescue nil ; cell(w) end

#cell_vspan(n, w) ⇒ Object

a cell in a row/table. take space of n cells, vericaly



46
# File 'lib/ruiby_gtk/dsl/table.rb', line 46

def  cell_vspan(n,w) cell_hvspan(0,n,w) end

#cell_vspan_bottom(n, w) ⇒ Object

a cell_vspan aligned on bottom



80
# File 'lib/ruiby_gtk/dsl/table.rb', line 80

def cell_vspan_bottom(n,w) razslot();w.set_alignment(0.5, 1.0)rescue nil ; cell_vspan(n,w) end

#cell_vspan_top(n, w) ⇒ Object

a cell_vspan aligned on top



78
# File 'lib/ruiby_gtk/dsl/table.rb', line 78

def cell_vspan_top(n,w)    razslot();w.set_alignment(0.5, 0.0)rescue nil ; cell_vspan(n,w) end

#centerObject

center { } container which center his content (auto-sloted) TODO : tested!



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 48

def center() 
  autoslot()
  valign = Gtk::Alignment.new(0,0,0,0)
  @lcur.last.pack_start(valign,false,false,0)
  vbox=VBox.new(true, 0)
  valign.add(vbox)
  @lcur << vbox
  yield
  autoslot()
  @lcur.pop
end

#check_button(text = "", value = false, option = {}, &blk) ⇒ Object

create a checked button state can be read by cb.active?



430
431
432
433
434
435
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 430

def check_button(text="",value=false,option={})
  b=CheckButton.new(text)
        .set_active(value)
  attribs(b,option)
  b
end

#clear(cont) ⇒ Object

clear a containet (stack or flow) thread protected



118
119
120
121
122
123
124
125
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 118

def clear(cont) 
  if $__mainthread__ != Thread.current
    p "not in main thread"
    gui_invoke { clear(cont) }
    return
  end
  cont.children.each { |w| cont.remove(w) } 
end

#clear_append_to(cont, &blk) ⇒ Object

clear a container (stack or flow) and append the result of bloc parameter to this container thread protected



130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 130

def clear_append_to(cont,&blk) 
  if $__mainthread__ != Thread.current
    p "not in main thread"
    gui_invoke { clear_append_to(cont,&blk) }
    return
  end
  cont.children.each { |w| cont.remove(w) } 
  @lcur << cont
  yield 
  autoslot()
  @lcur.pop
  show_all_children(cont)
end

#clickable(method_name, &b) ⇒ Object

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.



1054
1055
1056
1057
1058
1059
1060
1061
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1054

def clickable(methode_name,&b) 
  eventbox = Gtk::EventBox.new
  eventbox.events = Gdk::Event::BUTTON_PRESS_MASK
  ret=_cbox(true,eventbox,true,&b) 
  eventbox.realize
  eventbox.signal_connect('button_press_event') { |w, e| self.send(methode_name,ret)  rescue error($!) }
  ret
end

#close_dialogObject



94
95
96
# File 'lib/ruiby_gtk/systray.rb', line 94

def close_dialog
  destroy
end

#color_choice(text = nil, options = {}, &cb) ⇒ Object

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()



544
545
546
547
548
549
550
551
552
553
554
555
556
557
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 544

def color_choice(text=nil,options={},&cb)
  b,d=nil,nil
  hb=flow(false) { b = slot(button(text.to_s||"Color?...")) ; d=slot(DrawingArea.new) }					
  b.signal_connect("clicked") {
    c=ask_color
    if c
    d.modify_bg(Gtk::STATE_NORMAL,c)
    b.modify_bg(Gtk::STATE_NORMAL,c)
    cb.call(c) if block_given?
    end
  }
  attribs(hb,options)		
  hb
end

#color_conversion(color) ⇒ Object



281
282
283
284
285
286
287
288
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 281

def color_conversion(color)
  case color 
    when String then ::Gdk::Color.parse(color)
    when ::Gdk::Color then color
    else
      raise "unknown color : #{color}"
  end
end

#combo(choices, default = nil, option = {}, &blk) ⇒ Object

combo box, decribe with a Hash choice-text => value-of-choice choices: array of text choices dfault : text activate or index of text in array bloc ! called when a choice is selected

Usage : combo(%wbb cc,“bb”) { |text,index| alert(“the choice is #text at #index”) }



392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 392

def combo(choices,default=-1,option={})
  if   Ruiby.gtk_version(2)
    w=ComboBox.new()
    choices.each do |text,indice|  
      w.append_text(text) 
    end
    w.set_active(default) if default>=0
    attribs(w,option)		
    w
  else
    w=ComboBoxText.new()
    choices.each do |text,indice|  
      w.append_text(text) 
    end
    w.set_active(default) if default>=0
    attribs(w,option)		
    w
  end
end

#css_name(name) ⇒ Object

give a name to last widget created. Useful for css style declaration



164
# File 'lib/ruiby_gtk/ruiby_dsl3.rb', line 164

def css_name(name)  @current_widget ? @current_widget.set_name(name) : error("cssname #{name}: there are no current widget!") end

#def_style(string_style = nil) ⇒ Object

not ready!!!



1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1374

def def_style(string_style=nil)
  unless string_style
     fn=caller[0].gsub(/.rb$/,".rc")
     raise "Style: no ressource (#{fn} not-exist)" if !File.exists?(fn)
     string_style=File.read(fn)
  end
  begin
    Gtk::RC.parse_string(string_style)
    @style_loaded=true
  rescue Exception => e
    error "Error loading style : #{e}\n#{string_style}"
  end
end

#delete(w) ⇒ Object

delete a widget or a timer thread protected



181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 181

def delete(w)
  if $__mainthread__ != Thread.current
    gui_invoke { delete(w) }
    return
  end
  if  Numeric === w && @hTimer[w]
    @hTimer[w]=false
  elsif  GLib::Timeout === w
    w.destroy
  else
    w.parent.remove(w) rescue error($!)
  end
end

#dialog(title = "") ⇒ Object

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") ... }

}



1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1300

def dialog(title="") 
  dialog = Dialog.new(title,
    self,
    Dialog::DESTROY_WITH_PARENT,
    [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT],
          [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT])
    
  @lcur << dialog.vbox
  stack { yield }
  @lcur.pop
  
  dialog.set_window_position(Window::POS_CENTER)
  dialog.show_all	
  rep=dialog.run
  dialog.destroy
  rep
end

#dialog_async(title, config = {}, &b) ⇒ Object

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") ... }

}



1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1274

def dialog_async(title,config,&b) 
  dialog = Dialog.new("Message",
    self,
    Dialog::DESTROY_WITH_PARENT,
    [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT],
          [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT])

  dialog.set_window_position(Window::POS_CENTER)
  
  @lcur << dialog.vbox
  stack { yield }
  @lcur.pop

  dialog.signal_connect('response') do |w,e|
    rep=config[:response].call(dialog,e) if 
    dialog.destroy if rep
  end
  dialog.show_all	
end

#entry(value, size = 10, option = {}, &blk) ⇒ Object

create a text entry for keyboard input if block defined, it while be trigger on eech of (character) change of the entry



473
474
475
476
477
478
479
480
481
482
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 473

def entry(value,size=10,option={},&blk)
  w=Entry.new().tap {|e| e.set_text(value ? value.to_s : "") }
  after(1) do
    w.signal_connect("key-press-event") do |en,e|
      after(1) { blk.call(w.text) rescue error($!) }
      false
    end 
  end if block_given?
  attribs(w,option)
end

#fentry(value, option = {}, &blk) ⇒ Object

create a integer text entry for keyboed input option must define :min :max :by for spin button



500
501
502
503
504
505
506
507
508
509
510
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 500

def fentry(value,option={},&blk)
  w=SpinButton.new(option[:min].to_f,option[:max].to_f,option[:by].to_f)
  w.set_numeric(true)
  w.set_value(value ? value.to_f : 0.0)
  w.signal_connect("value-changed") do |en|
    after(1) { blk.call(w.value) rescue error($!)  }
    false
  end if block_given?
  attribs(w,option)		
  w
end

#field(tlabel, width, value, option = {}, &blk) ⇒ Object

show a label and a entry in a flow. entry widget is returned see fields()



216
217
218
219
220
221
222
223
224
# File 'lib/ruiby_gtk/dsl/form_fields.rb', line 216

def field(tlabel,width,value,option={},&blk)
  e=nil
  flow {
    l=label(tlabel+ " : ")
    l.width_chars=width+3
    e=entry(value,option,&blk)
  }
  e
end

#fields(alabel = [["nothing",""]], option = {}, &blk) ⇒ Object

show a stack of label/entry and buttons validation/annulation on button, bloc is invoked with the list of values of entrys



228
229
230
231
232
233
234
235
236
237
# File 'lib/ruiby_gtk/dsl/form_fields.rb', line 228

def fields(alabel,option={},&blk)   
  size=alabel.map {|t| t[0].size}.max
  stack {
    le=alabel.map { |(label,value)| field(label,size,value) }
    if block_given?
        button("Validation") { blk.call(*le.map {|t| t.text}) }
        button("Annulation") { blk.call(*le.map {|t| nil}) }
    end
  }
end

#flow(config = {}, add1 = true, &b) ⇒ Object

container : horizontal box, take all space available, sloted in parent by default



32
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 32

def flow(add1=true,&b)	   		_cbox(true,HBox.new(false, 2),add1,&b) end

#flow_paned(size, fragment, &blk) ⇒ Object

create a container which can containe 2 widgets, separated by movable bar block invoked must create 2 widgets,horizonaly disposed



887
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 887

def flow_paned(size,fragment,&blk) _paned(true,size,fragment,&blk) end

#flowi(config = {}, add1 = true, &b) ⇒ Object

container : horizontal box, take only necessary space , sloted in parent



36
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 36

def flowi(add1=true,&b)	   		_cbox(false,HBox.new(false, 2),add1,&b) end

#force_update(canvas) ⇒ Object

update a canvas



600
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 600

def force_update(canvas) canvas.queue_draw unless  canvas.destroyed?  end

#frame(t = "", config = {}, add1 = true, &b) ⇒ Object

a box with border and texte title, take all space



61
62
63
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 61

def frame(t="",add1=true,&b)  	
  _cbox(true,Frame.new(t),add1) { stack { b.call } } 
end

#framei(t = "", config = {}, add1 = true, &b) ⇒ Object

a box with border and texte title, take only necessary space



65
66
67
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 65

def framei(t="",add1=true,&b)
  _cbox(false,Frame.new(t),add1) { stack { b.call } }
end

#get_config(w) ⇒ Object

get a Hash aff all properties of a gtk widget



207
208
209
210
211
212
213
214
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 207

def get_config(w)
  return({"nil"=>""}) unless w && w.class.respond_to?("properties")
  w.class.properties().inject({"class"=>w.class.to_s}) { |h,meth| 
    data=(w.send(meth) rescue nil)
    h[meth]=data.inspect.gsub(/^#/,'')[0..32]  if data 
    h
  }
end

#get_current_containerObject



204
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 204

def get_current_container() @lcur.last end

#get_icon(name) ⇒ Object

raster images access #############################



218
219
220
221
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 218

def get_icon(name)
  return name if name.index('.') && File.exists?(name)
  eval("Gtk::Stock::"+name.upcase) rescue nil
end

#get_image_from(name, size = :button) ⇒ Object

get a Image widget from a file or from a Gtk::Stock image can be a filename or a predefined icon in GTK::Stock 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


232
233
234
235
236
237
238
239
240
241
242
243
244
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 232

def get_image_from(name)
  if name.index('.') 
    return Image.new(name) if File.exists?(name)
    return _sub_image(name) if name.index("[")
    alert("unknown icone #{name}")
  end
  iname=get_icon(name)
  if iname
    Image.new(iname,IconSize::BUTTON)
  else
    nil
  end
end

#get_pixbuf(name) ⇒ Object



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 248

def get_pixbuf(name)
  @cach_pix={} unless defined?(@cach_pix)
  filename,px,py,bidon,dim=name.split(/\[|,|(\]x)/)
  if filename && px && py && bidon && dim && File.exist?(filename)
    dim=dim.to_i
    @cach_pix[filename]=Gdk::Pixbuf.new(filename) unless @cach_pix[filename]
    x0= dim*px.to_i
    y0= dim*py.to_i
    #p [x0,y0,"/",@cach_pix[filename].width,@cach_pix[filename].height]
    Gdk::Pixbuf.new(@cach_pix[filename],x0,y0,dim,dim)
  elsif File.exists?(name)
    @cach_pix[name]=Gdk::Pixbuf.new(name) unless @cach_pix[name]
    @cach_pix[name]
  elsif ! name.index(".")
    get_stockicon_pixbuf(name)
  else
    raise("file #{name} not exist");
  end
end

#get_stockicon_pixbuf(name) ⇒ Object

Image#initialize(:label => nil, :mnemonic => nil, :stock => nil, :size => nil)'



12
13
14
# File 'lib/ruiby_gtk/dsl/pixmap.rb', line 12

def get_stockicon_pixbuf(name)
  Image.new(eval("Gtk::Stock::"+name.upcase),IconSize::BUTTON).pixbuf
end

#grid(names, w = 0, h = 0, options = {}) ⇒ Object

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



1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1123

def grid(names,w=0,h=0)
  scrolled_win = Gtk::ScrolledWindow.new
  scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
  scrolled_win.set_width_request(w)	if w>0
  scrolled_win.set_height_request(h)	if h>0
  
  model = Gtk::ListStore.new(*([String]*names.size))
  treeview = Gtk::TreeView.new(model)
  treeview.selection.set_mode(Gtk::SELECTION_SINGLE)
  names.each_with_index do  |name,i|
    treeview.append_column(
      Gtk::TreeViewColumn.new( name,Gtk::CellRendererText.new,{:text => i} )
    )
  end
  if block_given?
    treeview.signal_connect("row-activated") do |view, path, column|
      iter = view.model.get_iter(path)
      yield(names.size.times.map { |i| iter[i] })
    end		
  end
  
  def scrolled_win.grid() children[0].children[0] end
  def scrolled_win.model() grid().model end
  def scrolled_win.add_row(words)
    l=grid().model.append()
    words.each_with_index { |w,i| l[i] = w.to_s }
  end
  $ici=self
  def scrolled_win.get_data()	
    raise("grid.get_data() out of main thread!")if $__mainthread__ != Thread.current
    @ruiby_data
  end
  def scrolled_win.set_data(data)	
    @ruiby_data=data
    raise("grid.set_data() out of main thread!")if $__mainthread__ != Thread.current
    grid().model.clear() ; data.each { |words| add_row(words) }
  end
  def scrolled_win.selection() a=grid().selection.selected ; a ? a[0] : nil ; end
  def scrolled_win.index() grid().selection.selected end
  
  scrolled_win.add_with_viewport(treeview)
  autoslot(nil)
  slot(scrolled_win)
end

#haccordionObject

create a horizontral accordion menu. must contain aitem() which must containe alabel() : accordion { aitem(txt) { alabel(lib) { code }; …} … }



849
850
851
852
853
854
855
856
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 849

def haccordion() 
  @slot_accordion_active=nil #only one accordion active by window!
  w=flow { flowi {
    yield
  }}
  separator
  w
end

#hide_appObject



89
90
91
92
# File 'lib/ruiby_gtk/systray.rb', line 89

def hide_app
  iconify
  hide
end

#hradio_buttons(ltext = ["empty!"], value = -1)) ⇒ Object

as vradio_buttons , but horizontaly disposed



437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 437

def hradio_buttons(ltext=["empty!"],value=-1)
  flow(false) {
    b0=nil
    ltext.each_with_index {|t,i|
      b=if i==0
          b0=slot(RadioButton.new(t))
      else
          slot(RadioButton.new(b0,t))
      end
      if i==value
      b.toggled 
      b.set_active(true) 
      end
    }
  }
end

#html_color(str) ⇒ Object

parse color from #RRggBB html format



232
# File 'lib/ruiby_gtk/ruiby_dsl3.rb', line 232

def html_color(str) ::Gdk::Color.parse(str) end

#htoolbar(options = {}) ⇒ Object

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 ; ... }


353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 353

def htoolbar(items,options={})
  b=Toolbar.new
  b.set_toolbar_style(Toolbar::Style::ICONS)
  i=0
  items.each {|name_tooltip,v| 
    name,tooltip=name_tooltip,nil
    if ((ar=name_tooltip.split('/')).size>1)
      name,tooltip=*ar
      tooltip="  #{tooltip.capitalize}  "
    end
    iname=get_icon(name)
    w=if iname
      Gtk::ToolButton.new(iname).tap { |but|
        but.signal_connect("clicked") { v.call rescue error($!) } if v
        but.set_tooltip_text(tooltip) if tooltip
      }
    elsif name=~/^sep/i
      Gtk::SeparatorToolItem.new				
    elsif name=~/^right-(.*)/i
      Gtk::ToolButton.new(get_icon($1)).tap { |but|
        but.signal_connect("clicked") { v.call rescue error($!) } if v
        but.set_tooltip_text(tooltip) if tooltip
      }
    else
      puts "=======================\nUnknown icone : #{name}\n====================="
        puts "Icones dispo: #{Stock.constants.map { |ii| ii.downcase }.join(", ")}"
      Gtk::ToolButton.new(Stock::MISSING_IMAGE)
    end
    if w
      Ruiby.gtk_version(2) ? b.insert(i,w) : b.insert(w,i)
    end
    i+=1
   }
  attribs(b,options)
end

#htoolbar_with_icon_text(conf = {}) ⇒ Object

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



286
287
288
289
290
# File 'lib/ruiby_gtk/ruiby_dsl3.rb', line 286

def htoolbar_with_icon_text(conf={})
  flowi {
    yield
  }
end

#ientry(value, option = {}, &blk) ⇒ Object

create a integer text entry for keyboed input option must define :min :max :by for spin button



485
486
487
488
489
490
491
492
493
494
495
496
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 485

def ientry(value,option={},&blk)
  w=SpinButton.new(option[:min].to_i,option[:max].to_i,option[:by])
  w.set_numeric(true)
  w.set_value(value ? value.to_i : 0)
  
  w.signal_connect("value-changed") do |en|
    after(1) { blk.call(w.value) }
    false
  end if block_given?
  attribs(w,option)		
  w
end

#image(file, options = {}) ⇒ Object

create a icon with a raster file option can specify a new size : :width and :height, or :size (square image)



316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 316

def image(file,options={})
  im=if File.exists?(file)
    pix=Gdk::Pixbuf.new(file) 
    pix=pix.scale(options[:width],options[:height],Gdk::Pixbuf::INTERP_BILINEAR) if options[:width] && options[:height]
    pix=pix.scale(options[:size],options[:size],Gdk::Pixbuf::INTERP_BILINEAR)  if options[:size] 
    Image.new(pix)
  else
    label("? "+file)
  end
  options.delete(:size)
  attribs(im,options)
end

#islider(value = 0, option = {}, &b) ⇒ Object

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.



534
535
536
537
538
539
540
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 534

def islider(value,option={},&b)
  w=HScale.new(option[:min].to_i,option[:max].to_i,option[:by])
    .set_value(value ? value.to_i : 0)
  attribs(w,option)		
  w.signal_connect(:value_changed) { || b.call(w.value)  rescue error($!) } if block_given?
  w
end

#label(text, options = {}) ⇒ Object

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)



301
302
303
304
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 301

def label(text,options={})
  l=_label(text,options)
  attribs(l,options)
end

#labeli(text, options = {}) ⇒ Object



305
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 305

def labeli(text,options={}) sloti(label(text,options)) end

#left(&blk) ⇒ Object

TODO : not tested!



90
91
92
93
94
95
96
97
# File 'lib/ruiby_gtk/dsl/layouts.rb', line 90

def left(&blk) 
  autoslot()
  w=yield
  halign = Gtk::Alignment.new(0,0,0,0)
  halign.add(w)
  @lcur.last.pack_start(halign, :expand => false, :fill => false, :padding => 3)
  razslot()
end

#levelbar(start = 0, options) ⇒ Object



114
115
116
117
118
# File 'lib/ruiby_gtk/dsl/label_button_image.rb', line 114

def levelbar(start=0,options)
 w=Gtk::LevelBar.new
 # TODO set value/progress/BynVar
 attribs(w,{})
end

#list(title, w = 0, h = 0, options = {}) ⇒ Object

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 : #Ruiby_dsl.ii.join(',')”) }.set_data(%wb c d)



1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1084

def list(title,w=0,h=0)
  scrolled_win = Gtk::ScrolledWindow.new
  scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
  scrolled_win.set_width_request(w)	if w>0
  scrolled_win.set_height_request(h)	if h>0
  model = Gtk::ListStore.new(String)
  column = Gtk::TreeViewColumn.new(title.to_s,Gtk::CellRendererText.new, {:text => 0})
  treeview = Gtk::TreeView.new(model)
  if block_given?
    treeview.signal_connect("row-activated") do |view, path, _|
      iter = view.model.get_iter(path)
      yield iter[0]
    end		
  end
  treeview.append_column(column)
  treeview.selection.set_mode(Gtk::SELECTION_SINGLE)
  scrolled_win.add_with_viewport(treeview)
  def scrolled_win.list() children[0].children[0] end
  def scrolled_win.model() list().model end
  def scrolled_win.clear() list().model.clear end
  def scrolled_win.add_item(word)
    raise("list.add_item() out of main thread!") if $__mainthread__ != Thread.current
    list().model.append[0]=word  
  end
  def scrolled_win.set_data(words)
    raise("list.set_data() out of main thread!") if $__mainthread__ != Thread.current
    list().model.clear
    words.each { |w| list().model.append[0]=w }
  end
  def scrolled_win.selection() a=list().selection.selected ; a ? a[0] : nil ; end
  def scrolled_win.index() list().selection.selected end
  autoslot(scrolled_win)
  scrolled_win
end

#log(*txt) ⇒ Object

put a line of message text in log dialog (create and show the log dialog if not exist)



1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1321

def log(*txt)
  if $__mainthread__ && $__mainthread__ != Thread.current
    gui_invoke { log(*txt) }
    return
  end
  loglabel=_create_log_window()
  loglabel.buffer.text +=  Time.now.to_s+" | " + (txt.join(" ").encode("UTF-8"))+"\n" 
  if ( loglabel.buffer.text.size>1000*1000)
    loglabel.buffer.text=loglabel.buffer.text[-7000..-1].gsub(/^.*\n/m,"......\n\n")
  end
end

a vertial drop-down menu, only for menu_bar container



803
804
805
806
807
808
809
810
811
812
813
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 803

def menu(text)
raise("menu(#{text}) without menu_bar {}") unless @menuBar
@filem = MenuItem.new(text.to_s)
@menuBar.append(@filem)
@mmenu = Menu.new()
yield
@filem.submenu=@mmenu
show_all_children(@mmenu)
@filem=nil
@mmenu=nil
end

create a application menu. must contain menu() {} : menu_bar {menu(“F”) {menu_button(“a”) { } ; menu_separator; menu_checkbutton(“b”) { |w|} …}}



793
794
795
796
797
798
799
800
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 793

def menu_bar()
@menuBar= MenuBar.new
ret=@menuBar
yield
sloti(@menuBar)
@menuBar=nil
ret
end

create an text entry in a menu



816
817
818
819
820
821
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 816

def menu_button(text="?",&blk)
raise("menu_button(#{text}) without menu('ee') {}") unless @mmenu
item = MenuItem.new(text.to_s)
@mmenu.append(item)
item.signal_connect("activate") { blk.call(text)  rescue error($!) }
end

create an checkbox entry in a menu



824
825
826
827
828
829
830
831
832
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 824

def menu_checkbutton(text="?",state=false,&blk)
raise("menu_button(#{text}) without menu('ee') {}") unless @mmenu
item = CheckMenuItem.new(text,false)
item.active=state
@mmenu.append(item)
item.signal_connect("activate") {
  blk.call(item,text) rescue error($!.to_s)
} 
end


833
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 833

def menu_separator() @mmenu.append( SeparatorMenuItem.new ) end

#next_rowObject



37
38
39
40
# File 'lib/ruiby_gtk/dsl/table.rb', line 37

def next_row()
  @ltable.last[:col]=0 # will be increment by cell..()
  @ltable.last[:row]+=1
end

#notebookObject

create a notebook widget. it must contain page() wigget notebook { page(“first”) { … } ; … }



747
748
749
750
751
752
753
754
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 747

def notebook() 
nb = Notebook.new()
slot(nb)
@lcur << nb
yield
@lcur.pop
nb
end

#on_canvas_button_motion(&blk) ⇒ Object

define action on mouse button motion on current canvas definition



194
195
196
197
198
199
200
201
# File 'lib/ruiby_gtk/dsl/canvas.rb', line 194

def on_canvas_button_motion(&blk )
  _accept?(:handler)
  @currentCanvas.signal_connect('motion_notify_event')  { |w,e| 
    next unless w.get_memo()
    w.set_memo(blk.call(w,e,w.get_memo)) rescue error($!)
    force_update(w)
  }
end

#on_canvas_button_press(&blk) ⇒ Object

define action on button_press action must return an object whici will be transmit to motion/release handler



177
178
179
180
181
182
183
# File 'lib/ruiby_gtk/dsl/canvas.rb', line 177

def on_canvas_button_press(&blk)
  _accept?(:handler)
  @currentCanvas.signal_connect('button_press_event')   { |w,e| 
    w.set_memo(blk.call(w,e))  rescue error($!)
    force_update(w) 
  }  
end

#on_canvas_button_release(&blk) ⇒ Object

define action on mouse button press on current canvas definition



185
186
187
188
189
190
191
192
# File 'lib/ruiby_gtk/dsl/canvas.rb', line 185

def on_canvas_button_release(&blk)
  _accept?(:handler)
  @currentCanvas.signal_connect('button_release_event') { |w,e| 
    blk.call(w,e,w.get_memo) rescue error($!)
    w.set_memo(nil)
    force_update(w) 
  }  
end

#on_canvas_draw(&blk) ⇒ Object

define the drawing on current canvas definition



214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/ruiby_gtk/dsl/canvas.rb', line 214

def on_canvas_draw(&blk)
  _accept?(:handler)
  @currentCanvas.signal_connect(  'draw' ) do |w,cr| 
    cr.save do
      cr.set_line_join(Cairo::LINE_JOIN_ROUND)
      cr.set_line_cap(Cairo::LINE_CAP_ROUND)
      cr.set_line_width(2)
      cr.set_source_rgba(1,1,1,1)
      cr.paint
      begin
         w.instance_eval { @currentCanvasCtx=[w,cr] }
         blk.call(w,cr) 
         w.instance_eval { @currentCanvasCtx=nil }
      rescue Exception => e
       after(1) { error(e) }
      end  
    end
  end
end

#on_canvas_key_press(&blk) ⇒ Object

define action on keyboard press on current *window* definition



203
204
205
206
207
208
209
210
211
# File 'lib/ruiby_gtk/dsl/canvas.rb', line 203

def on_canvas_key_press(&blk)
  _accept?(:handler)
  p "signal key press"    
  @currentCanvas.signal_connect('key_press_event')  { |w,e| 
    p "signal key press  ok #{e}"    
    blk.call(w,e,Gdk::Keyval.to_name(e.keyval)) rescue error($!)
    force_update(w) 
  }
end

#page(title, icon = nil) ⇒ Object

a page widget. only for notebook container. button can be text or icone (if startin by '#', as label)



757
758
759
760
761
762
763
764
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 757

def page(title,icon=nil)
if icon && icon[0,1]=="#" 
  l = Image.new(get_icon(icon[1..-1]),IconSize::BUTTON); #flow(false) { label(icon) ; label(title) }
else
  l=Label.new(title)
end 
@lcur.last.append_page( stack(false)  { yield }, l )
end

#pclickable(aproc = nil, options = {}, &b) ⇒ Object

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



1065
1066
1067
1068
1069
1070
1071
1072
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1065

def pclickable(aproc,&b) 
  eventbox = Gtk::EventBox.new
  eventbox.events = Gdk::Event::BUTTON_PRESS_MASK
  ret=_cbox(true,eventbox,true,&b) 
  eventbox.realize
  eventbox.signal_connect('button_press_event') { |w, e| aproc.call(w,e)  rescue error($!)  }
  ret
end

#pclickablie(aproc = nil, options = {}, &b) ⇒ Object

as pclickable, but container is a stacki pclickablei(proc { alert(“e”) }) { label(“click me!”) }



154
155
156
157
158
159
160
161
162
163
# File 'lib/ruiby_gtk/dsl/label_button_image.rb', line 154

def pclickablie(aproc=nil,options={},&b) 
  _accept?(:layout)
  eventbox = Gtk::EventBox.new
  eventbox.events = Gdk::Event::BUTTON_PRESS_MASK
  ret=_cbox(false,eventbox,{},true,&b) 
  eventbox.realize
  eventbox.signal_connect('button_press_event') { |w, e| aproc.call(w,e)  rescue error($!)  } if aproc
  apply_options(eventbox,options)
  ret
end

#plot(width, height, curves, config = {}) ⇒ Object

define a plot zone, with several curves :

pl=plot(400,200,{
    "curve1" => {
       data:[[0,1],[110,1],[20,1],[30,1],[10,1],[22,1],[55,1],[77,1]],
       color: '#FF0000', xminmax:[0,100], yminmax:[0,100], style: :linear,},...})
}

this methods are added :

  • pl.set_data(name,data) : replace current values par a new list of point [ [y,x],.…] for curve named 'name'

  • pl.get_data(name)

  • pl.add_curve(name,data:…) : add a curve

  • pl.delete_curve(name) : delete a curve

  • pl.add_data(name,pt) : add a point at the end of the curve

  • pl.scroll_data(name,value) : add a point at last and scroll if necessary (act as oscilloscope)

see samples/plot.rb



291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# File 'lib/ruiby_gtk/dsl/canvas.rb', line 291

def plot(width,height,curves,config={})
   plot=canvas(width,height) do
     on_canvas_draw { |w,ctx| w.expose(ctx) }
     on_canvas_button_press { |w,event| }
   end
   def plot.add_curve(name,config) 
      c=config.dup
      c[:data] ||= [[0,0],[100,100]]
      c[:maxlendata] ||= 100
      c[:color] ||= "#003030"
      c[:xminmax] ||= [c[:data].first[1],c[:data].last[1]]
      c[:yminmax] ||= [0,100]
      c[:style] ||= :linear
      c[:xa] = 1.0*width_request/(c[:xminmax][1]-c[:xminmax][0])
      c[:xb] = 0.0    -c[:xminmax][0]*c[:xa]
      c[:ya] = 1.0*height_request/(c[:yminmax][0]-c[:yminmax][1])
      c[:yb] = 1.0*height_request+c[:yminmax][0]*c[:xa]
      @curves||={}
      @curves[name]=c
   end
   def plot.delete_curve(name) 
      @curves.delete(name)
      redraw
   end
   def plot.expose(ctx) 
      @curves.values.each do |c|
            next if c[:data].size<2
            l=c[:data].map { |(y,x)|  [x*c[:xa]+c[:xb] , y*c[:ya]+c[:yb] ]  }
            coul=c[:rgba]
            ctx.set_source_rgba(coul.red,coul.green,coul.blue)
            ctx.move_to(*l[0])
            l[1..-1].each { |pt| ctx.line_to(*pt) }
            ctx.stroke
      end
   end
   
   def plot.set_data(name,data) 
     @curves[name][:data]=data
     maxlen(name,@curves[name][:maxlendata])
     redraw
   end
   def plot.get_data(name) 
     @curves[name][:data]
   end
   def plot.add_data(name,pt) 
     @curves[name][:data] << pt
     maxlen(name,@curves[name][:maxlendata])
     redraw
   end
   def plot.scroll_data(name,value) 
      l=@curves[name][:data]
      pas=width_request/l.size
      l.each { |pt| pt[1]-=pas } 
      l << [ value , @curves[name][:xminmax].last ]
      maxlen(name,@curves[name][:maxlendata])
      redraw
   end
   def plot.maxlen(name,len)
     @curves[name][:data]=@curves[name][:data][-len..-1] if @curves[name][:data].size>len
   end
   curves.each { |name,descr| descr[:rgba]=color_conversion(descr[:color]||'#303030') ; plot.add_curve(name,descr) }
   plot
end

Popup create a dynamic popup. (shoud by calling in a closure) popup block can be composed by pp_item and pp_separator Exemple : popup { pp_item(“text”) { } ; pp_seperator ; pp_item('Exit“) { exit!(0)} ; .…}



768
769
770
771
772
773
774
775
776
777
778
779
780
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 768

def popup(w=nil)
w ||= @lcur.last() 
ppmenu = Gtk::Menu.new
@lcur << ppmenu 
yield
@lcur.pop
ppmenu.show_all		
w.add_events(Gdk::Event::BUTTON_PRESS_MASK)
w.signal_connect("button_press_event") do |widget, event|
  ppmenu.popup(nil, nil, event.button, event.time) if (event.button == 3)
end
ppmenu
end

#pp_item(text, &blk) ⇒ Object

a button in a popup



26
27
28
29
30
# File 'lib/ruiby_gtk/dsl/menus_popup.rb', line 26

def pp_item(text,&blk)
item = Gtk::MenuItem.new(text)
item.signal_connect('activate') { |w| blk.call() }
@lcur.last.append(item)
end

#pp_separatorObject

a bar separator in a popup



33
34
35
36
# File 'lib/ruiby_gtk/dsl/menus_popup.rb', line 33

def pp_separator()
item = Gtk::SeparatorMenuItem.new()
@lcur.last.append(item)
end

#progress_bar(start = 0, options) ⇒ Object

Show the evolution if a numeric value. Evolution is a number between 0 and 1.0 w.progress=n force current evolution



108
109
110
111
112
113
# File 'lib/ruiby_gtk/dsl/label_button_image.rb', line 108

def progress_bar(start=0,options)
 w=Gtk::ProgressBar.new
 w.define_singleton_method(:progress=) { |fract| w.fraction=fract }
 w.fraction=start
 attribs(w,{})
end

#properties(title, hash, options = {:edit=>false, :scroll=>[0,0]}) ⇒ Object

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



680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 680

def properties(title,hash,options={:edit=>false, :scroll=>[0,0]})
  if ! defined?(@prop_index)
    @prop_index=0
    @prop_hash={}
  else
    @prop_index+=1
  end
  prop_current=(@prop_hash[@prop_index]={})
  widget=stacki {
  framei(title.to_s) {
     stack {
      if options[:scroll] &&  options[:scroll][1]>0
       vbox_scrolled(options[:scroll][0],options[:scroll][1]) {
         table(2,hash.size) {
          hash.each { |k,v| row {
            _make_prop_line(prop_current,options,k,v)
          }}
          }
        }
      else
       table(2,hash.size) {
        hash.each { |k,v| row {
            _make_prop_line(prop_current,options,k,v)
        }}
        }
      end
        if options[:edit]
          sloti(button("Validation") { 
            nhash=widget.get_data()
            if block_given? 
              yield(nhash)
            else
              hash.clear
              nhash.each { |k,v| hash[k]=v }
            end
          }) 
        end
      }
   }
  }	
  widget.instance_variable_set(:@prop_current,prop_current)	  
  widget.instance_variable_set(:@hash_initial,hash)	  
  def widget.set_data(newh)
    newh.each { |k,v| @prop_current[k].text=v.to_s }
  end
  def widget.get_data()
  @prop_current.inject({}) {|nhash,(k,w)| 
    v_old=@hash_initial[k]
    v_new=w.text
    vbin=case v_old 
      when String then v_new
      when Fixnum then v_new.to_i
      when Float  then v_new.to_f
      when /^(\[.*\])|(\{.*\})$/ then eval( v_new ) rescue error($!)
      else v_new.to_s
    end
    nhash[k]=vbin
    nhash
  }
  end
  widget
end

#propertys(title, hash, options = {:edit=>false, :scroll=>[0,0]}, &b) ⇒ Object

deprecated: see properties



654
655
656
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 654

def propertys(title,hash,options={:edit=>false, :scroll=>[0,0]},&b)
  properties(title,hash,options,&b)
end

#razslotObject

forget precedent widget oconstructed



96
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 96

def razslot() @current_widget=nil; end

#regular(on = true) ⇒ Object

set homogeneous contrainte on current container : all chidren whill have same size

  • stack : children will have same height

  • flow : children will have same width



70
# File 'lib/ruiby_gtk/dsl/layouts.rb', line 70

def regular(on=true) @lcur.last.homogeneous=on end

#right(&blk) ⇒ Object

TODO : not tested!



99
100
101
102
103
104
105
106
# File 'lib/ruiby_gtk/dsl/layouts.rb', line 99

def right(&blk) 
  autoslot()
  w=yield
  halign = Gtk::Alignment.new(1,0,0,0)
  halign.add(w)
  @lcur.last.pack_start(halign, :expand => false, :fill => false, :padding => 3)
  razslot()
end

#rowObject

can only contain cell(s) call



30
31
32
33
34
35
36
# File 'lib/ruiby_gtk/dsl/table.rb', line 30

def row()
  autoslot()
  _accept?(:row)
  @ltable.last[:col]=0 # will be increment by cell..()
  yield
  @ltable.last[:row]+=1
end

#scrolled(width, height, &b) ⇒ Object

create a Scrolled widget with a autobuild stack in it stack can be populated respond to : scroll_to_top; scroll_to_bottom,



1032
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1032

def scrolled(width,height,&b)  vbox_scrolled(width,height,&b) end

#separator(width = 1.0) ⇒ Object

create a bar (vertical or horizontal according to stack/flow current container)



295
296
297
298
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 295

def separator(width=1.0)  
  autoslot()
  sloti(HBox === @lcur.last ? VSeparator.new : HSeparator.new)  
end

#show_all_children(c) ⇒ Object



143
144
145
146
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 143

def show_all_children(c)
  return unless c
  c.each { |f|   show_all_children(f) if  f.respond_to?(:children) ; f.show() } ; c.show
end

#show_appObject



85
86
87
88
# File 'lib/ruiby_gtk/systray.rb', line 85

def show_app()
  deiconify 
  show 
end

#show_methods(obj = nil, filter = nil) ⇒ Object

show methods of a object/class in log window



668
669
670
671
672
673
674
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 668

def show_methods(obj=nil,filter=nil)
  obj=self unless obj
  title="\n============ #{Class===obj.class ? obj : obj.class} ===========\n"
  data=(obj.methods-Object.methods).grep(filter || /.*/).sort.each_slice(3).map { |a,b,c| "%-30s| %-30s| %-30s" % [a,b,c]}.join("\n")
  footer="\n==================================================\n"
  log( title+data+footer)
end

#slider(start = 0.0, min = 0.0, max = 1.0, options = {}) ⇒ Object

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



96
97
98
99
100
101
102
103
104
# File 'lib/ruiby_gtk/dsl/label_button_image.rb', line 96

def slider(start=0.0,min=0.0,max=1.0,options={})
 w=Gtk::Scale.new(:horizontal)
 w.set_range min,max
 w.set_size_request 160, 35
 w.set_value start
 w.signal_connect("value-changed") { |w| yield(w.value) } if block_given?
 w.define_singleton_method(:progress=) { |value| w.set_value(value) }
 attribs(w,{})
end

#slot(w) ⇒ Object

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



84
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 84

def slot(w)  @current_widget=nil; @lcur.last.add(w) ; w end

#slot_append_after(w, wref) ⇒ Object

append the widget w after anotherone wref) thread protected



165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 165

def slot_append_after(w,wref)
  if $__mainthread__ != Thread.current
    gui_invoke { slot_append_after(w,wref) }
    return
  end
  parent=_check_append("slot_append_after",w,wref)
  parent.add(w)
  parent.children.each_with_index { |child,i| 
    next if child!=wref
    parent.reorder_child(w,i+1)
    break
  }
  w
end

#slot_append_before(w, wref) ⇒ Object

append the widget w before another one wref thread protected



149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 149

def slot_append_before(w,wref)
  if $__mainthread__ != Thread.current
    gui_invoke { slot_append_before(w,wref) }
    return
  end
  parent=_check_append("slot_append_before",w,wref)
  parent.add(w)
  parent.children.each_with_index { |child,i| 
    next if child!=wref
    parent.reorder_child(w,i)
    break
  }
  w
end

#sloti(w) ⇒ Object

pack widget in parameter, take only necessary space



87
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 87

def sloti(w) @current_widget=nil; @lcur.last.pack_start(w,false,false,3) ; w end

#snapshot(filename = nil) ⇒ Object

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



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/ruiby_gtk/dsl/commands.rb', line 136

def snapshot(filename=nil)
   return unless  RUBY_PLATFORM =~ /in.*32/
   require 'win32/screenshot'
   require 'win32ole'
   
   filename=Time.now.strftime("%D-%H%m%s.png").gsub('/','-') unless filename

   if ! self.title || self.title.size<3
      self.title=Time.now.to_f.to_s.gsub('.','')
   end
  File.delete(filename) if File.exists?(filename)
  puts "generated  for title '#{self.title}' ==> #{filename} ..."
  Win32::Screenshot::Take.of(:window,:title => /#{self.title}/, :context => :window).write(filename)
  puts "done #{File.size(filename)} B"
end

#source_editor(args = {}, &blk) ⇒ Object

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)



911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 911

def source_editor(args={}) # from green_shoes plugin
  begin
    require 'gtksourceview2'
  rescue Exception
    log('gtksourceview2 not installed!, please use text_area')
    return
  end
  args[:width]  = 400 unless args[:width]
  args[:height] = 300 unless args[:height]
  change_proc = proc { }
  (change_proc = args[:on_change]; args.delete :on_change) if args[:on_change]
  sv = ::Gtk::SourceView.new
  sv.show_line_numbers = true
  sv.insert_spaces_instead_of_tabs = false
  sv.smart_home_end = Gtk::SourceView::SMART_HOME_END_ALWAYS
  sv.tab_width = 4
  sv.buffer.text = (args[:text]||"").to_s
  sv.buffer.language = Gtk::SourceLanguageManager.new.get_language(args[:lang]||'ruby')
  sv.buffer.highlight_syntax = true
  sv.modify_font(  Pango::FontDescription.new(args[:font] || "Courier new 10")) 

  cb = ScrolledWindow.new
  cb.define_singleton_method(:editor) { sv }
  cb.define_singleton_method(:text=) { |t| sv.buffer.text=t }
  cb.define_singleton_method(:text) {  sv.buffer.text }

  cb.set_size_request(args[:width], args[:height])
  cb.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
  cb.set_shadow_type(SHADOW_IN)
  cb.add(sv)
  cb.show_all
  attribs(cb,{})	
end

#space(n = 1) ⇒ Object

create a one-character size space, (or n character x n line space)



329
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 329

def space(n=1) label(([" "*n]*n).join("\n"))  end

#spacei(n = 1) ⇒ Object



55
# File 'lib/ruiby_gtk/dsl/label_button_image.rb', line 55

def spacei(n=1) labeli(([" "*n]*n).join("\n"))  end

#spacing(npixels = 0) ⇒ Object

set space between each chidren of current box



73
# File 'lib/ruiby_gtk/dsl/layouts.rb', line 73

def spacing(npixels=0) @lcur.last.spacing=npixels end

#stack(config = {}, add1 = true, &b) ⇒ Object

container : vertical box, take all space available, sloted in parent by default



30
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 30

def stack(add1=true,&b)    		_cbox(true,VBox.new(false, 2),add1,&b) end

#stack_paned(size, fragment, &blk) ⇒ Object

create a container which can containe 2 widgets, separated by movable bar block invoked must create 2 widgets, vertivaly disposed



881
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 881

def stack_paned(size,fragment,&blk) _paned(false,size,fragment,&blk) end

#stacki(config = {}, add1 = true, &b) ⇒ Object

container : vertical box, take only necessary space , sloted in parent



34
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 34

def stacki(add1=true,&b)    	_cbox(false,VBox.new(false, 2),add1,&b) end

#syst_add_button(label, &prc) ⇒ Object



78
# File 'lib/ruiby_gtk/systray.rb', line 78

def syst_add_button(label,&prc)  @systray_config[label]=prc     ; end

#syst_add_check(label, &prc) ⇒ Object



80
# File 'lib/ruiby_gtk/systray.rb', line 80

def syst_add_check(label,&prc)   @systray_config["+"+label]=prc ; end

#syst_add_sepratatorObject



79
# File 'lib/ruiby_gtk/systray.rb', line 79

def syst_add_sepratator()        @systray_config["--#{@systray_config.size}"]= proc {} ; end

#syst_icon(file) ⇒ Object



77
# File 'lib/ruiby_gtk/systray.rb', line 77

def syst_icon(file)            @systray_config[:icon]=file     ; end

#syst_quit_button(yes) ⇒ Object



81
# File 'lib/ruiby_gtk/systray.rb', line 81

def syst_quit_button(yes)       @systray_config[:quit]=yes       ; end

#systray(x = nil, y = nil, systray_config = {}) ⇒ Object



71
72
73
74
75
76
# File 'lib/ruiby_gtk/systray.rb', line 71

def systray(x=nil,y=nil,systray_config={})
  @title=File.basename($0).gsub(/\.rb/,'') unless defined?(@title)
  @systray_config=systray_config
  yield
  @systray=::Gtk::SysTray.new(self,@title,@systray_config,x,y)
end

#systray_setup(config) ⇒ Object



82
83
84
# File 'lib/ruiby_gtk/systray.rb', line 82

def systray_setup(config)
  @systray=::Gtk::SysTray.new(self,@title,config)
end

#table(nb_col, nb_row, config = {}) ⇒ Object

table create a container for table-disposed widgets. this is not a grid! table(r,c) { row { cell(w) ; .. } ; … }



11
12
13
14
15
16
17
18
19
20
21
# File 'lib/ruiby_gtk/dsl/table.rb', line 11

def table(nb_col=0,nb_row=0,config={})
  table = Gtk::Table.new(nb_row,nb_col,false)
  table.set_column_spacings(config[:set_column_spacings]) if config[:set_column_spacings]
  _set_accepter(table,:row,:cell,:widget)
  @lcur << table
  @ltable << { :row => 0, :col => 0}
  yield
  @ltable.pop
  @lcur.pop
  attribs(table,config)
end

#text_area(w = 200, h = 100, args = {}) ⇒ Object

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



948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 948

def text_area(w=200,h=100,args={}) # from green_shoes app
    tv = Gtk::TextView.new
    tv.wrap_mode = TextTag::WRAP_WORD
    tv.buffer.text = args[:text].to_s if args[:text]
    tv.modify_font(Pango::FontDescription.new(args[:font])) if args[:font]
    tv.accepts_tab = true

    eb = Gtk::ScrolledWindow.new
    eb.set_size_request(w,h) 
    eb.add(tv)
    eb.define_singleton_method(:text_area) { tv }
    class << eb
    def text=(a)  self.children[0].buffer.text=a.to_s end
    def text()    self.children[0].buffer.text end
    def append(a) self.children[0].buffer.text+=a.to_s.encode("UTF-8") end
    end
    eb.children[0].buffer.text=(args[:text]||"")
    eb.show_all
    eb	
end

#text_area_dyn(dynvar, w = 200, h = 100, args = {}) ⇒ Object

multiline entry on dynvar



286
287
288
289
290
291
292
# File 'lib/ruiby_gtk/dsl/form_fields.rb', line 286

def text_area_dyn(dynvar,w=200,h=100,args={}) # from green_shoes app
  # TDODO : test !
  w=text_area_dyn(w,h,args) 
  dynvar.observ { |o,n| w.text=n }
  w.text_area.signal_connect(:changed) { |t,e| dynvar.value(w.text) }
  w
end

#toggle_button(text1, text2 = nil, value = false, option = {}, &blk) ⇒ Object

to state button, with text for each state and a initiale value value can be read by w.active? calue can be changed by w.set_active(true/false) callback on state change with new value as argument



415
416
417
418
419
420
421
422
423
424
425
426
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 415

def toggle_button(text1,text2=nil,value=false,option={},&blk)
  text2 = "- "+text1 unless text2
  b=ToggleButton.new(text1);
  b.signal_connect("toggled") do |w,e| 
    w.label= w.active?() ? text2.to_s : text1.to_s 
    ( blk.call(w.active?()) rescue error($!) ) if blk
  end
  b.set_active(value)
  b.label= value ? text2.to_s : text1.to_s 
  attribs(b,option)		
  b
end

#toolbar_button(name, tooltip = nil, &blk) ⇒ Object



257
258
259
260
261
262
263
264
265
266
267
# File 'lib/ruiby_gtk/ruiby_dsl3.rb', line 257

def toolbar_button(name,tooltip=nil,&blk)
    _accept?(:toolb)
    iname=get_icon(name)
    
    w=Gtk::ToolButton.new(:stock_id => iname)
    w.signal_connect("clicked") { blk.call rescue error($!) } if blk
    w.set_tooltip_text(tooltip) if tooltip
    
    @lcur.last.insert(w,@toolbarIndex)
    @toolbarIndex+=1
end

#toolbar_separatorObject



268
269
270
271
272
273
# File 'lib/ruiby_gtk/ruiby_dsl3.rb', line 268

def toolbar_separator()
    _accept?(:toolb)
    w=Gtk::SeparatorToolItem.new        
    @lcur.last.insert(w,@toolbarIndex)
    @toolbarIndex+=1
end

#tooltip(value = "?") ⇒ Object

give a tooltip to last widget created.



167
168
169
170
171
172
173
174
# File 'lib/ruiby_gtk/ruiby_dsl3.rb', line 167

def tooltip(value="?") 
  if @current_widget && @current_widget.respond_to?(:set_tooltip_markup)
    @current_widget.set_tooltip_markup(value) 
    @current_widget.has_tooltip=true
  else
    error("tooltip : '#{value[0..30]}' : there are no current widget or it cannot contain ToolTip !") 
  end
end

#tree_grid(names, w = 0, h = 0, options = {}) ⇒ Object

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 : <li> raster image if name start with a '#' <li> checkbutton if name start with a '?' <li> Integer if name start with a '0' <li> String else



1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1176

def tree_grid(names,w=0,h=0,options={})
  scrolled_win = Gtk::ScrolledWindow.new
  scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC)
  scrolled_win.set_width_request(w)	if w>0
  scrolled_win.set_height_request(h)	if h>0
  scrolled_win.shadow_type = Gtk::SHADOW_ETCHED_IN
  
  types=names.map do |name|
   case name[0,1]
    when "#" then Gdk::Pixbuf
    when "?" then TrueClass
    when "0".."9" then Integer
    else String
   end
  end
  model = Gtk::TreeStore.new(*types)
  
  treeview = Gtk::TreeView.new(model)
  treeview.selection.set_mode(Gtk::SELECTION_SINGLE)
  names.each_with_index do  |name,i|
    renderer,symb= *(
      if    types[i]==TrueClass then	 [Gtk::CellRendererToggle.new().tap { |r| r.signal_connect('toggled') { } },:win]
      elsif types[i]==Gdk::Pixbuf then [Gtk::CellRendererPixbuf.new,:active]
      elsif types[i]==Numeric then	 [Gtk::CellRendererText.new,:text]
      else 							 [Gtk::CellRendererText.new,:text]
      end
    )
    treeview.append_column(
      Gtk::TreeViewColumn.new( name.gsub(/^[#?0-9]/,""),renderer,{symb => i} )
    )
  end
  
  #------------- Build singleton
  
  def scrolled_win.init(types) @types=types end
  scrolled_win.init(types)
  def scrolled_win.tree() children[0].children[0] end
  def scrolled_win.model() tree().model end
  $ici=self
  def scrolled_win.get_data()	
    raise("tree.get_data() out of main thread!")if $__mainthread__ != Thread.current
    @ruiby_data
  end
  def scrolled_win.set_data(hdata,parent=nil,first=true)	
    raise("tree.set_data() out of main thread!")if $__mainthread__ != Thread.current
    if parent==nil && first
      @ruiby_data=hdata
      model.clear()
    end
    hdata.each do |k,v|
      case v
        when Array 
          set_row([k.to_s]+v,parent)
        when Hash 
          p=model.append(parent)
          p[0] =k.to_s
          set_data(v,p,false)
      end
    end
  end
  def scrolled_win.set_row(data,parent=nil)
    puts "treeview: raw data size nok : #{data.size}/#{data.inspect}" if data.size!=@types.size
    i=0
    c=self.model.append(parent)
    data.zip(@types) do |item,clazz|
      c[i]=if clazz==TrueClass then (item ? true : false)
        elsif clazz==Gdk::Pixbuf then $ici.get_pixbuf(item.to_s).tap {|a| p [item,clazz,a]}
        elsif clazz==Integer then item.to_i
        else item.to_s
      end
      i+=1
    end
  end
  def scrolled_win.selection() a=tree().selection.selected ; a ? a[0] : nil ; end
  def scrolled_win.index() tree().selection.selected end
  
  scrolled_win.add_with_viewport(treeview)
  autoslot(nil)
  slot(scrolled_win)
end

#updateObject



107
# File 'lib/ruiby_gtk/dsl/layouts.rb', line 107

def update() Ruiby.update() end

#var_box(sens, config = {}, add1 = true, &b) ⇒ Object

container : vertical or horizontal box (stack/flow, choice by first argument), sloted in parent by default



14
# File 'lib/ruiby_gtk/dsl/layouts.rb', line 14

def var_box(sens,config={},add1=true,&b) _cbox(true,Box.new(sens, 2),config,add1,&b) end

#var_boxi(sens, config = {}, add1 = true, &b) ⇒ Object

container : vertical or horizontal box (stacki/flowi, choice by first argument), sloted in parent by default



21
# File 'lib/ruiby_gtk/dsl/layouts.rb', line 21

def var_boxi(sens,config={},add1=true,&b) _cbox(false,Box.new(sens, 2),config,add1,&b) end

#vbox_scrolled(width, height, &b) ⇒ Object



1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1033

def vbox_scrolled(width,height,&b)
  sw=slot(ScrolledWindow.new())
  sw.set_width_request(width)		if width>0 
  sw.set_height_request(height)	if height>0
  sw.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS)
  ret= stack(false,&b) if  block_given? 
  sw.add_with_viewport(ret)
  class << sw
    def scroll_to_top()    vadjustment.set_value( 0 ) 					; vadjustment.value_changed ; end
    def scroll_to_bottom() vadjustment.set_value( vadjustment.upper - 100); vadjustment.value_changed ; end
    #def scroll_to_left()   hadjustment.set_value( 0 ) end
    #def scroll_to_right()  hadjustment.set_value( hadjustment.upper-1 ) end
  end
  attribs(sw,{})
end

#video(uri = nil, w = 300, h = 200, &blk) ⇒ Object

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= “foo.avi”

*.progress=n force current position in video (0..1)

video() need the gems clutter, GStreamer, and glues Clutter<=>Gtk : "clutter-gtk" and "clutter-gst" 
* gem install clutter-gtk 
* gem install clutter-gstreamer


1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 1006

def video(uri,w=300,h=200)
  wid=DrawingArea.new()
  wid.set_size_request(w,h)
  uri = File.join('file://', uri.gsub("\\", '/').sub(':', '')) unless uri =~ /^(\w\w+):\/\//
  require('gst')
  require('win32api') rescue nil
  v = Gst::ElementFactory.make('playbin2')
  v.video_sink = Gst::ElementFactory.make('dshowvideosink')
  v.uri = uri
  args[:real], args[:app] = v, self
      handle = wid.window.class.method_defined?(:xid) ? @app.win.window.xid : 
        Win32API.new('user32', 'GetForegroundWindow', [], 'N').call
      v.video_sink.xwindow_id = handle
  
  wid.events |= ( ::Gdk::Event::BUTTON_PRESS_MASK | ::Gdk::Event::POINTER_MOTION_MASK | ::Gdk::Event::BUTTON_RELEASE_MASK)
  wid.signal_connect('expose_event') do |w1,e| 		
  end
  def wid.video() v end
  wid.video.play
end

#vradio_buttons(ltext = ["empty!"], value = -1)) ⇒ Object

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



455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 455

def vradio_buttons(ltext=["empty!"],value=-1)
  stack(false) {
    b0=nil
    ltext.each_with_index {|t,i|
      b=if i==0
          b0=slot(RadioButton.new(t))
      else
          slot(RadioButton.new(b0,t))
      end
      if i==value
      b.toggled 
      b.set_active(true) 
      end
    }
  }
end

#widget_properties(title = nil, w = nil) ⇒ Object



289
290
291
292
# File 'lib/ruiby_gtk/ruiby_dsl.rb', line 289

def widget_properties(title=nil,w=nil) 
  widg=w||@current_widget||@lcur.last
  properties(title||widg.to_s,{},get_config(widg)) 
end