Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# v0.0.23 - 17 February 2025

* Exposed `@text_keys` as an instance variable instead of a local.
* Wrote up notes on custom keyboard handling with a filtering example.
* Documented `#delete_forward` and `#delete_back` methods.
* Deprecated `on_clicked` and added `on_click` in it's place.
* Documented `focused` argument and `#focused?` aliases for `focussed` and `#focussed?`

# v0.0.22 - 9 February 2025

* Fixed a bug when using `max_length` where `selection_end` (and `selection_start`) where incorrectly set (thanks to @TheCire for reporting in Discord).
Expand Down
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,10 @@ The argument list below will list `prompt_color` but not the individual `prompt_
* `word_wrap` - if the control should wrap (Boolean), default false
* `readonly` - initial input read only state (Boolean), default false
* `focussed` - initial input focus (Boolean), default false
* `on_clicked` - on click callback, receives 2 parameters, the click and the `Input` control instance, default NOOP
* `on_unhandled_key` - on unhandle key pressed callback, receives 2 parameters, the key and the `Input` control instance, default NOOP. This callback receives keys like `[tab]` and `[enter]`
* `focused` - Alias for `focussed`
* `on_clicked` - Deprecated - use `on_click`
* `on_click` - on click callback, receives 2 parameters, the click and the `Input` control instance, default `NOOP`
* `on_unhandled_key` - on unhandle key pressed callback, receives 2 parameters, the key and the `Input` control instance, default NOOP. This callback receives keys like `[tab]` and `[enter]` as symbols, so `:tab` and `:enter`
* `max_length` - maximum allowed length (Integer), default `false` which disables length checks
* `fill_from_bottom` - fill the text from the bottom, like for a log or game terminal, default `false`
* `draw_autocomplete_menu` - if the input draws the autocomplete menu automatically, default `true`
Expand Down Expand Up @@ -112,6 +114,9 @@ The argument list below will list `prompt_color` but not the individual `prompt_
* `#replace(text)` - Alias for `#insert(text)`
* `#replace_at(text, start, end = start)` - Alias for `#insert_at(text, start, end = start)`
* `#append(text)` - Appends text the end of the value, without changing the selection
* `#delete_forward` - Deletes selection or the character to the right of the cursor location if the selection is empty (typically in response to the `Delete` key)
* `#delete_back` - Deletes selection or the character to the left of the cursor location if the selection is empty (typically in response to the `Backspace` key)
* `#current_selection` - Returns the currently selected text
* `#current_selection` - Returns the currently selected text
* `#current_line` - Returns the currently selected line object
* `#current_word` - Returns the word currently under the cursor
Expand Down Expand Up @@ -146,8 +151,34 @@ The argument list below will list `prompt_color` but not the individual `prompt_
* `#focus` - Focusses the instance. Note the instance will only receive the focus after it's rendered. This prevents multiple instances from handling the keyboard and mouse events in the same tick.
* `#blur` - Removes the focus from the instance. This happens immediately and the instance will not process keyboard and some mouse events after being blurred.
* `#focussed?` - Returns true if the input is focussed, false otherwise
* `#focused?` - Alias for `#focussed?`
* `#value_changed?` - Returns true if the input value changed in the last tick, false otherwise

## Custom keyboard handling

There may be cases where you want to do some custom keyboard handling, like filtering out certain characters. In order to do this, create a subclass of `Input::Text` or `Input::Multiline` and override the `handle_keyboard` method, calling `super` when your special handling is done. The following instance variables are available:

* `@meta` - true if the Meta key is down (the Command key on a Mac, or Windows key on Windows)
* `@alt` - true if the Alt key is down
* `@shift` - true if the Shift key is down or `shift_lock` is set
* `@ctrl` - true if the Control key is down
* `@down_keys` - an `Array` of `Symbol`s of keys that are down excluding the special keys above
* `@text_keys` - an `Array` of printable characters that has been typed this tick

### Example: filtering

``` ruby
class FilenameInput < Input::Text
ALLOWED_CHARS = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a + ['_', '-', '.']

def handle_keyboard
@text_keys.select! { |key| ALLOWED_CHARS.include?(key) }

super
end
end
```

## Console replacement

This library includes the ability to replace the default DragonRuby Console (`~`). Simply call `Input.replace_console!` once to enable this.
Expand Down
4 changes: 2 additions & 2 deletions app/book_sample.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def tick(args)
args.state.multiline.focus
end
end,
on_clicked: lambda do |_mouse, input|
on_click: lambda do |_mouse, input|
input.focus
args.state.multiline.blur
end,
Expand All @@ -70,7 +70,7 @@ def tick(args)
args.state.text.focus
end
end,
on_clicked: lambda do |_mouse, input|
on_click: lambda do |_mouse, input|
input.focus
args.state.text.blur
end
Expand Down
2 changes: 1 addition & 1 deletion lib/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def initialize(**params) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticCo
@focussed = params[:focussed] || params[:focused] || false
@will_focus = false # Get the focus at the end of the tick

@on_clicked = params[:on_clicked] || NOOP
@on_click = params[:on_click] || params[:on_clicked] || NOOP
# @on_handled_key = params[:on_handled_key] || NOOP
@on_unhandled_key = params[:on_unhandled_key] || NOOP

Expand Down
2 changes: 2 additions & 0 deletions lib/keyboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ def prepare_special_keys # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
@alt = (special_keys & ALT_KEYS).any?
@shift = @shift_lock || (special_keys & SHIFT_KEYS).any?
@ctrl = (special_keys & CTRL_KEYS).any?

@text_keys = $args.inputs.text
end
end
end
1 change: 0 additions & 1 deletion lib/line_collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ def perform_word_wrap(text, width, first_line_number = 0, first_line_start = 0,

# break up long words
w = @font_style.string_width(word.rstrip)
# TODO: make this a binary search
while w > width
r = word.length - 1
l = 0
Expand Down
7 changes: 3 additions & 4 deletions lib/multiline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ def draw_override(ffi)
end

def handle_keyboard
text_keys = $args.inputs.text
# On a Mac:
# Home is Cmd + ↑ / Fn + ←
# End is Cmd + ↓ / Fn + →
Expand Down Expand Up @@ -103,7 +102,7 @@ def handle_keyboard
else
@on_unhandled_key.call(@down_keys.first, self)
end
elsif text_keys.empty?
elsif @text_keys.empty?
if @down_keys.include?(:delete)
delete_forward unless @readonly
@ensure_cursor_visible = true
Expand Down Expand Up @@ -164,7 +163,7 @@ def handle_keyboard
@on_unhandled_key.call(@down_keys.first, self)
end
else
insert(text_keys.join('')) unless @readonly
insert(@text_keys.join('')) unless @readonly
@ensure_cursor_visible = true
end
end
Expand Down Expand Up @@ -303,7 +302,7 @@ def handle_mouse # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
@selection_end = index
@mouse_down = false if mouse.up
else # clicking
@on_clicked.call(mouse, self)
@on_click.call(mouse, self)
return unless (@focussed || @will_focus) && mouse.button_left

if @shift
Expand Down
8 changes: 3 additions & 5 deletions lib/text.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ def draw_override(ffi)
end

def handle_keyboard
text_keys = $args.inputs.text

if @meta || @ctrl
# TODO: undo/redo
if @down_keys.include?(:a)
Expand All @@ -57,7 +55,7 @@ def handle_keyboard
else
@on_unhandled_key.call(@down_keys.first, self)
end
elsif text_keys.empty?
elsif @text_keys.empty?
if @down_keys.include?(:delete)
delete_forward unless @readonly
elsif @down_keys.include?(:backspace)
Expand Down Expand Up @@ -88,7 +86,7 @@ def handle_keyboard
@on_unhandled_key.call(@down_keys.first, self)
end
else
insert(text_keys.join('')) unless @readonly
insert(@text_keys.join('')) unless @readonly
@ensure_cursor_visible = true
end
end
Expand All @@ -110,7 +108,7 @@ def handle_mouse # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
@selection_end = index
@mouse_down = false if mouse.up
else
@on_clicked.call(mouse, self)
@on_click.call(mouse, self)
return unless @focussed || @will_focus

@mouse_down = true
Expand Down
2 changes: 1 addition & 1 deletion metadata/game_metadata.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ devid=fascinationworks
devtitle=Fascination Works
gameid=dr-input
gametitle=Dragon Ruby Input
version=0.0.22
version=0.0.23
icon=metadata/icon.png

# === Flags available at all licensing tiers ===
Expand Down
Loading