@@ -322,14 +322,9 @@ func (v *View) FocusPoint(cx int, cy int) {
322
322
if cy < 0 || cy > lineCount {
323
323
return
324
324
}
325
- _ , height := v .Size ()
325
+ height := v .InnerHeight ()
326
326
327
- ly := height - 1
328
- if ly < 0 {
329
- ly = 0
330
- }
331
-
332
- v .oy = calculateNewOrigin (cy , v .oy , lineCount , ly )
327
+ v .oy = calculateNewOrigin (cy , v .oy , lineCount , height )
333
328
v .cx = cx
334
329
v .cy = cy - v .oy
335
330
}
@@ -343,16 +338,16 @@ func (v *View) CancelRangeSelect() {
343
338
}
344
339
345
340
func calculateNewOrigin (selectedLine int , oldOrigin int , lineCount int , viewHeight int ) int {
346
- if viewHeight > lineCount {
341
+ if viewHeight >= lineCount {
347
342
return 0
348
- } else if selectedLine < oldOrigin || selectedLine > oldOrigin + viewHeight {
343
+ } else if selectedLine < oldOrigin || selectedLine >= oldOrigin + viewHeight {
349
344
// If the selected line is outside the visible area, scroll the view so
350
345
// that the selected line is in the middle.
351
346
newOrigin := selectedLine - viewHeight / 2
352
347
353
348
// However, take care not to overflow if the total line count is less
354
349
// than the view height.
355
- maxOrigin := lineCount - viewHeight - 1
350
+ maxOrigin := lineCount - viewHeight
356
351
if newOrigin > maxOrigin {
357
352
newOrigin = maxOrigin
358
353
}
@@ -438,22 +433,32 @@ func (v *View) Dimensions() (int, int, int, int) {
438
433
return v .x0 , v .y0 , v .x1 , v .y1
439
434
}
440
435
441
- // Size returns the number of visible columns and rows in the View.
436
+ // Size returns the number of visible columns and rows in the View, including
437
+ // the frame if any
442
438
func (v * View ) Size () (x , y int ) {
443
439
return v .Width (), v .Height ()
444
440
}
445
441
442
+ // InnerSize returns the number of usable columns and rows in the View, excluding
443
+ // the frame if any
444
+ func (v * View ) InnerSize () (x , y int ) {
445
+ return v .InnerWidth (), v .InnerHeight ()
446
+ }
447
+
446
448
func (v * View ) Width () int {
447
- return v .x1 - v .x0 - 1
449
+ return v .x1 - v .x0 + 1
448
450
}
449
451
450
452
func (v * View ) Height () int {
451
- return v .y1 - v .y0 - 1
453
+ return v .y1 - v .y0 + 1
452
454
}
453
455
454
- // if a view has a frame, that leaves less space for its writeable area
456
+ // The writeable area of the view is always two less then the view's size,
457
+ // because if it has a frame, we need to subtract that, but if it doesn't, the
458
+ // view is made 1 larger on all sides. I'd like to clean this up at some point,
459
+ // but for now we live with this weirdness.
455
460
func (v * View ) InnerWidth () int {
456
- innerWidth := v .Width () - v . frameOffset ()
461
+ innerWidth := v .Width () - 2
457
462
if innerWidth < 0 {
458
463
return 0
459
464
}
@@ -462,22 +467,14 @@ func (v *View) InnerWidth() int {
462
467
}
463
468
464
469
func (v * View ) InnerHeight () int {
465
- innerHeight := v .Height () - v . frameOffset ()
470
+ innerHeight := v .Height () - 2
466
471
if innerHeight < 0 {
467
472
return 0
468
473
}
469
474
470
475
return innerHeight
471
476
}
472
477
473
- func (v * View ) frameOffset () int {
474
- if v .Frame {
475
- return 1
476
- } else {
477
- return 0
478
- }
479
- }
480
-
481
478
// Name returns the name of the view.
482
479
func (v * View ) Name () string {
483
480
return v .name
@@ -573,7 +570,7 @@ func max(a, b int) int {
573
570
// SetCursor sets the cursor position of the view at the given point,
574
571
// relative to the view. It checks if the position is valid.
575
572
func (v * View ) SetCursor (x , y int ) {
576
- maxX , maxY := v .Size ()
573
+ maxX , maxY := v .InnerSize ()
577
574
if x < 0 || x >= maxX || y < 0 || y >= maxY {
578
575
return
579
576
}
@@ -582,15 +579,15 @@ func (v *View) SetCursor(x, y int) {
582
579
}
583
580
584
581
func (v * View ) SetCursorX (x int ) {
585
- maxX , _ := v .Size ()
582
+ maxX := v .InnerWidth ()
586
583
if x < 0 || x >= maxX {
587
584
return
588
585
}
589
586
v .cx = x
590
587
}
591
588
592
589
func (v * View ) SetCursorY (y int ) {
593
- _ , maxY := v .Size ()
590
+ maxY := v .InnerHeight ()
594
591
if y < 0 || y >= maxY {
595
592
return
596
593
}
@@ -917,7 +914,7 @@ func (v *View) parseInput(ch rune, x int, _ int) (bool, []cell) {
917
914
for _ , cell := range v .lines [v .wy ][0 :v .wx ] {
918
915
cx += runewidth .RuneWidth (cell .chr )
919
916
}
920
- repeatCount = v .InnerWidth () - cx + 1
917
+ repeatCount = v .InnerWidth () - cx
921
918
ch = ' '
922
919
truncateLine = true
923
920
} else if isEscape {
@@ -1157,7 +1154,7 @@ func (v *View) draw() {
1157
1154
1158
1155
v .clearRunes ()
1159
1156
1160
- maxX , maxY := v .Size ()
1157
+ maxX , maxY := v .InnerSize ()
1161
1158
1162
1159
if v .Wrap {
1163
1160
if maxX == 0 {
@@ -1250,7 +1247,7 @@ func (v *View) draw() {
1250
1247
1251
1248
func (v * View ) refreshViewLinesIfNeeded () {
1252
1249
if v .tainted {
1253
- maxX := v .Width ()
1250
+ maxX := v .InnerWidth ()
1254
1251
lineIdx := 0
1255
1252
lines := v .lines
1256
1253
if v .HasLoader {
@@ -1341,7 +1338,7 @@ func (v *View) realPosition(vx, vy int) (x, y int, ok bool) {
1341
1338
1342
1339
// clearRunes erases all the cells in the view.
1343
1340
func (v * View ) clearRunes () {
1344
- maxX , maxY := v .Size ()
1341
+ maxX , maxY := v .InnerSize ()
1345
1342
for x := 0 ; x < maxX ; x ++ {
1346
1343
for y := 0 ; y < maxY ; y ++ {
1347
1344
tcellSetCell (v .x0 + x + 1 , v .y0 + y + 1 , ' ' , v .FgColor , v .BgColor , v .outMode )
@@ -1789,7 +1786,7 @@ func (v *View) adjustDownwardScrollAmount(scrollHeight int) int {
1789
1786
_ , oy := v .Origin ()
1790
1787
y := oy
1791
1788
if ! v .CanScrollPastBottom {
1792
- _ , sy := v .Size ()
1789
+ sy := v .InnerHeight ()
1793
1790
y += sy
1794
1791
}
1795
1792
scrollableLines := v .ViewLinesHeight () - y
0 commit comments