tkwrapper 1.1.2 → 1.5.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 42d786c8eda480c18150ef9b6c3e67fc04c14d2c9ec70a037907dee5a9273264
4
- data.tar.gz: b669a2881c794270a80da8332a55393c90a7bb3115273b5c28fc5681fb43faf5
3
+ metadata.gz: abffb1cc7ae4efaf8b26ebdd49acca56837989829713473f21971f8a5f5a9063
4
+ data.tar.gz: 1e659e3049a41d4aff307f700ac27cc86d014ec844134aa65bc7bd20c2f692db
5
5
  SHA512:
6
- metadata.gz: 1c583155569bc2adf08a5177c35e123e45a69c997ecb3aa70d78841ab4418406a7daa83277c7efe7654585c77932b58094a4bace040d5c9555de30e4e493c9b0
7
- data.tar.gz: 63cb56447bc90a44a86251cfc5ef4507a5482063abb2f24a906610d6d23c3ba8cb341bf64a34ae027577ffbf6bb47ab4935e88a7ab56198e39b44e7f2d0cb890
6
+ metadata.gz: efbad85fe488198ff115feac31872163da0da8b796ef0a21babf33d21976e14da0f809a93a502cbfc0f9225e4446e30c1b567680af2b3c7e7eae862cf0b5f64b
7
+ data.tar.gz: 7d0addd32901d46c6d0175219ee83dd4478f699bc05ec7804f0a76dac02b1950a11f7a22dafa494996961bc8f25582c1f6be4f36c3cf19c9b3a3e5050cb0df9f
data/lib/tkwrapper.rb CHANGED
@@ -2,10 +2,16 @@
2
2
 
3
3
  LIB_DIR = __dir__
4
4
 
5
- module TkWrapper end
5
+ module TkWrapper
6
+ module Util
7
+ module Tk
8
+ end
9
+ end
10
+ end
6
11
 
7
12
  require_relative 'widgets/widgets'
8
13
 
9
14
  module TkWrapper
15
+ Manager = TkWrapper::Widgets::Base::Manager
10
16
  Widget = TkWrapper::Widgets::Base::Widget
11
17
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'tk'
4
+
5
+ class TkWrapper::Util::Tk::Cell
6
+ def initialize(widget)
7
+ @widget = widget
8
+ end
9
+
10
+ # returns the bounding box of the tk_widget
11
+ def bbox
12
+ return unless (container = container_parent)
13
+
14
+ grid_info = TkGrid.info(@widget.tk_widget)
15
+ start_col = grid_info['column']
16
+ end_col = start_col + grid_info['columnspan'] - 1
17
+ start_row = grid_info['row']
18
+ end_row = start_row + grid_info['rowspan'] - 1
19
+
20
+ TkGrid.bbox(container.tk_widget, start_col, start_row, end_col, end_row)
21
+ end
22
+
23
+ private
24
+
25
+ # the first parent, which contains a tk_widget, which is really different
26
+ # from self.tk_widget
27
+ def container_parent
28
+ container = @widget.parent
29
+ while container.tk_widget == @widget.tk_widget
30
+ return unless container.parent # not in a grid?
31
+
32
+ container = container.parent
33
+ end
34
+ container
35
+ end
36
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "#{LIB_DIR}/widgets/base/manager"
4
+ require "#{LIB_DIR}/widgets/base/matcher"
5
+ require "#{LIB_DIR}/widgets/base/matches"
6
+
7
+ class TkWrapper::Util::Tk::Finder
8
+ Match = TkWrapper::Widgets::Base::Match
9
+ Matcher = TkWrapper::Widgets::Base::Matcher
10
+ Matches = TkWrapper::Widgets::Base::Matches
11
+
12
+ def initialize(widgets: nil, lookup: nil)
13
+ @lookup = lookup
14
+ @widgets = widgets
15
+ end
16
+
17
+ def iter(comparators, widgets = @widgets, lookup = @lookup)
18
+ Enumerator.new do |y|
19
+ comparators = each_widget_lookup_match(lookup, comparators) { |m| y << m }
20
+ each_widget_comparator_match(widgets, comparators) { |m| y << m }
21
+ end
22
+ end
23
+
24
+ def find(comparators, widgets = @widgets, lookup = @lookup)
25
+ iter(comparators, widgets, lookup, &:itself).first
26
+ end
27
+
28
+ def find_all(comparators, widgets = @widgets, lookup = @lookup)
29
+ it = iter(comparators, widgets, lookup, &:itself)
30
+ it.each_with_object(Matches.new) { |match, matches| matches.push(match) }
31
+ end
32
+
33
+ private
34
+
35
+ def create_value_matchers(comparators)
36
+ comparators = [comparators] unless comparators.is_a?(Array)
37
+ comparators.map { |comparator| Matcher.new(comparator: comparator) }
38
+ end
39
+
40
+ def each_widget_lookup_match(lookup, comparators, &block)
41
+ return comparators unless lookup
42
+
43
+ comparators.filter do |comparator|
44
+ next true unless [String, Symbol].include?(comparator.class)
45
+
46
+ (lookup[comparator] || []).each do |widget|
47
+ block.call(Match.new(comparator, widget: widget))
48
+ end
49
+
50
+ false
51
+ end
52
+ end
53
+
54
+ def each_widget_comparator_match(widgets, comparators, &block)
55
+ matchers = create_value_matchers(comparators)
56
+
57
+ widgets.each do |widget|
58
+ widget.ids.each do |id|
59
+ matchers.each do |matcher|
60
+ (match = matcher.match(id, widget)) && block.call(match)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tk'
4
+ require 'forwardable'
5
+
6
+ require_relative 'tk'
7
+
8
+ class TkWrapper::Util::Tk::Font
9
+ def initialize(tk_widget)
10
+ @tk_widget = tk_widget
11
+ end
12
+
13
+ %i[family size weight slant underline overstrike].each do |option|
14
+ define_method("#{option}=") do |value, **args|
15
+ load unless @config
16
+ args[:update] ||= false
17
+ @config[option] = value
18
+ update if args[:update]
19
+ end
20
+
21
+ define_method(option) do
22
+ load unless @config
23
+ @config[option]
24
+ end
25
+ end
26
+
27
+ def with_update(&block)
28
+ block.call(self)
29
+ update
30
+ end
31
+
32
+ def method_missing(method, *args)
33
+ if TkFont.respond_to?(method)
34
+ TkFont.send(method, @tk_widget.font, *args)
35
+ else
36
+ super
37
+ end
38
+ end
39
+
40
+ def respond_to_missing?(method, *)
41
+ TkFont.respond_to?(method) || super
42
+ end
43
+
44
+ def load
45
+ @config = TkFont.actual(@tk_widget.font).to_h.transform_keys(&:to_sym)
46
+ end
47
+
48
+ def update
49
+ @tk_widget.font = TkFont.new(@config)
50
+ end
51
+ end
data/lib/util/tk/tk.rb ADDED
@@ -0,0 +1,8 @@
1
+ module TkWrapper
2
+ module Util
3
+ module Tk
4
+ end
5
+ end
6
+ end
7
+
8
+ require_relative 'font'
@@ -4,57 +4,31 @@ class TkWrapper::Widgets::AutoResizeEntry < TkWrapper::Widgets::Entry
4
4
  # auto resizes on user input, only works if in the grid geometry manager of tk
5
5
  attr_accessor :min_width, :add_width
6
6
 
7
- def initialize(config: {}, childs: [])
8
- @min_width = config.delete(:min_width) || 0
9
- @add_width = config.delete(:add_width) || 0
10
- super(config: config, childs: childs)
7
+ def initialize(**args)
8
+ @min_width = args.dig(:config, :min_width) || 0
9
+ @add_width = args.dig(:config, :add_width) || 0
10
+ super(**args)
11
11
  end
12
12
 
13
- def build(parent, configure: true)
14
- super(parent, configure: configure)
13
+ def build(parent, **args)
14
+ super(parent, **args)
15
15
  parent.tk_widget.bind('Configure') { resize }
16
16
  tk_widget.textvariable = TkVariable.new unless tk_widget.textvariable
17
17
  tk_widget.textvariable.trace('write') { resize }
18
18
  resize
19
19
  end
20
20
 
21
- def config_for_dummy_label
22
- grid_info = TkGrid.info(tk_widget)
23
- { config: { grid: {
24
- row: grid_info['row'],
25
- column: grid_info['column'],
26
- columnspan: grid_info['columnspan'],
27
- sticky: 'nw'
28
- } } }
21
+ def value=(value)
22
+ tk_widget.textvariable.value = value
29
23
  end
30
24
 
31
- def create_dummy_label_with_same_size(&block)
32
- label = TkWrapper::Widgets::Label.new(**config_for_dummy_label)
33
- label.build(@parent)
34
- label.tk_widget.text = tk_widget.textvariable.value
35
- label.tk_widget.lower
36
- result = block.call(label)
37
- label.tk_widget.destroy
38
- result
39
- end
40
-
41
- def text_width_in_pixel
42
- create_dummy_label_with_same_size do |label|
43
- @parent.tk_widget.update
44
- label.tk_widget.winfo_width
45
- end
46
- end
47
-
48
- def textwidth_and_maxwidth_in_pixel
49
- create_dummy_frame_with_same_size_label do |frame, label|
50
- { text_width: label.tk_widget.winfo_width,
51
- max_width: frame.tk_widget.winfo_width }
52
- end
25
+ def value
26
+ tk_widget.textvariable.value
53
27
  end
54
28
 
55
29
  def resize
56
- max_width = cell_bbox[2]
57
- text_width = text_width_in_pixel
30
+ max_width = [@cell.bbox[2], 0].max
31
+ text_width = @font.measure(value)
58
32
  new_width = [[@min_width, text_width + @add_width].max, max_width].min
59
33
  tk_widget.width = 0
60
34
  tk_widget.grid(ipadx: new_width / 2.0)
@@ -5,3 +5,4 @@ module TkWrapper::Widgets::Base end
5
5
  require_relative 'widget'
6
6
  require_relative 'manager'
7
7
  require_relative 'configuration'
8
+ require_relative 'matches'
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'matcher'
4
+
5
+ class TkWrapper::Widgets::Base::ComparatorItemStore
6
+ Matcher = TkWrapper::Widgets::Base::Matcher
7
+
8
+ def initialize
9
+ @key_map = {} # for fast lookup
10
+ @comparator_map = {} # for lookup using comparisons by Matcher class
11
+ end
12
+
13
+ def map_key?(key)
14
+ [String, Symbol].include?(key)
15
+ end
16
+
17
+ def push(key, *items)
18
+ if map_key?(key)
19
+ (@key_map[key] ||= []).concat(items)
20
+ else
21
+ (@comparator_map[key] ||= []).concat(items)
22
+ end
23
+ end
24
+
25
+ # returns [{items: [...], match: Match}, {items: [...]}, ...]
26
+ def items_and_matches_for_widget(widget)
27
+ widget.ids.reduce([]) do |items, id|
28
+ items + items_from_key_map(id) + items_from_comparator_map(id, widget)
29
+ end
30
+ end
31
+
32
+ def [](key)
33
+ items = map_key?(key) ? @key_map[key] : @comparator_map[key]
34
+ items&.length == 1 ? items.first : items
35
+ end
36
+
37
+ private
38
+
39
+ def items_from_key_map(id)
40
+ (items = @key_map[id]) ? [{ items: items }] : []
41
+ end
42
+
43
+ def items_from_comparator_map(id, widget)
44
+ matcher = Matcher.new(value: id)
45
+
46
+ @comparator_map.filter_map do |(comparator, items)|
47
+ (m = matcher.match(comparator, widget)) && { items: items, match: m }
48
+ end
49
+ end
50
+ end
@@ -20,7 +20,9 @@ class TkWrapper::Widgets::Base::Configuration
20
20
  }
21
21
  }.freeze
22
22
 
23
- NON_TK_OPTIONS = %i[id tk_class tearoff weights menu].freeze
23
+ NON_TK_OPTIONS = %i[
24
+ tk_class tearoff weights menu min_width add_width
25
+ ].freeze
24
26
 
25
27
  def initialize(config)
26
28
  @config = parse_and_clone(config)
@@ -110,6 +112,8 @@ class TkWrapper::Widgets::Base::Configuration
110
112
  end
111
113
 
112
114
  def merge_global_configurations(manager, widget)
115
+ return unless manager
116
+
113
117
  merge(*manager.configurations(widget))
114
118
  end
115
119
  end
@@ -1,32 +1,52 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # manages widgets and their global configurations
3
+ require_relative 'comparator_item_store'
4
+ require_relative 'widget_store'
5
+
4
6
  class TkWrapper::Widgets::Base::Manager
7
+ ComparatorItemStore = TkWrapper::Widgets::Base::ComparatorItemStore
8
+ WidgetStore = TkWrapper::Widgets::Base::WidgetStore
9
+
10
+ attr_reader :widgets
11
+
5
12
  def initialize
6
- @configurations = []
7
- @modifications = []
13
+ @configurations = ComparatorItemStore.new
14
+ @modifications = ComparatorItemStore.new
15
+ @widgets = WidgetStore.new
16
+ end
17
+
18
+ def add_configurations(matcher = nil, configuration = nil, **configurations)
19
+ add_configuration(matcher, configuration) if configuration
20
+
21
+ configurations.each { |mat, cfg| add_configuration(mat, cfg) }
8
22
  end
9
23
 
10
- def add_configuration(matcher, configuration)
11
- @configurations.push([matcher, configuration])
24
+ def add_configuration(comparator, configuration)
25
+ @configurations.push(comparator, configuration)
12
26
  end
13
27
 
14
28
  def add_modification(matcher, &callback)
15
- @modifications.push([matcher, callback])
29
+ @modifications.push(matcher, callback)
16
30
  end
17
31
 
18
32
  def configurations(widget)
19
- @configurations.filter_map do |(matcher, config)|
20
- config if widget.check_match(matcher)
21
- end
33
+ config_list = @configurations.items_and_matches_for_widget(widget)
34
+ config_list.map { |configs| configs[:items] }.flatten(1)
22
35
  end
23
36
 
24
37
  def execute_modifications(widget)
25
- @modifications.each do |(matcher, callback)|
26
- next unless (match = widget.check_match(matcher))
27
-
28
- arguments = match.is_a?(MatchData) ? [widget, match] : [widget]
29
- callback.call(*arguments)
38
+ item_list = @modifications.items_and_matches_for_widget(widget)
39
+ item_list.each do |items|
40
+ items[:items].each do |callback|
41
+ callback.call(widget, items[:match])
42
+ end
30
43
  end
31
44
  end
45
+
46
+ def configure(widget)
47
+ widget.config.merge(*configurations(widget))
48
+ end
49
+
50
+ alias modify add_modification
51
+ alias config add_configurations
32
52
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # single 'match' as part of a Matches object
4
+ class TkWrapper::Widgets::Base::Match
5
+ attr_reader :key, :widget, :match
6
+
7
+ def initialize(value, cls: nil, match: nil, widget: nil)
8
+ @key = match&.[](0) || value
9
+ @widget = widget
10
+ @match = match
11
+ @cls = cls
12
+ @value = value
13
+ end
14
+
15
+ def tk_widget
16
+ @widget&.tk_widget
17
+ end
18
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "#{LIB_DIR}/widgets/base/match"
4
+
5
+ class TkWrapper::Widgets::Base::Matcher
6
+ Match = TkWrapper::Widgets::Base::Match
7
+
8
+ def initialize(value: nil, comparator: nil)
9
+ @match_function = curry_match_function(value, comparator)
10
+ end
11
+
12
+ # args:
13
+ # [] if widget and matcher were provided on initialization
14
+ # [widget] if matcher was provided on initialization
15
+ # [matcher] if widget was provided on initialization
16
+ # [widget, matcher] if neither widget nor matcher were provided on initial.
17
+ def match(*args)
18
+ @match_function.call(*args)
19
+ end
20
+
21
+ private
22
+
23
+ def match_regex(value, comparator, widget)
24
+ (match = comparator.match(value)) &&
25
+ Match.new(value, match: match, widget: widget)
26
+ end
27
+
28
+ def match_string(value, comparator, widget)
29
+ value == comparator && Match.new(value, widget: widget)
30
+ end
31
+
32
+ def match_class(value, comparator, widget)
33
+ widget.is_a?(comparator) &&
34
+ Match.new(value, cls: comparator, widget: widget)
35
+ end
36
+
37
+ def match_f(value, comparator, widget)
38
+ case comparator
39
+ when String, Symbol then match_string(value, comparator, widget)
40
+ when Regexp then match_regex(value, comparator, widget)
41
+ when Class then match_class(value, comparator, widget)
42
+ when nil then Match(value, { widget: widget })
43
+ else false
44
+ end
45
+ end
46
+
47
+ def curry_match_function(value, comparator)
48
+ if value && comparator
49
+ ->(widget) { match_f(value, comparator, widget) }
50
+ elsif value
51
+ ->(x_comparator, widget) { match_f(value, x_comparator, widget) }
52
+ elsif comparator
53
+ ->(x_value, widget) { match_f(x_value, comparator, widget) }
54
+ else
55
+ ->(x_value, x_comparator, widget) { match_f(x_value, x_comparator, widget) }
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,38 @@
1
+ require_relative 'match'
2
+
3
+ # matches widgets against conditions and stores matching widgets and matches
4
+ class TkWrapper::Widgets::Base::Matches
5
+ include Enumerable
6
+
7
+ def initialize
8
+ @matches = {}
9
+ end
10
+
11
+ def push(match)
12
+ (@matches[match.key] ||= []).push(match)
13
+ end
14
+
15
+ def concat(matches)
16
+ matches.each { |match| push(match) }
17
+ end
18
+
19
+ def each(&block)
20
+ @matches.each do |(key, matches_for_key)|
21
+ matches_for_key.each do |match|
22
+ block.call([match.widget, key, match.match, match])
23
+ end
24
+ end
25
+ end
26
+
27
+ def [](key)
28
+ case @matches[key].size
29
+ when 0 then nil
30
+ when 1 then @matches[key][0]
31
+ else @matches[key]
32
+ end
33
+ end
34
+
35
+ def first
36
+ @matches.first&.[](1)
37
+ end
38
+ end
@@ -1,39 +1,28 @@
1
- # frozen_string_literal: true
2
-
3
- require 'tk'
4
-
1
+ require "#{LIB_DIR}/util/tk/cell"
2
+ require "#{LIB_DIR}/util/tk/finder"
5
3
  require "#{LIB_DIR}/tk_extensions"
6
4
 
7
5
  require_relative 'base'
8
6
 
9
7
  class TkWrapper::Widgets::Base::Widget
8
+ extend Forwardable
10
9
  include TkExtensions
10
+ include Enumerable
11
+
12
+ def_delegators :@finder, :find, :find_all
11
13
 
12
14
  attr_accessor :config
13
- attr_reader :parent, :childs
15
+ attr_reader :parent, :ids, :cell, :childs, :manager
14
16
 
15
17
  def tk_class() end
16
18
 
17
- def self.manager
18
- @manager ||= TkWrapper::Widgets::Base::Manager.new
19
- end
20
-
21
- def self.config(matcher, configuration)
22
- manager.add_configuration(matcher, configuration)
23
- end
24
-
25
- def self.modify(matcher, &callback)
26
- manager.add_modification(matcher, &callback)
27
- end
28
-
29
- def manager
30
- TkWrapper::Widgets::Base::Widget.manager
31
- end
32
-
33
- def initialize(config: {}, childs: [])
19
+ def initialize(config: {}, childs: [], manager: nil, ids: [])
20
+ @cell = TkWrapper::Util::Tk::Cell.new(self)
21
+ @finder = TkWrapper::Util::Tk::Finder.new(widgets: self)
34
22
  @config = TkWrapper::Widgets::Base::Configuration.new(config)
35
23
  @childs = childs.is_a?(Array) ? childs : [childs]
36
- @id = config[:id]
24
+ @manager = manager
25
+ @ids = ids.is_a?(Array) ? ids : [ids]
37
26
  end
38
27
 
39
28
  def create_tk_widget(parent)
@@ -52,84 +41,34 @@ class TkWrapper::Widgets::Base::Widget
52
41
  (@tk_widget = create_tk_widget(parent)) || parent&.tk_widget
53
42
  end
54
43
 
55
- def build(parent, configure: true)
44
+ def build(parent, configure: true, manager: nil)
56
45
  @parent = parent
57
46
  tk_widget # creates the widget if possible and not yet created
47
+ @font = TkWrapper::Util::Tk::Font.new(tk_widget)
48
+ @manager ||= manager
49
+ @config.merge(*@manager.configurations(self)) if @manager
58
50
  self.configure if configure
59
- manager.execute_modifications(self)
60
- @childs.each { |child| child.build(self) }
61
- end
62
-
63
- def push(child)
64
- @childs.push(child)
65
- child.build(self)
51
+ @manager&.execute_modifications(self)
52
+ @manager&.widgets&.push(self)
53
+ @childs.each { |child| child.build(self, manager: @manager) }
66
54
  end
67
55
 
68
56
  def configure
69
- @config.merge_global_configurations(manager, self)
70
57
  @config.configure_tk_widget(tk_widget)
71
58
  @config.configure_tearoff
72
59
  end
73
60
 
74
- def check_match(matcher)
75
- case matcher
76
- when Regexp
77
- matcher.match(@id)
78
- when String, Symbol
79
- matcher == @id
80
- when nil
81
- true
82
- else
83
- is_a?(matcher)
61
+ def each(&block)
62
+ nodes_to_walk = [self]
63
+ until nodes_to_walk.empty?
64
+ node = nodes_to_walk.pop
65
+ block.call(node)
66
+ nodes_to_walk = node.childs + nodes_to_walk
84
67
  end
85
68
  end
86
69
 
87
- def find(matcher)
88
- nodes_to_scan = [self]
89
- until nodes_to_scan.empty?
90
- node = nodes_to_scan.pop
91
- return node if node.check_match(matcher)
92
-
93
- nodes_to_scan = node.childs + nodes_to_scan
94
- end
95
- end
96
-
97
- def find_all(matcher)
98
- found_nodes = []
99
- nodes_to_scan = [self]
100
-
101
- until nodes_to_scan.empty?
102
- node = nodes_to_scan.pop
103
- found_nodes.push(node) if node.check_match(matcher)
104
-
105
- nodes_to_scan = node.childs + nodes_to_scan
106
- end
107
-
108
- found_nodes
109
- end
110
- end
111
-
112
- # the first parent, which contains a tk_widget, which is really different
113
- # from self.tk_widget
114
- def get_container_parent
115
- container = @parent
116
- while container.tk_widget == tk_widget
117
- return unless container.parent # not in a grid?
118
-
119
- container = container.parent
70
+ def push(child)
71
+ @childs.push(child)
72
+ child.build(self)
120
73
  end
121
- container
122
- end
123
-
124
- # returns the bounding box of the tk_widget
125
- def cell_bbox
126
- return unless (container = get_container_parent)
127
-
128
- grid_info = TkGrid.info(tk_widget)
129
- start_col = grid_info['column']
130
- end_col = start_col + grid_info['columnspan'] - 1
131
- start_row = grid_info['row']
132
- end_row = start_row + grid_info['rowspan'] - 1
133
-
134
- TkGrid.bbox(container.tk_widget, start_col, start_row, end_col, end_row)
135
74
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "#{LIB_DIR}/util/tk/finder"
4
+ require_relative 'comparator_item_store'
5
+
6
+ class TkWrapper::Widgets::Base::WidgetStore
7
+ extend Forwardable
8
+
9
+ def_delegators :@finder, :find, :find_all, :iter
10
+
11
+ def initialize
12
+ @lookup = {}
13
+ @finder = TkWrapper::Util::Tk::Finder.new(widgets: self, lookup: @lookup)
14
+ end
15
+
16
+ def push(widget)
17
+ widget.ids.each do |id|
18
+ (@lookup[id] ||= []).push(widget)
19
+ end
20
+ end
21
+
22
+ def each(&block)
23
+ @lookup.each_value do |widgets|
24
+ widgets.each { |widget| block.call(widget) }
25
+ end
26
+ end
27
+
28
+ def [](key)
29
+ @lookup[key].size == 1 ? @lookup[key].first : @lookup[key]
30
+ end
31
+
32
+ private
33
+
34
+ def map_key?(key)
35
+ [String, Symbol].include?(key)
36
+ end
37
+ end
data/lib/widgets/grid.rb CHANGED
@@ -10,8 +10,8 @@ class TkWrapper::Widgets::Grid < TkWrapper::Widgets::Base::Widget
10
10
  TkWidgets::Frame
11
11
  end
12
12
 
13
- def initialize(config: {}, childs: [])
14
- super(config: config, childs: childs)
13
+ def initialize(**arguments)
14
+ super(**arguments)
15
15
  @childs.map! { |row| row.is_a?(Array) ? row : [row] }
16
16
  configure_cells_for_grid
17
17
  @childs.flatten! && @childs.select! { |cell| cell.is_a?(Widget) }
data/lib/widgets/menu.rb CHANGED
@@ -5,8 +5,8 @@ class TkWrapper::Widgets::Menu < TkWrapper::Widgets::Base::Widget
5
5
  TkWidgets::TkMenu
6
6
  end
7
7
 
8
- def build(parent)
9
- super(parent)
8
+ def build(parent, **args)
9
+ super(parent, **args)
10
10
  parent.tk_widget['menu'] = tk_widget
11
11
  end
12
12
 
@@ -15,15 +15,18 @@ class TkWrapper::Widgets::Menu < TkWrapper::Widgets::Base::Widget
15
15
  TkWidgets::TkMenu
16
16
  end
17
17
 
18
- def build(parent)
19
- super(parent, configure: false)
18
+ def build(parent, **args)
19
+ args[:configure] = false
20
+ super(parent, **args)
20
21
  @config[:menu] = tk_widget
21
22
  parent.tk_widget.add :cascade, **@config.config
22
23
  end
23
24
  end
24
25
 
25
26
  class Command < TkWrapper::Widgets::Base::Widget
26
- def build(parent)
27
+ def build(parent, **args)
28
+ args[:configure] = false
29
+ super(parent, **args)
27
30
  parent.tk_widget.add :command, **@config.config
28
31
  end
29
32
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tkwrapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Schnitzler
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-13 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-12-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.4'
13
27
  description:
14
28
  email: reception@e.mail.de
15
29
  executables: []
@@ -19,13 +33,21 @@ files:
19
33
  - lib/tk_extensions.rb
20
34
  - lib/tkwrapper.rb
21
35
  - lib/util/hash_recursive.rb
36
+ - lib/util/tk/cell.rb
37
+ - lib/util/tk/finder.rb
38
+ - lib/util/tk/font.rb
39
+ - lib/util/tk/tk.rb
22
40
  - lib/util/virtual_methods.rb
23
41
  - lib/widgets/auto_resize_entry.rb
24
42
  - lib/widgets/base/base.rb
43
+ - lib/widgets/base/comparator_item_store.rb
25
44
  - lib/widgets/base/configuration.rb
26
45
  - lib/widgets/base/manager.rb
46
+ - lib/widgets/base/match.rb
47
+ - lib/widgets/base/matcher.rb
48
+ - lib/widgets/base/matches.rb
27
49
  - lib/widgets/base/widget.rb
28
- - lib/widgets/base/widgets.rb
50
+ - lib/widgets/base/widget_store.rb
29
51
  - lib/widgets/entry.rb
30
52
  - lib/widgets/frame.rb
31
53
  - lib/widgets/grid.rb
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class TkWrapper::Widgets::Base::Widgets
4
- def initialize
5
- @configurations = []
6
- @modifications = []
7
- end
8
-
9
- def add_configuration(matcher, configuration)
10
- @configurations.push(matcher, configuration)
11
- end
12
-
13
- def add_modification(matcher, &callback)
14
- @modifications.push(matcher, callback)
15
- end
16
-
17
- def configurations(widget)
18
- @configurations.filter_map do |(matcher, config)|
19
- config if widget.check_match(matcher)
20
- end
21
- end
22
-
23
- def execute_modifications(widget)
24
- @modifications.each do |(matcher, callback)|
25
- next unless (match = widget.check_match(matcher))
26
-
27
- arguments = match.is_a?(MatchData) ? [widget, match] : [widget]
28
- callback.call(*arguments)
29
- end
30
- end
31
- end