Class: MarsBase10::Pane
- Inherits:
-
Object
show all
- Defined in:
- lib/mars_base_10/pane.rb
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
#initialize(viewport:, at_row:, at_col:, height_pct: 1, width_pct: 1) ⇒ Pane
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
# File 'lib/mars_base_10/pane.rb', line 9
def initialize(viewport:, at_row:, at_col:, height_pct: 1, width_pct: 1)
@first_visible_index = 1
@height_pct = height_pct
@highlight = false
@index = 1
@last_visible_index = 0
@latch = ''
@latch_depth = 0
@left_edge_col = at_col
@subject = nil
@top_row = at_row
@win = nil
@viewport = viewport
@width_pct = width_pct
end
|
Instance Attribute Details
#cur_draw_col ⇒ Object
Returns the value of attribute cur_draw_col.
6
7
8
|
# File 'lib/mars_base_10/pane.rb', line 6
def cur_draw_col
@cur_draw_col
end
|
#cur_draw_row ⇒ Object
Returns the value of attribute cur_draw_row.
6
7
8
|
# File 'lib/mars_base_10/pane.rb', line 6
def cur_draw_row
@cur_draw_row
end
|
#extended_lines ⇒ Object
Returns the value of attribute extended_lines.
6
7
8
|
# File 'lib/mars_base_10/pane.rb', line 6
def extended_lines
@extended_lines
end
|
#height_pct ⇒ Object
Returns the value of attribute height_pct.
7
8
9
|
# File 'lib/mars_base_10/pane.rb', line 7
def height_pct
@height_pct
end
|
#highlight ⇒ Object
Returns the value of attribute highlight.
6
7
8
|
# File 'lib/mars_base_10/pane.rb', line 6
def highlight
@highlight
end
|
#index ⇒ Object
Returns the value of attribute index.
6
7
8
|
# File 'lib/mars_base_10/pane.rb', line 6
def index
@index
end
|
#latch ⇒ Object
Returns the value of attribute latch.
6
7
8
|
# File 'lib/mars_base_10/pane.rb', line 6
def latch
@latch
end
|
#left_edge_col ⇒ Object
Returns the value of attribute left_edge_col.
7
8
9
|
# File 'lib/mars_base_10/pane.rb', line 7
def left_edge_col
@left_edge_col
end
|
#subject ⇒ Object
Returns the value of attribute subject.
6
7
8
|
# File 'lib/mars_base_10/pane.rb', line 6
def subject
@subject
end
|
#top_row ⇒ Object
Returns the value of attribute top_row.
7
8
9
|
# File 'lib/mars_base_10/pane.rb', line 7
def top_row
@top_row
end
|
#viewport ⇒ Object
Returns the value of attribute viewport.
7
8
9
|
# File 'lib/mars_base_10/pane.rb', line 7
def viewport
@viewport
end
|
#width_pct ⇒ Object
Returns the value of attribute width_pct.
7
8
9
|
# File 'lib/mars_base_10/pane.rb', line 7
def width_pct
@width_pct
end
|
Instance Method Details
#active? ⇒ Boolean
26
27
28
|
# File 'lib/mars_base_10/pane.rb', line 26
def active?
self == self.viewport.active_pane
end
|
#clear ⇒ Object
30
31
32
33
34
35
36
37
38
39
|
# File 'lib/mars_base_10/pane.rb', line 30
def clear
self.reset
self.prepare_for_writing_contents
(0..(self.last_row - 1)).each do |item|
self.window.setpos(self.cur_draw_row, self.cur_draw_col)
self.window.addstr("")
self.window.clrtoeol
self.cur_draw_row += 1
end
end
|
#current_item_index ⇒ Object
41
42
43
|
# File 'lib/mars_base_10/pane.rb', line 41
def current_item_index
(self.cur_draw_row - self.extended_lines) + self.visible_content_shift
end
|
#current_subject_index ⇒ Object
45
46
47
|
# File 'lib/mars_base_10/pane.rb', line 45
def current_subject_index
self.subject.at(index: self.index)
end
|
#draw ⇒ Object
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
# File 'lib/mars_base_10/pane.rb', line 49
def draw
self.prepare_for_writing_contents
while self.cur_draw_row <= self.last_drawable_row
if self.current_item_index <= self.subject.item_index_range.last
if (self.current_item_index == self.index) && !self.highlight
self.window.attron(Curses::A_REVERSE)
self.highlight = true
end
if self.subject.line_length_at(index: self.current_item_index) > self.last_col
chunks = self.subject.line_at(index: self.current_item_index).chars.each_slice(self.last_col - 2).map(&:join)
chunks.each do |c|
self.draw_line
self.window.addstr("#{c}")
self.cur_draw_row += 1
self.extended_lines += 1
end
self.extended_lines -= 1
else
self.draw_line
self.window.addstr("#{self.subject.line_at(index: self.current_item_index)}")
self.cur_draw_row += 1
end
if self.highlight
self.window.attroff(Curses::A_REVERSE)
self.highlight = false
end
else
self.draw_line
self.window.addstr(" ")
self.cur_draw_row += 1
end
self.window.clrtoeol
end
self.draw_border
@last_visible_index = self.current_item_index - 1
end
|
#draw_border ⇒ Object
90
91
92
93
94
95
|
# File 'lib/mars_base_10/pane.rb', line 90
def draw_border
self.window.attron(Curses.color_pair(1) | Curses::A_BOLD) if self.active?
self.window.box
self.draw_title
self.window.attroff(Curses.color_pair(1) | Curses::A_BOLD) if self.active?
end
|
#draw_line ⇒ Object
97
98
99
|
# File 'lib/mars_base_10/pane.rb', line 97
def draw_line
self.window.setpos(self.cur_draw_row, self.cur_draw_col)
end
|
#draw_title ⇒ Object
101
102
103
104
|
# File 'lib/mars_base_10/pane.rb', line 101
def draw_title
self.window.setpos(0, 2)
self.window.addstr(" #{self.subject.title} (#{self.max_contents_rows} total) ")
end
|
#first_drawable_col ⇒ Object
106
107
108
|
# File 'lib/mars_base_10/pane.rb', line 106
def first_drawable_col
1
end
|
#first_drawable_row ⇒ Object
110
111
112
|
# File 'lib/mars_base_10/pane.rb', line 110
def first_drawable_row
1
end
|
#gutter_width ⇒ Object
114
115
116
|
# File 'lib/mars_base_10/pane.rb', line 114
def gutter_width
self.subject.index_width
end
|
#last_col ⇒ Object
This is the relative last column, e.g. the width of the pane in columns.
121
122
123
124
|
# File 'lib/mars_base_10/pane.rb', line 121
def last_col
(self.viewport.max_cols * self.width_pct).floor
end
|
#last_drawable_row ⇒ Object
126
127
128
|
# File 'lib/mars_base_10/pane.rb', line 126
def last_drawable_row
[self.last_visible_row, self.max_contents_rows].min
end
|
#last_row ⇒ Object
This is the relative last row, e.g. the height of the pane in rows
133
134
135
|
# File 'lib/mars_base_10/pane.rb', line 133
def last_row
(self.viewport.max_rows * self.height_pct).floor
end
|
#last_visible_row ⇒ Object
This is the height of the pane minus the border
140
141
142
|
# File 'lib/mars_base_10/pane.rb', line 140
def last_visible_row
self.last_row - 2
end
|
#latched? ⇒ Boolean
The pane is latched if it has consumed 1 key 0-9 and is awaiting the next key.
147
148
149
|
# File 'lib/mars_base_10/pane.rb', line 147
def latched?
@latch_depth > 0
end
|
#max_contents_rows ⇒ Object
151
152
153
|
# File 'lib/mars_base_10/pane.rb', line 151
def max_contents_rows
self.subject.item_index_range.last
end
|
#min_column_width ⇒ Object
155
156
157
|
# File 'lib/mars_base_10/pane.rb', line 155
def min_column_width
self.gutter_width + self.subject.max_content_width + self.right_pad
end
|
#prepare_for_writing_contents ⇒ Object
159
160
161
162
163
164
165
|
# File 'lib/mars_base_10/pane.rb', line 159
def prepare_for_writing_contents
self.cur_draw_row = self.first_drawable_row
self.cur_draw_col = self.first_drawable_col
self.extended_lines = 0
@first_visible_index = self.cur_draw_row + self.visible_content_shift
@last_visible_index = self.subject.item_count if @last_visible_index < @first_visible_index
end
|
#process ⇒ Object
process blocks and waits for a keypress.
this method handles only the “default” keypresses which all controllers/subjects
must support. Any unrecognized key is bubbled to the controller for more specific
handling.
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
# File 'lib/mars_base_10/pane.rb', line 174
def process
key = self.window.getch.to_s
case key
when 'j'
self.index = self.set_row(self.index + 1)
when 'k'
self.index = self.set_row(self.index - 1)
when 'J'
self.index = self.set_row([self.index + (self.last_visible_row), self.max_contents_rows].min)
when 'K'
self.index = self.set_row(self.index - self.visible_content_range.count)
when 'q'
exit 0
when ('0'..'9')
if self.latched?
self.latch << key
@latch_depth += 1
if @latch_depth == self.gutter_width
self.index = self.set_row(self.latch.to_i)
self.latch = ""
@latch_depth = 0
end
else
self.latch = key
@latch_depth = 1
end
end
self.viewport.controller.send key: key
end
|
#reset ⇒ Object
206
207
208
209
210
211
|
# File 'lib/mars_base_10/pane.rb', line 206
def reset
@index = 1
@latch = ''
@latch_depth = 0
end
|
#right_pad ⇒ Object
213
214
215
|
# File 'lib/mars_base_10/pane.rb', line 213
def right_pad
2
end
|
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
# File 'lib/mars_base_10/pane.rb', line 217
def scroll_to_row(index)
jump = [(index - self.index), (self.max_contents_rows - self.visible_content_range.last)].min
if index > self.index
if index > self.visible_content_range.last
@first_visible_index = @first_visible_index + jump
@last_visible_index = @last_visible_index + jump
end
else
if index < self.visible_content_range.first
@first_visible_index = [(@first_visible_index + jump), 1].max
@last_visible_index = @last_visible_index + jump
end
end
[index, 1].max
end
|
#set_row(i) ⇒ Object
this is a no-op if the index is out of range
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
|
# File 'lib/mars_base_10/pane.rb', line 238
def set_row(i)
return i if self.visible_content_range.include?(i)
current_index = self.index
return self.max_contents_rows if (i > self.max_contents_rows)
if (i < 1)
if i < 0
target_index = self.index
self.index = 1
end
i = [self.viewport.controller.load_history, 1].max
i = target_index if target_index
end
return self.scroll_to_row(i)
end
|
#view(subject:) ⇒ Object
258
259
260
|
# File 'lib/mars_base_10/pane.rb', line 258
def view(subject:)
@subject = subject
end
|
#visible_content_range ⇒ Object
262
263
264
265
|
# File 'lib/mars_base_10/pane.rb', line 262
def visible_content_range
(@first_visible_index..@last_visible_index)
end
|
#visible_content_shift ⇒ Object
267
268
269
|
# File 'lib/mars_base_10/pane.rb', line 267
def visible_content_shift
self.visible_content_range.first - self.first_drawable_row
end
|
#window ⇒ Object
271
272
273
274
|
# File 'lib/mars_base_10/pane.rb', line 271
def window
return @win if @win
@win = Curses::Window.new(self.last_row, self.last_col, self.top_row, self.left_edge_col)
end
|