1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

[ruby/reline] Implement scrollbar

https://github.com/ruby/reline/commit/4c7fc42151
This commit is contained in:
aycabta 2021-09-04 07:29:23 +09:00
parent ff372ed74b
commit ec36ceb072
2 changed files with 21 additions and 2 deletions

View file

@ -24,7 +24,7 @@ module Reline
end
end
CursorPos = Struct.new(:x, :y)
DialogRenderInfo = Struct.new(:pos, :contents, :pointer, :bg_color, :width, :height, keyword_init: true)
DialogRenderInfo = Struct.new(:pos, :contents, :pointer, :bg_color, :width, :height, :scrollbar, keyword_init: true)
class Core
ATTR_READER_NAMES = %i(
@ -228,7 +228,7 @@ module Reline
context.clear
context.push(cursor_pos_to_render, result, pointer, dialog)
end
DialogRenderInfo.new(pos: cursor_pos_to_render, contents: result, pointer: pointer, height: 15)
DialogRenderInfo.new(pos: cursor_pos_to_render, contents: result, pointer: pointer, scrollbar: true, height: 15)
}
Reline::DEFAULT_DIALOG_CONTEXT = Array.new

View file

@ -661,6 +661,13 @@ class Reline::LineEditor
reset_dialog(dialog, old_dialog)
move_cursor_down(dialog.vertical_offset)
Reline::IOGate.move_cursor_column(dialog.column)
if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
bar_max_height = height * 2
moving_distance = (dialog_render_info.contents.size - height) * 2
position_ratio = dialog.scroll_top.zero? ? 0.0 : ((dialog.scroll_top * 2).to_f / moving_distance)
bar_height = (bar_max_height * ((dialog.contents.size * 2).to_f / (dialog_render_info.contents.size * 2))).floor.to_i
position = ((bar_max_height - bar_height) * position_ratio).floor.to_i
end
dialog.contents.each_with_index do |item, i|
if i == pointer
bg_color = '45'
@ -672,10 +679,22 @@ class Reline::LineEditor
end
end
str = padding_space_with_escape_sequences(Reline::Unicode.take_range(item, 0, dialog.width), dialog.width)
if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
if position <= (i * 2) and (i * 2) <= (position + bar_height)
str += '█'
elsif position <= (i * 2) and (i * 2 - 1) <= (position + bar_height)
str += '▀'
elsif position <= (i * 2 + 1) and (i * 2) <= (position + bar_height)
str += '▄'
else
str += ' '
end
end
@output.write "\e[#{bg_color}m#{str}\e[49m"
Reline::IOGate.move_cursor_column(dialog.column)
move_cursor_down(1) if i < (dialog.contents.size - 1)
end
dialog.width += 1 if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
Reline::IOGate.move_cursor_column(cursor_column)
move_cursor_up(dialog.vertical_offset + dialog.contents.size - 1)
Reline::IOGate.show_cursor