Annotation of othersrc/dist/cdk/scale.c, revision 1.1

1.1     ! garbled     1: #include <cdk.h>
        !             2: 
        !             3: /*
        !             4:  * $Author: tom $
        !             5:  * $Date: 2000/02/18 23:20:55 $
        !             6:  * $Revision: 1.82 $
        !             7:  */
        !             8: 
        !             9: /*
        !            10:  * Declare file local prototypes.
        !            11:  */
        !            12: static void drawCDKScaleField (CDKSCALE *scale);
        !            13: 
        !            14: DeclareCDKObjects(my_funcs,Scale);
        !            15: 
        !            16: /*
        !            17:  * This function creates a scale widget.
        !            18:  */
        !            19: CDKSCALE *newCDKScale (CDKSCREEN *cdkscreen, int xplace, int yplace, char *title, char *label, chtype fieldAttr, int fieldWidth, int start, int low, int high, int inc, int fastinc, boolean Box, boolean shadow)
        !            20: {
        !            21:    /* Declare local variables. */
        !            22:    CDKSCALE *scale     = newCDKObject(CDKSCALE, &my_funcs);
        !            23:    chtype *holder      = 0;
        !            24:    int parentWidth     = getmaxx(cdkscreen->window);
        !            25:    int parentHeight    = getmaxy(cdkscreen->window);
        !            26:    int boxHeight       = 3;
        !            27:    int boxWidth                = fieldWidth + 2;
        !            28:    int maxWidth                = INT_MIN;
        !            29:    int horizontalAdjust = 0;
        !            30:    int xpos            = xplace;
        !            31:    int ypos            = yplace;
        !            32:    char **temp         = 0;
        !            33:    int x, len, junk, junk2;
        !            34: 
        !            35:    /* Set some basic values of the scale field. */
        !            36:    scale->label                = 0;
        !            37:    scale->labelLen     = 0;
        !            38:    scale->labelWin     = 0;
        !            39:    scale->titleLines   = 0;
        !            40: 
        !            41:   /*
        !            42:    * If the fieldWidth is a negative value, the fieldWidth will
        !            43:    * be COLS-fieldWidth, otherwise, the fieldWidth will be the
        !            44:    * given width.
        !            45:    */
        !            46:    fieldWidth = setWidgetDimension (parentWidth, fieldWidth, 0);
        !            47:    boxWidth = fieldWidth + 2;
        !            48: 
        !            49:    /* Translate the label char *pointer to a chtype pointer. */
        !            50:    if (label != 0)
        !            51:    {
        !            52:       scale->label     = char2Chtype (label, &scale->labelLen, &junk);
        !            53:       boxWidth         = scale->labelLen + fieldWidth + 2;
        !            54:    }
        !            55: 
        !            56:    /* Translate the char * items to chtype * */
        !            57:    if (title != 0)
        !            58:    {
        !            59:       temp = CDKsplitString (title, '\n');
        !            60:       scale->titleLines = CDKcountStrings (temp);
        !            61: 
        !            62:       /* We need to determine the widest title line. */
        !            63:       for (x=0; x < scale->titleLines; x++)
        !            64:       {
        !            65:         holder = char2Chtype (temp[x], &len, &junk2);
        !            66:         maxWidth = MAXIMUM (maxWidth, len);
        !            67:         freeChtype (holder);
        !            68:       }
        !            69: 
        !            70:       /*
        !            71:        * If one of the title lines is wider than the field and the label,
        !            72:        * the box width will expand to accomodate.
        !            73:        */
        !            74:        if (maxWidth > boxWidth)
        !            75:        {
        !            76:          horizontalAdjust = (int)((maxWidth - boxWidth) / 2) + 1;
        !            77:          boxWidth = maxWidth + 2;
        !            78:        }
        !            79: 
        !            80:       /* For each line in the title, convert from char * to chtype * */
        !            81:       for (x=0; x < scale->titleLines; x++)
        !            82:       {
        !            83:         scale->title[x]        = char2Chtype (temp[x], &scale->titleLen[x], &scale->titlePos[x]);
        !            84:         scale->titlePos[x]     = justifyString (boxWidth - 2, scale->titleLen[x], scale->titlePos[x]);
        !            85:       }
        !            86: 
        !            87:       CDKfreeStrings(temp);
        !            88:    }
        !            89:    else
        !            90:    {
        !            91:       /* No title? Set the required variables. */
        !            92:       scale->titleLines = 0;
        !            93:    }
        !            94:    boxHeight += scale->titleLines;
        !            95: 
        !            96:   /*
        !            97:    * Make sure we didn't extend beyond the dimensions of the window.
        !            98:    */
        !            99:    boxWidth = MINIMUM (boxWidth, parentWidth);
        !           100:    boxHeight = MINIMUM (boxHeight, parentHeight);
        !           101:    fieldWidth = (fieldWidth > (boxWidth - scale->labelLen - 2) ? (boxWidth - scale->labelLen - 2) : fieldWidth);
        !           102: 
        !           103:    /* Rejustify the x and y positions if we need to. */
        !           104:    alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
        !           105: 
        !           106:    /* Make the scale window. */
        !           107:    scale->win = newwin (boxHeight + !!shadow, boxWidth + !!shadow, ypos, xpos);
        !           108: 
        !           109:    /* Is the main window null??? */
        !           110:    if (scale->win == 0)
        !           111:    {
        !           112:       freeChtype (scale->label);
        !           113:       free (scale);
        !           114: 
        !           115:       /* Return a null pointer. */
        !           116:       return (0);
        !           117:    }
        !           118:    keypad (scale->win, TRUE);
        !           119:    leaveok (scale->win, TRUE);
        !           120: 
        !           121:    if (scale->titleLines > 0)
        !           122:    {
        !           123:       /* Make the title window. */
        !           124:       scale->titleWin = subwin (scale->win,
        !           125:                                scale->titleLines, boxWidth - 2,
        !           126:                                ypos + 1, xpos + 1);
        !           127:    }
        !           128: 
        !           129:    /* Create the scale label window. */
        !           130:    if (scale->label != 0)
        !           131:    {
        !           132:       scale->labelWin = subwin (scale->win, 1,
        !           133:                                scale->labelLen,
        !           134:                                ypos + scale->titleLines + 1,
        !           135:                                xpos + horizontalAdjust + 1);
        !           136:    }
        !           137: 
        !           138:    /* Create the scale field window. */
        !           139:    scale->fieldWin = subwin (scale->win, 1, fieldWidth,
        !           140:                                ypos + scale->titleLines + 1,
        !           141:                                xpos + scale->labelLen + horizontalAdjust + 1);
        !           142: 
        !           143:    /* Create the scale field. */
        !           144:    ScreenOf(scale)             = cdkscreen;
        !           145:    ObjOf(scale)->box           = Box;
        !           146:    scale->parent               = cdkscreen->window;
        !           147:    scale->boxWidth             = boxWidth;
        !           148:    scale->boxHeight            = boxHeight;
        !           149:    scale->fieldWidth           = fieldWidth;
        !           150:    scale->fieldAttr            = (chtype)fieldAttr;
        !           151:    scale->current              = low;
        !           152:    scale->low                  = low;
        !           153:    scale->high                 = high;
        !           154:    scale->current              = start;
        !           155:    scale->inc                  = inc;
        !           156:    scale->fastinc              = fastinc;
        !           157:    scale->exitType             = vNEVER_ACTIVATED;
        !           158:    scale->shadow               = shadow;
        !           159:    scale->preProcessFunction   = 0;
        !           160:    scale->preProcessData       = 0;
        !           161:    scale->postProcessFunction  = 0;
        !           162:    scale->postProcessData      = 0;
        !           163:    scale->ULChar               = ACS_ULCORNER;
        !           164:    scale->URChar               = ACS_URCORNER;
        !           165:    scale->LLChar               = ACS_LLCORNER;
        !           166:    scale->LRChar               = ACS_LRCORNER;
        !           167:    scale->HChar                        = ACS_HLINE;
        !           168:    scale->VChar                        = ACS_VLINE;
        !           169:    scale->BoxAttrib            = A_NORMAL;
        !           170: 
        !           171:    /* Clean the key bindings. */
        !           172:    cleanCDKObjectBindings (vSCALE, scale);
        !           173: 
        !           174:    /* Register this baby. */
        !           175:    registerCDKObject (cdkscreen, vSCALE, scale);
        !           176: 
        !           177:    /* Return the pointer. */
        !           178:    return (scale);
        !           179: }
        !           180: 
        !           181: /*
        !           182:  * This allows the person to use the scale field.
        !           183:  */
        !           184: int activateCDKScale (CDKSCALE *scale, chtype *actions)
        !           185: {
        !           186:    /* Declare local variables. */
        !           187:    int ret;
        !           188: 
        !           189:    /* Draw the scale widget. */
        !           190:    drawCDKScale (scale, ObjOf(scale)->box);
        !           191: 
        !           192:    /* Check if actions is null. */
        !           193:    if (actions == 0)
        !           194:    {
        !           195:       chtype input = 0;
        !           196:       for (;;)
        !           197:       {
        !           198:         /* Get the input. */
        !           199:         wrefresh (scale->win);
        !           200:         input = wgetch (scale->win);
        !           201: 
        !           202:         /* Inject the character into the widget. */
        !           203:         ret = injectCDKScale (scale, input);
        !           204:         if (scale->exitType != vEARLY_EXIT)
        !           205:         {
        !           206:            return ret;
        !           207:         }
        !           208:       }
        !           209:    }
        !           210:    else
        !           211:    {
        !           212:       int length = chlen (actions);
        !           213:       int x = 0;
        !           214: 
        !           215:       /* Inject each character one at a time. */
        !           216:       for (x=0; x < length; x++)
        !           217:       {
        !           218:         ret = injectCDKScale (scale, actions[x]);
        !           219:         if (scale->exitType != vEARLY_EXIT)
        !           220:         {
        !           221:            return ret;
        !           222:         }
        !           223:       }
        !           224:    }
        !           225: 
        !           226:    /* Set the exit type and return. */
        !           227:    scale->exitType = vEARLY_EXIT;
        !           228:    return -1;
        !           229: }
        !           230: 
        !           231: /*
        !           232:  * This function injects a single character into the widget.
        !           233:  */
        !           234: int injectCDKScale (CDKSCALE *scale, chtype input)
        !           235: {
        !           236:    /* Declare some local variables. */
        !           237:    int ppReturn = 1;
        !           238: 
        !           239:    /* Set the exit type. */
        !           240:    scale->exitType = vEARLY_EXIT;
        !           241: 
        !           242:    /* Draw the field. */
        !           243:    drawCDKScaleField (scale);
        !           244: 
        !           245:    /* Check if there is a pre-process function to be called. */
        !           246:    if (scale->preProcessFunction != 0)
        !           247:    {
        !           248:       /* Call the pre-process function. */
        !           249:       ppReturn = ((PROCESSFN)(scale->preProcessFunction)) (vSCALE, scale, scale->preProcessData, input);
        !           250:    }
        !           251: 
        !           252:    /* Should we continue? */
        !           253:    if (ppReturn != 0)
        !           254:    {
        !           255:       /* Check for a key binding. */
        !           256:       if (checkCDKObjectBind(vSCALE, scale, input) != 0)
        !           257:       {
        !           258:         scale->exitType = vESCAPE_HIT;
        !           259:         return 0;
        !           260:       }
        !           261:       else
        !           262:       {
        !           263:         switch (input)
        !           264:         {
        !           265:            case KEY_LEFT : case 'd' : case '-' : case KEY_DOWN :
        !           266:                 if (scale->current > scale->low)
        !           267:                 {
        !           268:                    scale->current -= scale->inc;
        !           269:                 }
        !           270:                 else
        !           271:                 {
        !           272:                    Beep();
        !           273:                 }
        !           274:                 break;
        !           275: 
        !           276:            case KEY_RIGHT : case 'u' : case '+' : case KEY_UP :
        !           277:                 if (scale->current < scale->high)
        !           278:                 {
        !           279:                    scale->current += scale->inc;
        !           280:                 }
        !           281:                 else
        !           282:                 {
        !           283:                    Beep();
        !           284:                 }
        !           285:                 break;
        !           286: 
        !           287:            case KEY_PPAGE : case 'U' : case CONTROL('B') :
        !           288:                 if ((scale->current + scale->fastinc) <= scale->high)
        !           289:                 {
        !           290:                    scale->current += scale->fastinc;
        !           291:                 }
        !           292:                 else
        !           293:                 {
        !           294:                    Beep();
        !           295:                 }
        !           296:                 break;
        !           297: 
        !           298:               case KEY_NPAGE : case 'D' : case CONTROL('F') :
        !           299:                 if ((scale->current - scale->fastinc) >= scale->low)
        !           300:                 {
        !           301:                    scale->current -= scale->fastinc;
        !           302:                 }
        !           303:                 else
        !           304:                 {
        !           305:                    Beep();
        !           306:                 }
        !           307:                 break;
        !           308: 
        !           309:            case KEY_HOME : case 'g' : case '0' :
        !           310:                 scale->current = scale->low;
        !           311:                 break;
        !           312: 
        !           313:            case KEY_END : case 'G' : case '$' :
        !           314:                 scale->current = scale->high;
        !           315:                 break;
        !           316: 
        !           317:            case KEY_RETURN : case TAB : case KEY_ENTER :
        !           318:                 scale->exitType = vNORMAL;
        !           319:                 return (scale->current);
        !           320: 
        !           321:            case KEY_ESC :
        !           322:                 scale->exitType = vESCAPE_HIT;
        !           323:                 return (scale->current);
        !           324: 
        !           325:            case CDK_REFRESH :
        !           326:                 eraseCDKScreen (ScreenOf(scale));
        !           327:                 refreshCDKScreen (ScreenOf(scale));
        !           328:                 break;
        !           329: 
        !           330:            default :
        !           331:                 Beep();
        !           332:                 break;
        !           333:         }
        !           334:       }
        !           335: 
        !           336:       /* Should we call a post-process? */
        !           337:       if (scale->postProcessFunction != 0)
        !           338:       {
        !           339:         ((PROCESSFN)(scale->postProcessFunction)) (vSCALE, scale, scale->postProcessData, input);
        !           340:       }
        !           341:    }
        !           342: 
        !           343:    /* Draw the field window. */
        !           344:    drawCDKScaleField (scale);
        !           345: 
        !           346:    /* Set the exit type and return. */
        !           347:    scale->exitType = vEARLY_EXIT;
        !           348:    return 0;
        !           349: }
        !           350: 
        !           351: /*
        !           352:  * This moves the scale field to the given location.
        !           353:  */
        !           354: static void _moveCDKScale (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag)
        !           355: {
        !           356:    CDKSCALE *scale = (CDKSCALE *)object;
        !           357: 
        !           358:    /*
        !           359:     * If this is a relative move, then we will adjust where we want
        !           360:     * to move to.
        !           361:     */
        !           362:    if (relative)
        !           363:    {
        !           364:       xplace += getbegx(scale->win);
        !           365:       yplace += getbegy(scale->win);
        !           366:    }
        !           367: 
        !           368:    /* Adjust the window if we need to. */
        !           369:    alignxy (WindowOf(scale), &xplace, &yplace, scale->boxWidth, scale->boxHeight);
        !           370: 
        !           371:    /* Move the window to the new location. */
        !           372:    moveCursesWindow(scale->win, xplace, yplace);
        !           373: 
        !           374:    /* Redraw the window, if they asked for it. */
        !           375:    if (refresh_flag)
        !           376:    {
        !           377:       drawCDKScale (scale, ObjOf(scale)->box);
        !           378:    }
        !           379: }
        !           380: 
        !           381: /*
        !           382:  * This function draws the scale widget.
        !           383:  */
        !           384: static void _drawCDKScale (CDKOBJS *object, boolean Box)
        !           385: {
        !           386:    CDKSCALE *scale = (CDKSCALE *)object;
        !           387:    int x;
        !           388: 
        !           389:    /* Box the widget if asked. */
        !           390:    if (Box)
        !           391:    {
        !           392:       attrbox (scale->win,
        !           393:                scale->ULChar, scale->URChar,
        !           394:                scale->LLChar, scale->LRChar,
        !           395:                scale->HChar,  scale->VChar,
        !           396:                scale->BoxAttrib,
        !           397:                scale->shadow);
        !           398:    }
        !           399: 
        !           400:    if (scale->titleLines > 0)
        !           401:    {
        !           402:       /* Draw in the title if there is one. */
        !           403:       for (x=0; x < scale->titleLines; x++)
        !           404:       {
        !           405:         writeChtype (scale->titleWin,
        !           406:                        scale->titlePos[x], x,
        !           407:                        scale->title[x],
        !           408:                        HORIZONTAL, 0,
        !           409:                        scale->titleLen[x]);
        !           410:       }
        !           411:       wnoutrefresh (scale->titleWin);
        !           412:    }
        !           413: 
        !           414:    /* Draw the label. */
        !           415:    if (scale->label != 0)
        !           416:    {
        !           417:       writeChtype (scale->labelWin, 0, 0,
        !           418:                        scale->label,
        !           419:                        HORIZONTAL, 0,
        !           420:                        scale->labelLen);
        !           421:       wnoutrefresh (scale->labelWin);
        !           422:    }
        !           423: 
        !           424:    /* Draw the field window. */
        !           425:    drawCDKScaleField (scale);
        !           426: }
        !           427: 
        !           428: /*
        !           429:  * This draws the scale widget.
        !           430:  */
        !           431: static void drawCDKScaleField (CDKSCALE *scale)
        !           432: {
        !           433:    /* Declare the local variables. */
        !           434:    int len;
        !           435:    char temp[256];
        !           436: 
        !           437:    /* Erase the field. */
        !           438:    werase (scale->fieldWin);
        !           439: 
        !           440:    /* Draw the value in the field. */
        !           441:    sprintf (temp, "%d", scale->current);
        !           442:    len = (int)strlen(temp);
        !           443:    writeCharAttrib (scale->fieldWin,
        !           444:                        scale->fieldWidth-len, 0, temp,
        !           445:                        scale->fieldAttr,
        !           446:                        HORIZONTAL, 0,
        !           447:                        len);
        !           448: 
        !           449:    /* Refresh the field window. */
        !           450:    wnoutrefresh (scale->fieldWin);
        !           451:    wnoutrefresh (scale->win);
        !           452: }
        !           453: 
        !           454: /*
        !           455:  * These functions set the drawing characters of the widget.
        !           456:  */
        !           457: void setCDKScaleULChar (CDKSCALE *scale, chtype character)
        !           458: {
        !           459:    scale->ULChar = character;
        !           460: }
        !           461: void setCDKScaleURChar (CDKSCALE *scale, chtype character)
        !           462: {
        !           463:    scale->URChar = character;
        !           464: }
        !           465: void setCDKScaleLLChar (CDKSCALE *scale, chtype character)
        !           466: {
        !           467:    scale->LLChar = character;
        !           468: }
        !           469: void setCDKScaleLRChar (CDKSCALE *scale, chtype character)
        !           470: {
        !           471:    scale->LRChar = character;
        !           472: }
        !           473: void setCDKScaleVerticalChar (CDKSCALE *scale, chtype character)
        !           474: {
        !           475:    scale->VChar = character;
        !           476: }
        !           477: void setCDKScaleHorizontalChar (CDKSCALE *scale, chtype character)
        !           478: {
        !           479:    scale->HChar = character;
        !           480: }
        !           481: void setCDKScaleBoxAttribute (CDKSCALE *scale, chtype character)
        !           482: {
        !           483:    scale->BoxAttrib = character;
        !           484: }
        !           485: 
        !           486: /*
        !           487:  * This sets the background color of the widget.
        !           488:  */
        !           489: void setCDKScaleBackgroundColor (CDKSCALE *scale, char *color)
        !           490: {
        !           491:    chtype *holder = 0;
        !           492:    int junk1, junk2;
        !           493: 
        !           494:    /* Make sure the color isn't null. */
        !           495:    if (color == 0)
        !           496:    {
        !           497:       return;
        !           498:    }
        !           499: 
        !           500:    /* Convert the value of the environment variable to a chtype. */
        !           501:    holder = char2Chtype (color, &junk1, &junk2);
        !           502: 
        !           503:    /* Set the widgets background color. */
        !           504:    wbkgd (scale->win, holder[0]);
        !           505:    wbkgd (scale->fieldWin, holder[0]);
        !           506:    if (scale->label != 0)
        !           507:    {
        !           508:       wbkgd (scale->labelWin, holder[0]);
        !           509:    }
        !           510: 
        !           511:    /* Clean up. */
        !           512:    freeChtype (holder);
        !           513: }
        !           514: 
        !           515: /*
        !           516:  * This function destroys the scale widget.
        !           517:  */
        !           518: void destroyCDKScale (CDKSCALE *scale)
        !           519: {
        !           520:    int x;
        !           521: 
        !           522:    /* Erase the object. */
        !           523:    eraseCDKScale (scale);
        !           524: 
        !           525:    /* Clean up the char pointers. */
        !           526:    freeChtype (scale->label);
        !           527:    for (x=0; x < scale->titleLines; x++)
        !           528:    {
        !           529:       freeChtype (scale->title[x]);
        !           530:    }
        !           531: 
        !           532:    /* Clean up the windows. */
        !           533:    deleteCursesWindow (scale->win);
        !           534: 
        !           535:    /* Unregister this object. */
        !           536:    unregisterCDKObject (vSCALE, scale);
        !           537: 
        !           538:    /* Finish cleaning up. */
        !           539:    free (scale);
        !           540: }
        !           541: 
        !           542: /*
        !           543:  * This function erases the scale widget from the screen.
        !           544:  */
        !           545: static void _eraseCDKScale (CDKOBJS *object)
        !           546: {
        !           547:    CDKSCALE *scale = (CDKSCALE *)object;
        !           548: 
        !           549:    eraseCursesWindow (scale->win);
        !           550: }
        !           551: 
        !           552: /*
        !           553:  * These functions set specific attributes of the widget.
        !           554:  */
        !           555: void setCDKScale (CDKSCALE *scale, int low, int high, int value, boolean Box)
        !           556: {
        !           557:    setCDKScaleLowHigh (scale, low, high);
        !           558:    setCDKScaleValue (scale, value);
        !           559:    setCDKScaleBox (scale, Box);
        !           560: }
        !           561: 
        !           562: /*
        !           563:  * This sets the low and high values of the scale widget.
        !           564:  */
        !           565: void setCDKScaleLowHigh (CDKSCALE *scale, int low, int high)
        !           566: {
        !           567:    /* Make sure the values aren't out of bounds. */
        !           568:    if (low <= high)
        !           569:    {
        !           570:       scale->low       = low;
        !           571:       scale->high      = high;
        !           572:    }
        !           573:    else if (low > high)
        !           574:    {
        !           575:       scale->low       = high;
        !           576:       scale->high      = low;
        !           577:    }
        !           578: }
        !           579: int getCDKScaleLowValue (CDKSCALE *scale)
        !           580: {
        !           581:    return scale->low;
        !           582: }
        !           583: int getCDKScaleHighValue (CDKSCALE *scale)
        !           584: {
        !           585:    return scale->high;
        !           586: }
        !           587: 
        !           588: /*
        !           589:  * This sets the scale value.
        !           590:  */
        !           591: void setCDKScaleValue (CDKSCALE *scale, int value)
        !           592: {
        !           593:    if ((value >= scale->low) && (value <= scale->high))
        !           594:    {
        !           595:       scale->current = value;
        !           596:    }
        !           597: }
        !           598: int getCDKScaleValue (CDKSCALE *scale)
        !           599: {
        !           600:    return scale->current;
        !           601: }
        !           602: 
        !           603: /*
        !           604:  * This sets the scale box attribute.
        !           605:  */
        !           606: void setCDKScaleBox (CDKSCALE *scale, boolean Box)
        !           607: {
        !           608:    ObjOf(scale)->box = Box;
        !           609: }
        !           610: boolean getCDKScaleBox (CDKSCALE *scale)
        !           611: {
        !           612:    return ObjOf(scale)->box;
        !           613: }
        !           614: 
        !           615: /*
        !           616:  * This function sets the pre-process function.
        !           617:  */
        !           618: void setCDKScalePreProcess (CDKSCALE *scale, PROCESSFN callback, void *data)
        !           619: {
        !           620:    scale->preProcessFunction = callback;
        !           621:    scale->preProcessData = data;
        !           622: }
        !           623: 
        !           624: /*
        !           625:  * This function sets the post-process function.
        !           626:  */
        !           627: void setCDKScalePostProcess (CDKSCALE *scale, PROCESSFN callback, void *data)
        !           628: {
        !           629:    scale->postProcessFunction = callback;
        !           630:    scale->postProcessData = data;
        !           631: }

CVSweb <webmaster@jp.NetBSD.org>