module WhirledPeas::Graphics::ScrollbarHelper
Constants
- HORIZONTAL
Contants to paint scrollbars
- SCROLL_HANDLE_SCALE
The number of units of scrollbar a single character can be divided into
- VERTICAL
Public Class Methods
horiz(col_count, viewable_col_count, first_visible_col)
click to toggle source
Return the characters to paint the horizontal scroll bar with for the given column
@see scroll_chars for more details
# File lib/whirled_peas/graphics/scrollbar_helper.rb, line 21 def horiz(col_count, viewable_col_count, first_visible_col) scroll_chars(col_count, viewable_col_count, first_visible_col, HORIZONTAL) end
vert(row_count, viewable_row_count, first_visible_row)
click to toggle source
Return the characters to paint the vertical scroll bar with for the given row
@see scroll_chars for more details
# File lib/whirled_peas/graphics/scrollbar_helper.rb, line 28 def vert(row_count, viewable_row_count, first_visible_row) scroll_chars(row_count, viewable_row_count, first_visible_row, VERTICAL) end
Private Class Methods
scroll_chars(total_count, viewable_count, first_visible, chars)
click to toggle source
Determine which character to paint a for a scrollbar
@param total_count [Integer] total number of rows/columns in the content @param viewable_count [Integer] number of rows/columns visible in the viewport @param first_visible [Integer] zero-based index of the first row/column that is visible
in the viewport
@param chars [Array<String>] an array with four 1-character strings, the frist is the
gutter (i.e. no scrolbar handle visible), then the "second half" scrollbar character, then second is the "first half" scrollbar character, and finally the "full"
# File lib/whirled_peas/graphics/scrollbar_helper.rb, line 43 def scroll_chars(total_count, viewable_count, first_visible, chars) # Start by initializing the scroll back to to all gutters scrollbar = Array.new(viewable_count) { chars[0] } return scrollbar if total_count == 0 return scrollbar if viewable_count == 0 return scrollbar if viewable_count >= total_count # The scroll handle has the exact same relative size and position in the scroll gutter # that the viewable content has in the total content area. For example, a content area # that is 50 columns wide with a view port that is 20 columns wide might look like # # +---------1-----****2*********3******---4---------+ # | * * | # | hidden * viewable * hidden | # | * * | # +---------1-----****2*********3******---4---------+ # # The scoll gutter, would look like # # |......********.....| # # Scrolling all the way to the right results in # # +---------1---------2---------3*********4*********+ # | * * # | hidden * viewable * # | * * # +---------1---------2---------3*********4*********+ # |...........********| # # Returning to the first example, we can match up the arguments to this method to the # diagram # # total_count = 50 # |<----------------------------------------------->| # | | # | veiwable_count = 20 | # | |<----------------->| | # ↓ ↓ ↓ ↓ # +---------1-----****2*********3******---4---------+ # | * * | # | hidden * viewable * hidden | # | * * | # +---------1-----****2*********3******---4---------+ # |......****?***.....| # ↑ ↑ # first_visible = 16 | # curr = 11 # Always use the same length for the scrollbar so it does not give an inchworm effect # as it scrolls along. This will calculate the "ideal" length of the scroll bar if we # could infinitely divide a character. length = (viewable_count ** 2).to_f / total_count # Round the length to the nearst "scaled" value length = (SCROLL_HANDLE_SCALE * length).round.to_f / SCROLL_HANDLE_SCALE # Ensure we have a scrollbar! length = 1.0 / SCROLL_HANDLE_SCALE if length == 0 # Find the "ideal" position of where the scrollbar should start. start = first_visible * viewable_count.to_f / total_count # Round the start to the nearest "scaled" value start = (SCROLL_HANDLE_SCALE * start).round.to_f / SCROLL_HANDLE_SCALE # Make sure we didn't scroll off the page! start -= length if start == viewable_count (start.floor..[(start + length).floor, viewable_count - 1].min).each do |curr_0| curr_1 = curr_0 + 1.0 / SCROLL_HANDLE_SCALE first_half = start <= curr_0 && curr_0 < start + length ? 2 : 0 second_half = start <= curr_1 && curr_1 < start + length ? 1 : 0 scrollbar[curr_0] = chars[second_half | first_half] end scrollbar end