glimmer-dsl-tk 0.0.39 → 0.0.40

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: 40c011bf31bc0b5d5691abc8930f93b7fe33c77b8cb77f1f0bf439cd3344d9d7
4
- data.tar.gz: 65af004b131e750be35b4bab6b11316c012e49dbbcc3509171c40abcdc4b809f
3
+ metadata.gz: 94a9453b27626850d61fc8b19ebf662f5f842a39548eb52cc280a2f123bb5a9b
4
+ data.tar.gz: '08586efe1d641f14ed9d93975efea3de3697c51fe37e3496ad257cc5498fd2d6'
5
5
  SHA512:
6
- metadata.gz: b53ed25b7f36d71a8db9dfde148589b95efd88b5ba881b9da1ce011024f13eb90d6b7b4c536fe0302774fe5bf71645e457eb694adceba7f94238d7cc24e3a26c
7
- data.tar.gz: 11b7ada873371764ec7e255e2ab070863eaad8deec1f54da0246fa7e5e7ed3af3b53ef1fb11954a2d572502353b9b1ed43e6cf557d43cf9517f6fb0047da60b0
6
+ metadata.gz: 00c61781ce122ec8053c81cdd4aaf90707a6f2c984a6be794d47d41760fd98ad5e0ffb90816ae510d4243ac776a8c4cf1dd0f797b7e08d9736695f03985d283a
7
+ data.tar.gz: 959e8368cb542d0d01d501ce5bd4ee3c9a3e83cb8822eeaca1aadcdf2a781515d3e453df2d93d4802bfee77ae4ac2a7e626988115cd458ba7088ff54c14a594f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.40
4
+
5
+ - Hello, Scrollbar!
6
+ - Default to 'alt' Tk theme on Linux
7
+ - Added Windows/Linux accelerators to Hello, Menu Bar!
8
+ - Fix issue with extra junk character added to beginning of Hello, Checkbutton! by mistake
9
+ - Fix issue with Hello, Menu Bar! help menu item crashing in Linux (it is restricted to Mac only)
10
+ - Fix issue with Hello, Text! focus losing selection in Linux upon setting background/foreground/font/font-size
11
+
3
12
  ## 0.0.39
4
13
 
5
14
  - Add Language and Language Name menus to Hello, Menu Bar! sample
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.39
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.40
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)
@@ -121,6 +121,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
121
121
  - [Hello, Drag and Drop!](#hello-drag-and-drop)
122
122
  - [Hello, Built-in Dialog!](#hello-built-in-dialog)
123
123
  - [Hello, Separator!](#hello-separator)
124
+ - [Hello, Scrollbar!](#hello-scrollbar)
124
125
  - [Hello, Menu Bar!](#hello-menu-bar)
125
126
  - [Applications](#applications)
126
127
  - [Glimmer Tk Calculator](#glimmer-tk-calculator)
@@ -156,6 +157,14 @@ For example, on Windows, you can follow the [instructions over here](https://tkd
156
157
  - Setup environment variables TCL_LIBRARY=C:\ActiveTcl\lib\tcl8.6 & TK_LIBRARY=C:\ActiveTcl\lib\tk8.6
157
158
  - Run: `gem install tk -v0.4.0`
158
159
 
160
+ For example, on Linux, you can:
161
+ - Download the ActiveTcl Linux package from [ActiveState.com](https://activestate.com)
162
+ - Extract the tar gz file using command `tar zxvf ActiveTcl-version-number.tar.gz`
163
+ - Run included install shell script `./ActiveTcl-version-number/install.sh`
164
+ - Install [RVM](https://rvm.io/) by running `\curl -sSL https://get.rvm.io | bash -s stable` (and run `curl -sSL https://rvm.io/pkuczynski.asc | gpg --import -` if needed for mentioned security reasons)
165
+ - Run: `rvm install 3.0.2 --enable-shared --enable-pthread --with-tk --with-tcl`
166
+ - Run: `gem install tk -v0.4.0`
167
+
159
168
  Afterwards, if you open `irb`, you should be able to run `require 'tk'` successfully.
160
169
 
161
170
  ## Setup
@@ -171,7 +180,7 @@ gem install glimmer-dsl-tk
171
180
 
172
181
  Add the following to `Gemfile`:
173
182
  ```
174
- gem 'glimmer-dsl-tk', '~> 0.0.39'
183
+ gem 'glimmer-dsl-tk', '~> 0.0.40'
175
184
  ```
176
185
 
177
186
  And, then run:
@@ -300,6 +309,9 @@ keyword(args) | attributes | event bindings & callbacks
300
309
  `notebook` | None | None
301
310
  `radiobutton` | `text`, `variable` (Boolean), `image` (optional keyword args: `subsample`, `zoom`, `from`, `to`, `shrink`, `compositingrule`), `compound` (`'center', 'top', 'bottom', 'left', 'right'`), `value` (default: `text`) | `command {}`
302
311
  `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'`
312
+ `scrollbar` | `orient` | `command`
313
+ `x_scrollbar` | `orient` (`'horizontal'`) | `command`
314
+ `y_scrollbar` | `orient` (`'vertical'`) | `command`
303
315
  `separator` | `orient` (`'horizontal' (default) or 'vertical'`) | None
304
316
  `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'`
305
317
  `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'`)
@@ -422,8 +434,44 @@ Other useful built-in API methods:
422
434
  - `text_edit_undo`
423
435
  - `text_edit_redo`
424
436
 
437
+ If you would like to add scrollbars, you can set the `xscrollbar` and `yscrollbar` attributes.
438
+
439
+ Example of adding a vertical `scrollbar`:
440
+
441
+ ```ruby
442
+ textarea_yscrollbar = y_scrollbar {
443
+ grid row:0, column:1
444
+ }
445
+
446
+ textarea = text {
447
+ grid row:0, column:0, column_weight: 0
448
+ wrap "word"
449
+ yscrollbar textarea_yscrollbar
450
+ }
451
+ ```
452
+
453
+ Example of adding both a horizontal `scrollbar` and a vertical `scrollbar` (must disable `wrap "word"` for horizontal scrolling to work):
454
+
455
+ ```ruby
456
+ textarea_xscrollbar = x_scrollbar {
457
+ grid row:1, column:0, column_span: 2, row_weight: 0
458
+ }
459
+
460
+ textarea_yscrollbar = y_scrollbar {
461
+ grid row:0, column:1
462
+ }
463
+
464
+ textarea = text {
465
+ grid row:0, column:0, column_weight: 0
466
+ xscrollbar textarea_xscrollbar
467
+ yscrollbar textarea_yscrollbar
468
+ }
469
+ ```
470
+
425
471
  Check out the [Hello, Text!](#hello-text) sample for a good demonstration of the `text` widget features.
426
472
 
473
+ Check out the [Hello, Scrollbar!](#hello-scrollbar) sample for a `text` demo with scrolling.
474
+
427
475
  #### Drag and Drop API
428
476
 
429
477
  Drag and drop works by simply designating a widget as a drag source with attribute `drag_source true`
@@ -2937,6 +2985,77 @@ Glimmer app:
2937
2985
 
2938
2986
  ![glimmer dsl tk screenshot sample hello separator](images/glimmer-dsl-tk-screenshot-sample-hello-separator.png)
2939
2987
 
2988
+ ### Hello, Scrollbar!
2989
+
2990
+ Glimmer code (from [samples/hello/hello_scrollbar.rb](samples/hello/hello_scrollbar.rb)):
2991
+
2992
+ ```ruby
2993
+ require 'glimmer-dsl-tk'
2994
+
2995
+ include Glimmer
2996
+
2997
+ root {
2998
+ title 'Hello, Scrollbar!'
2999
+ width 400
3000
+ height 500
3001
+
3002
+ notebook {
3003
+ grid sticky: 'nsew', row_weight: 1, column_weight: 1
3004
+
3005
+ frame(text: 'Scrollable List') {
3006
+ @list = list {
3007
+ grid sticky: 'nsew', row: 0, column: 0, row_weight: 1, column_weight: 1
3008
+ items 40.times.map {|n| "Item #{n + 1} of a very long list" }
3009
+ }
3010
+
3011
+ @scrollbar = scrollbar {
3012
+ grid row: 0, column: 1
3013
+ # orient 'vertical' # default
3014
+ }
3015
+ @list.yscrollbar @scrollbar
3016
+ }
3017
+
3018
+ frame(text: 'Scrollable Text') {
3019
+ @text = text {
3020
+ grid sticky: 'nsew', row: 0, column: 0, row_weight: 1, column_weight: 1
3021
+ value ("This is a random sample of text that will repeat over and over and over"*2 + "\n")*40
3022
+ }
3023
+
3024
+ @yscrollbar = scrollbar {
3025
+ grid row: 0, column: 1
3026
+ # orient 'vertical' # default
3027
+ }
3028
+ @text.yscrollbar @yscrollbar
3029
+
3030
+ @xscrollbar = scrollbar {
3031
+ grid row: 1, column: 0, column_span: 2, row_weight: 0
3032
+ orient 'horizontal'
3033
+ }
3034
+ @text.xscrollbar @xscrollbar
3035
+ }
3036
+ }
3037
+
3038
+ }.open
3039
+ ```
3040
+
3041
+ Run with [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
3042
+
3043
+ ```
3044
+ ruby -r glimmer-dsl-tk -e "require 'samples/hello/hello_scrollbar'"
3045
+ ```
3046
+
3047
+ Alternatively, run from cloned project without [glimmer-dsl-tk](https://rubygems.org/gems/glimmer-dsl-tk) gem installed:
3048
+
3049
+ ```
3050
+ ruby -r ./lib/glimmer-dsl-tk.rb samples/hello/hello_scrollbar.rb
3051
+ ```
3052
+
3053
+ Glimmer app:
3054
+
3055
+ ![glimmer dsl tk screenshot sample hello scrollbar](images/glimmer-dsl-tk-screenshot-sample-hello-scrollbar-list.png)
3056
+
3057
+ ![glimmer dsl tk screenshot sample hello scrollbar](images/glimmer-dsl-tk-screenshot-sample-hello-scrollbar-text.png)
3058
+
2940
3059
  ### Hello, Menu Bar!
2941
3060
 
2942
3061
  Glimmer code (from [samples/hello/hello_menu_bar.rb](samples/hello/hello_menu_bar.rb)):
@@ -2961,6 +3080,38 @@ root { |r|
2961
3080
  }
2962
3081
 
2963
3082
  menu {
3083
+ # Mac-specific application menu (right next to the Apple menu)
3084
+ if OS.mac?
3085
+ menu(:application) {
3086
+ menu_item(:about, label: 'About My Application') {
3087
+ accelerator 'Command+A'
3088
+
3089
+ on('command') do
3090
+ message_box(parent: r, title: 'About', message: 'About my application.')
3091
+ end
3092
+ }
3093
+
3094
+ menu_item(:preferences) {
3095
+ on('command') do
3096
+ message_box(parent: r, title: 'Preferences', message: 'Preferences of my application.')
3097
+ end
3098
+ }
3099
+
3100
+ # If not defined, application simply quits upon selecting Quit menu item
3101
+ menu_item(:quit) {
3102
+ on('command') do
3103
+ message_box(parent: r, title: 'Quit', message: 'Quitting my application...')
3104
+ exit(0)
3105
+ end
3106
+ }
3107
+ }
3108
+ end
3109
+
3110
+ # Windows-specific system menu (to the top-left of the window frame)
3111
+ if OS.windows?
3112
+ menu(label: 'System')
3113
+ end
3114
+
2964
3115
  menu(label: 'File', underline: 0) {
2965
3116
  menu_item(label: 'New', underline: 0) {
2966
3117
  accelerator 'Command+N'
@@ -2969,6 +3120,7 @@ root { |r|
2969
3120
  message_box(parent: r, title: 'New', message: 'New file created.')
2970
3121
  end
2971
3122
  }
3123
+
2972
3124
  menu_item(label: 'Open...', underline: 0) {
2973
3125
  accelerator 'Command+O'
2974
3126
 
@@ -2976,36 +3128,44 @@ root { |r|
2976
3128
  message_box(parent: r, title: 'Open', message: 'Opening File...')
2977
3129
  end
2978
3130
  }
3131
+
2979
3132
  menu(label: 'Open Recent', underline: 5) {
2980
3133
  menu_item(label: 'File 1') {
2981
3134
  on('command') do
2982
3135
  message_box(parent: r, title: 'File 1', message: 'File 1 Contents')
2983
3136
  end
2984
3137
  }
3138
+
2985
3139
  menu_item(label: 'File 2') {
2986
3140
  on('command') do
2987
3141
  message_box(parent: r, title: 'File 2', message: 'File 2 Contents')
2988
3142
  end
2989
3143
  }
2990
3144
  }
3145
+
2991
3146
  menu_item(:separator)
3147
+
2992
3148
  menu_item(label: 'Exit', underline: 1) {
2993
3149
  on('command') do
2994
3150
  exit(0)
2995
3151
  end
2996
3152
  }
2997
3153
  }
3154
+
2998
3155
  menu(label: 'Edit', underline: 0) {
2999
3156
  menu_item(label: 'Cut', underline: 2) {
3000
3157
  accelerator 'Command+X'
3001
3158
  }
3159
+
3002
3160
  menu_item(label: 'Copy', underline: 0) {
3003
3161
  accelerator 'Command+C'
3004
3162
  }
3163
+
3005
3164
  menu_item(label: 'Paste', underline: 0) {
3006
3165
  accelerator 'Command+V'
3007
3166
  }
3008
3167
  }
3168
+
3009
3169
  menu(label: 'Options', underline: 0) {
3010
3170
  menu_item(:checkbutton, label: 'Enabled', underline: 0) {
3011
3171
  on('command') do
@@ -3013,6 +3173,7 @@ root { |r|
3013
3173
  @select_multiple_menu.children.each { |menu_item| menu_item.state = menu_item.state == 'disabled' ? 'normal' : 'disabled' }
3014
3174
  end
3015
3175
  }
3176
+
3016
3177
  @select_one_menu = menu(label: 'Select One', underline: 0) {
3017
3178
  menu_item(:radiobutton, label: 'Option 1') {
3018
3179
  state 'disabled'
@@ -3024,6 +3185,7 @@ root { |r|
3024
3185
  state 'disabled'
3025
3186
  }
3026
3187
  }
3188
+
3027
3189
  @select_multiple_menu = menu(label: 'Select Multiple', underline: 0) {
3028
3190
  menu_item(:checkbutton, label: 'Option 4') {
3029
3191
  state 'disabled'
@@ -3036,6 +3198,26 @@ root { |r|
3036
3198
  }
3037
3199
  }
3038
3200
  }
3201
+
3202
+ menu(label: 'Language', underline: 3) {
3203
+ ['denmark', 'finland', 'france', 'germany', 'italy', 'mexico', 'netherlands', 'norway', 'usa'].each do |image_name|
3204
+ menu_item(:radiobutton, label: image_name.capitalize) {
3205
+ selection image_name == 'usa'
3206
+ image File.expand_path("images/#{image_name}.png", __dir__)
3207
+ }
3208
+ end
3209
+ }
3210
+
3211
+ menu(label: 'Language Country', underline: 3) {
3212
+ ['denmark', 'finland', 'france', 'germany', 'italy', 'mexico', 'netherlands', 'norway', 'usa'].each do |image_name|
3213
+ menu_item(:radiobutton, label: image_name.capitalize) {
3214
+ selection image_name == 'usa'
3215
+ image File.expand_path("images/#{image_name}.png", __dir__)
3216
+ compound 'left'
3217
+ }
3218
+ end
3219
+ }
3220
+
3039
3221
  menu(label: 'Format', underline: 0) {
3040
3222
  menu(label: 'Background Color', underline: 0) {
3041
3223
  COLORS.each { |color_style|
@@ -3046,6 +3228,7 @@ root { |r|
3046
3228
  }
3047
3229
  }
3048
3230
  }
3231
+
3049
3232
  menu(label: 'Foreground Color', underline: 11) {
3050
3233
  COLORS.each { |color_style|
3051
3234
  menu_item(:radiobutton, label: color_style.to_s.split('_').map(&:capitalize).join(' ')) {
@@ -3056,6 +3239,7 @@ root { |r|
3056
3239
  }
3057
3240
  }
3058
3241
  }
3242
+
3059
3243
  menu(label: 'View', underline: 0) {
3060
3244
  menu_item(:radiobutton, label: 'Small', underline: 0) {
3061
3245
  accelerator 'Command+S'
@@ -3064,6 +3248,7 @@ root { |r|
3064
3248
  @label.font = {size: 25}
3065
3249
  end
3066
3250
  }
3251
+
3067
3252
  menu_item(:radiobutton, label: 'Medium', underline: 0) {
3068
3253
  accelerator 'Command+M'
3069
3254
  selection true
@@ -3072,6 +3257,7 @@ root { |r|
3072
3257
  @label.font = {size: 50}
3073
3258
  end
3074
3259
  }
3260
+
3075
3261
  menu_item(:radiobutton, label: 'Large', underline: 0) {
3076
3262
  accelerator 'Command+L'
3077
3263
 
@@ -3080,7 +3266,16 @@ root { |r|
3080
3266
  end
3081
3267
  }
3082
3268
  }
3269
+
3270
+ menu(label: 'Window', underline: 0)
3271
+
3083
3272
  menu(label: 'Help', underline: 0) {
3273
+ menu_item(:help) {
3274
+ on('command') do
3275
+ message_box(parent: r, title: 'Help', message: 'Help for my application.')
3276
+ end
3277
+ }
3278
+
3084
3279
  menu_item(label: 'Manual', underline: 0) {
3085
3280
  accelerator 'Command+Shift+M'
3086
3281
 
@@ -3088,6 +3283,7 @@ root { |r|
3088
3283
  message_box(parent: r, title: 'Manual', message: 'Manual Contents')
3089
3284
  end
3090
3285
  }
3286
+
3091
3287
  menu_item(label: 'Tutorial', underline: 0) {
3092
3288
  accelerator 'Command+Shift+T'
3093
3289
 
@@ -3095,7 +3291,9 @@ root { |r|
3095
3291
  message_box(parent: r, title: 'Tutorial', message: 'Tutorial Contents')
3096
3292
  end
3097
3293
  }
3294
+
3098
3295
  menu_item(:separator)
3296
+
3099
3297
  menu_item(label: 'Report an Issue...', underline: 0) {
3100
3298
  on('command') do
3101
3299
  message_box(parent: r, title: 'Report an Issue', message: 'Reporting an issue...')
@@ -3158,7 +3356,7 @@ https://github.com/ancorgs/y3network-ruby-ui
3158
3356
 
3159
3357
  ### CryptoPunks GUI
3160
3358
 
3161
- This is a Graphical User Interface for the famous [cryptopunks Ruby gem](https://github.com/cryptopunksnotdead/cryptopunks/tree/master/cryptopunks).
3359
+ This is a Graphical User Interface for the [cryptopunks Ruby gem](https://github.com/cryptopunksnotdead/cryptopunks/tree/master/cryptopunks).
3162
3360
 
3163
3361
  https://github.com/cryptopunksnotdead/cryptopunks-gui
3164
3362
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.39
1
+ 0.0.40
Binary file
@@ -20,11 +20,14 @@
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
22
  require 'glimmer/tk/widget_proxy'
23
+ require 'glimmer/tk/scrollable'
23
24
 
24
25
  module Glimmer
25
26
  module Tk
26
27
  # Custom list widget implementation
27
28
  class ListProxy < WidgetProxy
29
+ include Scrollable
30
+
28
31
  def initialize(underscored_widget_name, parent_proxy, args)
29
32
  super('treeview', parent_proxy, args)
30
33
  @tk.show = 'tree'
@@ -164,11 +164,11 @@ module Glimmer
164
164
  # configures menu item attribute through parent menu
165
165
  def configure_menu_item_attribute(attribute_value_hash)
166
166
  if preferences? && attribute_value_hash[:command]
167
- ::Tk.ip_eval("proc ::tk::mac::ShowPreferences {} {#{::Tk.install_cmd(attribute_value_hash[:command])}}")
167
+ ::Tk.ip_eval("proc ::tk::mac::ShowPreferences {} {#{::Tk.install_cmd(attribute_value_hash[:command])}}") if OS.mac?
168
168
  elsif help? && attribute_value_hash[:command]
169
- ::Tk.ip_eval("proc ::tk::mac::ShowHelp {} {#{::Tk.install_cmd(attribute_value_hash[:command])}}")
169
+ ::Tk.ip_eval("proc ::tk::mac::ShowHelp {} {#{::Tk.install_cmd(attribute_value_hash[:command])}}") if OS.mac?
170
170
  elsif quit? && attribute_value_hash[:command]
171
- ::Tk.ip_eval("proc ::tk::mac::Quit {} {#{::Tk.install_cmd(attribute_value_hash[:command])}}")
171
+ ::Tk.ip_eval("proc ::tk::mac::Quit {} {#{::Tk.install_cmd(attribute_value_hash[:command])}}") if OS.mac?
172
172
  else
173
173
  @parent_proxy.tk.entryconfigure label, attribute_value_hash
174
174
  end
@@ -0,0 +1,49 @@
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
+ # Represents widgets that can scroll vertically and horizontally
27
+ module Scrollable
28
+ def xscrollcommand_block=(proc)
29
+ tk.xscrollcommand(proc)
30
+ end
31
+
32
+ def yscrollcommand_block=(proc)
33
+ tk.yscrollcommand(proc)
34
+ end
35
+
36
+ def handle_listener(listener_name, &listener)
37
+ case listener_name.to_s.downcase
38
+ when 'xscrollcommand'
39
+ xscrollcommand(listener)
40
+ when 'yscrollcommand'
41
+ yscrollcommand(listener)
42
+ else
43
+ super
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+
@@ -0,0 +1,31 @@
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
+ require 'glimmer/tk/commandable'
24
+
25
+ module Glimmer
26
+ module Tk
27
+ class ScrollbarProxy < WidgetProxy
28
+ include Commandable
29
+ end
30
+ end
31
+ 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/tk/widget_proxy'
23
+ require 'glimmer/tk/scrollable'
23
24
 
24
25
  module Glimmer
25
26
  module Tk
@@ -27,6 +28,8 @@ module Glimmer
27
28
  #
28
29
  # Follows the Proxy Design Pattern
29
30
  class TextProxy < WidgetProxy
31
+ include Scrollable
32
+
30
33
  ALL_TAG = '__all__'
31
34
  FORMAT_DEFAULT_MAP = {
32
35
  'justify' => 'left',
@@ -46,10 +46,13 @@ module Glimmer
46
46
  # This supports widgets in and out of basic Tk
47
47
  def tk_widget_class_for(underscored_widget_name)
48
48
  tk_widget_class_basename = underscored_widget_name.camelcase(:upper)
49
+ # TODO consider exposing this via Glimmer::Config
49
50
  potential_tk_widget_class_names = [
50
51
  "::Tk::Tile::#{tk_widget_class_basename}",
51
- "::Tk::#{tk_widget_class_basename}",
52
+ "::Tk::BWidget::#{tk_widget_class_basename}",
53
+ "::Tk::Iwidgets::#{tk_widget_class_basename}",
52
54
  "::Tk#{tk_widget_class_basename}",
55
+ "::Tk::#{tk_widget_class_basename}",
53
56
  "::Glimmer::Tk::#{tk_widget_class_basename}Proxy",
54
57
  ]
55
58
  tk_widget_class = nil
@@ -79,7 +82,7 @@ module Glimmer
79
82
  @block = block
80
83
  build_widget
81
84
  # a common widget initializer
82
- @parent_proxy.post_initialize_child(self)
85
+ @parent_proxy&.post_initialize_child(self)
83
86
  initialize_defaults
84
87
  post_add_content if @block.nil?
85
88
  end
@@ -247,9 +250,12 @@ module Glimmer
247
250
  end
248
251
  end
249
252
 
253
+ def index_in_parent
254
+ @parent_proxy&.children&.index(self)
255
+ end
256
+
250
257
  def grid(options = {})
251
258
  options = options.stringify_keys
252
- index_in_parent = @parent_proxy&.children&.index(self)
253
259
  options['rowspan'] = options.delete('row_span') if options.keys.include?('row_span')
254
260
  options['columnspan'] = options.delete('column_span') if options.keys.include?('column_span')
255
261
  options['rowweight'] = options.delete('row_weight') if options.keys.include?('row_weight')
@@ -268,7 +274,7 @@ module Glimmer
268
274
  TkGrid.columnconfigure(@parent_proxy.tk, index_in_parent, 'weight'=> options.delete('columnweight')) if options.keys.include?('columnweight')
269
275
  TkGrid.columnconfigure(@parent_proxy.tk, index_in_parent, 'minsize'=> options.delete('columnminsize')) if options.keys.include?('columnminsize')
270
276
  end
271
- @tk.grid(options)
277
+ griddable_tk&.grid(options)
272
278
  end
273
279
 
274
280
  def font=(value)
@@ -506,6 +512,11 @@ module Glimmer
506
512
 
507
513
  private
508
514
 
515
+ # The Tk element to apply grid to (is different from @tk in composite widgets like notebook or scrolledframe)
516
+ def griddable_tk
517
+ @tk
518
+ end
519
+
509
520
  def build_widget
510
521
  tk_widget_class = self.class.tk_widget_class_for(@keyword)
511
522
  @tk = tk_widget_class.new(@parent_proxy.tk, *args)
@@ -27,6 +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
32
  require 'os'
31
33
  require 'facets/hash/symbolize_keys'
32
34
  require 'facets/string/underscore'
@@ -46,6 +48,8 @@ Glimmer::Config.excluded_keyword_checkers << lambda do |method_symbol, *args|
46
48
  result ||= method == 'load_iseq'
47
49
  end
48
50
 
51
+ Tk::Tile::Style.theme_use 'alt' if OS.linux?
52
+
49
53
  ::TkOption.add '*tearOff', 0
50
54
 
51
55
  class ::Tk::TkSysMenu_Window < Tk::Menu
@@ -1,4 +1,4 @@
1
- `# Copyright (c) 2020-2021 Andy Maleh
1
+ # Copyright (c) 2020-2021 Andy Maleh
2
2
  #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
@@ -38,6 +38,7 @@ root { |r|
38
38
  }
39
39
 
40
40
  menu {
41
+ # Mac-specific application menu (right next to the Apple menu)
41
42
  if OS.mac?
42
43
  menu(:application) {
43
44
  menu_item(:about, label: 'About My Application') {
@@ -64,13 +65,14 @@ root { |r|
64
65
  }
65
66
  end
66
67
 
68
+ # Windows-specific system menu (to the top-left of the window frame)
67
69
  if OS.windows?
68
70
  menu(label: 'System')
69
71
  end
70
72
 
71
73
  menu(label: 'File', underline: 0) {
72
74
  menu_item(label: 'New', underline: 0) {
73
- accelerator 'Command+N'
75
+ accelerator OS.mac? ? 'Command+N' : 'Control+N'
74
76
 
75
77
  on('command') do
76
78
  message_box(parent: r, title: 'New', message: 'New file created.')
@@ -78,7 +80,7 @@ root { |r|
78
80
  }
79
81
 
80
82
  menu_item(label: 'Open...', underline: 0) {
81
- accelerator 'Command+O'
83
+ accelerator OS.mac? ? 'Command+O' : 'Control+O'
82
84
 
83
85
  on('command') do
84
86
  message_box(parent: r, title: 'Open', message: 'Opening File...')
@@ -110,15 +112,15 @@ root { |r|
110
112
 
111
113
  menu(label: 'Edit', underline: 0) {
112
114
  menu_item(label: 'Cut', underline: 2) {
113
- accelerator 'Command+X'
115
+ accelerator OS.mac? ? 'Command+X' : 'Control+X'
114
116
  }
115
117
 
116
118
  menu_item(label: 'Copy', underline: 0) {
117
- accelerator 'Command+C'
119
+ accelerator OS.mac? ? 'Command+C' : 'Control+C'
118
120
  }
119
121
 
120
122
  menu_item(label: 'Paste', underline: 0) {
121
- accelerator 'Command+V'
123
+ accelerator OS.mac? ? 'Command+V' : 'Control+V'
122
124
  }
123
125
  }
124
126
 
@@ -130,7 +132,7 @@ root { |r|
130
132
  end
131
133
  }
132
134
 
133
- @select_one_menu = menu(label: 'Select One', underline: 0) {
135
+ @select_one_menu = menu(label: 'Select One', underline: 7) {
134
136
  menu_item(:radiobutton, label: 'Option 1') {
135
137
  state 'disabled'
136
138
  }
@@ -142,7 +144,7 @@ root { |r|
142
144
  }
143
145
  }
144
146
 
145
- @select_multiple_menu = menu(label: 'Select Multiple', underline: 0) {
147
+ @select_multiple_menu = menu(label: 'Select Multiple', underline: 7) {
146
148
  menu_item(:checkbutton, label: 'Option 4') {
147
149
  state 'disabled'
148
150
  }
@@ -164,7 +166,7 @@ root { |r|
164
166
  end
165
167
  }
166
168
 
167
- menu(label: 'Language Name', underline: 3) {
169
+ menu(label: 'Country', underline: 3) {
168
170
  ['denmark', 'finland', 'france', 'germany', 'italy', 'mexico', 'netherlands', 'norway', 'usa'].each do |image_name|
169
171
  menu_item(:radiobutton, label: image_name.capitalize) {
170
172
  selection image_name == 'usa'
@@ -198,7 +200,7 @@ root { |r|
198
200
 
199
201
  menu(label: 'View', underline: 0) {
200
202
  menu_item(:radiobutton, label: 'Small', underline: 0) {
201
- accelerator 'Command+S'
203
+ accelerator OS.mac? ? 'Command+S' : 'Control+S'
202
204
 
203
205
  on('command') do
204
206
  @label.font = {size: 25}
@@ -206,7 +208,7 @@ root { |r|
206
208
  }
207
209
 
208
210
  menu_item(:radiobutton, label: 'Medium', underline: 0) {
209
- accelerator 'Command+M'
211
+ accelerator OS.mac? ? 'Command+M' : 'Control+M'
210
212
  selection true
211
213
 
212
214
  on('command') do
@@ -215,7 +217,7 @@ root { |r|
215
217
  }
216
218
 
217
219
  menu_item(:radiobutton, label: 'Large', underline: 0) {
218
- accelerator 'Command+L'
220
+ accelerator OS.mac? ? 'Command+L' : 'Control+L'
219
221
 
220
222
  on('command') do
221
223
  @label.font = {size: 75}
@@ -223,17 +225,20 @@ root { |r|
223
225
  }
224
226
  }
225
227
 
226
- menu(label: 'Window', underline: 0)
228
+ # Mac-specific window menu (containing zooming/resizing menu items)
229
+ menu(label: 'Window', underline: 0) if OS.mac?
227
230
 
228
231
  menu(label: 'Help', underline: 0) {
229
- menu_item(:help) {
230
- on('command') do
231
- message_box(parent: r, title: 'Help', message: 'Help for my application.')
232
- end
233
- }
232
+ if OS.mac?
233
+ menu_item(:help) {
234
+ on('command') do
235
+ message_box(parent: r, title: 'Help', message: 'Help for my application.')
236
+ end
237
+ }
238
+ end
234
239
 
235
240
  menu_item(label: 'Manual', underline: 0) {
236
- accelerator 'Command+Shift+M'
241
+ accelerator OS.mac? ? 'Command+Shift+M' : 'Control+U'
237
242
 
238
243
  on('command') do
239
244
  message_box(parent: r, title: 'Manual', message: 'Manual Contents')
@@ -241,7 +246,7 @@ root { |r|
241
246
  }
242
247
 
243
248
  menu_item(label: 'Tutorial', underline: 0) {
244
- accelerator 'Command+Shift+T'
249
+ accelerator OS.mac? ? 'Command+Shift+T' : 'Control+T'
245
250
 
246
251
  on('command') do
247
252
  message_box(parent: r, title: 'Tutorial', message: 'Tutorial Contents')
@@ -0,0 +1,67 @@
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-dsl-tk'
23
+
24
+ include Glimmer
25
+
26
+ root {
27
+ title 'Hello, Scrollbar!'
28
+ width 400
29
+ height 500
30
+
31
+ notebook {
32
+ grid sticky: 'nsew', row_weight: 1, column_weight: 1
33
+
34
+ frame(text: 'Scrollable List') {
35
+ @list = list {
36
+ grid sticky: 'nsew', row: 0, column: 0, row_weight: 1, column_weight: 1
37
+ items 40.times.map {|n| "Item #{n + 1} of a very long list" }
38
+ }
39
+
40
+ @scrollbar = scrollbar {
41
+ grid row: 0, column: 1
42
+ # orient 'vertical' # default
43
+ }
44
+ @list.yscrollbar @scrollbar
45
+ }
46
+
47
+ frame(text: 'Scrollable Text') {
48
+ @text = text {
49
+ grid sticky: 'nsew', row: 0, column: 0, row_weight: 1, column_weight: 1
50
+ value ("This is a random sample of text that will repeat over and over and over"*2 + "\n")*40
51
+ }
52
+
53
+ @yscrollbar = scrollbar {
54
+ grid row: 0, column: 1
55
+ # orient 'vertical' # default
56
+ }
57
+ @text.yscrollbar @yscrollbar
58
+
59
+ @xscrollbar = scrollbar {
60
+ grid row: 1, column: 0, column_span: 2, row_weight: 0
61
+ orient 'horizontal'
62
+ }
63
+ @text.xscrollbar @xscrollbar
64
+ }
65
+ }
66
+
67
+ }.open
@@ -105,32 +105,32 @@ class HelloText
105
105
  height 800
106
106
 
107
107
  frame {
108
- grid row: 0, column: 0
108
+ grid row: 0, column: 0, column_span: 2
109
109
 
110
110
  column_index = -1
111
111
 
112
112
  combobox { |cb|
113
113
  grid row: 1, column: column_index += 1, column_weight: 1
114
114
  readonly true
115
- text <=> [self, :font_family, after_write: ->(value) { @text.toggle_selection_font_format('family', value == FONT_FAMILY_PROMPT ? 'Courier New' : value, focus: 100) }]
115
+ text <=> [self, :font_family, after_write: ->(value) { @text.toggle_selection_font_format('family', value == FONT_FAMILY_PROMPT ? 'Courier New' : value, focus: OS.mac? ? 100 : true) }]
116
116
  }
117
117
 
118
118
  combobox {
119
119
  grid row: 1, column: column_index += 1, column_weight: 1
120
120
  readonly true
121
- text <=> [self, :font_size, after_write: ->(value) { @text.toggle_selection_font_format('size', value == FONT_SIZE_PROMPT ? 13 : value, focus: 100) }]
121
+ text <=> [self, :font_size, after_write: ->(value) { @text.toggle_selection_font_format('size', value == FONT_SIZE_PROMPT ? 13 : value, focus: OS.mac? ? 100 : true) }]
122
122
  }
123
123
 
124
124
  combobox {
125
125
  grid row: 1, column: column_index += 1, column_weight: 1
126
126
  readonly true
127
- text <=> [self, :foreground, after_write: ->(value) { @text.add_selection_format('foreground', value == FOREGROUND_PROMPT ? 'black' : value, focus: 100) }]
127
+ text <=> [self, :foreground, after_write: ->(value) { @text.add_selection_format('foreground', value == FOREGROUND_PROMPT ? 'black' : value, focus: OS.mac? ? 100 : true) }]
128
128
  }
129
129
 
130
130
  combobox {
131
131
  grid row: 1, column: column_index += 1, column_weight: 1
132
132
  readonly true
133
- text <=> [self, :background, after_write: ->(value) { @text.add_selection_format('background', value == BACKGROUND_PROMPT ? 'white' : value, focus: 100) }]
133
+ text <=> [self, :background, after_write: ->(value) { @text.add_selection_format('background', value == BACKGROUND_PROMPT ? 'white' : value, focus: OS.mac? ? 100 : true) }]
134
134
  }
135
135
 
136
136
  separator {
@@ -282,7 +282,7 @@ class HelloText
282
282
 
283
283
  @text = text {
284
284
  grid row: 1, column: 0, row_weight: 1
285
- wrap 'word'
285
+ # wrap 'word'
286
286
  undo true
287
287
  value <=> [self, :document]
288
288
 
@@ -303,6 +303,16 @@ class HelloText
303
303
  show_find_dialog if (event.keysym == 'f') && ((OS.mac? && event.state == 8) || (!OS.mac? && event.state == 4))
304
304
  end
305
305
  }
306
+
307
+ @yscrollbar = y_scrollbar {
308
+ grid row: 1, column: 1
309
+ }
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
306
316
  }
307
317
  @root.open
308
318
  end
@@ -74,7 +74,7 @@ root { |root_window|
74
74
 
75
75
  frame {
76
76
  label {
77
- text "This is a transparent window\nYou can hit ESCAPE to close."
77
+ text "This is a transparent window\n(Varies per platform)\nYou can hit ESCAPE to close."
78
78
  anchor 'center'
79
79
  }
80
80
  }
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.39
4
+ version: 0.0.40
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 00:00:00.000000000 Z
11
+ date: 2021-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: glimmer
@@ -240,6 +240,8 @@ files:
240
240
  - lib/glimmer/tk/notebook_proxy.rb
241
241
  - lib/glimmer/tk/radiobutton_proxy.rb
242
242
  - lib/glimmer/tk/root_proxy.rb
243
+ - lib/glimmer/tk/scrollable.rb
244
+ - lib/glimmer/tk/scrollbar_proxy.rb
243
245
  - lib/glimmer/tk/spinbox_proxy.rb
244
246
  - lib/glimmer/tk/text_proxy.rb
245
247
  - lib/glimmer/tk/text_variable_owner.rb
@@ -265,6 +267,7 @@ files:
265
267
  - samples/hello/hello_notebook.rb
266
268
  - samples/hello/hello_radiobutton.rb
267
269
  - samples/hello/hello_root.rb
270
+ - samples/hello/hello_scrollbar.rb
268
271
  - samples/hello/hello_separator.rb
269
272
  - samples/hello/hello_spinbox.rb
270
273
  - samples/hello/hello_text.rb