Skip to content

Commit

Permalink
Have text widget grab focus after every formatting modification in …
Browse files Browse the repository at this point in the history
…Hello, Text! (e.g. after clicking `B` for Bold)
  • Loading branch information
AndyObtiva committed Nov 6, 2021
1 parent ef5cfae commit 9399955
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 36 deletions.
4 changes: 4 additions & 0 deletions 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)
Expand Down
37 changes: 20 additions & 17 deletions README.md
@@ -1,4 +1,4 @@
# [<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.36
# [<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.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)
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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

Expand All @@ -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`
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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')
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions TODO.md
Expand Up @@ -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 `'<KeyPress>'` on `text` widget works just like `'KeyPress'`)

## General

Expand Down
2 changes: 1 addition & 1 deletion VERSION
@@ -1 +1 @@
0.0.36
0.0.37
Binary file modified glimmer-dsl-tk.gemspec
Binary file not shown.
31 changes: 18 additions & 13 deletions lib/glimmer/tk/text_proxy.rb
Expand Up @@ -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
Expand All @@ -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)
Expand Down
10 changes: 5 additions & 5 deletions samples/hello/hello_text.rb
Expand Up @@ -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 {
Expand Down

0 comments on commit 9399955

Please sign in to comment.