Class: Chamomile::Paginator

Inherits:
Object
  • Object
show all
Defined in:
lib/chamomile/components/paginator.rb,
lib/chamomile/components/paginator/key_map.rb

Overview

Page navigation with dot or arabic display and key binding support.

Constant Summary collapse

TYPE_DOT =
:dot
TYPE_ARABIC =
:arabic
DEFAULT_KEY_MAP =
KeyBinding.normalize({
  prev_page: [[:left, []], ["h", []], [:page_up, []]],
  next_page: [[:right, []], ["l", []], [:page_down, []]],
})

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(total_pages: 1, per_page: 0, type: TYPE_DOT, key_map: DEFAULT_KEY_MAP) ⇒ Paginator

Returns a new instance of Paginator.



12
13
14
15
16
17
18
19
20
# File 'lib/chamomile/components/paginator.rb', line 12

def initialize(total_pages: 1, per_page: 0, type: TYPE_DOT, key_map: DEFAULT_KEY_MAP)
  @total_pages = [total_pages, 1].max
  @per_page = [per_page, 0].max
  @type = type
  @key_map = key_map
  @active_dot = "\u25cf"   # ●
  @inactive_dot = "\u25cb" # ○
  @page = 0
end

Instance Attribute Details

#active_dotObject

Returns the value of attribute active_dot.



10
11
12
# File 'lib/chamomile/components/paginator.rb', line 10

def active_dot
  @active_dot
end

#inactive_dotObject

Returns the value of attribute inactive_dot.



10
11
12
# File 'lib/chamomile/components/paginator.rb', line 10

def inactive_dot
  @inactive_dot
end

#key_mapObject

Returns the value of attribute key_map.



10
11
12
# File 'lib/chamomile/components/paginator.rb', line 10

def key_map
  @key_map
end

#pageObject

Returns the value of attribute page.



9
10
11
# File 'lib/chamomile/components/paginator.rb', line 9

def page
  @page
end

#per_pageObject

Returns the value of attribute per_page.



9
10
11
# File 'lib/chamomile/components/paginator.rb', line 9

def per_page
  @per_page
end

#total_pagesObject

Returns the value of attribute total_pages.



9
10
11
# File 'lib/chamomile/components/paginator.rb', line 9

def total_pages
  @total_pages
end

#typeObject

Returns the value of attribute type.



10
11
12
# File 'lib/chamomile/components/paginator.rb', line 10

def type
  @type
end

Instance Method Details

#handle(msg) ⇒ Object Also known as: update

Elm protocol



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/chamomile/components/paginator.rb', line 75

def handle(msg)
  case msg
  when Chamomile::KeyEvent
    if KeyBinding.key_matches?(msg, @key_map, :prev_page)
      prev_page
    elsif KeyBinding.key_matches?(msg, @key_map, :next_page)
      next_page
    end
  end

  nil
end

#next_pageObject



42
43
44
45
# File 'lib/chamomile/components/paginator.rb', line 42

def next_page
  self.page = @page + 1
  self
end

#on_first_page?Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/chamomile/components/paginator.rb', line 47

def on_first_page?
  @page.zero?
end

#on_last_page?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/chamomile/components/paginator.rb', line 51

def on_last_page?
  @page >= @total_pages - 1
end

#prev_pageObject



37
38
39
40
# File 'lib/chamomile/components/paginator.rb', line 37

def prev_page
  self.page = @page - 1
  self
end

#slice_bounds(total_items) ⇒ Object

Slicing helper — returns [start_index, length] for Array#slice



56
57
58
59
60
61
62
63
# File 'lib/chamomile/components/paginator.rb', line 56

def slice_bounds(total_items)
  return [0, 0] if @per_page <= 0 || total_items <= 0

  start = @page * @per_page
  start = [start, total_items].min
  length = [@per_page, total_items - start].min
  [start, length]
end

#total_pages_from_items(total_items) ⇒ Object

Calculate and update total_pages from item count and per_page.



66
67
68
69
70
71
# File 'lib/chamomile/components/paginator.rb', line 66

def total_pages_from_items(total_items)
  return if @per_page <= 0

  @total_pages = [(total_items.to_f / @per_page).ceil, 1].max
  @page = @page.clamp(0, @total_pages - 1)
end

#viewObject



90
91
92
93
94
95
96
97
# File 'lib/chamomile/components/paginator.rb', line 90

def view
  case @type
  when TYPE_ARABIC
    "#{@page + 1}/#{@total_pages}"
  else
    (0...@total_pages).map { |i| i == @page ? @active_dot : @inactive_dot }.join(" ")
  end
end