2
Author: Vitaliy Trifonov
16
ncurses, panel, sysutils;
19
TNcCoord = array[0..1] of Smallint;
21
TNcStr = packed record
29
function CTRL( ch: chtype ): chtype; inline;
34
function randomchar: chtype;
38
while not (ch in ['0'..'9','A'..'Z','a'..'z']) do
39
ch := Char(Random(123));
40
randomchar := chtype(ch);
43
function randompair: longint;
47
while not (pair in [1..5]) do
57
for y := 0 to LINES - 1 do
58
for x := 0 to COLS - 1 do
59
mvaddch(y, x, randomchar OR COLOR_PAIR(randompair));
62
procedure draw_pad(win: PWINDOW);
65
y, x, my, mx: Smallint;
68
wborder(win, ACS_CKBOARD,ACS_CKBOARD,ACS_CKBOARD,ACS_CKBOARD,
69
ACS_CKBOARD,ACS_CKBOARD,ACS_CKBOARD,ACS_CKBOARD);
70
for y := 1 to my - 2 do
72
for x := 1 to mx - 2 do
73
if (x mod 10) = 1 then
74
mvwaddch(win, y, x, randomchar OR COLOR_PAIR(randompair))
76
mvwaddch(win, y, x, ACS_HLINE)
78
for x := 1 to mx - 2 do
79
if (x mod 10) = 1 then
80
mvwaddch(win, y, x, ACS_VLINE)
82
mvwaddch(win, y, x, chtype(' '))
86
function st_middle(scrlen, itemlen: Smallint): Smallint; inline;
88
st_middle := (scrlen - itemlen) div 2;
91
procedure print_in_middle(win: PWINDOW; var nstr: TNcStr; width: Longint);
95
getmaxyx(win, my, mx);
98
if (width > length(nstr.str)) OR (width < 1) then
99
width := length(nstr.str);
104
nstr.coord[x] += st_middle(mx,width);
106
wattron(win,nstr.attr);
107
mvwaddnstr(win,nstr.coord[y],nstr.coord[x],PChar(nstr.str),width);
108
wattroff(win,nstr.attr);
112
TBarData = packed record
113
beg, len, slen: Smallint;
118
wyx, pyx, ppos, grid: TNcCoord;
119
hbar, vbar: TBarData;
120
padwin, projwin: PWINDOW;
128
function scroll_right: Boolean;
129
function scroll_left: Boolean;
130
function scroll_down: Boolean;
131
function scroll_up: Boolean;
132
function doevent: chtype;
134
function move(const ncoord: array of Smallint): Boolean; inline;
135
function hide: Boolean; inline;
136
function show: Boolean; inline;
138
function resize(const nsize: array of Smallint): Boolean;
139
constructor create(const parm: array of TNcCoord; const hdr: TNcStr);
140
destructor destroy; override;
141
property win: PWINDOW read padwin;
142
property ysize: Smallint read wyx[y];
143
property xsize: Smallint read wyx[x];
147
procedure TPad.init_bars;
149
function get_scrl_len(blen, wsz, psz: Smallint): Smallint; inline;
151
get_scrl_len := (blen * wsz) div psz;
156
hbar.len := wyx[x] - hbar.beg * 2;
157
hbar.slen := get_scrl_len(hbar.len, wyx[x], pyx[x]);
160
vbar.len := wyx[y] - vbar.beg * 2;
161
vbar.slen := get_scrl_len(vbar.len, wyx[y], pyx[y]);
164
function get_scrl_beg(ind, slen, blen, wsz, psz, bbeg: Smallint): Smallint;
167
get_scrl_beg := (ind * (blen - slen)) div (psz - wsz) + bbeg
169
get_scrl_beg := bbeg;
172
procedure TPad.draw_hbar;
178
sbeg := get_scrl_beg(ppos[x],hbar.slen,hbar.len,wyx[x], pyx[x],hbar.beg);
179
wattron(projwin,header.attr);
180
for i := beg to beg + len - 1 do
181
if (i < sbeg) OR (i > sbeg + slen) then
182
mvwaddch(projwin,wyx[y]-1,i ,ACS_CKBOARD)
184
mvwaddch(projwin,wyx[y]-1,i,ACS_BLOCK);
185
wattroff(projwin,header.attr);
189
procedure TPad.draw_vbar;
195
sbeg := get_scrl_beg(ppos[y],vbar.slen,vbar.len,wyx[y], pyx[y],vbar.beg);
196
wattron(projwin,header.attr);
197
for i := beg to beg + len - 1 do
198
if (i < sbeg) OR (i > sbeg + slen) then
199
mvwaddch(projwin,i,wyx[x]-1,ACS_CKBOARD)
201
mvwaddch(projwin,i,wyx[x]-1,ACS_BLOCK);
202
wattroff(projwin,header.attr);
206
function TPad.scroll_right: Boolean;
210
if (ppos[x] < grid[x]) then
219
scroll_right := false
222
function TPad.scroll_left: Boolean;
226
dwidth := pyx[x] - wyx[x] + 2;
227
if ppos[x] < dwidth then
229
if ppos[x] > (dwidth - grid[x]) then
241
function TPad.scroll_down: Boolean;
245
if ppos[y] < grid[y] then
257
function TPad.scroll_up: Boolean;
261
dheight := pyx[y] - wyx[y] + 2;
262
if ppos[y] < dheight then
264
if ppos[y] > (dheight - grid[x]) then
276
function TPad.doevent: chtype;
279
rval: Boolean = true;
281
ch := wgetch(projwin);
283
KEY_DOWN: rval := scroll_up;
284
KEY_UP: rval := scroll_down;
285
KEY_LEFT: rval := scroll_right;
286
KEY_RIGHT: rval := scroll_left;
296
procedure TPad.dorefresh;
302
rval := copywin(padwin,projwin,ppos[y],ppos[x],1,1,wyx[y]-2,wyx[x]-2, 0);
303
assert(rval=OK,'copywin error');
309
function TPad.move(const ncoord: array of Smallint): Boolean;
311
move := move_panel(panel, ncoord[y], ncoord[x]) = OK
314
function TPad.hide: Boolean;
316
hide := hide_panel(panel) = OK
319
function TPad.show: Boolean;
321
show := show_panel(panel) = OK
324
procedure TPad.resize;
327
doresize: Boolean = false;
329
getbegyx(projwin,nsize[y],nsize[x]);
334
if nsize[y] > LINES then
336
nsize[y] := LINES; doresize := true
341
if nsize[x] > COLS then
343
nsize[x] := COLS; doresize := true
352
function TPad.resize(const nsize: array of Smallint): Boolean;
355
domove: Boolean = false;
359
if (nsize[y] <= LINES)AND(nsize[x] <= COLS) then
361
if nsize[y] > pyx[y] + 2 then
362
tcoord[y] := pyx[y] + 2
364
tcoord[y] := nsize[y];
366
if nsize[x] > pyx[x] + 2 then
367
tcoord[x] := pyx[x] + 2
369
tcoord[x] := nsize[x];
372
getbegyx(projwin, by, bx);
374
if tcoord[y] + by >= LINES then
376
by := LINES - tcoord[y]; domove := true
379
if tcoord[x] + bx >= COLS then
381
bx := COLS - tcoord[x]; domove := true
384
if tcoord[x] > (pyx[x] - ppos[x]) then
386
if tcoord[y] > (pyx[y] - ppos[y]) then
390
wresize(projwin, tcoord[y], tcoord[x]);
393
move_panel(panel, by, bx);
396
box(projwin, ACS_VLINE, ACS_HLINE);
398
getmaxyx(projwin,wyx[y],wyx[x]);
399
header.coord[y] := 0; header.coord[x] := 0;
401
print_in_middle(projwin, header, 0);
413
constructor TPad.create(const parm: array of TNcCoord; const hdr: TNcStr);
416
tysz, txsz: Smallint;
419
if parm[0,y] >= parm[1,y] + 2 then
420
wyx[y] := parm[1,y] + 2
424
if parm[0,x] >= parm[1,x] + 2 then
425
wyx[x] := parm[1,x] + 2
429
projwin := newwin(wyx[y], wyx[x], (LINES - wyx[y]) div 2, (COLS - wyx[x]) div 2);
430
intrflush(projwin, FALSE);
431
keypad(projwin, TRUE);
432
box(projwin, ACS_VLINE, ACS_HLINE);
434
panel := new_panel(projwin);
435
padwin := newpad(parm[1,y], parm[1,x]);
442
getmaxyx(projwin,tysz, txsz);
443
assert((wyx[y]=tysz)AND(wyx[x]=txsz), 'Invalid window');
445
getmaxyx(padwin,tysz, txsz);
446
assert((pyx[y]=tysz)AND(pyx[x]=txsz), 'Invalid pad');
448
FmtStr(header.str, '%s, pad: h=%d w=%d, win: h=%d w=%d', [hdr.str,pyx[y],pyx[x],wyx[y],wyx[x]]);
451
print_in_middle(projwin, header, 0);
460
destructor TPad.destroy;
467
procedure init_stdscr;
470
attron(COLOR_PAIR(7));
471
mvaddstr(LINES - 3, 0,'press "+" "-" to resize ');
472
mvaddstr(LINES - 2, 0,'press UP, DOWN, LEFT, RIGHT to scroll');
473
mvaddstr(LINES - 1, 0,'press F10 or q to exit ');
474
attroff(COLOR_PAIR(7));
482
my_bg: Smallint = COLOR_BLACK;
483
wnd, pad, grid: TNcCoord;
485
header: TNcStr = (str:'Pad demo';attr:A_NORMAL;coord:(0,0));
493
keypad(stdscr, TRUE);
500
if (use_default_colors() = OK) then
503
my_bg := COLOR_BLACK;
505
init_pair(1, COLOR_YELLOW, my_bg);
506
init_pair(2, COLOR_MAGENTA, my_bg);
507
init_pair(3, COLOR_WHITE, my_bg);
508
init_pair(4, COLOR_CYAN, my_bg);
509
init_pair(5, COLOR_GREEN, my_bg);
510
init_pair(6, COLOR_WHITE, COLOR_BLUE);
511
init_pair(7, COLOR_BLACK, COLOR_YELLOW);
519
pad[y] := wnd[y] + 6;
520
pad[x] := wnd[x] + 6;
525
if paramcount > 1 then
527
val(ParamStr(1),pad[y],code);
528
val(ParamStr(2),pad[x],code);
531
if paramcount > 3 then
533
val(ParamStr(3),wnd[y],code);
534
val(ParamStr(4),wnd[x],code);
537
header.attr := COLOR_PAIR(6);
538
ncpad := TPad.create([wnd,pad,grid],header);
547
chtype('+'): ncpad.resize([ncpad.ysize + 1,ncpad.xsize + 1]);
548
chtype('='): ncpad.resize([ncpad.ysize + 1,ncpad.xsize + 1]);
549
chtype('-'): ncpad.resize([ncpad.ysize - 1,ncpad.xsize - 1]);
550
chtype(' '): ncpad.resize([wnd[y],wnd[x]]);
561
until (ch = chtype('q')) OR (ch = KEY_F(10));