glimmer-dsl-tk 0.0.61 → 0.0.63

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 65202d323a2567e112890475495d310877f839c0a064f8f4e17e2564df47b422
4
- data.tar.gz: 93515ff8e8ef6ff1e8b3eae4d3f809522110fb9e0e83e4523eaede034cd605d0
3
+ metadata.gz: 68fb65641bc77c179c7600d37210817eadd271de99aeb0ed8ca6bd7c3c5716b3
4
+ data.tar.gz: 40be5cb8a31b5a8284a8c3a208e6ccee512df2d42d051db3fdb9c7fc0041554a
5
5
  SHA512:
6
- metadata.gz: a5206b004b6b49c5b29444410b86d978cb787314e25c32f069e2e973b456f164a20c04a295a2cac4bd90d0e5627df5477605daf8cc9439bf883caea4e79485b3
7
- data.tar.gz: 9addeadf0b91a2c51a0ac137b550d700a2a621d52ca997d8618ff6d83281be2c030eebe34ca0cf4bd0c122b3fa4b26c9ac8ecf4b1e2b3f46ba7bafad562f1052
6
+ metadata.gz: 002fe595bd7e763629bd42c63f1ac9b004388dab953e3bb3b764582b623befff82cc17009a9277f75f314621b7e8fb393efe9595dcda3ecf83389f0a0c95d204
7
+ data.tar.gz: 5f31f46283e9170bd5459514f4406b829cb718d3bb068a35f3983fcd9e6e29142a4d15bbffd9c60b59dbb135f40ce982f48b2d14561df7e8c5a8fb8f4d986693
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.63
4
+
5
+ - `modal = true` modifier for toplevels (the root becomes hidden till the toplevel is closed)
6
+ - If no icon is set for a toplevel, take icon from the root
7
+ - An experimental fix of `center_within_screen` for Linux multi-monitor environments
8
+ - `center_within_root` method to center a toplevel within the boundaries of the root (useful for modal windows / dialogs)
9
+ - A helper `window?` method to determine if the widget is a window (root, toplevel) or not
10
+ - Support for single style name argument in the `style` setter to be able to use predefined Tk styles by name
11
+ - Support for `columnuniform` / `rowuniform` grid arguments, aliased also as `column_uniform` / `row_uniform`
12
+ - `event_generate` method for raising custom Tk events (wrapper around `tk.event_generate`)
13
+ - Fix `unbind_all`, use `tk.bind_remove` instead of `tk.bind(..., '')` which was causing weird effects when reloading events
14
+ - `closest_window` method to find the closest parent window-type widget
15
+ - `enabled` / `disabled` pair of attributes
16
+ - `visible` / `hidden` pair of attributes
17
+ - Fixed the problem when variables bound to deselected radiobuttons weren't being updated to false
18
+
19
+ ## 0.0.62
20
+
21
+ - `icon_photo` as alias for `iconphoto` attribute on `root` and `toplevel`
22
+ - `initial_color` as alias for `initialcolor` attribute on `choose_color` built-in dialog
23
+
3
24
  ## 0.0.61
4
25
 
5
26
  - Fix issue with Hello, Entry! breaking after the latest release due to mistakenly converting color `'red'` to `'#red'` by thinking it is hex
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Tk 0.0.61
1
+ # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Tk 0.0.63
2
2
  ## Ruby Tk Desktop Development GUI Library
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-tk.svg)](http://badge.fury.io/rb/glimmer-dsl-tk)
4
4
  [![Ruby](https://github.com/AndyObtiva/glimmer-dsl-tk/actions/workflows/ruby.yml/badge.svg)](https://github.com/AndyObtiva/glimmer-dsl-tk/actions/workflows/ruby.yml)
@@ -51,19 +51,7 @@ Glimmer app:
51
51
 
52
52
  NOTE: Glimmer DSL for Tk is currently in early alpha mode (only about 44% complete). If you want it developed faster, then [open an issue report](https://github.com/AndyObtiva/glimmer-dsl-tk/issues/new). I have completed some features much faster before due to [issue reports](https://github.com/AndyObtiva/glimmer-dsl-tk/issues) and [pull requests](https://github.com/AndyObtiva/glimmer-dsl-tk/pulls). Please help make better by contributing, adopting for small or low risk projects, and providing feedback. It is still an early alpha, so the more feedback and issues you report the better.
53
53
 
54
- **[Glimmer](https://rubygems.org/gems/glimmer) DSL Comparison Table:**
55
- DSL | Platforms | Native? | Vector Graphics? | Pros | Cons | Prereqs
56
- ----|-----------|---------|------------------|------|------|--------
57
- [Glimmer DSL for SWT (JRuby Desktop Development GUI Framework)](https://github.com/AndyObtiva/glimmer-dsl-swt) | Mac / Windows / Linux | Yes | Yes (Canvas Shape DSL) | Very Mature / Scaffolding / Native Executable Packaging / Custom Widgets | Slow JRuby Startup Time / Heavy Memory Footprint | Java / JRuby
58
- [Glimmer DSL for Opal (Pure Ruby Web GUI and Auto-Webifier of Desktop Apps)](https://github.com/AndyObtiva/glimmer-dsl-opal) | All Web Browsers | No | Yes (Canvas Shape DSL) | Simpler than All JavaScript Technologies / Auto-Webify Desktop Apps | Setup Process / Incomplete Alpha | Rails
59
- [Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-libui) | Mac / Windows / Linux | Yes | Yes (Area API) | Fast Startup Time / Light Memory Footprint | LibUI is an Incomplete Mid-Alpha Only | None Other Than MRI Ruby
60
- [Glimmer DSL for Tk (Ruby Tk Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-tk) | Mac / Windows / Linux | Some Native-Themed Widgets (Not Truly Native) | Yes (Canvas) | Fast Startup Time / Light Memory Footprint | Complicated setup / Widgets Do Not Look Truly Native, Espcially on Linux | ActiveTcl / MRI Ruby
61
- [Glimmer DSL for GTK (Ruby-GNOME Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-gtk) | Mac / Windows / Linux | Only on Linux | Yes (Cairo) | Complete Access to GNOME Features on Linux (Forte) | Not Native on Mac and Windows | None Other Than MRI Ruby on Linux / Brew Packages on Mac / MSYS & MING Toolchains on Windows / MRI Ruby
62
- [Glimmer DSL for FX (FOX Toolkit Ruby Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-fx) | Mac (requires XQuartz) / Windows / Linux | No | Yes (Canvas) | No Prerequisites on Windows (Forte Since Binaries Are Included Out of The Box) | Widgets Do Not Look Native / Mac Usage Obtrusively Starts XQuartz | None Other Than MRI Ruby on Windows / XQuarts on Mac / MRI Ruby
63
- [Glimmer DSL for JFX (JRuby JavaFX Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-jfx) | Mac / Windows / Linux | No | Yes (javafx.scene.shape and javafx.scene.canvas) | Rich in Custom Widgets | Slow JRuby Startup Time / Heavy Memory Footprint / Widgets Do Not Look Native | Java / JRuby / JavaFX SDK
64
- [Glimmer DSL for Swing (JRuby Swing Desktop Development GUI Library)](https://github.com/AndyObtiva/glimmer-dsl-swing) | Mac / Windows / Linux | No | Yes (Java2D) | Very Mature | Slow JRuby Startup Time / Heavy Memory Footprint / Widgets Do Not Look Native | Java / JRuby
65
- [Glimmer DSL for XML (& HTML)](https://github.com/AndyObtiva/glimmer-dsl-xml) | All Web Browsers | No | Yes (SVG) | Programmable / Lighter-weight Than Actual XML | XML Elements Are Sometimes Not Well-Named (Many Types of Input) | None
66
- [Glimmer DSL for CSS](https://github.com/AndyObtiva/glimmer-dsl-css) | All Web Browsers | No | Yes | Programmable | CSS Is Over-Engineered / Too Many Features To Learn | None
54
+ Learn more about the differences between various [Glimmer](https://github.com/AndyObtiva/glimmer) DSLs by looking at the **[Glimmer DSL Comparison Table](https://github.com/AndyObtiva/glimmer#glimmer-dsl-comparison-table)**.
67
55
 
68
56
  ## Table of Contents
69
57
 
@@ -139,7 +127,6 @@ DSL | Platforms | Native? | Vector Graphics? | Pros | Cons | Prereqs
139
127
  - [Applications](#applications)
140
128
  - [Glimmer Tk Calculator](#glimmer-tk-calculator)
141
129
  - [Y3network Ruby UI](#y3network-ruby-ui)
142
- - [CryptoPunks GUI](#cryptopunks-gui)
143
130
  - [Circule](#circule)
144
131
  - [Process](#process)
145
132
  - [Resources](#resources)
@@ -195,7 +182,7 @@ gem install glimmer-dsl-tk
195
182
 
196
183
  Add the following to `Gemfile`:
197
184
  ```
198
- gem 'glimmer-dsl-tk', '0.0.61'
185
+ gem 'glimmer-dsl-tk', '0.0.63'
199
186
  ```
200
187
 
201
188
  And, then run:
@@ -309,7 +296,7 @@ keyword(args) | attributes | event bindings & callbacks
309
296
  ------------- | ---------- | ---------
310
297
  `button` | `text`, `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `default` (`'active', 'normal'`) | `command {}`
311
298
  `checkbutton` | `text`, `variable` (Boolean), `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `onvalue` (default: `1`), `offvalue` (default: `0`) | `command {}`
312
- `choose_color(parent: nil, initialcolor: 'white', title: 'Colors')` | None | None
299
+ `choose_color(parent: nil, initial_color: 'white', title: 'Colors')` | None | None
313
300
  `choose_directory(parent: nil)` | None | None
314
301
  `choose_font(family: nil, size: nil, weight: nil) {|font| ... }` | None | None
315
302
  `combobox` | `state`, `text` | `'ComboboxSelected'`
@@ -328,11 +315,11 @@ keyword(args) | attributes | event bindings & callbacks
328
315
  `menu_item(style = :command, label: , underline: )` (style also can be `:radiobutton`, `:checkbutton`, `:separator`, `:about`, `:preferences`, `:quit`, `:help`) | `state`, `accelerator`, `selection` & `variable` (if `:radiobutton` or `:checkbutton`), `image`, `compound` | `command`
329
316
  `notebook` | None | None
330
317
  `radiobutton` | `text`, `variable` (Boolean), `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `value` (default: `text`) | `command {}`
331
- `root` | `title`, `iconphoto`, `background`, `alpha`, `escapable`, `fullscreen?`, `topmost?`, `transparent?`, `stackorder`, `winfo_screendepth`, `winfo_screenvisual`, `winfo_screenwidth`, `winfo_screenheight`, `winfo_pixels('li')`, `winfo_screen`, `wm_maxsize`, `state` (`'normal', 'iconic', 'withdrawn', 'icon', 'zoomed'`) | `'DELETE_WINDOW'`, `'OPEN_WINDOW'`
318
+ `root` | `title`, `icon_photo`, `background`, `alpha`, `escapable`, `fullscreen?`, `topmost?`, `transparent?`, `stackorder`, `winfo_screendepth`, `winfo_screenvisual`, `winfo_screenwidth`, `winfo_screenheight`, `winfo_pixels('li')`, `winfo_screen`, `wm_maxsize`, `state` (`'normal', 'iconic', 'withdrawn', 'icon', 'zoomed'`) | `'DELETE_WINDOW'`, `'OPEN_WINDOW'`
332
319
  `scrollbar` | `orient` | `command`
333
320
  `scrollbar_frame` | `xscrollbar` (Boolean or scrollbar widget proxy), `yscrollbar` (Boolean or scrollbar widget proxy) | None
334
321
  `separator` | `orient` (`'horizontal' (default) or 'vertical'`) | None
335
- `toplevel` | `title`, `iconphoto`, `background`, `alpha`, `escapable`, `fullscreen?`, `topmost?`, `transparent?`, `stackorder`, `winfo_screendepth`, `winfo_screenvisual`, `winfo_screenwidth`, `winfo_screenheight`, `winfo_pixels('li')`, `winfo_screen`, `wm_maxsize`, `state` (`'normal', 'iconic', 'withdrawn', 'icon', 'zoomed'`) | `'DELETE_WINDOW'`
322
+ `toplevel` | `title`, `icon_photo`, `background`, `alpha`, `escapable`, `fullscreen?`, `topmost?`, `transparent?`, `stackorder`, `winfo_screendepth`, `winfo_screenvisual`, `winfo_screenwidth`, `winfo_screenheight`, `winfo_pixels('li')`, `winfo_screen`, `wm_maxsize`, `state` (`'normal', 'iconic', 'withdrawn', 'icon', 'zoomed'`) | `'DELETE_WINDOW'`
336
323
  `text` | `value`, [many more attributes](https://tcl.tk/man/tcl8.6/TkCmd/text.htm#M116) | `'modified'`, `'selection'`, `'insert_mark_moved'` (alias: `'insert_mark_move', 'InsertMarkMove', 'InsertMarkMoved'`)
337
324
  `x_scrollbar` | `orient` (`'horizontal'`) | `command`
338
325
  `y_scrollbar` | `orient` (`'vertical'`) | `command`
@@ -555,7 +542,7 @@ When nesting `frame` under `notebook`, you can pass a `:text` keyword argument t
555
542
 
556
543
  #### Icon Photo
557
544
 
558
- The `iconphoto` attribute on `root` is set to the Glimmer icon by default if no icon photo is supplied.
545
+ The `icon_photo` attribute (alias for `iconphoto`) on `root` is set to the Glimmer icon by default if no icon photo is supplied.
559
546
 
560
547
  Otherwise, [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk) is smart enough to accept an image path directly (no need to wrap with `TkPhotoImage`)
561
548
 
@@ -564,7 +551,7 @@ Example with direct image path (you may copy/paste in [`girb`](#girb-glimmer-irb
564
551
  ```ruby
565
552
  root {
566
553
  title 'Title'
567
- iconphoto 'icons/glimmer.png'
554
+ icon_photo 'icons/glimmer.png'
568
555
  }.open
569
556
  ```
570
557
 
@@ -573,7 +560,7 @@ Example with `TkPhotoImage` object (you may copy/paste in [`girb`](#girb-glimmer
573
560
  ```ruby
574
561
  root {
575
562
  title 'Title'
576
- iconphoto TkPhotoImage.new(file: 'icons/glimmer.png')
563
+ icon_photo TkPhotoImage.new(file: 'icons/glimmer.png')
577
564
  }.open
578
565
  ```
579
566
 
@@ -1535,7 +1522,7 @@ include Glimmer
1535
1522
 
1536
1523
  root { |r|
1537
1524
  title 'Hello, Root!'
1538
- iconphoto File.expand_path('../../icons/glimmer.png', __dir__)
1525
+ icon_photo File.expand_path('../../icons/glimmer.png', __dir__)
1539
1526
  width 400
1540
1527
  height 200
1541
1528
  x -150
@@ -4283,14 +4270,6 @@ https://github.com/ancorgs/glimmer-tk-calculator
4283
4270
 
4284
4271
  https://github.com/ancorgs/y3network-ruby-ui
4285
4272
 
4286
- ### CryptoPunks GUI
4287
-
4288
- This is a Graphical User Interface for the famous [cryptopunks Ruby gem](https://github.com/cryptopunksnotdead/cryptopunks/tree/master/cryptopunks).
4289
-
4290
- https://github.com/cryptopunksnotdead/cryptopunks/tree/master/cryptopunks-gui
4291
-
4292
- ![CryptoPunks GUI Screenshot](https://raw.githubusercontent.com/cryptopunksnotdead/cryptopunks/master/cryptopunks-gui/screenshots/cryptopunks-gui-screenshot.png)
4293
-
4294
4273
  ### Circule
4295
4274
 
4296
4275
  Generate an icon of overlapping circles derived from a hash.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.61
1
+ 0.0.63
Binary file
@@ -38,6 +38,7 @@ module Glimmer
38
38
  def interpret(parent, keyword, *args, &block)
39
39
  if args.first.is_a?(Hash)
40
40
  options = args.first.symbolize_keys
41
+ options[:initialcolor] = options.delete(:initial_color) if options.keys.include?(:initial_color)
41
42
  options[:filetypes] = options.delete(:file_types) if options.keys.include?(:file_types)
42
43
  options[:filetypes] = options[:filetypes].map { |key, value| "{#{key}} {#{value}}" } if options[:filetypes].is_a?(Hash)
43
44
  options[:parent] = options[:parent].tk if options[:parent].is_a?(Glimmer::Tk::RootProxy)
@@ -32,30 +32,58 @@ module Glimmer
32
32
  DEFAULT_HEIGHT = 0
33
33
 
34
34
  attr_reader :tk
35
- attr_accessor :escapable
35
+ attr_accessor :escapable, :modal, :centered
36
36
  alias escapable? escapable
37
-
37
+ alias modal? modal
38
+ alias centered? centered
39
+
38
40
  def post_add_content
39
- center_within_screen unless @x || @y
40
41
  if escapable?
41
42
  on('KeyPress') do |event|
42
- if event.keysym == 'Escape'
43
- grab_release
43
+ if event.state == 0 && event.keysym == 'Escape'
44
+ tk.grab_release
44
45
  destroy
45
46
  end
46
47
  end
47
48
  end
49
+
50
+ if modal?
51
+ unless is_a?(Glimmer::Tk::ToplevelProxy)
52
+ raise 'Modal windows must be top level windows. Root cannot be modal.'
53
+ end
54
+
55
+ center_within_root unless @x || @y
56
+ root_parent_proxy.withdraw
57
+ tk.grab_set
58
+ on('WM_DELETE_WINDOW') do
59
+ tk.grab_release
60
+ root_parent_proxy.deiconify
61
+ destroy
62
+ true
63
+ end
64
+ on('destroy') do
65
+ tk.grab_release
66
+ root_parent_proxy.deiconify
67
+ true
68
+ end
69
+ else
70
+ center_within_screen unless @x || @y
71
+ end
72
+
73
+ if is_a?(Glimmer::Tk::ToplevelProxy) && @tk.iconphoto.nil? && root_parent_proxy.iconphoto
74
+ @tk.iconphoto = root_parent_proxy.iconphoto
75
+ end
48
76
  end
49
77
 
50
78
  def has_attribute?(attribute, *args)
51
- %w[width height x y].include?(attribute.to_s) || super
79
+ %w[width height x y icon_photo].include?(attribute.to_s) || super
52
80
  end
53
81
 
54
82
  def set_attribute(attribute, *args)
55
83
  case attribute.to_s
56
- when 'iconphoto'
84
+ when 'iconphoto', 'icon_photo'
57
85
  args[0..-1] = [image_argument(args)]
58
- super
86
+ super('iconphoto', *args)
59
87
  when 'resizable'
60
88
  if args.size == 1 && !args.first.is_a?(Array)
61
89
  self.resizable = [args.first]*2
@@ -67,6 +95,19 @@ module Glimmer
67
95
  end
68
96
  end
69
97
 
98
+ def get_attribute(attribute)
99
+ case attribute.to_s
100
+ when 'icon_photo'
101
+ super('iconphoto')
102
+ else
103
+ super
104
+ end
105
+ end
106
+
107
+ def icon_photo
108
+ iconphoto
109
+ end
110
+
70
111
  def width
71
112
  geometry.split(REGEX_GEOMETRY)[0].to_i
72
113
  end
@@ -112,18 +153,68 @@ module Glimmer
112
153
  super
113
154
  end
114
155
  end
115
-
156
+
116
157
  def center_within_screen
117
158
  monitor_width, monitor_height = wm_maxsize
118
159
  update :idletasks
119
160
  current_width = width
120
161
  current_height = height
121
- self.x = (winfo_screenwidth - width) / 2
122
- self.y = (winfo_screenheight - height) / 2
162
+
163
+ if RbConfig::CONFIG['host_os'] == 'linux'
164
+ begin
165
+ # example output: HDMI-A-0 connected primary 2560x1080+1024+100 (normal left inverted right x axis y axis) 798mm x 334mm
166
+ # TODO: is xrandr output same on all systems?
167
+ sizes = `xrandr`
168
+ .split("\n")
169
+ .find { |line| line.include?(' connected primary ') }
170
+ &.match(/([0-9]+)x([0-9]+)\+([0-9]+)\+([0-9]+)/)
171
+ raise "`xrandr` returned unexpected results. Try to run `xrandr`, verify it's output and possibly update this code." unless sizes
172
+
173
+ self.x = (sizes[1].to_i - width) / 2 + sizes[3].to_i
174
+ self.y = (sizes[2].to_i - height) / 2 + sizes[4].to_i
175
+
176
+ rescue StandardError => e
177
+ Glimmer::Config.logger.debug {"Unable to detect primary screen on Linux with xrandr"}
178
+ Glimmer::Config.logger.debug {e.full_message}
179
+
180
+ self.x = (winfo_screenwidth - width) / 2
181
+ self.y = (winfo_screenheight - height) / 2
182
+ end
183
+
184
+ else
185
+ self.x = (winfo_screenwidth - width) / 2
186
+ self.y = (winfo_screenheight - height) / 2
187
+ end
188
+
123
189
  self.width = width
124
190
  self.height = height
125
191
  end
126
-
192
+
193
+ def center_within_root(margin: 0)
194
+ self.x = root_parent_proxy.x + margin
195
+ self.y = root_parent_proxy.y + margin
196
+ self.width = root_parent_proxy.width - 2 * margin
197
+ self.height = root_parent_proxy.height - 2 * margin
198
+ end
199
+
200
+ def window?
201
+ true
202
+ end
203
+
204
+ [:visible, :hidden, :enabled, :disabled,
205
+ :visible=, :hidden=, :enabled=, :disabled=,
206
+ :visible?, :hidden?, :enabled?, :disabled?].each \
207
+ do |restricted_method|
208
+ define_method(restricted_method) do
209
+ # TODO: or just do nothing?
210
+ raise 'Not applicable for a root / toplevel'
211
+ end
212
+ end
213
+
214
+ def closest_window
215
+ self
216
+ end
217
+
127
218
  private
128
219
 
129
220
  def sign_number(sign, number)
@@ -19,6 +19,7 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
+ require 'yaml'
22
23
  require 'glimmer/data_binding/tk/one_time_observer'
23
24
  require 'glimmer/tk/widget'
24
25
  require 'glimmer/tk/draggable_and_droppable'
@@ -102,6 +103,7 @@ module Glimmer
102
103
  def toplevel_parent_proxy
103
104
  ancestor_proxies.find {|widget_proxy| widget_proxy.is_a?(ToplevelProxy)}
104
105
  end
106
+ alias closest_window toplevel_parent_proxy
105
107
 
106
108
  # returns list of ancestors ordered from direct parent to root parent
107
109
  def ancestor_proxies
@@ -254,13 +256,18 @@ module Glimmer
254
256
  "#{attribute}="
255
257
  end
256
258
 
257
- def style=(styles)
258
- styles.each do |attribute, value|
259
- apply_style(attribute => value)
259
+ def style=(style_or_styles)
260
+ if style_or_styles.is_a? String
261
+ @tk.style(style_or_styles)
262
+ else
263
+ style_or_styles.each do |attribute, value|
264
+ apply_style(attribute => value)
265
+ end
260
266
  end
261
267
  end
262
-
268
+
263
269
  def grid(options = {})
270
+ @_visible = true
264
271
  options = options.stringify_keys
265
272
  options['rowspan'] = options.delete('row_span') if options.keys.include?('row_span')
266
273
  options['columnspan'] = options.delete('column_span') if options.keys.include?('column_span')
@@ -273,13 +280,17 @@ module Glimmer
273
280
  options['columnminsize'] = options.delete('column_minsize') if options.keys.include?('column_minsize')
274
281
  options['columnminsize'] = options.delete('minwidth') if options.keys.include?('minwidth')
275
282
  options['columnminsize'] = options.delete('min_width') if options.keys.include?('min_width')
276
- options['columnminsize'] = options['rowminsize'] = options.delete('minsize') if options.keys.include?('minsize')
283
+ options['columnminsize'] = options['rowminsize'] = options.delete('minsize') if options.keys.include?('minsize')
284
+ options['rowuniform'] = options.delete('row_uniform') || options.delete('rowuniform')
285
+ options['columnuniform'] = options.delete('column_uniform') || options.delete('columnuniform')
277
286
  index_in_parent = griddable_parent_proxy&.children&.index(griddable_proxy)
278
287
  if index_in_parent
279
288
  TkGrid.rowconfigure(griddable_parent_proxy.tk, index_in_parent, 'weight'=> options.delete('rowweight')) if options.keys.include?('rowweight')
280
289
  TkGrid.rowconfigure(griddable_parent_proxy.tk, index_in_parent, 'minsize'=> options.delete('rowminsize')) if options.keys.include?('rowminsize')
290
+ TkGrid.rowconfigure(griddable_parent_proxy.tk, index_in_parent, 'uniform'=> options.delete('rowuniform')) if options.keys.include?('rowuniform')
281
291
  TkGrid.columnconfigure(griddable_parent_proxy.tk, index_in_parent, 'weight'=> options.delete('columnweight')) if options.keys.include?('columnweight')
282
292
  TkGrid.columnconfigure(griddable_parent_proxy.tk, index_in_parent, 'minsize'=> options.delete('columnminsize')) if options.keys.include?('columnminsize')
293
+ TkGrid.columnconfigure(griddable_parent_proxy.tk, index_in_parent, 'uniform'=> options.delete('columnuniform')) if options.keys.include?('columnuniform')
283
294
  end
284
295
  griddable_proxy&.tk&.grid(options)
285
296
  end
@@ -297,6 +308,7 @@ module Glimmer
297
308
  end
298
309
 
299
310
  def destroy
311
+ children.each(&:destroy)
300
312
  unbind_all
301
313
  @tk.destroy
302
314
  @on_destroy_procs&.each {|p| p.call(@tk)}
@@ -410,6 +422,10 @@ module Glimmer
410
422
  getter: {name: 'text', invoker: lambda { |widget, args| @tk.title }},
411
423
  setter: {name: 'text=', invoker: lambda { |widget, args| @tk.title = args.first }},
412
424
  },
425
+ 'icon_photo' => {
426
+ getter: {name: 'icon_photo', invoker: lambda { |widget, args| @tk.iconphoto }},
427
+ setter: {name: 'icon_photo=', invoker: lambda { |widget, args| @tk.iconphoto = image_argument(args) }},
428
+ },
413
429
  },
414
430
  }
415
431
  end
@@ -480,7 +496,15 @@ module Glimmer
480
496
  },
481
497
  ::Tk::Tile::TRadiobutton => {
482
498
  'variable' => lambda do |observer|
499
+ # tk.command is called only when the radiobutton is clicked/selected
500
+ # it isn't called when other radiobutton in the group is clicked/selected == this radiobutton is deselected
501
+ # so, we need to call the observers of the deselected radiobuttons in order for their variables to be reset to false
483
502
  @tk.command {
503
+ if @tk.variable.value == @tk.value
504
+ sibling_radio_buttons.each do |sibling_radio_button|
505
+ sibling_radio_button.tk.command.call
506
+ end
507
+ end
484
508
  observer.call(@tk.variable.value == @tk.value)
485
509
  }
486
510
  end,
@@ -547,21 +571,81 @@ module Glimmer
547
571
  def on(listener_name, &listener)
548
572
  handle_listener(listener_name, &listener)
549
573
  end
550
-
574
+
575
+ def event_generate(event_name, data = nil)
576
+ data = YAML.dump(data) if data && !data.is_a?(String)
577
+ tk.event_generate("<#{event_name}>", data: data)
578
+ end
579
+
551
580
  def unbind_all
552
581
  @listeners&.keys&.each do |key|
553
582
  if key.to_s.downcase.include?('command')
554
583
  @tk.send(key, '')
555
584
  else
556
- @tk.bind(key, '')
585
+ @tk.bind_remove(key)
557
586
  end
558
587
  end
588
+ @listeners = nil
559
589
  end
560
-
590
+
591
+ def clear_children
592
+ children.each(&:destroy)
593
+ @children = []
594
+ end
595
+
561
596
  def content(&block)
562
597
  Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Tk::WidgetExpression.new, keyword, *args, &block)
563
598
  end
564
599
 
600
+ def window?
601
+ false
602
+ end
603
+
604
+ def visible
605
+ @visible = true if @visible.nil?
606
+ @visible
607
+ end
608
+ alias visible? visible
609
+
610
+ def visible=(value)
611
+ value = !!value
612
+ return if visible == value
613
+
614
+ if value
615
+ grid
616
+ else
617
+ tk.grid_remove
618
+ end
619
+ @visible = value
620
+ end
621
+
622
+ def hidden
623
+ !visible
624
+ end
625
+ alias hidden? hidden
626
+
627
+ def hidden=(value)
628
+ self.visible = !value
629
+ end
630
+
631
+ def enabled
632
+ tk.state == 'normal'
633
+ end
634
+ alias enabled? enabled
635
+
636
+ def enabled=(value)
637
+ tk.state = !!value ? 'normal' : 'disabled'
638
+ end
639
+
640
+ def disabled
641
+ !enabled
642
+ end
643
+ alias disabled? disabled
644
+
645
+ def disabled=(value)
646
+ self.enabled = !value
647
+ end
648
+
565
649
  def method_missing(method, *args, &block)
566
650
  method = method.to_s
567
651
  attribute_name = method.sub(/=$/, '')
@@ -62,7 +62,7 @@ root { |w|
62
62
  # initialcolor is optional (defaults to 'white').
63
63
  # It can be a built-in color (e.g. 'AliceBlue') or hex (e.g. '#FFFF00')
64
64
  # Full list of built-in colors is at: https://tcl.tk/man/tcl8.6/TkCmd/colors.htm
65
- chosen_color = choose_color(parent: w, title: 'Choose Color', initialcolor: '#FFFF00')
65
+ chosen_color = choose_color(parent: w, title: 'Choose Color', initial_color: '#FFFF00')
66
66
  @result_label.text = chosen_color
67
67
  end
68
68
  }
@@ -25,7 +25,7 @@ include Glimmer
25
25
 
26
26
  root { |r|
27
27
  title 'Hello, Root!'
28
- iconphoto File.expand_path('../../icons/glimmer.png', __dir__)
28
+ icon_photo File.expand_path('../../icons/glimmer.png', __dir__)
29
29
  width 400
30
30
  height 200
31
31
  x -150
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-tk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.61
4
+ version: 0.0.63
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-27 00:00:00.000000000 Z
11
+ date: 2024-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -302,7 +302,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
302
302
  - !ruby/object:Gem::Version
303
303
  version: '0'
304
304
  requirements: []
305
- rubygems_version: 3.3.1
305
+ rubygems_version: 3.5.3
306
306
  signing_key:
307
307
  specification_version: 4
308
308
  summary: Glimmer DSL for Tk