Annotation of othersrc/dist/cdk/slider.c, revision 1.1.1.1

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

CVSweb <webmaster@jp.NetBSD.org>