Class: Shoes::App

Inherits:
Object show all
Includes:
Mod2
Defined in:
lib/shoes/app.rb,
lib/shoes/text.rb,
lib/plugins/video.rb,
lib/shoes/helper_methods.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Mod2

#init_app_vars

Constructor Details

#initialize(args = {}) ⇒ App

Returns a new instance of App.



5
6
7
8
9
10
11
12
13
14
# File 'lib/shoes/app.rb', line 5

def initialize args={}
  args.each do |k, v|
    instance_variable_set "@#{k}", v
  end
  App.class_eval do
    attr_accessor *(args.keys - [:width, :height, :title])
  end
  init_app_vars
  @top_slot, @cslot = nil, self
end

Instance Attribute Details

#contentsObject

Returns the value of attribute contents.



16
17
18
# File 'lib/shoes/app.rb', line 16

def contents
  @contents
end

#cslotObject

Returns the value of attribute cslot.



16
17
18
# File 'lib/shoes/app.rb', line 16

def cslot
  @cslot
end

#hidedObject

Returns the value of attribute hided.



16
17
18
# File 'lib/shoes/app.rb', line 16

def hided
  @hided
end

#locationObject (readonly)

Returns the value of attribute location.



18
19
20
# File 'lib/shoes/app.rb', line 18

def location
  @location
end

#mmcsObject

Returns the value of attribute mmcs.



16
17
18
# File 'lib/shoes/app.rb', line 16

def mmcs
  @mmcs
end

#mouse_button=(value) ⇒ Object (writeonly)

Sets the attribute mouse_button

Parameters:

  • value

    the value to set the attribute mouse_button to.



17
18
19
# File 'lib/shoes/app.rb', line 17

def mouse_button=(value)
  @mouse_button = value
end

#mouse_posObject

Returns the value of attribute mouse_pos.



16
17
18
# File 'lib/shoes/app.rb', line 16

def mouse_pos
  @mouse_pos
end

#mscsObject

Returns the value of attribute mscs.



16
17
18
# File 'lib/shoes/app.rb', line 16

def mscs
  @mscs
end

#orderObject

Returns the value of attribute order.



16
17
18
# File 'lib/shoes/app.rb', line 16

def order
  @order
end

#top_slotObject

Returns the value of attribute top_slot.



16
17
18
# File 'lib/shoes/app.rb', line 16

def top_slot
  @top_slot
end

Instance Method Details

#aflushObject



691
692
693
694
695
696
697
698
# File 'lib/shoes/app.rb', line 691

def aflush
  @hided = true
  Swt::Display.getDefault.asyncExec do
    Shoes.call_back_procs self
    @hided = false
    @cs.redraw unless @cs.isDisposed
  end
end

#animate(n = 10, repaint = true, &blk) ⇒ Object



233
234
235
236
237
238
# File 'lib/shoes/app.rb', line 233

def animate n=10, repaint=true, &blk
  n, i = 1000 / n, 0
  Anim.new(@cs, n, repaint, &blk).tap do |a|
    Shoes.display.timerExec n, a
  end
end

#background(pat, args = {}) ⇒ Object



583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
# File 'lib/shoes/app.rb', line 583

def background pat, args={}
  args[:pattern] = pat
  args = basic_attributes args
  args[:curve] ||= 0
  args[:real] = args[:create_real] ? :pattern : false
  args[:app] = self
  Background.new(args).tap do |s|
    unless s.real
      pat = s.pattern
      pl = Swt::PaintListener.new
      s.pl = pl
      class << pl; self end.
      instance_eval do
        define_method :paintControl do |e|
          unless s.hided
            gc = e.gc
            Shoes.dps_reset s.dps, gc
            gc.setAntialias Swt::SWT::ON
            Shoes.set_pattern s, gc, pat
            gc.fillRoundRectangle s.left, s.top, s.width, s.height, s.curve*2, s.curve*2
          end
        end
      end
      @cs.addPaintListener pl unless @cs.isDisposed
    end
    oval 0, 0, 0, strokewidth: 0 # A monkey patch for sample 10. I don't know why this line is necessary... xx-P
  end
end


114
# File 'lib/shoes/app.rb', line 114

def banner *msg; textblock Banner, 48, *msg; end

#basic_attributes(args = {}) ⇒ Object



34
35
36
37
38
39
# File 'lib/shoes/helper_methods.rb', line 34

def basic_attributes args={}
  default = BASIC_ATTRIBUTES_DEFAULT
  default.merge!({nocontrol: true}) if @nolayout
  replace_string_to_float args
  default.merge args
end

#border(pat, args = {}) ⇒ Object



612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
# File 'lib/shoes/app.rb', line 612

def border pat, args={}
  args[:pattern] = pat
  args = basic_attributes args
  args[:curve] ||= 0
  args[:strokewidth] = ( args[:strokewidth] or strokewidth or 1 )
  args[:real] = args[:create_real] ? :pattern : false
  args[:app] = self
  Border.new(args).tap do |s|
    unless s.real
      pat = s.pattern
      sw = s.strokewidth
      pl = Swt::PaintListener.new
      s.pl = pl
      class << pl; self end.
      instance_eval do
        define_method :paintControl do |e|
          unless s.hided
            gc = e.gc
            Shoes.dps_reset s.dps, gc
            gc.setAntialias Swt::SWT::ON
            Shoes.set_pattern s, gc, pat, :Foreground
            if sw > 0
              gc.setLineWidth sw
              gc.drawRoundRectangle s.left+sw/2, s.top+sw/2, s.width-sw, s.height-sw, s.curve*2, s.curve*2
            end
          end
        end
      end
      @cs.addPaintListener pl unless @cs.isDisposed
    end
  end
end

#button(name, args = {}) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/shoes/app.rb', line 155

def button name, args={}
  args = basic_attributes args
  b = Swt::Button.new @cs, Swt::SWT::NULL
  b.setText name
  b.setLocation args[:left], args[:top]
  if args[:width] > 0 and args[:height] > 0
    b.setSize args[:width], args[:height]
  else
    b.pack
  end
  args[:real], args[:text], args[:app] = b, name, self
  Button.new(args).tap do |s|
    b.addSelectionListener do |e|
      yield s
    end if block_given?
  end
end

#caption(*msg) ⇒ Object



118
# File 'lib/shoes/app.rb', line 118

def caption *msg; textblock Caption, 14, *msg; end

#clear(&blk) ⇒ Object



46
47
48
49
# File 'lib/shoes/app.rb', line 46

def clear &blk
  @top_slot.clear &blk
  aflush
end

#click(&blk) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/shoes/app.rb', line 51

def click &blk
  if blk
    app = self
    ln = Swt::Listener.new
    class << ln; self end.
    instance_eval do
      define_method :handleEvent do |e|
        blk[*app.mouse]
      end
    end
    @cs.addListener Swt::SWT::MouseDown, ln unless @cs.isDisposed
  end
end

#clickable(s, flag = :click, &blk) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/shoes/helper_methods.rb', line 55

def clickable s, flag = :click, &blk
  if blk
    ln = Swt::Listener.new
    s.ln = ln
    @mscs << s
    class << ln; self end.
    instance_eval do
      define_method :handleEvent do |e|
        if s.is_a?(Link) and !s.parent.hided
          mouse_x, mouse_y = e.x, e.y
          blk[s] if ((s.pl..(s.pl+s.pw)).include?(mouse_x) and (s.sy..s.ey).include?(mouse_y) and !((s.pl..s.sx).include?(mouse_x) and (s.sy..(s.sy+s.lh)).include?(mouse_y)) and !((s.ex..(s.pl+s.pw)).include?(mouse_x) and ((s.ey-s.lh)..s.ey).include?(mouse_y)))
        elsif !s.is_a?(Link) and !s.hided
          dx, dy = s.is_a?(Star) ? [s.width / 2.0, s.height / 2.0] : [0, 0]
          blk[s] if s.left - dx <= e.x and e.x <= s.left - dx + s.width and s.top - dy <= e.y and e.y <= s.top - dy + s.height
        end
      end
    end
    @cs.addListener Swt::SWT::MouseDown, ln if flag == :click
    @cs.addListener Swt::SWT::MouseUp, ln if flag == :release
  end
end

#closeObject



680
681
682
# File 'lib/shoes/app.rb', line 680

def close
  @shell.close
end

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



659
660
661
# File 'lib/shoes/app.rb', line 659

def download name, args={}, &blk
  Download.new name, args, &blk
end

#edit_box(*attrs, &blk) ⇒ Object



212
213
214
# File 'lib/shoes/app.rb', line 212

def edit_box *attrs, &blk
  edit_text [EditBox, 200, 100, Swt::SWT::MULTI | Swt::SWT::WRAP, blk, attrs]
end

#edit_line(*attrs, &blk) ⇒ Object



208
209
210
# File 'lib/shoes/app.rb', line 208

def edit_line *attrs, &blk
  edit_text [EditLine, 200, 20, Swt::SWT::SINGLE, blk, attrs]
end

#edit_text(attrs) ⇒ Object



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/shoes/app.rb', line 191

def edit_text attrs
  klass, w, h, style, blk, attrs = attrs
  args = attrs.last.class == Hash ? attrs.pop : {}
  txt = attrs.first unless attrs.empty?
  args = basic_attributes args
  args[:width] = w if args[:width].zero?
  args[:height] = h if args[:height].zero?
  
  el = Swt::Text.new @cs, Swt::SWT::BORDER | style
  el.setText txt || args[:text].to_s
  el.setSize args[:width], args[:height]
  args[:real], args[:app] = el, self
  klass.new(args).tap do |s|
    el.addModifyListener{|e| blk[s]} if blk
  end      
end

#every(n = 1, &blk) ⇒ Object



240
241
242
# File 'lib/shoes/app.rb', line 240

def every n=1, &blk
  animate 1.0/n, &blk
end

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



41
42
43
44
# File 'lib/shoes/app.rb', line 41

def flow args={}, &blk
  args[:app] = self
  Flow.new slot_attributes(args), &blk
end

#flushObject



684
685
686
687
688
689
# File 'lib/shoes/app.rb', line 684

def flush
  unless @cs.isDisposed
    Shoes.call_back_procs self
    @cs.redraw
  end
end

#font(name) ⇒ Object



20
21
22
# File 'lib/shoes/text.rb', line 20

def font name
  @font_family = name
end

#get_styles(msg, styles = [], spoint = 0) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
# File 'lib/shoes/helper_methods.rb', line 77

def get_styles msg, styles=[], spoint=0
  msg.each do |e|
    if e.is_a? Text
      epoint = spoint + e.to_s.length - 1
      styles << [e, spoint..epoint]
      get_styles e.str, styles, spoint
    end
    spoint += e.to_s.length
  end
  styles
end

#gradient(*attrs) ⇒ Object



548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
# File 'lib/shoes/app.rb', line 548

def gradient *attrs
  case attrs.length
    when 1, 2
      pat1, pat2 = attrs
      pat2 = pat1 unless pat2
      return tr_color(pat1)..tr_color(pat2)
    when 5, 6
      pat, l, t, w, h, angle = attrs
      angle = 0 unless angle
    else
    return black..black
  end

  pat = tr_color pat
  color = case pat
    when Range; [tr_color(pat.first), tr_color(pat.last)]
    when Array; [pat, pat]
    when String
      return Swt::Pattern.new(Shoes.display, Swt::Image.new(Shoes.display, pat))
    else
      [black, black]
  end
  Swt::Pattern.new Shoes.display, *pattern_pos(l, t, w, h, -angle), Swt::Color.new(Shoes.display, *color[0][0, 3]), Swt::Color.new(Shoes.display, *color[1][0, 3])
end

#gray(*attrs) ⇒ Object



706
707
708
709
# File 'lib/shoes/app.rb', line 706

def gray *attrs
  g, a = attrs
  g ? rgb(g*255, g*255, g*255, a) : rgb(128, 128, 128)[0..2]
end

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



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/shoes/app.rb', line 122

def image name, args={}, &blk
  args = basic_attributes args
  args[:rotate] ||= rotate
  img = Swt::Image.new Shoes.display, name
  args[:full_width], args[:full_height] = img.getImageData.width, img.getImageData.height
  args[:real], args[:app] = img, self
  
  Image.new(args).tap do |s|
    pl = Swt::PaintListener.new
    s.pl = pl
    class << pl; self end.
    instance_eval do
      define_method :paintControl do |e|
        gc = e.gc
        Shoes.dps_reset s.dps, gc
        unless s.hided
          Shoes.set_rotate e.gc, *s.rotate do
            if s.initials[:width].zero? and s.initials[:height].zero?
              gc.drawImage img, s.left, s.top
            else
              s.width = s.full_width if s.width.zero?
              s.height = s.full_height if s.height.zero?
              gc.drawImage img, 0, 0, s.full_width, s.full_height, s.left, s.top, s.width, s.height
            end
          end
        end
      end
    end
    @cs.addPaintListener pl unless @cs.isDisposed
    clickable s, &blk
  end
end

#inscription(*msg) ⇒ Object



120
# File 'lib/shoes/app.rb', line 120

def inscription *msg; textblock Para, 10, *msg; end

#keypress(&blk) ⇒ Object



253
254
255
256
257
258
259
260
261
# File 'lib/shoes/app.rb', line 253

def keypress &blk
  kl = Swt::KeyListener.new
  class << kl; self end.
  instance_eval do
    define_method(:keyPressed){|e| blk[KEY_NAMES[e.keyCode] || e.character.chr]}
    define_method(:keyReleased){|e|}
  end
  @shell.addKeyListener kl
end

#line(*attrs, &blk) ⇒ Object



409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
# File 'lib/shoes/app.rb', line 409

def line *attrs, &blk
  args = attrs.last.class == Hash ? attrs.pop : {}
  case attrs.length
    when 0, 1, 2
    when 3; args[:sx], args[:sy], args[:ex] = attrs; args[:ey] = args[:ex]
    else args[:sx], args[:sy], args[:ex], args[:ey] = attrs
  end
  sx, sy, ex, ey = args[:sx], args[:sy], args[:ex], args[:ey]
  sw = args[:strokewidth] = ( args[:strokewidth] or strokewidth or 1 )
  cw = hsw = sw*0.5
  args[:width], args[:height] = (sx - ex).abs, (sy - ey).abs
  args[:width] += cw
  args[:height] += cw
  args[:nocontrol] = args[:noorder] = true
  args = basic_attributes args
  
  if ((sx - ex) < 0 and (sy - ey) < 0) or ((sx - ex) > 0 and (sy - ey) > 0)
    args[:left] = (sx - ex) < 0 ? sx - hsw : ex - hsw
    args[:top] = (sy - ey) < 0 ? sy - hsw : ey - hsw
  elsif ((sx - ex) < 0 and (sy - ey) > 0) or ((sx - ex) > 0 and (sy - ey) < 0)
    args[:left] = (sx - ex) < 0 ? sx - hsw : ex - hsw
    args[:top] = (sy - ey) < 0 ? sy - hsw : ey - hsw
  elsif !(sx - ex).zero? and (sy - ey).zero?
    args[:left] = (sx - ex) < 0 ? sx : ex
    args[:top] = (sy - ey) < 0 ? sy - hsw : ey - hsw
  elsif (sx - ex).zero? and !(sy - ey).zero?
    args[:left] = (sx - ex) < 0 ? sx - hsw : ex - hsw
    args[:top] = (sy - ey) < 0 ? sy : ey
  else
    args[:left] = sw
    args[:top] = sy
  end

  args[:stroke] ||= stroke
  args[:rotate] ||= rotate
  args[:real], args[:app] = :shape, self
  Line.new(args).tap do |s|
    pl = Swt::PaintListener.new
    s.pl = pl
    class << pl; self end.
    instance_eval do
      define_method :paintControl do |e|
        unless s.hided
          gc = e.gc
          Shoes.dps_reset s.dps, gc
          gc.setAntialias Swt::SWT::ON
          sw, pat = s.strokewidth, s.stroke
          Shoes.set_rotate gc, *s.rotate do
            if pat
              Shoes.set_pattern s, gc, pat, :Foreground
              if sw > 0
                gc.setLineWidth sw
                gc.drawLine s.sx, s.sy, s.ex, s.ey
              end
            end
          end
        end
      end
    end
    @cs.addPaintListener pl unless @cs.isDisposed
    clickable s, &blk
  end
end


16
17
18
# File 'lib/shoes/text.rb', line 16

def link *str, &blk
  Link.new :link, str, &blk
end

#list_box(args = {}) ⇒ Object



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/shoes/app.rb', line 216

def list_box args={}
  args = basic_attributes args
  args[:width] = 200 if args[:width].zero?
  args[:height] = 20 if args[:height].zero?
  args[:items] ||= []
  cb = Swt::Combo.new @cs, Swt::SWT::DROP_DOWN
  cb.setSize args[:width], args[:height]
  cb.setItems args[:items].map(&:to_s)
  cb.setText args[:choose].to_s
  args[:real], args[:app] = cb, self
  ListBox.new(args).tap do |s|
    cb.addSelectionListener do |e|
      yield s
    end if block_given?
  end
end

#motion(&blk) ⇒ Object



249
250
251
# File 'lib/shoes/app.rb', line 249

def motion &blk
  @mmcs << blk
end

#mouseObject



263
264
265
# File 'lib/shoes/app.rb', line 263

def mouse
  [@mouse_button, @mouse_pos[0], @mouse_pos[1]]
end

#nested_styles(styles, st) ⇒ Object



157
158
159
160
161
# File 'lib/shoes/helper_methods.rb', line 157

def nested_styles styles, st
  styles.map do |e|
    (e[1].first <= st[1].first and st[1].last <= e[1].last) ? e : nil
  end - [nil]
end

#nofillObject



544
545
546
# File 'lib/shoes/app.rb', line 544

def nofill
  @fill = false
end

#nostrokeObject



540
541
542
# File 'lib/shoes/app.rb', line 540

def nostroke
  strokewidth 0
end

#oval(*attrs, &blk) ⇒ Object



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
354
355
356
357
# File 'lib/shoes/app.rb', line 309

def oval *attrs, &blk
  args = attrs.last.class == Hash ? attrs.pop : {}
  case attrs.length
    when 0, 1
    when 2; args[:left], args[:top] = attrs
    when 3; args[:left], args[:top], args[:radius] = attrs
    else args[:left], args[:top], args[:width], args[:height] = attrs
  end
  args = basic_attributes args
  args[:width].zero? ? (args[:width] = args[:radius] * 2) : (args[:radius] = args[:width]/2.0)
  args[:height] = args[:width] if args[:height].zero?
  args[:strokewidth] = ( args[:strokewidth] or strokewidth or 1 )
  args[:nocontrol] = args[:noorder] = true

  args[:stroke] ||= stroke
  args[:fill] ||= fill
  args[:rotate] ||= rotate
  args[:real], args[:app] = :shape, self
  Oval.new(args).tap do |s|
    pl = Swt::PaintListener.new
    s.pl = pl
    class << pl; self end.
    instance_eval do
      define_method :paintControl do |e|
        unless s.hided
          gc = e.gc
          Shoes.dps_reset s.dps, gc
          gc.setAntialias Swt::SWT::ON
          sw, pat1, pat2 = s.strokewidth, s.stroke, s.fill
          Shoes.set_rotate gc, *s.rotate do
            if pat2
              Shoes.set_pattern s, gc, pat2
              gc.fillOval s.left+sw, s.top+sw, s.width-sw*2, s.height-sw*2
            end
            if pat1
              Shoes.set_pattern s, gc, pat1, :Foreground
              if sw > 0
                gc.setLineWidth sw
                gc.drawOval s.left+sw/2, s.top+sw/2, s.width-sw, s.height-sw
              end
            end
          end
        end
      end
    end
    @cs.addPaintListener pl unless @cs.isDisposed
    clickable s, &blk
  end
end

#para(*msg) ⇒ Object



119
# File 'lib/shoes/app.rb', line 119

def para *msg; textblock Para, 12, *msg; end

#pattern_pos(left, top, w, h, a) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/shoes/helper_methods.rb', line 163

def pattern_pos left, top, w, h, a
  w, h = w*0.5, h*0.5
  a = Math::PI*(a/180.0)
  a = a % (Math::PI*2.0)
  cal = proc do
    l = Math.sqrt(w**2 + h**2)
    b = Math.atan(h/w)
    c = Math::PI*0.5 - a - b
    r = l * Math.cos(c.abs)
    [r * Math.cos(b+c), r * Math.sin(b+c)]
  end
  if 0 <= a and a < Math::PI*0.5
    x, y = cal.call
    [left+w+x, top+h-y, left+w-x, top+h+y]
  elsif Math::PI*0.5 <= a and a < Math::PI
    a -= Math::PI*0.5
    w, h = h, w
    x, y = cal.call
    [left+h+y, top+w+x, left+h-y, top+w-x]
  elsif Math::PI <= a and a < Math::PI*1.5
    a -= Math::PI
    x, y = cal.call
    [left+w-x, top+h+y, left+w+x, top+h-y]
  elsif Math::PI*1.5 <= a and a < Math::PI*2.0
    a -= Math::PI*1.5
    w, h = h, w
    x, y = cal.call
    [left+h-y, top+w-x, left+h+y, top+w+x]
  end
end

#progress(args = {}) ⇒ Object



645
646
647
648
649
650
651
652
653
654
655
656
657
# File 'lib/shoes/app.rb', line 645

def progress args={}
  pb = Swt::ProgressBar.new @cs, Swt::SWT::SMOOTH
  if args[:left] or args[:top]
    args[:noorder] = args[:nocontrol] = true
  end
  args[:width] ||= 150
  args[:height] ||= 16
  args = basic_attributes args
  pb.setSize args[:width], args[:height]
  pb.setLocation args[:left], args[:top]
  args[:real], args[:app] = pb, self
  Progress.new args
end

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



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/shoes/app.rb', line 173

def radio args={}, &blk
  args = basic_attributes args
  args[:block] = blk
  b = Swt::Button.new @cs, Swt::SWT::RADIO
  b.setLocation args[:left], args[:top]
  if args[:width] > 0 and args[:height] > 0
    b.setSize args[:width], args[:height]
  else
    b.pack
  end
  args[:real], args[:app] = b, self
  Radio.new(args).tap do |s|
    b.addSelectionListener do |e|
      blk[s] if b.getSelection
    end if blk
  end
end

#rect(*attrs, &blk) ⇒ Object



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
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
# File 'lib/shoes/app.rb', line 359

def rect *attrs, &blk
  args = attrs.last.class == Hash ? attrs.pop : {}
  case attrs.length
    when 0, 1
    when 2; args[:left], args[:top] = attrs
    when 3; args[:left], args[:top], args[:width] = attrs
    else args[:left], args[:top], args[:width], args[:height] = attrs
  end
  args[:height] = args[:width] unless args[:height]
  args[:strokewidth] = ( args[:strokewidth] or strokewidth or 1 )
  args[:curve] ||= 0
  args[:nocontrol] = args[:noorder] = true
  args = basic_attributes args

  args[:stroke] ||= stroke
  args[:fill] ||= fill
  args[:rotate] ||= rotate
  args[:real], args[:app] = :shape, self
  Rect.new(args).tap do |s|
    pl = Swt::PaintListener.new
    s.pl = pl
    class << pl; self end.
    instance_eval do
      define_method :paintControl do |e|
        unless s.hided
          gc = e.gc
          Shoes.dps_reset s.dps, gc
          gc.setAntialias Swt::SWT::ON
          sw, pat1, pat2 = s.strokewidth, s.stroke, s.fill
          Shoes.set_rotate gc, *s.rotate do
            if pat2
              Shoes.set_pattern s, gc, pat2
              gc.fillRoundRectangle s.left+sw/2, s.top+sw/2, s.width-sw, s.height-sw, s.curve*2, s.curve*2
            end
            if pat1
              Shoes.set_pattern s, gc, pat1, :Foreground
              if sw > 0
                gc.setLineWidth sw
                gc.drawRoundRectangle s.left+sw/2, s.top+sw/2, s.width-sw, s.height-sw, s.curve*2, s.curve*2
              end
            end
          end
        end
      end
    end
    @cs.addPaintListener pl unless @cs.isDisposed
    clickable s, &blk
  end
end

#replace_string_to_float(args = {}) ⇒ Object



47
48
49
50
51
52
53
# File 'lib/shoes/helper_methods.rb', line 47

def replace_string_to_float args={}
  [:width, :height, :left, :top].each do |k|
    if args[k].is_a? String
      args[k] = args[k].include?('%') ? args[k].to_f / 100 : args[k].to_i
    end
  end
end

#rgb(r, g, b, l = 1.0) ⇒ Object



528
529
530
# File 'lib/shoes/app.rb', line 528

def rgb r, g, b, l=1.0
  (r <= 1 and g <= 1 and b <= 1) ? [r*255, g*255, b*255, l] : [r, g, b, l]
end

#rotate(angle = nil, left = 0, top = 0) ⇒ Object



536
537
538
# File 'lib/shoes/app.rb', line 536

def rotate angle=nil, left=0, top=0
  angle ? @rotate = [angle, left, top] : @rotate ||= [0, 0, 0]
end

#scroll_heightObject



672
673
674
# File 'lib/shoes/app.rb', line 672

def scroll_height
  scroll_max + height
end

#scroll_maxObject



676
677
678
# File 'lib/shoes/app.rb', line 676

def scroll_max
  shell.getVerticalBar.getMaximum - 10
end

#scroll_topObject



663
664
665
# File 'lib/shoes/app.rb', line 663

def scroll_top
  cs.getLocation.y
end

#scroll_top=(n) ⇒ Object



667
668
669
670
# File 'lib/shoes/app.rb', line 667

def scroll_top=(n)
  cs.setLocation 0, -n
  shell.getVerticalBar.setSelection n
end

#set_styles(s, args) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/shoes/helper_methods.rb', line 89

def set_styles s, args
  tl = s.real
  tl.setJustify args[:justify]
  tl.setSpacing(args[:leading] || 4)
  tl.setAlignment case args[:align]
    when 'center'; Swt::SWT::CENTER
    when 'right'; Swt::SWT::RIGHT
    else Swt::SWT::LEFT
    end
  font = Swt::Font.new Shoes.display, args[:font], args[:size], Swt::SWT::NORMAL
  fgc = Swt::Color.new Shoes.display, *args[:stroke]
  bgc = args[:fill] ? Swt::Color.new(Shoes.display, *args[:fill]) : nil
  style = Swt::TextStyle.new font, fgc, bgc
  tl.setStyle style, 0, args[:markup].length - 1
  s.dps << font << fgc << bgc
  
  args[:styles].each do |st|
    font, ft, fg, bg, cmds, small = args[:font], Swt::SWT::NORMAL, fgc, bgc, [], 1
    nested_styles(args[:styles], st).each do |e|
      case e[0].style
      when :strong
        ft = ft | Swt::SWT::BOLD
      when :em
        ft = ft | Swt::SWT::ITALIC 
      when :fg
        fg = Swt::Color.new Shoes.display, *e[0].color[0,3]
      when :bg
        bg = Swt::Color.new Shoes.display, *e[0].color[0,3]
      when :ins
        cmds << "underline = true"
      when :del
        cmds << "strikeout = true"
      when :sub
        small *= 0.8
        cmds << "rise = -5"
      when :sup
        small *= 0.8
        cmds << "rise = 5"
      when :code
        font = "Lucida Console"
      when :link
        cmds << "underline = true"
        fg = Swt::Color.new Shoes.display, *blue
        spos = tl.getLocation e[1].first, false
        epos = tl.getLocation e[1].last, true
        e[0].lh = tl.getLineBounds(0).height
        e[0].sx, e[0].sy = s.left + spos.x, s.top + spos.y
        e[0].ex, e[0].ey = s.left + epos.x, s.top + epos.y + e[0].lh
        e[0].pl, e[0].pt, e[0].pw, e[0].ph = s.left, s.top, s.width, s.height
        s.links << e[0]
        unless e[0].clickabled
          e[0].parent = s
          clickable e[0], &e[0].blk
          e[0].clickabled = true
        end
      else
      end
    end
    ft = Swt::Font.new Shoes.display, font, args[:size]*small, ft
    style = Swt::TextStyle.new ft, fg, bg
    cmds.each do |cmd|
      eval "style.#{cmd}"
    end
    tl.setStyle style, st[1].first, st[1].last
    s.dps << ft
  end if args[:styles]
end

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



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'lib/shoes/app.rb', line 267

def shape args={}, &blk
  args = basic_attributes args
  args[:strokewidth] = ( args[:strokewidth] or strokewidth or 1 )
  args[:nocontrol] = args[:noorder] = true
  args[:stroke] ||= stroke
  args[:fill] ||= fill
  args[:rotate] ||= rotate
  args[:real], args[:app], args[:block] = :shape, self, blk
  Shape.new(args).tap do |s|
    pl = Swt::PaintListener.new
    s.pl = pl
    s.real = Swt::Path.new Shoes.display
    class << pl; self end.
    instance_eval do
      define_method :paintControl do |e|
        unless s.hided
          gc = e.gc
          Shoes.dps_reset s.dps, gc
          gc.setAntialias Swt::SWT::ON
          sw, pat1, pat2 = s.strokewidth, s.stroke, s.fill
          Shoes.set_rotate gc, *s.rotate do
            if pat2
              Shoes.set_pattern s, gc, pat2
              s.instance_eval &s.block
              gc.fillPath s.real
            end
            if pat1
              Shoes.set_pattern s, gc, pat1, :Foreground
              if sw > 0
                gc.setLineWidth sw
                s.instance_eval &s.block
                gc.drawPath s.real
              end
            end
          end
        end
      end
    end
    @cs.addPaintListener pl unless @cs.isDisposed
  end
end

#slot_attributes(args = {}) ⇒ Object



41
42
43
44
45
# File 'lib/shoes/helper_methods.rb', line 41

def slot_attributes args={}
  default = SLOT_ATTRIBUTES_DEFAULT
  replace_string_to_float args
  default.merge args
end

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



36
37
38
39
# File 'lib/shoes/app.rb', line 36

def stack args={}, &blk
  args[:app] = self
  Stack.new slot_attributes(args), &blk
end

#star(*attrs, &blk) ⇒ Object



473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
# File 'lib/shoes/app.rb', line 473

def star *attrs, &blk
  args = attrs.last.class == Hash ? attrs.pop : {}
  case attrs.length
    when 2; args[:left], args[:top] = attrs
    when 5; args[:left], args[:top], args[:points], args[:outer], args[:inner] = attrs
    else
  end
  args[:points] ||= 10; args[:outer] ||= 100.0; args[:inner] ||= 50.0
  args[:width] = args[:height] = args[:outer]*2.0
  args[:strokewidth] = ( args[:strokewidth] or strokewidth or 1 )
  args[:nocontrol] = args[:noorder] = true
  args[:stroke] ||= stroke
  args[:fill] ||= fill
  args[:rotate] ||= rotate
  args[:real], args[:app] = :shape, self
  Star.new(args).tap do |s|
    pl = Swt::PaintListener.new
    s.pl = pl
    class << pl; self end.
    instance_eval do
      define_method :paintControl do |e|
        unless s.hided
          gc = e.gc
          Shoes.dps_reset s.dps, gc
          gc.setAntialias Swt::SWT::ON
          sw, pat1, pat2 = s.strokewidth, s.stroke, s.fill
          outer, inner, points, left, top = s.outer, s.inner, s.points, s.left, s.top
          polygon = []
          polygon << left << (top + outer)
          (1..points*2).each do |i|
            angle =  i * Math::PI / points
            r = (i % 2 == 0) ? outer : inner
            polygon << (left + r * Math.sin(angle)) << (top + r * Math.cos(angle))
          end
          Shoes.set_rotate gc, *s.rotate do
            if pat2
              Shoes.set_pattern s, gc, pat2
              gc.fillPolygon polygon
            end
            if pat1
              Shoes.set_pattern s, gc, pat1, :Foreground
              if sw > 0
                gc.setLineWidth sw
                gc.drawPolygon polygon
              end
            end
          end
        end
      end
    end
    @cs.addPaintListener pl unless @cs.isDisposed
    clickable s, &blk
  end
end

#subtitle(*msg) ⇒ Object



116
# File 'lib/shoes/app.rb', line 116

def subtitle *msg; textblock Subtitle, 26, *msg; end

#tagline(*msg) ⇒ Object



117
# File 'lib/shoes/app.rb', line 117

def tagline *msg; textblock Tagline, 18, *msg; end

#textblock(klass, font_size, *msg) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/shoes/app.rb', line 65

def textblock klass, font_size, *msg
  args = msg.last.class == Hash ? msg.pop : {}
  args = basic_attributes args
  args[:markup] = msg.map(&:to_s).join

  styles = get_styles msg
  args[:styles] = styles unless styles.empty?

  args[:size] ||= font_size
  args[:font] ||= (@font_family or 'sans')
  args[:stroke] ||= black
  args[:rotate] ||= rotate
  
  unless args[:left].zero? and args[:top].zero?
    args[:nocontrol], args[:width] = true, width
    layout_control = false
  else
    layout_control = true
  end

  args[:real] = (args[:create_real] or !layout_control) ? :textblock : false
  args[:app] = self
  
  klass.new(args).tap do |s|
    unless s.real and layout_control
      tl = Swt::TextLayout.new Shoes.display
      s.real = tl
      pl = Swt::PaintListener.new
      s.pl = pl
      class << pl; self end.
      instance_eval do
        define_method :paintControl do |e|
          gc = e.gc
          Shoes.dps_reset s.dps, gc
          tl.setText s.markup
          s.app.set_styles s, args
          tl.setWidth s.width if s.width > 0
          unless s.hided
            Shoes.set_rotate gc, *s.rotate do
              tl.draw gc, s.left, s.top
            end
          end
        end
      end
      @cs.addPaintListener pl unless @cs.isDisposed
    end
  end
end

#timer(n = 1, &blk) ⇒ Object



244
245
246
247
# File 'lib/shoes/app.rb', line 244

def timer n=1, &blk
  n *= 1000
  Timer.new(self, n, &blk).tap{|t| Shoes.display.timerExec n, t}
end

#title(*msg) ⇒ Object



115
# File 'lib/shoes/app.rb', line 115

def title *msg; textblock Title, 34, *msg; end

#tr_color(pat) ⇒ Object



573
574
575
576
577
578
579
580
581
# File 'lib/shoes/app.rb', line 573

def tr_color pat
  if pat.is_a?(String) and pat[0] == '#'
    color = pat[1..-1]
    color = color.gsub(/(.)/){$1 + '0'} if color.length == 3
    rgb *color.gsub(/(..)/).map{$1.hex}
  else
    pat
  end
end

#video(file) ⇒ Object



82
83
84
85
86
# File 'lib/plugins/video.rb', line 82

def video file
  args = {}
  args[:real], args[:app], args[:path] = nil, self, file
  Video.new args
end

#visit(url) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/shoes/app.rb', line 20

def visit url
  if url =~ /^(http|https):\/\//
    require 'rbconfig'
    Thread.new do
      case RbConfig::CONFIG['host_os']
      when /mswin/; system "start #{url}"
      when /linux/; system("/etc/alternatives/x-www-browser #{url} &")
      else
        puts "Sorry, your platform [#{RUBY_PLATFORM}] is not supported..."
      end
    end
  else
    $urls.each{|k, v| clear{init_app_vars; @location = url; v.call self, $1} if k =~ url}
  end
end