glimmer-dsl-tk 0.0.41 → 0.0.45
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +126 -63
- data/VERSION +1 -1
- data/glimmer-dsl-tk.gemspec +0 -0
- data/lib/glimmer/dsl/tk/list_selection_data_binding_expression.rb +1 -1
- data/lib/glimmer/tk/drag_and_drop_extension.rb +39 -9
- data/lib/glimmer/tk/lbl_proxy.rb +33 -0
- data/lib/glimmer/tk/menu_proxy.rb +7 -6
- data/lib/glimmer/tk/root_proxy.rb +1 -1
- data/lib/glimmer/tk/scrollbar_frame_proxy.rb +1 -1
- data/lib/glimmer/tk/widget.rb +28 -0
- data/lib/glimmer/tk/widget_proxy.rb +25 -5
- data/lib/glimmer-dsl-tk.rb +4 -3
- data/lib/os.rb +36 -0
- data/samples/elaborate/meta_sample.rb +10 -0
- data/samples/hello/hello_drag_and_drop.rb +112 -61
- data/samples/hello/hello_menu_bar.rb +3 -8
- data/samples/hello/hello_text.rb +2 -7
- metadata +6 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a9655c46ab2b4638e96077e0795a6b7201456baf020ade27838d139797d3a44
|
4
|
+
data.tar.gz: dc2b2924a180df216a16161aa938b4429f814a59f18e0fba945b73eb40513bd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cab872767a730b059ebdaee18a124f0ded5e9fa0d5f980592b2c9fc9a20d756894846a4662b1f20043108987424daf6b79f895df639d1e273b66cad90f8437ae
|
7
|
+
data.tar.gz: 5a92bbe321b0ca538fbebc84d5e076047b2a761294f47be236f041853873c60787ce593dd142e7a5ba9671b9cdc7faaf1ca6d9f41c9a45fed1dde8cc55b5f184
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.0.45
|
4
|
+
|
5
|
+
- Support `lbl` widget as the non-tile-themed version of `label` (i.e. `::TkLabel` not `::Tk::Tile::TLabel`)
|
6
|
+
- Add `#proxy` method to all Tk widgets to return Glimmer widget proxy objects (e.g. `Tk::Tile::TButton#proxy` returns `Glimmer::Tk::WidgetProxy` object)
|
7
|
+
- Provide question mark alias of `event.drop_accepted` (i.e. `drop_accepted?`)
|
8
|
+
- Have `DragAndDropEvent` `source`/`target` be the enhanced Glimmer widget proxy instead of the unenhanced Tk widget
|
9
|
+
- Look into improving code that uses `TkLabel` explicitly in Hello, Drag and Drop! (do `event.tooltip.content {label {...} }` with Glimmer DSL instead)
|
10
|
+
- Add Glimmer Style Guide
|
11
|
+
- Fix issue with dropping button and list unto checkbox in Hello, Drag and Drop!
|
12
|
+
|
13
|
+
## 0.0.44
|
14
|
+
|
15
|
+
- Fix issue with not being able to drop list into checkbox in Hello, Drag and Drop! by disabling functionality for list just like button
|
16
|
+
|
17
|
+
## 0.0.43
|
18
|
+
|
19
|
+
- Modified Hello, Drag and Drop! to include a list
|
20
|
+
- Removed the need to require `'glimmer/tk/drag_and_drop_extension'` to do drag and drop; it is automatically included in `require 'glimmer-dsl-tk'` now.
|
21
|
+
- Remove 'os' gem due to Tk having the capability to detect the OS it is on using `Tk.windowingsystem` (include Glimmer implementation of `OS` class having `OS.mac?`, `OS.windows?` and `OS.linux?`)
|
22
|
+
- Default to 'clam' Tk theme on Linux ('alt' looks a bit too classic with certain widgets)
|
23
|
+
|
24
|
+
## 0.0.42
|
25
|
+
|
26
|
+
- Add vertical/horizontal scrollbars to Meta-Sample
|
27
|
+
- Keep only vertical scrollbar in Hello, Text!
|
28
|
+
- Fix issue with including bwidgets and iwidgets in Windows (by removing from default requires, leaving to users to require manually when needed only and only systems that support them)
|
29
|
+
- Fix Hello, Menu Bar! sample in Windows (by disabling Windows-special System menu, which does not seem to be working in Tk)
|
30
|
+
|
3
31
|
## 0.0.41
|
4
32
|
|
5
33
|
- Support `scrollbar_frame` Glimmer custom widget as a frame that automatically provides scrollbars when its content's size exceeds its size
|
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.
|
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.45
|
2
2
|
## MRI Ruby 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)
|
@@ -100,6 +100,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
100
100
|
- [Radiobutton Data-Binding](#radiobutton-data-binding)
|
101
101
|
- [Command Callback](#command-callback)
|
102
102
|
- [Gotchas](#gotchas)
|
103
|
+
- [Glimmer Style Guide](#glimmer-style-guide)
|
103
104
|
- [Samples](#samples)
|
104
105
|
- [Hello, World!](#hello-world)
|
105
106
|
- [Hello, Button!](#hello-button)
|
@@ -181,7 +182,7 @@ gem install glimmer-dsl-tk
|
|
181
182
|
|
182
183
|
Add the following to `Gemfile`:
|
183
184
|
```
|
184
|
-
gem 'glimmer-dsl-tk', '
|
185
|
+
gem 'glimmer-dsl-tk', '0.0.45'
|
185
186
|
```
|
186
187
|
|
187
188
|
And, then run:
|
@@ -225,6 +226,8 @@ The Glimmer GUI DSL follows these simple concepts in mapping from Tk syntax:
|
|
225
226
|
- **Content/Options Block**: Any keyword may optionally be followed by a Ruby curly-brace block containing nested widgets (content) and attributes (options). Attributes are simply Tk option keywords followed by arguments and no block (e.g. `title 'Hello, World!'` under a `root`)
|
226
227
|
- **Event Binding Block**: `on(event) {}` keyword receiving a Tk binding event name (e.g. `KeyPress` or `ComboboxSelected`). Surrounding event by `<>` is optional as [Glimmer DSL for Tk](https://rubygems.org/gems/glimmer-dsl-tk) can take care of that automatically.
|
227
228
|
|
229
|
+
Note that Glimmer widgets are proxy objects (wrappers) for Tk widgets. To get wrapped Tk widget from a Glimmer widget, you simply invoke `#tk` method. To get the proxy of a wrapped Tk widget, you may invoke `#proxy` method.
|
230
|
+
|
228
231
|
Example of an app written in [Tk](https://www.tcl.tk/) imperative syntax:
|
229
232
|
|
230
233
|
```ruby
|
@@ -303,6 +306,7 @@ keyword(args) | attributes | event bindings & callbacks
|
|
303
306
|
`spinbox` | `text`, `from`, `to`, `increment`, `format`, [more attributes](https://tcl.tk/man/tcl8.6/TkCmd/text.htm#M116) | `command {}`, `'increment'`, `'decrement'`
|
304
307
|
`frame(text: nil)` | `width`, `height`, `borderwidth`, `relief` (`'flat' (default), 'raised', 'sunken', 'solid', 'ridge', 'groove'`) | None
|
305
308
|
`label` | `text`, `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `font` (`'default', 'text', 'fixed', 'menu', 'heading', 'caption', 'small_caption', 'icon', 'tooltip'`), `relief` (`'flat' (default), 'raised', 'sunken', 'solid', 'ridge', 'groove'`), `justify` (`'left', 'center', 'right'`), `foreground`, `background` | None
|
309
|
+
`lbl` (non-theme version of `label`) | `text`, `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `font` (`'default', 'text', 'fixed', 'menu', 'heading', 'caption', 'small_caption', 'icon', 'tooltip'`), `relief` (`'flat' (default), 'raised', 'sunken', 'solid', 'ridge', 'groove'`), `justify` (`'left', 'center', 'right'`), `foreground`, `background`, `bg`, `bitmap`, [more here](https://tcl.tk/man/tcl8.6/TkCmd/label.htm) | None
|
306
310
|
`list` | `selectmode`, `selection` | None
|
307
311
|
`message_box(type: , message: , detail: , title: , icon: , default: , parent: )` | None | None
|
308
312
|
`menu(label: nil) (label is nil if nested under root/toplevel for menu bar)` | None | None
|
@@ -824,6 +828,14 @@ More details can be found in the [Hello, Button!](#hello-button) sample below.
|
|
824
828
|
|
825
829
|
- Setting `background` attribute on `frame` or `label` does not work in `'aqua'` theme on the Mac (only in `'classic'` theme)
|
826
830
|
|
831
|
+
## Glimmer Style Guide
|
832
|
+
|
833
|
+
- Widget arguments are always wrapped by parentheses.
|
834
|
+
- Widget blocks are always declared with curly braces `{}` to clearly visualize hierarchical view code and separate from logic code.
|
835
|
+
- Widget attribute declarations always have arguments that are never wrapped inside parentheses and never take a block.
|
836
|
+
- Widget listeners are always declared with `on` keyword receiving listener event name as an argument. Their multi-line blocks have a `do; end` style to distinguish as logic from widget keywords and attributes.
|
837
|
+
- Pure logic multi-line blocks that do not constitute GUI DSL view elements in general always have `do; end` style to clearly separate logic code from view code.
|
838
|
+
|
827
839
|
## Samples
|
828
840
|
|
829
841
|
The easiest way to run samples is by launching the Glimmer Meta-Sample (the Sample of Samples).
|
@@ -2683,140 +2695,191 @@ Glimmer app:
|
|
2683
2695
|
Glimmer code (from [samples/hello/hello_drag_and_drop.rb](samples/hello/hello_drag_and_drop.rb)):
|
2684
2696
|
|
2685
2697
|
```ruby
|
2686
|
-
require
|
2687
|
-
require "glimmer/tk/drag_and_drop_extension"
|
2698
|
+
require 'glimmer-dsl-tk'
|
2688
2699
|
|
2689
2700
|
include Glimmer
|
2690
2701
|
|
2691
2702
|
root {
|
2692
2703
|
title "Hello, Drag and Drop!"
|
2704
|
+
|
2693
2705
|
frame {
|
2694
2706
|
padding 5
|
2707
|
+
|
2695
2708
|
labelframe {
|
2696
2709
|
text "Drag sources"
|
2697
2710
|
padding 5
|
2711
|
+
|
2698
2712
|
label {
|
2699
|
-
text "Entry"
|
2700
2713
|
grid :row => 0, :column => 0
|
2714
|
+
text "Label"
|
2715
|
+
}
|
2716
|
+
label {
|
2717
|
+
grid :row => 0, :column => 1, :pady => 10, :sticky => "e"
|
2718
|
+
text "Drag label text"
|
2719
|
+
width 30
|
2720
|
+
drag_source true
|
2721
|
+
}
|
2722
|
+
|
2723
|
+
label {
|
2724
|
+
grid :row => 1, :column => 0
|
2725
|
+
text "Entry"
|
2701
2726
|
}
|
2702
2727
|
entry {
|
2728
|
+
grid :row => 1, :column => 1, :pady => 5, :sticky => "e"
|
2703
2729
|
text "Drag entry text"
|
2704
2730
|
width 30
|
2705
|
-
|
2706
|
-
|
2707
|
-
|
2731
|
+
|
2732
|
+
# This is how to do `drag_source true` the manual way for use in exceptional cases
|
2733
|
+
on_drag_start do |event|
|
2734
|
+
event.data = event.source.text
|
2708
2735
|
event.source.configure(:cursor => "hand2")
|
2709
|
-
|
2710
|
-
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
|
-
|
2716
|
-
|
2717
|
-
|
2736
|
+
event.tooltip.content {
|
2737
|
+
lbl { # non-tile-theme version of label
|
2738
|
+
text event.data + " "
|
2739
|
+
bg "yellow"
|
2740
|
+
bitmap "warning"
|
2741
|
+
compound "right"
|
2742
|
+
}
|
2743
|
+
}
|
2744
|
+
end
|
2745
|
+
on_drag_motion do |event|
|
2746
|
+
if event.drop_accepted?
|
2718
2747
|
event.source.configure(:cursor => "hand1")
|
2719
2748
|
else
|
2720
2749
|
event.source.configure(:cursor => "hand2")
|
2721
2750
|
end
|
2722
2751
|
event.tooltip.geometry("+#{event.x_root + 10}+#{event.y_root - 4}")
|
2723
|
-
|
2724
|
-
}
|
2725
|
-
label {
|
2726
|
-
text "Label"
|
2727
|
-
grid :row => 1, :column => 0
|
2728
|
-
}
|
2729
|
-
label {
|
2730
|
-
text "Drag label text"
|
2731
|
-
width 30
|
2732
|
-
grid :row => 1, :column => 1, :pady => 10, :sticky => "e"
|
2733
|
-
drag_source true
|
2752
|
+
end
|
2734
2753
|
}
|
2754
|
+
|
2735
2755
|
label {
|
2736
|
-
text "Combobox"
|
2737
2756
|
grid :row => 2, :column => 0
|
2757
|
+
text "Combobox"
|
2738
2758
|
}
|
2739
2759
|
combobox {
|
2760
|
+
grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
|
2740
2761
|
text "Spain"
|
2741
2762
|
values %w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
|
2742
2763
|
width 27
|
2743
|
-
|
2744
|
-
on_drag_start
|
2745
|
-
event.data = event.source.
|
2746
|
-
|
2764
|
+
|
2765
|
+
on_drag_start do |event|
|
2766
|
+
event.data = event.source.text
|
2767
|
+
end
|
2747
2768
|
}
|
2769
|
+
|
2748
2770
|
label {
|
2749
|
-
text "Button"
|
2750
2771
|
grid :row => 3, :column => 0
|
2772
|
+
text 'List'
|
2773
|
+
}
|
2774
|
+
list {
|
2775
|
+
grid :row => 3, :column => 1, :pady => 5, :sticky => "e"
|
2776
|
+
selectmode 'browse'
|
2777
|
+
items %w[USA Canada Mexico]
|
2778
|
+
selection 'Canada'
|
2779
|
+
height 3
|
2780
|
+
|
2781
|
+
on_drag_start do |event|
|
2782
|
+
event.data = event.source.selection.first
|
2783
|
+
end
|
2784
|
+
}
|
2785
|
+
|
2786
|
+
label {
|
2787
|
+
grid :row => 4, :column => 0
|
2788
|
+
text "Button"
|
2751
2789
|
}
|
2752
2790
|
button {
|
2791
|
+
grid :row => 4, :column => 1, :pady => 5, :sticky => "w"
|
2753
2792
|
text "Drag it"
|
2754
|
-
grid :row => 3, :column => 1, :pady => 5, :sticky => "w"
|
2755
2793
|
drag_source true
|
2756
2794
|
}
|
2757
2795
|
}
|
2758
2796
|
|
2759
2797
|
labelframe {
|
2760
|
-
text "Drop targets"
|
2761
2798
|
grid :sticky => "nsew", :pady => 15
|
2799
|
+
text "Drop targets"
|
2762
2800
|
padding 5
|
2801
|
+
|
2763
2802
|
label {
|
2764
|
-
text "Entry"
|
2765
2803
|
grid :row => 0, :column => 0
|
2804
|
+
text "Label"
|
2766
2805
|
}
|
2767
|
-
|
2806
|
+
label {
|
2807
|
+
grid :row => 0, :column => 1, :pady => 10, :sticky => "e"
|
2768
2808
|
width 30
|
2769
|
-
|
2770
|
-
|
2771
|
-
|
2772
|
-
|
2809
|
+
borderwidth 2
|
2810
|
+
relief "solid"
|
2811
|
+
|
2812
|
+
on_drop do |event|
|
2813
|
+
event.target.text = event.data
|
2814
|
+
end
|
2773
2815
|
}
|
2816
|
+
|
2774
2817
|
label {
|
2775
|
-
text "Label"
|
2776
2818
|
grid :row => 1, :column => 0
|
2819
|
+
text "Entry"
|
2777
2820
|
}
|
2778
|
-
|
2821
|
+
entry {
|
2822
|
+
grid :row => 1, :column => 1, :pady => 5, :sticky => "e"
|
2779
2823
|
width 30
|
2780
|
-
|
2781
|
-
borderwidth 2
|
2782
|
-
relief "solid"
|
2824
|
+
|
2783
2825
|
on_drop { |event|
|
2784
|
-
event.target.
|
2826
|
+
event.target.text = event.data
|
2785
2827
|
}
|
2786
2828
|
}
|
2829
|
+
|
2787
2830
|
label {
|
2788
|
-
text "Combobox"
|
2789
2831
|
grid :row => 2, :column => 0
|
2832
|
+
text "Combobox"
|
2790
2833
|
}
|
2791
2834
|
combobox {
|
2792
|
-
width 27
|
2793
2835
|
grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
|
2794
|
-
|
2795
|
-
|
2796
|
-
|
2836
|
+
width 27
|
2837
|
+
|
2838
|
+
on_drop do |event|
|
2839
|
+
event.target.text = event.data
|
2840
|
+
end
|
2797
2841
|
}
|
2842
|
+
|
2798
2843
|
label {
|
2799
|
-
text "Button"
|
2800
2844
|
grid :row => 3, :column => 0
|
2845
|
+
text 'List'
|
2846
|
+
}
|
2847
|
+
list {
|
2848
|
+
grid :row => 3, :column => 1, :pady => 5, :sticky => "e"
|
2849
|
+
selectmode 'browse'
|
2850
|
+
height 3
|
2851
|
+
|
2852
|
+
on_drop do |event|
|
2853
|
+
event.target.items += [event.data]
|
2854
|
+
end
|
2855
|
+
}
|
2856
|
+
|
2857
|
+
label {
|
2858
|
+
grid :row => 4, :column => 0
|
2859
|
+
text "Button"
|
2801
2860
|
}
|
2802
2861
|
button {
|
2862
|
+
grid :row => 4, :column => 1, :pady => 5, :sticky => "w"
|
2803
2863
|
text "Drop here"
|
2804
|
-
|
2805
|
-
on_drop
|
2864
|
+
|
2865
|
+
on_drop do |event|
|
2806
2866
|
event.target.text = event.data
|
2807
|
-
|
2867
|
+
end
|
2808
2868
|
}
|
2869
|
+
|
2809
2870
|
label {
|
2871
|
+
grid :row => 5, :column => 0
|
2810
2872
|
text "Checkbutton"
|
2811
|
-
grid :row => 4, :column => 0
|
2812
2873
|
}
|
2813
2874
|
checkbutton {
|
2814
|
-
|
2815
|
-
|
2816
|
-
|
2875
|
+
grid :row => 5, :column => 1, :pady => 5, :sticky => "w"
|
2876
|
+
text "Drop here to destroy a widget"
|
2877
|
+
|
2878
|
+
on_drop do |event|
|
2817
2879
|
event.target.text = event.data
|
2818
|
-
|
2819
|
-
|
2880
|
+
# execute asynchronously after 100ms to ensure all events have been processed before destruction
|
2881
|
+
::Tk.after(100) {event.source.destroy}
|
2882
|
+
end
|
2820
2883
|
}
|
2821
2884
|
}
|
2822
2885
|
}
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.45
|
data/glimmer-dsl-tk.gemspec
CHANGED
Binary file
|
@@ -50,7 +50,7 @@ module Glimmer
|
|
50
50
|
#TODO check if nested data binding works for list widget and other widgets that need custom data binding
|
51
51
|
list_selection_binding.observe(model, model_binding.property_name_expression)
|
52
52
|
|
53
|
-
parent.
|
53
|
+
parent.on('<TreeviewSelect>') do
|
54
54
|
model_binding.call(list_selection_binding.evaluate_property)
|
55
55
|
end
|
56
56
|
end
|
@@ -1,3 +1,24 @@
|
|
1
|
+
# Copyright (c) 2020-2021 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
1
22
|
require "json"
|
2
23
|
|
3
24
|
module Glimmer
|
@@ -23,7 +44,7 @@ module Glimmer
|
|
23
44
|
@on_drop_block = value
|
24
45
|
self.tk.bind("<DropEvent>", proc { |tk_event|
|
25
46
|
drop_event = DragAndDropEvent.json_create(JSON.parse("{" + tk_event.detail + "}"))
|
26
|
-
@on_drop_block.call(drop_event) if self
|
47
|
+
@on_drop_block.call(drop_event) if self == drop_event.target
|
27
48
|
})
|
28
49
|
self.tk.bind("<DropCheckEvent>", proc { |tk_event|
|
29
50
|
drop_check_event = DragAndDropEvent.json_create(JSON.parse("{" + tk_event.detail + "}"))
|
@@ -40,23 +61,30 @@ module Glimmer
|
|
40
61
|
bind("<DropAcceptedEvent>", proc { |event| drag_event.drop_accepted = true })
|
41
62
|
bind("B1-Motion", proc { |tk_event|
|
42
63
|
if drag_event.nil?
|
43
|
-
tooltip =
|
64
|
+
tooltip = WidgetProxy.new('toplevel', root_parent_proxy, [])
|
65
|
+
tooltip.overrideredirect(1) #create tooltip window to display dragged data
|
44
66
|
tooltip.geometry("+#{tk_event.x_root + 10}+#{tk_event.y_root - 2}")
|
45
|
-
drag_event = DragAndDropEvent.new(self
|
67
|
+
drag_event = DragAndDropEvent.new(self, nil, tooltip, tk_event.x_root, tk_event.y_root, nil, false)
|
46
68
|
if @drag_source
|
47
69
|
tk_event.widget.configure(:cursor => "hand2")
|
48
70
|
# Default data to drag is text
|
49
71
|
drag_event.data = if textvariable_defined? then tk.textvariable.value elsif has_attribute?(:text) then tk.text end
|
50
|
-
|
72
|
+
tooltip_label = WidgetProxy.new('label', tooltip, [])
|
73
|
+
tooltip_label.text = drag_event.data
|
74
|
+
tooltip_label.pack # TODO look into using grid instead to be consistent with the modern Tk way
|
51
75
|
elsif !@on_drag_start_block.nil?
|
52
76
|
@on_drag_start_block.call(drag_event)
|
53
|
-
|
77
|
+
if tooltip.winfo_children().length == 0
|
78
|
+
tooltip_label = WidgetProxy.new('label', tooltip, [])
|
79
|
+
tooltip_label.text = drag_event.data
|
80
|
+
tooltip_label.pack # TODO look into using grid instead to be consistent with the modern Tk way
|
81
|
+
end
|
54
82
|
end
|
55
83
|
else
|
56
84
|
drag_event.x_root, drag_event.y_root = tk_event.x_root, tk_event.y_root
|
57
85
|
drag_event.drop_accepted = false
|
58
86
|
move_over_widget = tk_event.widget.winfo_containing(tk_event.x_root, tk_event.y_root)
|
59
|
-
drag_event.target = move_over_widget
|
87
|
+
drag_event.target = move_over_widget.proxy
|
60
88
|
move_over_widget.event_generate("<DropCheckEvent>", :data => drag_event.to_json)
|
61
89
|
if @on_drag_motion_block.nil?
|
62
90
|
# Default motion behavior:
|
@@ -75,7 +103,7 @@ module Glimmer
|
|
75
103
|
})
|
76
104
|
bind("ButtonRelease-1", proc { |tk_event|
|
77
105
|
if drag_event
|
78
|
-
drag_event.target = tk_event.widget.winfo_containing(tk_event.x_root, tk_event.y_root)
|
106
|
+
drag_event.target = tk_event.widget.winfo_containing(tk_event.x_root, tk_event.y_root).proxy
|
79
107
|
drag_event.source.configure(:cursor => "")
|
80
108
|
drag_event.target.event_generate("<DropEvent>", :data => drag_event.to_json)
|
81
109
|
drag_event.tooltip.destroy
|
@@ -91,6 +119,8 @@ module Glimmer
|
|
91
119
|
end
|
92
120
|
|
93
121
|
DragAndDropEvent = Struct.new(:source, :target, :tooltip, :x_root, :y_root, :data, :drop_accepted) do
|
122
|
+
alias drop_accepted? drop_accepted
|
123
|
+
|
94
124
|
def as_json(*)
|
95
125
|
klass = self.class.name
|
96
126
|
{
|
@@ -104,9 +134,9 @@ module Glimmer
|
|
104
134
|
end
|
105
135
|
|
106
136
|
def self.json_create(object)
|
107
|
-
new(*[ObjectSpace._id2ref(object["v"][0]), ObjectSpace._id2ref(object["v"][1]), ObjectSpace._id2ref(object["v"][2])].concat(object["v"].drop 3))
|
137
|
+
new(*[ObjectSpace._id2ref(object["v"][0]), ObjectSpace._id2ref(object["v"][1]).proxy, ObjectSpace._id2ref(object["v"][2])].concat(object["v"].drop 3))
|
108
138
|
end
|
109
139
|
end
|
110
140
|
end
|
111
141
|
end
|
112
|
-
end
|
142
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Copyright (c) 2020-2021 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'glimmer/tk/widget_proxy'
|
23
|
+
|
24
|
+
module Glimmer
|
25
|
+
module Tk
|
26
|
+
# Non-Themable (non-Tile) Tk Label
|
27
|
+
class LblProxy < WidgetProxy
|
28
|
+
def build_widget
|
29
|
+
@tk = ::TkLabel.new(@parent_proxy.tk, *args).tap {|tk| tk.singleton_class.include(Glimmer::Tk::Widget); tk.proxy = self}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -63,19 +63,20 @@ module Glimmer
|
|
63
63
|
def build_widget
|
64
64
|
if application?
|
65
65
|
if OS.mac?
|
66
|
-
@tk = ::TkSysMenu_Apple.new(@parent_proxy.tk)
|
66
|
+
@tk = ::TkSysMenu_Apple.new(@parent_proxy.tk).tap {|tk| tk.singleton_class.include(Glimmer::Tk::Widget); tk.proxy = self}
|
67
67
|
@parent_proxy.tk.add :cascade, :menu => @tk
|
68
68
|
end
|
69
69
|
else
|
70
70
|
if @parent_proxy.parent_proxy.is_a?(ToplevelProxy) && (OS.mac? || OS.linux?) && help?
|
71
|
-
@tk = ::TkSysMenu_Help.new(@parent_proxy.tk)
|
71
|
+
@tk = ::TkSysMenu_Help.new(@parent_proxy.tk).tap {|tk| tk.singleton_class.include(Glimmer::Tk::Widget); tk.proxy = self}
|
72
72
|
elsif @parent_proxy.parent_proxy.is_a?(ToplevelProxy) && OS.mac? && window?
|
73
|
-
@tk = ::Tk::TkSysMenu_Window.new(@parent_proxy.tk)
|
74
|
-
|
75
|
-
|
73
|
+
@tk = ::Tk::TkSysMenu_Window.new(@parent_proxy.tk).tap {|tk| tk.singleton_class.include(Glimmer::Tk::Widget); tk.proxy = self}
|
74
|
+
# Windows system menu does not seem to work
|
75
|
+
# elsif @parent_proxy.parent_proxy.is_a?(ToplevelProxy) && OS.windows? && system?
|
76
|
+
# @tk = ::TkSysMenu_System.new(@parent_proxy.tk).tap {|tk| tk.singleton_class.include(Glimmer::Tk::Widget); tk.proxy = self}
|
76
77
|
else
|
77
78
|
tk_widget_class = self.class.tk_widget_class_for(@keyword)
|
78
|
-
@tk = tk_widget_class.new(@parent_proxy.tk)
|
79
|
+
@tk = tk_widget_class.new(@parent_proxy.tk).tap {|tk| tk.singleton_class.include(Glimmer::Tk::Widget); tk.proxy = self}
|
79
80
|
end
|
80
81
|
case @parent_proxy
|
81
82
|
when MenuProxy
|
@@ -28,7 +28,7 @@ module Glimmer
|
|
28
28
|
# Follows the Proxy Design Pattern
|
29
29
|
class RootProxy < ToplevelProxy
|
30
30
|
def initialize(*args, &block)
|
31
|
-
@tk = ::TkRoot.new
|
31
|
+
@tk = ::TkRoot.new.tap {|tk| tk.singleton_class.include(Glimmer::Tk::Widget); tk.proxy = self}
|
32
32
|
@tk.minsize = DEFAULT_WIDTH, DEFAULT_HEIGHT
|
33
33
|
initialize_defaults
|
34
34
|
post_add_content if block.nil?
|
@@ -103,7 +103,7 @@ module Glimmer
|
|
103
103
|
build_yscrollbar
|
104
104
|
build_xscrollbar
|
105
105
|
tk_widget_class = self.class.tk_widget_class_for('frame')
|
106
|
-
@tk = tk_widget_class.new(@canvas_proxy.tk, *args)
|
106
|
+
@tk = tk_widget_class.new(@canvas_proxy.tk, *args).tap {|tk| tk.singleton_class.include(Glimmer::Tk::Widget); tk.proxy = self}
|
107
107
|
TkcWindow.new(@canvas_proxy.tk, 0, 0, :anchor => "nw", :window => @tk)
|
108
108
|
end
|
109
109
|
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Copyright (c) 2020-2021 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
module Glimmer
|
23
|
+
module Tk
|
24
|
+
module Widget
|
25
|
+
attr_accessor :proxy
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -20,6 +20,7 @@
|
|
20
20
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
21
|
|
22
22
|
require 'glimmer/data_binding/tk/one_time_observer'
|
23
|
+
require 'glimmer/tk/widget'
|
23
24
|
|
24
25
|
module Glimmer
|
25
26
|
module Tk
|
@@ -49,10 +50,10 @@ module Glimmer
|
|
49
50
|
# TODO consider exposing this via Glimmer::Config
|
50
51
|
potential_tk_widget_class_names = [
|
51
52
|
"::Tk::Tile::#{tk_widget_class_basename}",
|
52
|
-
"::Tk::BWidget::#{tk_widget_class_basename}",
|
53
|
-
"::Tk::Iwidgets::#{tk_widget_class_basename}",
|
54
53
|
"::Tk#{tk_widget_class_basename}",
|
55
54
|
"::Tk::#{tk_widget_class_basename}",
|
55
|
+
"::Tk::BWidget::#{tk_widget_class_basename}",
|
56
|
+
"::Tk::Iwidgets::#{tk_widget_class_basename}",
|
56
57
|
"::Glimmer::Tk::#{tk_widget_class_basename}Proxy",
|
57
58
|
]
|
58
59
|
tk_widget_class = nil
|
@@ -70,7 +71,8 @@ module Glimmer
|
|
70
71
|
|
71
72
|
FONTS_PREDEFINED = %w[default text fixed menu heading caption small_caption icon tooltip]
|
72
73
|
|
73
|
-
attr_reader :parent_proxy, :tk, :args, :keyword, :children
|
74
|
+
attr_reader :parent_proxy, :tk, :args, :keyword, :children, :bind_ids, :destroyed
|
75
|
+
alias destroyed? destroyed
|
74
76
|
|
75
77
|
# Initializes a new Tk Widget
|
76
78
|
#
|
@@ -127,7 +129,7 @@ module Glimmer
|
|
127
129
|
end
|
128
130
|
|
129
131
|
def tk_widget_has_attribute_setter?(attribute)
|
130
|
-
return true if @tk.respond_to?(attribute)
|
132
|
+
return true if @tk.respond_to?(attribute) && attribute != 'focus' # TODO configure exceptions via constant if needed
|
131
133
|
result = nil
|
132
134
|
begin
|
133
135
|
# TK Widget currently doesn't support respond_to? properly, so I have to resort to this trick for now
|
@@ -288,8 +290,10 @@ module Glimmer
|
|
288
290
|
end
|
289
291
|
|
290
292
|
def destroy
|
293
|
+
unbind_all
|
291
294
|
@tk.destroy
|
292
295
|
@on_destroy_procs&.each {|p| p.call(@tk)}
|
296
|
+
@destroyed = true
|
293
297
|
end
|
294
298
|
|
295
299
|
def apply_style(options)
|
@@ -384,6 +388,7 @@ module Glimmer
|
|
384
388
|
if observer.is_a?(Glimmer::DataBinding::ModelBinding)
|
385
389
|
model = observer.model
|
386
390
|
options_model_property = observer.property_name + '_options'
|
391
|
+
# TODO perform data-binding to values too
|
387
392
|
@tk.values = model.send(options_model_property) if model.respond_to?(options_model_property)
|
388
393
|
end
|
389
394
|
@tk.bind('<ComboboxSelected>') {
|
@@ -490,6 +495,16 @@ module Glimmer
|
|
490
495
|
handle_listener(listener_name, &listener)
|
491
496
|
end
|
492
497
|
|
498
|
+
def unbind_all
|
499
|
+
@listeners&.keys&.each do |key|
|
500
|
+
if key.to_s.downcase.include?('command')
|
501
|
+
@tk.send(key, '')
|
502
|
+
else
|
503
|
+
@tk.bind(key, '')
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
493
508
|
def content(&block)
|
494
509
|
Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::Tk::WidgetExpression.new, keyword, *args, &block)
|
495
510
|
end
|
@@ -513,6 +528,11 @@ module Glimmer
|
|
513
528
|
!super_only && tk.respond_to?(method, *args, &block)
|
514
529
|
end
|
515
530
|
|
531
|
+
# inspect is overridden to prevent printing very long stack traces
|
532
|
+
def inspect
|
533
|
+
"#{super[0, 150]}... >"
|
534
|
+
end
|
535
|
+
|
516
536
|
private
|
517
537
|
|
518
538
|
# The griddable parent widget proxy to apply grid to (is different from @tk in composite widgets like notebook or scrolledframe)
|
@@ -527,7 +547,7 @@ module Glimmer
|
|
527
547
|
|
528
548
|
def build_widget
|
529
549
|
tk_widget_class = self.class.tk_widget_class_for(@keyword)
|
530
|
-
@tk = tk_widget_class.new(@parent_proxy.tk, *args)
|
550
|
+
@tk = tk_widget_class.new(@parent_proxy.tk, *args).tap {|tk| tk.singleton_class.include(Glimmer::Tk::Widget); tk.proxy = self}
|
531
551
|
end
|
532
552
|
|
533
553
|
def initialize_defaults
|
data/lib/glimmer-dsl-tk.rb
CHANGED
@@ -27,8 +27,8 @@ require 'glimmer'
|
|
27
27
|
require 'puts_debuggerer' if ENV['pd'].to_s.downcase == 'true'
|
28
28
|
# require 'super_module'
|
29
29
|
require 'tk'
|
30
|
-
require 'tkextlib/bwidget'
|
31
|
-
require 'tkextlib/iwidgets'
|
30
|
+
#require 'tkextlib/bwidget' # does not work on Windows
|
31
|
+
#require 'tkextlib/iwidgets' # does not work on Windows
|
32
32
|
require 'os'
|
33
33
|
require 'facets/hash/symbolize_keys'
|
34
34
|
require 'facets/string/underscore'
|
@@ -39,6 +39,7 @@ require 'delegate'
|
|
39
39
|
# require 'ext/glimmer/config'
|
40
40
|
# require 'ext/glimmer'
|
41
41
|
require 'glimmer/dsl/tk/dsl'
|
42
|
+
require 'glimmer/tk/drag_and_drop_extension'
|
42
43
|
|
43
44
|
Glimmer::Config.loop_max_count = -1
|
44
45
|
|
@@ -48,7 +49,7 @@ Glimmer::Config.excluded_keyword_checkers << lambda do |method_symbol, *args|
|
|
48
49
|
result ||= method == 'load_iseq'
|
49
50
|
end
|
50
51
|
|
51
|
-
Tk::Tile::Style.theme_use '
|
52
|
+
Tk::Tile::Style.theme_use 'clam' if OS.linux?
|
52
53
|
|
53
54
|
::TkOption.add '*tearOff', 0
|
54
55
|
|
data/lib/os.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright (c) 2020-2021 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
class OS
|
23
|
+
class << self
|
24
|
+
def mac?
|
25
|
+
Tk.windowingsystem == 'aqua'
|
26
|
+
end
|
27
|
+
|
28
|
+
def windows?
|
29
|
+
Tk.windowingsystem == 'win32'
|
30
|
+
end
|
31
|
+
|
32
|
+
def linux?
|
33
|
+
Tk.windowingsystem == 'x11'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -130,6 +130,16 @@ class MetaSample
|
|
130
130
|
grid row: 0, column: 1, column_weight: 1
|
131
131
|
value File.read(file_path_for(selected_sample))
|
132
132
|
}
|
133
|
+
|
134
|
+
@yscrollbar = scrollbar {
|
135
|
+
grid row: 0, column: 2
|
136
|
+
}
|
137
|
+
@code_text.yscrollbar @yscrollbar
|
138
|
+
|
139
|
+
@xscrollbar = scrollbar {
|
140
|
+
grid row: 1, column: 1, column_span: 2
|
141
|
+
}
|
142
|
+
@code_text.xscrollbar @xscrollbar
|
133
143
|
}
|
134
144
|
@root.open
|
135
145
|
end
|
@@ -19,140 +19,191 @@
|
|
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
|
23
|
-
require "glimmer/tk/drag_and_drop_extension"
|
22
|
+
require 'glimmer-dsl-tk'
|
24
23
|
|
25
24
|
include Glimmer
|
26
25
|
|
27
26
|
root {
|
28
27
|
title "Hello, Drag and Drop!"
|
28
|
+
|
29
29
|
frame {
|
30
30
|
padding 5
|
31
|
+
|
31
32
|
labelframe {
|
32
33
|
text "Drag sources"
|
33
34
|
padding 5
|
35
|
+
|
34
36
|
label {
|
35
|
-
text "Entry"
|
36
37
|
grid :row => 0, :column => 0
|
38
|
+
text "Label"
|
39
|
+
}
|
40
|
+
label {
|
41
|
+
grid :row => 0, :column => 1, :pady => 10, :sticky => "e"
|
42
|
+
text "Drag label text"
|
43
|
+
width 30
|
44
|
+
drag_source true
|
45
|
+
}
|
46
|
+
|
47
|
+
label {
|
48
|
+
grid :row => 1, :column => 0
|
49
|
+
text "Entry"
|
37
50
|
}
|
38
51
|
entry {
|
52
|
+
grid :row => 1, :column => 1, :pady => 5, :sticky => "e"
|
39
53
|
text "Drag entry text"
|
40
54
|
width 30
|
41
|
-
|
42
|
-
|
43
|
-
|
55
|
+
|
56
|
+
# This is how to do `drag_source true` the manual way for use in exceptional cases
|
57
|
+
on_drag_start do |event|
|
58
|
+
event.data = event.source.text
|
44
59
|
event.source.configure(:cursor => "hand2")
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
60
|
+
event.tooltip.content {
|
61
|
+
lbl { # non-tile-theme version of label
|
62
|
+
text event.data + " "
|
63
|
+
bg "yellow"
|
64
|
+
bitmap "warning"
|
65
|
+
compound "right"
|
66
|
+
}
|
67
|
+
}
|
68
|
+
end
|
69
|
+
on_drag_motion do |event|
|
70
|
+
if event.drop_accepted?
|
54
71
|
event.source.configure(:cursor => "hand1")
|
55
72
|
else
|
56
73
|
event.source.configure(:cursor => "hand2")
|
57
74
|
end
|
58
75
|
event.tooltip.geometry("+#{event.x_root + 10}+#{event.y_root - 4}")
|
59
|
-
|
60
|
-
}
|
61
|
-
label {
|
62
|
-
text "Label"
|
63
|
-
grid :row => 1, :column => 0
|
76
|
+
end
|
64
77
|
}
|
78
|
+
|
65
79
|
label {
|
66
|
-
text "Drag label text"
|
67
|
-
width 30
|
68
|
-
grid :row => 1, :column => 1, :pady => 10, :sticky => "e"
|
69
|
-
drag_source true
|
70
|
-
}
|
71
|
-
label {
|
72
|
-
text "Combobox"
|
73
80
|
grid :row => 2, :column => 0
|
81
|
+
text "Combobox"
|
74
82
|
}
|
75
83
|
combobox {
|
84
|
+
grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
|
76
85
|
text "Spain"
|
77
86
|
values %w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
|
78
87
|
width 27
|
79
|
-
|
80
|
-
on_drag_start
|
81
|
-
event.data = event.source.
|
82
|
-
|
88
|
+
|
89
|
+
on_drag_start do |event|
|
90
|
+
event.data = event.source.text
|
91
|
+
end
|
83
92
|
}
|
93
|
+
|
84
94
|
label {
|
85
|
-
text "Button"
|
86
95
|
grid :row => 3, :column => 0
|
96
|
+
text 'List'
|
97
|
+
}
|
98
|
+
list {
|
99
|
+
grid :row => 3, :column => 1, :pady => 5, :sticky => "e"
|
100
|
+
selectmode 'browse'
|
101
|
+
items %w[USA Canada Mexico]
|
102
|
+
selection 'Canada'
|
103
|
+
height 3
|
104
|
+
|
105
|
+
on_drag_start do |event|
|
106
|
+
event.data = event.source.selection.first
|
107
|
+
end
|
108
|
+
}
|
109
|
+
|
110
|
+
label {
|
111
|
+
grid :row => 4, :column => 0
|
112
|
+
text "Button"
|
87
113
|
}
|
88
114
|
button {
|
115
|
+
grid :row => 4, :column => 1, :pady => 5, :sticky => "w"
|
89
116
|
text "Drag it"
|
90
|
-
grid :row => 3, :column => 1, :pady => 5, :sticky => "w"
|
91
117
|
drag_source true
|
92
118
|
}
|
93
119
|
}
|
94
120
|
|
95
121
|
labelframe {
|
96
|
-
text "Drop targets"
|
97
122
|
grid :sticky => "nsew", :pady => 15
|
123
|
+
text "Drop targets"
|
98
124
|
padding 5
|
125
|
+
|
99
126
|
label {
|
100
|
-
text "Entry"
|
101
127
|
grid :row => 0, :column => 0
|
128
|
+
text "Label"
|
102
129
|
}
|
103
|
-
|
130
|
+
label {
|
131
|
+
grid :row => 0, :column => 1, :pady => 10, :sticky => "e"
|
104
132
|
width 30
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
133
|
+
borderwidth 2
|
134
|
+
relief "solid"
|
135
|
+
|
136
|
+
on_drop do |event|
|
137
|
+
event.target.text = event.data
|
138
|
+
end
|
109
139
|
}
|
140
|
+
|
110
141
|
label {
|
111
|
-
text "Label"
|
112
142
|
grid :row => 1, :column => 0
|
143
|
+
text "Entry"
|
113
144
|
}
|
114
|
-
|
145
|
+
entry {
|
146
|
+
grid :row => 1, :column => 1, :pady => 5, :sticky => "e"
|
115
147
|
width 30
|
116
|
-
|
117
|
-
borderwidth 2
|
118
|
-
relief "solid"
|
148
|
+
|
119
149
|
on_drop { |event|
|
120
|
-
event.target.
|
150
|
+
event.target.text = event.data
|
121
151
|
}
|
122
152
|
}
|
153
|
+
|
123
154
|
label {
|
124
|
-
text "Combobox"
|
125
155
|
grid :row => 2, :column => 0
|
156
|
+
text "Combobox"
|
126
157
|
}
|
127
158
|
combobox {
|
128
|
-
width 27
|
129
159
|
grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
|
130
|
-
|
131
|
-
|
132
|
-
|
160
|
+
width 27
|
161
|
+
|
162
|
+
on_drop do |event|
|
163
|
+
event.target.text = event.data
|
164
|
+
end
|
133
165
|
}
|
166
|
+
|
134
167
|
label {
|
135
|
-
text "Button"
|
136
168
|
grid :row => 3, :column => 0
|
169
|
+
text 'List'
|
170
|
+
}
|
171
|
+
list {
|
172
|
+
grid :row => 3, :column => 1, :pady => 5, :sticky => "e"
|
173
|
+
selectmode 'browse'
|
174
|
+
height 3
|
175
|
+
|
176
|
+
on_drop do |event|
|
177
|
+
event.target.items += [event.data]
|
178
|
+
end
|
179
|
+
}
|
180
|
+
|
181
|
+
label {
|
182
|
+
grid :row => 4, :column => 0
|
183
|
+
text "Button"
|
137
184
|
}
|
138
185
|
button {
|
186
|
+
grid :row => 4, :column => 1, :pady => 5, :sticky => "w"
|
139
187
|
text "Drop here"
|
140
|
-
|
141
|
-
on_drop
|
188
|
+
|
189
|
+
on_drop do |event|
|
142
190
|
event.target.text = event.data
|
143
|
-
|
191
|
+
end
|
144
192
|
}
|
193
|
+
|
145
194
|
label {
|
195
|
+
grid :row => 5, :column => 0
|
146
196
|
text "Checkbutton"
|
147
|
-
grid :row => 4, :column => 0
|
148
197
|
}
|
149
198
|
checkbutton {
|
150
|
-
|
151
|
-
|
152
|
-
|
199
|
+
grid :row => 5, :column => 1, :pady => 5, :sticky => "w"
|
200
|
+
text "Drop here to destroy a widget"
|
201
|
+
|
202
|
+
on_drop do |event|
|
153
203
|
event.target.text = event.data
|
154
|
-
|
155
|
-
|
204
|
+
# execute asynchronously after 100ms to ensure all events have been processed before destruction
|
205
|
+
::Tk.after(100) {event.source.destroy}
|
206
|
+
end
|
156
207
|
}
|
157
208
|
}
|
158
209
|
}
|
@@ -25,7 +25,7 @@ include Glimmer
|
|
25
25
|
|
26
26
|
COLORS = [:white, :red, :yellow, :green, :blue, :magenta, :gray, :black]
|
27
27
|
|
28
|
-
Tk::Tile::Style.theme_use
|
28
|
+
Tk::Tile::Style.theme_use 'classic' if OS.mac? # this enables setting background on label just for demo purposes
|
29
29
|
|
30
30
|
root { |r|
|
31
31
|
title 'Hello, Menu Bar!'
|
@@ -65,11 +65,6 @@ root { |r|
|
|
65
65
|
}
|
66
66
|
end
|
67
67
|
|
68
|
-
# Windows-specific system menu (to the top-left of the window frame)
|
69
|
-
if OS.windows?
|
70
|
-
menu(label: 'System')
|
71
|
-
end
|
72
|
-
|
73
68
|
menu(label: 'File', underline: 0) {
|
74
69
|
menu_item(label: 'New', underline: 0) {
|
75
70
|
accelerator OS.mac? ? 'Command+N' : 'Control+N'
|
@@ -166,7 +161,7 @@ root { |r|
|
|
166
161
|
end
|
167
162
|
}
|
168
163
|
|
169
|
-
menu(label: 'Country', underline:
|
164
|
+
menu(label: 'Country', underline: 0) {
|
170
165
|
['denmark', 'finland', 'france', 'germany', 'italy', 'mexico', 'netherlands', 'norway', 'usa'].each do |image_name|
|
171
166
|
menu_item(:radiobutton, label: image_name.capitalize) {
|
172
167
|
selection image_name == 'usa'
|
@@ -176,7 +171,7 @@ root { |r|
|
|
176
171
|
end
|
177
172
|
}
|
178
173
|
|
179
|
-
menu(label: 'Format', underline:
|
174
|
+
menu(label: 'Format', underline: 3) {
|
180
175
|
menu(label: 'Background Color', underline: 0) {
|
181
176
|
COLORS.each { |color_style|
|
182
177
|
menu_item(:radiobutton, label: color_style.to_s.split('_').map(&:capitalize).join(' ')) {
|
data/samples/hello/hello_text.rb
CHANGED
@@ -282,7 +282,7 @@ class HelloText
|
|
282
282
|
|
283
283
|
@text = text {
|
284
284
|
grid row: 1, column: 0, row_weight: 1
|
285
|
-
|
285
|
+
wrap 'word'
|
286
286
|
undo true
|
287
287
|
value <=> [self, :document]
|
288
288
|
|
@@ -304,15 +304,10 @@ class HelloText
|
|
304
304
|
end
|
305
305
|
}
|
306
306
|
|
307
|
-
@yscrollbar =
|
307
|
+
@yscrollbar = scrollbar {
|
308
308
|
grid row: 1, column: 1
|
309
309
|
}
|
310
310
|
@text.yscrollbar @yscrollbar
|
311
|
-
|
312
|
-
@xscrollbar = x_scrollbar {
|
313
|
-
grid row: 2, column: 0, column_span: 2, row_weight: 0
|
314
|
-
}
|
315
|
-
@text.xscrollbar @xscrollbar
|
316
311
|
}
|
317
312
|
@root.open
|
318
313
|
end
|
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.
|
4
|
+
version: 0.0.45
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-11-
|
11
|
+
date: 2021-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: glimmer
|
@@ -38,26 +38,6 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.13.1
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: os
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 1.0.0
|
48
|
-
- - "<"
|
49
|
-
- !ruby/object:Gem::Version
|
50
|
-
version: 2.0.0
|
51
|
-
type: :runtime
|
52
|
-
prerelease: false
|
53
|
-
version_requirements: !ruby/object:Gem::Requirement
|
54
|
-
requirements:
|
55
|
-
- - ">="
|
56
|
-
- !ruby/object:Gem::Version
|
57
|
-
version: 1.0.0
|
58
|
-
- - "<"
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: 2.0.0
|
61
41
|
- !ruby/object:Gem::Dependency
|
62
42
|
name: tk
|
63
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -232,6 +212,7 @@ files:
|
|
232
212
|
- lib/glimmer/tk/entry_proxy.rb
|
233
213
|
- lib/glimmer/tk/frame_proxy.rb
|
234
214
|
- lib/glimmer/tk/label_proxy.rb
|
215
|
+
- lib/glimmer/tk/lbl_proxy.rb
|
235
216
|
- lib/glimmer/tk/list_proxy.rb
|
236
217
|
- lib/glimmer/tk/menu_item_proxy.rb
|
237
218
|
- lib/glimmer/tk/menu_proxy.rb
|
@@ -245,7 +226,9 @@ files:
|
|
245
226
|
- lib/glimmer/tk/toplevel_proxy.rb
|
246
227
|
- lib/glimmer/tk/treeview_proxy.rb
|
247
228
|
- lib/glimmer/tk/variable_owner.rb
|
229
|
+
- lib/glimmer/tk/widget.rb
|
248
230
|
- lib/glimmer/tk/widget_proxy.rb
|
231
|
+
- lib/os.rb
|
249
232
|
- samples/elaborate/meta_sample.rb
|
250
233
|
- samples/hello/hello_built_in_dialog.rb
|
251
234
|
- samples/hello/hello_button.rb
|
@@ -310,7 +293,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
310
293
|
- !ruby/object:Gem::Version
|
311
294
|
version: '0'
|
312
295
|
requirements: []
|
313
|
-
rubygems_version: 3.2.
|
296
|
+
rubygems_version: 3.2.31
|
314
297
|
signing_key:
|
315
298
|
specification_version: 4
|
316
299
|
summary: Glimmer DSL for Tk
|