Skip to content

Commit 4c7fc42

Browse files
committed
Implement scrollbar
1 parent c77c3c6 commit 4c7fc42

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

lib/reline.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def match?(key)
2424
end
2525
end
2626
CursorPos = Struct.new(:x, :y)
27-
DialogRenderInfo = Struct.new(:pos, :contents, :pointer, :bg_color, :width, :height, keyword_init: true)
27+
DialogRenderInfo = Struct.new(:pos, :contents, :pointer, :bg_color, :width, :height, :scrollbar, keyword_init: true)
2828

2929
class Core
3030
ATTR_READER_NAMES = %i(
@@ -228,7 +228,7 @@ def get_screen_size
228228
context.clear
229229
context.push(cursor_pos_to_render, result, pointer, dialog)
230230
end
231-
DialogRenderInfo.new(pos: cursor_pos_to_render, contents: result, pointer: pointer, height: 15)
231+
DialogRenderInfo.new(pos: cursor_pos_to_render, contents: result, pointer: pointer, scrollbar: true, height: 15)
232232
}
233233
Reline::DEFAULT_DIALOG_CONTEXT = Array.new
234234

lib/reline/line_editor.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,13 @@ def add_dialog_proc(name, p, context = nil)
661661
reset_dialog(dialog, old_dialog)
662662
move_cursor_down(dialog.vertical_offset)
663663
Reline::IOGate.move_cursor_column(dialog.column)
664+
if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
665+
bar_max_height = height * 2
666+
moving_distance = (dialog_render_info.contents.size - height) * 2
667+
position_ratio = dialog.scroll_top.zero? ? 0.0 : ((dialog.scroll_top * 2).to_f / moving_distance)
668+
bar_height = (bar_max_height * ((dialog.contents.size * 2).to_f / (dialog_render_info.contents.size * 2))).floor.to_i
669+
position = ((bar_max_height - bar_height) * position_ratio).floor.to_i
670+
end
664671
dialog.contents.each_with_index do |item, i|
665672
if i == pointer
666673
bg_color = '45'
@@ -672,10 +679,22 @@ def add_dialog_proc(name, p, context = nil)
672679
end
673680
end
674681
str = padding_space_with_escape_sequences(Reline::Unicode.take_range(item, 0, dialog.width), dialog.width)
682+
if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
683+
if position <= (i * 2) and (i * 2) <= (position + bar_height)
684+
str += '█'
685+
elsif position <= (i * 2) and (i * 2 - 1) <= (position + bar_height)
686+
str += '▀'
687+
elsif position <= (i * 2 + 1) and (i * 2) <= (position + bar_height)
688+
str += '▄'
689+
else
690+
str += ' '
691+
end
692+
end
675693
@output.write "\e[#{bg_color}m#{str}\e[49m"
676694
Reline::IOGate.move_cursor_column(dialog.column)
677695
move_cursor_down(1) if i < (dialog.contents.size - 1)
678696
end
697+
dialog.width += 1 if dialog_render_info.scrollbar and dialog_render_info.contents.size > height
679698
Reline::IOGate.move_cursor_column(cursor_column)
680699
move_cursor_up(dialog.vertical_offset + dialog.contents.size - 1)
681700
Reline::IOGate.show_cursor

0 commit comments

Comments
 (0)