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/row.b | 767 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 767 insertions(+) create mode 100644 appl/acme/row.b (limited to 'appl/acme/row.b') diff --git a/appl/acme/row.b b/appl/acme/row.b new file mode 100644 index 00000000..9c857c93 --- /dev/null +++ b/appl/acme/row.b @@ -0,0 +1,767 @@ +implement Rowm; + +include "common.m"; + +sys : Sys; +bufio : Bufio; +utils : Utils; +drawm : Draw; +acme : Acme; +graph : Graph; +gui : Gui; +dat : Dat; +bufferm : Bufferm; +textm : Textm; +filem : Filem; +windowm : Windowm; +columnm : Columnm; +exec : Exec; +look : Look; +edit : Edit; +ecmd : Editcmd; + +ALLLOOPER, ALLTOFILE, ALLMATCHFILE, ALLFILECHECK, ALLELOGTERM, ALLEDITINIT, ALLUPDATE: import Edit; +sprint : import sys; +FALSE, TRUE, XXX : import Dat; +Border, BUFSIZE, Astring : import Dat; +Reffont, reffont, Lock, Ref : import dat; +row, home, mouse : import dat; +fontnames : import acme; +font, draw : import graph; +Point, Rect, Image : import drawm; +min, max, abs, error, warning, clearmouse, stralloc, strfree : import utils; +black, white, mainwin : import gui; +Buffer : import bufferm; +Tag, Rowtag, Text : import textm; +Window : import windowm; +File : import filem; +Column : import columnm; +Iobuf : import bufio; + +init(mods : ref Dat->Mods) +{ + sys = mods.sys; + bufio = mods.bufio; + dat = mods.dat; + utils = mods.utils; + drawm = mods.draw; + acme = mods.acme; + graph = mods.graph; + gui = mods.gui; + bufferm = mods.bufferm; + textm = mods.textm; + filem = mods.filem; + windowm = mods.windowm; + columnm = mods.columnm; + exec = mods.exec; + look = mods.look; + edit = mods.edit; + ecmd = mods.editcmd; +} + +newrow() : ref Row +{ + r := ref Row; + r.qlock = Lock.init(); + r.r = ((0, 0), (0, 0)); + r.tag = nil; + r.col = nil; + r.ncol = 0; + return r; +} + +Row.init(row : self ref Row, r : Rect) +{ + r1 : Rect; + t : ref Text; + dummy : ref File = nil; + + draw(mainwin, r, white, nil, (0, 0)); + row.r = r; + row.col = nil; + row.ncol = 0; + r1 = r; + r1.max.y = r1.min.y + font.height; + row.tag = textm->newtext(); + t = row.tag; + t.init(dummy.addtext(t), r1, Reffont.get(FALSE, FALSE, FALSE, nil), acme->tagcols); + t.what = Rowtag; + t.row = row; + t.w = nil; + t.col = nil; + r1.min.y = r1.max.y; + r1.max.y += Border; + draw(mainwin, r1, black, nil, (0, 0)); + t.insert(0, "Newcol Kill Putall Dump Exit ", 29, TRUE, 0); + t.setselect(t.file.buf.nc, t.file.buf.nc); +} + +Row.add(row : self ref Row, c : ref Column, x : int) : ref Column +{ + r, r1 : Rect; + d : ref Column; + i : int; + + d = nil; + r = row.r; + r.min.y = row.tag.frame.r.max.y+Border; + if(x0){ #steal 40% of last column by default + d = row.col[row.ncol-1]; + x = d.r.min.x + 3*d.r.dx()/5; + } + # look for column we'll land on + for(i=0; i 0){ + if(i < row.ncol) + i++; # new column will go after d + r = d.r; + if(r.dx() < 100) + return nil; + draw(mainwin, r, white, nil, (0, 0)); + r1 = r; + r1.max.x = min(x, r.max.x-50); + if(r1.dx() < 50) + r1.max.x = r1.min.x+50; + d.reshape(r1); + r1.min.x = r1.max.x; + r1.max.x = r1.min.x+Border; + draw(mainwin, r1, black, nil, (0, 0)); + r.min.x = r1.max.x; + } + if(c == nil){ + c = ref Column; + c.init(r); + reffont.r.inc(); + }else + c.reshape(r); + c.row = row; + c.tag.row = row; + orc := row.col; + row.col = array[row.ncol+1] of ref Column; + row.col[0:] = orc[0:i]; + row.col[i+1:] = orc[i:row.ncol]; + orc = nil; + row.col[i] = c; + row.ncol++; + clearmouse(); + return c; +} + +Row.reshape(row : self ref Row, r : Rect) +{ + i, dx, odx : int; + r1, r2 : Rect; + c : ref Column; + + dx = r.dx(); + odx = row.r.dx(); + row.r = r; + r1 = r; + r1.max.y = r1.min.y + font.height; + row.tag.reshape(r1); + r1.min.y = r1.max.y; + r1.max.y += Border; + draw(mainwin, r1, black, nil, (0, 0)); + r.min.y = r1.max.y; + r1 = r; + r1.max.x = r1.min.x; + for(i=0; icursorswitch(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; i0 && p.xc.r.max.x)){ + # shuffle + x = c.r.min.x; + row.close(c, FALSE); + if(row.add(c, p.x) == nil) # whoops! + if(row.add(c, x) == nil) # WHOOPS! + if(row.add(c, -1)==nil){ # shit! + row.close(c, TRUE); + return; + } + c.mousebut(); + return; + } + d = row.col[i-1]; + if(p.x < d.r.min.x+80+Dat->Scrollwid) + p.x = d.r.min.x+80+Dat->Scrollwid; + if(p.x > c.r.max.x-80-Dat->Scrollwid) + p.x = c.r.max.x-80-Dat->Scrollwid; + r = d.r; + r.max.x = c.r.max.x; + draw(mainwin, r, white, nil, (0, 0)); + r.max.x = p.x; + d.reshape(r); + r = c.r; + r.min.x = p.x; + r.max.x = r.min.x; + r.max.x += Border; + draw(mainwin, r, black, nil, (0, 0)); + r.min.x = r.max.x; + r.max.x = c.r.max.x; + c.reshape(r); + c.mousebut(); +} + +Row.close(row : self ref Row, c : ref Column, dofree : int) +{ + r : Rect; + i : int; + + for(i=0; ibartflag) + t = dat->barttext; + else + t = row.which(p); + if(t!=nil && !(t.what==Tag && p.in(t.scrollr))){ + w = t.w; + if(w == nil) + t.typex(r, 0); + else{ + w.lock('K'); + w.typex(t, r); + w.unlock(); + } + } + row.qlock.unlock(); + return t; +} + +Row.clean(row : self ref Row, exiting : int) : int +{ + clean : int; + i : int; + + clean = TRUE; + for(i=0; icreate(file, Bufio->OWRITE, 8r600); + if(b == nil){ + warning(nil, sprint("can't open %s: %r\n", file)); + raise "e"; + } + r = stralloc(BUFSIZE); + b.puts(acme->wdir); b.putc('\n'); + b.puts(fontnames[0]); b.putc('\n'); + b.puts(fontnames[1]); b.putc('\n'); + for(i=0; iQWevent] > byte 0) + if(w.dumpstr == nil) + continue; + # zeroxes of external windows are tossed + if(t.file.ntext > 1) + for(n=0; nQWevent] != byte 0) { + j = c.nw; + continue; + } + } + fontname = ""; + if(t.reffont.f != font) + fontname = t.reffont.f.name; + a = t.file.name; + if(t.file.dumpid){ + dumped = FALSE; + b.puts(sprint("x%11d %11d %11d %11d %11d %s\n", i, t.file.dumpid, + w.body.q0, w.body.q1, + 100*(w.r.min.y-c.r.min.y)/c.r.dy(), + fontname)); + }else if(w.dumpstr != nil){ + dumped = FALSE; + b.puts(sprint("e%11d %11d %11d %11d %11d %s\n", i, t.file.dumpid, + 0, 0, + 100*(w.r.min.y-c.r.min.y)/c.r.dy(), + fontname)); + }else if(len a == 0){ # don't save unnamed windows + continue; + }else if((!w.dirty && utils->access(a)==0) || w.isdir){ + dumped = FALSE; + t.file.dumpid = w.id; + b.puts(sprint("f%11d %11d %11d %11d %11d %s\n", i, w.id, + w.body.q0, w.body.q1, + 100*(w.r.min.y-c.r.min.y)/c.r.dy(), + fontname)); + }else{ + dumped = TRUE; + t.file.dumpid = w.id; + b.puts(sprint("F%11d %11d %11d %11d %11d %11d %s\n", i, j, + w.body.q0, w.body.q1, + 100*(w.r.min.y-c.r.min.y)/c.r.dy(), + w.body.file.buf.nc, fontname)); + } + a = nil; + buf = w.ctlprint(); + b.puts(buf); + m = min(BUFSIZE, w.tag.file.buf.nc); + w.tag.file.buf.read(0, r, 0, m); + n = 0; + while(n Dat->BUFSIZE) + n = Dat->BUFSIZE; + t.file.buf.read(q0, r, 0, n); + b.puts(r.s[0:n]); + q0 += n; + } + } + if(w.dumpstr != nil){ + if(w.dumpdir != nil) + b.puts(sprint("%s\n%s\n", w.dumpdir, w.dumpstr)); + else + b.puts(sprint("\n%s\n", w.dumpstr)); + } + } + } + b.close(); + b = nil; + strfree(r); + r = nil; + } + exception{ + * => + return; + } +} + +rdline(b : ref Iobuf, line : int) : (int, string) +{ + l : string; + + l = b.gets('\n'); + if(l != nil) + line++; + return (line, l); +} + +Row.loadx(row : self ref Row, file : string, initing : int) +{ + i, j, line, percent, y, nr, nfontr, n, ns, ndumped, dumpid, x : int; + b, bout : ref Iobuf; + fontname : string; + l, buf, t : string; + rune : int; + r, fontr : string; + c, c1, c2 : ref Column; + q0, q1 : int; + r1, r2 : Rect; + w : ref Window; + + { + if(file == nil){ + if(home == nil){ + warning(nil, "can't find file for load: $home not defined\n"); + raise "e"; + } + buf = sprint("%s/acme.dump", home); + file = buf; + } + b = bufio->open(file, Bufio->OREAD); + if(b == nil){ + warning(nil, sprint("can't open load file %s: %r\n", file)); + raise "e"; + } + + { + # current directory + (line, l) = rdline(b, 0); + if(l == nil) + raise "e"; + l = l[0:len l - 1]; + if(sys->chdir(l) < 0){ + warning(nil, sprint("can't chdir %s\n", l)); + b.close(); + return; + } + # global fonts + for(i=0; i<2; i++){ + (line, l) = rdline(b, line); + if(l == nil) + raise "e"; + l = l[0:len l -1]; + if(l != nil && l != fontnames[i]) + Reffont.get(i, TRUE, i==0 && initing, l); + } + if(initing && row.ncol==0) + row.init(mainwin.clipr); + (line, l) = rdline(b, line); + if(l == nil) + raise "e"; + j = len l/12; + if(j<=0 || j>10) + raise "e"; + for(i=0; i=100) + raise "e"; + x = row.r.min.x+percent*row.r.dx()/100; + if(i < row.ncol){ + if(i == 0) + continue; + c1 = row.col[i-1]; + c2 = row.col[i]; + r1 = c1.r; + r2 = c2.r; + r1.max.x = x; + r2.min.x = x+Border; + if(r1.dx() < 50 || r2.dx() < 50) + continue; + draw(mainwin, (r1.min, r2.max), white, nil, (0, 0)); + c1.reshape(r1); + c2.reshape(r2); + r2.min.x = x; + r2.max.x = x+Border; + draw(mainwin, r2, black, nil, (0, 0)); + } + if(i >= row.ncol) + row.add(nil, x); + } + for(;;){ + (line, l) = rdline(b, line); + if(l == nil) + break; + dumpid = 0; + case(l[0]){ + 'e' => + if(len l < 1+5*12+1) + raise "e"; + (line, l) = rdline(b, line); # ctl line; ignored + if(l == nil) + raise "e"; + (line, l) = rdline(b, line); # directory + if(l == nil) + raise "e"; + l = l[0:len l -1]; + if(len l != 0) + r = l; + else{ + if(home == nil) + r = "./"; + else + r = home+"/"; + } + nr = len r; + (line, l) = rdline(b, line); # command + if(l == nil) + raise "e"; + t = l[0:len l -1]; + spawn exec->run(nil, t, r, nr, TRUE, nil, nil, FALSE); + # r is freed in run() + continue; + 'f' => + if(len l < 1+5*12+1) + raise "e"; + fontname = l[1+5*12:len l - 1]; + ndumped = -1; + 'F' => + if(len l < 1+6*12+1) + raise "e"; + fontname = l[1+6*12:len l - 1]; + ndumped = int l[1+5*12:1+5*12+11]; + 'x' => + if(len l < 1+5*12+1) + raise "e"; + fontname = l[1+5*12: len l - 1]; + ndumped = -1; + dumpid = int l[1+1*12:1+1*12+11]; + * => + raise "e"; + } + l = l[0:len l -1]; + if(len fontname != 0) { + fontr = fontname; + nfontr = len fontname; + } + else + (fontr, nfontr) = (nil, 0); + i = int l[1+0*12:1+0*12+11]; + j = int l[1+1*12:1+1*12+11]; + q0 = int l[1+2*12:1+2*12+11]; + q1 = int l[1+3*12:1+3*12+11]; + percent = int l[1+4*12:1+4*12+11]; + if(i<0 || i>10) + raise "e"; + if(i > row.ncol) + i = row.ncol; + c = row.col[i]; + y = c.r.min.y+(percent*c.r.dy())/100; + if(y=c.r.max.y) + y = -1; + if(dumpid == 0) + w = c.add(nil, nil, y); + else + w = c.add(nil, look->lookid(dumpid, TRUE), y); + if(w == nil) + continue; + w.dumpid = j; + (line, l) = rdline(b, line); + if(l == nil) + raise "e"; + l = l[0:len l - 1]; + r = l[5*12:len l]; + nr = len r; + ns = -1; + for(n=0; n= 0){ + # simplest thing is to put it in a file and load that + buf = sprint("/tmp/d%d.%.4sacme", sys->pctl(0, nil), utils->getuser()); + bout = bufio->create(buf, Bufio->OWRITE, 8r600); + if(bout == nil){ + warning(nil, "can't create temp file: %r\n"); + b.close(); + return; + } + for(n=0; nEOF){ + bout.close(); + bout = nil; + raise "e"; + } + bout.putc(rune); + } + bout.close(); + bout = nil; + w.body.loadx(0, buf, 1); + w.body.file.mod = TRUE; + for(n=0; nremove(buf); + buf = nil; + }else if(dumpid==0 && r[ns+1]!='+' && r[ns+1]!='-') + exec->get(w.body, nil, nil, FALSE, nil, 0); + l = r = nil; + if(fontr != nil){ + exec->fontx(w.body, nil, nil, fontr, nfontr); + fontr = nil; + } + if(q0>w.body.file.buf.nc || q1>w.body.file.buf.nc || q0>q1) + q0 = q1 = 0; + w.body.show(q0, q1); + w.maxlines = min(w.body.frame.nlines, max(w.maxlines, w.body.frame.maxlines)); + } + b.close(); + } + exception{ + * => + warning(nil, sprint("bad load file %s:%d\n", file, line)); + b.close(); + raise "e"; + } + } + exception{ + * => + return; + } +} + +allwindows(o: int, aw: ref Dat->Allwin) +{ + for(i:=0; i + pick k := aw{ + LP => ecmd->alllooper(w, k.lp); + } + ALLTOFILE => + pick k := aw{ + FF => ecmd->alltofile(w, k.ff); + } + ALLMATCHFILE => + pick k := aw{ + FF => ecmd->allmatchfile(w, k.ff); + } + ALLFILECHECK => + pick k := aw{ + FC => ecmd->allfilecheck(w, k.fc); + } + ALLELOGTERM => + edit->allelogterm(w); + ALLEDITINIT => + edit->alleditinit(w); + ALLUPDATE => + edit->allupdate(w); + } + } + } +} \ No newline at end of file -- cgit v1.2.3