diff --git a/CHANGELOG.md b/CHANGELOG.md index e201f5e..7cbe10c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## 0.0.37 + +- Have `text` widget grab focus after every formatting modification in Hello, Text! (e.g. after clicking `B` for Bold) + ## 0.0.36 - Hello, Toplevel! (Custom Window and Custom Dialog) diff --git a/README.md b/README.md index c9fdd18..cea44bb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# [](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Tk 0.0.36 +# [](https://github.com/AndyObtiva/glimmer) Glimmer DSL for Tk 0.0.37 ## MRI Ruby Desktop Development GUI Library [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-tk.svg)](http://badge.fury.io/rb/glimmer-dsl-tk) [![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) @@ -161,7 +161,7 @@ gem install glimmer-dsl-tk Add the following to `Gemfile`: ``` -gem 'glimmer-dsl-tk', '~> 0.0.36' +gem 'glimmer-dsl-tk', '~> 0.0.37' ``` And, then run: @@ -352,12 +352,12 @@ The `text` widget is enhanced by [Glimmer DSL for Tk](https://rubygems.org/gems/ - `add_font_format(region_start, region_end, font_option, value)` - `remove_font_format(region_start, region_end, font_option, value)` - `toggle_font_format(region_start, region_end, font_option, value)` -- `add_selection_format(option, value, no_selection_default: :insert_word)`: adds format to selection. If there is no selection, then applies format to current insert mark word. -- `remove_selection_format(option, value, no_selection_default: :insert_word)` -- `toggle_selection_format(option, value, no_selection_default: :insert_word)`: toggles format on selection. If there is no selection, then toggles format on current insert mark word. -- `add_selection_font_format(font_option, value, no_selection_default: :insert_word)` -- `remove_selection_font_format(font_option, value, no_selection_default: :insert_word)` -- `toggle_selection_font_format(font_option, value, no_selection_default: :insert_word)` +- `add_selection_format(option, value, no_selection_default: :insert_word, focus: true)`: adds format to selection. If there is no selection, then applies format to current insert mark word. +- `remove_selection_format(option, value, no_selection_default: :insert_word, focus: true)` +- `toggle_selection_format(option, value, no_selection_default: :insert_word, focus: true)`: toggles format on selection. If there is no selection, then toggles format on current insert mark word. +- `add_selection_font_format(font_option, value, no_selection_default: :insert_word, focus: true)` +- `remove_selection_font_format(font_option, value, no_selection_default: :insert_word, focus: true)` +- `toggle_selection_font_format(font_option, value, no_selection_default: :insert_word, focus: true)` - `text#insert_image(text_index, *image_args)`: inserts image into `text` `value` content at `text_index` location (e.g. `'insert'`) - `text#get_open_file_to_insert_image(text_index = 'insert')`: opens a file dialog to select one of the available image formats and then inserts image into `text` `value` content @@ -366,6 +366,9 @@ The `:no_selection_default` keyword arg to `*_selection_*` methods determines wh - `:insert_letter`: current letter for insert mark - `:none`: no behavior when no selection is in place +The `:focus` keyword arg defaults to `true` to indicate that the `text` widget should automatically grab focus after formatting modification. +Also, the `:focus` keyword arg can have an integer value representing number of milliseconds after which to grab focus once the formatting modification is done. This helps in special situations like when making the formatting modification from a combobox, which takes a while before relinquishing focus, so adding `100` millisecond delay helps ensure the `text` widget grabs focus after modification. Check [Hello, Text!](#hello-text) for an example of that. + Available options: - `background` @@ -2190,28 +2193,28 @@ class HelloText column_index = -1 - combobox { + combobox { |cb| grid row: 1, column: column_index += 1, column_weight: 1 readonly true - text <=> [self, :font_family, after_write: ->(value) { @text.toggle_selection_font_format('family', value == FONT_FAMILY_PROMPT ? 'Courier New' : value) }] + text <=> [self, :font_family, after_write: ->(value) { @text.toggle_selection_font_format('family', value == FONT_FAMILY_PROMPT ? 'Courier New' : value, focus: 100) }] } combobox { grid row: 1, column: column_index += 1, column_weight: 1 readonly true - text <=> [self, :font_size, after_write: ->(value) { @text.toggle_selection_font_format('size', value == FONT_SIZE_PROMPT ? 13 : value) }] + text <=> [self, :font_size, after_write: ->(value) { @text.toggle_selection_font_format('size', value == FONT_SIZE_PROMPT ? 13 : value, focus: 100) }] } combobox { grid row: 1, column: column_index += 1, column_weight: 1 readonly true - text <=> [self, :foreground, after_write: ->(value) { @text.add_selection_format('foreground', value == FOREGROUND_PROMPT ? 'black' : value) }] + text <=> [self, :foreground, after_write: ->(value) { @text.add_selection_format('foreground', value == FOREGROUND_PROMPT ? 'black' : value, focus: 100) }] } combobox { grid row: 1, column: column_index += 1, column_weight: 1 readonly true - text <=> [self, :background, after_write: ->(value) { @text.add_selection_format('background', value == BACKGROUND_PROMPT ? 'white' : value) }] + text <=> [self, :background, after_write: ->(value) { @text.add_selection_format('background', value == BACKGROUND_PROMPT ? 'white' : value, focus: 100) }] } separator { @@ -2367,10 +2370,6 @@ class HelloText undo true value <=> [self, :document] - on('KeyPress') do |event| - show_find_dialog if (event.keysym == 'f') && ((OS.mac? && event.state == 8) || (!OS.mac? && event.state == 4)) - end - on('InsertMarkMoved') do self.font_family = @text.applied_font_format_value('family') self.font_size = @text.applied_font_format_value('size') @@ -2383,6 +2382,10 @@ class HelloText @justify_center_button.default = @text.applied_format_value('justify') == 'center' ? 'active' : 'normal' @justify_right_button.default = @text.applied_format_value('justify') == 'right' ? 'active' : 'normal' end + + on('KeyPress') do |event| + show_find_dialog if (event.keysym == 'f') && ((OS.mac? && event.state == 8) || (!OS.mac? && event.state == 4)) + end } } @root.open diff --git a/TODO.md b/TODO.md index f146c44..00c53fc 100644 --- a/TODO.md +++ b/TODO.md @@ -17,6 +17,7 @@ - Allow setting root x/y without affecting its default width/height - Look into updating block_attribute expression to not require defining blocks that simply forward to tk on the widget - Document Glimmer debug logging +- Make Glimmer tolerate adding extra '<>' to event names when they don't need it (e.g. binding `''` on `text` widget works just like `'KeyPress'`) ## General diff --git a/VERSION b/VERSION index e85669f..1435d6c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.36 +0.0.37 diff --git a/glimmer-dsl-tk.gemspec b/glimmer-dsl-tk.gemspec index f58fa27..e4b0ba9 100644 Binary files a/glimmer-dsl-tk.gemspec and b/glimmer-dsl-tk.gemspec differ diff --git a/lib/glimmer/tk/text_proxy.rb b/lib/glimmer/tk/text_proxy.rb index b63f74a..c07103c 100644 --- a/lib/glimmer/tk/text_proxy.rb +++ b/lib/glimmer/tk/text_proxy.rb @@ -92,31 +92,31 @@ def edit_redo end end - def add_selection_format(option, value, no_selection_default: :insert_word) - process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| add_format(range_start, range_end, option, value) } + def add_selection_format(option, value, no_selection_default: :insert_word, focus: true) + process_selection_ranges(no_selection_default: no_selection_default, focus: focus) { |range_start, range_end| add_format(range_start, range_end, option, value) } end - def remove_selection_format(option, value, no_selection_default: :insert_word) - process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| remove_format(range_start, range_end, option, value) } + def remove_selection_format(option, value, no_selection_default: :insert_word, focus: true) + process_selection_ranges(no_selection_default: no_selection_default, focus: focus) { |range_start, range_end| remove_format(range_start, range_end, option, value) } end - def toggle_selection_format(option, value, no_selection_default: :insert_word) - process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| toggle_format(range_start, range_end, option, value) } + def toggle_selection_format(option, value, no_selection_default: :insert_word, focus: true) + process_selection_ranges(no_selection_default: no_selection_default, focus: focus) { |range_start, range_end| toggle_format(range_start, range_end, option, value) } end - def add_selection_font_format(option, value, no_selection_default: :insert_word) - process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| add_font_format(range_start, range_end, option, value) } + def add_selection_font_format(option, value, no_selection_default: :insert_word, focus: true) + process_selection_ranges(no_selection_default: no_selection_default, focus: focus) { |range_start, range_end| add_font_format(range_start, range_end, option, value) } end - def remove_selection_font_format(option, value, no_selection_default: :insert_word) - process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| remove_font_format(range_start, range_end, option, value) } + def remove_selection_font_format(option, value, no_selection_default: :insert_word, focus: true) + process_selection_ranges(no_selection_default: no_selection_default, focus: focus) { |range_start, range_end| remove_font_format(range_start, range_end, option, value) } end - def toggle_selection_font_format(option, value, no_selection_default: :insert_word) - process_selection_ranges(no_selection_default: no_selection_default) { |range_start, range_end| toggle_font_format(range_start, range_end, option, value) } + def toggle_selection_font_format(option, value, no_selection_default: :insert_word, focus: true) + process_selection_ranges(no_selection_default: no_selection_default, focus: focus) { |range_start, range_end| toggle_font_format(range_start, range_end, option, value) } end - def process_selection_ranges(no_selection_default: :insert_word, &processor) + def process_selection_ranges(no_selection_default: :insert_word, focus: true, &processor) regions = @tk.tag_ranges('sel') if regions.empty? case no_selection_default @@ -131,6 +131,11 @@ def process_selection_ranges(no_selection_default: :insert_word, &processor) range_end = region.last processor.call(range_start, range_end) end + if focus == true + @tk.focus + elsif focus.is_a?(Integer) + ::Tk.after(focus) { @tk.focus } + end end def applied_format?(region_start, region_end, option, value) diff --git a/samples/hello/hello_text.rb b/samples/hello/hello_text.rb index df0df32..53f99bd 100644 --- a/samples/hello/hello_text.rb +++ b/samples/hello/hello_text.rb @@ -109,28 +109,28 @@ def launch column_index = -1 - combobox { + combobox { |cb| grid row: 1, column: column_index += 1, column_weight: 1 readonly true - text <=> [self, :font_family, after_write: ->(value) { @text.toggle_selection_font_format('family', value == FONT_FAMILY_PROMPT ? 'Courier New' : value) }] + text <=> [self, :font_family, after_write: ->(value) { @text.toggle_selection_font_format('family', value == FONT_FAMILY_PROMPT ? 'Courier New' : value, focus: 100) }] } combobox { grid row: 1, column: column_index += 1, column_weight: 1 readonly true - text <=> [self, :font_size, after_write: ->(value) { @text.toggle_selection_font_format('size', value == FONT_SIZE_PROMPT ? 13 : value) }] + text <=> [self, :font_size, after_write: ->(value) { @text.toggle_selection_font_format('size', value == FONT_SIZE_PROMPT ? 13 : value, focus: 100) }] } combobox { grid row: 1, column: column_index += 1, column_weight: 1 readonly true - text <=> [self, :foreground, after_write: ->(value) { @text.add_selection_format('foreground', value == FOREGROUND_PROMPT ? 'black' : value) }] + text <=> [self, :foreground, after_write: ->(value) { @text.add_selection_format('foreground', value == FOREGROUND_PROMPT ? 'black' : value, focus: 100) }] } combobox { grid row: 1, column: column_index += 1, column_weight: 1 readonly true - text <=> [self, :background, after_write: ->(value) { @text.add_selection_format('background', value == BACKGROUND_PROMPT ? 'white' : value) }] + text <=> [self, :background, after_write: ->(value) { @text.add_selection_format('background', value == BACKGROUND_PROMPT ? 'white' : value, focus: 100) }] } separator {