glimmer-dsl-tk 0.0.62 → 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: b6a4152765e0997cd3d29beec05f16be105a09ae868e49335fb09e81d552e576
4
- data.tar.gz: 31c3f1d4ee33b5ab9dec7ccd76d11a6c50cde145cf3a5517401859b0ae16a45a
3
+ metadata.gz: 68fb65641bc77c179c7600d37210817eadd271de99aeb0ed8ca6bd7c3c5716b3
4
+ data.tar.gz: 40be5cb8a31b5a8284a8c3a208e6ccee512df2d42d051db3fdb9c7fc0041554a
5
5
  SHA512:
6
- metadata.gz: 7f4820bb0d35553b16fc9b37bfca7d2abdc463cbd2e958f462b5be5c53e79e7ae3abc918fa2bbc6775d642432b127fa3d26ff72d96195287fecd287e13a50a23
7
- data.tar.gz: 6f5b093cd7f834e6d8126142d5f63e66dde7c164b463eee577cd8b177d27784335d3f2df88555ce103c68a29eaed72ab1ec1e608018e8b76655c9704e77c0826
6
+ metadata.gz: 002fe595bd7e763629bd42c63f1ac9b004388dab953e3bb3b764582b623befff82cc17009a9277f75f314621b7e8fb393efe9595dcda3ecf83389f0a0c95d204
7
+ data.tar.gz: 5f31f46283e9170bd5459514f4406b829cb718d3bb068a35f3983fcd9e6e29142a4d15bbffd9c60b59dbb135f40ce982f48b2d14561df7e8c5a8fb8f4d986693
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
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
+
3
19
  ## 0.0.62
4
20
 
5
21
  - `icon_photo` as alias for `iconphoto` attribute on `root` and `toplevel`
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.62
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.62'
185
+ gem 'glimmer-dsl-tk', '0.0.63'
199
186
  ```
200
187
 
201
188
  And, then run:
@@ -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.62
1
+ 0.0.63
Binary file
@@ -32,19 +32,47 @@ 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)
@@ -125,18 +153,68 @@ module Glimmer
125
153
  super
126
154
  end
127
155
  end
128
-
156
+
129
157
  def center_within_screen
130
158
  monitor_width, monitor_height = wm_maxsize
131
159
  update :idletasks
132
160
  current_width = width
133
161
  current_height = height
134
- self.x = (winfo_screenwidth - width) / 2
135
- 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
+
136
189
  self.width = width
137
190
  self.height = height
138
191
  end
139
-
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
+
140
218
  private
141
219
 
142
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)}
@@ -484,7 +496,15 @@ module Glimmer
484
496
  },
485
497
  ::Tk::Tile::TRadiobutton => {
486
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
487
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
488
508
  observer.call(@tk.variable.value == @tk.value)
489
509
  }
490
510
  end,
@@ -551,21 +571,81 @@ module Glimmer
551
571
  def on(listener_name, &listener)
552
572
  handle_listener(listener_name, &listener)
553
573
  end
554
-
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
+
555
580
  def unbind_all
556
581
  @listeners&.keys&.each do |key|
557
582
  if key.to_s.downcase.include?('command')
558
583
  @tk.send(key, '')
559
584
  else
560
- @tk.bind(key, '')
585
+ @tk.bind_remove(key)
561
586
  end
562
587
  end
588
+ @listeners = nil
563
589
  end
564
-
590
+
591
+ def clear_children
592
+ children.each(&:destroy)
593
+ @children = []
594
+ end
595
+
565
596
  def content(&block)
566
597
  Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Tk::WidgetExpression.new, keyword, *args, &block)
567
598
  end
568
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
+
569
649
  def method_missing(method, *args, &block)
570
650
  method = method.to_s
571
651
  attribute_name = method.sub(/=$/, '')
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.62
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-30 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