From 37da2899f40661e3e9631e497da8dc59b971cbd0 Mon Sep 17 00:00:00 2001 From: "Charles.Forsyth" Date: Fri, 22 Dec 2006 17:07:39 +0000 Subject: 20060303a --- appl/acme/col.b | 610 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 610 insertions(+) create mode 100644 appl/acme/col.b (limited to 'appl/acme/col.b') diff --git a/appl/acme/col.b b/appl/acme/col.b new file mode 100644 index 00000000..c696fc5d --- /dev/null +++ b/appl/acme/col.b @@ -0,0 +1,610 @@ +implement Columnm; + +include "common.m"; + +sys : Sys; +utils : Utils; +drawm : Draw; +acme : Acme; +graph : Graph; +gui : Gui; +dat : Dat; +textm : Textm; +rowm : Rowm; +filem : Filem; +windowm : Windowm; + +FALSE, TRUE, XXX : import Dat; +Border : import Dat; +mouse, colbutton : import dat; +Point, Rect, Image : import drawm; +draw : import graph; +min, max, abs, error, clearmouse : import utils; +black, white, mainwin : import gui; +Text : import textm; +Row : import rowm; +Window : import windowm; +File : import filem; +Columntag : import Textm; +BACK : import Framem; +tagcols, textcols : import acme; + +init(mods : ref Dat->Mods) +{ + sys = mods.sys; + dat = mods.dat; + utils = mods.utils; + drawm = mods.draw; + acme = mods.acme; + graph = mods.graph; + gui = mods.gui; + textm = mods.textm; + rowm = mods.rowm; + filem = mods.filem; + windowm = mods.windowm; +} + +Column.init(c : self ref Column, r : Rect) +{ + r1 : Rect; + t : ref Text; + dummy : ref File = nil; + + draw(mainwin, r, white, nil, (0, 0)); + c.r = r; + c.row = nil; + c.w = nil; + c.nw = 0; + c.tag = textm->newtext(); + t = c.tag; + t.w = nil; + t.col = c; + r1 = r; + r1.max.y = r1.min.y + (graph->font).height; + t.init(dummy.addtext(t), r1, dat->reffont, tagcols); + t.what = Columntag; + r1.min.y = r1.max.y; + r1.max.y += Border; + draw(mainwin, r1, black, nil, (0, 0)); + t.insert(0, "New Cut Paste Snarf Sort Zerox Delcol ", 38, TRUE, 0); + t.setselect(t.file.buf.nc, t.file.buf.nc); + draw(mainwin, t.scrollr, colbutton, nil, colbutton.r.min); + c.safe = TRUE; +} + +Column.add(c : self ref Column, w : ref Window, clone : ref Window, y : int) : ref Window +{ + r, r1 : Rect; + v : ref Window; + i, t : int; + + v = nil; + r = c.r; + r.min.y = c.tag.frame.r.max.y+Border; + if(y0){ # steal half of last window by default + v = c.w[c.nw-1]; + y = v.body.frame.r.min.y+v.body.frame.r.dy()/2; + } + # look for window we'll land on + for(i=0; i 0){ + if(i < c.nw) + i++; # new window will go after v + # + # if v's too small, grow it first. + # + + if(!c.safe || v.body.frame.maxlines<=3){ + c.grow(v, 1, 1); + y = v.body.frame.r.min.y+v.body.frame.r.dy()/2; + } + r = v.r; + if(i == c.nw) + t = c.r.max.y; + else + t = c.w[i].r.min.y-Border; + r.max.y = t; + draw(mainwin, r, textcols[BACK], nil, (0, 0)); + r1 = r; + y = min(y, t-(v.tag.frame.font.height+v.body.frame.font.height+Border+1)); + r1.max.y = min(y, v.body.frame.r.min.y+v.body.frame.nlines*v.body.frame.font.height); + r1.min.y = v.reshape(r1, FALSE); + r1.max.y = r1.min.y+Border; + draw(mainwin, r1, black, nil, (0, 0)); + r.min.y = r1.max.y; + } + if(w == nil){ + w = ref Window; + draw(mainwin, r, textcols[BACK], nil, (0, 0)); + w.col = c; + w.init(clone, r); + }else{ + w.col = c; + w.reshape(r, FALSE); + } + w.tag.col = c; + w.tag.row = c.row; + w.body.col = c; + w.body.row = c.row; + ocw := c.w; + c.w = array[c.nw+1] of ref Window; + c.w[0:] = ocw[0:i]; + c.w[i+1:] = ocw[i:c.nw]; + ocw = nil; + c.nw++; + c.w[i] = w; + utils->savemouse(w); + # near but not on the button + graph->cursorset(w.tag.scrollr.max.add(Point(3, 3))); + dat->barttext = w.body; + c.safe = TRUE; + return w; +} + +Column.close(c : self ref Column, w : ref Window, dofree : int) +{ + r : Rect; + i : int; + + # w is locked + if(!c.safe) + c.grow(w, 1, 1); + for(i=0; irestoremouse(w); + if(dofree){ + w.delete(); + w.close(); + } + ocw := c.w; + c.w = array[c.nw-1] of ref Window; + c.w[0:] = ocw[0:i]; + c.w[i:] = ocw[i+1:c.nw]; + ocw = nil; + c.nw--; + if(c.nw == 0){ + draw(mainwin, r, white, nil, (0, 0)); + return; + } + if(i == c.nw){ # extend last window down + w = c.w[i-1]; + r.min.y = w.r.min.y; + r.max.y = c.r.max.y; + }else{ # extend next window up + w = c.w[i]; + r.max.y = w.r.max.y; + } + draw(mainwin, r, textcols[BACK], nil, (0, 0)); + if(c.safe) + w.reshape(r, FALSE); +} + +Column.closeall(c : self ref Column) +{ + i : int; + w : ref Window; + + if(c == dat->activecol) + dat->activecol = nil; + c.tag.close(); + for(i=0; icursorset(c.tag.scrollr.min.add(c.tag.scrollr.max).div(2)); +} + +Column.reshape(c : self ref Column, r : Rect) +{ + i : int; + r1, r2 : Rect; + w : ref Window; + + clearmouse(); + r1 = r; + r1.max.y = r1.min.y + c.tag.frame.font.height; + c.tag.reshape(r1); + draw(mainwin, c.tag.scrollr, colbutton, nil, colbutton.r.min); + r1.min.y = r1.max.y; + r1.max.y += Border; + draw(mainwin, r1, black, nil, (0, 0)); + r1.max.y = r.max.y; + for(i=0; i r2) + return 1; + return 0; +} + +qsort(a : array of ref Window, n : int) +{ + i, j : int; + t : ref Window; + + while(n > 1) { + i = n>>1; + t = a[0]; a[0] = a[i]; a[i] = t; + i = 0; + j = n; + for(;;) { + do + i++; + while(i < n && colcmp(a[i], a[0]) < 0); + do + j--; + while(j > 0 && colcmp(a[j], a[0]) > 0); + if(j < i) + break; + t = a[i]; a[i] = a[j]; a[j] = t; + } + t = a[0]; a[0] = a[j]; a[j] = t; + n = n-j-1; + if(j >= n) { + qsort(a, j); + a = a[j+1:]; + } else { + qsort(a[j+1:], n); + n = j; + } + } +} + +Column.sort(c : self ref Column) +{ + i, y : int; + r, r1 : Rect; + rp : array of Rect; + w : ref Window; + wp : array of ref Window; + + if(c.nw == 0) + return; + clearmouse(); + rp = array[c.nw] of Rect; + wp = array[c.nw] of ref Window; + wp[0:] = c.w[0:c.nw]; + qsort(wp, c.nw); + for(i=0; i=0 && nl[j]){ + l = min(dnl, max(1, nl[j]/2)); + nl[j] -= l; + nl[i] += l; + dnl -= l; + } + } + } + # pack everyone above + y1 = cr.min.y; + for(j=0; ji; j--){ + v = c.w[j]; + r = v.r; + r.min.y = y2-v.tag.all.dy(); + if(nl[j]) + r.min.y -= 1 + nl[j]*v.body.frame.font.height; + r.min.y -= Border; + ny[j] = r.min.y; + y2 = r.min.y; + } + # compute new size of window + r = w.r; + r.min.y = y1; + r.max.y = r.min.y+w.tag.all.dy(); + h = w.body.frame.font.height; + if(y2-r.max.y >= 1+h+Border){ + r.max.y += 1; + r.max.y += h*((y2-r.max.y)/h); + } + # draw window + if(!c.safe || !w.r.eq(r)){ + draw(mainwin, r, textcols[BACK], nil, (0, 0)); + w.reshape(r, c.safe); + } + if(i < c.nw-1){ + r.min.y = r.max.y; + r.max.y += Border; + draw(mainwin, r, black, nil, (0, 0)); + for(j=i+1; jcursorswitch(dat->boxcursor); + b = mouse.buttons; + op = mouse.xy; + while(mouse.buttons == b) + acme->frgetmouse(); + graph->cursorswitch(dat->arrowcursor); + if(mouse.buttons){ + while(mouse.buttons) + acme->frgetmouse(); + return; + } + + for(i=0; iop.x+30 && c.row.whichcol(p) == c) + p.x += w.r.dx(); # yes: toss to next column + nc = c.row.whichcol(p); + if(nc!=nil && nc!=c){ + c.close(w, FALSE); + nc.add(w, nil, p.y); + w.mousebut(); + return; + } + if(i==0 && c.nw==1) + return; # can't do it + if((i>0 && p.yw.r.max.y) + || (i==0 && p.y>w.r.max.y)){ + # shuffle + c.close(w, FALSE); + c.add(w, nil, p.y); + w.mousebut(); + return; + } + if(i == 0) + return; + v = c.w[i-1]; + if(p.y < v.tag.all.max.y) + p.y = v.tag.all.max.y; + if(p.y > w.r.max.y-w.tag.all.dy()-Border) + p.y = w.r.max.y-w.tag.all.dy()-Border; + r = v.r; + r.max.y = p.y; + if(r.max.y > v.body.frame.r.min.y){ + r.max.y -= (r.max.y-v.body.frame.r.min.y)%v.body.frame.font.height; + if(v.body.frame.r.min.y == v.body.frame.r.max.y) + r.max.y++; + } + if(!r.eq(v.r)){ + draw(mainwin, r, textcols[BACK], nil, (0, 0)); + v.reshape(r, c.safe); + } + r.min.y = v.r.max.y; + r.max.y = r.min.y+Border; + draw(mainwin, r, black, nil, (0, 0)); + r.min.y = r.max.y; + if(i == c.nw-1) + r.max.y = c.r.max.y; + else + r.max.y = c.w[i+1].r.min.y-Border; + # r.max.y = w.r.max.y; + if(!r.eq(w.r)){ + draw(mainwin, r, textcols[BACK], nil, (0, 0)); + w.reshape(r, c.safe); + } + c.safe = TRUE; + w.mousebut(); +} + +Column.which(c : self ref Column, p : Point) : ref Text +{ + i : int; + w : ref Window; + + if(!p.in(c.r)) + return nil; + if(p.in(c.tag.all)) + return c.tag; + for(i=0; i