NB. base grid class
NB. built from project: ~Source\classes\grid\grid\grid
NB. util
NB.
NB. defines:
NB.
NB. amendx
NB. fontadjust
NB. getfontsize
NB. paintx
NB. sumtomax
NB.
NB. nouns:
NB. DEBUG
NB. MERGED
NB. LOGPIXELSY

script_z_ '~system\packages\color\color16.ijs'
script_z_ '~system\main\gl2.ijs'
script_z_ '~system\main\pack.ijs'

coclass 'jzgrid'


coextend 'jgl2'
". toupper COLOR16
3 : 0''
if. IFWINCE do.
  LOGPIXELSY=: 120
elseif. IFWIN32 > IFJAVA do.
  LOGPIXELSY=: 5 { 0 ". wd 'qscreen'
elseif. do.
  LOGPIXELSY=: 96
end.
)

DEBUG=: 0
MERGED=: _1
amendx=: 2 : 0
:
if. m. >: #y. do.
  x. m. } (m.+1) {.!.n. y.
else.
  x. m. } y.
end.
)
getfontsize=: 13 : '{.1{._1 -.~ _1 ". y.'
fontadjust=: 3 : 0
fs=. ":s=. getfontsize y.
i=. 1 i.~ fs E. y.
n=. i {. y.
t=. (i + #fs) }. y.
n , (":fontadjustsize s) , t
)
fontadjustsize=: 3 : 0
<. 0.5 + y. * LOGPIXELSY % 72
)
paintx=: 3 : 0
if. DEBUG do. smoutput 'paintx ',":6!:0'' end.
glpaintx''
)

paintx=: glpaintx
rplc=: 4 : 0
'o n'=. ,&.>y.
l=. #o
c=. o E. x=. ,x.
if. (0<l) *: 1 e. c do. x return. end.

c=. I. c
while. 0 e. d=. 1,<:/\(#o)<:(}.-}:)c
do. c=. d#c end.
p=. (i.#x) e. 0,c
x=. p <;.1 x
b=. o&-:@(l&$) &> x
f=. n&,@(l&}.) &.>
;(f b#x) (I. b) }x
)
stretch=: [ $ ] , ($ ,: @ {:)
sumtomax=: 4 : 0
+/\ ^:_1 x. <. +/\ y.
)
gridshow=: wdinfo@('show'&;)@:((> , ': '"_ , 5!:5)"0)@(;:^:(L. = 0:))
gridpos=: gridshow bind 'mark skipr skipc scrollr scrollc maxr maxc'
resetatts=: 3 : 0

off=. (IFWINCE) * 16b40000000
f=. ". @ wd @ ('qcolor '&,) @ ": @ (off&+)

'wind text bord high htxt gray'=. f &> 5 8 10 13 14 17
'wind text bord high htxt gray'=. f &> 5 8 10 13 14 15

if. IFUNIX do.
  wind=. 255 255 255
end.

j=. i.0 0
j=. j, wind,bord,text,1 2 0          
j=. j, gray,wind,text,0 _1 1         
j=. j, gray,high,htxt,0 _1 1         
j=. j, wind,bord,text,0 _1 1         
j=. j, bord,bord,bord,0 _1 1         
j=. j, gray,gray,gray,0 _1 1         
j=. j, wind,bord,text,1 1 0          
j=. j, wind,high,htxt,1 1 0          
j=. j, wind,gray,htxt,1 1 0          
j=. j, wind,bord,text,1 2 0          
j=. j, wind,high,htxt,1 2 0          
j=. j, wind,gray,htxt,1 2 0          
j=. j, wind,bord,text,1 0 0          
j=. j, wind,high,htxt,1 0 0          
j=. j, wind,gray,htxt,1 0 0          
j=. j, gray,wind,text,0 1 1          
j=. j, gray,high,htxt,0 1 1          
j=. j, gray,att0,text,0 1 1          
j=. j, gray,att1,text,0 1 1          
j=. j, gray,att2,text,0 1 1          
j=. j, gray,wind,text,0 2 1          
j=. j, gray,high,htxt,0 2 1          
j=. j, gray,att0,text,0 2 1          
j=. j, gray,att1,text,0 2 1          
j=. j, gray,att2,text,0 2 1          
j=. j, gray,wind,text,0 0 1          
j=. j, gray,high,htxt,0 0 1          
j=. j, gray,att0,text,0 0 1          
j=. j, gray,att1,text,0 0 1          
j=. j, gray,att2,text,0 0 1          

20{."1 j
)

BORDER=: 0 : 0
pc border dialog owner;
menupop "File";
menu new "&New" "" "" "";
menu open "&Open" "" "" "";
menusep ;
menu exit "&Exit" "" "" "";
menupopz;
xywh 281 20 34 12;cc cancel button;cn "Cancel";
xywh 281 5 34 12;cc ok button;cn "OK";
xywh 189 78 26 11;cc bc3 radiobutton;cn "Blue";
xywh 161 78 26 11;cc bc2 radiobutton group;cn "Green";
xywh 133 78 26 11;cc bc1 radiobutton group;cn "Red";
xywh 105 78 26 11;cc bc0 radiobutton group;cn "Black";
xywh 61 77 20 10;cc static static;
xywh 202 67 26 11;cc bt11 radiobutton;cn "Double";
xywh 174 67 26 11;cc bt3 radiobutton group;cn "Fat";
xywh 146 67 26 11;cc bt2 radiobutton group;cn "Mid";
xywh 118 67 26 11;cc bt1 radiobutton group;cn "Thin";
xywh 90 67 26 11;cc bt0 radiobutton group;cn "None";
xywh 64 68 20 10;cc static static;
xywh 276 48 26 11;cc rc3 radiobutton;cn "Blue";
xywh 248 48 26 11;cc rc2 radiobutton group;cn "Green";
xywh 220 48 26 11;cc rc1 radiobutton group;cn "Red";
xywh 192 48 26 11;cc rc0 radiobutton group;cn "Black";
xywh 150 47 20 10;cc static static;
xywh 287 37 26 11;cc rt11 radiobutton;cn "Double";
xywh 259 37 26 11;cc rt3 radiobutton group;cn "Fat";
xywh 231 37 26 11;cc rt2 radiobutton group;cn "Mid";
xywh 203 37 26 11;cc rt1 radiobutton group;cn "Thin";
xywh 175 37 26 11;cc rt0 radiobutton group;cn "None";
xywh 153 37 18 10;cc static static;
xywh 107 48 26 11;cc lc3 radiobutton;cn "Blue";
xywh 79 48 26 11;cc lc2 radiobutton group;cn "Green";
xywh 51 48 26 11;cc lc1 radiobutton group;cn "Red";
xywh 23 48 26 11;cc lc0 radiobutton group;cn "Black";
xywh 1 48 20 10;cc static static;
xywh 117 37 26 11;cc lt11 radiobutton;cn "Double";
xywh 89 37 26 11;cc lt3 radiobutton group;cn "Fat";
xywh 61 37 26 11;cc lt2 radiobutton group;cn "Mid";
xywh 33 37 26 11;cc lt1 radiobutton group;cn "Thin";
xywh 5 37 26 11;cc lt0 radiobutton group;cn "None";
xywh 4 25 20 10;cc static static;
xywh 189 20 26 11;cc tc3 radiobutton;cn "Blue";
xywh 161 20 26 11;cc tc2 radiobutton group;cn "Green";
xywh 133 20 26 11;cc tc1 radiobutton group;cn "Red";
xywh 105 20 26 11;cc tc0 radiobutton group;cn "Black";
xywh 64 18 20 10;cc static static;
xywh 202 9 26 11;cc tt11 radiobutton;cn "Double";
xywh 174 9 26 11;cc tt3 radiobutton group;cn "Fat";
xywh 146 9 26 11;cc tt2 radiobutton group;cn "Mid";
xywh 118 9 26 11;cc tt1 radiobutton group;cn "Thin";
xywh 90 9 26 11;cc tt0 radiobutton group;cn "None";
xywh 66 8 20 10;cc static static;
pas 6 6;pcenter;
rem form end;
)
border_run=: 3 : 0
wd BORDER
wd 'pshow;'
)
border_close=: 3 : 0
wd 'pclose'
)
border_cancel_button=: 3 : 0
border_close ''
)
border_ok_button=: 3 : 0
wd 'pclose'
b=. borders
m=. mark , extent
b=. (((#b) % 20) , 20) $ b
b=. , (-.m -:"1 [ 4 {."1 b) # b
b=. b , m
b=. b , (((lt0 , lt1 , lt2 , lt3 , lt11) i. '1') { 0 1 2 3 11) , ((lc0 , lc1 , lc2 , lc3) i. '1') { 0 0 0 , 255 0 0 , 0 255 0 , 1 3 $ 0 0 255
b=. b , (((tt0 , tt1 , lt2 , tt3 , tt11) i. '1') { 0 1 2 3 11) , ((tc0 , tc1 , tc2 , tc3) i. '1') { 0 0 0 , 255 0 0 , 0 255 0 , 1 3 $ 0 0 255
b=. b , (((rt0 , rt1 , rt2 , rt3 , rt11) i. '1') { 0 1 2 3 11) , ((rc0 , rc1 , rc2 , rc3) i. '1') { 0 0 0 , 255 0 0 , 0 255 0 , 1 3 $ 0 0 255
b=. b , (((bt0 , bt1 , bt2 , bt3 , bt11) i. '1') { 0 1 2 3 11) , ((bc0 , bc1 , bc2 , bc3) i. '1') { 0 0 0 , 255 0 0 , 0 255 0 , 1 3 $ 0 0 255
setborder borders=: b
glpaint ''
)

char=: 3 : 0

'sysdata sysmodifiers'=. y.

c=. 0 { sysdata

'shift ctrl shiftctrl'=. '123' e. sysmodifiers

select. d=. a. i. c
  
case. 13 do.
  0 scroll 1 0
  
  
case. 165 ; 166 ; 167 ; 168 do.
  d=. (165 166 167 168 i. d) { 0 _1, _1 0, 0 1,: 1 0
  if. shiftctrl do.
    setincwh d
  elseif. shift do.
    extendselect d
  elseif. 1 do.
    ctrl scroll d
  end.
  
  
case. 161 ; 162 do.
  'r c'=. screenrc''
  scrolldata 0 ,~ r * (d=162) { _1 1
  
  
case. 163 do.
  
case. 164 do.
  scrollc=: -skipc
  
  if. ctrl do.
    scrollr=: -skipr
    setmark fixr , fixc
  else.
    setmark ({.mark), fixc
  end.
  get ''
  paintx ''
  setscrollbars ''
  
case. do.
  if. d <: 126 do.
    if. editok '' do.
      showcell mark
      editflag=: 1
      glgridedit c
      glgridedit 1
    end.
  end.
  
end.
)

reset=: 3 : 0
att0=: 166 202 240  
att1=: 140 220 140  
att2=: 255 153 153  
atts=: resetatts ''
borders=: ''
capture=: 0
defheight=: 20
defwidth=: 50
dtype=: ''
editenable=: 0
editflag=: 0
extent=: 1 1
filltype=: 3
fixc=: 1
fixeddata=: 0
fixr=: 1
fixtype=: 3
fns=. ": 1200 % LOGPIXELSY
font0=: '"courier new" ',fns
font1=: 'arial ',fns
gridhs=: i.0
gridid=: 'grid'
gridws=: i.0
mark=: fixr,fixc
marktrue=: mark
maxc=: _
maxr=: _
minheight=: 5
minwidth=: 10
sbarid=: 'scrollbar'
sbarvid=: 'scrollbarv'
scrollc=: 0
scrollr=: 0
sizeenable=: 0
skipc=: 0
skipr=: 0
rowheight=: defheight
colwidth=: defwidth
)

doc=: 0 : 0
jzgrid implements a grid (spreadsheet) control on an isigraph control.
Methods:
Properties:
)
actiondoc=: 0 : 0
arrows - move selection
shift+arrows - extends range
ctrl+arrows - scrolls data
ctrl+shift+arrows - changes default cell size
home - scrolls col 0 to left
ctrl+home - scrolls to row 0 and col 0
ascii characters - new data for selected cell
enter - end edit mode, move to next row
alt-enter - edit mode new line
click - selects cell
double-click - enter edit mode for current cell
mouse-down & hold   - extends range to right and down
ctrl+f - font
ctrl+e - enable/disable edit
)

pix=: > @ {
tominus=: $ $ '-'& (I. @ (e.&'_') @ ]}) @ ,
ischar=: 2: = 3!:0
joinres=: [: > ,.&.>/
fmtfull=: 3 : 0
if. ischar y. do.
  <"1 ":y.
else.
  y=. ,y.
  s=. y<0
  y=. |y
  d=. }.@": each 1|y
  i=. 0 ": each <.y
  (s{'';'-') ,each i ,each d
end.
)
ffmt=: 3 : 0
'' fmt y.
:

spc=. x.
dat=. y.
if. 0 = L.dat do. dat=. <@,."1 |: dat end.
if. 0 e. $spc do. joinres fmtfull each dat return. end.
if. 0 = L.spc do. spc=. <;._2 spc,',' end.

spc=. (#dat) $ spc

r=. ''

for_i. dat do.
  
  fm=. i_index pix spc
  dt=. i_index pix dat
  
  if. 0=#fm do. r=. r, < fmtfull ,.dt continue. end.
  
  if. 'v'={.fm do. r=. r, < (}.fm)~ dt continue. end.
  
  if. ischar dt do. r=. r, < fmtfull ,.dt continue. end.
  
  n=. fm -. 'bcn'
  d=. 0.1 * {. 1 {. ".n
  
  if. 'c' e. fm do.
    
    dt=. ,dt
    neg=. 0 > dt
    dt=. |dt
    ds=. 1 | dt
    if. #n do.
      dec=. }. @ (d&":) each ds
    else.
      dec=. }. each fmtfull ,.ds
    end.
    
    k=. 51
    msk=. (k$1j1 1 1),1
    exp=. #!.','~ ({.&msk)@-@#
    df=. exp @ (0&":) each <. dt
    
    if. 1 e. neg do.
      df=. (neg{'';'-') ,each df
    end.
    df=. df ,each dec
    
  else.
    if. 0=#n do.
      df=. fmtfull dt
    else.
      df=. d&": each dt
    end.
  end.
  
  if. 'b' e. fm do.
    df=. a: (I. 0=,dt) } df
  end.
  
  r=. r, <df
end.

joinres r
)

mfmt=: 3 : 0
if. (3!:0 y.) e. 2 32 do. y. return. end.
s=. $y.
y=. ,y.
b=. y < 0
s $ (b{'';'-') ,each ": each | y
)

fit=: 3 : 0
b=. ({.y.,0) +. fitgrid''
glgridscroll scrollr, scrollc
glgridskip skipr, skipc
glgriddrawmark ''
if. b do. setdata '' end.
paintx''
setscrollbars ''
)
fitgrid=: 3 : 0
old=. scrollr,scrollc,skipr,skipc
if. maxr < _ do.
  'scrollr skipr'=: (screenoffrows'') sumtomax scrollr, skipr
end.
if. maxc < _ do.
  'scrollc skipc'=: <. (screenoffcols'') sumtomax scrollc, skipc
end.

-. old -: scrollr,scrollc,skipr,skipc
)

get=: 3 : 0

if. fixeddata do. 0 return. end.
f=. 0
if. scrollc < 0 do.
  if. skipc do.
    skipc=: 0 >. skipc + scrollc
    scrollc=: minscrollc <. skipc
    skipc=: skipc - scrollc
    f=. 1
  else.
    scrollc=: 0
  end.
end.

if. maxscrollc < scrollc do.
  skipc=: skipc + scrollc - minscrollc
  scrollc=: minscrollc
  f=. 1
end.
if. scrollr < 0 do.
  if. skipr do.
    skipr=: 0 >. skipr + scrollr
    scrollr=: minscrollr <. skipr
    skipr=: skipr - scrollr
    f=. 1
  else.
    scrollr=: 0
  end.
end.

if. maxscrollr < scrollr do.
  skipr=: skipr + scrollr - minscrollr
  scrollr=: minscrollr
  f=. 1
end.
glgridscroll scrollr , scrollc
glgridskip skipr , skipc

if. f do. setdata '' end.
)

create=: reset
destroy=: codestroy
setdata=: 0:

formselect=: 3 : 'wd ''psel '',formhwnd'
gridselect=: 3 : 'glsel gridhwnd'

gridfocus=: 3 : 0
gridselect''
wd 'setfocus ',gridid
)
edit=: 3 : 0
if. editflag do.
  editflag=: seteditdata mark ; glgridgetedit ''
  if. editflag do. return. end.
  glgridedit 0
end.
)
editok=: 3 : 0
editenable *. (1 1 -: extent) *. 1 = geteditable mark
)
extendselect=: 3 : 0
if. 0 = */ onscreen mark + extent - 1 do. return. end.

setmarkextent extent + y.
src=. onscreen mark + extent - 1

if. 0 = */ src do.
  scrolldata 0 = src
  glpaint ''     
else.
  glgriddrawmark ''
end.
)

onscreen=: 3 : 0
'r c'=. y.
'w h'=. glqwh''

if. c < fixc do.
  cc=. 1
elseif. (c >: fixc) *. c < fixc + skipc + scrollc do.
  cc=. 0
elseif. 1 do.
  ws=. (fixc {. gridws) , (fixc + scrollc) }. gridws
  col=. +/ w > +/ \ ws            
  t=. skipc + scrollc + col       
  cc=. c < t
  
  
end.

if. r < fixr do.
  rr=. 1
elseif. (r >: fixr) *. r < fixr + skipr + scrollr do.
  rr=. 0
elseif. 1 do.
  hs=. (fixr {. gridhs) , (fixr + scrollr) }. gridhs
  row=. +/ h > +/ \ hs           
  t=. skipr + scrollr + row      
  rr=. r < t
end.
rr , cc
)
showcell=: 3 : 0

'r c'=. y.
'sr sc'=. onscreen y.

if. 0 = sc do.
  t=. fixc + skipc + scrollc    
  scrollc=: scrollc + c - t
end.

if. 0 = sr do.
  
  t=. fixr + skipr + scrollr    
  scrollr=: scrollr + r - t
end.

if. 0 = sr * sc do.
  get ''
  paintx ''
end.
0
)
size=: 3 : 0
old=. sizewh
sizewh=: glqwh''
if. 1 e. (old < sizewh), y. do.
  getreqrc''
  fit''
  setdata''
end.
)
updatecell=: 4 : 0
setinvalidate 1
(y. , 1 1) settext x.
setinvalidate 0
)

init=: 3 : 0

if. #y. do. 'dataname gridid sbarid sbarvid'=: y. end.

glsel gridid
formhwnd=: wd 'qhwndp'
gridhwnd=: wd 'qhwndc ',gridid
glwantresize ''
glnoerasebkgnd 1
glmap MM_RAW
glcursor IDC_ARROW
setfont0 font0
setfont1 font1
setatt atts
glgridfix fixr, fixc
glgridfill defwidth, defheight, fixtype, filltype
glgrid ''
sizewh=: glqwh''
setdata ''
setscrollbars''
glshow ''
)

mbldown=: 3 : 0
gridfocus''

'colx rowx col row val type'=. mouse y.
captureval=: val

select. type
  
case. 0 do.
  if. 0 = col * row do. return. end.
  flag=. editflag
  edit ''
  if. editflag do. return. end.
  
  mark=: row , col
  
  if. -.flag do.
    setmarkextent 1 1
    glgriddrawmark ''
  end.
  
  glcapture 1
  captureindex=: capturesize=: 0
  capturerowcol=: row , col
  mousetime=: 6!:1 ''
  capture=: 3
  
case. 1 do.
  if. sizeenable do.
    glcursor IDC_SIZEWE
    glcapture 5    
    capture=: 1
    captureindex=: col - 1
    capturesize=: (colx - 1) { gridws
  end.
  
case. 2 do.
  if. sizeenable do.
    glcursor IDC_SIZENS
    glcapture 6    
    capture=: 2
    captureindex=: row - 1
    capturesize=: (rowx - 1) { gridhs
  end.
  
end.
)
mblup=: 3 : 0
if. 0 = capture do. return. end.
glcapture 0
t=. capture
capture=: 0
d=. (0 { d) , -/ 3 1 { d=. ".y.
d=. 0 >. capturesize + d - captureval
select. t
case. 1 do.
  colwidth=: (0 { d) captureindex amendx defwidth colwidth
  setwidths (0 { d) (captureindex - skipc) } gridws
  paintx ''
case. 2 do.
  rowheight=: (1 { d) captureindex amendx defheight rowheight
  gridhs=: (1 { d) (captureindex - skipr) } gridhs
  setheights gridhs
  paintx ''
end.
)
mbldbl=: 3 : 0
'colx rowx col row val type'=. mouse y.
if. 0 = col * row do. return. end.
if. editok '' do.
  
  if. +./mark>:(fixr,fixc)+$".dataname do.
    wdinfo 'Edit';'Cell out of range' return.
  end.
  
  editflag=: 1
  glgridedit getedit mark
  glgridedit 1
end.
)
mmove=: 3 : 0
if. capture = 3 do.
  'colx rowx col row val type'=. mouse y.
  t=. 0 >. (row , col) - mark
  
  
  if. ((0.1 + mousetime) < 6!:1 '') *. -.t -: extent do.
    
    mousetime=: 6!:1 ''
    extendselect 1 + t - extent
  end.
  
  return.
end.
if. -.capture do.
  cndx=. sizeenable * {:mouse y.
  glcursor cndx { IDC_ARROW , IDC_SIZEWE , IDC_SIZENS
end.
)
mouse=: 3 : 0
'x y h'=. 0 1 3 { 0 ". y.

y=. h - y
tol=. 2

ws=. (fixc {. gridws) , (fixc + scrollc) }. gridws
hs=. (fixr {. gridhs) , (fixr + scrollr) }. gridhs

colx=. +/ (x+tol) >: +/\ ws
rowx=. +/ (y+tol) >: +/\ hs

col=. colx + (colx >: fixc) * scrollc + skipc
row=. rowx + (rowx >: fixr) * scrollr + skipr
val=. 0

if. (row < fixr) *. tol >: | x - val=. +/ colx {. ws do. type=. 1
elseif. (col < fixc) *. tol >: | y - val=. +/ rowx {. hs do. type=. 2
elseif. 1 do. type=. 0
end.
if. maxc < _ do. colx=. colx <. col=. col <. maxc-1 end.
if. maxr < _ do. rowx=. rowx <. row=. row <. maxr-1 end.

colx , rowx , col , row , val , type
)

geteditable=: 12&{@glgridgettype

gettype=: {.@glgridgettype
setborder=: glgridborder
setinvalidate=: glgridinvalidate
getreqrc=: 3 : 0
maxscrollr=: _1 + +: minscrollr=: >: screenrows''
maxscrollc=: _1 + +: minscrollc=: >: screencols''
reqrc=: 1 + 3 * minscrollr,minscrollc
)
setheights=: 3 : 0
glgridh gridhs=: minheight >. (0 { gridrc) {.!.defheight y.
)
setincwh=: 3 : 0
setwidths (fixc {. gridws) , fixc }. 2 >. gridws + 2 * 1 { y.
setheights (fixr {. gridhs) , fixr }. 2 >. gridhs + 2 * 0 { y.
paintx ''
defwidth=: 2 >. defwidth + 2 * 1 { y.
defheight=: 2 >. defheight + 2 * 0 { y.
)
setmark=: 3 : 0
mark=: 0 >. ((maxr,maxc) - fixr,fixc) <. 2{.y.
setmarkextent 2 {. 2 }. y.
)
setmarkextent=: 3 : 0

extent=: 1 >. y. <. (maxr,maxc) - mark
k=. mark
c=. 1 { k
ex=. extent
cols=. 1
if. 1 1 -: ex do.
  while. (0 < 1 { k) *. MERGED = gettype k do.
    k=. k - 0 1
  end.
  while. MERGED = gettype k + 0 , cols do.
    cols=. >:cols
  end.
  ex=. 1 , cols
end.
mark=: k >. fixr,fixc
marktrue=: mark
ex=. ex <. (maxr,maxc) - fixr,fixc

glgridmark mark , ex
)
settext=: 3 : 0
'' settext y.
:
dat=. y.
if. #x. do. glgridrchw x. end.
if. 0 e. $dat do. return. end.
if. 0 = L.dat do. dat=. ":each dat end.
glgridtext ; dat , each 0 { a.
)
settexttype=: ''&$: : (4 : 0)
if. #x. do. glgridrchw x. end.
settext > {.y.
settype > {:y.
)
settype=: ''&$: : (4 : 0)
if. #x. do. glgridrchw x. end.
glgridtype , y.
)
setwidths=: 3 : 0
glgridw gridws=: minwidth >. (1 { gridrc) {.!.defwidth y.
)

scroll=: 4 : 0

if. x.=1 do. scrolldata y. return. end.

edit ''
if. editflag do. return. end.

firsttype=. gettype marktrue
scrollmark y.
if. 1 = 1 { y. do.
  while. MERGED = gettype marktrue do. scrollmark y. end.
elseif. _1 = 1 { y. do.
  if. MERGED = firsttype do.
    while. MERGED = gettype marktrue do. scrollmark y. end.
    scrollmark y.
  end.
end.
)
scrollbar=: 3 : 0
y=. ".y.
scrollc=: y - skipc
if. scrollc >: 0 do.
  glgridscroll scrollr , scrollc
  glgridskip skipr , skipc
end.
get ''
paintx ''
)
scrollbarv=: 3 : 0
y=. ".y.
scrollr=: y - skipr
if. scrollr >: 0 do.
  glgridscroll scrollr , scrollc
  glgridskip skipr , skipc
end.
get ''
paintx ''
)
scrolldata=: 3 : 0
off=: (scrollr,scrollc) + skipr, skipc
scrollr=: scrollr + 0 { y.
scrollc=: scrollc + 1 { y.
get ''
paintx ''
setscrollbars ''
)
scrollmark=: 3 : 0
src=. onscreen marktrue
mark=: marktrue=: (<: maxr,maxc) <. (fixr,fixc) >. marktrue + y.
setmarkextent 1 1
if. 0 e. src do. showcell mark return. end.
src=. onscreen mark
if. 0 e. src do.
  
  while.
    scrollr=: scrollr + 0 { y.
    scrollc=: scrollc + 1 { y.
    get ''
    0 e. onscreen mark do. ''
  end.
  
  paintx ''
  setscrollbars ''
  
else.
  
  glgriddrawmark ''
  
end.
)
setscrollbars=: setscrollbar @ setscrollbarv
setscrollbar=: 3 : 0
if. #sbarid do.
  p=. skipc + scrollc
  try.
    if. maxc < _ do.
      m=. screenoffcols''
      p=. p <. m
      s=. 1 >. screencols''
      wd 'set ' , sbarid , ' ' , ":0,p,m,s
    else.
      wd 'set ' , sbarid , ' ' , ":p
    end.
  catch.
    sbarid=: ''
  end.
end.
)

setscrollbarv=: 3 : 0
if. #sbarvid do.
  p=. skipr + scrollr
  try.
    if. maxr < _ do.
      m=. screenoffrows''
      p=. p <. m
      s=. 1 >. screenrows''
      wd 'set ' , sbarvid , ' ' , ":0,p,m,s
    else.
      wd 'set ' , sbarvid , ' ' , ":p
    end.
  catch.
    sbarvid=: ''
  end.
end.
)
screenoffrc=: screenoffrows,screenoffcols
screenoffrows=: 3 : 0
'w h'=. glqwh''
rws=. maxr - fixr
top=. +/ fixr {. gridhs
bot=. +/\. fixr }. gridhs
0 >. rws - +/ h >: top + bot
)
screenoffcols=: 3 : 0
'w h'=. glqwh''
cls=. maxc - fixc
left=. +/ fixc {. gridws
right=. +/\. fixc |. gridws
0 >. cls - +/ w >: left + right
)
screenrc=: screenrows,screencols
screenrows=: 3 : 0
'tw th'=. glqwh''
h=. (fixr {. gridhs) , (fixr + scrollr) }. gridhs
fixr -~ 1 i.~ th < +/\ h, defheight $~ >. th % defheight
)
screencols=: 3 : 0
'tw th'=. glqwh''
w=. (fixc {. gridws) , (fixc + scrollc) }. gridws
fixc -~ 1 i.~ tw < +/\ w, defwidth $~ >. tw % defwidth
)

setatt=: glgridatt@,
setfont0=: 3 : 'setdefheight glgridfont0 fontadjust font0=: y.'
setfont1=: 3 : 'setdefheight glgridfont1 fontadjust font1=: y.'
setgrid=: 3 : 'glgridrc gridrc=: y.'
set=: 3 : 0
nms=. ;:^:(L. = 0:) y.
cnm=. nms ,each <'__COCREATOR'
msk=. 0=4!:0 cnm
nms=. msk#nms
if. #nms do.
  (nms)=: ". each msk#cnm
end.
)
setdefheight=: 3 : 0
defheight=: 4 + fontadjustsize (getfontsize font0) >. getfontsize font1
)

state=: 3 : 0
formselect''
gridselect''
p=. [: (, ,&< ".)&> ;:^:(L. = 0:)
wh=. glqwh''
maxscrollrc=. maxscrollr,maxscrollc
minscrollrc=. minscrollr,minscrollc
scrollrc=. scrollr,scrollc
skiprc=. skipr, skipc
screenrc=. (screenrows''),screencols''
p 'wh reqrc screenrc skiprc scrollrc minscrollrc maxscrollrc'
)