/*----------------------------------------------------------------------- Wega 1.00 - Demonstrationsprogramm (c) 1991 by D. Rabich ================================== Handling - Slider -----------------------------------------------------------------------*/ #include /* Wegabibliothek */ #include #include "handling.h" #include "ifkt.h" /* Funktionsmakros */ #define max(x, y) (((x) < (y)) ? (y) : (x)) #define min(x, y) (((x) > (y)) ? (y) : (x)) #define sign(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0)) #define TOPROMILLE(x) (POSITIONDIFF ? ((WORD)((((LONG)((x) - \ MINPOSITION)) * \ 1000L) / (LONG)POSITIONDIFF)) : 0) #define KORREKTUR (POSITIONDIFF ? (500L / (LONG)POSITIONDIFF) : 0) #define TOPOSITION(x) (MINPOSITION + (WORD)((LONG)(x + KORREKTUR) * \ (LONG)POSITIONDIFF / \ 1000L)) /* Makros */ #define CURRENT lsli->current #define MAXVALUE max(lsli->max, 0) #define MINVALUE lsli->min #define VISIBLE lsli->visible #define INCPAGE lsli->incpage #define TYPE lsli->type #define DRAW lsli->draw #define INFORMATION lsli->info #define TREE lsli->tree #define OBJBACKGROUND lsli->background #define OBJSLPARENT lsli->parent #define OBJSLIDER lsli->slider #define OBJLEFTUP lsli->leftup #define OBJRIGHTDOWN lsli->rightdown #define NUMBER extinfo.anzahl #define POSITIONDIFF extinfo.posidiff #define MAXPOSITION extinfo.maxpos #define MINPOSITION extinfo.minpos /* Variablen */ static SLIDERINFO *lsli; static struct { WORD anzahl; WORD posidiff; WORD minpos; WORD maxpos; } extinfo; /* Prototypen */ static VOID setamount(WORD); static VOID slideinfo(WORD, VOID*); static VOID waitnomkey(VOID); static WORD sfkt(WORD, IFKT*); static VOID posslider(WORD, WORD); /* korrigiert Sliderposition bzgl. aktueller Position */ static VOID setamount(WORD mode) { GRECT old, new; if(mode == 1) { old = *(GRECT*)(&TREE[OBJSLIDER].ob_x); objc_offset(TREE, OBJSLIDER, &old.g_x, &old.g_y); } { UWORD *state, *flags; state = &(TREE[OBJLEFTUP].ob_state); flags = &(TREE[OBJLEFTUP].ob_flags); /* Pfeilbuttons DISABLED? */ if((CURRENT == MINPOSITION) && !(*state & DISABLED)) { *state |= DISABLED; *flags &= ~TOUCHEXIT; if(mode != 2) GObjcDraw(TREE, OBJLEFTUP); } if((CURRENT != MINPOSITION) && (*state & DISABLED)) { *state &= ~DISABLED; *flags |= TOUCHEXIT; if(mode != 2) GObjcDraw(TREE, OBJLEFTUP); } state = &(TREE[OBJRIGHTDOWN].ob_state); flags = &(TREE[OBJRIGHTDOWN].ob_flags); if ((CURRENT == MAXPOSITION) && !(*state & DISABLED)) { *state |= DISABLED; *flags &= ~TOUCHEXIT; if(mode != 2) GObjcDraw(TREE, OBJRIGHTDOWN); } if ((CURRENT != MAXPOSITION) && (*state & DISABLED)) { *state &= ~DISABLED; *flags |= TOUCHEXIT; if(mode != 2) GObjcDraw(TREE, OBJRIGHTDOWN); } } /* Slider korrigieren? */ if(mode) { if(TYPE) { WORD minsize, dummy, *sh, *ph; GQChar(&dummy, &dummy, &dummy, &minsize); sh = &(TREE[OBJSLIDER].ob_height); ph = &(TREE[OBJSLPARENT].ob_height); *sh = (WORD)(((LONG)VISIBLE * (LONG)*ph) / (LONG)NUMBER); *sh = max(*sh, minsize); *sh = min(*sh, TREE[OBJSLPARENT].ob_height); TREE[OBJSLIDER].ob_y = POSITIONDIFF ? ((WORD)(((LONG)(CURRENT - MINVALUE) * (LONG)(*ph - *sh) / (LONG)POSITIONDIFF))) : 0; } else { WORD minsize, dummy, *sw, *pw; GQChar(&dummy, &dummy, &minsize, &dummy); sw = &(TREE[OBJSLIDER].ob_width); pw = &(TREE[OBJSLPARENT].ob_width); *sw = (WORD)(((LONG)VISIBLE * (LONG)*pw) / (LONG)NUMBER); *sw = max(*sw, minsize); *sw = min(*sw, TREE[OBJSLPARENT].ob_width); TREE[OBJSLIDER].ob_x = POSITIONDIFF ? ((WORD)(((LONG)(CURRENT - MINVALUE) * (LONG)(*pw - *sw) / (LONG)POSITIONDIFF))) : 0; } } /* korrigierten Slider ausgeben */ if(mode == 1) { GRECT inter; new = *(GRECT*)(&TREE[OBJSLIDER].ob_x); objc_offset(TREE, OBJSLIDER, &new.g_x, &new.g_y); GRectSurround(&inter, &new, &old); objc_draw(TREE, OBJSLPARENT, MAX_DEPTH, inter.g_x, inter.g_y, inter.g_w, inter.g_h); } } /* Sliderinfo */ #pragma warn -par static VOID slideinfo(WORD amount, VOID *data) { WORD zw; zw = TOPOSITION(amount); if(zw != CURRENT) { CURRENT = zw; setamount(0); DRAW(lsli); } } #pragma warn .par /* warten, daž Maustaste losgelassen wird */ static VOID waitnomkey(VOID) { WORD dummy, mkey; do { graf_mkstate(&dummy, &dummy, &mkey, &dummy); } while(mkey); } /* Funktionsauswertung */ static WORD sfkt(WORD x, IFKT *f) { do { if((x >= f->x) && ((x < (f + 1)->x) || ((f + 1)->x == -1))) return(f->fkt); f++; } while(f->fkt != -1); return(0); } /* Slider in vorgegebene Richtung weitersetzen */ static VOID posslider(WORD inc, WORD mode) { WORD zw, dummy, mkey, cnt = 0; do { zw = CURRENT + inc; switch(mode) { case SL_LINEAR : zw += sign(inc) * ((cnt++) / 8); break; case SL_EXPONENTIELL : zw += sign(inc) * sfkt(++cnt, iexp); break; case SL_LOGARITHMISCH : zw += sign(inc) * sfkt(++cnt, ilog); break; } CURRENT = (inc < 0) ? max(zw, MINPOSITION) : min(zw, MAXPOSITION); setamount(1); DRAW(lsli); graf_mkstate(&dummy, &dummy, &mkey, &dummy); } while(mkey && (CURRENT != ((inc < 0) ? MINPOSITION : MAXPOSITION))); } /* Slider bearbeiten */ VOID hdle_slider(SLIDERINFO *sli, WORD mode) { /* Hilfswerte berechnen, Vorbelegungen */ sli->info = slideinfo; lsli = sli; NUMBER = MAXVALUE - MINVALUE + 1; MINPOSITION = MINVALUE; MAXPOSITION = MINVALUE + max(NUMBER - (WORD)VISIBLE, 0); POSITIONDIFF = MAXPOSITION - MINPOSITION; /* Was soll gemacht werden? */ switch(mode) { /* Anpassungen */ case INITIAL: setamount(2); break; /* Slider bewegen? */ case VARIOUS: GSlideBox(TREE, OBJSLPARENT, OBJSLIDER, TYPE, INFORMATION, NULL); setamount(1); break; /* ein Schritt aufw„rts */ case SINGLEUPLEFT: posslider(-1, GQSlide()); break; /* ein Schritt abw„rts */ case SINGLEDOWNRIGHT: posslider(1, GQSlide()); break; /* eine Seite aufw„rts */ case PAGEUPLEFT: posslider(-INCPAGE, SL_KONSTANT); waitnomkey(); break; /* eine Seite abw„rts */ case PAGEDOWNRIGHT: posslider(INCPAGE, SL_KONSTANT); waitnomkey(); break; /* Minimalposition */ case MINIMUM: CURRENT = MINPOSITION; setamount(1); DRAW(lsli); break; /* Maximalposition */ case MAXIMUM: CURRENT = MAXPOSITION; setamount(1); DRAW(lsli); break; } }