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  }