glimmer-dsl-tk 0.0.39 → 0.0.40

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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