home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 500-599 / ff562.lza / Intuisup / Gadgets / source.lzh / gadgets2.c < prev    next >
C/C++ Source or Header  |  1991-10-20  |  45KB  |  1,283 lines

  1.         /*************************************
  2.          *                                   *
  3.          *            Gadgets v2.0           *
  4.          *   by Torsten Jürgeleit in 05/91   *
  5.          *                                   *
  6.          *          Routines - Part 2        *
  7.          *                                   *
  8.          *************************************/
  9.  
  10.     /* Includes */
  11.  
  12. #include <exec/types.h>
  13. #include <exec/memory.h>
  14. #include <devices/inputevent.h>
  15. #include <intuition/intuition.h>
  16. #include <functions.h>
  17. #include <string.h>
  18. #include "/render/render.h"
  19. #include "/texts/texts.h"
  20. #include "/borders/borders.h"
  21. #include "gadgets.h"
  22. #include "imports.h"
  23.  
  24.     /* Count entries in gadget data array */
  25.  
  26.    USHORT
  27. count_gadget_data_entries(struct GadgetData  *gd)
  28. {
  29.    USHORT data_entries = 0;
  30.  
  31.    while (gd->gd_Type != INTUISUP_DATA_END &&
  32.                       gd->gd_Type <= MAX_GADGET_DATA_TYPE) {
  33.       data_entries++;
  34.       gd++;
  35.    }
  36.    return(data_entries);
  37. }
  38.     /* Get buffer size for gadgets and borders */
  39.  
  40.    ULONG
  41. get_gadget_buffer_size(struct GadgetList  *gl)
  42. {
  43.    struct RenderInfo  *ri = gl->gl_RenderInfo;
  44.    struct GadgetData  *gd = gl->gl_Data;
  45.    struct TextAttr    *text_attr;
  46.    struct Image       *image;
  47.    ULONG  flags;
  48.    USHORT i, type, gadget_size, border_size, num, height, spacing,
  49.       data_entries = gl->gl_DataEntries;
  50.    BYTE   **text;
  51.    ULONG  buffer_size = 0;
  52.  
  53.    for (i = 0; i < data_entries; i++, gd++) {
  54.       type  = gd->gd_Type;
  55.       flags = gd->gd_Flags;
  56.       /* if monochrome display then set HIGHCOMP flag */
  57.       if (ri->ri_ScreenDepth == 1) {
  58.      flags |= GADGET_DATA_FLAG_HIGH_COMP;
  59.       }
  60.       switch(type) {
  61.      case GADGET_DATA_TYPE_BUTTON :
  62.         gadget_size = sizeof(struct ExtendedGadget);
  63.         if ((flags & GADGET_DATA_FLAG_BUTTON_TOGGLE &&
  64.                    flags & GADGET_DATA_FLAG_BUTTON_IMAGE) ||
  65.                        flags & GADGET_DATA_FLAG_HIGH_COMP) {
  66.            border_size = BORDER_TYPE_BOX1_BUFFER_SIZE;
  67.         } else {
  68.            border_size = 2 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  69.         }
  70.         /* add image struct size if chip mem copies of image data needed */
  71.         if (gd->gd_Flags & GADGET_DATA_FLAG_BUTTON_IMAGE) {
  72.            if ((image = gd->gd_SpecialData.gd_ButtonData.gd_ButtonNormalRender) &&
  73.                        check_gadget_image(image) == FALSE) {
  74.           buffer_size += sizeof(struct Image);
  75.            }
  76.            if ((image = gd->gd_SpecialData.gd_ButtonData.gd_ButtonSelectRender) &&
  77.                        check_gadget_image(image) == FALSE) {
  78.           buffer_size += sizeof(struct Image);
  79.            }
  80.         }
  81.         break;
  82.      case GADGET_DATA_TYPE_CHECK :
  83.         gadget_size = sizeof(struct ExtendedGadget);
  84.         border_size = BORDER_TYPE_BOX1_BUFFER_SIZE;
  85.         break;
  86.      case GADGET_DATA_TYPE_MX :
  87.         text = gd->gd_SpecialData.gd_MXData.gd_MXTextArray;
  88.         num  = 0;
  89.         while (*text++) {
  90.            num++;
  91.         }
  92.         gadget_size = num * (sizeof(struct ExtendedGadget) +
  93.               sizeof(struct IntuiText)) + sizeof(struct MXData);
  94.         border_size = BORDER_TYPE_BOX1_BUFFER_SIZE;
  95.         break;
  96.      case GADGET_DATA_TYPE_STRING :
  97.      case GADGET_DATA_TYPE_INTEGER :
  98.         /* calc size of input buffer */
  99.         if (type == GADGET_DATA_TYPE_STRING) {
  100.            num = gd->gd_SpecialData.gd_InputData.gd_InputLen;
  101.            if (flags & (GADGET_DATA_FLAG_STRING_UNSIGNED_DEC |
  102.                     GADGET_DATA_FLAG_STRING_SIGNED_DEC |
  103.                            GADGET_DATA_FLAG_STRING_HEX |
  104.                          GADGET_DATA_FLAG_STRING_BIN)) {
  105.           if (num < MAX_BIN_NUM_DIGITS) {
  106.              num = MAX_BIN_NUM_DIGITS;
  107.           }
  108.            }
  109.         } else {
  110.            num = MAX_DEC_NUM_DIGITS;
  111.         }
  112.         if (num & 1) {   /* odd input len ? */
  113.            num += 1;
  114.         } else {
  115.            num += 2;   /* inc for end of string marker */
  116.         }
  117.         gadget_size = sizeof(struct ExtendedGadget) +
  118.                         sizeof(struct StringInfo) + num;
  119.         border_size = BORDER_TYPE_BOX2_BUFFER_SIZE;
  120.         break;
  121.      case GADGET_DATA_TYPE_SLIDER :
  122.         gadget_size = sizeof(struct ExtendedGadget) +
  123.                 sizeof(struct PropInfo) + sizeof(struct Image) +
  124.                           sizeof(struct SliderData);
  125.         border_size = BORDER_TYPE_BOX1_BUFFER_SIZE;
  126.         break;
  127.      case GADGET_DATA_TYPE_SCROLLER :
  128.         if (flags & GADGET_DATA_FLAG_SCROLLER_NO_ARROWS) {
  129.            gadget_size = sizeof(struct ExtendedGadget) +
  130.                 sizeof(struct PropInfo) + sizeof(struct Image) +
  131.                         sizeof(struct ScrollerData);
  132.            border_size = BORDER_TYPE_BOX1_BUFFER_SIZE;
  133.         } else {
  134.            gadget_size = 3 * sizeof(struct ExtendedGadget) +
  135.                 sizeof(struct PropInfo) + sizeof(struct Image) +
  136.                         sizeof(struct ScrollerData);
  137.            if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  138.           border_size = 3 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  139.            } else {
  140.           border_size = 5 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  141.            }
  142.         }
  143.         break;
  144.      case GADGET_DATA_TYPE_CYCLE :
  145.         gadget_size = sizeof(struct ExtendedGadget) +
  146.                            sizeof(struct CycleData);
  147.         if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  148.            border_size = BORDER_TYPE_BOX1_BUFFER_SIZE;
  149.         } else {
  150.            border_size = 2 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  151.         }
  152.         break;
  153.      case GADGET_DATA_TYPE_COUNT :
  154.         gadget_size = sizeof(struct ExtendedGadget) +
  155.                            sizeof(struct CountData);
  156.         border_size = 2 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  157.         break;
  158.      case GADGET_DATA_TYPE_LISTVIEW :
  159.         if (flags & GADGET_DATA_FLAG_LISTVIEW_READ_ONLY) {
  160.            num = 0;
  161.         } else {
  162.            if (!(text_attr = gd->gd_TextAttr)) {
  163.           text_attr = &gl->gl_RenderInfo->ri_TextAttr;
  164.            }
  165.            height  = gd->gd_Height;
  166.            spacing = gd->gd_SpecialData.gd_ListViewData.gd_ListViewSpacing;
  167.            if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  168.           height -= 2 * 1;
  169.            }
  170.            num = (height + spacing) / (text_attr->ta_YSize + spacing);
  171.         }
  172.         gadget_size = (3 + num) * sizeof(struct ExtendedGadget) +
  173.                 sizeof(struct PropInfo) + sizeof(struct Image) +
  174.                         sizeof(struct ListViewData);
  175.         if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  176.            border_size = 4 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  177.         } else {
  178.            border_size = 6 * BORDER_TYPE_BOX1_BUFFER_SIZE;
  179.         }
  180.         break;
  181.      case GADGET_DATA_TYPE_PALETTE :
  182.         num         = 1L << gd->gd_SpecialData.gd_PaletteData.gd_PaletteDepth;
  183.         gadget_size = num * (sizeof(struct ExtendedGadget) +
  184.              sizeof(struct Image)) + sizeof(struct PaletteData);
  185.         if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  186.            border_size = num * BORDER_TYPE_BOX1_BUFFER_SIZE;
  187.         } else {
  188.            border_size = num * (2 * BORDER_TYPE_BOX1_BUFFER_SIZE);
  189.         }
  190.         if (!(flags & GADGET_DATA_FLAG_PALETTE_NO_INDICATOR)) {
  191.            gadget_size += sizeof(struct ExtendedGadget) +
  192.                                sizeof(struct Image);
  193.            border_size += BORDER_TYPE_BOX1_BUFFER_SIZE;
  194.         }
  195.         break;
  196.       }
  197.       buffer_size += gadget_size;
  198.       if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  199.      buffer_size += border_size;
  200.       }
  201.    }
  202.    return(buffer_size);
  203. }
  204.     /* Get buffer size for image data */
  205.  
  206.    ULONG
  207. get_image_buffer_size(struct GadgetList  *gl)
  208. {
  209.    struct GadgetData  *gd = gl->gl_Data;
  210.    struct Image       *image;
  211.    ULONG  buffer_size = 0;
  212.    USHORT i, data_entries = gl->gl_DataEntries;
  213.  
  214.    for (i = 0; i < data_entries; i++, gd++) {
  215.       if (gd->gd_Type == GADGET_DATA_TYPE_BUTTON &&
  216.                (gd->gd_Flags & GADGET_DATA_FLAG_BUTTON_IMAGE)) {
  217.      if ((image = gd->gd_SpecialData.gd_ButtonData.gd_ButtonNormalRender) &&
  218.                        check_gadget_image(image) == FALSE) {
  219.         buffer_size += (image->Width / 16 + (image->Width & 15 ? 1 : 0))
  220.                      * image->Height * image->Depth * 2;
  221.      }
  222.      if ((image = gd->gd_SpecialData.gd_ButtonData.gd_ButtonSelectRender) &&
  223.                        check_gadget_image(image) == FALSE) {
  224.         buffer_size += (image->Width / 16 + (image->Width & 15 ? 1 : 0))
  225.                      * image->Height * image->Depth * 2;
  226.      }
  227.       }
  228.    }
  229.    return(buffer_size);
  230. }
  231.     /* Initialize gadgets from gadget list */
  232.  
  233.    VOID
  234. init_gadgets(struct GadgetList  *gl, SHORT hoffset, SHORT voffset)
  235. {
  236.    struct RenderInfo      *ri = gl->gl_RenderInfo;
  237.    struct GadgetData      *gd;
  238.    struct ExtendedGadget  *egad, *first_egad;
  239.    struct Image           *image;
  240.    struct IntuiText       itext;
  241.    struct TextAttr        *text_attr;
  242.    struct MXData          *mx;
  243.    struct SliderData      *sl;
  244.    struct ScrollerData    *sc;
  245.    struct CycleData       *cy;
  246.    struct CountData       *co;
  247.    struct ListViewData    *lv;
  248.    struct PaletteData     *pd;
  249.    BYTE   **text, *buffer = gl->gl_GadgetBuffer,
  250.       *image_buffer = gl->gl_ImageBuffer;
  251.    ULONG  min, max, flags;
  252.    USHORT i, j, k, type, save_left_edge, left_edge, top_edge, width, height,
  253.       max_width, num, len, xoffset, yoffset, xmin, ymin, xnum, ynum,
  254.       yinc, spacing, data_entries = gl->gl_DataEntries;
  255.  
  256.    for (i = 0, gd = gl->gl_Data; i < data_entries; i++, gd++) {
  257.       /* get gadget data */
  258.       type      = gd->gd_Type;
  259.       flags     = gd->gd_Flags;
  260.       left_edge = gd->gd_LeftEdge + hoffset;
  261.       top_edge  = gd->gd_TopEdge + voffset;
  262.       width     = gd->gd_Width;
  263.       height    = gd->gd_Height;
  264.       text_attr = (gd->gd_TextAttr ? gd->gd_TextAttr : &ri->ri_TextAttr);
  265.       /* inner window position needed ? */
  266.       if (ri->ri_Flags & RENDER_INFO_FLAG_INNER_WINDOW) {
  267.      left_edge += ri->ri_WindowBorderLeft;
  268.      top_edge  += ri->ri_WindowBorderTop;
  269.       }
  270.       /* init intui text */
  271.       itext.ITextFont = text_attr;
  272.       /* get gadget buffer ptr and reserve buffer */
  273.       egad    = first_egad = gl->gl_Gadgets[i] = (struct ExtendedGadget *)
  274.                                      buffer;
  275.       buffer += sizeof(struct ExtendedGadget);
  276.       /* calc border offsets */
  277.       if (flags & GADGET_DATA_FLAG_NO_BORDER) {
  278.      xoffset = 0;
  279.      yoffset = 0;
  280.       } else {
  281.      switch (type) {
  282.         case GADGET_DATA_TYPE_MX :
  283.            xoffset = 8;
  284.            yoffset = 4;
  285.            break;
  286.         case GADGET_DATA_TYPE_STRING :
  287.         case GADGET_DATA_TYPE_INTEGER :
  288.            xoffset = 6;
  289.            yoffset = 3;
  290.            break;
  291.         case GADGET_DATA_TYPE_CYCLE :
  292.         case GADGET_DATA_TYPE_COUNT :
  293.            xoffset = 2;
  294.            yoffset = 1;
  295.            break;
  296.         default :
  297.            xoffset = 4;
  298.            yoffset = 2;
  299.            break;
  300.      }
  301.       }
  302.       /* if fixed gadget dimensions or data buffers so init them yet */
  303.       switch (type) {
  304.      case GADGET_DATA_TYPE_CHECK :
  305.         /* calc fixed dimensions of check gadget */
  306.         width  = IMAGE_CHECK_WIDTH + 2 * IMAGE_HORIZ_OFFSET;
  307.         height = IMAGE_CHECK_HEIGHT + 2 * IMAGE_VERT_OFFSET;
  308.         break;
  309.      case GADGET_DATA_TYPE_MX :
  310.         /* init mx data */
  311.         mx      = (struct MXData *)buffer;
  312.         buffer += sizeof(struct MXData);
  313.         /* calc fixed dimensions of mx gadget */
  314.         width  = IMAGE_KNOB_WIDTH;
  315.         height = IMAGE_KNOB_HEIGHT;
  316.         /* calc vertical offset between mx gadget */
  317.         if ((yinc = text_attr->ta_YSize) < height) {
  318.            yinc = height;
  319.         }
  320.         yinc += gd->gd_SpecialData.gd_MXData.gd_MXSpacing;
  321.         /* count mx gadgets and calc maximal text width */
  322.         text      = gd->gd_SpecialData.gd_MXData.gd_MXTextArray;
  323.         num       = 0;
  324.         max_width = 0;
  325.         while (*text) {
  326.            itext.IText = (UBYTE *)*text++;
  327.            if ((len = IntuiTextLength(&itext)) > max_width) {
  328.           max_width = len;
  329.            }
  330.            num++;
  331.         }
  332.         mx->mx_TextEntries = num;
  333.         /* left and top edge of gadget */
  334.         if (flags & GADGET_DATA_FLAG_TEXT_LEFT) {
  335.            left_edge += max_width + xoffset + 8;
  336.         } else {
  337.            left_edge += xoffset;
  338.         }
  339.         if (text_attr->ta_YSize > height) {
  340.            top_edge += (text_attr->ta_YSize - height) / 2 + yoffset;
  341.         } else {
  342.            top_edge += yoffset;
  343.         }
  344.         break;
  345.      case GADGET_DATA_TYPE_STRING :
  346.      case GADGET_DATA_TYPE_INTEGER :
  347.         /* calc fixed height of input gadgets */
  348.         height = ri->ri_TextAttr.ta_YSize;
  349.         break;
  350.      case GADGET_DATA_TYPE_SLIDER :
  351.         /* init slider data */
  352.         sl      = (struct SliderData *)buffer;
  353.         buffer += sizeof(struct SliderData);
  354.         break;
  355.      case GADGET_DATA_TYPE_SCROLLER :
  356.         /* calc minimum dimensions of scroller gadget */
  357.         if (!(flags & GADGET_DATA_FLAG_SCROLLER_NO_ARROWS)) {
  358.            xmin = IMAGE_ARROW_WIDTH + IMAGE_HORIZ_OFFSET + xoffset;
  359.            ymin = IMAGE_ARROW_HEIGHT + IMAGE_VERT_OFFSET + yoffset;
  360.            if (flags & GADGET_DATA_FLAG_ORIENTATION_VERT) {
  361.           if (width < xmin) {
  362.              width = xmin;
  363.           }
  364.           if (height < 3 * ymin) {
  365.              height = 3 * ymin;
  366.           }
  367.            } else {
  368.           if (width < 3 * xmin) {
  369.              width = 3 * xmin;
  370.           }
  371.           if (height < ymin) {
  372.              height = ymin;
  373.           }
  374.            }
  375.         }
  376.         /* init scroller data */
  377.         sc      = (struct ScrollerData *)buffer;
  378.         buffer += sizeof(struct ScrollerData);
  379.         break;
  380.      case GADGET_DATA_TYPE_CYCLE :
  381.         /* init cycle data */
  382.         cy      = (struct CycleData *)buffer;
  383.         buffer += sizeof(struct CycleData);
  384.         break;
  385.      case GADGET_DATA_TYPE_COUNT :
  386.         /* init count data */
  387.         co      = (struct CountData *)buffer;
  388.         buffer += sizeof(struct CountData);
  389.         break;
  390.      case GADGET_DATA_TYPE_LISTVIEW :
  391.         /* calc minimum dimension of list view gadget */
  392.         xmin = IMAGE_ARROW_WIDTH + IMAGE_HORIZ_OFFSET + xoffset;
  393.         ymin = IMAGE_ARROW_HEIGHT + IMAGE_VERT_OFFSET + yoffset;
  394.         if (height < 3 * ymin) {
  395.            height = 3 * ymin;
  396.         }
  397.         spacing = gd->gd_SpecialData.gd_ListViewData.gd_ListViewSpacing;
  398.         yinc    = text_attr->ta_YSize + spacing;
  399.         num     = (height - 2 * yoffset + spacing) / yinc;
  400.         height  = num * yinc + 2 * yoffset;
  401.         /* init list view data */
  402.         lv      = (struct ListViewData *)buffer;
  403.         buffer += sizeof(struct ListViewData);
  404.         break;
  405.      case GADGET_DATA_TYPE_PALETTE :
  406.         /* calc dimension of color squares of palette */
  407.         min  = gd->gd_SpecialData.gd_PaletteData.gd_PaletteColorOffset;
  408.         max  = 1L << gd->gd_SpecialData.gd_PaletteData.gd_PaletteDepth;
  409.         xnum = max;   /* start with all squares in a horizontal line */
  410.         ynum = 1;
  411.         while (xnum > 1 && (width / xnum) / 2 < height / ynum) {
  412.            xnum /= 2;
  413.            ynum *= 2;
  414.         }
  415.         if (!(flags & GADGET_DATA_FLAG_PALETTE_NO_INDICATOR)) {
  416.            /* insert color indicator */
  417.            if (flags & GADGET_DATA_FLAG_PALETTE_INDICATOR_TOP) {
  418.           ynum++;
  419.            } else {
  420.           xnum++;
  421.            }
  422.         }
  423.         /* calc gadget dimension */
  424.         if (xnum == 1) {
  425.            xmin = width;
  426.         } else {
  427.            xmin  = (width - 2 * (xnum - 1)) / xnum;
  428.            width = xmin * xnum + 2 * (xnum - 1);
  429.         }
  430.         if (ynum == 1) {
  431.            ymin = height;
  432.         } else {
  433.            ymin   = (height - 1 * (ynum - 1)) / ynum;
  434.            height = ymin * ynum + 1 * (ynum - 1);
  435.         }
  436.         /* init palette data */
  437.         pd      = (struct PaletteData *)buffer;
  438.         buffer += sizeof(struct PaletteData);
  439.         break;
  440.       }
  441.       /* init gadget */
  442.       switch (type) {
  443.      case GADGET_DATA_TYPE_BUTTON :
  444.         buffer = init_extended_gadget(egad, buffer, gl, i,
  445.             EXTENDED_GADGET_TYPE_BUTTON, left_edge, top_edge, width,
  446.                                     height);
  447.         break;
  448.      case GADGET_DATA_TYPE_CHECK :
  449.         buffer = init_extended_gadget(egad, buffer, gl, i,
  450.              EXTENDED_GADGET_TYPE_CHECK, left_edge, top_edge, width,
  451.                                     height);
  452.         break;
  453.      case GADGET_DATA_TYPE_MX :
  454.         /* init all mx gadgets */
  455.         text = gd->gd_SpecialData.gd_MXData.gd_MXTextArray;
  456.         for (j = 0; j < num; j++, text++) {
  457.            buffer = init_extended_gadget(egad, buffer, gl, i,
  458.             EXTENDED_GADGET_TYPE_MX, left_edge, top_edge, width,
  459.                                     height);
  460.            buffer = init_mx_text(egad, buffer, *text, width, height,
  461.                               flags, text_attr);
  462.            egad->eg_Gadget.GadgetID = j;   /* num of mx gadget */
  463.            if (j < (num - 1)) {   /* another mx gadget ? */
  464.           top_edge += yinc;
  465.           egad      = egad->eg_NextGadget =
  466.                         (struct ExtendedGadget *)buffer;
  467.           buffer   += sizeof(struct ExtendedGadget);
  468.            }
  469.         }
  470.         /* calc area dimension and draw border around it */
  471.         width += max_width + 2 * xoffset + 8;
  472.         height = yinc * num + 2 * yoffset -
  473.                   gd->gd_SpecialData.gd_MXData.gd_MXSpacing;
  474.         if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  475.            if (flags & GADGET_DATA_FLAG_TEXT_LEFT) {
  476.           left_edge = -(max_width + xoffset + 8);
  477.            } else {
  478.           left_edge = -xoffset;   /* default right */
  479.            }
  480.            if (text_attr->ta_YSize > height) {
  481.           top_edge = -((text_attr->ta_YSize - height) / 2 + yoffset);
  482.            } else {
  483.           top_edge = -yoffset;
  484.            }
  485.            first_egad->eg_Flags  = EXTENDED_GADGET_FLAG_RENDER_BORDER;
  486.            first_egad->eg_Render = (APTR)buffer;
  487.            buffer                = init_border(ri, buffer, left_edge,
  488.              top_edge, width, height, BORDER_DATA_TYPE_BOX1_IN);
  489.         }
  490.         break;
  491.      case GADGET_DATA_TYPE_STRING :
  492.         buffer = init_extended_gadget(egad, buffer, gl, i,
  493.             EXTENDED_GADGET_TYPE_STRING, left_edge, top_edge, width,
  494.                                     height);
  495.         break;
  496.      case GADGET_DATA_TYPE_INTEGER :
  497.         buffer = init_extended_gadget(egad, buffer, gl, i,
  498.            EXTENDED_GADGET_TYPE_INTEGER, left_edge, top_edge, width,
  499.                                     height);
  500.         break;
  501.      case GADGET_DATA_TYPE_SLIDER :
  502.         /* init slider data */
  503.         sl->sl_Flags = flags;
  504.         sl->sl_Min   = gd->gd_SpecialData.gd_SliderData.gd_SliderMin;
  505.         sl->sl_Max   = gd->gd_SpecialData.gd_SliderData.gd_SliderMax;
  506.         buffer       = init_extended_gadget(egad, buffer, gl, i,
  507.               EXTENDED_GADGET_TYPE_SLIDER_PROP, left_edge, top_edge,
  508.                                  width, height);
  509.         break;
  510.      case GADGET_DATA_TYPE_SCROLLER :
  511.         /* init scroller data */
  512.         sc->sc_Flags   = flags;
  513.         sc->sc_Total   = gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerTotal;
  514.         sc->sc_Visible = gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerVisible;
  515.         /* init scroller gadgets */
  516.         if (flags & GADGET_DATA_FLAG_SCROLLER_NO_ARROWS) {
  517.            buffer = init_extended_gadget(egad, buffer, gl, i,
  518.                   EXTENDED_GADGET_TYPE_SCROLLER_PROP, left_edge,
  519.                            top_edge, width, height);
  520.         } else {
  521.            if (flags & GADGET_DATA_FLAG_ORIENTATION_VERT) {
  522.           /* create vertical scroller - prop gadget first */
  523.           buffer = init_extended_gadget(egad, buffer, gl, i,
  524.                   EXTENDED_GADGET_TYPE_SCROLLER_PROP, left_edge,
  525.                   top_edge, width, height - 2 * (ymin + 1));
  526.           /* init scroller up arrow gadget */
  527.           egad    = egad->eg_NextGadget = (struct ExtendedGadget *)
  528.                                      buffer;
  529.           buffer += sizeof(struct ExtendedGadget);
  530.           buffer  = init_extended_gadget(egad, buffer, gl, i,
  531.                 EXTENDED_GADGET_TYPE_SCROLLER_UP, left_edge,
  532.                  top_edge + height - 2 * ymin - 1, width, ymin);
  533.           /* change type of vertical scroller arrow gadget for correct counting */
  534.           egad->eg_Type = EXTENDED_GADGET_TYPE_SCROLLER_DOWN;
  535.           /* init scroller down arrow gadget */
  536.           egad    = egad->eg_NextGadget = (struct ExtendedGadget *)
  537.                                      buffer;
  538.           buffer += sizeof(struct ExtendedGadget);
  539.           buffer  = init_extended_gadget(egad, buffer, gl, i,
  540.                   EXTENDED_GADGET_TYPE_SCROLLER_DOWN, left_edge,
  541.                      top_edge + height - ymin, width, ymin);
  542.           /* change type of vertical scroller arrow gadget for correct counting */
  543.           egad->eg_Type = EXTENDED_GADGET_TYPE_SCROLLER_UP;
  544.            } else {
  545.           /* create horizontal scroller - prop gadget first */
  546.           buffer = init_extended_gadget(egad, buffer, gl, i,
  547.                   EXTENDED_GADGET_TYPE_SCROLLER_PROP, left_edge,
  548.                   top_edge, width - 2 * (xmin + 1), height);
  549.           /* init scroller left arrow gadget */
  550.           egad    = egad->eg_NextGadget = (struct ExtendedGadget *)
  551.                                      buffer;
  552.           buffer += sizeof(struct ExtendedGadget);
  553.           buffer  = init_extended_gadget(egad, buffer, gl, i,
  554.                  EXTENDED_GADGET_TYPE_SCROLLER_LEFT, left_edge +
  555.                   width - 2 * xmin - 1, top_edge, xmin, height);
  556.           /* init scroller right arrow gadget */
  557.           egad    = egad->eg_NextGadget = (struct ExtendedGadget *)
  558.                                      buffer;
  559.           buffer += sizeof(struct ExtendedGadget);
  560.           buffer  = init_extended_gadget(egad, buffer, gl, i,
  561.                 EXTENDED_GADGET_TYPE_SCROLLER_RIGHT, left_edge +
  562.                       width - xmin, top_edge, xmin, height);
  563.            }
  564.         }
  565.         break;
  566.      case GADGET_DATA_TYPE_CYCLE :
  567.         /* count entries and calc max width of cycle text array */
  568.                text = gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray;
  569.         num  = max_width = 0;
  570.         while (*text) {
  571.            itext.IText = (UBYTE *)*text++;
  572.            if ((len = IntuiTextLength(&itext)) > max_width) {
  573.           max_width = len;
  574.            }
  575.            num++;
  576.         }
  577.         /* init cycle data */
  578.         image              = &ri->ri_Images[IMAGE_CYCLE];
  579.         xmin               = image->LeftEdge + image->Width + xoffset + 4;
  580.         cy->cy_LeftEdge    = left_edge + xmin + (SHORT)(width -
  581.                           max_width - xmin - 4) / 2;
  582.         cy->cy_TopEdge     = top_edge + (SHORT)(height -
  583.                            text_attr->ta_YSize) / 2;
  584.         cy->cy_Width       = max_width;
  585.         cy->cy_Height      = text_attr->ta_YSize;
  586.         cy->cy_Flags       = flags;
  587.         cy->cy_TextAttr    = text_attr;
  588.         cy->cy_TextArray   = gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray;
  589.         cy->cy_TextEntries = num;
  590.         buffer             = init_extended_gadget(egad, buffer, gl, i,
  591.              EXTENDED_GADGET_TYPE_CYCLE, left_edge, top_edge, width,
  592.                                     height);
  593.         break;
  594.      case GADGET_DATA_TYPE_COUNT :
  595.         /* calc max width of count value */
  596.         min = gd->gd_SpecialData.gd_CountData.gd_CountMin;
  597.         max = gd->gd_SpecialData.gd_CountData.gd_CountMax;
  598.         if (flags & GADGET_DATA_FLAG_COUNT_SIGNED_DEC) {
  599.            len       = convert_signed_dec((LONG)min, (BYTE *)NULL);
  600.            max_width = convert_signed_dec((LONG)max, (BYTE *)NULL);
  601.         } else {
  602.            len       = convert_unsigned_dec(min, (BYTE *)NULL);
  603.            max_width = convert_unsigned_dec(max, (BYTE *)NULL);
  604.         }
  605.         if (len > max_width) {
  606.            max_width = len;
  607.         }
  608.         itext.IText = (UBYTE *)"8";
  609.         max_width  *= IntuiTextLength(&itext);
  610.         /* init count data */
  611.         co->co_LeftEdge = left_edge + (SHORT)(width - max_width) / 2;
  612.         co->co_TopEdge  = top_edge + (SHORT)(height -
  613.                             text_attr->ta_YSize) / 2;
  614.         co->co_Width    = max_width;
  615.         co->co_Height   = text_attr->ta_YSize;
  616.         co->co_Flags    = flags;
  617.         co->co_TextAttr = text_attr;
  618.         co->co_Min      = min;
  619.         co->co_Max      = max;
  620.         buffer          = init_extended_gadget(egad, buffer, gl, i,
  621.              EXTENDED_GADGET_TYPE_COUNT, left_edge, top_edge, width,
  622.                                     height);
  623.         break;
  624.      case GADGET_DATA_TYPE_LISTVIEW :
  625.         /* init list view data */
  626.         lv->lv_LeftEdge       = left_edge + xoffset;
  627.         lv->lv_TopEdge        = top_edge + yoffset;
  628.         lv->lv_Width          = width - 2 * xoffset - xmin - 2;
  629.         lv->lv_Height         = height - 2 * yoffset;
  630.         lv->lv_Flags          = flags;
  631.         lv->lv_TextAttr       = text_attr;
  632.         lv->lv_VisibleEntries = num;
  633.         lv->lv_EntryHeight    = yinc;
  634.         /* create vertical scroller - prop gadget first */
  635.         left_edge += width - xmin;
  636.         buffer     = init_extended_gadget(egad, buffer, gl, i,
  637.             EXTENDED_GADGET_TYPE_LISTVIEW_PROP, left_edge, top_edge,
  638.                          xmin, height - 2 * (ymin + 1));
  639.         /* create entry field border */
  640.         if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  641.            ((struct Border *)egad->eg_Render)->NextBorder->NextBorder =
  642.                             (struct Border *)buffer;
  643.            if (flags & GADGET_DATA_FLAG_LISTVIEW_READ_ONLY) {
  644.           j = BORDER_DATA_TYPE_BOX1_IN;
  645.            } else {
  646.           j = BORDER_DATA_TYPE_BOX1_OUT;
  647.            }
  648.            buffer = init_border(ri, buffer, -(width + xoffset - xmin),
  649.                      -yoffset, width - xmin - 2, height, j);
  650.         }
  651.         /* init list view up arrow gadget */
  652.         egad    = egad->eg_NextGadget = (struct ExtendedGadget *)buffer;
  653.         buffer += sizeof(struct ExtendedGadget);
  654.         buffer  = init_extended_gadget(egad, buffer, gl, i,
  655.              EXTENDED_GADGET_TYPE_LISTVIEW_UP, left_edge, top_edge +
  656.                      height - 2 * ymin - 1, xmin, ymin);
  657.         /* init list view down arrow gadget */
  658.         egad    = egad->eg_NextGadget = (struct ExtendedGadget *)buffer;
  659.         buffer += sizeof(struct ExtendedGadget);
  660.         buffer  = init_extended_gadget(egad, buffer, gl, i,
  661.            EXTENDED_GADGET_TYPE_LISTVIEW_DOWN, left_edge, top_edge +
  662.                          height - ymin, xmin, ymin);
  663.         /* init list view entry gadgets */
  664.         if (!(flags & GADGET_DATA_FLAG_LISTVIEW_READ_ONLY)) {
  665.            left_edge = lv->lv_LeftEdge;
  666.            top_edge  = lv->lv_TopEdge;
  667.            for (j = 0; j < num; j++, top_edge += yinc) {
  668.           egad            = egad->eg_NextGadget =
  669.                         (struct ExtendedGadget *)buffer;
  670.           buffer         += sizeof(struct ExtendedGadget);
  671.           buffer          = init_extended_gadget(egad, buffer, gl,
  672.               i, EXTENDED_GADGET_TYPE_LISTVIEW_ENTRY, left_edge,
  673.                           top_edge, lv->lv_Width, yinc);
  674.           egad->eg_Gadget.GadgetID = j;   /* num of entry gadget */
  675.            }
  676.         }
  677.         break;
  678.      case GADGET_DATA_TYPE_PALETTE :
  679.         /* init palette data */
  680.         pd->pd_Flags       = flags;
  681.         pd->pd_ColorOffset = min;
  682.         pd->pd_MaxColors   = max;
  683.         /* build color indicator */
  684.         if (!(flags & GADGET_DATA_FLAG_PALETTE_NO_INDICATOR)) {
  685.            if (flags & GADGET_DATA_FLAG_PALETTE_INDICATOR_TOP) {
  686.           buffer    = init_extended_gadget(egad, buffer, gl, i,
  687.               EXTENDED_GADGET_TYPE_PALETTE_INDICATOR, left_edge,
  688.                              top_edge, width, ymin);
  689.           top_edge += ymin + 1;
  690.           ynum--;
  691.            } else {
  692.           buffer     = init_extended_gadget(egad, buffer, gl, i,
  693.               EXTENDED_GADGET_TYPE_PALETTE_INDICATOR, left_edge,
  694.                             top_edge, xmin, height);
  695.           left_edge += xmin + 2;
  696.           xnum--;
  697.            }
  698.            egad    = egad->eg_NextGadget = (struct ExtendedGadget *)
  699.                                      buffer;
  700.            buffer += sizeof(struct ExtendedGadget);
  701.         }
  702.         /* build color gadgets */
  703.         save_left_edge = left_edge;
  704.         num            = gd->gd_SpecialData.gd_PaletteData.gd_PaletteColorOffset;
  705.         for (j = 0; j < ynum; j++, top_edge += ymin + 1) {
  706.            for (k = 0, left_edge = save_left_edge; k < xnum; k++,
  707.                             left_edge += xmin + 2) {
  708.           buffer = init_extended_gadget(egad, buffer, gl, i,
  709.                   EXTENDED_GADGET_TYPE_PALETTE_COLOR, left_edge,
  710.                               top_edge, xmin, ymin);
  711.           ((struct Image *)egad->eg_Render)->PlaneOnOff = egad->eg_Gadget.GadgetID = num++;
  712.           if (j < (ynum - 1) || k < (xnum - 1)) {
  713.              egad    = egad->eg_NextGadget = (struct ExtendedGadget *)
  714.                                      buffer;
  715.              buffer += sizeof(struct ExtendedGadget);
  716.           }
  717.            }
  718.         }
  719.         break;
  720.       }
  721.       /* init border dimension for editor */
  722.       first_egad->eg_BorderWidth  = width;
  723.       first_egad->eg_BorderHeight = height;
  724.       /* init text and images */
  725.       if (gd->gd_Text) {
  726.      init_gadget_text(first_egad, gd->gd_Text, width, height, flags,
  727.                                  text_attr);
  728.       }
  729.       if (image_buffer && type == GADGET_DATA_TYPE_BUTTON && (flags &
  730.                       GADGET_DATA_FLAG_BUTTON_IMAGE)) {
  731.      image_buffer = init_image_data(egad, image_buffer);
  732.       }
  733.       set_gadget_attributes(gl, i, flags, gd->gd_SpecialData.gd_Data.gd_Data1,
  734.                     gd->gd_SpecialData.gd_Data.gd_Data2,
  735.                        gd->gd_SpecialData.gd_Data.gd_Data3);
  736.    }
  737. }
  738.     /* Init extended gadget */
  739.  
  740.    STATIC BYTE *
  741. init_extended_gadget(struct ExtendedGadget  *egad, BYTE *buffer,
  742.              struct GadgetList  *gl, USHORT data_entry, USHORT type,
  743.          USHORT left_edge, USHORT top_edge, USHORT width, USHORT height)
  744. {
  745.    struct RenderInfo  *ri = gl->gl_RenderInfo;
  746.    struct GadgetData  *gd = gl->gl_Data + data_entry;
  747.    struct Gadget      *gad = &egad->eg_Gadget;
  748.    struct StringInfo  *sinfo;
  749.    struct PropInfo    *pinfo;
  750.    struct Image       *image;
  751.    ULONG  flags = gd->gd_Flags;
  752.    USHORT len;
  753.  
  754.    /* if monochrome display then set HIGHCOMP flag */
  755.    if (ri->ri_ScreenDepth == 1) {
  756.       flags |= GADGET_DATA_FLAG_HIGH_COMP;
  757.    }
  758.    /* init extended gadget */
  759.    egad->eg_Type       = type;
  760.    egad->eg_DataEntry  = data_entry;
  761.    egad->eg_GadgetList = gl;
  762.    /* init normal gadget */
  763.    gad->LeftEdge      = left_edge;
  764.    gad->TopEdge       = top_edge;
  765.    gad->Width         = width;
  766.    gad->Height        = height;
  767.    gad->MutualExclude = ISUP_ID;
  768.    switch (type) {
  769.       case EXTENDED_GADGET_TYPE_BUTTON :
  770.      gad->GadgetType = BOOLGADGET;
  771.      if (flags & GADGET_DATA_FLAG_BUTTON_TOGGLE) {
  772.         gad->Activation = RELVERIFY | TOGGLESELECT;
  773.         if (flags & GADGET_DATA_FLAG_BUTTON_IMAGE) {
  774.            gad->Flags = GADGIMAGE | GADGHIMAGE;
  775.            buffer     = init_gadget_image(egad, gd, buffer);
  776.         }
  777.      } else {
  778.         gad->Activation = RELVERIFY;
  779.         if (flags & GADGET_DATA_FLAG_BUTTON_IMAGE) {
  780.            if ((flags & GADGET_DATA_FLAG_NO_BORDER) &&
  781.                     !(flags & GADGET_DATA_FLAG_HIGH_COMP)) {
  782.           gad->Flags = GADGIMAGE | GADGHIMAGE;
  783.           buffer     = init_gadget_image(egad, gd, buffer);
  784.            } else {
  785.           egad->eg_Flags = EXTENDED_GADGET_FLAG_RENDER_IMAGE;
  786.           buffer         = init_gadget_image(egad, gd, buffer);
  787.            }
  788.         }
  789.      }
  790.      break;
  791.       case EXTENDED_GADGET_TYPE_CHECK :
  792.       case EXTENDED_GADGET_TYPE_MX :
  793.      gad->GadgetType = BOOLGADGET;
  794.      gad->Activation = TOGGLESELECT | GADGIMMEDIATE;
  795.      gad->Flags      = GADGIMAGE | GADGHIMAGE;
  796.      if (type == EXTENDED_GADGET_TYPE_CHECK) {
  797.         gad->GadgetRender = (APTR)&ri->ri_Images[IMAGE_CHECK_UNSELECTED];
  798.         gad->SelectRender = (APTR)&ri->ri_Images[IMAGE_CHECK_SELECTED];
  799.      } else {
  800.         gad->GadgetRender = (APTR)&ri->ri_Images[IMAGE_KNOB_UNSELECTED];
  801.         gad->SelectRender = (APTR)&ri->ri_Images[IMAGE_KNOB_SELECTED];
  802.      }
  803.      break;
  804.       case EXTENDED_GADGET_TYPE_STRING :
  805.       case EXTENDED_GADGET_TYPE_INTEGER :
  806.      gad->GadgetType = STRGADGET;
  807.      if (type == EXTENDED_GADGET_TYPE_STRING) {
  808.         gad->Activation = RELVERIFY;
  809.      } else {
  810.         gad->Activation = RELVERIFY | LONGINT;
  811.      }
  812.      gad->Flags       = GADGHCOMP;
  813.      gad->SpecialInfo = (APTR)buffer;
  814.      /* calc size of input buffer */
  815.      if (type == GADGET_DATA_TYPE_STRING) {
  816.         len = gd->gd_SpecialData.gd_InputData.gd_InputLen;
  817.         if (flags & (GADGET_DATA_FLAG_STRING_UNSIGNED_DEC |
  818.                     GADGET_DATA_FLAG_STRING_SIGNED_DEC |
  819.                            GADGET_DATA_FLAG_STRING_HEX |
  820.                          GADGET_DATA_FLAG_STRING_BIN)) {
  821.            if (len < MAX_BIN_NUM_DIGITS) {
  822.           len = MAX_BIN_NUM_DIGITS;
  823.            }
  824.         }
  825.      } else {
  826.         len = MAX_DEC_NUM_DIGITS;
  827.      }
  828.      /* init string info */
  829.      sinfo           = (struct StringInfo *)buffer;
  830.      buffer         += sizeof(struct StringInfo);
  831.      sinfo->Buffer   = (UBYTE *)buffer;
  832.      sinfo->MaxChars = len;
  833.      if (len & 1) {   /* input len odd */
  834.         buffer += len + 1;
  835.      } else {
  836.         buffer += len + 2;
  837.      }
  838.      break;
  839.       case EXTENDED_GADGET_TYPE_SLIDER_PROP :
  840.       case EXTENDED_GADGET_TYPE_SCROLLER_PROP :
  841.       case EXTENDED_GADGET_TYPE_LISTVIEW_PROP :
  842.      gad->GadgetType   = PROPGADGET;
  843.      gad->Activation   = GADGIMMEDIATE | RELVERIFY | FOLLOWMOUSE;
  844.      gad->Flags        = GADGHNONE;
  845.      gad->GadgetRender = (APTR)buffer;   /* needed for auto knob */
  846.      buffer           += sizeof(struct Image);
  847.      gad->SpecialInfo  = (APTR)buffer;
  848.      /* init prop info */
  849.      pinfo   = (struct PropInfo *)buffer;
  850.      buffer += sizeof(struct PropInfo);
  851.      if (type == EXTENDED_GADGET_TYPE_LISTVIEW_PROP || flags &
  852.                     GADGET_DATA_FLAG_ORIENTATION_VERT) {
  853.         pinfo->Flags = AUTOKNOB | FREEVERT | PROPBORDERLESS;
  854.      } else {
  855.         pinfo->Flags = AUTOKNOB | FREEHORIZ | PROPBORDERLESS;
  856.      }
  857.      break;
  858.       case EXTENDED_GADGET_TYPE_SCROLLER_LEFT :
  859.       case EXTENDED_GADGET_TYPE_SCROLLER_RIGHT :
  860.       case EXTENDED_GADGET_TYPE_SCROLLER_UP :
  861.       case EXTENDED_GADGET_TYPE_SCROLLER_DOWN :
  862.       case EXTENDED_GADGET_TYPE_LISTVIEW_UP :
  863.       case EXTENDED_GADGET_TYPE_LISTVIEW_DOWN :
  864.      gad->GadgetType = BOOLGADGET;
  865.      gad->Activation = GADGIMMEDIATE | RELVERIFY;
  866.      switch (type) {
  867.         case EXTENDED_GADGET_TYPE_SCROLLER_LEFT :
  868.            egad->eg_Render = (APTR)&ri->ri_Images[IMAGE_ARROW_LEFT];
  869.            break;
  870.         case EXTENDED_GADGET_TYPE_SCROLLER_RIGHT :
  871.            egad->eg_Render = (APTR)&ri->ri_Images[IMAGE_ARROW_RIGHT];
  872.            break;
  873.         case EXTENDED_GADGET_TYPE_SCROLLER_UP :
  874.         case EXTENDED_GADGET_TYPE_LISTVIEW_UP :
  875.            egad->eg_Render = (APTR)&ri->ri_Images[IMAGE_ARROW_UP];
  876.            break;
  877.         case EXTENDED_GADGET_TYPE_SCROLLER_DOWN :
  878.         case EXTENDED_GADGET_TYPE_LISTVIEW_DOWN :
  879.            egad->eg_Render = (APTR)&ri->ri_Images[IMAGE_ARROW_DOWN];
  880.            break;
  881.      }
  882.      egad->eg_Flags = EXTENDED_GADGET_FLAG_RENDER_IMAGE;
  883.      break;
  884.       case EXTENDED_GADGET_TYPE_CYCLE :
  885.      gad->GadgetType = BOOLGADGET;
  886.      gad->Activation = RELVERIFY;
  887.      egad->eg_Render = (APTR)&ri->ri_Images[IMAGE_CYCLE];
  888.      egad->eg_Flags  = EXTENDED_GADGET_FLAG_RENDER_IMAGE;
  889.      break;
  890.       case EXTENDED_GADGET_TYPE_COUNT :
  891.      gad->GadgetType = BOOLGADGET;
  892.      gad->Activation = TOGGLESELECT | GADGIMMEDIATE;
  893.      egad->eg_Render = (APTR)&ri->ri_Images[IMAGE_COUNT_LEFT];
  894.      egad->eg_Flags  = EXTENDED_GADGET_FLAG_RENDER_IMAGE;
  895.      break;
  896.       case EXTENDED_GADGET_TYPE_LISTVIEW_ENTRY :
  897.      gad->GadgetType = BOOLGADGET;
  898.      gad->Activation = RELVERIFY;
  899.      gad->Flags      = GADGHCOMP;
  900.      break;
  901.       case EXTENDED_GADGET_TYPE_PALETTE_INDICATOR :
  902.       case EXTENDED_GADGET_TYPE_PALETTE_COLOR :
  903.      gad->GadgetType = BOOLGADGET;
  904.      gad->Activation = RELVERIFY;
  905.      /* init image */
  906.      image   = (struct Image *)buffer;
  907.      buffer += sizeof(struct Image);
  908.      if (flags & GADGET_DATA_FLAG_NO_BORDER) {
  909.         image->Width    = width;
  910.         image->Height   = height;
  911.      } else {
  912.         image->LeftEdge = 0;
  913.         image->TopEdge  = 0;
  914.         image->Width    = width - 2 * 4;
  915.         image->Height   = height - 2 * 2;
  916.      }
  917.      image->Depth    = ri->ri_ScreenDepth;
  918.      egad->eg_Render = (APTR)image;
  919.      egad->eg_Flags  = EXTENDED_GADGET_FLAG_RENDER_IMAGE;
  920.      break;
  921.    }
  922.    if (flags & GADGET_DATA_FLAG_DISABLED) {
  923.       gad->Flags |= GADGDISABLED;
  924.    }
  925.    return(init_gadget_border(buffer, ri, egad, flags));
  926. }
  927.     /* Init gadget border */
  928.  
  929.    STATIC BYTE *
  930. init_gadget_border(BYTE *buffer, struct RenderInfo  *ri,
  931.                   struct ExtendedGadget  *egad, ULONG flags)
  932. {
  933.    struct Gadget  *gad = &egad->eg_Gadget;
  934.    USHORT width = gad->Width, height = gad->Height;
  935.  
  936.    switch (egad->eg_Type) {
  937.       case EXTENDED_GADGET_TYPE_BUTTON :
  938.      if ((flags & GADGET_DATA_FLAG_BUTTON_TOGGLE)  &&
  939.                   (flags & GADGET_DATA_FLAG_BUTTON_IMAGE)) {
  940.         /* init non toggle border out */
  941.         if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  942.            egad->eg_Render = (APTR)buffer;
  943.            egad->eg_Flags |= EXTENDED_GADGET_FLAG_RENDER_BORDER;
  944.            buffer          = init_border(ri, buffer, 0, 0, width,
  945.                      height, BORDER_DATA_TYPE_BOX1_OUT);
  946.         }
  947.      } else {
  948.         /* init toggle border */
  949.         if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  950.            gad->Flags |= GADGHCOMP;
  951.            if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  952.           gad->GadgetRender = (APTR)buffer;
  953.           buffer            = init_border(ri, buffer, 0, 0, width,
  954.                      height, BORDER_DATA_TYPE_BOX1_OUT);
  955.            }
  956.         } else {
  957.            if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  958.           gad->Flags       |= GADGHIMAGE;
  959.           gad->GadgetRender = (APTR)buffer;
  960.           buffer            = init_border(ri, buffer, 0, 0, width,
  961.                      height, BORDER_DATA_TYPE_BOX1_OUT);
  962.           gad->SelectRender = (APTR)buffer;
  963.           buffer            = init_border(ri, buffer, 0, 0, width,
  964.                       height, BORDER_DATA_TYPE_BOX1_IN);
  965.            } else {
  966.           if (!(gad->Flags & GADGHIMAGE)) {
  967.              gad->Flags |= GADGHNONE;
  968.           }
  969.            }
  970.         }
  971.      }
  972.      break;
  973.       case EXTENDED_GADGET_TYPE_CHECK :
  974.      /* init non toggle border out */
  975.      if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  976.         egad->eg_Render = (APTR)buffer;
  977.         egad->eg_Flags  = EXTENDED_GADGET_FLAG_RENDER_BORDER;
  978.         buffer          = init_border(ri, buffer, 0, 0, width, height,
  979.                          BORDER_DATA_TYPE_BOX1_OUT);
  980.      }
  981.      break;
  982.       case EXTENDED_GADGET_TYPE_SCROLLER_LEFT :
  983.       case EXTENDED_GADGET_TYPE_SCROLLER_RIGHT :
  984.       case EXTENDED_GADGET_TYPE_SCROLLER_UP :
  985.       case EXTENDED_GADGET_TYPE_SCROLLER_DOWN :
  986.       case EXTENDED_GADGET_TYPE_LISTVIEW_UP :
  987.       case EXTENDED_GADGET_TYPE_LISTVIEW_DOWN :
  988.       case EXTENDED_GADGET_TYPE_CYCLE :
  989.       case EXTENDED_GADGET_TYPE_COUNT :
  990.       case EXTENDED_GADGET_TYPE_PALETTE_COLOR :
  991.      /* init toggle border */
  992.      if (flags & GADGET_DATA_FLAG_HIGH_COMP) {
  993.         gad->Flags |= GADGHCOMP;
  994.         if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  995.            gad->GadgetRender = (APTR)buffer;
  996.            buffer            = init_border(ri, buffer, 0, 0,
  997.                   width, height, BORDER_DATA_TYPE_BOX1_OUT);
  998.         }
  999.      } else {
  1000.         if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1001.            gad->Flags       |= GADGHIMAGE;
  1002.            gad->GadgetRender = (APTR)buffer;
  1003.            buffer            = init_border(ri, buffer, 0, 0, width,
  1004.                      height, BORDER_DATA_TYPE_BOX1_OUT);
  1005.            gad->SelectRender = (APTR)buffer;
  1006.            buffer            = init_border(ri, buffer, 0, 0, width,
  1007.                       height, BORDER_DATA_TYPE_BOX1_IN);
  1008.         } else {
  1009.            gad->Flags |= GADGHNONE;
  1010.         }
  1011.      }
  1012.      break;
  1013.       case EXTENDED_GADGET_TYPE_PALETTE_INDICATOR :
  1014.      /* init non toggle border in */
  1015.      gad->Flags |= GADGHNONE;
  1016.      if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1017.         gad->GadgetRender = (APTR)buffer;
  1018.         buffer            = init_border(ri, buffer, 0, 0, width, height,
  1019.                           BORDER_DATA_TYPE_BOX1_IN);
  1020.      }
  1021.      break;
  1022.       case EXTENDED_GADGET_TYPE_STRING :
  1023.       case EXTENDED_GADGET_TYPE_INTEGER :
  1024.      /* init input border */
  1025.      if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1026.         gad->GadgetRender = (APTR)buffer;
  1027.         gad->LeftEdge    += 6;
  1028.         gad->TopEdge     += 3;
  1029.         gad->Width       -= 2 * 6;
  1030.         buffer            = init_border(ri, buffer, -6, -3, width,
  1031.                  height + 2 * 3, BORDER_DATA_TYPE_BOX2_OUT);
  1032.      }
  1033.      break;
  1034.       case EXTENDED_GADGET_TYPE_SLIDER_PROP :
  1035.       case EXTENDED_GADGET_TYPE_SCROLLER_PROP :
  1036.       case EXTENDED_GADGET_TYPE_LISTVIEW_PROP :
  1037.      /* init prop border */
  1038.      if (!(flags & GADGET_DATA_FLAG_NO_BORDER)) {
  1039.         egad->eg_Render = (APTR)buffer;
  1040.         egad->eg_Flags  = EXTENDED_GADGET_FLAG_RENDER_BORDER;
  1041.         gad->LeftEdge  += 4;
  1042.         gad->TopEdge   += 2;
  1043.         gad->Width     -= 2 * 4;
  1044.         gad->Height    -= 2 * 2;
  1045.         buffer          = init_border(ri, buffer, -4, -2, width, height,
  1046.                          BORDER_DATA_TYPE_BOX1_OUT);
  1047.      }
  1048.      break;
  1049.    }
  1050.    return(buffer);
  1051. }
  1052.     /* Init gadget text */
  1053.  
  1054.    STATIC USHORT
  1055. init_gadget_text(struct ExtendedGadget  *egad, BYTE *text, USHORT width,
  1056.             USHORT height, ULONG flags, struct TextAttr  *text_attr)
  1057. {
  1058.    struct IntuiText  itext;
  1059.    BYTE   c, *ptr, hot_key_id[] = "_";
  1060.    USHORT type = (egad->eg_GadgetList->gl_Data + egad->eg_DataEntry)->gd_Type;
  1061.    SHORT  i, xoffset, yoffset, left_edge, top_edge, text_width, text_height;
  1062.  
  1063.    /* search hot key in gadget text */
  1064.    if (flags & GADGET_DATA_FLAG_HOT_KEY) {
  1065.       for (i = 0, ptr = text; *ptr; i++) {
  1066.      if (*ptr++ == '_' && (c = *ptr)) {
  1067.         if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
  1068.                            (c >= '0' && c <= '9')) {
  1069.            egad->eg_Hotkey    = (USHORT)c;
  1070.            egad->eg_HotkeyPos = i + 1;
  1071.            egad->eg_Flags    |= EXTENDED_GADGET_FLAG_HOT_KEY;
  1072.            break;
  1073.         }
  1074.      }
  1075.       }
  1076.    }
  1077.    /* calc text dimension */
  1078.    itext.IText     = (UBYTE *)text;
  1079.    itext.ITextFont = text_attr;
  1080.    text_width      = IntuiTextLength(&itext);
  1081.    text_height     = text_attr->ta_YSize;
  1082.    if (egad->eg_Flags & EXTENDED_GADGET_FLAG_HOT_KEY) {
  1083.       itext.IText = (UBYTE *)&hot_key_id[0];
  1084.       text_width -= IntuiTextLength(&itext);
  1085.    }
  1086.    /* calc border offset */
  1087.    if (flags & GADGET_DATA_FLAG_NO_BORDER) {
  1088.       xoffset = 0;
  1089.       yoffset = 0;
  1090.    } else {
  1091.       switch (type) {
  1092.      case GADGET_DATA_TYPE_MX :
  1093.         xoffset = 8;
  1094.         yoffset = 4;
  1095.         break;
  1096.      case GADGET_DATA_TYPE_STRING :
  1097.      case GADGET_DATA_TYPE_INTEGER :
  1098.         xoffset = 6;
  1099.         yoffset = 0;
  1100.         break;
  1101.      case GADGET_DATA_TYPE_SLIDER :
  1102.      case GADGET_DATA_TYPE_SCROLLER :
  1103.      case GADGET_DATA_TYPE_LISTVIEW :
  1104.         xoffset = 4;
  1105.         yoffset = 2;
  1106.         break;
  1107.      default :
  1108.         xoffset = 0;
  1109.         yoffset = 0;
  1110.         break;
  1111.       }
  1112.    }
  1113.    /* calc text pos */
  1114.    switch (type) {
  1115.       case GADGET_DATA_TYPE_MX :
  1116.      if (flags & GADGET_DATA_FLAG_TEXT_LEFT) {
  1117.         left_edge = -(width - egad->eg_Gadget.Width - xoffset - (SHORT)
  1118.                           (width - text_width) / 2);
  1119.      } else {
  1120.         left_edge = (SHORT)(width - text_width) / 2 - xoffset;
  1121.      }
  1122.      top_edge = -(text_height + yoffset + 4);
  1123.      break;
  1124.       case GADGET_DATA_TYPE_LISTVIEW :
  1125.      left_edge = -(width - egad->eg_Gadget.Width - xoffset - (SHORT)
  1126.                           (width - text_width) / 2);
  1127.      top_edge  = -(text_height + yoffset + 4);
  1128.      break;
  1129.       case GADGET_DATA_TYPE_PALETTE :
  1130.      left_edge = (SHORT)(width - text_width) / 2;
  1131.      top_edge  = -(text_height + 4);
  1132.      break;
  1133.       default :
  1134.      /* calc horizontal pos */
  1135.      if (flags & GADGET_DATA_FLAG_TEXT_LEFT) {
  1136.         left_edge = -(text_width + xoffset + 8);
  1137.      } else {
  1138.         if (flags & GADGET_DATA_FLAG_TEXT_RIGHT) {
  1139.            left_edge = width - xoffset + 8;
  1140.         } else {
  1141.            left_edge = (SHORT)(width - 2 * xoffset - text_width) / 2;
  1142.         }
  1143.      }
  1144.      /* calc vertical pos */
  1145.      if (flags & GADGET_DATA_FLAG_TEXT_ABOVE) {
  1146.         top_edge = -(text_height + yoffset + 4);
  1147.      } else {
  1148.         if (flags & GADGET_DATA_FLAG_TEXT_BELOW) {
  1149.            top_edge = height - yoffset + 4;
  1150.         } else {
  1151.            top_edge = (SHORT)(height - 2 * yoffset - text_height) / 2;
  1152.         }
  1153.      }
  1154.      break;
  1155.    }
  1156.    egad->eg_TextLeftEdge = left_edge;
  1157.    egad->eg_TextTopEdge  = top_edge;
  1158.    egad->eg_Text         = text;
  1159.    return(text_width);
  1160. }
  1161.     /* Init mutual exclude gadget text */
  1162.  
  1163.    STATIC BYTE *
  1164. init_mx_text(struct ExtendedGadget  *egad, BYTE *buffer, BYTE *text,
  1165.       USHORT width, USHORT height, ULONG flags, struct TextAttr  *text_attr)
  1166. {
  1167.    struct RenderInfo  *ri = egad->eg_GadgetList->gl_RenderInfo;
  1168.    struct IntuiText   *itext;
  1169.  
  1170.    itext            = (struct IntuiText *)buffer;
  1171.    buffer          += sizeof(struct IntuiText);
  1172.    itext->FrontPen  = (flags & GADGET_DATA_FLAG_TEXT_COLOR2 ?
  1173.                      ri->ri_TextPen2 : ri->ri_TextPen1);
  1174.    itext->BackPen   = ri->ri_BackPen;
  1175.    itext->DrawMode  = JAM2;
  1176.    itext->IText     = (UBYTE *)text;
  1177.    itext->ITextFont = text_attr;
  1178.    itext->TopEdge   = (SHORT)(height - text_attr->ta_YSize) / 2;
  1179.    if (flags & GADGET_DATA_FLAG_TEXT_LEFT) {
  1180.       itext->LeftEdge = -(IntuiTextLength(itext) + 8);
  1181.    } else {
  1182.       itext->LeftEdge = width + 8;   /* default right */
  1183.    }
  1184.    egad->eg_Gadget.GadgetText = itext;
  1185.    return(buffer);
  1186. }
  1187.     /* Check image for valid chip mem data */
  1188.  
  1189.    STATIC BOOL
  1190. check_gadget_image(struct Image  *image)
  1191. {
  1192.    BYTE *data;
  1193.    BOOL result;
  1194.  
  1195.    if ((data = (BYTE *)image->ImageData) && !(TypeOfMem(data) & MEMF_CHIP)) {
  1196.       result = FALSE;
  1197.    } else {
  1198.       result = TRUE;
  1199.    }
  1200.    return(result);
  1201. }
  1202.     /* Init gadget image */
  1203.  
  1204.    STATIC BYTE *
  1205. init_gadget_image(struct ExtendedGadget  *egad, struct GadgetData  *gd,
  1206.                                    BYTE *buffer)
  1207. {
  1208.    struct Gadget  *gad = &egad->eg_Gadget;
  1209.    struct Image   *image = gd->gd_SpecialData.gd_ButtonData.gd_ButtonNormalRender;
  1210.  
  1211.    if (gad->Flags & GADGIMAGE) {
  1212.       if (check_gadget_image(image) == FALSE) {
  1213.      egad->eg_Flags = EXTENDED_GADGET_FLAG_NORMAL_IMAGE_COPY;
  1214.      CopyMem((BYTE *)image, buffer, (LONG)sizeof(struct Image));
  1215.      image   = (struct Image *)buffer;
  1216.      buffer += sizeof(struct Image);
  1217.       }
  1218.       gad->GadgetRender = (APTR)image;
  1219.       if (gad->Flags & GADGHIMAGE) {
  1220.      if (!(image = gd->gd_SpecialData.gd_ButtonData.gd_ButtonSelectRender)) {
  1221.         gad->Flags &= ~GADGHIGHBITS;
  1222.         gad->Flags |= GADGHNONE;
  1223.      } else {
  1224.         if (check_gadget_image(image) == FALSE) {
  1225.            egad->eg_Flags |= EXTENDED_GADGET_FLAG_SELECT_IMAGE_COPY;
  1226.            CopyMem((BYTE *)image, buffer, (LONG)sizeof(struct Image));
  1227.            image   = (struct Image *)buffer;
  1228.            buffer += sizeof(struct Image);
  1229.         }
  1230.         gad->SelectRender = (APTR)image;
  1231.      }
  1232.       }
  1233.    } else {
  1234.       if (check_gadget_image(image) == FALSE) {
  1235.      egad->eg_Flags |= EXTENDED_GADGET_FLAG_NORMAL_IMAGE_COPY;
  1236.      CopyMem((BYTE *)image, buffer, (LONG)sizeof(struct Image));
  1237.      image   = (struct Image *)buffer;
  1238.      buffer += sizeof(struct Image);
  1239.       }
  1240.       egad->eg_Render = (APTR)image;
  1241.    }
  1242.    return(buffer);
  1243. }
  1244.     /* Init image data - make chipmem copy if needed */
  1245.  
  1246.    STATIC BYTE *
  1247. init_image_data(struct ExtendedGadget  *egad, BYTE *buffer)
  1248. {
  1249.    struct Gadget  *gad = &egad->eg_Gadget;
  1250.    struct Image   *image;
  1251.    UBYTE flags = egad->eg_Flags;
  1252.    BYTE  *data;
  1253.    LONG  size;
  1254.  
  1255.    if (flags & EXTENDED_GADGET_FLAG_NORMAL_IMAGE_COPY) {
  1256.       if (flags & EXTENDED_GADGET_FLAG_RENDER_IMAGE) {
  1257.      image = (struct Image *)egad->eg_Render;
  1258.       } else {
  1259.      image = (struct Image *)gad->GadgetRender;
  1260.       }
  1261.       if ((data = (BYTE *)image->ImageData) && !(TypeOfMem(data) &
  1262.                                    MEMF_CHIP)) {
  1263.      size = (image->Width / 16 + (image->Width & 15 ? 1 : 0))
  1264.                      * image->Height * image->Depth * 2;
  1265.      CopyMem(data, buffer, size);
  1266.      image->ImageData = (UWORD *)buffer;
  1267.      buffer          += size;
  1268.       }
  1269.    }
  1270.    if (flags & EXTENDED_GADGET_FLAG_SELECT_IMAGE_COPY) {
  1271.       image = (struct Image *)gad->SelectRender;
  1272.       if ((data = (BYTE *)image->ImageData) && !(TypeOfMem(data) &
  1273.                                    MEMF_CHIP)) {
  1274.      size = (image->Width / 16 + (image->Width & 15 ? 1 : 0))
  1275.                      * image->Height * image->Depth * 2;
  1276.      CopyMem(data, buffer, size);
  1277.      image->ImageData = (UWORD *)buffer;
  1278.      buffer          += size;
  1279.       }
  1280.    }
  1281.    return(buffer);
  1282. }
  1283.