home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 594a.lha / maker_v0.1 / gadget.c < prev    next >
C/C++ Source or Header  |  1991-10-18  |  23KB  |  919 lines

  1. #include "maker.h"
  2. #include "proto.h"
  3. #include "global.h"
  4.  
  5. #include <libraries/gadtools.h>
  6. #include <graphics/gfxmacros.h>
  7. #include <intuition/gadgetclass.h>
  8.  
  9. #include <proto/intuition.h>
  10. #include <proto/graphics.h>
  11. #include <proto/exec.h>
  12. #include <proto/gadtools.h>
  13.  
  14. #include <string.h>
  15.  
  16. #define    CYCLE_XWIDTH    28
  17. #define    MX_XWIDTH        28
  18.  
  19. USHORT CalcMaxWidth(char **theStrings);
  20.  
  21. void NewObj(USHORT code)
  22. {
  23.     BOOL                refresh = FALSE;
  24.     USHORT            objType;
  25.     LinkNode            *nodePtr = 0L;
  26.     
  27.     switch (code)
  28.     {
  29.         case ITEM_NewButton:
  30.             objType = OTYPE_Button;
  31.             break;
  32.         case ITEM_NewCycle:
  33.             objType = OTYPE_Cycle;
  34.             break;
  35.         case ITEM_NewSlider:
  36.             objType = OTYPE_Slider;
  37.             break;
  38.         case ITEM_NewScroller:
  39.             objType = OTYPE_Scroller;
  40.             break;
  41.         case ITEM_NewMX:
  42.             objType = OTYPE_MX;
  43.             break;
  44.         case ITEM_NewCheckBox:
  45.             objType = OTYPE_CheckBox;
  46.             break;
  47.         case ITEM_NewString:
  48.             objType = OTYPE_String;
  49.             break;
  50.         case ITEM_NewPalette:
  51.             objType = OTYPE_Palette;
  52.             break;
  53.         case ITEM_NewListView:
  54.             objType = OTYPE_ListView;
  55.             break;
  56.         case ITEM_NewRect:
  57.             objType = OTYPE_Rect;
  58.             break;
  59.         case ITEM_NewLine:
  60.             objType = OTYPE_Line;
  61.             break;
  62.         case ITEM_NewText:
  63.             objType = OTYPE_Text;
  64.             break;
  65.         case ITEM_NewIText:
  66.             objType = OTYPE_IText;
  67.             break;
  68.     }
  69.         
  70.     nodePtr = AllocateObj(objType);
  71.     if (!nodePtr)
  72.         return;
  73.     
  74.     if (MakeGadget(nodePtr) != 2)
  75.     {
  76.         gSelObj = nodePtr;
  77.         refresh = TRUE;
  78.     }
  79.     else
  80.     {
  81.         // the operation failed, so nuke the object
  82.         
  83.         DisposeObj(nodePtr);
  84.     }
  85.                         
  86.     if (!gEditMode)            // if we're not in edit mode, don't highlight the new object
  87.         gSelObj = 0L;
  88.         
  89.     if (refresh)
  90.         ReDraw();
  91. }
  92.  
  93. /*        Allocate the specified object type, and initialize it to default values        */
  94.  
  95. LinkNode *AllocateObj( USHORT objType )
  96. {
  97.     LinkNode        *nodePtr = 0L;
  98.     
  99.     switch (objType)
  100.     {
  101.         case OTYPE_Button:
  102.             {
  103.                 ButtonObj    *newButton = 0L;
  104.                 
  105.                 if (GetMem( (void **) &newButton, sizeof(ButtonObj)))
  106.                 {
  107.                     strcpy(newButton->label, "Push Me");
  108.                     
  109.                     newButton->type = OTYPE_Button;
  110.                     newButton->numBytes = sizeof(ButtonObj);
  111.                     newButton->rect.minX = 20;
  112.                     newButton->rect.minY = 20;
  113.                     newButton->rect.maxX = 83;
  114.                     newButton->rect.maxY = 31;
  115.                     newButton->flags = PLACETEXT_IN;
  116.                     
  117.                     nodePtr = (LinkNode *) newButton;
  118.                 }
  119.             }
  120.             break;
  121.         case OTYPE_Cycle:
  122.             {
  123.                 CycleObj    *newCycle = 0L;
  124.                 
  125.                 if (GetMem( (void **) &newCycle, sizeof(CycleObj)))
  126.                 {
  127.                     strcpy(newCycle->label, "Cycle:");
  128.                     
  129.                     newCycle->type = OTYPE_Cycle;
  130.                     newCycle->numBytes = sizeof(CycleObj);
  131.                     newCycle->textLabels = gDefaultMX;
  132.                     
  133.                     newCycle->rect.minX = 20;
  134.                     newCycle->rect.minY = 20;
  135.                     newCycle->rect.maxX = newCycle->rect.minX + CYCLE_XWIDTH +
  136.                                                     CalcMaxWidth(newCycle->textLabels) - 1;
  137.                     newCycle->rect.maxY = 31;
  138.                     newCycle->flags = PLACETEXT_LEFT;
  139.                     newCycle->activeItem = 0;
  140.                     
  141.                     nodePtr = (LinkNode *) newCycle;
  142.                 }
  143.             }
  144.             break;
  145.         case OTYPE_Slider:
  146.             {
  147.                 SliderObj    *newSlider = 0L;
  148.                 
  149.                 if (GetMem( (void **) &newSlider, sizeof(SliderObj)))
  150.                 {
  151.                     strcpy(newSlider->label, "Slider:");
  152.                     
  153.                     newSlider->type = OTYPE_Slider;
  154.                     newSlider->numBytes = sizeof(SliderObj);
  155.                     newSlider->rect.minX = 20;
  156.                     newSlider->rect.minY = 20;
  157.                     newSlider->rect.maxX = 83;
  158.                     newSlider->rect.maxY = 31;
  159.                     newSlider->flags = PLACETEXT_ABOVE;
  160.                     
  161.                     newSlider->minLevel = 0;
  162.                     newSlider->maxLevel = 10;
  163.                     newSlider->currentLevel = 0;
  164.                     newSlider->maxChars = 10;
  165.                     strcpy(newSlider->format, "%ld");
  166.                     newSlider->levelPlace = PLACETEXT_LEFT;
  167.                     newSlider->orientation = LORIENT_HORIZ;
  168.                     newSlider->immediateMsg = FALSE;
  169.                     newSlider->releaseMsg = TRUE;
  170.                     
  171.                     nodePtr = (LinkNode *) newSlider;
  172.                 }
  173.             }
  174.             break;
  175.         case OTYPE_Scroller:
  176.             {
  177.                 ScrollerObj    *newScroller = 0L;
  178.                 
  179.                 if (GetMem( (void **) &newScroller, sizeof(ScrollerObj)))
  180.                 {
  181.                     strcpy(newScroller->label, "Scroller:");
  182.                     
  183.                     newScroller->type = OTYPE_Scroller;
  184.                     newScroller->numBytes = sizeof(ScrollerObj);
  185.                     newScroller->rect.minX = 20;
  186.                     newScroller->rect.minY = 20;
  187.                     newScroller->rect.maxX = 35;
  188.                     newScroller->rect.maxY = 89;
  189.                     newScroller->flags = PLACETEXT_RIGHT;
  190.                     
  191.                     newScroller->topItem = 0;
  192.                     newScroller->totalItems = 10;
  193.                     newScroller->visibleItems = 4;
  194.                     newScroller->arrowSize = 12;
  195.                     newScroller->orientation = LORIENT_VERT;
  196.                     newScroller->immediateMsg = FALSE;
  197.                     newScroller->releaseMsg = TRUE;
  198.                     
  199.                     nodePtr = (LinkNode *) newScroller;
  200.                 }
  201.             }
  202.             break;
  203.         case OTYPE_MX:
  204.             {
  205.                 MXObj    *newMX = 0L;
  206.                 
  207.                 if (GetMem( (void **) &newMX, sizeof(MXObj)))
  208.                 {
  209.                     strcpy(newMX->label, "MX:");
  210.                     
  211.                     newMX->type = OTYPE_MX;
  212.                     newMX->numBytes = sizeof(MXObj);
  213.                     newMX->textLabels = gDefaultMX;
  214.                     
  215.                     newMX->rect.minX = 20;
  216.                     newMX->rect.minY = 20;
  217.                     newMX->rect.maxX = newMX->rect.minX + MX_XWIDTH +
  218.                                                 CalcMaxWidth(newMX->textLabels) - 1;
  219.                     newMX->rect.maxY = 52;
  220.                     newMX->flags = PLACETEXT_RIGHT;
  221.                     newMX->activeItem = 0;
  222.                     newMX->extraSpacing = 3;
  223.                     
  224.                     nodePtr = (LinkNode *) newMX;
  225.                 }
  226.             }
  227.             break;
  228.         case OTYPE_CheckBox:
  229.             {
  230.                 CheckBoxObj    *newCheckBox = 0L;
  231.                 
  232.                 if (GetMem( (void **) &newCheckBox, sizeof(CheckBoxObj)))
  233.                 {
  234.                     strcpy(newCheckBox->label, "Check Box");
  235.                     
  236.                     newCheckBox->type = OTYPE_CheckBox;
  237.                     newCheckBox->numBytes = sizeof(CheckBoxObj);
  238.                     newCheckBox->rect.minX = 20;
  239.                     newCheckBox->rect.minY = 20;
  240.                     newCheckBox->rect.maxX = 45;
  241.                     newCheckBox->rect.maxY = 30;
  242.                     newCheckBox->flags = PLACETEXT_RIGHT;
  243.                     newCheckBox->checked = TRUE;
  244.                     
  245.                     nodePtr = (LinkNode *) newCheckBox;
  246.                 }
  247.             }
  248.             break;
  249.         case OTYPE_String:
  250.             {
  251.                 StringObj    *newString = 0L;
  252.                 
  253.                 if (GetMem( (void **) &newString, sizeof(StringObj)))
  254.                 {
  255.                     strcpy(newString->label, "The String");
  256.                     strcpy(newString->theChars, "Initial Text");
  257.                     
  258.                     newString->type = OTYPE_String;
  259.                     newString->numBytes = sizeof(StringObj);
  260.                     newString->rect.minX = 20;
  261.                     newString->rect.minY = 20;
  262.                     newString->rect.maxX = 99;
  263.                     newString->rect.maxY = 31;
  264.                     newString->maxChars = MAX_TEXT_LEN - 1;
  265.                     newString->flags = PLACETEXT_LEFT;
  266.                     
  267.                     nodePtr = (LinkNode *) newString;
  268.                 }
  269.             }
  270.             break;
  271.         case OTYPE_Palette:
  272.             {
  273.                 PaletteObj    *newPalette = 0L;
  274.                 
  275.                 if (GetMem( (void **) &newPalette, sizeof(PaletteObj)))
  276.                 {
  277.                     strcpy(newPalette->label, "Color Palette:");
  278.                     
  279.                     newPalette->type = OTYPE_Palette;
  280.                     newPalette->numBytes = sizeof(PaletteObj);
  281.                     newPalette->rect.minX = 20;
  282.                     newPalette->rect.minY = 20;
  283.                     newPalette->rect.maxX = 99;
  284.                     newPalette->rect.maxY = 35;
  285.                     newPalette->flags = PLACETEXT_ABOVE;
  286.                     newPalette->depth = 4;
  287.                     newPalette->firstColor = 1;
  288.                     newPalette->colorOffset = 0;
  289.                     newPalette->indicatorWidth = 24L;
  290.                     newPalette->indicatorHeight = 0L;
  291.                     
  292.                     nodePtr = (LinkNode *) newPalette;
  293.                 }
  294.             }
  295.             break;
  296.         case OTYPE_ListView:
  297.             {
  298.                 ListViewObj    *newListView = 0L;
  299.                 
  300.                 if (GetMem( (void **) &newListView, sizeof(ListViewObj)))
  301.                 {
  302.                     strcpy(newListView->label, "ListView:");
  303.                     
  304.                     newListView->type = OTYPE_ListView;
  305.                     newListView->numBytes = sizeof(ListViewObj);
  306.                     newListView->rect.minX = 20;
  307.                     newListView->rect.minY = 40;
  308.                     newListView->rect.maxX = 120;
  309.                     newListView->rect.maxY = 100;
  310.                     newListView->flags = PLACETEXT_ABOVE;
  311.                     
  312.                     newListView->topItem = 0;
  313.                     memmove(&newListView->itemList, &gDefaultList, sizeof(List));
  314. /*                    NewList(&newListView->itemList);    */
  315.                     newListView->readOnly = FALSE;
  316.                     newListView->scrollWidth = 16;
  317.                     newListView->stringObj = 0L;        // make this point to a string obj for editing
  318.                     newListView->selectedItem = 0;
  319.                     newListView->extraSpacing = 1;
  320.                     
  321.                     nodePtr = (LinkNode *) newListView;
  322.                 }
  323.             }
  324.             break;
  325.         case OTYPE_Rect:
  326.             {
  327.                 RectObj    *newRect = 0L;
  328.                 
  329.                 if (GetMem( (void **) &newRect, sizeof(RectObj)))
  330.                 {
  331.                     newRect->type = OTYPE_Rect;
  332.                     newRect->color = blackPen;
  333.                     newRect->numBytes = sizeof(RectObj);
  334.                     newRect->rect.minX = 20;
  335.                     newRect->rect.minY = 20;
  336.                     newRect->rect.maxX = 40;
  337.                     newRect->rect.maxY = 40;
  338.                     
  339.                     nodePtr = (LinkNode *) newRect;
  340.                 }
  341.             }
  342.             break;
  343.         case OTYPE_Line:
  344.             break;
  345.         case OTYPE_Text:
  346.             {
  347.                 TextObj    *newText = 0L;
  348.                 
  349.                 if (GetMem( (void **) &newText, sizeof(TextObj)))
  350.                 {
  351.                     newText->type = OTYPE_Text;
  352.                     newText->numBytes = sizeof(TextObj);
  353.                     
  354.                     strcpy(newText->label, "Sample Text");
  355.                     
  356.                     newText->rect.minX = 20;
  357.                     newText->rect.minY = 20;
  358.                     newText->rect.maxX = newText->rect.minX +
  359.                             TextLength(gWindPtr->RPort, newText->label, strlen(newText->label));
  360.                     newText->rect.maxY = newText->rect.minY + gWindPtr->RPort->Font->tf_YSize;
  361.                     
  362.                     newText->flags = PLACETEXT_LEFT;
  363.                     
  364.                     newText->copyText = FALSE;
  365.                     newText->border = TRUE;
  366.                     
  367.                     nodePtr = (LinkNode *) newText;
  368.                 }
  369.             }
  370.             break;
  371.         case OTYPE_IText:  
  372.             {
  373.                 ITextObj    *newIText = 0L;
  374.                 
  375.                 if (GetMem( (void **) &newIText, sizeof(ITextObj)))
  376.                 {
  377.                     strcpy(newIText->label, "Sample IText");
  378.                     newIText->type = OTYPE_IText;
  379.                     newIText->numBytes = sizeof(ITextObj);
  380.                     
  381.                     newIText->iText.FrontPen = blackPen;
  382.                     newIText->iText.BackPen = grayPen;
  383.                     newIText->iText.DrawMode = JAM2;
  384.                     newIText->iText.LeftEdge = 1;
  385.                     newIText->iText.TopEdge = 1;
  386.                     newIText->iText.ITextFont = &topaz8;
  387.                     newIText->iText.IText = newIText->label;
  388.                     newIText->iText.NextText = 0L;
  389.                 
  390.                     newIText->rect.minX = 20;
  391.                     newIText->rect.minY = 20;
  392.                     newIText->rect.maxX = newIText->rect.minX + IntuiTextLength(&newIText->iText);
  393.                     newIText->rect.maxY = newIText->rect.minY + gWindPtr->RPort->Font->tf_YSize;
  394.                     
  395.                     nodePtr = (LinkNode *) newIText;
  396.                 }
  397.             }
  398.             break;
  399.     }
  400.     
  401. //    if (nodePtr)
  402. //        nodePtr->itemNum = gNextItemNum++;
  403.  
  404.     if (nodePtr)
  405.         AddLink( (void **) &gObjList, nodePtr);
  406.     
  407.     return nodePtr;
  408. }
  409.  
  410. USHORT CalcMaxWidth(char **theStrings)
  411. {
  412.     USHORT    width,
  413.                 maxWidth = 0;
  414.     
  415.     for (; *theStrings; theStrings++)
  416.     {
  417.         width = TextLength(gWindPtr->RPort, *theStrings, strlen(*theStrings));
  418.         maxWidth = (width > maxWidth) ? width : maxWidth;
  419.     }
  420.     
  421.     return maxWidth;
  422. }
  423.  
  424. void DisposeObj( LinkNode *nodePtr )
  425. {
  426.     Gadget        *gadgetPtr;
  427.     USHORT        numGadget;
  428.     
  429.     if (nodePtr)
  430.     {
  431.         if (GetGadgetData(nodePtr, &gadgetPtr, &numGadget, 0L, 0L, 0L))
  432.         {
  433.             // detach the gadget list from the window,
  434.             //    and remove the gadget(s) associated with this object from the list
  435.                         
  436.             BreakGList(gadgetPtr, numGadget);
  437.             
  438.             UpdateLVConnect(nodePtr, TRUE);        // clear any current connections to the string gadg
  439.  
  440.             // re-attach the gadget list to the window
  441.             
  442.             if (!gEditMode)
  443.             {
  444.                 AddGList(gWindPtr, gGadgetContext, -1L, -1L, 0L);
  445.                 gGadgetsOn = TRUE;
  446.             }
  447.             
  448.             if ( ((GadgetObj *)nodePtr)->remKey )
  449.                 FreeRemember( &((GadgetObj *)nodePtr)->remKey, TRUE );
  450.         }
  451.         
  452.         RemLink( (void **) &gObjList, nodePtr);
  453.         DropMem( (void **) &nodePtr, nodePtr->numBytes );
  454.     }
  455. }
  456.  
  457. BOOL UpdateLVConnect(LinkNode *nodePtr, BOOL clearIt)
  458. {
  459.     ListViewObj    *listViewPtr;
  460.     
  461.     // determine if this gadget is attached to a current ListView.  If so, disconnect it.
  462.             
  463.     for (listViewPtr=gObjList; listViewPtr; listViewPtr=listViewPtr->next)
  464.     {
  465.         if (listViewPtr->type == OTYPE_ListView && listViewPtr->stringObj == nodePtr)
  466.         {
  467.             if (clearIt)
  468.                 listViewPtr->stringObj = 0L;
  469.             if (MakeGadget( (LinkNode *) listViewPtr) != 0)
  470.             {
  471.                 gSelObj = 0L;
  472.                 DisposeObj(nodePtr);
  473.                 return FALSE;
  474.             }
  475.         }
  476.     }
  477.     
  478.     return TRUE;
  479. }
  480.                 
  481. /*=======================================================================================*/
  482.  
  483. /*
  484.         MakeGadget    - return values    0 = All ok,  1 = object is not gadget type, or
  485.                                                 2 = allocations failed
  486. */
  487.  
  488. USHORT MakeGadget(LinkNode *nodePtr)
  489. {
  490.     struct NewGadget    ng;
  491.     Gadget                *gadgetPtr,
  492.                             *lastGadget;
  493.     Rect                    *rectPtr;
  494.     ULONG                    flags;
  495.     char                    *labelPtr;
  496.     USHORT                numGadget;
  497.     GadgetObj            *objPtr = (GadgetObj *) nodePtr;
  498.     BOOL                    disable;
  499.         
  500.     rectPtr = &objPtr->rect;
  501.  
  502.     if (!GetGadgetData(nodePtr, &gadgetPtr, &numGadget, &flags, &labelPtr, &disable))
  503.         return 1;
  504.  
  505.     memset(&ng, 0, sizeof(struct NewGadget));
  506.     
  507.     // remove this gadget from the windowlist and free its memory, if it exists
  508.     
  509.     BreakGList(gadgetPtr, numGadget);
  510.     
  511.     // set up the new gadget structure
  512.     
  513.     ng.ng_LeftEdge = rectPtr->minX;
  514.     ng.ng_TopEdge = rectPtr->minY;
  515.     ng.ng_Width = rectPtr->maxX - rectPtr->minX + 1;
  516.     ng.ng_Height = rectPtr->maxY - rectPtr->minY + 1;
  517.                 
  518.     ng.ng_TextAttr = &topaz8;
  519.     ng.ng_VisualInfo = gVI;
  520.     ng.ng_Flags = flags;
  521.     ng.ng_UserData = (APTR) nodePtr;
  522.  
  523.     ng.ng_GadgetID = 0;                    // nodePtr->itemNum;
  524.     ng.ng_GadgetText = labelPtr;
  525.                     
  526.     objPtr->disable = disable;
  527.  
  528.     lastGadget = LastGadget();
  529.  
  530.     switch (objPtr->type)
  531.     {
  532.         case OTYPE_Palette:
  533.             {
  534.                 PaletteObj    *newPalette = (PaletteObj *) objPtr;
  535.                 
  536.                 gadgetPtr = CreateGadget(PALETTE_KIND, lastGadget, &ng,
  537.                                                     GA_Disabled, gDisableAll || newPalette->disable,
  538.                                                     GTPA_Depth, newPalette->depth,
  539.                                                     GTPA_Color, newPalette->firstColor,
  540.                                                     GTPA_ColorOffset, newPalette->colorOffset,
  541.                                                     GTPA_IndicatorWidth, newPalette->indicatorWidth,
  542.                                                     GTPA_IndicatorHeight, newPalette->indicatorWidth,
  543.                                                     TAG_DONE);
  544.             }
  545.             break;
  546.         case OTYPE_String:
  547.             {
  548.                 StringObj    *newString = (StringObj *) objPtr;
  549.                 
  550.                 gadgetPtr = CreateGadget(STRING_KIND, lastGadget, &ng,
  551.                                                     GA_Disabled, gDisableAll || newString->disable,
  552.                                                     GTST_String, newString->theChars,
  553.                                                     GTST_MaxChars, newString->maxChars,
  554.                                                     TAG_DONE);
  555.             }
  556.             break;
  557.         case OTYPE_ListView:
  558.             {
  559.                 ListViewObj    *newListView = (ListViewObj *) objPtr;
  560.                 Gadget        *tempPtr = 0L;
  561.                 
  562.                 if (newListView->stringObj && newListView->stringObj->gadget &&
  563.                         NodeNum(&gObjList, (LinkNode *) newListView->stringObj) != -1)
  564.                     tempPtr = newListView->stringObj->gadget;
  565.                 else
  566.                     newListView->stringObj = 0L;
  567.  
  568.                 gadgetPtr = CreateGadget(LISTVIEW_KIND, lastGadget, &ng,
  569. //                                                    GA_Disabled, gDisableAll || newListView->disable,
  570.                                                     GTLV_Top, newListView->topItem,
  571.                                                     GTLV_Labels, &newListView->itemList,
  572.                                                     GTLV_ReadOnly, newListView->readOnly,
  573.                                                     GTLV_ScrollWidth, newListView->scrollWidth,
  574.                                                     GTLV_ShowSelected, tempPtr,
  575.                                                     GTLV_Selected, newListView->selectedItem,
  576.                                                     LAYOUTA_SPACING, newListView->extraSpacing,
  577.                                                     TAG_DONE);
  578.                 
  579.             }
  580.             break;
  581.         case OTYPE_Button:
  582.             {
  583.                 ButtonObj    *newButton = (ButtonObj *) objPtr;
  584.                 
  585.                 gadgetPtr = CreateGadget(BUTTON_KIND, lastGadget, &ng,
  586.                                                         GA_Disabled, gDisableAll || newButton->disable,
  587.                                                         TAG_DONE);
  588.             }
  589.             break;
  590.         case OTYPE_Slider:
  591.             {
  592.                 SliderObj    *newSlider = (SliderObj *) objPtr;
  593.                 
  594.                 gadgetPtr = CreateGadget(SLIDER_KIND, lastGadget, &ng,
  595.                                                         GA_Disabled, gDisableAll || newSlider->disable,
  596.                                                         GTSL_Min, newSlider->minLevel,
  597.                                                         GTSL_Max, newSlider->maxLevel,
  598.                                                         GTSL_Level, newSlider->currentLevel,
  599.                                                         GTSL_MaxLevelLen, newSlider->maxChars,
  600.                                                         GTSL_LevelFormat, newSlider->format,
  601.                                                         GTSL_LevelPlace, newSlider->levelPlace,
  602.                                                         GA_IMMEDIATE, newSlider->immediateMsg,
  603.                                                         GA_RELVERIFY, newSlider->releaseMsg,
  604.                                                         PGA_FREEDOM, newSlider->orientation,
  605.                                                         TAG_DONE);
  606.             }
  607.             break;
  608.         case OTYPE_Scroller:
  609.             {
  610.                 ScrollerObj        *newScroller = (ScrollerObj *) objPtr;
  611.                 
  612.                 gadgetPtr = CreateGadget(SCROLLER_KIND, lastGadget, &ng,
  613.                                                         GA_Disabled, gDisableAll || newScroller->disable,
  614.                                                         GTSC_Top, newScroller->topItem,
  615.                                                         GTSC_Total, newScroller->totalItems,
  616.                                                         GTSC_Visible, newScroller->visibleItems,
  617.                                                         GTSC_Arrows, newScroller->arrowSize,
  618.                                                         PGA_FREEDOM, newScroller->orientation,
  619.                                                         GA_IMMEDIATE, newScroller->immediateMsg,
  620.                                                         GA_RELVERIFY, newScroller->releaseMsg,
  621.                                                         TAG_DONE);
  622.             }
  623.             break;
  624.         case OTYPE_Cycle:
  625.             {
  626.                 CycleObj    *newCycle = (CycleObj *) objPtr;
  627.                 
  628.                 gadgetPtr = CreateGadget(CYCLE_KIND, lastGadget, &ng,
  629.                                                         GA_Disabled, gDisableAll || newCycle->disable,
  630.                                                         GTCY_Labels, newCycle->textLabels,
  631.                                                         GTCY_Active, newCycle->activeItem,
  632.                                                         TAG_DONE);
  633.             }
  634.             break;
  635.         case OTYPE_MX:
  636.             {
  637.                 MXObj        *newMX = (MXObj *) objPtr;
  638.                 
  639.                 gadgetPtr = CreateGadget(MX_KIND, lastGadget, &ng,
  640.                                                         GA_Disabled, gDisableAll || newMX->disable,
  641.                                                         GTMX_Labels, newMX->textLabels,
  642.                                                         GTMX_Active, newMX->activeItem,
  643.                                                         GTMX_Spacing, newMX->extraSpacing,
  644.                                                         TAG_DONE);
  645.             }
  646.             break;
  647.         case OTYPE_CheckBox:
  648.             {
  649.                 CheckBoxObj        *newCheckBox = (CheckBoxObj *) objPtr;
  650.                 
  651.                 gadgetPtr = CreateGadget(CHECKBOX_KIND, lastGadget, &ng,
  652.                                                         GA_Disabled, gDisableAll || newCheckBox->disable,
  653.                                                         GTCB_Checked, newCheckBox->checked,
  654.                                                         TAG_DONE);
  655.             }
  656.             break;
  657.         case OTYPE_Text:
  658.             {
  659.                 TextObj        *newText = (TextObj *) objPtr;
  660.                 
  661.                 ng.ng_GadgetText = 0L;                                            //text obj has no label
  662. /*
  663.                 newText->rect.maxX = newText->rect.minX +
  664.                         TextLength(gWindPtr->RPort, newText->label, strlen(newText->label));
  665. */
  666.                 gadgetPtr = CreateGadget(TEXT_KIND, lastGadget, &ng,
  667.                                                         GA_Disabled, gDisableAll || newText->disable,
  668.                                                         GTTX_Text, newText->label,
  669.                                                         GTTX_CopyText, newText->copyText,
  670.                                                         GTTX_Border, newText->border,
  671.                                                         TAG_DONE);
  672.             }
  673.             break;
  674.     }
  675.  
  676.     if (gadgetPtr)
  677.             CountGadgets( lastGadget, &objPtr->topGadget, &objPtr->numGadget );
  678.  
  679.     objPtr->gadget = gadgetPtr;
  680.  
  681.     if (!gEditMode)
  682.     {
  683.         AddGList(gWindPtr, gGadgetContext, -1L, -1L, 0L);
  684.         gGadgetsOn = TRUE;
  685.     }
  686.     
  687.     //    In order to be able to drag the object around without
  688.     //    interference by its gadgets, we need to actually disable the entire group
  689.     // of gadgets associated with the object.  The GA_Disabled flag only causes some
  690.     // of the gadgets to be disabled.  Therefore, we just go in and do it manually.
  691.  
  692. //    gEditMode = !gEditMode;  // DoDisable will swap this flag back to original state
  693. //    DoDisable(0);
  694.  
  695. //    if (gadgetPtr)
  696. //        RefreshGList(gadgetPtr, gWindPtr, NULL, 1L);
  697.                 
  698. //    GT_RefreshWindow(gWindPtr, NULL);
  699.     
  700.     if (gadgetPtr)
  701.         return 0;
  702.     else
  703.         return 2;
  704. }
  705.  
  706. /* ===================================================================================== */
  707.  
  708. void CountGadgets( Gadget *lastGadget, Gadget **topGadget, USHORT *numGadget )
  709. {
  710.     Gadget    *tempPtr;
  711.     USHORT    gadCount = 0;
  712.     
  713.     // count the number of gadgets that CreateGadget() added to the list
  714.     // so we know how to deal with them later
  715.         
  716.     *topGadget = lastGadget->NextGadget;
  717.         
  718.     for (tempPtr=*topGadget; tempPtr; tempPtr=tempPtr->NextGadget)
  719.             gadCount++;
  720.     
  721.     *numGadget = gadCount;
  722. }
  723.                 
  724. /* ===================================================================================== */
  725.  
  726. void DoDisable(USHORT code)
  727. {
  728.     LinkNode *nodePtr;
  729.     Gadget    *gadgetPtr;
  730.     USHORT    i, numGadget;
  731.     BOOL        disable;
  732.     
  733. //    gEditMode = !gEditMode;
  734.     
  735.     if (!gGadgetsOn)
  736.     {
  737.         AddGList(gWindPtr, gGadgetContext, -1L, -1L, 0L);
  738.         gGadgetsOn = TRUE;
  739.     }
  740.  
  741.     gDisableAll = !gDisableAll;
  742.  
  743.     for (nodePtr=gObjList; nodePtr; nodePtr=nodePtr->next)
  744.     {
  745.         GetGadgetData(nodePtr, &gadgetPtr, &numGadget, 0L, 0L, &disable);
  746.         
  747.         if (gadgetPtr)
  748.         {
  749.             for (i=0; i<numGadget && gadgetPtr; i++, gadgetPtr=gadgetPtr->NextGadget)
  750.             {
  751.                 if (gadgetPtr && (gDisableAll || disable))
  752.                     OffGadget(gadgetPtr, gWindPtr, 0L);
  753.                 else if (gadgetPtr)
  754.                     OnGadget(gadgetPtr, gWindPtr, 0L);
  755.             }
  756.         }
  757.     }
  758.     
  759.     if (gGadgetsOn && !gEditMode)
  760.     {
  761.         RemoveGList(gWindPtr, gGadgetContext, -1L);
  762.         gGadgetsOn = FALSE;
  763.     }
  764.     
  765. //    if (!gEditMode)    
  766. //        gSelObj = 0L;    //    Just in case a gadget is currently selected
  767.         
  768.     ReDraw();
  769. }
  770.  
  771. BOOL GetGadgetData(LinkNode *nodePtr, Gadget **firstGadget, USHORT *numGadget, ULONG *flags,
  772.                             char **labelPtr, BOOL *disable)
  773. {
  774.     switch (nodePtr->type)
  775.     {
  776.         case OTYPE_Button:
  777.         case OTYPE_String:
  778.         case OTYPE_Palette:
  779.         case OTYPE_CheckBox:
  780.         case OTYPE_Cycle:
  781.         case OTYPE_ListView:
  782.         case OTYPE_MX:
  783.         case OTYPE_Scroller:
  784.         case OTYPE_Slider:
  785.         case OTYPE_Text:
  786.             if (firstGadget)
  787.                 *firstGadget = ( (GadgetObj *) nodePtr)->topGadget;
  788.             if (numGadget)
  789.                 *numGadget = ( (GadgetObj *) nodePtr)->numGadget;
  790.             if (flags)
  791.                 *flags = ( (GadgetObj *) nodePtr)->flags;
  792.             if (labelPtr)
  793.                 *labelPtr = ( (GadgetObj *) nodePtr)->label;
  794.             if (disable)
  795.                 *disable = ( (GadgetObj *) nodePtr)->disable;
  796.             break;
  797.         default:
  798.             if (firstGadget)
  799.                 *firstGadget = 0L;
  800.             if (numGadget)
  801.                 *numGadget = 0;
  802.             if (flags)
  803.                 *flags = 0L;
  804.             if (labelPtr)
  805.                 *labelPtr = 0L;
  806.             if (disable)
  807.                 *disable = FALSE;
  808.             return FALSE;
  809.             break;
  810.     }
  811.     
  812.     return TRUE;
  813. }
  814.     
  815. /* ===================================================================================== */
  816.  
  817. void DoBringFront(USHORT code)
  818. {
  819.     if (gSelObj)
  820.     {
  821.         RemLink( (void **) &gObjList, gSelObj);
  822.         AddLink( (void **) &gObjList, gSelObj);
  823.         
  824.         ReDraw();
  825.     }
  826. }
  827.  
  828. /* ===================================================================================== */
  829.  
  830. void DoSendBack(USHORT code)
  831. {
  832.     if (gSelObj)
  833.     {
  834.         RemLink( (void **) &gObjList, gSelObj);
  835.         InsertLink( (void **) &gObjList, gSelObj, 0);
  836.     
  837.         ReDraw();
  838.     }
  839. }
  840.  
  841. /* ===================================================================================== */
  842.  
  843. /*
  844.         Find the last gadget in the linked list, so we can link to it
  845.         Note that this needs to be used only because it is possible that the last gadget
  846.         created could have been deleted (by the user).  Therefore, just saving the last
  847.         allocated gadget in a global won't do.
  848.  
  849. */
  850.  
  851. Gadget    *LastGadget()
  852. {
  853.     Gadget    *gadgetPtr;
  854.     
  855.     Forbid();        // just to be safe
  856.     
  857.     for (gadgetPtr=gGadgetContext; gadgetPtr; gadgetPtr=gadgetPtr->NextGadget)
  858.         if (!gadgetPtr->NextGadget)
  859.             break;
  860.     
  861.     Permit();        // we must be friendly!
  862.     
  863.     return gadgetPtr;
  864. }
  865.  
  866. /*
  867.     BreakGList - Disconnect the gadgets from the window, and remove the specified gadget group
  868.                         from the linked-list.  This routine leaves the gadget list disconnected from
  869.                         the window.
  870. */
  871.  
  872. BOOL BreakGList(Gadget *theGadget, USHORT numGadget)
  873. {
  874.     USHORT        pos, i;
  875.     Gadget        *gadgetPtr, *endGadget;
  876.     
  877.     if (gGadgetsOn)
  878.     {
  879.         pos = RemoveGList(gWindPtr, gGadgetContext, -1L);
  880.         gGadgetsOn = FALSE;
  881.     }
  882.     
  883.     if (theGadget)
  884.     {
  885.         // Walk the gadgetlist & find where this gadget is linked in
  886.     
  887.         for (gadgetPtr=gGadgetContext; gadgetPtr; gadgetPtr=gadgetPtr->NextGadget)
  888.         {
  889.             if (gadgetPtr->NextGadget == theGadget)
  890.             {
  891.                 // now find the end of the gadget grouping that we are going to remove from
  892.                 //    the linked list
  893.                 
  894.                 endGadget = theGadget;
  895.                 for (i=1; i<numGadget; i++)
  896.                     if (endGadget->NextGadget)
  897.                         endGadget = endGadget->NextGadget;
  898.             
  899.                 // now, remove the whole group from the linked-list
  900.                 //    (at this point, theGadget is the first gadget in the group, and
  901.                 //        endGadget is the last gadget in the group)
  902.     
  903.                 gadgetPtr->NextGadget = endGadget->NextGadget;
  904.                 endGadget->NextGadget = 0L;
  905.                 break;
  906.             }
  907.         }
  908.         
  909.         // Free up the memory for the gadget group
  910.     
  911.         FreeGadgets(theGadget);
  912.         
  913.         return TRUE;
  914.     }
  915.     
  916.     return FALSE;
  917. }
  918.  
  919.