a27f41a601
This commit introduces a significant enhancement to the DynamicCursesInput gem, enabling the creation of colored text windows within the terminal. The new `DynamicCursesInput::ColorWindow` class provides methods to add colored text to the window and handle user input. Notable changes in this commit include: - Implementation of colored windows with customizable color schemes and text content. - Automatic centering of text within the window when 'x' is set to 'center.' - Fine-tuning of centered positioning to shift back by 12 cells for improved visual layout. - Removal of Fiber reliance and adoption of instance methods to resolve positioning issues. - Compatibility fixes for different terminal environments to ensure consistent behavior. Additionally, bug fixes have been made to resolve issues related to text misalignment and window positioning. This feature-rich update aims to improve the user experience and offer better control over window positioning and color schemes. We hope these enhancements will be beneficial to our users. Feedback and suggestions are always welcome!
90 lines
2.9 KiB
Ruby
90 lines
2.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# lib/dynamic_curses_input.rb
|
|
|
|
require 'readline' # Add the Readline module
|
|
require_relative 'dynamic_curses_input/version'
|
|
require_relative 'dynamic_curses_input/input_handler'
|
|
require_relative 'dynamic_curses_input/color_window'
|
|
|
|
# The module entrypoint for our Gem
|
|
module DynamicCursesInput
|
|
class Error < StandardError; end
|
|
|
|
def self.catch_input(echo)
|
|
InputHandler.catch_input(echo)
|
|
end
|
|
|
|
def self.ask_question(color = 'white', question, x: 'center', input: true, echo: nil)
|
|
Curses.clear
|
|
ColorWindow.add_color_window(color, question, y:, x:, input:, echo:)
|
|
end
|
|
|
|
def self.print_color_window(color, text, y_value: nil, x: 'center', input: nil, echo: true)
|
|
case x
|
|
when 'center'
|
|
terminal_size = `stty size`.split.map(&:to_i)
|
|
y_value = terminal_size[0] / 2
|
|
x_value = terminal_size[1] / 2 - text.length / 2 # Adjust x-coordinate to center the window
|
|
x_value -= 12 if x_value > 1
|
|
# the above line shifts the X value of the cell coords back by 12 cells if we are trying to center the window
|
|
# we have to do this because math gets kind of approximate when we convert pixel ratios to character cell coords
|
|
when 'left'
|
|
y_value = Curses.lines / 2
|
|
x_value = 0
|
|
when 'right'
|
|
y_value = Curses.lines / 2
|
|
x_value = Curses.cols - text.length
|
|
when 'left_center'
|
|
y_value = Curses.lines / 4
|
|
x_value = 0
|
|
when 'right_center'
|
|
y_value = Curses.lines / 4
|
|
x_value = Curses.cols - text.length
|
|
else
|
|
y_value, x_value = x.split('px').map(&:to_i)
|
|
end
|
|
|
|
# Initialize curses and get the terminal size
|
|
Curses.init_screen
|
|
Curses.start_color
|
|
Curses.refresh
|
|
|
|
# Set up Readline for proper terminal settings
|
|
setup_readline
|
|
|
|
ColorWindow.new(echo, x_value, y_value).add_color_window(color, text, x_value, y_value, input:, echo:)
|
|
end
|
|
|
|
class << self
|
|
private
|
|
|
|
def process_print_color_window_args(args)
|
|
case args.size
|
|
when 2
|
|
['white', args[0], args[1], 'center', nil, true]
|
|
when 3
|
|
['white', args[0], args[1], args[2], nil, true]
|
|
when 4
|
|
['white', args[0], args[1], args[2], args[3], true]
|
|
when 5
|
|
[args[0], args[1], args[2], args[3], args[4]]
|
|
else
|
|
raise ArgumentError, 'print_color_window accepts 2 to 5 arguments: color, text, [position], [input], [echo]'
|
|
end
|
|
end
|
|
end
|
|
|
|
def self.setup_readline
|
|
# Set up Readline for proper terminal settings
|
|
Readline.emacs_editing_mode
|
|
# the above line sets Readline to emacs_editing_mode so that terminals behave like they're supposed to
|
|
Readline.completion_append_character = ' '
|
|
# we remove Readlines thing where it adds a space to the end of tab completes because it breaks the Curses cursor
|
|
Readline.completion_proc = proc { |_s| [] }
|
|
# here we basically are disabling tab completion all together. That's because for some reason it breaks the cursor
|
|
end
|
|
end
|
|
|
|
DCI = DynamicCursesInput
|