fzeet 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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