📄 zbrowse.c
字号:
#include <stdio.h>
#include <malloc.h>
#include "zlib.h"
typedef struct
{
int (*p)();
} ZPROC;
typedef struct
{
int k;
char *l;
} ZBUTL;
typedef struct
{
void *s;
ZBROWSE *b;
ZPROC n;
ZPROC *k;
} ZBRWS;
static ZBRWS *S;
static ZBROWSE *B;
static ZBUTL CtrlKey[]=
{
{ UP, "↑上行" },
{ DOWN, "↓下行" },
{ LEFT, "←左列" },
{ RIGHT, "→右列" },
{ HOME, "Home首页" },
{ END, "End 末页" },
{ PGUP, "PgUp前页" },
{ PGDN, "PgDn次页" },
{ '8', "8-上行" },
{ '2', "2-下行" },
{ '4', "4-左列" },
{ '6', "6-右列" },
{ '7', "7-首页" },
{ '1', "1-末页" },
{ '9', "9-前页" },
{ '3', "3-次页" }
};
static void GetPage()
{
int i;
B->lc = 0;
for( i = 0; i < B->rr * B->rc; i ++ )
{
if( ( !B->gl || ( *B->gl )( i ) ) && B->el )
( *B->el )();
B->lc ++;
if( i == B->rr * B->rc - 1 || !B->nl || ( *B->nl )() )
break;
}
}
static void EmptyRest()
{
int i;
if( B->el )
for( i = B->lc; i < B->rr * B->rc; i ++ )
( *B->el )( i );
}
static void DispCursor()
{
if( B->dl && B->lc > 0 )
{
ZWattr( ZA_SELBAR );
( *B->dl )( B->cl );
ZWattr( ZA_TEXT );
}
if( B->cc )
( *B->cc )();
}
static void DispPage()
{
int i;
if( B->dl )
for( i = 0; i < B->rr * B->rc; i ++ )
( *B->dl )( i );
if( B->cl >= B->lc )
B->cl = B->lc - 1;
if( B->cl < 0 )
B->cl = 0;
DispCursor();
}
static int BackLine( int Lines )
{
int i;
if( !B->pl || !B->sl || !B->gl )
return( 0 );
for( i = 0; i < Lines; i ++ )
{
if( ( *B->sl )( 0 ) )
break;
if( ( *B->pl )() )
break;
if( ( *B->gl )( 0 ) )
break;
}
if( ( *B->sl )( 0 ) )
return( 0 );
return( i );
}
static int RoundPage()
{
int l, c;
if( B->lc < 0 )
B->lc = 0;
else{
l = -1;
while( l != B->lc )
{
GetPage();
l = B->lc;
if( l < B->rr * B->rc )
{
c = BackLine( B->rr * B->rc - l );
B->lc += c;
B->cl += c;
}
}
if( B->lc == 1 && B->ur )
return( ( *B->ur )() );
}
return( 0 );
}
static int NewPage()
{
int r;
r = RoundPage();
if( r )
return( r );
EmptyRest();
DispPage();
return( 0 );
}
static void ChangeCursor( int New )
{
if( B->dl )
( *B->dl )( B->cl );
B->cl = New;
DispCursor();
}
static int KeyValid( int Key )
{
int r;
if( B->st )
return( -1 );
r = 0;
switch( Key )
{
case UP:
case '8':
if( B->cl < B->rc && !BackLine( B->rc ) )
r = -1;
break;
case DOWN:
case '2':
if( B->cl >= B->lc - B->rc && ( B->lc < B->rr * B->rc || !B->sl || ( *B->sl )( B->lc - 1 ) || !B->nl || ( *B->nl )() || !B->sl || ( *B->sl )( B->rc ) ) )
r = -1;
break;
case LEFT:
case '4':
if( !B->cl && ( !B->sl || ( *B->sl )( 0 ) || !B->pl || ( *B->pl )() ) )
r = -1;
break;
case RIGHT:
case '6':
if( B->cl + 1 >= B->lc && ( B->lc < B->rr * B->rc || !B->sl || ( *B->sl )( B->lc -1 ) || !B->nl || ( *B->nl )() || !B->sl || ( *B->sl )( 1 ) ) )
r = -1;
break;
case HOME:
case '7':
if( !B->sl || ( *B->sl )( 0 ) || !B->pl || ( *B->pl )() || !B->fl || ( *B->fl )() )
r = -1;
break;
case END:
case '1':
if( B->lc < B->rr * B->rc || !B->sl || ( *B->sl )( B->lc - 1 ) || !B->nl || ( *B->nl )() || !B->ll || ( *B->ll )() )
r = -1;
break;
case PGUP:
case '9':
if( !BackLine( B->rr * B->rc ) )
r = -1;
break;
case PGDN:
case '3':
if( B->lc < B->rr * B->rc || !B->sl || ( *B->sl )( B->lc - 1 ) || !B->nl || ( *B->nl )() )
r = -1;
break;
}
return( r );
}
static int KeyHit( int Key )
{
switch( Key ){
case UP:
case '8':
if( B->cl >= B->rc )
ChangeCursor( B->cl - B->rc );
else
NewPage();
break;
case DOWN:
case '2':
if( B->cl < B->lc - B->rc )
ChangeCursor( B->cl + B->rc );
else
NewPage();
break;
case LEFT:
case '4':
if( B->cl > 0 )
ChangeCursor( B->cl - 1 );
else
NewPage();
break;
case RIGHT:
case '6':
if( B->cl + 1 < B->lc )
ChangeCursor( B->cl + 1 );
else
NewPage();
break;
case HOME:
case '7':
case END:
case '1':
case PGUP:
case '9':
case PGDN:
case '3':
NewPage();
break;
}
return( -1 );
}
static int CheckStatus( int Key, int Number )
{
if( B->st )
return( -1 );
if( !( S->k + Number )->p )
return( 0 );
return( ( *( S->k + Number )->p )( Key, Number ) );
}
static int StartUp()
{
if( B->fl && ( *B->fl )() )
{
if( B->nr )
return( ( *B->nr )() );
else
B->lc = -1;
}
return( 0 );
}
static int EndOver()
{
if( B->ll && ( *B->ll )() )
{
if( B->nr )
return( ( *B->nr )() );
else
B->lc = -1;
}
return( 0 );
}
static int IdleProc()
{
int r;
if( B->st )
{
switch( B->st )
{
case ZI_CURSOR:
if( ( !B->sl || ( *B->sl )( B->cl ) || !B->gl || ( *B->gl )( B->cl ) ) && B->el )
B->el( B->cl );
DispCursor();
break;
case ZI_PAGE:
if( ( r = NewPage() ) != 0 )
return( r );
break;
case ZI_FIRST:
if( ( r = StartUp() ) != 0 )
return( r );
if( ( r = NewPage() ) != 0 )
return( r );
break;
case ZI_LAST:
if( ( r = EndOver() ) != 0 )
return( r );
if( ( r = NewPage() ) != 0 )
return( r );
break;
}
B->st = 0;
}
if( B->dc && !( *B->dc )() )
{
while( B->lc && B->sl && ( *B->sl )( B->cl ) )
if( B->cl )
B->cl --;
else
B->lc = 0;
if( B->lc )
B->cl = BackLine( B->cl );
else if( ( r = EndOver() ) != 0 )
return( r );
if( ( r = NewPage() ) != 0 )
return( r );
}
if( S->n.p )
return( ( *S->n.p )( B->s->fc, 0 ) );
return( 0 );
}
static void SetButton( ZBUTTON *B, int C, ZBUTL *L )
{
int i;
if( ( i = ZBkey( B, C, L->k ) ) >= 0 )
{
if( !( B + i )->l )
( B + i )->l = L->l;
if( !( B + i )->v )
( B + i )->v = KeyValid;
if( !( B + i )->p )
( B + i )->p = KeyHit;
}
}
static void ResetButton( ZBUTTON *B, int C, ZBUTL *L )
{
int i;
if( ( i = ZBkey( B, C, L->k ) ) >= 0 )
{
if( ( B + i )->l == L->l )
( B + i )->l = 0;
if( ( B + i )->v == KeyValid )
( B + i )->v = 0;
if( ( B + i )->p == KeyHit )
( B + i )->p = 0;
}
}
static void BeforeExec()
{
int i;
ZBUTTON *p;
int c;
p = B->s->bs;
c = B->s->bc;
for( i = 0; i < sizeof( CtrlKey ) / sizeof( ZBUTL ); i ++ )
SetButton( ( ZBUTTON * ) p, c, CtrlKey + i );
for( i = 0; i < c; i ++ )
if( ( ( ZBUTTON * ) p + i )->v != KeyValid )
{
( S->k + i )->p = ( ( ZBUTTON * ) p + i )->v;
( ( ZBUTTON * ) p + i )->v = CheckStatus;
}
S->n.p = B->s->nk;
B->s->nk = IdleProc;
}
static void AfterExec()
{
int i;
ZBUTTON *p;
int c;
B->s->nk = S->n.p;
p = B->s->bs;
c = B->s->bc;
for( i = 0; i < c; i ++ )
if( ( ( ZBUTTON * ) p + i )->v == CheckStatus )
( ( ZBUTTON * ) p + i )->v = ( S->k + i )->p;
for( i = 0; i < sizeof( CtrlKey ) / sizeof( ZBUTL ); i ++ )
ResetButton( ( ZBUTTON * ) p, c, CtrlKey + i );
}
int Zbrowse( ZBROWSE *BS )
{
int r;
ZBRWS *t;
if( ( t = ( ZBRWS * ) malloc( sizeof( ZBRWS ) ) ) == NULL )
return( 0 );
t->s = S;
S = t;
B = S->b = BS;
S->k = NULL;
if( ( S->k = ( ZPROC * ) malloc( B->s->bc * sizeof( int * ) ) ) == NULL )
goto Exit;
B->cl = 0;
if( ( r = StartUp() ) != 0 )
goto Exit;
if( ( r = RoundPage() ) != 0 )
goto Exit;
if( ZWopen( B->wp ) )
goto Exit;
if( B->ds )
( *B->ds )();
EmptyRest();
DispPage();
BeforeExec();
r = Zscreen( B->s );
AfterExec();
ZWclose();
Exit:
if( S->k != NULL )
free( S->k );
t = S->s;
free( S );
S = t;
B = S->b;
return( r );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -