9fans.net/go@v0.0.7/cmd/acme/internal/wind/rows.go (about) 1 package wind 2 3 import ( 4 "sync" 5 6 "9fans.net/go/cmd/acme/internal/adraw" 7 "9fans.net/go/cmd/acme/internal/util" 8 "9fans.net/go/draw" 9 ) 10 11 type Row struct { 12 Lk sync.Mutex 13 R draw.Rectangle 14 Tag Text 15 Col []*Column 16 } 17 18 var TheRow Row 19 20 func RowInit(row *Row, r draw.Rectangle) { 21 adraw.Display.ScreenImage.Draw(r, adraw.Display.White, nil, draw.ZP) 22 row.R = r 23 row.Col = nil 24 r1 := r 25 r1.Max.Y = r1.Min.Y + adraw.Font.Height 26 t := &row.Tag 27 textinit(t, fileaddtext(nil, t), r1, adraw.FindFont(false, false, false, ""), adraw.TagCols[:]) 28 t.What = Rowtag 29 t.Row = row 30 t.W = nil 31 t.Col = nil 32 r1.Min.Y = r1.Max.Y 33 r1.Max.Y += adraw.Border() 34 adraw.Display.ScreenImage.Draw(r1, adraw.Display.Black, nil, draw.ZP) 35 Textinsert(t, 0, []rune("Newcol Kill Putall Dump Exit "), true) 36 Textsetselect(t, t.Len(), t.Len()) 37 } 38 39 func RowAdd(row *Row, c *Column, x int) *Column { 40 var d *Column 41 r := row.R 42 r.Min.Y = row.Tag.Fr.R.Max.Y + adraw.Border() 43 if x < r.Min.X && len(row.Col) > 0 { //steal 40% of last column by default 44 d = row.Col[len(row.Col)-1] 45 x = d.R.Min.X + 3*d.R.Dx()/5 46 } 47 var i int 48 // look for column we'll land on 49 for i = 0; i < len(row.Col); i++ { 50 d = row.Col[i] 51 if x < d.R.Max.X { 52 break 53 } 54 } 55 if len(row.Col) > 0 { 56 if i < len(row.Col) { 57 i++ // new column will go after d 58 } 59 r = d.R 60 if r.Dx() < 100 { 61 return nil 62 } 63 adraw.Display.ScreenImage.Draw(r, adraw.Display.White, nil, draw.ZP) 64 r1 := r 65 r1.Max.X = util.Min(x-adraw.Border(), r.Max.X-50) 66 if r1.Dx() < 50 { 67 r1.Max.X = r1.Min.X + 50 68 } 69 Colresize(d, r1) 70 r1.Min.X = r1.Max.X 71 r1.Max.X = r1.Min.X + adraw.Border() 72 adraw.Display.ScreenImage.Draw(r1, adraw.Display.Black, nil, draw.ZP) 73 r.Min.X = r1.Max.X 74 } 75 if c == nil { 76 c = new(Column) 77 colinit(c, r) 78 util.Incref(&adraw.RefFont1.Ref) 79 } else { 80 Colresize(c, r) 81 } 82 c.Row = row 83 c.Tag.Row = row 84 row.Col = append(row.Col, nil) 85 copy(row.Col[i+1:], row.Col[i:]) 86 row.Col[i] = c 87 return c 88 } 89 90 func Rowclose(row *Row, c *Column, dofree bool) { 91 var i int 92 for i = 0; i < len(row.Col); i++ { 93 if row.Col[i] == c { 94 goto Found 95 } 96 } 97 util.Fatal("can't find column") 98 Found: 99 r := c.R 100 if dofree { 101 colcloseall(c) 102 } 103 copy(row.Col[i:], row.Col[i+1:]) 104 row.Col = row.Col[:len(row.Col)-1] 105 if len(row.Col) == 0 { 106 adraw.Display.ScreenImage.Draw(r, adraw.Display.White, nil, draw.ZP) 107 return 108 } 109 if i == len(row.Col) { // extend last column right 110 c = row.Col[i-1] 111 r.Min.X = c.R.Min.X 112 r.Max.X = row.R.Max.X 113 } else { // extend next window left 114 c = row.Col[i] 115 r.Max.X = c.R.Max.X 116 } 117 adraw.Display.ScreenImage.Draw(r, adraw.Display.White, nil, draw.ZP) 118 Colresize(c, r) 119 } 120 121 func Rowresize(row *Row, r draw.Rectangle) { 122 or := row.R 123 deltax := r.Min.X - or.Min.X 124 row.R = r 125 r1 := r 126 r1.Max.Y = r1.Min.Y + adraw.Font.Height 127 Textresize(&row.Tag, r1, true) 128 r1.Min.Y = r1.Max.Y 129 r1.Max.Y += adraw.Border() 130 adraw.Display.ScreenImage.Draw(r1, adraw.Display.Black, nil, draw.ZP) 131 r.Min.Y = r1.Max.Y 132 r1 = r 133 r1.Max.X = r1.Min.X 134 for i := 0; i < len(row.Col); i++ { 135 c := row.Col[i] 136 r1.Min.X = r1.Max.X 137 // the test should not be necessary, but guarantee we don't lose a pixel 138 if i == len(row.Col)-1 { 139 r1.Max.X = r.Max.X 140 } else { 141 r1.Max.X = (c.R.Max.X-or.Min.X)*r.Dx()/or.Dx() + deltax 142 } 143 if i > 0 { 144 r2 := r1 145 r2.Max.X = r2.Min.X + adraw.Border() 146 adraw.Display.ScreenImage.Draw(r2, adraw.Display.Black, nil, draw.ZP) 147 r1.Min.X = r2.Max.X 148 } 149 Colresize(c, r1) 150 } 151 } 152 153 func Rowclean(row *Row) bool { 154 clean := true 155 for i := 0; i < len(row.Col); i++ { 156 clean = Colclean(row.Col[i]) && clean 157 } 158 return clean 159 } 160 161 func Rowdragcol1(row *Row, c *Column, op, p draw.Point) { 162 var i int 163 for i = 0; i < len(row.Col); i++ { 164 if row.Col[i] == c { 165 goto Found 166 } 167 } 168 util.Fatal("can't find column") 169 170 Found: 171 if util.Abs(p.X-op.X) < 5 && util.Abs(p.Y-op.Y) < 5 { 172 return 173 } 174 if (i > 0 && p.X < row.Col[i-1].R.Min.X) || (i < len(row.Col)-1 && p.X > c.R.Max.X) { 175 // shuffle 176 x := c.R.Min.X 177 Rowclose(row, c, false) 178 if RowAdd(row, c, p.X) == nil { // whoops! 179 if RowAdd(row, c, x) == nil { // WHOOPS! 180 if RowAdd(row, c, -1) == nil { // shit! 181 Rowclose(row, c, true) 182 return 183 } 184 } 185 } 186 return 187 } 188 if i == 0 { 189 return 190 } 191 d := row.Col[i-1] 192 if p.X < d.R.Min.X+80+adraw.Scrollwid() { 193 p.X = d.R.Min.X + 80 + adraw.Scrollwid() 194 } 195 if p.X > c.R.Max.X-80-adraw.Scrollwid() { 196 p.X = c.R.Max.X - 80 - adraw.Scrollwid() 197 } 198 r := d.R 199 r.Max.X = c.R.Max.X 200 adraw.Display.ScreenImage.Draw(r, adraw.Display.White, nil, draw.ZP) 201 r.Max.X = p.X 202 Colresize(d, r) 203 r = c.R 204 r.Min.X = p.X 205 r.Max.X = r.Min.X 206 r.Max.X += adraw.Border() 207 adraw.Display.ScreenImage.Draw(r, adraw.Display.Black, nil, draw.ZP) 208 r.Min.X = r.Max.X 209 r.Max.X = c.R.Max.X 210 Colresize(c, r) 211 } 212 213 func rowwhichcol(row *Row, p draw.Point) *Column { 214 for i := 0; i < len(row.Col); i++ { 215 c := row.Col[i] 216 if p.In(c.R) { 217 return c 218 } 219 } 220 return nil 221 } 222 223 func Rowwhich(row *Row, p draw.Point) *Text { 224 if p.In(row.Tag.All) { 225 return &row.Tag 226 } 227 c := rowwhichcol(row, p) 228 if c != nil { 229 return colwhich(c, p) 230 } 231 return nil 232 } 233 234 func All(f func(*Window, interface{}), arg interface{}) { 235 for _, c := range TheRow.Col { 236 for _, w := range c.W { 237 f(w, arg) 238 } 239 } 240 }