fzeet 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
data/examples/Command.rbw CHANGED
@@ -3,20 +3,18 @@ require 'fzeet'
3
3
  include Fzeet
4
4
 
5
5
  Application.run { |window|
6
- window.
7
- on(:create) {
8
- window.menu = Menu.new.
9
- append(:popup, 'Menu&1', PopupMenu.new.
10
- append(:string, "Item&1\tAlt+I", :item1)
11
- )
6
+ window.menu = Menu.new.
7
+ append(:popup, 'Menu&1', PopupMenu.new.
8
+ append(:string, "Item&1\tAlt+I", :item1)
9
+ )
12
10
 
13
- Application.accelerators << AcceleratorTable.new(
14
- [:alt, :I, :item1]
15
- )
11
+ Application.accelerators << AcceleratorTable.new(
12
+ [:alt, :I, :item1]
13
+ )
16
14
 
17
- Button.new(window, :button1, x: 10, y: 10, width: 76, height: 24)
18
- }.
15
+ Button.new(window, :button1, x: 10, y: 10, width: 76, height: 24)
19
16
 
17
+ window.
20
18
  on(:command, :item1) {
21
19
  message 'on(:command, :item1)'
22
20
 
@@ -0,0 +1,19 @@
1
+ require 'fzeet'
2
+
3
+ include Fzeet
4
+
5
+ Application.run { |window|
6
+ Button.new(window, :button1, x: 10, y: 10, width: 76, height: 24) {
7
+ message 'on(:command, :button1)'
8
+ }
9
+
10
+ Button.new(window, :button2, x: 10, y: 40, width: 76, height: 24, style: :notify,
11
+ doubleclicked: -> { message 'on(:command, :button2, :doubleclicked)' }
12
+ )
13
+
14
+ Button.new(window, :button3, x: 10, y: 70, width: 76, height: 24, style: :splitbutton)
15
+
16
+ window[:button3].on(:dropdown) {
17
+ message 'on(:notify, :button3, :dropdown)'
18
+ }
19
+ }
@@ -0,0 +1,43 @@
1
+ require 'fzeet'
2
+
3
+ include Fzeet
4
+
5
+ Application.run { |window|
6
+ Button.new(window, :modeless, x: 10, y: 10, width: 76, height: 24) {
7
+ Dialog.new(window, caption: 'Modeless', x: 100, y: 100) { |args|
8
+ dialog = args[:window]
9
+
10
+ Button.new(dialog, :ok, x: 228, y: 242, width: 76, height: 24) {
11
+ dialog.dispose; window[:modeless].toggle(:enabled)
12
+ }
13
+
14
+ Button.new(dialog, :cancel, x: 308, y: 242, width: 76, height: 24) {
15
+ dialog.dispose; window[:modeless].toggle(:enabled)
16
+ }
17
+
18
+ Button.new(dialog, :button1, x: 10, y: 10, width: 76, height: 24) {
19
+ dialog.message 'clicked'
20
+ }
21
+ }
22
+
23
+ window[:modeless].toggle(:enabled)
24
+ }
25
+
26
+ Button.new(window, :modal, x: 90, y: 10, width: 76, height: 24) {
27
+ message(Dialog.new(window, modal: true, caption: 'Modal', x: 150, y: 150) { |args|
28
+ dialog = args[:window]
29
+
30
+ Button.new(dialog, :ok, x: 228, y: 242, width: 76, height: 24) {
31
+ dialog.end(:ok)
32
+ }
33
+
34
+ Button.new(dialog, :cancel, x: 308, y: 242, width: 76, height: 24) {
35
+ dialog.end(:cancel)
36
+ }
37
+
38
+ Button.new(dialog, :button1, x: 10, y: 10, width: 76, height: 24) {
39
+ dialog.message 'clicked'
40
+ }
41
+ }.result.ok?)
42
+ }
43
+ }
@@ -0,0 +1,22 @@
1
+ require 'fzeet'
2
+
3
+ include Fzeet
4
+
5
+ Dialog.new(nil, modal: true, style: [:overlappedwindow, :center]) { |args|
6
+ dialog = Application.window = args[:window]
7
+
8
+ dialog.menu = Menu.new.
9
+ append(:popup, 'Menu&1', PopupMenu.new.
10
+ append(:string, 'Item&1', :item1).
11
+ append(:separator).
12
+ append(:string, 'E&xit', :exit)
13
+ )
14
+
15
+ Button.new(dialog, :button1, caption: '&Button1', x: 10, y: 10, width: 76, height: 24)
16
+
17
+ dialog.
18
+ on(:command, :exit) { dialog.end(:ok) }.
19
+ on(:command, :cancel) { dialog.end(:cancel) if question('Close?').yes? }.
20
+ on(:command, :item1) { message 'on(:command, :item1)' }.
21
+ on(:command, :button1) { message 'on(:command, :button1)' }
22
+ }
@@ -0,0 +1,44 @@
1
+ require 'fzeet'
2
+
3
+ include Fzeet
4
+
5
+ class Window1 < Window
6
+ message <<-MSG
7
+ class: #{self}
8
+ superclass: #{self.superclass}
9
+ WindowClass: #{self::WindowClass.name}
10
+ WindowClass.prototype: #{self::WindowClass.prototype.name}
11
+ MSG
12
+
13
+ def initialize
14
+ super
15
+
16
+ self.menu = Menu.new.
17
+ append(:popup, 'Menu&1', PopupMenu.new.
18
+ append(:string, 'Item&1', :item1)
19
+ )
20
+
21
+ on(:command, :item1, &method(:onItem1))
22
+ end
23
+
24
+ def onItem1(args)
25
+ message "Window1##{__method__}"
26
+ end
27
+ end
28
+
29
+ class Window2 < Window1
30
+ message <<-MSG
31
+ class: #{self}
32
+ superclass: #{self.superclass}
33
+ WindowClass: #{self::WindowClass.name}
34
+ WindowClass.prototype: #{self::WindowClass.prototype.name}
35
+ MSG
36
+
37
+ def onItem1(args)
38
+ message "Window2##{__method__}"
39
+
40
+ super
41
+ end
42
+ end
43
+
44
+ Application.run(Window2.new)
@@ -0,0 +1,43 @@
1
+ require 'fzeet'
2
+
3
+ include Fzeet
4
+
5
+ Window1 = Window['X.Window1',
6
+ background: SystemBrush.new(:appworkspace)
7
+ ]
8
+
9
+ class Window1
10
+ message <<-MSG
11
+ class: #{self}
12
+ superclass: #{self.superclass}
13
+ WindowClass: #{self::WindowClass.name}
14
+ WindowClass.prototype: #{self::WindowClass.prototype.name}
15
+ MSG
16
+
17
+ def initialize(opts = {})
18
+ (opts[:style] ||= []) << :hscroll
19
+
20
+ super
21
+ end
22
+ end
23
+
24
+ Window2 = Window1['X.Window2',
25
+ cursor: SystemCursor.new(:hand)
26
+ ]
27
+
28
+ class Window2
29
+ message <<-MSG
30
+ class: #{self}
31
+ superclass: #{self.superclass}
32
+ WindowClass: #{self::WindowClass.name}
33
+ WindowClass.prototype: #{self::WindowClass.prototype.name}
34
+ MSG
35
+
36
+ def initialize(opts = {})
37
+ (opts[:style] ||= []) << :vscroll
38
+
39
+ super
40
+ end
41
+ end
42
+
43
+ Application.run(Window2.new)
@@ -2,7 +2,7 @@ require 'fzeet'
2
2
 
3
3
  include Fzeet
4
4
 
5
- Application.run { |window|
5
+ Application.run(deferCreateWindow: true) { |window|
6
6
  window.
7
7
  on(:create) { |args|
8
8
  args[:result] = -1 if question('Create?').no?
@@ -1,6 +1,6 @@
1
1
  require 'fzeet'
2
2
 
3
- Fzeet::Application.run do |window|
3
+ Fzeet::Application.run(deferCreateWindow: true) do |window|
4
4
  window.on :create do |args|
5
5
  args[:result] = -1 if Fzeet.question('Create?').no?
6
6
  end
@@ -4,7 +4,7 @@ include Fzeet
4
4
 
5
5
  Application.quitWhenMainWindowCloses = false
6
6
 
7
- Application.run { |window|
7
+ Application.run(deferCreateWindow: true) { |window|
8
8
  window.
9
9
  on(:nccreate) { |args|
10
10
  args[:result] = 0 if question('NCCreate?').no?
@@ -0,0 +1,15 @@
1
+ require 'fzeet'
2
+
3
+ include Fzeet
4
+
5
+ Application.run { |window|
6
+ window.
7
+ on(:contextmenu) { |args| using(
8
+ PopupMenu.new.
9
+ append(:string, 'Item&1', :item1)
10
+ ) { |popup|
11
+ popup.track(window, args[:x], args[:y])
12
+ }}.
13
+
14
+ on(:command, :item1) { message 'on(:command, :item1)' }
15
+ }
@@ -3,33 +3,30 @@ require 'fzeet'
3
3
  include Fzeet
4
4
 
5
5
  Application.run { |window|
6
- window.
7
- on(:create) {
8
- window.menu = Menu.new.
9
- append(:popup, 'Menu&1', PopupMenu.new.
10
- append(:string, 'Item&1', :item1).
11
- append([:string, :grayed], 'Item&2', :item2).
12
- append([:string, :checked], 'Item&3', :item3).
6
+ window.menu = Menu.new.
7
+ append(:popup, 'Menu&1', PopupMenu.new.
8
+ append(:string, 'Item&1', :item1).
9
+ append([:string, :grayed], 'Item&2', :item2).
10
+ append([:string, :checked], 'Item&3', :item3).
13
11
 
14
- append(:separator).
12
+ append(:separator).
15
13
 
16
- append([:string, :usecheckbitmaps, :checked], 'Item&4', :item4).
17
- append([:string, :usecheckbitmaps], 'Item&5', :item5).
14
+ append([:string, :radiocheck, :checked], 'Item&4', :item4).
15
+ append([:string, :radiocheck], 'Item&5', :item5).
18
16
 
19
- append(:separator).
17
+ append(:separator).
20
18
 
21
- append(:popup, 'Menu&2', PopupMenu.new.
22
- append([:string, :usecheckbitmaps, :checked], 'Item&6', :item6).
23
- append([:string, :usecheckbitmaps], 'Item&7', :item7)
24
- )
25
- ).
19
+ append(:popup, 'Menu&2', PopupMenu.new.
20
+ append([:string, :radiocheck, :checked], 'Item&6', :item6).
21
+ append([:string, :radiocheck], 'Item&7', :item7)
22
+ )
23
+ ).
26
24
 
27
- append(:string, 'Item&8', :item8).
25
+ append(:string, 'Item&8', :item8).
28
26
 
29
- append([:popup, :rightjustify], 'Menu&3', PopupMenu.new.
30
- append(:string, 'Item&9', :item9)
31
- )
32
- }
27
+ append([:popup, :rightjustify], 'Menu&3', PopupMenu.new.
28
+ append(:string, 'Item&9', :item9)
29
+ )
33
30
 
34
31
  window.
35
32
  on(:command, :item1) { window.menu[:item2].toggle(:enabled) }.
@@ -44,5 +41,17 @@ Application.run { |window|
44
41
  window.on(:command, id) { window.menu[id].select(:item6, :item7) }
45
42
  }
46
43
 
47
- window.on(:command, :item8) { message 'on(:command, :item8)' }
44
+ window.
45
+ on(:command, :item8) { message 'on(:command, :item8)' }.
46
+
47
+ on(:command, :item9) {
48
+ message <<-MSG
49
+ window.menu[:item2].enabled? - #{window.menu[:item2].enabled?}
50
+ window.menu[:item3].checked? - #{window.menu[:item3].checked?}
51
+ window.menu[:item4].checked? - #{window.menu[:item4].checked?}
52
+ window.menu[:item5].checked? - #{window.menu[:item5].checked?}
53
+ window.menu[:item6].checked? - #{window.menu[:item6].checked?}
54
+ window.menu[:item7].checked? - #{window.menu[:item7].checked?}
55
+ MSG
56
+ }
48
57
  }
@@ -0,0 +1,22 @@
1
+ require 'fzeet'
2
+
3
+ include Fzeet
4
+
5
+ Application.run { |window|
6
+ images = {
7
+ cut: PARGB32.new('../res/edit-cut.bmp'),
8
+ copy: PARGB32.new('../res/edit-copy.bmp'),
9
+ paste: PARGB32.new('../res/edit-paste.bmp')
10
+ }
11
+
12
+ window.menu = Menu.new.
13
+ append(:popup, '&Edit', PopupMenu.new.
14
+ append(:string, 'Cu&t', :cut).
15
+ append(:string, '&Copy', :copy).
16
+ append(:string, '&Paste', :paste)
17
+ )
18
+
19
+ window.menu.images = images
20
+
21
+ window.on(:destroy) { images.values.each(&:dispose) }
22
+ }
@@ -0,0 +1,7 @@
1
+ require 'fzeet'
2
+
3
+ include Fzeet
4
+
5
+ Application.run(width: 400, height: 300) { |window|
6
+
7
+ }
@@ -0,0 +1,26 @@
1
+ require 'fzeet'
2
+
3
+ include Fzeet
4
+
5
+ Application.run { |window|
6
+ dc = nil
7
+
8
+ window.
9
+ on(:lbuttondown) { |args|
10
+ window.capture = true
11
+ dc = ClientDC.new(window)
12
+
13
+ dc.move(args[:x], args[:y])
14
+ }.
15
+
16
+ on(:lbuttonup) {
17
+ dc.dispose; dc = nil
18
+ window.capture = false
19
+ }.
20
+
21
+ on(:mousemove) { |args|
22
+ next unless window.capture?
23
+
24
+ dc.line(args[:x], args[:y])
25
+ }
26
+ }
Binary file
Binary file
Binary file
@@ -13,7 +13,7 @@ module Fzeet
13
13
  args.each_with_index { |data, i|
14
14
  accel = Windows::ACCEL.new(paccels + i * Windows::ACCEL.size)
15
15
 
16
- accel[:fVirt] = [*data[0]].inject(0) { |flags, flag| flags |= Windows.const_get("F#{flag.upcase}") }
16
+ accel[:fVirt] = Fzeet.flags(data[0], :f)
17
17
  accel[:fVirt] |= Windows::FVIRTKEY if data[1].kind_of?(Symbol)
18
18
  accel[:key] = data[1].to_s.ord
19
19
  accel[:cmd] = Command[data[2]]
@@ -2,7 +2,7 @@ require_relative 'common'
2
2
 
3
3
  module Fzeet
4
4
  class Application
5
- @name = File.basename($0, '*.rbw')
5
+ @name = File.basename($0, '.rbw')
6
6
  @version = '0.1.0'
7
7
  @authors = []
8
8
 
@@ -10,14 +10,32 @@ module Fzeet
10
10
 
11
11
  @window = nil
12
12
  @accelerators = []
13
+ @dialogs = []
13
14
 
14
15
  class << self
15
16
  attr_accessor :name, :version, :authors, :quitWhenMainWindowCloses
16
- attr_reader :window, :accelerators
17
+ attr_reader :window, :accelerators, :dialogs
17
18
  end
18
19
 
19
- def self.run(window = nil, &block)
20
- return 0 if (@window = window || Window.new(&block)).handle.null?
20
+ def self.window=(window)
21
+ raise 'Application.window already set.' if @window
22
+
23
+ @window = window
24
+ end
25
+
26
+ def self.run(windowOrOpts = {}, &block)
27
+ @window = case windowOrOpts
28
+ when Window; windowOrOpts.tap { |window| block.call(window) if block }
29
+ when Hash
30
+ if windowOrOpts[:deferCreateWindow].tap { windowOrOpts.delete_if { |k, v| k == :deferCreateWindow } }
31
+ Window.new(windowOrOpts, &block)
32
+ else
33
+ Window.new(windowOrOpts).tap { |window| block.call(window) if block }
34
+ end
35
+ else raise ArgumentError
36
+ end
37
+
38
+ return 0 if window.handle.null?
21
39
 
22
40
  @window.on(:destroy) { quit } if @quitWhenMainWindowCloses
23
41
 
@@ -27,7 +45,8 @@ module Fzeet
27
45
 
28
46
  while msg.get!
29
47
  msg.translate.dispatch unless
30
- accelerators.any? { |table| table.translate?(msg, @window) }
48
+ accelerators.any? { |table| table.translate?(msg, @window) } ||
49
+ dialogs.any? { |dialog| dialog.dlgmsg?(msg) }
31
50
  end
32
51
 
33
52
  msg[:wParam]
data/lib/fzeet/Control.rb CHANGED
@@ -14,14 +14,24 @@ module Fzeet
14
14
  at_exit { Font.dispose }
15
15
  }
16
16
 
17
+ def self.crackNotification(args) end
18
+
17
19
  def initialize(className, parent, id, opts = {})
18
20
  @parent = parent
19
21
  @id = Command[id]
20
22
 
23
+ handlers = {}
24
+
25
+ opts.delete_if { |k, v|
26
+ next false unless v.kind_of?(Proc)
27
+
28
+ handlers[k] = v; true
29
+ }
30
+
21
31
  _opts = {
22
32
  xstyle: [],
23
33
  caption: id.capitalize,
24
- style: [:child, :visible],
34
+ style: [],
25
35
  x: Windows::CW_USEDEFAULT,
26
36
  y: Windows::CW_USEDEFAULT,
27
37
  width: Windows::CW_USEDEFAULT,
@@ -30,9 +40,9 @@ module Fzeet
30
40
  badopts = opts.keys - _opts.keys; raise "Bad option(s): #{badopts.join(', ')}." unless badopts.empty?
31
41
  _opts.merge!(opts)
32
42
 
33
- _opts[:xstyle] = _opts[:xstyle].inject(0) { |flags, xstyle| flags |= Windows.const_get("WS_EX_#{xstyle.upcase}") }
43
+ _opts[:xstyle] = Fzeet.flags(_opts[:xstyle], *self.class::Prefix[:xstyle])
34
44
  _opts[:caption] = _opts[:caption].to_s
35
- _opts[:style] = _opts[:style].inject(0) { |flags, style| flags |= Windows.const_get("WS_#{style.upcase}") }
45
+ _opts[:style] = Fzeet.flags([:child, :visible, :tabstop], :ws_) | Fzeet.flags(_opts[:style], *self.class::Prefix[:style])
36
46
 
37
47
  @handle = Windows.DetonateLastError(FFI::Pointer::NULL, :CreateWindowEx,
38
48
  _opts[:xstyle], className, _opts[:caption], _opts[:style],
@@ -43,6 +53,8 @@ module Fzeet
43
53
  attach
44
54
 
45
55
  sendmsg(:setfont, Font.handle, 1)
56
+
57
+ handlers.each { |k, v| on(k, &v) }
46
58
  end
47
59
 
48
60
  attr_reader :parent, :id
@@ -51,10 +63,27 @@ module Fzeet
51
63
  end
52
64
 
53
65
  class Button < Control
66
+ Prefix = {
67
+ xstyle: [:ws_ex_],
68
+ style: [:bs_, :ws_],
69
+ message: [:bm_, :bcm_, :ccm_, :wm_],
70
+ notification: [:bn_, :bcn_, :nm_]
71
+ }
72
+
54
73
  def initialize(parent, id, opts = {}, &block)
55
74
  super('Button', parent, id, opts)
56
75
 
57
76
  @parent.on(:command, @id, &block) if block
58
77
  end
78
+
79
+ def on(notification, &block)
80
+ if (notification = Fzeet.constant(notification, *self.class::Prefix[:notification])) < Windows::BCN_LAST
81
+ @parent.on(:command, @id, notification, &block)
82
+ else
83
+ @parent.on(:notify, @id, notification, &block)
84
+ end
85
+
86
+ self
87
+ end
59
88
  end
60
89
  end
data/lib/fzeet/Menu.rb CHANGED
@@ -43,6 +43,38 @@ module Fzeet
43
43
 
44
44
  self
45
45
  end
46
+
47
+ def info(mask)
48
+ Windows.DetonateLastError(0, :GetMenuItemInfo,
49
+ @menu.handle,
50
+ @id,
51
+ 0,
52
+ info = Windows::MENUITEMINFO.new.tap { |mii|
53
+ mii[:cbSize] = mii.size
54
+ mii[:fMask] = Fzeet.constant(mask, :miim_)
55
+ }
56
+ )
57
+
58
+ info
59
+ end
60
+
61
+ def info=(mii)
62
+ Windows.DetonateLastError(0, :SetMenuItemInfo,
63
+ @menu.handle,
64
+ @id,
65
+ 0,
66
+ mii.tap { mii[:cbSize] = mii.size }
67
+ )
68
+ end
69
+
70
+ def image; (Handle.instance?(handle = info(:bitmap)[:hbmpItem])) ? Handle.instance(handle) : nil end
71
+
72
+ def image=(image)
73
+ self.info = Windows::MENUITEMINFO.new.tap { |mii|
74
+ mii[:fMask] = Windows::MIIM_BITMAP
75
+ mii[:hbmpItem] = image.handle
76
+ }
77
+ end
46
78
  end
47
79
 
48
80
  module MenuMethods
@@ -53,7 +85,7 @@ module Fzeet
53
85
  def append(flags, item = nil, id = 0)
54
86
  Windows.DetonateLastError(0, :AppendMenu,
55
87
  @handle,
56
- [*flags].inject(0) { |flags, flag| flags |= Windows.const_get("MF_#{flag.upcase}") },
88
+ Fzeet.flags(flags, :mf_, :mft_, :mfs_),
57
89
  case id
58
90
  when Integer; id
59
91
  when Symbol; Command[id]
@@ -65,6 +97,8 @@ module Fzeet
65
97
 
66
98
  self
67
99
  end
100
+
101
+ def images=(images) images.each { |id, image| self[id].image = image } end
68
102
  end
69
103
 
70
104
  class Menu < Handle
@@ -93,5 +127,7 @@ module Fzeet
93
127
  attr_reader :submenus
94
128
 
95
129
  def dispose; Windows.DestroyMenu(@handle); rdetach end
130
+
131
+ def track(window, x, y, flags = 0) Windows.TrackPopupMenu(@handle, Fzeet.flags(flags, :tpm_), x, y, 0, window.handle, nil); self end
96
132
  end
97
133
  end