glimmer-dsl-tk 0.0.42 → 0.0.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fbb49ce9e435d0313cdec33a81afec3ad4d7716ee6e8363004651417d3535704
4
- data.tar.gz: 9ad46f88ace884c5d670d2449728369af8510b95e24c291a3bda7580cef65820
3
+ metadata.gz: e07fd35aa994530b829c419c68d6ddb23e443055e374f1777ef78e1b4f3235c2
4
+ data.tar.gz: d543e113f866f4f28c5093f4d69b86910387bf4630b8ad58e64877f83bd054e4
5
5
  SHA512:
6
- metadata.gz: d58a0179466efe9991f53eefb23c6dd3749c386230d70722e0a6c3f24c85f2affc361e18c21d65b34b2cb37269dfb8c7ceff9953a1bc5059f1db971051b0c4c8
7
- data.tar.gz: bad07c9519d483534306b04be7e4d110fe302c6dc3f03028d85aa5c85fcfe01437c0471d58b49e3db013abc99d6f55535d5aefacc4bdc651df50b30ecda467e0
6
+ metadata.gz: 99ce3e9598f70e10b3a4ee882f584cbfca9d6f41bce358f71e7028911ad2274788c55428175a1805484dfcd3dc6251da7251d592d0312861bf96872966626ba5
7
+ data.tar.gz: 96fdf7e866610ced773cdaa62bc097b0eac5845d57691d860053b78b543205e343c00f23a45a0d7e32471d33070b89359a021ccafff71d75ba230bb6f2da3889
data/CHANGELOG.md CHANGED
@@ -1,10 +1,17 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.43
4
+
5
+ - Modified Hello, Drag and Drop! to include a list
6
+ - 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.
7
+ - 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?`)
8
+ - Default to 'clam' Tk theme on Linux ('alt' looks a bit too classic with certain widgets)
9
+
3
10
  ## 0.0.42
4
11
 
5
12
  - Add vertical/horizontal scrollbars to Meta-Sample
6
13
  - Keep only vertical scrollbar in Hello, Text!
7
- - Fix issue with including bwidgets and iwidgets in Windows
14
+ - 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)
8
15
  - Fix Hello, Menu Bar! sample in Windows (by disabling Windows-special System menu, which does not seem to be working in Tk)
9
16
 
10
17
  ## 0.0.41
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.42
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.43
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)
@@ -181,7 +181,7 @@ gem install glimmer-dsl-tk
181
181
 
182
182
  Add the following to `Gemfile`:
183
183
  ```
184
- gem 'glimmer-dsl-tk', '0.0.42'
184
+ gem 'glimmer-dsl-tk', '0.0.43'
185
185
  ```
186
186
 
187
187
  And, then run:
@@ -2683,27 +2683,31 @@ Glimmer app:
2683
2683
  Glimmer code (from [samples/hello/hello_drag_and_drop.rb](samples/hello/hello_drag_and_drop.rb)):
2684
2684
 
2685
2685
  ```ruby
2686
- require "glimmer-dsl-tk"
2687
- require "glimmer/tk/drag_and_drop_extension"
2686
+ require 'glimmer-dsl-tk'
2688
2687
 
2689
2688
  include Glimmer
2690
2689
 
2691
2690
  root {
2692
2691
  title "Hello, Drag and Drop!"
2692
+
2693
2693
  frame {
2694
2694
  padding 5
2695
+
2695
2696
  labelframe {
2696
2697
  text "Drag sources"
2697
2698
  padding 5
2699
+
2698
2700
  label {
2699
- text "Entry"
2700
2701
  grid :row => 0, :column => 0
2702
+ text "Entry"
2701
2703
  }
2704
+
2702
2705
  entry {
2706
+ grid :row => 0, :column => 1, :pady => 5, :sticky => "e"
2703
2707
  text "Drag entry text"
2704
2708
  width 30
2705
- grid :row => 0, :column => 1, :pady => 5, :sticky => "e"
2706
- on_drag_start { |event|
2709
+
2710
+ on_drag_start do |event|
2707
2711
  event.data = event.source.textvariable&.value
2708
2712
  event.source.configure(:cursor => "hand2")
2709
2713
  TkLabel.new(event.tooltip) {
@@ -2712,111 +2716,166 @@ root {
2712
2716
  bitmap "warning"
2713
2717
  compound "right"
2714
2718
  }.pack
2715
- }
2716
- on_drag_motion { |event|
2719
+ end
2720
+
2721
+ on_drag_motion do |event|
2717
2722
  if event.drop_accepted
2718
2723
  event.source.configure(:cursor => "hand1")
2719
2724
  else
2720
2725
  event.source.configure(:cursor => "hand2")
2721
2726
  end
2722
2727
  event.tooltip.geometry("+#{event.x_root + 10}+#{event.y_root - 4}")
2723
- }
2728
+ end
2724
2729
  }
2730
+
2725
2731
  label {
2726
- text "Label"
2727
2732
  grid :row => 1, :column => 0
2733
+ text "Label"
2728
2734
  }
2735
+
2729
2736
  label {
2737
+ grid :row => 1, :column => 1, :pady => 10, :sticky => "e"
2730
2738
  text "Drag label text"
2731
2739
  width 30
2732
- grid :row => 1, :column => 1, :pady => 10, :sticky => "e"
2733
2740
  drag_source true
2734
2741
  }
2742
+
2735
2743
  label {
2736
- text "Combobox"
2737
2744
  grid :row => 2, :column => 0
2745
+ text "Combobox"
2738
2746
  }
2747
+
2739
2748
  combobox {
2749
+ grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
2740
2750
  text "Spain"
2741
2751
  values %w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
2742
2752
  width 27
2743
- grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
2744
- on_drag_start { |event|
2753
+
2754
+ on_drag_start do |event|
2745
2755
  event.data = event.source.textvariable&.value
2746
- }
2756
+ end
2747
2757
  }
2758
+
2748
2759
  label {
2749
- text "Button"
2750
2760
  grid :row => 3, :column => 0
2761
+ text 'List'
2762
+ }
2763
+
2764
+ country_list = list {
2765
+ grid :row => 3, :column => 1, :pady => 5, :sticky => "e"
2766
+ selectmode 'browse'
2767
+ items %w[USA Canada Mexico]
2768
+ selection 'Canada'
2769
+ height 3
2770
+
2771
+ on_drag_start do |event|
2772
+ event.data = event.source.selection.to_a.first.text
2773
+ end
2774
+ }
2775
+
2776
+ label {
2777
+ grid :row => 4, :column => 0
2778
+ text "Button"
2751
2779
  }
2780
+
2752
2781
  button {
2782
+ grid :row => 4, :column => 1, :pady => 5, :sticky => "w"
2753
2783
  text "Drag it"
2754
- grid :row => 3, :column => 1, :pady => 5, :sticky => "w"
2755
2784
  drag_source true
2756
2785
  }
2757
2786
  }
2758
2787
 
2759
2788
  labelframe {
2760
- text "Drop targets"
2761
2789
  grid :sticky => "nsew", :pady => 15
2790
+ text "Drop targets"
2762
2791
  padding 5
2792
+
2763
2793
  label {
2764
- text "Entry"
2765
2794
  grid :row => 0, :column => 0
2795
+ text "Entry"
2766
2796
  }
2797
+
2767
2798
  entry {
2768
- width 30
2769
2799
  grid :row => 0, :column => 1, :pady => 5, :sticky => "e"
2800
+ width 30
2801
+
2770
2802
  on_drop { |event|
2771
2803
  event.target.textvariable.value = event.data
2772
2804
  }
2773
2805
  }
2806
+
2774
2807
  label {
2775
- text "Label"
2776
2808
  grid :row => 1, :column => 0
2809
+ text "Label"
2777
2810
  }
2811
+
2778
2812
  label {
2779
- width 30
2780
2813
  grid :row => 1, :column => 1, :pady => 10, :sticky => "e"
2814
+ width 30
2781
2815
  borderwidth 2
2782
2816
  relief "solid"
2783
- on_drop { |event|
2817
+
2818
+ on_drop do |event|
2784
2819
  event.target.textvariable.value = event.data
2785
- }
2820
+ end
2786
2821
  }
2822
+
2787
2823
  label {
2788
- text "Combobox"
2789
2824
  grid :row => 2, :column => 0
2825
+ text "Combobox"
2790
2826
  }
2827
+
2791
2828
  combobox {
2792
- width 27
2793
2829
  grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
2794
- on_drop { |event|
2830
+ width 27
2831
+
2832
+ on_drop do |event|
2795
2833
  event.target.textvariable.value = event.data
2796
- }
2834
+ end
2835
+ }
2836
+
2837
+ label {
2838
+ grid :row => 3, :column => 0
2839
+ text 'List'
2840
+ }
2841
+
2842
+ list {
2843
+ grid :row => 3, :column => 1, :pady => 5, :sticky => "e"
2844
+ selectmode 'browse'
2845
+ height 3
2846
+
2847
+ on_drop do |event|
2848
+ event.target.insert('', 'end', :text => event.data)
2849
+ end
2797
2850
  }
2851
+
2798
2852
  label {
2853
+ grid :row => 4, :column => 0
2799
2854
  text "Button"
2800
- grid :row => 3, :column => 0
2801
2855
  }
2856
+
2802
2857
  button {
2858
+ grid :row => 4, :column => 1, :pady => 5, :sticky => "w"
2803
2859
  text "Drop here"
2804
- grid :row => 3, :column => 1, :pady => 5, :sticky => "w"
2805
- on_drop { |event|
2860
+
2861
+ on_drop do |event|
2806
2862
  event.target.text = event.data
2807
- }
2863
+ end
2808
2864
  }
2865
+
2809
2866
  label {
2867
+ grid :row => 5, :column => 0
2810
2868
  text "Checkbutton"
2811
- grid :row => 4, :column => 0
2812
2869
  }
2870
+
2813
2871
  checkbutton {
2872
+ grid :row => 5, :column => 1, :pady => 5, :sticky => "w"
2814
2873
  text "Drop here to destroy a widget\n(except button)"
2815
- grid :row => 4, :column => 1, :pady => 5, :sticky => "w"
2816
- on_drop { |event|
2874
+
2875
+ on_drop do |event|
2817
2876
  event.target.text = event.data
2818
2877
  event.source.destroy unless event.source.is_a? Tk::Button
2819
- }
2878
+ end
2820
2879
  }
2821
2880
  }
2822
2881
  }
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.42
1
+ 0.0.43
Binary file
@@ -49,10 +49,10 @@ module Glimmer
49
49
  # TODO consider exposing this via Glimmer::Config
50
50
  potential_tk_widget_class_names = [
51
51
  "::Tk::Tile::#{tk_widget_class_basename}",
52
- "::Tk::BWidget::#{tk_widget_class_basename}",
53
- "::Tk::Iwidgets::#{tk_widget_class_basename}",
54
52
  "::Tk#{tk_widget_class_basename}",
55
53
  "::Tk::#{tk_widget_class_basename}",
54
+ "::Tk::BWidget::#{tk_widget_class_basename}",
55
+ "::Tk::Iwidgets::#{tk_widget_class_basename}",
56
56
  "::Glimmer::Tk::#{tk_widget_class_basename}Proxy",
57
57
  ]
58
58
  tk_widget_class = nil
@@ -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 'alt' if OS.linux?
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
@@ -19,27 +19,31 @@
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 "glimmer-dsl-tk"
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 "Entry"
37
39
  }
40
+
38
41
  entry {
42
+ grid :row => 0, :column => 1, :pady => 5, :sticky => "e"
39
43
  text "Drag entry text"
40
44
  width 30
41
- grid :row => 0, :column => 1, :pady => 5, :sticky => "e"
42
- on_drag_start { |event|
45
+
46
+ on_drag_start do |event|
43
47
  event.data = event.source.textvariable&.value
44
48
  event.source.configure(:cursor => "hand2")
45
49
  TkLabel.new(event.tooltip) {
@@ -48,111 +52,166 @@ root {
48
52
  bitmap "warning"
49
53
  compound "right"
50
54
  }.pack
51
- }
52
- on_drag_motion { |event|
55
+ end
56
+
57
+ on_drag_motion do |event|
53
58
  if event.drop_accepted
54
59
  event.source.configure(:cursor => "hand1")
55
60
  else
56
61
  event.source.configure(:cursor => "hand2")
57
62
  end
58
63
  event.tooltip.geometry("+#{event.x_root + 10}+#{event.y_root - 4}")
59
- }
64
+ end
60
65
  }
66
+
61
67
  label {
62
- text "Label"
63
68
  grid :row => 1, :column => 0
69
+ text "Label"
64
70
  }
71
+
65
72
  label {
73
+ grid :row => 1, :column => 1, :pady => 10, :sticky => "e"
66
74
  text "Drag label text"
67
75
  width 30
68
- grid :row => 1, :column => 1, :pady => 10, :sticky => "e"
69
76
  drag_source true
70
77
  }
78
+
71
79
  label {
72
- text "Combobox"
73
80
  grid :row => 2, :column => 0
81
+ text "Combobox"
74
82
  }
83
+
75
84
  combobox {
85
+ grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
76
86
  text "Spain"
77
87
  values %w[USA Canada Mexico Columbia UK Australia Germany Italy Spain]
78
88
  width 27
79
- grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
80
- on_drag_start { |event|
89
+
90
+ on_drag_start do |event|
81
91
  event.data = event.source.textvariable&.value
82
- }
92
+ end
83
93
  }
94
+
84
95
  label {
85
- text "Button"
86
96
  grid :row => 3, :column => 0
97
+ text 'List'
98
+ }
99
+
100
+ country_list = list {
101
+ grid :row => 3, :column => 1, :pady => 5, :sticky => "e"
102
+ selectmode 'browse'
103
+ items %w[USA Canada Mexico]
104
+ selection 'Canada'
105
+ height 3
106
+
107
+ on_drag_start do |event|
108
+ event.data = event.source.selection.to_a.first.text
109
+ end
110
+ }
111
+
112
+ label {
113
+ grid :row => 4, :column => 0
114
+ text "Button"
87
115
  }
116
+
88
117
  button {
118
+ grid :row => 4, :column => 1, :pady => 5, :sticky => "w"
89
119
  text "Drag it"
90
- grid :row => 3, :column => 1, :pady => 5, :sticky => "w"
91
120
  drag_source true
92
121
  }
93
122
  }
94
123
 
95
124
  labelframe {
96
- text "Drop targets"
97
125
  grid :sticky => "nsew", :pady => 15
126
+ text "Drop targets"
98
127
  padding 5
128
+
99
129
  label {
100
- text "Entry"
101
130
  grid :row => 0, :column => 0
131
+ text "Entry"
102
132
  }
133
+
103
134
  entry {
104
- width 30
105
135
  grid :row => 0, :column => 1, :pady => 5, :sticky => "e"
136
+ width 30
137
+
106
138
  on_drop { |event|
107
139
  event.target.textvariable.value = event.data
108
140
  }
109
141
  }
142
+
110
143
  label {
111
- text "Label"
112
144
  grid :row => 1, :column => 0
145
+ text "Label"
113
146
  }
147
+
114
148
  label {
115
- width 30
116
149
  grid :row => 1, :column => 1, :pady => 10, :sticky => "e"
150
+ width 30
117
151
  borderwidth 2
118
152
  relief "solid"
119
- on_drop { |event|
153
+
154
+ on_drop do |event|
120
155
  event.target.textvariable.value = event.data
121
- }
156
+ end
122
157
  }
158
+
123
159
  label {
124
- text "Combobox"
125
160
  grid :row => 2, :column => 0
161
+ text "Combobox"
126
162
  }
163
+
127
164
  combobox {
128
- width 27
129
165
  grid :row => 2, :column => 1, :pady => 5, :sticky => "e"
130
- on_drop { |event|
166
+ width 27
167
+
168
+ on_drop do |event|
131
169
  event.target.textvariable.value = event.data
132
- }
170
+ end
133
171
  }
172
+
134
173
  label {
135
- text "Button"
136
174
  grid :row => 3, :column => 0
175
+ text 'List'
176
+ }
177
+
178
+ list {
179
+ grid :row => 3, :column => 1, :pady => 5, :sticky => "e"
180
+ selectmode 'browse'
181
+ height 3
182
+
183
+ on_drop do |event|
184
+ event.target.insert('', 'end', :text => event.data)
185
+ end
186
+ }
187
+
188
+ label {
189
+ grid :row => 4, :column => 0
190
+ text "Button"
137
191
  }
192
+
138
193
  button {
194
+ grid :row => 4, :column => 1, :pady => 5, :sticky => "w"
139
195
  text "Drop here"
140
- grid :row => 3, :column => 1, :pady => 5, :sticky => "w"
141
- on_drop { |event|
196
+
197
+ on_drop do |event|
142
198
  event.target.text = event.data
143
- }
199
+ end
144
200
  }
201
+
145
202
  label {
203
+ grid :row => 5, :column => 0
146
204
  text "Checkbutton"
147
- grid :row => 4, :column => 0
148
205
  }
206
+
149
207
  checkbutton {
208
+ grid :row => 5, :column => 1, :pady => 5, :sticky => "w"
150
209
  text "Drop here to destroy a widget\n(except button)"
151
- grid :row => 4, :column => 1, :pady => 5, :sticky => "w"
152
- on_drop { |event|
210
+
211
+ on_drop do |event|
153
212
  event.target.text = event.data
154
213
  event.source.destroy unless event.source.is_a? Tk::Button
155
- }
214
+ end
156
215
  }
157
216
  }
158
217
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-tk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.42
4
+ version: 0.0.43
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
@@ -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
@@ -246,6 +226,7 @@ files:
246
226
  - lib/glimmer/tk/treeview_proxy.rb
247
227
  - lib/glimmer/tk/variable_owner.rb
248
228
  - lib/glimmer/tk/widget_proxy.rb
229
+ - lib/os.rb
249
230
  - samples/elaborate/meta_sample.rb
250
231
  - samples/hello/hello_built_in_dialog.rb
251
232
  - samples/hello/hello_button.rb