9fans.net/go@v0.0.5/draw/frame/frdelete.go (about) 1 package frame 2 3 import "9fans.net/go/draw" 4 5 // Delete deletes from f the text between p0 and p1; 6 // p1 points at the first rune beyond the deletion. 7 func (f *Frame) Delete(p0, p1 int) int { 8 if p0 >= f.NumChars || p0 == p1 || f.B == nil { 9 return 0 10 } 11 if p1 > f.NumChars { 12 p1 = f.NumChars 13 } 14 n0 := f.findbox(0, 0, p0) 15 if n0 >= len(f.box) { 16 drawerror(f.Display, "off end in frdelete") 17 } 18 n1 := f.findbox(n0, p0, p1) 19 pt0 := f.ptofcharnb(p0, n0) 20 pt1 := f.PointOf(p1) 21 if f.P0 == f.P1 { 22 f.Tick(f.PointOf(f.P0), false) 23 } 24 nn0 := n0 25 ppt0 := pt0 26 f.modified = true 27 28 // Invariants: 29 // - pt0 points to beginning, pt1 points to end 30 // - n0 is box containing beginning of stuff being deleted 31 // - n1, b are box containing beginning of stuff to be kept after deletion 32 // - cn1 is char position of n1 33 // - f.P0 and f.P1 are not adjusted until after all deletion is done 34 cn1 := p1 35 for pt1.X != pt0.X && n1 < len(f.box) { 36 b := &f.box[n1] 37 f.cklinewrap0(&pt0, b) 38 f.cklinewrap(&pt1, b) 39 n := f.canfit(pt0, b) 40 if n == 0 { 41 drawerror(f.Display, "_frcanfit==0") 42 } 43 r := draw.Rectangle{pt0, pt0} 44 r.Max.Y += f.Font.Height 45 if b.nrune > 0 { 46 w0 := b.wid 47 if n != b.nrune { 48 f.splitbox(n1, n) 49 b = &f.box[n1] 50 } 51 r.Max.X += b.wid 52 f.B.Draw(r, f.B, nil, pt1) 53 cn1 += b.nrune 54 55 // blank remainder of line 56 r.Min.X = r.Max.X 57 r.Max.X += w0 - b.wid 58 if r.Max.X > f.R.Max.X { 59 r.Max.X = f.R.Max.X 60 } 61 f.B.Draw(r, f.Cols[BACK], nil, r.Min) 62 } else { 63 r.Max.X += f.newwid0(pt0, b) 64 if r.Max.X > f.R.Max.X { 65 r.Max.X = f.R.Max.X 66 } 67 col := f.Cols[BACK] 68 if f.P0 <= cn1 && cn1 < f.P1 { 69 col = f.Cols[HIGH] 70 } 71 f.B.Draw(r, col, nil, pt0) 72 cn1++ 73 } 74 f.advance(&pt1, b) 75 pt0.X += f.newwid(pt0, b) 76 f.box[n0] = f.box[n1] 77 n0++ 78 n1++ 79 } 80 if n1 == len(f.box) && pt0.X != pt1.X { // deleting last thing in window; must clean up 81 f.SelectPaint(pt0, pt1, f.Cols[BACK]) 82 } 83 if pt1.Y != pt0.Y { 84 pt2 := f.ptofcharptb(32767, pt1, n1) // TODO 32767 85 if pt2.Y > f.R.Max.Y { 86 drawerror(f.Display, "frptofchar in frdelete") 87 } 88 if n1 < len(f.box) { 89 q0 := pt0.Y + f.Font.Height 90 q1 := pt1.Y + f.Font.Height 91 q2 := pt2.Y + f.Font.Height 92 if q2 > f.R.Max.Y { 93 q2 = f.R.Max.Y 94 } 95 f.B.Draw(draw.Rect(pt0.X, pt0.Y, pt0.X+(f.R.Max.X-pt1.X), q0), f.B, nil, pt1) 96 f.B.Draw(draw.Rect(f.R.Min.X, q0, f.R.Max.X, q0+(q2-q1)), f.B, nil, draw.Pt(f.R.Min.X, q1)) 97 f.SelectPaint(draw.Pt(pt2.X, pt2.Y-(pt1.Y-pt0.Y)), pt2, f.Cols[BACK]) 98 } else { 99 f.SelectPaint(pt0, pt2, f.Cols[BACK]) 100 } 101 } 102 f.delbox(n0, n1-1) 103 if nn0 > 0 && f.box[nn0-1].nrune >= 0 && ppt0.X-f.box[nn0-1].wid >= f.R.Min.X { 104 nn0-- 105 ppt0.X -= f.box[nn0].wid 106 } 107 if n0 < len(f.box)-1 { 108 n0++ 109 } 110 f.clean(ppt0, nn0, n0) 111 if f.P1 > p1 { 112 f.P1 -= p1 - p0 113 } else if f.P1 > p0 { 114 f.P1 = p0 115 } 116 if f.P0 > p1 { 117 f.P0 -= p1 - p0 118 } else if f.P0 > p0 { 119 f.P0 = p0 120 } 121 f.NumChars -= p1 - p0 122 if f.P0 == f.P1 { 123 f.Tick(f.PointOf(f.P0), true) 124 } 125 pt0 = f.PointOf(f.NumChars) 126 n := f.NumLines 127 f.NumLines = (pt0.Y - f.R.Min.Y) / f.Font.Height 128 if pt0.X > f.R.Min.X { 129 f.NumLines++ 130 } 131 return n - f.NumLines 132 }