home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
back2roots/padua
/
padua.7z
/
padua
/
ftp.vapor.com
/
microdot-1
/
md1_src_02.lzx
/
scroller.c
< prev
next >
Wrap
C/C++ Source or Header
|
2014-05-19
|
37KB
|
1,974 lines
#include "microdot.h"
#include <proto/gadtools.h>
#include "ogre_protos.h"
extern struct Gadget scrollgad;
extern struct PropInfo propinfo;
static int scrollermode;
static struct List *currentlist;
static long currenttop, currentsel, nopropupdate;
static APTR topnode;
static ULONG numentries;
static int lastdir = -1;
#define LDU 0
#define LDD 1
#define swap(a,b){int t;t=a;a=b;b=t;}
static ULONG scrollerhistory[ 128 ];
// Fⁿr ALT-F1/F10
static ULONG posarray[á4 * 10 ];
static void scrollerup( void );
static void scrollerdown( void );
static void scrolleruplines( int );
static void scrollerdownlines( int );
static int mark_xs, mark_ys, mark_xe, mark_ye;
void updateprop(void)
{
ULONG total = numentries;
ULONG hidden,top = currenttop;
if( nopropupdate )
return;
hidden = max( total - screenlines, 0 );
if(top>hidden) top=hidden;
propinfo.VertPot=(hidden>0)?(((ULONG)top*MAXPOT)/hidden):0;
NewModifyProp( &scrollgad, w, 0, propinfo.Flags,
propinfo.HorizPot, propinfo.VertPot,
propinfo.HorizBody, propinfo.VertBody, 1
);
}
static char gadt[ 16 * 32];
static struct Gadget gads[16];
static struct IntuiText gadit[32];
static UBYTE gscs[32];
static int gads_active, gadsize;
static struct Gadget *gtglist;
static struct VisualInfo *gtvi;
static struct TextAttr microfontta, microfontta_underlined;
#define SETXY(b,n,x,y) b[(n)*2]=x;b[((n)*2)+1]=y;
void removescrollgads( void )
{
if( gads_active )
{
if( gtglist )
{
RemoveGList( w, gtglist, gads_active );
FreeGadgets( gtglist );
FreeVisualInfo( gtvi );
gtglist = NULL;
}
else
{
RemoveGList( w, &gads[0], gads_active );
}
gads_active = 0;
}
}
static void scrollgads( int maxentries, char **entries, UWORD *codes )
{
int c;
int gadxsize, gadysize;
int halfmaxentries = maxentries / 2;
ULONG posarray[8];
ULONG sizearray[8];
char *p;
int labeloffs, labelchar;
int fys, cml;
struct TextFont *gtf;
struct Border *gb, *sb;
struct NewGadget ng;
struct Gadget *gtlg = NULL, *g;
static char **oldentries;
static UWORD *oldcodes;
static ULONG oldwidth;
if( ! ( prefs.flags & MDF_GADGETS ) /*&& !wbwindow */ )
{
removescrollgads();
return;
}
if( gads_active && ( entries == oldentries ) && ( codes == oldcodes ) && ( oldwidth == w->Width ) )
{
if( !wbwindow )
screenlines = (scr->Height - topoffs - gadsize ) / fontysize;
return;
}
oldentries = entries;
oldcodes = codes;
oldwidth = w->Width;
removescrollgads();
microfontta.ta_Name = prefs.gadfontname;
microfontta.ta_YSize = fys = prefs.gadfontheight;
microfontta_underlined = microfontta;
microfontta_underlined.ta_Style |= FSF_UNDERLINED;
gtf = OpenDiskFont( µfontta );
memset( &gads[0], 0, sizeof( struct Gadget ) * 16 );
memset( &gadit[0], 0, sizeof( struct IntuiText ) * 16 );
gadsize = ( fys + 2 ) * 2 + 4;
gadysize = fys + 2;
if( !wbwindow )
{
gyoffs = scr->Height - gadsize;
screenlines = (scr->Height - topoffs - gadsize ) / fontysize;
SetAPen(rp, screenpens[ SHADOWPEN ] );
Move(rp,0,gyoffs);
Draw(rp,screenxsize-17,rp->cp_y);
SetAPen(rp, screenpens[ SHINEPEN ] );
Move(rp,0,rp->cp_y+1);
Draw(rp,screenxsize-17,rp->cp_y);
SetAPen( rp, 0 );
RectFill( rp, 0, gyoffs + 2, screenxsize - 17, scr->Height - 1 );
}
else
{
gyoffs = - ( ( ( fys + 4 ) * 2 ) + 1 );
}
/* Setup Positions */
if( wbwindow )
{
c = w->Width - w->BorderLeft - w->BorderRight - 4;
gadxsize = ( c / halfmaxentries ) - 2;
for( c = 0; c < halfmaxentries; c++ )
posarray[c] = ( ( gadxsize + 2 ) * c ) + w->BorderLeft + 2;
}
else
{
gadxsize = ( ( screenxsize - 20) / halfmaxentries ) - 2;
for( c = 0; c < halfmaxentries; c++ )
sizearray[c] = gadxsize;
rtSpread( posarray, sizearray, gadxsize*halfmaxentries, 8, screenxsize - 24, halfmaxentries );
if( isv37 )
{
gtvi = GetVisualInfo( scr, TAG_DONE );
gtlg = CreateContext( >glist );
ng.ng_TextAttr = µfontta;
ng.ng_Width = gadxsize;
ng.ng_Height = gadysize;
ng.ng_Flags = 0;
ng.ng_VisualInfo = gtvi;
}
}
if( !gtlg )
{
gb = makebevelborder( gadxsize, gadysize, FALSE );
sb = makebevelborder( gadxsize, gadysize, TRUE );
}
/* Setup Gadgets */
for( c = 0; c < maxentries; c++ )
{
if( gtlg )
{
ng.ng_GadgetText = entries[ cá];
ng.ng_LeftEdge = posarray[ c % halfmaxentries ];
ng.ng_TopEdge = ( c >= halfmaxentries ) ? gyoffs + gadysize + 4 : gyoffs + 3;
ng.ng_GadgetID = 256 + c;
ng.ng_UserData = ( void * ) codes[ác ];
gtlg = CreateGadget( BUTTON_KIND, gtlg, &ng, GT_Underscore, '_', TAG_DONE );
}
else
{
if( c != ( maxentries - 1 ) )
gads[c].NextGadget = &gads[ác + 1];
gads[c].LeftEdge = posarray[ c % halfmaxentries ];
gads[c].TopEdge = ( c >= halfmaxentries ) ? gyoffs + gadysize + 4 : gyoffs + 3;
gads[c].Width = gadxsize;
gads[c].Height = gadysize;
gads[c].Flags = GFLG_GADGHIMAGE;
gads[c].Activation = GACT_RELVERIFY;
gads[c].GadgetType = GTYP_BOOLGADGET;
gads[c].GadgetRender= gb;
gads[c].SelectRender= sb;
gads[c].GadgetID = 256 + c;
gads[c].GadgetText = &gadit[c];
gads[c].UserData = (void *) codes[c];
if( wbwindow )
{
gads[c].Activation |= GACT_BOTTOMBORDER;
gads[c].GadgetType |= GTYP_GZZGADGET;
gads[c].Flags |= GFLG_RELBOTTOM;
}
gadit[c].FrontPen = 1;
gadit[c].TopEdge = 1;
gadit[c].IText = &gadt[c*32];
gadit[c].ITextFont = µfontta;
strcpy( &gadt[c*32], entries[c]);
p = strchr( &gadt[c*32], '_' );
if( p )
{
*p = 0;
gscs[ c * 2 ] = p[ 1 ];
labeloffs = IntuiTextLength( &gadit[c] );
labelchar = ( ( int ) p ) - ( ( int )( &gadt[ c * 32 ] ) );
strcpy( p, &p[1] );
}
gadit[c].LeftEdge = ( gadxsize - IntuiTextLength( &gadit[c] ) ) / 2;
/* Gadget-Text Kⁿrzen? */
if( gadit[c].LeftEdge < 2 )
{
cml = ogreTextFit( gtf, &gadt[ c * 32 ], gadxsize - 4 );
gadt[ ( c * 32 ) + cml ] = 0;
/* Shortcut wech? */
if( cml <= labelchar )
p = NULL;
gadit[c].LeftEdge = ( gadxsize - IntuiTextLength( &gadit[c] ) ) / 2;
}
if( p )
{
gadit[ c + 16] = gadit[c];
gadit[c].NextText = &gadit[ c + 16 ];
gadit[c+16].IText = &gscs[ c * 2 ];
gadit[c+16].ITextFont = µfontta_underlined;
gadit[c+16].LeftEdge += labeloffs;
}
}
}
gads_active = maxentries;
if( gtglist )
{
/* Gadtools-Gadgets zΣhlen */
g = gtglist;
gads_active = 0;
while( g )
{
gads_active++;
g = g->NextGadget;
}
AddGList( w, gtglist, 0, gads_active, NULL );
RefreshGList( gtglist, w, NULL, gads_active + 1 );
GT_RefreshWindow( w, NULL );
}
else
{
AddGList( w, &gads[0], 0, gads_active, NULL );
if( wbwindow )
RefreshWindowFrame( w );
else
RefreshGList( &gads[0], w, NULL, gads_active );
}
CloseFont( gtf );
}
static char *sg_brett[12] = {
"WΣhlen",
"Markieren",
"Alle Demarkieren",
"_nΣchste Neue",
"_Neues Brett",
"_aufrΣumen",
"_Alles AufrΣumen",
"Brettinhalt l÷schen",
"Brett l÷schen",
"Brett_parameter",
"Nachricht schr_eiben",
"Hilfe" };
static UWORD sg_brett_codes[12] = {
0x44,
0x40,
0x0 | 0x100,
0x36,
0x36 | 0x100,
0x20,
0x20 | 0x100,
0x46,
0x46 | 0x100,
0x19,
0x12,
0x5f };
static char *sg_inhalt[14]á= {
"Lesen",
"_Antwort",
"_Private Antwort",
"_Weiterleiten",
"Markieren",
"_Drucken",
"Auslagern",
"Thread _falten",
"Alle fal_ten",
"Alle entfal_Ten",
"Schr_eiben",
"L÷schen",
"Zurⁿck/Neu l÷schen",
"Zurⁿck",
};
static UWORD sg_inhalt_codes[14] = {
0x44,
0x20 | 0x100,
0x19 | 0x100,
0x11,
0x40,
0x22,
0x32 /*| 0x100*/,
0x23,
0x14,
0x14 | 0x100,
0x12,
0x46,
0x200,
0x201
};
static char *sg_msg[14]á= {
"Extern anzeigen",
"_Antwort",
"_Private Antwort",
"_Weiterleiten",
"Markieren",
"_Drucken",
"Auslagern",
"Halten",
"Wiedervorlage",
"L÷schen",
"Thread _Killen",
"Absender speichern",
"_nΣchste Neue",
"Zurⁿck",
};
static UWORD sg_msg_codes[14] = {
0x34,
0x20 | 0x100,
0x19 | 0x100,
0x11,
0x40,
0x22,
0x32 /*| 0x100*/,
0x25,
0x01 | 0x100,
0x46,
0x27 | 0x100,
0x21 | 0x100,
0x36,
0x45,
};
void makescrollergads( void )
{
switch( scrollermode )
{
case 0:
scrollgads( 12, sg_brett, sg_brett_codes );
break;
case 1:
scrollgads( 14, sg_inhalt, sg_inhalt_codes );
break;
case 2:
scrollgads( 14, sg_msg, sg_msg_codes );
break;
default:
removescrollgads();
SetAPen( rp, 0 );
RectFill( rp, 0, topoffs, scr->Width - 17, scr->Height - 1 );
break;
}
}
void __inline findtopnode( void )
{
topnode = GetEntry( currentlist, currenttop );
}
static void __inline findtopnode_next( int n )
{
topnode = GetEntryFromHere( topnode, n );
}
static void __inline findtopnode_before( int n )
{
while( n-- )
topnode = ( ( struct Node * ) topnode )->ln_Pred;
}
void setupscroller(struct List *l,int mode)
{
UWORD total,hidden;
OffMenu( w, FULLMENUNUM( 3, 22, NOSUB ) ); // Clipboard...
mark_xs = mark_ys = mark_xe = mark_ye = -1;
memset( &scrollerhistory[á0 ], 0xff, 128 * 4 );
scrollermode=mode;
currenttop=currentsel=0;
currentlist=l;
findtopnode();
numentries = total = GetNumEntries(currentlist);
hidden = max( total - screenlines, 0 );
propinfo.VertBody=(hidden>0)?(UWORD)(((ULONG)(screenlines-1)*MAXBODY)/(total-1)):MAXBODY;
updateprop();
SetAPen( rp, 0 );
RectFill( rp, 0, topoffs, scr->Width-17, topoffs + ( fontysize * screenlines ) - 1 );
if( mode > 1 )
memset( &posarray[ámode * 10 ], 0, 10 * 4 );
/*screenlines=(scr->Height-topoffs)/fontysize;*/
recalcwindowsize();
scrollerdoclick( 0 );
makescrollergads();
}
/*static void formatbrettline( char *buff, struct mbrett *n )
{
char x[ 6 ];
utunpk(n->b.lastwrite,x);
sprintf(buff,"%-39.39s\x05%4ld\x05%4ld\x05%4ld\x05%02ld.%02ld\x05%s",
n->viewname,
n->b.mails,
n->b.newmails,
n->b.unreadmails,
x[á1 ], x[á2 ],
n->b.betreff
);
}*/
extern __asm formatbrettline( register __a0 char *, register __a1 struct mbrett * );
void displayscrollerbrett(void)
{
ULONG c;
struct mbrett *n=(struct mbrett*)topnode;
char buff[ 512 ];
int p;
for(c=0; c<screenlines; c++)
{
if(n && n->n.ln_Succ)
{
if( c == currentsel - currenttop )
{
if( n->n.ln_Type )
p = PEN_MARKSEL;
else
p = PEN_SEL;
}
else
{
if( n->n.ln_Type )
p = PEN_MARK;
else
p = PEN_TEXT;
}
formatbrettline( buff, n );
qf_ws( c, p, buff );
n=(struct mbrett*)n->n.ln_Succ;
}
else
{
qf_ws( c, 0, "" );
}
}
}
static void countmailstree(struct mmail *n,int *new,int *count)
{
*count=(*count)+1;
if(n->m.flags&MMF_UNSEEN) *new=(*new)+1;
if(n->bezlink) countmailstree(n->bezlink,new,count);
if(n->firstbez) countmailstree(n->firstbez,new,count);
}
extern int ml_bet, ml_kb;
static void __inline fmtmsgline(struct vmail *vn,char *to)
{
struct mmail *n=vn->m;
int ind;
char fch1,fch2;
char *bet = n->m.betreff;
char *p;
int len;
/* Betreff RE:s filtern? */
if( prefs.flags & MDF_FILTERRE )
bet = &bet[ávn->m->reoffset ];
len = strlen( bet );
fch1='-';
if(n->m.flags&MMF_ARCHIVE) fch1='H';
else if(n->m.flags&MMF_DEL) fch1='L';
//if(n->m.flags&MMF_KILL) fch1='K';
fch2='-';
if(n->m.flags&MMF_UNSEEN) fch2='N';
if(n->m.flags&MMF_SHOW) fch2='!';
if(n->m.flags&MMF_OUT) fch2='>';
p = &to[áml_bet ];
*p++á= 5;
*p++á= fch2;
*p++á= (n->m.flags&MMF_GOTEB)?'E':((n->m.flags&MMF_READ)?'G':'-');
*p++á= ( n->m.flags & MMF_BIN ) ? 'B'á: '-';
*p++á= fch1;
*p++ = 5;
memcpy( p, vn->kb, ml_kb );
p += ml_kb;
*p++ = 5;
strcpy( p, vn->date );
p = strchr( p, 0 );
*p++ = 5;
strcpy( p, (n->m.absenderreal[0]&&prefs.flags&MDF_SHOWREAL)?n->m.absenderreal:n->m.absender );
/* sprintf( &to[áml_bet ],"\x05%lc%lc%lc%lc\x05%s\x05%s\x05%s",
fch2,
(n->m.flags&MMF_GOTEB)?'E':((n->m.flags&MMF_READ)?'G':'-'),
fch3,
fch1,
vn->kb,
vn->date,
(n->m.absenderreal[0]&&prefs.flags&MDF_SHOWREAL)?n->m.absenderreal:n->m.absender
);*/
ind = vn->indent;
if( ind > ( ml_bet - 1 ) )
{
memcpy( to, vn->indentspace, ml_bet - 1 );
to[áml_bet - 1 ]á= '╗';
}
else if( ind )
{
len = min( len, ml_bet - ind );
memcpy( to, vn->indentspace, ind );
memcpy( &to[áind ], bet, len );
memset( &to[ len + ind ], 32, ( ml_bet - ind ) - len );
}
else
{
len = min( len, ml_bet );
memcpy( to, bet, len );
memset( &to[ len ], 32, ml_bet - len );
}
if( n->m.flags & MMF_FOLD )
{
int v1=0,v2=0;
char x[á32 ];
if(n->firstbez)
countmailstree(n->firstbez,&v1,&v2);
sprintf(x," {F:%ld/%ld}",v1,v2);
memcpy( &to[ ml_bet - strlen( x ) ], x, strlen( x ) );
}
}
static void __inline displayscrollermsg(void)
{
ULONG c;
struct vmail *n=(struct vmail*)topnode;
char buff[ 512 ];
int p;
for(c=0; c<screenlines; c++)
{
if( n && n->n.mln_Succ )
{
if( c == currentsel - currenttop )
{
if( n->sel )
p = PEN_MARKSEL;
else
p = PEN_SEL;
}
else
{
if( n->sel )
p = PEN_MARK;
else
p = PEN_TEXT;
}
fmtmsgline(n,buff);
qf_ws( c, p, buff );
n=(struct vmail*)n->n.mln_Succ;
}
else
{
qf_ws( c, 0, "" );
}
}
}
static void markscrollerline( int line, int linelen )
{
int mxs = -1, mye = linelen;
int m_ys = mark_ys;
int m_xs = mark_xs;
int m_ye = mark_ye;
int m_xe = mark_xe;
if( m_ys > m_ye )
{
swap( m_ys, m_ye );
swap( m_xs, m_xe );
}
if( m_ys == m_ye )
{
if( m_xs > m_xe )
swap( m_xs, m_xe );
}
line += currenttop;
if( line == m_ys )
{
if( m_ys == m_ye )
mye = m_xe;
mxs = m_xs;
}
else if( line > m_ys && line < m_ye )
mxs = 0;
else if( line == m_ye )
{
mxs = 0;
mye = m_xe;
}
if( mxs >= 0 )
{
//Printf( "qf_inv %ld, %ld, %ld\n", line - currenttop, mxs, mye );
qf_inv( line - currenttop, mxs, mye );
}
}
static void __inline displayscrollertxt(void)
{
ULONG c;
struct dnode *n=(struct dnode*)topnode;
//UWORD pen[]á= { PEN_READ, PEN_QUOTE, PEN_HEAD };
for(c=0; c<screenlines; c++)
{
if(n && n->n.mln_Succ)
{
qf_wt( c, n );
markscrollerline( c, strlen( n->txt ) );
n=(struct dnode*)n->n.mln_Succ;
}
else
{
qf_clr( c );
}
}
}
static void __inline displayscrollermaps(void)
{
ULONG c;
struct mvnode *n=(struct mvnode*)topnode;
int p;
for(c=0; c<screenlines; c++) {
if(n && n->n.mln_Succ)
{
if( c == currentsel - currenttop )
{
if( n->sel )
p = PEN_MARKSEL;
else
p = PEN_SEL;
}
else
{
if( n->sel )
p = PEN_MARK;
else
p = PEN_TEXT;
}
qf_ws( c, p, n->txt );
n=(struct mvnode*)n->n.mln_Succ;
}
else
{
qf_clr( c );
}
}
}
void displayscroller(void)
{
switch(scrollermode) {
case 0: displayscrollerbrett(); break;
case 1: displayscrollermsg(); break;
case 2: displayscrollertxt(); break;
case 3: displayscrollermaps(); break;
}
}
static void __inline displayscrollerlinebrett(int c)
{
struct mbrett *n;
char buff[ 512 ];
int p;
if(c<0||c>=screenlines) return;
n=(struct mbrett*)GetEntryFromHere( topnode, c );
if( n && n->n.ln_Succ )
{
if( c == currentsel - currenttop )
{
if( n->n.ln_Type )
p = PEN_MARKSEL;
else
p = PEN_SEL;
}
else
{
if( n->n.ln_Type )
p = PEN_MARK;
else
p = PEN_TEXT;
}
formatbrettline( buff, n );
qf_ws( c, p, buff );
/*n=(struct mbrett*)n->n.ln_Succ;*/
}
else
{
qf_ws( c, 0, "" );
}
}
static void __inline displayscrollerlinemsg(int c)
{
struct vmail *n;
char buff[ 512 ];
int p;
if(c<0||c>=screenlines||!topnode) return;
n=(struct vmail*)GetEntryFromHere( topnode, c );
if(n && n->n.mln_Succ)
{
if( c == currentsel - currenttop )
{
if( n->sel )
p = PEN_MARKSEL;
else
p = PEN_SEL;
}
else
{
if( n->sel )
p = PEN_MARK;
else
p = PEN_TEXT;
}
fmtmsgline(n,buff);
qf_ws( c, p, buff );
/*n=(struct vmail*)n->n.mln_Succ;*/
}
else
{
qf_ws( c, 0, "" );
}
}
static void __inline displayscrollerlinetxt(int c)
{
struct dnode *n;
//UWORD pen[]á= { PEN_READ, PEN_QUOTE, PEN_HEAD };
if(c<0||c>=screenlines) return;
n=(struct dnode*)GetEntryFromHere( topnode, c );
if( n && n->n.mln_Succ )
{
qf_wt( c, n );
/*n=(struct vmail*)n->n.mln_Succ;*/
markscrollerline( c, strlen( n->txt ) );
}
else
{
qf_clr( c );
}
}
static void __inline displayscrollerlinemaps(int c)
{
struct mvnode *n;
int p;
if(c<0||c>=screenlines) return;
n=(struct mvnode*)GetEntryFromHere( topnode, c );
if(n && n->n.mln_Succ)
{
if( c == currentsel - currenttop )
{
if( n->sel )
p = PEN_MARKSEL;
else
p = PEN_SEL;
}
else
{
if( n->sel )
p = PEN_MARK;
else
p = PEN_TEXT;
}
qf_ws( c, p, n->txt );
}
else
{
qf_ws( c, 0, "" );
}
}
void displayscrollerline( int c )
{
switch( scrollermode )
{
case 0: displayscrollerlinebrett(c); break;
case 1: displayscrollerlinemsg(c); break;
case 2: displayscrollerlinetxt(c); break;
case 3: displayscrollerlinemaps(c); break;
}
}
extern void __asm storeselsup( register __a0 APTR from, register __d0 ULONG new );
static void storecurrentsel( void )
{
storeselsup( &scrollerhistory[á128 ], getscrollerstate() );
/* memmove( &scrollerhistory[ 1 ], &scrollerhistory[á0 ], 127 * 4 );
scrollerhistory[á0 ]á= getscrollerstate();*/
}
static void scrollerhis( void )
{
ULONG s = scrollerhistory[á0 ];
if( s == ~0 )
{
displaybeep();
return;
}
scrollerhistory[ 127 ]á= ~0;
memcpy( &scrollerhistory[á0 ], &scrollerhistory[á1 ], 127 * 4 );
setscrollerstate( s );
}
void setscrollercurrent_internal( int num )
{
if( num != currentsel )
storecurrentsel();
currentsel = num;
}
void setscrollercurrent( int num )
{
int oldsel=currentsel;
if( scrollermode == 2 )
{
if(num<0) num=0;
if( num > ( numentries - screenlines ) )
num = numentries - screenlines;
/*currentsel = num;*/
if( num < oldsel )
scrolleruplines( oldsel - num );
else
scrollerdownlines( num - oldsel );
/*setscrollertop( num );*/
return;
}
if( num < 0 )
num = 0;
if( num >= numentries )
num = numentries - 1;
if( num != oldsel )
storecurrentsel();
currentsel=num;
displayscrollerline(oldsel-currenttop);
displayscrollerline(currentsel-currenttop);
}
void setscrollercurrent2( int num )
{
int oldsel=currentsel;
if( scrollermode == 2 )
{
if(num<0) num=0;
if(num>(numentries-screenlines)) num=numentries-screenlines;
/*currentsel=num;*/
if( num < oldsel )
scrolleruplines( oldsel - num );
else
scrollerdownlines( num - oldsel );
/*setscrollertop(num);*/
return;
}
if( num < 0 )
num = 0;
if( num >= numentries )
num = numentries - 1;
if( num != oldsel )
storecurrentsel();
currentsel = num;
/* Alte demarkieren */
displayscrollerline( oldsel - currenttop );
}
void displaycurrentline( void )
{
displayscrollerline( currentsel - currenttop );
}
static void scrollerup( void )
{
if( scrollermode == 2 )
{
if( currentsel > 0 )
{
setscrollercurrent( currentsel - 1 );
//findtopnode_before( 1 );
}
return;
}
if( currenttop )
{
currenttop--;
findtopnode_before( 1 );
ClipBlit( rp, 0, topoffs, rp, 0, topoffs+fontysize, screenxsize-16,(screenlines-1)*fontysize, 0xc0 );
displayscrollerline( 0 );
updateprop();
}
}
static void scrollerdown(void)
{
int x;
if( scrollermode == 2 )
{
if( currentsel < ( numentries - screenlines ) )
{
setscrollercurrent( currentsel + 1 );
//findtopnode_next( 1 );
}
return;
}
x=max(numentries-screenlines,0);
if(currenttop<x)
{
currenttop++;
findtopnode_next( 1 );
ClipBlit( rp,0,topoffs+fontysize, rp,0,topoffs, screenxsize-16,(screenlines-1)*fontysize, 0xc0 );
displayscrollerline( screenlines - 1);
updateprop();
}
}
void showcurrentitem( void )
{
int total;
int sj;
int newct;
int delta;
int ld = lastdir;
lastdir = -1;
if( scrollermode == 2 )
return;
if( currenttop < 0 )
{
currenttop = 0;
findtopnode();
displayscroller();
updateprop();
}
sj = ( ( prefs.flags2 & MDF2_SCROLLJUMP ) && ( scrollermode != 2 ) ) ? 5 : 1;
/* Prⁿfen, ob Cursor im Fenster ist */
switch( ld )
{
case LDD:
if( currentsel < ( currenttop + screenlines - sj ) )
return;
break;
case LDU:
if( currentsel >= currenttop + sj )
return;
break;
default:
if( currentsel >= currenttop &&
currentsel < ( currenttop + screenlines ) )
return;
break;
}
if( ( currentsel <= currenttop ) || ( ld == LDU ) )
{
newct = max( currentsel - sj + 1, 0 );
delta = currenttop - newct;
scrolleruplines( delta );
return;
}
else
{
total = numentries;
newct = min( currentsel - screenlines + sj, total - screenlines );
delta = currenttop - newct;
scrollerdownlines( -delta );
return;
}
}
int getscrollercurrent(void)
{
return(currentsel);
}
void setscrollertop(int top)
{
UWORD total = numentries;
UWORD hidden;
hidden = max( total - screenlines, 0 );
if( top > hidden )
top = hidden;
if( top == currenttop )
return;
currenttop = top;
findtopnode();
propinfo.VertPot=(hidden>0)?(((ULONG)top*MAXPOT)/hidden):0;
updateprop();
displayscroller();
}
void normalizescroller( void )
{
if( currentsel < 0 )
return;
if( currentsel < currenttop )
{
currenttop = currentsel;
findtopnode();
}
if( currentsel >= currenttop + screenlines )
{
currenttop = currentsel - screenlines + 1;
findtopnode();
}
}
ULONG getscrollerstate(void)
{
ULONG r=(currentsel|(currenttop<<16));
return(r);
}
void setscrollerstate( ULONG r )
{
currenttop=~0;
currentsel= r & 0xffff;
setscrollertop( r >> 16 );
}
struct si {
struct List *l;
ULONG mode;
USHORT currenttop,currentsel;
};
void *pushscs(void)
{
struct si *si=LibAllocPooled(miscmempool,sizeof(struct si));
if(!si) return(0);
si->mode=scrollermode;
si->currenttop=currenttop;
si->currentsel=currentsel;
si->l=currentlist;
return(si);
}
void popscs(void *sip)
{
struct si *si=sip;
if(!si) return;
setupscroller(si->l,si->mode);
currentsel=si->currentsel;
currenttop=~0;
setscrollertop(si->currenttop);
LibFreePooled(miscmempool,si,sizeof(struct si));
}
void popscsnv(void *sip)
{
struct si *si=sip;
if(!si) return;
// setupscroller(si->l,si->mode);
currentlist = si->l;
scrollermode = si->mode;
currentsel = si->currentsel;
currenttop = si->currenttop;
findtopnode();
LibFreePooled(miscmempool,si,sizeof(struct si));
}
void scrollerresize( void )
{
static UWORD lastwinx, lastwiny;
if( wbwindow && ( w->Height != lastwiny || w->Width != lastwinx ) )
{
recalcwindowsize();
if( w->Width != lastwinx )
makescrollergads();
lastwinx = w->Width;
lastwiny = w->Height;
updateprop();
sabd( rp, 0, 0, JAM1 );
RectFill( rp, 0, topoffs, screenxsize, w->GZZHeight );
if( scrollermode == 1 )
makevnodemlist( currentlist );
displayscroller();
}
}
static void resetmark( void )
{
if( mark_xs >= 0 )
{
mark_xs = mark_ys = mark_xe = mark_ye = -1;
OffMenu( w, FULLMENUNUM( 3, 22, NOSUB ) );
displayscrollertxt();
}
}
void doscrollerclipboard( void )
{
struct dnode *n;
int t;
int len = 0, la = 0, c;
char *p;
static struct IOClipReq *iocr;
struct MsgPort *iop;
static ULONG iffheader[]á= {
MAKE_ID('F','O','R','M'), 0,
MAKE_ID('F','T','X','T'),
MAKE_ID('C','H','R','S'), 0
};
if( scrollermode != 2 && mark_xs < 0 )
{
displaybeep();
return;
}
if( !iocr )
iocr = LibAllocPooled( miscmempool, sizeof( *iocr ) );
else
memset( iocr, 0, sizeof( *iocr ) );
if( mark_ys > mark_ye )
{
t = mark_ys;
mark_ys = mark_ye;
mark_ye = t;
t = mark_xs;
mark_xs = mark_xe;
mark_xe = t;
}
if( mark_ys == mark_ye )
{
if( mark_xs > mark_xe )
{
t = mark_xs;
mark_xs = mark_xe;
mark_xe = t;
}
}
for( c = mark_ys; c <= mark_ye; c++ )
{
n = ( struct dnode * ) GetEntry( currentlist, c );
if( n )
p = n->txt;
else
p = "";
len += strlen( p ) + 1;
if( c == mark_ys )
len -= mark_xs;
if( c == mark_ye )
len -= strlen( p ) - mark_xe;
}
if( len & 1 )
la = 1;
// Open Clipboard
iop = CreatePort( NULL, 0 );
iocr->io_Message.mn_ReplyPort = iop;
if( OpenDevice( "clipboard.device", 0, iocr, 0 ) )
{
askreq( "\"clipboard.device\" konnte nicht\nge÷ffnet werden.", "Abbruch" );
DeletePort( iop );
return;
}
iffheader[á1 ]á= len + la + 12;
iffheader[á4 ]á= len;
iocr->io_Command = CMD_WRITE;
iocr->io_Data = iffheader;
iocr->io_Length = 20;
DoIO( iocr );
for( c = mark_ys; c <= mark_ye; c++ )
{
n = ( struct dnode * ) GetEntry( currentlist, c );
if( n )
p = n->txt;
else
p = "";
len = strlen( p );
if( c == mark_ye )
len -= strlen( p ) - mark_xe;
if( c == mark_ys )
{
p = &p[ámark_xs ];
len -= mark_xs;
}
if( strlen( p ) )
{
iocr->io_Command = CMD_WRITE;
iocr->io_Data = p;
iocr->io_Length = strlen( p );
DoIO( iocr );
}
iocr->io_Command = CMD_WRITE;
iocr->io_Data = "\n";
iocr->io_Length = 1;
DoIO( iocr );
}
iocr->io_Command = CMD_UPDATE;
DoIO( iocr );
CloseDevice( iocr );
DeletePort( iop );
resetmark();
}
static void handletxtsel( struct IntuiMessage *im, int startline )
{
int startcol;
int Done = FALSE;
struct IntuiMessage cim;
int mousex = im->MouseX, mousey = im->MouseY;
int cx, cy;
int oldcy = -1, oldcx = -1;
struct dnode *n;
if( wbwindow )
{
mousex -= w->BorderLeft;
mousey -= w->BorderTop;
}
startcol = mousex / fontxsize;
n = ( struct dnode * ) GetEntryFromHere( topnode, startline );
if( !n || !n->txt )
startcol = 0;
else
startcol = min( startcol, strlen( n->txt ) - 1 );
resetmark();
OnMenu( w, FULLMENUNUM( 3, 22, NOSUB ) );
mark_xs = mark_xe = startcol;
mark_ys = mark_ye = startline + currenttop;
displayscrollerlinetxt( startline );
ReportMouse( TRUE, w );
w->Flags |= WFLG_RMBTRAP;
while( !Done )
{
while( !( im = GetIMsg( w->UserPort ) ) )
WaitPort( w->UserPort );
cim = *im;
ReplyMsg( im );
if( cim.Class == MOUSEBUTTONS )
{
if( cim.Code == SELECTUP )
Done = TRUE;
else if( cim.Code == MENUDOWN )
Done = 2;
}
else if( cim.Class == MOUSEMOVE )
{
mousex = cim.MouseX;
mousey = cim.MouseY;
if( wbwindow )
{
mousex -= w->BorderLeft;
mousey -= w->BorderTop;
}
}
if( cim.Class == INTUITICKS || cim.Class == MOUSEMOVE )
{
cx = mousex / fontxsize;
cy = ( mousey - (int)topoffs ) / (int)fontysize;
if( cx >= screencols )
cx = screencols - 1;
if( cy < 0 )
{
scrollerup();
cy = 0;
}
else if( cy >= screenlines )
{
scrollerdown();
cy = screenlines - 1;
}
n = ( struct dnode * ) GetEntryFromHere( topnode, cy );
if( n && n->txt )
{
mark_xe = min( cx, strlen( n->txt ) );
}
else
mark_xe = 0;
mark_ye = cy + currenttop;
if( mark_xe != oldcx || mark_ye != oldcy )
{
if( mark_ye != oldcy )
{
displayscrollertxt();
}
else
{
displayscrollerlinetxt( oldcy - currenttop );
}
}
oldcx = mark_xe;
oldcy = mark_ye;
}
}
w->Flags &= ~WFLG_RMBTRAP;
ReportMouse( FALSE, w );
if( Done == 2 )
resetmark();
}
int scrollerdoclick( struct IntuiMessage *im )
{
int l;
static int lastline;
static ULONG seconds,micros;
struct Node *n;
int rc=0;
UWORD mousex, mousey;
if( !im )
{
seconds = micros = 0;
return(0);
}
mousex = im->MouseX;
mousey = im->MouseY;
if( wbwindow )
{
mousex -= w->BorderLeft;
mousey -= w->BorderTop;
if( mousex < 0 || mousey < 0 || mousex >= screenxsize || mousey >= w->GZZHeight )
return( 0 );
}
if( im->Code == MIDDLEDOWN )
{
im->Code = SELECTDOWN;
im->Qualifier = QSHIFT;
}
if( im->Code == SELECTDOWN )
{
if(scrollermode>=1 && scrollermode<=3 && mousex<2 && mousey>22)
return( -1 );
if(scrollermode>=0 && scrollermode<=3 && mousey >= scr->Height - 2 )
return( -2 );
l= ( mousey - topoffs ) / fontysize;
if( l < 0 || l>=screenlines )
return( 0 );
/* Markieren */
if( scrollermode == 2 )
{
handletxtsel( im, l );
}
else
{
if( im->Qualifier & QSHIFT )
{
n=GetEntryFromHere( topnode,l );
if(n)
{
if(scrollermode && scrollermode !=3 )
((struct vmail*)n)->sel^=0xff;
else
n->ln_Type^=~0;
displayscrollerline(l);
}
}
else
{
setscrollercurrent( currenttop + l );
if( DoubleClick( seconds, micros,
im->Seconds,
im->Micros ) && l == lastline ) rc=1;
}
lastline=l;
seconds = im->Seconds;
micros = im->Micros;
}
}
return(rc);
}
void scrollerdomove( struct IntuiMessage *im )
{
UWORD total=numentries;
UWORD new, hidden;
int delta, dir = 0;
hidden=max(total-screenlines,0);
new=(((ULONG)hidden*propinfo.VertPot)+(MAXPOT/2))>>16;
delta = currenttop - new;
if( !delta )
return;
else if( delta < 0 )
{
dir = 1;
delta = -delta;
}
nopropupdate = 1;
if( dir )
scrollerdownlines( delta );
else
scrolleruplines( delta );
nopropupdate = 0;
}
/* called on GADGETDOWN */
int scrollerdogad(struct IntuiMessage *im)
{
struct Gadget *g=im->IAddress;
long doup,class,tickcount=4;
if( g->GadgetID >= 256 )
{
if( im->Class == GADGETUP )
return( (int) g->UserData );
else
return( 0 );
}
doup = g->GadgetID - 2;
if( doup < 0 )
{
scrollerdomove( im );
return( 0 );
}
if( doup )
scrollerup();
else
scrollerdown();
for(;;)
{
while(!(im=(struct IntuiMessage*)GetMsg(w->UserPort)))
mWaitPort(w->UserPort);
class=im->Class;
ReplyMsg(im);
if( class != INTUITICKS )
break;
if( ! ( --tickcount ) )
{
tickcount = 1;
if( doup )
scrollerup();
else
scrollerdown();
}
}
return( 0 );
}
extern long mmcount;
static int disableinc;
void xscroller( void )
{
disableinc = mmcount;
}
void incscroller( void )
{
if( disableinc )
{
disableinc = FALSE;
return;
}
if( !( prefs.flags2 & MDF2_AUTOLF ) )
return;
setscrollercurrent( currentsel + 1 );
lastdir = LDD;
showcurrentitem();
}
extern void savesel( void );
static void mb_findscrollerentrybyrawkey( char key, int dir )
{
struct mbrett *mb = ( struct mbrett * ) GetEntry( currentlist, currentsel );
struct mbrett *oldmb = mb;
if( key >= '1' && key <= '4'á)
{
setscrollercurrent( key - '1' );
showcurrentitem();
return;
}
mb = ( struct mbrett * ) ( dir ? mb->n.ln_Pred : mb->n.ln_Succ );
if( !dir && !mb->n.ln_Succ )
mb = ( struct mbrett * ) currentlist->lh_Head;
else if( dir && !mb->n.ln_Pred )
mb = ( struct mbrett * ) currentlist->lh_TailPred;
while( mb != oldmb )
{
/* NΣchster gefunden! */
if( mb->b.name[ 0 ]á== key ||
( ( mb->b.name[á0 ]á== '/' ) && mb->b.name[á1 ]á== key ) )
{
setscrollercurrent( GetEntryNum( currentlist, mb ) );
showcurrentitem();
return;
}
mb = ( struct mbrett * ) ( dir ? mb->n.ln_Pred : mb->n.ln_Succ );
if( !dir && !mb->n.ln_Succ )
mb = ( struct mbrett * ) currentlist->lh_Head;
else if( dir && !mb->n.ln_Pred )
mb = ( struct mbrett * ) currentlist->lh_TailPred;
}
}
static void maps_findscrollerentrybyrawkey( char key, int dir )
{
struct mvnode *mb = ( struct mvnode * ) GetEntry( currentlist, currentsel );
struct mvnode *oldmb = mb;
mb = ( struct mvnode * ) ( dir ? mb->n.mln_Pred : mb->n.mln_Succ );
if( !dir && !mb->n.mln_Succ )
mb = ( struct mvnode * ) currentlist->lh_Head;
else if( dir && !mb->n.mln_Pred )
mb = ( struct mvnode * ) currentlist->lh_TailPred;
while( mb != oldmb )
{
/* NΣchster gefunden! */
if( mb->txt[ prefs.maps_list_boffs ]á== key ||
( ( mb->txt[áprefs.maps_list_boffs ]á== '/' ) && mb->txt[áprefs.maps_list_boffs + 1 ]á== key ) )
{
setscrollercurrent( GetEntryNum( currentlist, mb ) );
showcurrentitem();
return;
}
mb = ( struct mvnode * ) ( dir ? mb->n.mln_Pred : mb->n.mln_Succ );
if( !dir && !mb->n.mln_Succ )
mb = ( struct mvnode * ) currentlist->lh_Head;
else if( dir && !mb->n.mln_Pred )
mb = ( struct mvnode * ) currentlist->lh_TailPred;
}
}
static void findscrollerentrybyrawkey( char key, int dir )
{
switch( scrollermode )
{
case 0:
mb_findscrollerentrybyrawkey( key, dir );
break;
case 3:
maps_findscrollerentrybyrawkey( key, dir );
break;
}
}
int scrollerdokey(struct IntuiMessage *im)
{
struct mbrett *n;
int scrolljump = ( ( prefs.flags2 & MDF2_SCROLLJUMP ) && ( scrollermode != 2 ) ) ? 5 : 1;
//
// <alt>-Buchstabe springt zum entsprechenden Eintrag
//
if( im->Qualifier & ( IEQUALIFIER_LALT | IEQUALIFIER_RALT ) )
{
char *vankey;
struct IntuiMessage im2 = *im;
int isshift = im->Qualifier & QSHIFT;
/* Funktionstasten */
if( im2.Code >= 0x50 && im2.Code <= 0x59 )
{
ULONG *cp = &posarray[á( scrollermode * 10 ) + im2.Code - 0x50 ];
if( im->Qualifier & IEQUALIFIER_LALT )
{
setscrollerstate( *cp );
}
else
{
*cp = getscrollerstate();
}
return( 0 );
}
im2.Qualifier = 0;
vankey = rawkeyconvert( &im2 );
if( *vankey && !isspace( *vankey ) )
findscrollerentrybyrawkey( toupper( *vankey ), isshift );
return( 0 ); // Event gefressen...
}
switch(im->Code)
{
case 0: /* deselect */
if(scrollermode==2) break;
if(scrollermode==1) {
struct vmail *m=(struct vmail*)currentlist->lh_Head;
savesel();
while(m->n.mln_Succ)
{
m->sel=0;
m=(struct vmail*)m->n.mln_Succ;
}
}
else
{
n=(struct mbrett*)currentlist->lh_Head;
while(n->n.ln_Succ)
{
n->n.ln_Type=0;
n=(struct mbrett*)n->n.ln_Succ;
}
}
displayscroller();
break;
case 0x5d: // History
scrollerhis();
return( 0 );
case 0x41: /* Backspace */ im->Qualifier|=QSHIFT;
case 0x3d:
case 0x3e:
case 0x3f:
case 0x4c: /* up */
if(im->Qualifier&QSHIFT || im->Code==0x3f) setscrollercurrent2(currentsel-screenlines+scrolljump);
else if(im->Qualifier&QCTRL || im->Code==0x3d) setscrollercurrent2(0);
else setscrollercurrent2(currentsel-1);
lastdir = LDU;
showcurrentitem();
displaycurrentline();
return(0);
case 0x1d:
case 0x1e:
case 0x1f:
case 0x4d: /* down */
if((im->Qualifier&QSHIFT) || im->Code==0x1f) setscrollercurrent2(currentsel+screenlines-scrolljump);
else if( ( im->Qualifier&QCTRL ) || im->Code==0x1d) setscrollercurrent2(numentries-1);
else setscrollercurrent2( currentsel + 1 );
lastdir = LDD;
showcurrentitem();
displaycurrentline();
return(0);
case 0x40: /* space */
if(scrollermode==2) break;
n=(struct mbrett*)GetEntry(currentlist,currentsel);
if(n && n->n.ln_Succ) {
if(scrollermode&&scrollermode!=3) ((struct vmail*)n)->sel^=0xff;
else n->n.ln_Type^=~0;
displaycurrentline();
incscroller();
}
return(1);
}
return(-1);
}
void calcnumentries( void )
{
numentries = GetNumEntries( currentlist );
}
void resetscroller( void )
{
numentries = GetNumEntries( currentlist );
if( currenttop + screenlines >= numentries )
currenttop = max( 0, numentries - screenlines );
recalcwindowsize();
makescrollergads();
findtopnode();
updateprop();
displayscroller();
}
static void scrolleruplines( int l )
{
int remain;
l = min( currenttop, l );
if( l < 1 )
return;
remain = screenlines - l;
if( scrollermode == 2 )
{
storecurrentsel();
currentsel -= l;
}
if( remain < 9 )
{
setscrollertop( currenttop - l );
return;
}
ClipBlit( rp, 0, topoffs,
rp, 0, topoffs + ( fontysize * ( screenlines - remain ) ),
screenxsize - 16,
( remain ) * fontysize,
0xc0
);
currenttop -= l;
findtopnode_before( l );
/* Redraw missing entries */
while( l-- )
displayscrollerline( l );
updateprop();
}
static void scrollerdownlines( int l )
{
int remain;
int c;
c = max( numentries - screenlines, 0 );
if( currenttop + l > c )
l = c - currenttop;
if( l < 1 )
return;
remain = screenlines - l;
if( scrollermode == 2 )
{
storecurrentsel();
currentsel += l;
}
if( remain < 5 )
{
setscrollertop( currenttop + l );
return;
}
currenttop += l;
findtopnode_next( l );
ClipBlit( rp, 0, topoffs + ( fontysize * ( screenlines - remain ) ),
rp, 0, topoffs,
screenxsize - 16,
( remain ) * fontysize,
0xc0 );
/* Redraw missing entries */
while( l-- )
displayscrollerline( screenlines - l - 1 );
updateprop();
}
/*int getscrollertop( void )
{
return( currenttop );
}
*/
int getscrollerselect( void )
{
struct Node *obj = GetEntry( currentlist, currentsel );
if( !obj )
return( FALSE );
if( !scrollermode )
return( obj->ln_Type );
else
return( ( ( struct vmail * ) obj) -> sel );
}
void scrollerselect( int mode, int which )
{
struct Node *obj;
UBYTE flg = which ? 0xff : 0;
if( !mode )
obj = GetEntry( currentlist, currentsel );
else
obj = currentlist->lh_Head;
while( obj->ln_Succ )
{
if( scrollermode )
((struct vmail*)obj)->sel = flg;
else
obj->ln_Type = flg;
if( mode )
obj = obj->ln_Succ;
else
break;
}
if( mode )
displayscroller();
else
displaycurrentline();
}