home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / XfeWidgets / Xfe / ToolBox.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  69.4 KB  |  2,745 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /*-----------------------------------------*/
  19. /*                                                                        */
  20. /* Name:        <Xfe/ToolBox.c>                                            */
  21. /* Description:    XfeToolBox widget source.                                */
  22. /* Author:        Ramiro Estrugo <ramiro@netscape.com>                    */
  23. /*                                                                        */
  24. /*----------------------------------------------------------------------*/
  25.  
  26.  
  27. #include <stdio.h>
  28.  
  29. #include <Xfe/ToolBoxP.h>
  30. #include <Xfe/Button.h>
  31. #include <Xfe/Tab.h>
  32. #include <Xm/Form.h>
  33.  
  34. #define MESSAGE1 "Widget is not an XfeToolBox."
  35. #define MESSAGE2 "XmNitemCount is a read-only resource."
  36. #define MESSAGE3 "XfeToolBox can only have XfeToolItem childred."
  37. #define MESSAGE4 "XmNswapThreshold is to large."
  38. #define MESSAGE5 "XmNpositionIndex out of range for %s"
  39. #define MESSAGE6 "XmNclosedTabs is a read-only resource."
  40. #define MESSAGE7 "XmNopenedTabs is a read-only resource."
  41.  
  42. #define OPENED_TAB_BUTTON_NAME            "Tab"
  43. #define CLOSED_TAB_BUTTON_NAME            "Tab"
  44.  
  45. #define DRAG_EVENTS (ButtonPressMask | ButtonReleaseMask | Button1MotionMask)
  46.  
  47. #define DIRECTION_NONE        0
  48. #define DIRECTION_DOWN        1
  49. #define DIRECTION_UP        -1
  50.  
  51. #define CHECK_RANGE(tp,i) \
  52. ( ( (i) >= 0 ) && ( i < (tp) -> item_count ) )
  53.  
  54. #define IS_OUR_TAB(w,child) \
  55. (XfeIsTab(child) && (_XfeParent(child) == w))
  56.  
  57. #define _XfeSwap(_x,_y,_t)                        \
  58. {                                                \
  59.     _t __tmp__ = _x;                            \
  60.                                                 \
  61.     _x = _y;                                    \
  62.     _y = __tmp__;                                \
  63. }
  64.  
  65. /*----------------------------------------------------------------------*/
  66. /*                                                                        */
  67. /* Core class methods                                                    */
  68. /*                                                                        */
  69. /*----------------------------------------------------------------------*/
  70. static void     Initialize        (Widget,Widget,ArgList,Cardinal *);
  71. static void     Destroy            (Widget);
  72. static Boolean    SetValues        (Widget,Widget,Widget,ArgList,Cardinal *);
  73.  
  74. /*----------------------------------------------------------------------*/
  75. /*                                                                        */
  76. /* Constraint Class Methods                                                */
  77. /*                                                                        */
  78. /*----------------------------------------------------------------------*/
  79. static void            ConstraintInitialize    (Widget,Widget,ArgList,Cardinal *);
  80. static Boolean        ConstraintSetValues        (Widget,Widget,Widget,ArgList,
  81.                                              Cardinal *);
  82.  
  83. /*----------------------------------------------------------------------*/
  84. /*                                                                        */
  85. /* XfeManager class methods                                                */
  86. /*                                                                        */
  87. /*----------------------------------------------------------------------*/
  88. static void        PreferredGeometry    (Widget,Dimension *,Dimension *);
  89. static void        MinimumGeometry    (Widget,Dimension *,Dimension *);
  90. static void        LayoutComponents    (Widget);
  91. static void        LayoutChildren        (Widget);
  92. static Boolean    AcceptChild            (Widget);
  93. static Boolean    DeleteChild            (Widget);
  94. static Boolean    InsertChild            (Widget);
  95.  
  96. /*----------------------------------------------------------------------*/
  97. /*                                                                        */
  98. /* Misc XfeToolBox functions                                            */
  99. /*                                                                        */
  100. /*----------------------------------------------------------------------*/
  101. static Widget        CreateTab                (Widget,Boolean);
  102. static Cardinal        ActiveItemCount            (Widget);
  103. static Dimension    MaxItemWidth            (Widget);
  104. static int            ItemToIndex                (Widget);
  105. static int            TabToIndex                (Widget);
  106. static void            CheckSwapThreshold        (Widget);
  107.  
  108.  
  109. static void            DragStart                (Widget,XEvent *,int,int);
  110. static void            DragEnd                    (Widget,XEvent *,int,int);
  111. static void            DragMotion                (Widget,XEvent *,int,int);
  112.  
  113. static Boolean        MoveItem                (Widget,Cardinal,int);
  114. static int            MaxItemY                (Widget);
  115. static void            SwapItems                (Widget,int,int);
  116.  
  117.  
  118. static void            RaiseItem                (Widget,int);
  119.  
  120.  
  121. static int            FindItemUnder            (Widget,int);
  122. static Boolean        ItemOverItem            (Widget,int,int,Dimension);
  123. static void            SnapItemInPlace            (Widget,int);
  124.  
  125.  
  126. static int            FirstManagedIndex        (Widget);
  127. static int            LastManagedIndex        (Widget);
  128. static int            NextManagedIndex        (Widget,int);
  129. static int            PreviousManagedIndex    (Widget,int);
  130.  
  131. static void            InvokeSwapCallbacks        (Widget,XEvent *,Widget,
  132.                                              Widget,int,int);
  133. static void            InvokeCallbacks            (Widget,XtCallbackList,int,
  134.                                              XEvent *,Widget,Widget,Widget,int);
  135. static void            UpdatePositionIndeces    (Widget);
  136.  
  137. /*----------------------------------------------------------------------*/
  138. /*                                                                        */
  139. /* Child functions                                                        */
  140. /*                                                                        */
  141. /*----------------------------------------------------------------------*/
  142. static void            ChildSetDraggable        (Widget,Widget,Boolean);
  143.  
  144. /*----------------------------------------------------------------------*/
  145. /*                                                                        */
  146. /* Item functions                                                        */
  147. /*                                                                        */
  148. /*----------------------------------------------------------------------*/
  149. static void            UpdateItems                (Widget);
  150. static void            UpdatePixmaps            (Widget);
  151.  
  152. /*----------------------------------------------------------------------*/
  153. /*                                                                        */
  154. /* TaskBar callbacks                                                    */
  155. /*                                                                        */
  156. /*----------------------------------------------------------------------*/
  157. static void    TabActivateCB                (Widget,XtPointer,XtPointer);
  158. static void    TabArmCB                    (Widget,XtPointer,XtPointer);
  159. static void    TabDisarmCB                    (Widget,XtPointer,XtPointer);
  160.  
  161. /*----------------------------------------------------------------------*/
  162. /*                                                                        */
  163. /* Descendant event handlers                                            */
  164. /*                                                                        */
  165. /*----------------------------------------------------------------------*/
  166. static void    DescendantEH        (Widget,XtPointer,XEvent *,Boolean *);
  167.  
  168. /*----------------------------------------------------------------------*/
  169. /*                                                                        */
  170. /* XfeToolBox Resources                                                    */
  171. /*                                                                        */
  172. /*----------------------------------------------------------------------*/
  173. static XtResource resources[] =     
  174. {                    
  175.     /* Callback resources */         
  176.     { 
  177.         XmNcloseCallback,
  178.         XmCCallback,
  179.         XmRCallback,
  180.         sizeof(XtCallbackList),
  181.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . close_callback),
  182.         XmRImmediate, 
  183.         (XtPointer) NULL
  184.     },
  185.     { 
  186.         XmNopenCallback,
  187.         XmCCallback,
  188.         XmRCallback,
  189.         sizeof(XtCallbackList),
  190.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . open_callback),
  191.         XmRImmediate, 
  192.         (XtPointer) NULL
  193.     },
  194.     { 
  195.         XmNdragAllowCallback,
  196.         XmCCallback,
  197.         XmRCallback,
  198.         sizeof(XtCallbackList),
  199.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . drag_allow_callback),
  200.         XmRImmediate, 
  201.         (XtPointer) NULL
  202.     },
  203.     { 
  204.         XmNdragStartCallback,
  205.         XmCCallback,
  206.         XmRCallback,
  207.         sizeof(XtCallbackList),
  208.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . drag_start_callback),
  209.         XmRImmediate, 
  210.         (XtPointer) NULL
  211.     },
  212.     { 
  213.         XmNdragEndCallback,
  214.         XmCCallback,
  215.         XmRCallback,
  216.         sizeof(XtCallbackList),
  217.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . drag_end_callback),
  218.         XmRImmediate, 
  219.         (XtPointer) NULL
  220.     },
  221.     { 
  222.         XmNdragMotionCallback,
  223.         XmCCallback,
  224.         XmRCallback,
  225.         sizeof(XtCallbackList),
  226.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . drag_motion_callback),
  227.         XmRImmediate, 
  228.         (XtPointer) NULL
  229.     },
  230.     { 
  231.         XmNnewItemCallback,
  232.         XmCCallback,
  233.         XmRCallback,
  234.         sizeof(XtCallbackList),
  235.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . new_item_callback),
  236.         XmRImmediate, 
  237.         (XtPointer) NULL
  238.     },
  239.     { 
  240.         XmNswapCallback,
  241.         XmCCallback,
  242.         XmRCallback,
  243.         sizeof(XtCallbackList),
  244.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . swap_callback),
  245.         XmRImmediate, 
  246.         (XtPointer) NULL
  247.     },
  248.     { 
  249.         XmNsnapCallback,
  250.         XmCCallback,
  251.         XmRCallback,
  252.         sizeof(XtCallbackList),
  253.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . snap_callback),
  254.         XmRImmediate, 
  255.         (XtPointer) NULL
  256.     },
  257.  
  258.  
  259.     /* Item resources */
  260.     { 
  261.         XmNitems,
  262.         XmCReadOnly,
  263.         XmRWidgetList,
  264.         sizeof(WidgetList),
  265.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . items),
  266.         XmRImmediate, 
  267.         (XtPointer) NULL
  268.     },
  269.     { 
  270.         XmNitemCount,
  271.         XmCReadOnly,
  272.         XmRCardinal,
  273.         sizeof(Cardinal),
  274.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . item_count),
  275.         XmRImmediate, 
  276.         (XtPointer) 0
  277.     },
  278.  
  279.     /* Tab resources */
  280.     { 
  281.         XmNclosedTabs,
  282.         XmCReadOnly,
  283.         XmRWidgetList,
  284.         sizeof(WidgetList),
  285.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . closed_tabs),
  286.         XmRImmediate, 
  287.         (XtPointer) NULL
  288.     },
  289.     { 
  290.         XmNopenedTabs,
  291.         XmCReadOnly,
  292.         XmRWidgetList,
  293.         sizeof(WidgetList),
  294.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . opened_tabs),
  295.         XmRImmediate, 
  296.         (XtPointer) NULL
  297.     },
  298.     { 
  299.         XmNtabOffset,
  300.         XmCOffset,
  301.         XmRHorizontalDimension,
  302.         sizeof(Dimension),
  303.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . tab_offset),
  304.         XmRImmediate, 
  305.         (XtPointer) 10
  306.     },
  307.  
  308.     /* Spacing resources */
  309.     { 
  310.         XmNverticalSpacing,
  311.         XmCSpacing,
  312.         XmRVerticalDimension,
  313.         sizeof(Dimension),
  314.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . vertical_spacing),
  315.         XmRImmediate, 
  316.         (XtPointer) 0
  317.     },
  318.     { 
  319.         XmNhorizontalSpacing,
  320.         XmCSpacing,
  321.         XmRHorizontalDimension,
  322.         sizeof(Dimension),
  323.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . horizontal_spacing),
  324.         XmRImmediate, 
  325.         (XtPointer) 0
  326.     },
  327.  
  328.  
  329.     /* Drag resources */
  330.     { 
  331.         XmNdragCursor,
  332.         XmCDragCursor,
  333.         XmRCursor,
  334.         sizeof(Widget),
  335.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . drag_cursor),
  336.         XmRString, 
  337.         XfeDEFAULT_TOOL_BOX_DRAG_CURSOR
  338.     },
  339.     { 
  340.         XmNdragButton,
  341.         XmCDragButton,
  342.         XmRInt,
  343.         sizeof(int),
  344.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . drag_button),
  345.         XmRImmediate, 
  346.         (XtPointer) Button1
  347.     },
  348.     { 
  349.         XmNdragThreshold,
  350.         XmCDragThreshold,
  351.         XmRVerticalDimension,
  352.         sizeof(Dimension),
  353.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . drag_threshold),
  354.         XmRImmediate, 
  355.         (XtPointer) 10
  356.     },
  357.  
  358.     /* Swap resources */
  359.     { 
  360.         XmNswapThreshold,
  361.         XmCSwapThreshold,
  362.         XmRVerticalDimension,
  363.         sizeof(Dimension),
  364.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . swap_threshold),
  365.         XmRImmediate, 
  366.         (XtPointer) 10
  367.     },
  368.  
  369.     /* Pixmap resources */
  370.     { 
  371.         XmNbottomPixmap,
  372.         XmCBottomPixmap,
  373.         XmRPixmap,
  374.         sizeof(Pixmap),
  375.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . bottom_pixmap),
  376.         XmRImmediate, 
  377.         (XtPointer) XmUNSPECIFIED_PIXMAP
  378.     },
  379.     { 
  380.         XmNhorizontalPixmap,
  381.         XmCHorizontalPixmap,
  382.         XmRPixmap,
  383.         sizeof(Pixmap),
  384.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . horizontal_pixmap),
  385.         XmRImmediate, 
  386.         (XtPointer) XmUNSPECIFIED_PIXMAP
  387.     },
  388.     { 
  389.         XmNleftPixmap,
  390.         XmCLeftPixmap,
  391.         XmRPixmap,
  392.         sizeof(Pixmap),
  393.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . left_pixmap),
  394.         XmRImmediate, 
  395.         (XtPointer) XmUNSPECIFIED_PIXMAP
  396.     },
  397.     { 
  398.         XmNrightPixmap,
  399.         XmCRightPixmap,
  400.         XmRPixmap,
  401.         sizeof(Pixmap),
  402.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . right_pixmap),
  403.         XmRImmediate, 
  404.         (XtPointer) XmUNSPECIFIED_PIXMAP
  405.     },
  406.     { 
  407.         XmNtopPixmap,
  408.         XmCTopPixmap,
  409.         XmRPixmap,
  410.         sizeof(Pixmap),
  411.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . top_pixmap),
  412.         XmRImmediate, 
  413.         (XtPointer) XmUNSPECIFIED_PIXMAP
  414.     },
  415.     { 
  416.         XmNverticalPixmap,
  417.         XmCVerticalPixmap,
  418.         XmRPixmap,
  419.         sizeof(Pixmap),
  420.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . vertical_pixmap),
  421.         XmRImmediate, 
  422.         (XtPointer) XmUNSPECIFIED_PIXMAP
  423.     },
  424.     { 
  425.         XmNbottomRaisedPixmap,
  426.         XmCBottomRaisedPixmap,
  427.         XmRPixmap,
  428.         sizeof(Pixmap),
  429.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . bottom_raised_pixmap),
  430.         XmRImmediate, 
  431.         (XtPointer) XmUNSPECIFIED_PIXMAP
  432.     },
  433.     { 
  434.         XmNhorizontalRaisedPixmap,
  435.         XmCHorizontalRaisedPixmap,
  436.         XmRPixmap,
  437.         sizeof(Pixmap),
  438.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . horizontal_raised_pixmap),
  439.         XmRImmediate, 
  440.         (XtPointer) XmUNSPECIFIED_PIXMAP
  441.     },
  442.     { 
  443.         XmNleftRaisedPixmap,
  444.         XmCLeftRaisedPixmap,
  445.         XmRPixmap,
  446.         sizeof(Pixmap),
  447.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . left_raised_pixmap),
  448.         XmRImmediate, 
  449.         (XtPointer) XmUNSPECIFIED_PIXMAP
  450.     },
  451.     { 
  452.         XmNrightRaisedPixmap,
  453.         XmCRightRaisedPixmap,
  454.         XmRPixmap,
  455.         sizeof(Pixmap),
  456.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . right_raised_pixmap),
  457.         XmRImmediate, 
  458.         (XtPointer) XmUNSPECIFIED_PIXMAP
  459.     },
  460.     { 
  461.         XmNtopRaisedPixmap,
  462.         XmCTopRaisedPixmap,
  463.         XmRPixmap,
  464.         sizeof(Pixmap),
  465.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . top_raised_pixmap),
  466.         XmRImmediate, 
  467.         (XtPointer) XmUNSPECIFIED_PIXMAP
  468.     },
  469.     { 
  470.         XmNverticalRaisedPixmap,
  471.         XmCVerticalRaisedPixmap,
  472.         XmRPixmap,
  473.         sizeof(Pixmap),
  474.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . vertical_raised_pixmap),
  475.         XmRImmediate, 
  476.         (XtPointer) XmUNSPECIFIED_PIXMAP
  477.     },
  478.  
  479.     /* Force XmNusePreferredHeight to True and XmNusePreferredWidth to False */
  480.     {
  481.         XmNusePreferredHeight,
  482.         XmCUsePreferredHeight,
  483.         XmRBoolean,
  484.         sizeof(Boolean),
  485.         XtOffsetOf(XfeToolBoxRec , xfe_manager . use_preferred_height),
  486.         XmRImmediate, 
  487.         (XtPointer) True
  488.     },
  489.     {
  490.         XmNusePreferredWidth,
  491.         XmCUsePreferredWidth,
  492.         XmRBoolean,
  493.         sizeof(Boolean),
  494.         XtOffsetOf(XfeToolBoxRec , xfe_manager . use_preferred_width),
  495.         XmRImmediate, 
  496.         (XtPointer) False
  497.     },
  498. };   
  499.  
  500. /*----------------------------------------------------------------------*/
  501. /*                                                                        */
  502. /* XfeBoxBar Synthetic Resources                                        */
  503. /*                                                                        */
  504. /*----------------------------------------------------------------------*/
  505. static XmSyntheticResource syn_resources[] =
  506. {
  507.     { 
  508.         XmNverticalSpacing,
  509.         sizeof(Dimension),
  510.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . vertical_spacing),
  511.         _XmFromVerticalPixels,
  512.         _XmToVerticalPixels 
  513.     },
  514.     { 
  515.         XmNhorizontalSpacing,
  516.         sizeof(Dimension),
  517.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . horizontal_spacing),
  518.         _XmFromHorizontalPixels,
  519.         _XmToHorizontalPixels 
  520.     },
  521.     { 
  522.         XmNswapThreshold,
  523.         sizeof(Dimension),
  524.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . swap_threshold),
  525.         _XmFromVerticalPixels,
  526.         _XmToVerticalPixels 
  527.     },
  528.     { 
  529.         XmNdragThreshold,
  530.         sizeof(Dimension),
  531.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . drag_threshold),
  532.         _XmFromVerticalPixels,
  533.         _XmToVerticalPixels 
  534.     },
  535.     { 
  536.          XmNtabOffset,
  537.         sizeof(Dimension),
  538.         XtOffsetOf(XfeToolBoxRec , xfe_tool_box . tab_offset),
  539.         _XmFromHorizontalPixels,
  540.         _XmToHorizontalPixels 
  541.     },
  542. };
  543.  
  544. /*----------------------------------------------------------------------*/
  545. /*                                                                        */
  546. /* XfeToolBox constraint resources                                        */
  547. /*                                                                        */
  548. /*----------------------------------------------------------------------*/
  549. static XtResource constraint_resources[] = 
  550. {
  551.     { 
  552.         XmNopen,
  553.         XmCOpen,
  554.         XmRBoolean,
  555.         sizeof(Boolean),
  556.         XtOffsetOf(XfeToolBoxConstraintRec , xfe_tool_box . open),
  557.         XmRImmediate,
  558.         (XtPointer) True
  559.     },
  560. };   
  561.  
  562. /*----------------------------------------------------------------------*/
  563. /*                                                                        */
  564. /* Widget Class Record Initialization                                   */
  565. /*                                                                        */
  566. /*----------------------------------------------------------------------*/
  567. _XFE_WIDGET_CLASS_RECORD(toolbox,ToolBox) =
  568. {
  569.     {
  570.         (WidgetClass) &xfeManagerClassRec,        /* superclass           */
  571.         "XfeToolBox",                            /* class_name           */
  572.         sizeof(XfeToolBoxRec),                    /* widget_size          */
  573.         NULL,                                    /* class_initialize     */
  574.         NULL,                                    /* class_part_initialize*/
  575.         FALSE,                                  /* class_inited         */
  576.         Initialize,                             /* initialize           */
  577.         NULL,                                   /* initialize_hook      */
  578.         XtInheritRealize,                        /* realize              */
  579.         NULL,                                    /* actions              */
  580.         0,                                        /* num_actions            */
  581.         resources,                              /* resources            */
  582.         XtNumber(resources),                    /* num_resources        */
  583.         NULLQUARK,                              /* xrm_class            */
  584.         TRUE,                                   /* compress_motion      */
  585.         XtExposeCompressMaximal,                /* compress_exposure    */
  586.         TRUE,                                   /* compress_enterleave    */
  587.         FALSE,                                  /* visible_interest     */
  588.         Destroy,                                /* destroy              */
  589.         XtInheritResize,                        /* resize               */
  590.         XtInheritExpose,                        /* expose               */
  591.         SetValues,                              /* set_values           */
  592.         NULL,                                   /* set_values_hook      */
  593.         XtInheritSetValuesAlmost,                /* set_values_almost    */
  594.         NULL,                                    /* get_values_hook        */
  595.         NULL,                                   /* accexfe_focus         */
  596.         XtVersion,                              /* version              */
  597.         NULL,                                   /* callback_private     */
  598.         XtInheritTranslations,                    /* tm_table                */
  599.         XtInheritQueryGeometry,                    /* query_geometry       */
  600.         XtInheritDisplayAccelerator,            /* display accel        */
  601.         NULL,                                   /* extension            */
  602.     },
  603.  
  604.     /* Composite Part */
  605.     {
  606.         XtInheritGeometryManager,                /* geometry_manager        */
  607.         XtInheritChangeManaged,                    /* change_managed        */
  608.         XtInheritInsertChild,                    /* insert_child            */
  609.         XtInheritDeleteChild,                    /* delete_child            */
  610.         NULL                                    /* extension            */
  611.     },
  612.  
  613.     /* Constraint Part */
  614.     {
  615.         constraint_resources,                    /* constraint res        */
  616.         XtNumber(constraint_resources),            /* num constraint res    */
  617.         sizeof(XfeToolBoxConstraintRec),        /* constraint size         */
  618.         ConstraintInitialize,                    /* init proc            */
  619.         NULL,                                   /* destroy proc            */
  620.         ConstraintSetValues,                    /* set values proc        */
  621.         NULL,                                   /* extension               */
  622.     },
  623.  
  624.     /* XmManager Part */
  625.     {
  626.         XtInheritTranslations,                    /* tm_table                */
  627.         syn_resources,                            /* syn resources        */
  628.         XtNumber(syn_resources),                /* num syn_resources    */
  629.         NULL,                                   /* syn_cont_resources      */
  630.         0,                                      /* num_syn_cont_resource*/
  631.         XmInheritParentProcess,                 /* parent_process          */
  632.         NULL,                                   /* extension               */
  633.     },
  634.  
  635.     /* XfeManager Part     */
  636.     {
  637.         XfeInheritBitGravity,                    /* bit_gravity            */
  638.         PreferredGeometry,                        /* preferred_geometry    */
  639.         MinimumGeometry,                        /* minimum_geometry        */
  640.         XfeInheritUpdateRect,                    /* update_rect            */
  641.         AcceptChild,                            /* accept_child            */
  642.         InsertChild,                            /* insert_child            */
  643.         DeleteChild,                            /* delete_child            */
  644.         NULL,                                    /* change_managed        */
  645.         NULL,                                    /* prepare_components    */
  646.         LayoutComponents,                        /* layout_components    */
  647.         LayoutChildren,                            /* layout_children        */
  648.         NULL,                                    /* draw_background        */
  649.         XfeInheritDrawShadow,                    /* draw_shadow            */
  650.         NULL,                                    /* draw_components        */
  651.         NULL,                                    /* extension              */
  652.     },
  653.  
  654.     /* XfeToolBox Part */
  655.     {
  656.         NULL,                                    /* extension              */
  657.     },
  658. };
  659.  
  660. /*----------------------------------------------------------------------*/
  661. /*                                                                        */
  662. /* xfeToolBoxWidgetClass declaration.                                    */
  663. /*                                                                        */
  664. /*----------------------------------------------------------------------*/
  665. _XFE_WIDGET_CLASS(toolbox,ToolBox);
  666.  
  667. /*----------------------------------------------------------------------*/
  668. /*                                                                        */
  669. /* Core class methods                                                    */
  670. /*                                                                        */
  671. /*----------------------------------------------------------------------*/
  672. static void
  673. Initialize(Widget rw,Widget nw,ArgList args,Cardinal *nargs)
  674. {
  675.     XfeToolBoxPart *    tp = _XfeToolBoxPart(nw);
  676.  
  677.     /* Make sure read only resoures are not set */
  678.     if (tp->item_count > 0)
  679.     {
  680.         tp->item_count = 0;
  681.  
  682.         _XfeWarning(nw,MESSAGE2);
  683.     }
  684.  
  685.     if (tp->closed_tabs != NULL)
  686.     {
  687.         tp->closed_tabs = NULL;
  688.  
  689.         _XfeWarning(nw,MESSAGE7);
  690.     }
  691.  
  692.     if (tp->opened_tabs != NULL)
  693.     {
  694.         tp->opened_tabs = NULL;
  695.  
  696.         _XfeWarning(nw,MESSAGE7);
  697.     }
  698.  
  699.  
  700.     tp->last_moved_item        = NULL;
  701.  
  702.     tp->dragging_tab        = False;
  703.     tp->clicking_tab        = False;
  704.  
  705.     /* Finish of initialization */
  706.     _XfeManagerChainInitialize(rw,nw,xfeToolBoxWidgetClass);
  707. }
  708. /*----------------------------------------------------------------------*/
  709. static void
  710. Destroy(Widget w)
  711. {
  712.     XfeToolBoxPart * tp = _XfeToolBoxPart(w);
  713.  
  714.     /* Free the tabs if needed */
  715.     if (tp->closed_tabs)
  716.     {
  717.         XtFree((char *) tp->closed_tabs);
  718.     }
  719.  
  720.     if (tp->opened_tabs)
  721.     {
  722.         XtFree((char *) tp->opened_tabs);
  723.     }
  724.  
  725.     /* Free the items if needed */
  726.     if (tp->items)
  727.     {
  728.         XtFree((char *) tp->items);
  729.     }
  730. }
  731. /*----------------------------------------------------------------------*/
  732. static Boolean
  733. SetValues(Widget ow,Widget rw,Widget nw,ArgList args,Cardinal *nargs)
  734. {
  735.     XfeToolBoxPart *        np = _XfeToolBoxPart(nw);
  736.     XfeToolBoxPart *        op = _XfeToolBoxPart(ow);
  737.     Boolean                    update_pixmaps = False;
  738.  
  739.     /* item_count */
  740.     if (np->item_count != op->item_count)
  741.     {
  742.         np->item_count = op->item_count;
  743.  
  744.         _XfeWarning(nw,MESSAGE2);
  745.     }
  746.  
  747.     /* closed_tabs */
  748.     if (np->closed_tabs != op->closed_tabs)
  749.     {
  750.         np->closed_tabs = op->closed_tabs;
  751.  
  752.         _XfeWarning(nw,MESSAGE6);
  753.     }
  754.  
  755.     /* opened_tabs */
  756.     if (np->opened_tabs != op->opened_tabs)
  757.     {
  758.         np->opened_tabs = op->opened_tabs;
  759.  
  760.         _XfeWarning(nw,MESSAGE7);
  761.     }
  762.  
  763.     /* tab_offset */
  764.     if (np->tab_offset != op->tab_offset)
  765.     {
  766.         _XfemConfigFlags(nw) |= XfeConfigGLE;
  767.     }
  768.  
  769.     /* tab_offset */
  770.     if (np->tab_offset != op->tab_offset)
  771.     {
  772.         _XfemConfigFlags(nw) |= XfeConfigGLE;
  773.     }
  774.  
  775.     /* left_pixmap */
  776.     if ((np->left_pixmap                != op->left_pixmap) || 
  777.         (np->right_pixmap                != op->right_pixmap) || 
  778.         (np->top_pixmap                    != op->top_pixmap) || 
  779.         (np->bottom_pixmap                != op->bottom_pixmap) || 
  780.         (np->vertical_pixmap            != op->vertical_pixmap) || 
  781.         (np->horizontal_pixmap            != op->horizontal_pixmap) ||
  782.         (np->left_raised_pixmap            != op->left_raised_pixmap) || 
  783.         (np->right_raised_pixmap        != op->right_raised_pixmap) || 
  784.         (np->top_raised_pixmap            != op->top_raised_pixmap) || 
  785.         (np->bottom_raised_pixmap        != op->bottom_raised_pixmap) || 
  786.         (np->vertical_raised_pixmap        != op->vertical_raised_pixmap) || 
  787.         (np->horizontal_raised_pixmap    != op->horizontal_raised_pixmap))
  788.     {
  789.         update_pixmaps = True;
  790.     }
  791.  
  792.     /* drag_cursor */
  793.     if (np->drag_cursor != op->drag_cursor)
  794.     {
  795.         /* Update drag cursor */
  796.     }
  797.  
  798.     /* swap_threshold */
  799.     if (np->swap_threshold != op->swap_threshold)
  800.     {
  801.         /* Make sure the new swap threshold is ok */
  802.         CheckSwapThreshold(nw);
  803.     }
  804.  
  805.     /* Update pixmaps if needed */
  806.     if (update_pixmaps)
  807.     {
  808.         UpdatePixmaps(nw);
  809.     }
  810.  
  811.     return _XfeManagerChainSetValues(ow,rw,nw,xfeToolBoxWidgetClass);
  812. }
  813. /*----------------------------------------------------------------------*/
  814.  
  815. /*----------------------------------------------------------------------*/
  816. /*                                                                        */
  817. /* Constraint Class Methods                                                */
  818. /*                                                                        */
  819. /*----------------------------------------------------------------------*/
  820. static void
  821. ConstraintInitialize(Widget rc,Widget nc,ArgList args,Cardinal *nargs)
  822. {
  823. /*     Widget                        w = XtParent(nc); */
  824.  
  825. /*     printf("ConstraintInitialize(%s) for %s\n",XtName(w),XtName(nc)); */
  826.  
  827. /*     Widget                        w = XtParent(nc); */
  828. /*    XfeManagerConstraintPart *    cp = _XfeManagerConstraintPart(nc);*/
  829.  
  830.  
  831.     /* Finish constraint initialization */
  832.     _XfeConstraintChainInitialize(rc,nc,xfeToolBoxWidgetClass);
  833. }
  834. /*----------------------------------------------------------------------*/
  835. static Boolean
  836. ConstraintSetValues(Widget oc,Widget rc,Widget nc,ArgList args,Cardinal *nargs)
  837. {
  838.     Widget                        w = XtParent(nc);
  839.     XfeToolBoxPart *            tp = _XfeToolBoxPart(w);
  840.      XfeToolBoxConstraintPart *    ncp = _XfeToolBoxConstraintPart(nc);
  841.      XfeToolBoxConstraintPart *    ocp = _XfeToolBoxConstraintPart(oc);
  842.  
  843.     /* position_index */
  844.     if (_XfeManagerPositionIndex(nc) != _XfeManagerPositionIndex(oc))
  845.     {
  846.         /* Make sure the new position index is within range */
  847.         if ((_XfeManagerPositionIndex(nc) < 0) || 
  848.             (_XfeManagerPositionIndex(nc) >= tp->item_count))
  849.         {
  850.             _XfeManagerPositionIndex(nc) = _XfeManagerPositionIndex(oc);
  851.  
  852.             _XfeArgWarning(w,MESSAGE5,XtName(nc));
  853.         }
  854.         else
  855.         {
  856.             /* Swap the items */
  857.             SwapItems(w,
  858.                       _XfeManagerPositionIndex(nc),
  859.                       _XfeManagerPositionIndex(oc));
  860.  
  861.  
  862. /*             UpdatePositionIndeces(w); */
  863.             
  864.              _XfemConfigFlags(w) |= XfeConfigLayout;
  865.         }
  866.     }
  867.  
  868.     /* open */
  869.     if (ncp->open != ocp->open)
  870.     {
  871. /*          printf("%s,%s: change in open\n",XtName(nc),XtName(w)); */
  872.  
  873.         _XfemConfigFlags(w) |= XfeConfigGLE;
  874.     }
  875.  
  876.     /* Finish constraint set values */
  877.     return _XfeConstraintChainSetValues(oc,rc,nc,xfeToolBoxWidgetClass);
  878. }
  879. /*----------------------------------------------------------------------*/
  880.  
  881.  
  882. /*----------------------------------------------------------------------*/
  883. /*                                                                        */
  884. /* XfeManager class methods                                                */
  885. /*                                                                        */
  886. /*----------------------------------------------------------------------*/
  887. static void
  888. PreferredGeometry(Widget w,Dimension * width,Dimension * height)
  889. {
  890.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  891.     Dimension                total_tab_width = 0;
  892.     Dimension                total_tab_height = 0;
  893.     Cardinal                i;
  894.  
  895.     *width  = _XfemOffsetLeft(w) + _XfemOffsetRight(w) + MaxItemWidth(w);
  896.     *height = _XfemOffsetTop(w)  + _XfemOffsetBottom(w);
  897.  
  898.     for (i = 0; i < tp->item_count; i++)
  899.     {
  900.         /* Shown */
  901.         if (_XfeChildIsShown(tp->items[i]))
  902.         {
  903.             /* Open */
  904.             if (_XfeToolBoxChildOpen(tp->items[i]))
  905.             {
  906.                 *height += (_XfeHeight(tp->items[i]) + tp->vertical_spacing);
  907.             }
  908.             /* Closed */
  909.             else
  910.             {
  911.                 total_tab_width += (_XfeHeight(tp->items[i]) + 
  912.                                     tp->horizontal_spacing);
  913.  
  914.                 total_tab_height = _XfePreferredHeight(tp->closed_tabs[i]);
  915.             }
  916.         }
  917.     }
  918.  
  919.     *height += total_tab_height;
  920.  
  921.     /* Make sure the tool box is at least wide enough to hold the tabs */
  922.     if (*width < total_tab_width)
  923.     {
  924.         *width = total_tab_width;
  925.     }
  926. }
  927. /*----------------------------------------------------------------------*/
  928. static void
  929. MinimumGeometry(Widget w,Dimension * width,Dimension * height)
  930. {
  931. /*     XfeToolBoxPart *        tp = _XfeToolBoxPart(w); */
  932.  
  933.     *width  = _XfemOffsetLeft(w) + _XfemOffsetRight(w);
  934.     *height = _XfemOffsetTop(w) + _XfemOffsetBottom(w);
  935. }
  936. /*----------------------------------------------------------------------*/
  937. static void
  938. LayoutComponents(Widget w)
  939. {
  940.     XfeToolBoxPart *    tp = _XfeToolBoxPart(w);
  941.     Cardinal            i;
  942.     int                    x = _XfemRectX(w);
  943.     int                    y = _XfemRectY(w);
  944.  
  945. /*     if ((_XfeWidth(w) <= 10) || (_XfeHeight(w) <= 10)) */
  946. /*     { */
  947. /*         return; */
  948. /*     } */
  949.  
  950. /*     printf("LayoutComponents(%s)\n",XtName(w)); */
  951.  
  952.     for (i = 0; i < tp->item_count; i++)
  953.     {
  954.         /* Item is managed */
  955.         if (_XfeChildIsShown(tp->items[i]))
  956.         {
  957.             /* Open */
  958.             if (_XfeToolBoxChildOpen(tp->items[i]))
  959.             {
  960.                 _XfeConfigureWidget(tp->opened_tabs[i],
  961.                                     
  962.                                     _XfemRectX(w),
  963.                                     
  964.                                     y,
  965.  
  966.                                     _XfePreferredWidth(tp->opened_tabs[i]),
  967.                                     
  968.                                     _XfeHeight(tp->items[i]));
  969.                 
  970.                 y += (_XfeHeight(tp->items[i]) + tp->vertical_spacing);
  971.  
  972.                 _XfeMoveWidget(tp->closed_tabs[i],-1000,-1000);
  973.             }
  974.             /* Closed */
  975.             else
  976.             {
  977.                 Dimension width = _XfeHeight(tp->items[i]);
  978.                 
  979.                 _XfeConfigureWidget(tp->closed_tabs[i],
  980.                                     
  981.                                     x,
  982.                                     
  983.                                     _XfeHeight(w) - 
  984.                                     _XfemOffsetBottom(w) -
  985.                                     _XfePreferredHeight(tp->closed_tabs[i]),
  986.                                     
  987.                                     width,
  988.                                 
  989.                                     _XfePreferredHeight(tp->closed_tabs[i]));
  990.                 
  991.                 x += width;
  992.  
  993.                 _XfeMoveWidget(tp->opened_tabs[i],-1000,-1000);
  994.             }
  995.         }
  996.         /* Item is unmanaged */
  997.         else
  998.         {
  999.             _XfeMoveWidget(tp->closed_tabs[i],-1000,-1000);
  1000.             _XfeMoveWidget(tp->opened_tabs[i],-1000,-1000);
  1001.         }
  1002.     }
  1003. }
  1004. /*----------------------------------------------------------------------*/
  1005. static void
  1006. LayoutChildren(Widget w)
  1007. {
  1008.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1009.     Cardinal                i;
  1010.     int                        y = _XfemRectY(w);
  1011.  
  1012.     for (i = 0; i < tp->item_count; i++)
  1013.     {
  1014.         Widget item = tp->items[i];
  1015.  
  1016.         if (_XfeIsAlive(item))
  1017.         {
  1018.             /* Item is managed */
  1019.             if (_XfeChildIsShown(item))
  1020.             {
  1021.                 /* Open */
  1022.                 if (_XfeToolBoxChildOpen(tp->items[i]))
  1023.                 {
  1024.                     _XfeConfigureWidget(item,
  1025.                                         
  1026.                                         _XfemRectX(w) + 
  1027.                                         _XfePreferredWidth(tp->opened_tabs[i]),
  1028.                                         
  1029.                                         y,
  1030.                                         
  1031.                                         _XfemRectWidth(w) - 
  1032.                                         _XfePreferredWidth(tp->opened_tabs[i]),
  1033.                                         
  1034.                                         _XfeHeight(item));
  1035.                            
  1036.                     y += (_XfeHeight(item) + tp->vertical_spacing);
  1037.  
  1038.                     XtVaSetValues(item,XmNmappedWhenManaged,True,NULL);
  1039.                 }
  1040.                 /* Closed */
  1041.                 else
  1042.                 {
  1043.                     XtVaSetValues(item,XmNmappedWhenManaged,False,NULL);
  1044.                 }
  1045.             }
  1046.         }
  1047.     }
  1048. }
  1049. /*----------------------------------------------------------------------*/
  1050. static Boolean
  1051. AcceptChild(Widget child)
  1052. {
  1053.     return True;
  1054. }
  1055. /*----------------------------------------------------------------------*/
  1056. static Boolean
  1057. InsertChild(Widget child)
  1058. {
  1059.     Widget                    w = XtParent(child);
  1060.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1061.     Widget                    opened_tab;
  1062.     Widget                    closed_tab;
  1063.     Cardinal                index;
  1064.  
  1065. /*      printf("InsertChild(%s) for %s\n",XtName(w),XtName(child)); */
  1066.  
  1067.     /* Increase the item count */
  1068.     tp->item_count++;
  1069.  
  1070.     /* The new tab's index */
  1071.     index = tp->item_count - 1;
  1072.  
  1073.     /* For every tool item, we need 2 tab buttoms: (1 opened & 1 closed) */
  1074.     closed_tab = CreateTab(w,False);
  1075.     opened_tab = CreateTab(w,True);
  1076.  
  1077.     /* Add callbacks to tabs */
  1078.     XtAddCallback(closed_tab,XmNactivateCallback,TabActivateCB,NULL);
  1079.     XtAddCallback(closed_tab,XmNarmCallback,TabArmCB,NULL);
  1080.     XtAddCallback(closed_tab,XmNdisarmCallback,TabDisarmCB,NULL);
  1081.  
  1082.     XtAddCallback(opened_tab,XmNactivateCallback,TabActivateCB,NULL);
  1083.     XtAddCallback(opened_tab,XmNarmCallback,TabArmCB,NULL);
  1084.     XtAddCallback(opened_tab,XmNdisarmCallback,TabDisarmCB,NULL);
  1085.  
  1086.     /* Allocate more space for the new tabs */
  1087.     tp->closed_tabs = (WidgetList) XtRealloc((char *) tp->closed_tabs,
  1088.                                              sizeof(Widget) * tp->item_count);
  1089.     
  1090.     tp->opened_tabs = (WidgetList) XtRealloc((char *) tp->opened_tabs,
  1091.                                              sizeof(Widget) * tp->item_count);
  1092.     
  1093.     /* Place the new tabs in the tab lists */
  1094.     tp->closed_tabs[index] = closed_tab;
  1095.     tp->opened_tabs[index] = opened_tab;
  1096.     
  1097.     /* Allocate more space for the new item */
  1098.     tp->items = (WidgetList) XtRealloc((char *) tp->items,
  1099.                                        sizeof(Widget) * tp->item_count);
  1100.  
  1101.     /* Place the new tab in the tab tab list */
  1102.     tp->items[index] = child;
  1103.  
  1104.     /* Add item event handlers */
  1105.     ChildSetDraggable(w,child,True);
  1106.  
  1107.     /* Make sure the swap threshold is ok */
  1108.     CheckSwapThreshold(w);
  1109.  
  1110.     /* Update the position_index contraint member of the items */
  1111.     UpdatePositionIndeces(w);
  1112.  
  1113.     /* Invoke new item callbacks */
  1114.     InvokeCallbacks(w,
  1115.                     tp->new_item_callback,
  1116.                     XmCR_TOOL_BOX_NEW_ITEM,
  1117.                     NULL,
  1118.                     child,
  1119.                     closed_tab,
  1120.                     opened_tab,
  1121.                     index);
  1122.  
  1123.     /* Do layout only of the new child is managed */
  1124.     return XtIsManaged(child);
  1125. }
  1126. /*----------------------------------------------------------------------*/
  1127. static Boolean
  1128. DeleteChild(Widget child)
  1129. {
  1130.     Widget                    w = XtParent(child);
  1131.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1132.     int                        index = ItemToIndex(child);
  1133.  
  1134.     assert( CHECK_RANGE(tp,index) );
  1135.  
  1136.     /* Remove the corresponding tabs */
  1137.     XtDestroyWidget(tp->closed_tabs[index]);
  1138.     XtDestroyWidget(tp->opened_tabs[index]);
  1139.  
  1140.     /* Mark the item and tab NULL */
  1141.     tp->items[index]        = NULL;
  1142.     tp->closed_tabs[index]  = NULL;
  1143.     tp->opened_tabs[index]  = NULL;
  1144.  
  1145.     /* Update the item and tab lists */
  1146.     UpdateItems(w);
  1147.  
  1148.     /* Decrease the item count */
  1149.     tp->item_count++;
  1150.  
  1151.     return XtIsManaged(child);
  1152. }
  1153. /*----------------------------------------------------------------------*/
  1154.  
  1155. /*----------------------------------------------------------------------*/
  1156. /*                                                                        */
  1157. /* Misc XfeToolBox functions                                            */
  1158. /*                                                                        */
  1159. /*----------------------------------------------------------------------*/
  1160. static Widget
  1161. CreateTab(Widget w,Boolean opened)
  1162. {
  1163.     XfeToolBoxPart *    tp = _XfeToolBoxPart(w);
  1164.     Widget                tab;
  1165.     char                name_buf[20];
  1166.     Arg                    av[10];
  1167.     Cardinal            ac = 0;
  1168.  
  1169.     XtSetArg(av[ac],XmNprivateComponent,        True); ac++;
  1170.  
  1171.     /* Opened - vertical */
  1172.     if (opened)
  1173.     {
  1174.         sprintf(name_buf,"%s%d",OPENED_TAB_BUTTON_NAME,tp->item_count - 1);
  1175.  
  1176.         XtSetArg(av[ac],XmNorientation,                XmVERTICAL); ac++;
  1177.         
  1178.         XtSetArg(av[ac],XmNtopPixmap,                tp->top_pixmap); ac++;
  1179.         XtSetArg(av[ac],XmNtopRaisedPixmap,            tp->top_raised_pixmap); ac++;
  1180.  
  1181.         XtSetArg(av[ac],XmNbottomPixmap,            tp->bottom_pixmap); ac++;
  1182.         XtSetArg(av[ac],XmNbottomRaisedPixmap,        tp->bottom_raised_pixmap); ac++;
  1183.  
  1184.         XtSetArg(av[ac],XmNverticalPixmap,            tp->vertical_pixmap); ac++;
  1185.         XtSetArg(av[ac],XmNverticalRaisedPixmap,    tp->vertical_raised_pixmap); ac++;
  1186.     }
  1187.     /* Closed - horizontal */
  1188.     else
  1189.     {
  1190.         sprintf(name_buf,"%s%d",CLOSED_TAB_BUTTON_NAME,tp->item_count - 1);
  1191.  
  1192.         XtSetArg(av[ac],XmNorientation,                XmHORIZONTAL); ac++;
  1193.  
  1194.         XtSetArg(av[ac],XmNleftPixmap,                tp->left_pixmap); ac++;
  1195.         XtSetArg(av[ac],XmNleftRaisedPixmap,        tp->left_raised_pixmap); ac++;
  1196.  
  1197.         XtSetArg(av[ac],XmNrightPixmap,                tp->right_pixmap); ac++;
  1198.         XtSetArg(av[ac],XmNrightRaisedPixmap,        tp->right_raised_pixmap); ac++;
  1199.  
  1200.         XtSetArg(av[ac],XmNhorizontalPixmap,        tp->horizontal_pixmap); ac++;
  1201.         XtSetArg(av[ac],XmNhorizontalRaisedPixmap,    tp->horizontal_raised_pixmap); ac++;
  1202.     }
  1203.  
  1204.     tab = XtCreateWidget(name_buf,xfeTabWidgetClass,w,av,ac);
  1205.  
  1206.     /* Allow the only the opened tab to drag the item */
  1207.     if (opened)
  1208.     {
  1209.         ChildSetDraggable(w,tab,True);
  1210.     }
  1211.  
  1212.     XtManageChild(tab);
  1213.  
  1214.     return tab;
  1215. }
  1216. /*----------------------------------------------------------------------*/
  1217. static Cardinal
  1218. ActiveItemCount(Widget w)
  1219. {
  1220.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1221.     Cardinal                managed_item_count = 0;
  1222.     Cardinal                i;
  1223.  
  1224.     for (i = 0; i < tp->item_count; i++)
  1225.     {
  1226.         Widget child = tp->items[i];
  1227.  
  1228.         /* Shown and open */
  1229.         if (_XfeChildIsShown(child) && _XfeToolBoxChildOpen(tp->items[i]))
  1230.         {
  1231.             managed_item_count++;
  1232.         }
  1233.     }
  1234.  
  1235.     return managed_item_count;
  1236. }
  1237. /*----------------------------------------------------------------------*/
  1238. static Dimension
  1239. MaxItemWidth(Widget w)
  1240. {
  1241.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1242.     Dimension                max_item_width = 0;
  1243.     Cardinal                i;
  1244.     
  1245.     for (i = 0; i < tp->item_count; i++)
  1246.     {
  1247.         /* Shown */
  1248.         if (_XfeChildIsShown(tp->items[i]))
  1249.         {
  1250.             if (_XfeWidth(tp->items[i]) > max_item_width)
  1251.             {
  1252.                 max_item_width = _XfeWidth(tp->items[i]);
  1253.             }
  1254.         }
  1255.     }
  1256.  
  1257.     return max_item_width;
  1258. }
  1259. /*----------------------------------------------------------------------*/
  1260.  
  1261. /*----------------------------------------------------------------------*/
  1262. /*                                                                        */
  1263. /* Tab callbacks                                                        */
  1264. /*                                                                        */
  1265. /*----------------------------------------------------------------------*/
  1266. static void
  1267. TabActivateCB(Widget button,XtPointer client_data,XtPointer call_data)
  1268. {
  1269.     Widget                    w = XtParent(button);
  1270.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1271.     int                        index = TabToIndex(button);
  1272.  
  1273.     assert( CHECK_RANGE(tp,index) );
  1274.  
  1275. /*     printf("TabActivateCB(%s = %d)\n",XtName(tp->items[index]),index); */
  1276.  
  1277.     /* Make sure that this callback was not the result of a drag */
  1278.     if (tp->dragging_tab)
  1279.     {
  1280.         tp->dragging_tab = False;
  1281.  
  1282.         return;
  1283.     }
  1284.  
  1285.     XfeToolBoxItemToggleOpen(w,tp->items[index]);
  1286.  
  1287.     /* Invoke open callbacks */
  1288.     if (_XfeToolBoxChildOpen(tp->items[index]))
  1289.     {
  1290. /*         printf("Open(%s = %d)\n",XtName(tp->items[index]),index); */
  1291.         InvokeCallbacks(w,
  1292.                         tp->open_callback,
  1293.                         XmCR_TOOL_BOX_OPEN,
  1294.                         NULL,
  1295.                         tp->items[index],
  1296.                         tp->closed_tabs[index],
  1297.                         tp->opened_tabs[index],
  1298.                         index);
  1299.     }
  1300.     /* Invoke close callbacks */
  1301.     else
  1302.     {
  1303. /*         printf("Close(%s = %d)\n",XtName(tp->items[index]),index); */
  1304.         InvokeCallbacks(w,
  1305.                         tp->close_callback,
  1306.                         XmCR_TOOL_BOX_CLOSE,
  1307.                         NULL,
  1308.                         tp->items[index],
  1309.                         tp->closed_tabs[index],
  1310.                         tp->opened_tabs[index],
  1311.                         index);
  1312.     }
  1313. }
  1314. /*----------------------------------------------------------------------*/
  1315. static void
  1316. TabArmCB(Widget button,XtPointer client_data,XtPointer call_data)
  1317. {
  1318.     Widget                    w = XtParent(button);
  1319.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1320.  
  1321. /*      printf("TabArmCB(%s)\n",XtName(w)); */
  1322.  
  1323.     tp->clicking_tab = True;
  1324. }
  1325. /*----------------------------------------------------------------------*/
  1326. static void
  1327. TabDisarmCB(Widget button,XtPointer client_data,XtPointer call_data)
  1328. {
  1329.     Widget                    w = XtParent(button);
  1330.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1331.  
  1332. /*      printf("TabDisarmCB(%s)\n",XtName(w)); */
  1333.  
  1334.     tp->clicking_tab = False;
  1335. }
  1336. /*----------------------------------------------------------------------*/
  1337.  
  1338. /*----------------------------------------------------------------------*/
  1339. /*                                                                        */
  1340. /* Descendant event handlers                                            */
  1341. /*                                                                        */
  1342. /*----------------------------------------------------------------------*/
  1343. static void
  1344. DescendantEH(Widget            descendant,
  1345.              XtPointer        client_data,
  1346.              XEvent *        event,
  1347.              Boolean *        cont)
  1348. {
  1349.     Widget                w = (Widget) client_data;
  1350.     XfeToolBoxPart *    tp = _XfeToolBoxPart(w);
  1351.     Widget                target = descendant;
  1352.     Widget                item = NULL;
  1353.     Position            y;
  1354.  
  1355.     assert( _XfeIsAlive(descendant) );
  1356.     assert( _XfeIsAlive(w) );
  1357.  
  1358.     /* Ignore drag request from sensitive XfeButtons */
  1359.     if (XfeIsButton(descendant) && 
  1360.         _XfeIsSensitive(descendant) && 
  1361.         !XfeIsTab(descendant))
  1362.     {
  1363.         return;
  1364.     }
  1365.  
  1366.     /* Find the ancestor item for the given descendant */
  1367.     if (XfeIsTab(descendant))
  1368.     {
  1369.         int index = TabToIndex(descendant);
  1370.  
  1371.         item = tp->items[index];
  1372.     }
  1373.     else
  1374.     {
  1375.         while (!item)
  1376.         {
  1377.             if (XfeIsToolBox(XtParent(target)))
  1378.             {
  1379.                 item = target;
  1380.             }
  1381.             else
  1382.             {
  1383.                 target = XtParent(target);
  1384.             }
  1385.         }
  1386.     }
  1387.  
  1388.     switch(event->type) 
  1389.     {
  1390.     case ButtonPress:
  1391.  
  1392.         if (event->xbutton.button == tp->drag_button)
  1393.         {
  1394.             y = event->xbutton.y;
  1395.  
  1396.             if (event->xbutton.y > _XfeHeight(w))
  1397.             {
  1398.                 y -= (event->xbutton.y - _XfeHeight(w));
  1399.             }
  1400.             else if (event->xbutton.y < 0)
  1401.             {
  1402.                 y -= event->xbutton.y;
  1403.             }
  1404.  
  1405.             DragStart(item,event,y,event->xbutton.y_root);
  1406.  
  1407.             /* Clear the dragging tab flag if needed */
  1408.             if (XfeIsTab(descendant))
  1409.             {
  1410.                 tp->dragging_tab = False;
  1411.             }
  1412.         }
  1413.  
  1414.         break;
  1415.  
  1416.     case ButtonRelease:
  1417.  
  1418.         if (event->xbutton.button == tp->drag_button)
  1419.         {
  1420.             y = event->xbutton.y;
  1421.             
  1422.             if (event->xbutton.y > _XfeHeight(w))
  1423.             {
  1424.                 y -= (event->xbutton.y - _XfeHeight(w));
  1425.             }
  1426.             else if (event->xbutton.y < 0)
  1427.             {
  1428.                 y -= event->xbutton.y;
  1429.             }
  1430.             
  1431.             DragEnd(item,event,y,event->xbutton.y_root);
  1432.         }
  1433.  
  1434.         break;
  1435.         
  1436.     case MotionNotify:
  1437.  
  1438.         if (!(event->xmotion.state & Button1Mask))
  1439.         {
  1440.             return;
  1441.         }
  1442.  
  1443.         y = event->xmotion.y;
  1444.         
  1445.  
  1446.         if (event->xmotion.y > _XfeHeight(w))
  1447.         {
  1448.             y -= (event->xmotion.y - _XfeHeight(w));
  1449.         }
  1450.         else if (event->xmotion.y < 0)
  1451.         {
  1452.             y -= event->xmotion.y;
  1453.         }
  1454.         
  1455.         DragMotion(item,event,event->xmotion.y,event->xmotion.y_root);
  1456.  
  1457.         /* Set the dragging tab flag if needed */
  1458.         if (XfeIsTab(descendant))
  1459.         {
  1460.             tp->clicking_tab = False;
  1461.             tp->dragging_tab = True;
  1462.         }
  1463.         
  1464.         break;
  1465.     }
  1466.  
  1467.  
  1468.     *cont = True;
  1469. }
  1470. /*----------------------------------------------------------------------*/
  1471. static void
  1472. DragStart(Widget item,XEvent * event,int y,int root_y)
  1473. {
  1474.     Widget                    w = XtParent(item);
  1475.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1476.     int                        index;
  1477.  
  1478. /*     printf("DragStart(%s)\n",XtName(w)); */
  1479.  
  1480.     /* Make sure there are at least 2 items managed before dragging */
  1481.     if (ActiveItemCount(w) <= 1)
  1482.     {
  1483.         return;
  1484.     }
  1485.  
  1486.     index = ItemToIndex(item);
  1487.  
  1488.     assert( CHECK_RANGE(tp,index) );
  1489.  
  1490.     if (tp->drag_cursor != None)
  1491.     {
  1492.         XfeCursorDefine(w,tp->drag_cursor);
  1493.     }
  1494.  
  1495.     tp->dragging = True;
  1496.  
  1497.     tp->start_drag_y = root_y;
  1498.  
  1499.     tp->original_y = _XfeY(tp->items[index]);
  1500.  
  1501.     tp->last_y = _XfeY(tp->items[index]);
  1502.  
  1503.     tp->last_moved_item = NULL;
  1504.  
  1505.     tp->drag_direction = DIRECTION_NONE;
  1506.  
  1507.     /* Make sure the item being dragged is on top of other items */
  1508.     RaiseItem(w,index);
  1509. }
  1510. /*----------------------------------------------------------------------*/
  1511. static void
  1512. DragEnd(Widget item,XEvent * event,int y,int root_y)
  1513. {
  1514.     Widget                    w = XtParent(item);
  1515.     XfeToolBoxPart *        tp = _XfeToolBoxPart(XtParent(item));
  1516.     int                        index;
  1517.  
  1518. /*     printf("DragEnd(%s)\n",XtName(w)); */
  1519.  
  1520.     tp->dragging = False;
  1521.  
  1522.     index = ItemToIndex(item);
  1523.  
  1524.     assert( CHECK_RANGE(tp,index) );
  1525.  
  1526.     if (tp->drag_cursor != None)
  1527.     {
  1528.         XfeCursorUndefine(w);
  1529.     }
  1530.  
  1531.     if (!tp->clicking_tab)
  1532.     {
  1533.         /* Snap the item in place */
  1534.         SnapItemInPlace(w,index);
  1535.     }
  1536.  
  1537.     LayoutComponents(w);
  1538.     LayoutChildren(w);
  1539. }
  1540. /*----------------------------------------------------------------------*/
  1541. static void
  1542. DragMotion(Widget item,XEvent * event,int y,int root_y)
  1543. {
  1544.     Widget                    w = XtParent(item);
  1545.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1546.     int                        dy;
  1547.     int                        index;
  1548.     int                        new_y;
  1549.     int                        old_drag_direction = tp->drag_direction;
  1550.     int                        under_index;
  1551.  
  1552. /*     printf("DragMotion(%s)\n",XtName(w)); */
  1553.  
  1554.     index = ItemToIndex(item);
  1555.  
  1556.     assert( CHECK_RANGE(tp,index) );
  1557.  
  1558.     /* Make sure we are dragging */
  1559.     if (!tp->dragging)
  1560.     {
  1561.         return;
  1562.     }
  1563.  
  1564.     /* Compute the change in position */
  1565.     dy = root_y - tp->start_drag_y;
  1566.  
  1567.     /* Make sure some change in y occurred before moving item */
  1568.     if (!dy)
  1569.     {
  1570.         return;
  1571.     }
  1572.  
  1573.     /* Compute the new item's position */
  1574.     new_y = tp->original_y + dy;
  1575.  
  1576.     /* Make sure the item moved only a reasonable amount to avoid holes */
  1577.  
  1578.     /* Check down */
  1579.     if (new_y > tp->last_y)
  1580.     {
  1581.         if ((new_y - tp->last_y) > tp->drag_threshold)
  1582.         {
  1583.             new_y = tp->last_y + tp->drag_threshold;
  1584.         }
  1585.     }
  1586.     /* Check up */
  1587.     else
  1588.     {
  1589.         if ((tp->last_y - new_y) > tp->drag_threshold)
  1590.         {
  1591.             new_y = tp->last_y - tp->drag_threshold;
  1592.         }
  1593.     }
  1594.         
  1595.     /* Make sure the new y position is within range */
  1596.     if (new_y < _XfemOffsetTop(w))
  1597.     {
  1598.         new_y = _XfemOffsetTop(w);
  1599.     }
  1600.     else if (new_y > MaxItemY(tp->items[index]))
  1601.     {
  1602.         new_y = MaxItemY(tp->items[index]);
  1603.     }
  1604.  
  1605.     /* Make sure the new y position is different */
  1606.     if (_XfeY(item) == new_y)
  1607.     {
  1608.         return;
  1609.     }
  1610.  
  1611.     /* Move the item to its new position */
  1612.     MoveItem(w,index,new_y);
  1613.  
  1614.     /* Compute the new drag direction */
  1615.     if (new_y > tp->last_y)
  1616.     {
  1617.         tp->drag_direction = DIRECTION_DOWN;
  1618.     }
  1619.     else
  1620.     {
  1621.         tp->drag_direction = DIRECTION_UP;
  1622.     }    
  1623.  
  1624.     /* Find out if an item is underneath the item */
  1625.     under_index = FindItemUnder(w,index);
  1626.  
  1627.     if (CHECK_RANGE(tp,under_index))
  1628.     {
  1629.         Widget        under_item = tp->items[under_index];
  1630.         Position    empty_slot_y;
  1631.  
  1632.         /* Make sure the item underneath was not already swapped */
  1633.         if (under_item != tp->last_moved_item)
  1634.         {
  1635.             /* Up */
  1636.             if (tp->drag_direction == DIRECTION_UP)
  1637.             {
  1638.                 if (index == LastManagedIndex(w))
  1639.                 {
  1640.                     empty_slot_y = MaxItemY(tp->items[under_index]);
  1641.                 }
  1642.                 else
  1643.                 {
  1644.                     int next_index = NextManagedIndex(w,index);
  1645.                     
  1646.                     empty_slot_y = 
  1647.                         _XfeY(tp->items[next_index]) - 
  1648.                         _XfeHeight(tp->items[under_index]) -
  1649.                         tp->vertical_spacing;
  1650.                 }
  1651.             }
  1652.             /* Down */
  1653.             else
  1654.             {
  1655.                 if (index == FirstManagedIndex(w))
  1656.                 {
  1657.                     empty_slot_y = _XfemRectY(w);
  1658.                 }
  1659.                 else
  1660.                 {
  1661.                     int prev_index = PreviousManagedIndex(w,index);
  1662.  
  1663.                     empty_slot_y = 
  1664.                         _XfeY(tp->items[prev_index]) +
  1665.                         _XfeHeight(tp->items[prev_index]) +
  1666.                         tp->vertical_spacing;
  1667.                 }
  1668.             }
  1669.  
  1670.             /* Swap the item being dragged with the underneath item */
  1671.             MoveItem(w,under_index,empty_slot_y);
  1672.             
  1673.             SwapItems(w,index,under_index);
  1674.             
  1675.             tp->last_moved_item = under_item;
  1676.  
  1677.             /* Update the position_index contraint member of the items */
  1678.             UpdatePositionIndeces(w);
  1679.  
  1680. /*             printf("Swap(%s = %d)\n",XtName(tp->items[index]),index); */
  1681.  
  1682.             /* Invoke the swap callbacks */
  1683.             InvokeSwapCallbacks(w,event,item,under_item,index,under_index);
  1684.         }
  1685.     }
  1686.  
  1687.     /* If the direction changed within a drag, rest the last moved item */
  1688.     if (old_drag_direction != tp->drag_direction)
  1689.     {
  1690.         if (_XfeIsAlive(tp->last_moved_item))
  1691.         {
  1692.             tp->last_moved_item = NULL;
  1693.         }
  1694.     }
  1695.  
  1696.     tp->last_y = new_y;
  1697. }
  1698. /*----------------------------------------------------------------------*/
  1699. static Boolean
  1700. MoveItem(Widget w,Cardinal index,int y)
  1701. {
  1702.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1703.  
  1704.     if (_XfeY(tp->items[index]) != y)
  1705.     {
  1706.         /* Move the item */
  1707.         _XfeMoveWidget(tp->items[index],_XfeX(tp->items[index]),y);
  1708.         
  1709.         /* Move the item's tab button */
  1710.         _XfeMoveWidget(tp->opened_tabs[index],_XfeX(tp->opened_tabs[index]),y);
  1711.  
  1712.         return True;
  1713.     }
  1714.  
  1715.     return False;
  1716. }
  1717. /*----------------------------------------------------------------------*/
  1718. static int
  1719. MaxItemY(Widget item)
  1720. {
  1721.     Widget                    w = XtParent(item);
  1722.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1723.     Dimension                max_y  = _XfeHeight(w) - _XfemOffsetBottom(w);
  1724.  
  1725.     /* Include the closed tab button height if any are active */
  1726.     if (ActiveItemCount(w) < tp->item_count)
  1727.     {
  1728.         max_y -= _XfePreferredHeight(tp->closed_tabs[tp->item_count - 1]);
  1729.     }
  1730.  
  1731.     max_y -= _XfeHeight(item);
  1732.  
  1733.     return max_y;
  1734. }
  1735. /*----------------------------------------------------------------------*/
  1736. static void
  1737. SwapItems(Widget w,int i,int j)
  1738. {
  1739.     XfeToolBoxPart *            tp = _XfeToolBoxPart(w);
  1740.      XfeToolBoxConstraintPart *    cpi;
  1741.      XfeToolBoxConstraintPart *    cpj;
  1742.  
  1743.     assert( CHECK_RANGE(tp,i) );
  1744.     assert( CHECK_RANGE(tp,j) );
  1745.  
  1746.     /* Swap the item */
  1747.     _XfeSwap(tp->items[i],tp->items[j],Widget);
  1748.  
  1749.     /* Swap the tab buttons */
  1750.     _XfeSwap(tp->closed_tabs[i],tp->closed_tabs[j],Widget);
  1751.     _XfeSwap(tp->opened_tabs[i],tp->opened_tabs[j],Widget);
  1752.  
  1753.     /* Swap the item state */
  1754.     cpi = _XfeToolBoxConstraintPart(tp->items[i]);
  1755.     cpj = _XfeToolBoxConstraintPart(tp->items[j]);
  1756.     
  1757.     _XfeSwap(cpi->open,cpj->open,Boolean);
  1758. }
  1759. /*----------------------------------------------------------------------*/
  1760. static int
  1761. ItemToIndex(Widget item)
  1762. {
  1763.     XfeToolBoxPart *        tp = _XfeToolBoxPart(XtParent(item));
  1764.     Cardinal                i = 0;
  1765.  
  1766.     for (i = 0; i < tp->item_count; i++)
  1767.     {
  1768.         if (item == tp->items[i])
  1769.         {
  1770.             return i;
  1771.         }
  1772.     }
  1773.  
  1774.     return -1;
  1775. }
  1776. /*----------------------------------------------------------------------*/
  1777. static int
  1778. TabToIndex(Widget tab)
  1779. {
  1780.     XfeToolBoxPart *        tp = _XfeToolBoxPart(XtParent(tab));
  1781.     Cardinal                i = 0;
  1782.  
  1783.     for (i = 0; i < tp->item_count; i++)
  1784.     {
  1785.         if ((tab == tp->closed_tabs[i]) || (tab == tp->opened_tabs[i]))
  1786.         {
  1787.             return i;
  1788.         }
  1789.     }
  1790.  
  1791.     return -1;
  1792. }
  1793. /*----------------------------------------------------------------------*/
  1794.  
  1795. /*----------------------------------------------------------------------*/
  1796. /*                                                                        */
  1797. /* Item functions                                                        */
  1798. /*                                                                        */
  1799. /*----------------------------------------------------------------------*/
  1800. static void
  1801. UpdateItems(Widget w)
  1802. {
  1803.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1804.     Cardinal                i;
  1805.     Cardinal                new_count = 0;
  1806.  
  1807.     /* First, count the number of items that are alive */
  1808.     for (i = 0; i < tp->item_count; i++)
  1809.     {
  1810.         if (_XfeIsAlive(tp->items[i]))
  1811.         {
  1812.             new_count++;
  1813.         }
  1814.     }
  1815.  
  1816.     if (!new_count)
  1817.     {
  1818.         if (tp->items)
  1819.         {
  1820.             XtFree((char *) tp->items);
  1821.         }
  1822.  
  1823.         if (tp->closed_tabs)
  1824.         {
  1825.             XtFree((char *) tp->closed_tabs);
  1826.         }
  1827.  
  1828.         if (tp->opened_tabs)
  1829.         {
  1830.             XtFree((char *) tp->opened_tabs);
  1831.         }
  1832.  
  1833.         tp->items        = NULL;
  1834.         tp->closed_tabs = NULL;
  1835.         tp->opened_tabs    = NULL;
  1836.         tp->item_count    = 0;
  1837.     }
  1838.     else
  1839.     {
  1840.         WidgetList    new_items = 
  1841.             (WidgetList) XtMalloc(sizeof(Widget) * new_count);
  1842.  
  1843.         WidgetList    new_closed_tabs  = 
  1844.             (WidgetList) XtMalloc(sizeof(Widget) * new_count);
  1845.  
  1846.         WidgetList    new_opened_tabs  = 
  1847.             (WidgetList) XtMalloc(sizeof(Widget) * new_count);
  1848.  
  1849.         Cardinal    index = 0;
  1850.         
  1851.         for (i = 0; i < tp->item_count; i++)
  1852.         {
  1853.             if (_XfeIsAlive(tp->items[i]))
  1854.             {
  1855.                 new_items[index]        = tp->items[i];
  1856.                 new_closed_tabs[index]    = tp->closed_tabs[i];
  1857.                 new_opened_tabs[index]    = tp->opened_tabs[i];
  1858.  
  1859.                 index++;
  1860.             }
  1861.         }
  1862.  
  1863.         if (tp->items)
  1864.         {
  1865.             XtFree((char *) tp->items);
  1866.         }
  1867.  
  1868.         if (tp->closed_tabs)
  1869.         {
  1870.             XtFree((char *) tp->closed_tabs);
  1871.         }
  1872.  
  1873.         if (tp->opened_tabs)
  1874.         {
  1875.             XtFree((char *) tp->opened_tabs);
  1876.         }
  1877.  
  1878.         tp->items        = new_items;
  1879.         tp->closed_tabs    = new_closed_tabs;
  1880.         tp->opened_tabs    = new_opened_tabs;
  1881.         tp->item_count    = new_count;
  1882.     }
  1883. }
  1884. /*----------------------------------------------------------------------*/
  1885.  
  1886. static int
  1887. FirstManagedIndex(Widget w)
  1888. {
  1889.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1890.     Cardinal                i;
  1891.  
  1892.     for (i = 0; i < tp->item_count; i++)
  1893.     {
  1894.         if (XtIsManaged(tp->items[i]))
  1895.         {
  1896.             return i;
  1897.         }
  1898.     }
  1899.  
  1900.     return -1;
  1901. }
  1902. /*----------------------------------------------------------------------*/
  1903. static int
  1904. LastManagedIndex(Widget w)
  1905. {
  1906.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1907.     Cardinal                i;
  1908.  
  1909.     for (i = (tp->item_count - 1); i >= 0; i--)
  1910.     {
  1911.         if (XtIsManaged(tp->items[i]))
  1912.         {
  1913.             return i;
  1914.         }
  1915.     }
  1916.  
  1917.     return -1;
  1918. }
  1919. /*----------------------------------------------------------------------*/
  1920. static int
  1921. NextManagedIndex(Widget w,int index)
  1922. {
  1923.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1924.     Cardinal                i;
  1925.  
  1926.     assert( CHECK_RANGE(tp,index) );
  1927.     assert( CHECK_RANGE(tp,index + 1) );
  1928.  
  1929.     for (i = (index + 1); i < tp->item_count; i++)
  1930.     {
  1931.         if (XtIsManaged(tp->items[i]))
  1932.         {
  1933.             return i;
  1934.         }
  1935.     }
  1936.  
  1937.     return -1;
  1938. }
  1939. /*----------------------------------------------------------------------*/
  1940. static int
  1941. PreviousManagedIndex(Widget w,int index)
  1942. {
  1943.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1944.     Cardinal                i;
  1945.  
  1946.     assert( CHECK_RANGE(tp,index) );
  1947.     assert( CHECK_RANGE(tp,index - 1) );
  1948.  
  1949.     for (i = (index - 1); i >= 0; i--)
  1950.     {
  1951.         if (XtIsManaged(tp->items[i]))
  1952.         {
  1953.             return i;
  1954.         }
  1955.     }
  1956.  
  1957.     return -1;
  1958. }
  1959. /*----------------------------------------------------------------------*/
  1960. static void
  1961. RaiseItem(Widget w,int index)
  1962. {
  1963.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1964.  
  1965.     assert( CHECK_RANGE(tp,index) );
  1966.     assert( _XfeIsAlive(tp->items[index]) );
  1967.     assert( _XfeIsAlive(tp->opened_tabs[index]) );
  1968.  
  1969.     XRaiseWindow(XtDisplay(w),_XfeWindow(tp->items[index]));
  1970.     XRaiseWindow(XtDisplay(w),_XfeWindow(tp->opened_tabs[index]));
  1971. }
  1972. /*----------------------------------------------------------------------*/
  1973. static void
  1974. SnapItemInPlace(Widget w,int index)
  1975. {
  1976.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  1977.     int                        last_managed_index;
  1978.     int                        first_managed_index;
  1979.     Boolean                    moved = False;
  1980.  
  1981.     assert( CHECK_RANGE(tp,index) );
  1982.     assert( _XfeIsAlive(tp->items[index]) );
  1983.     assert( _XfeIsAlive(tp->opened_tabs[index]) );
  1984.  
  1985.      first_managed_index = FirstManagedIndex(w);
  1986.     last_managed_index = LastManagedIndex(w);
  1987.  
  1988.     /* Check for the first item */
  1989.     if (index == first_managed_index)
  1990.     {
  1991.         moved = MoveItem(w,index,_XfemRectY(w));
  1992.     }
  1993.     /* Check for the last item */
  1994.     else if (index == last_managed_index)
  1995.     {
  1996.         moved = MoveItem(w,index,MaxItemY(tp->items[index]));
  1997.     }
  1998.     /* Other in-between items */
  1999.     else
  2000.     {
  2001.         int next_managed_index = NextManagedIndex(w,index);
  2002.         int previous_managed_index = PreviousManagedIndex(w,index);
  2003.  
  2004.         assert( CHECK_RANGE(tp,previous_managed_index) );
  2005.         assert( CHECK_RANGE(tp,next_managed_index) );
  2006.  
  2007.         /* Check previous item */
  2008.         if (ItemOverItem(w,index,previous_managed_index,0))
  2009.         {
  2010.             moved = MoveItem(w,
  2011.                              index,
  2012.                              _XfeY(tp->items[previous_managed_index]) + 
  2013.                              _XfeHeight(tp->items[previous_managed_index]) + 
  2014.                              tp->vertical_spacing);
  2015.         }
  2016.         /* Check next item */
  2017.         /*else if (ItemOverItem(w,index,next_managed_index,0))*/
  2018.         else
  2019.         {
  2020.             moved = MoveItem(w,
  2021.                              index,
  2022.                              _XfeY(tp->items[next_managed_index]) - 
  2023.                              _XfeHeight(tp->items[index]) - 
  2024.                              tp->vertical_spacing);
  2025.         }
  2026.     }
  2027.  
  2028.     /* Invoke snap callbacks only if the item actually moved */
  2029.     if (moved)
  2030.     {
  2031.         InvokeCallbacks(w,
  2032.                         tp->snap_callback,
  2033.                         XmCR_TOOL_BOX_SNAP,
  2034.                         NULL,
  2035.                         tp->items[index],
  2036.                         tp->closed_tabs[index],
  2037.                         tp->opened_tabs[index],
  2038.                         index);
  2039.     }
  2040. }
  2041. /*----------------------------------------------------------------------*/
  2042. static int
  2043. FindItemUnder(Widget w,int over_index)
  2044. {
  2045.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  2046.     Cardinal                i;
  2047.  
  2048.     assert( CHECK_RANGE(tp,over_index) );
  2049.  
  2050.     for (i = 0; i < tp->item_count; i++)
  2051.     {
  2052.         /* Ignore the over item */
  2053.         if (i != over_index)
  2054.         {
  2055.             if (XtIsManaged(tp->items[i]))
  2056.             {
  2057.                 if (ItemOverItem(w,over_index,i,tp->swap_threshold))
  2058.                 {
  2059.                     return i;
  2060.                 }
  2061.             }
  2062.         }
  2063.     }
  2064.  
  2065.     return -1;
  2066. }
  2067. /*----------------------------------------------------------------------*/
  2068. static Boolean
  2069. ItemOverItem(Widget w,int over_index,int under_index,Dimension threshold)
  2070. {
  2071.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  2072.     Widget                    over_item;
  2073.     Widget                    under_item;
  2074.     Position                over_y0;
  2075.     Position                over_y1;
  2076.     Position                under_y0;
  2077.     Position                under_y1;
  2078.  
  2079.     assert( CHECK_RANGE(tp,over_index) );
  2080.     assert( CHECK_RANGE(tp,under_index) );
  2081.  
  2082.     over_item = tp->items[over_index];
  2083.     under_item = tp->items[under_index];
  2084.  
  2085.     over_y0 = _XfeY(over_item);
  2086.     over_y1 = _XfeY(over_item) + _XfeHeight(over_item);
  2087.  
  2088.     under_y0 = _XfeY(under_item);
  2089.     under_y1 = _XfeY(under_item) + _XfeHeight(under_item);
  2090.  
  2091.     assert( _XfeIsAlive(over_item) );
  2092.     assert( _XfeIsAlive(under_item) );
  2093.  
  2094.     return (
  2095.  
  2096.         ((over_y1 > under_y1) && (over_y0 < under_y0)) ||
  2097.         ((over_y1 > (under_y0 + threshold)) && (over_y1 < under_y1)) ||
  2098.         ((over_y0 > under_y0) && (over_y0 < (under_y1 - threshold))) 
  2099.  
  2100.         );
  2101. }
  2102. /*----------------------------------------------------------------------*/
  2103. static void
  2104. CheckSwapThreshold(Widget w)
  2105. {
  2106.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  2107.     Cardinal                i;
  2108.  
  2109.     return;
  2110.  
  2111.     for (i = 0; i < tp->item_count; i++)
  2112.     {
  2113.         if (tp->swap_threshold > (_XfeHeight(tp->items[i]) - 4))
  2114.         {
  2115.             tp->swap_threshold = (_XfeHeight(tp->items[i]) - 4);
  2116.  
  2117.             _XfeWarning(w,MESSAGE4);
  2118.         }
  2119.     }
  2120. }
  2121. /*----------------------------------------------------------------------*/
  2122. static void
  2123. UpdatePixmaps(Widget w)
  2124. {
  2125.     XfeToolBoxPart *    tp = _XfeToolBoxPart(w);
  2126.     Cardinal            i;
  2127.     Arg                    oav[6];
  2128.     Cardinal            oac = 0;
  2129.     Arg                    cav[6];
  2130.     Cardinal            cac = 0;
  2131.  
  2132.     /* Opened - vertical */
  2133.     XtSetArg(oav[oac],XmNtopPixmap,                tp->top_pixmap); oac++;
  2134.     XtSetArg(oav[oac],XmNtopRaisedPixmap,        tp->top_raised_pixmap); oac++;
  2135.     
  2136.     XtSetArg(oav[oac],XmNbottomPixmap,            tp->bottom_pixmap); oac++;
  2137.     XtSetArg(oav[oac],XmNbottomRaisedPixmap,    tp->bottom_raised_pixmap); oac++;
  2138.     
  2139.     XtSetArg(oav[oac],XmNverticalPixmap,        tp->vertical_pixmap); oac++;
  2140.     XtSetArg(oav[oac],XmNverticalRaisedPixmap,    tp->vertical_raised_pixmap); oac++;
  2141.     
  2142.     /* Closed - horizontal */
  2143.     XtSetArg(cav[cac],XmNleftPixmap,            tp->left_pixmap); cac++;
  2144.     XtSetArg(cav[cac],XmNleftRaisedPixmap,        tp->left_raised_pixmap); cac++;
  2145.     
  2146.     XtSetArg(cav[cac],XmNrightPixmap,            tp->right_pixmap); cac++;
  2147.     XtSetArg(cav[cac],XmNrightRaisedPixmap,        tp->right_raised_pixmap); cac++;
  2148.     
  2149.     XtSetArg(cav[cac],XmNhorizontalPixmap,        tp->horizontal_pixmap); cac++;
  2150.     XtSetArg(cav[cac],XmNhorizontalRaisedPixmap,tp->horizontal_raised_pixmap); cac++;
  2151.  
  2152.     for (i = 0; i < tp->item_count; i++)
  2153.     {
  2154.         XtSetValues(tp->opened_tabs[i],oav,oac);
  2155.         XtSetValues(tp->closed_tabs[i],cav,cac);
  2156.     }
  2157. }
  2158. /*----------------------------------------------------------------------*/
  2159. static void
  2160. InvokeSwapCallbacks(Widget        w,
  2161.                     XEvent *    event,
  2162.                     Widget        swapped,
  2163.                     Widget        displaced,
  2164.                     int            from_index,
  2165.                     int            to_index)
  2166. {
  2167.     XfeToolBoxPart *    tp = _XfeToolBoxPart(w);
  2168.  
  2169.     if (tp->swap_callback)
  2170.     {
  2171.         XfeToolBoxSwapCallbackStruct cbs;
  2172.  
  2173.         cbs.reason        = XmCR_TOOL_BOX_SWAP;
  2174.         cbs.event        = event;
  2175.         cbs.swapped        = swapped;
  2176.         cbs.displaced    = displaced;
  2177.         cbs.from_index    = from_index;
  2178.         cbs.to_index    = to_index;
  2179.  
  2180.         /* Invoke the Callback List */
  2181.         XtCallCallbackList(w,tp->swap_callback,&cbs);
  2182.     }
  2183. }
  2184. /*----------------------------------------------------------------------*/
  2185. static void
  2186. InvokeCallbacks(Widget            w,
  2187.                 XtCallbackList    list,
  2188.                 int                reason,
  2189.                 XEvent *        event,
  2190.                 Widget            item,
  2191.                 Widget            closed_tab,
  2192.                 Widget            opened_tab,
  2193.                 int                index)
  2194. {
  2195.     if (list)
  2196.     {
  2197.         XfeToolBoxCallbackStruct cbs;
  2198.  
  2199.         cbs.reason        = reason;
  2200.         cbs.event        = event;
  2201.         cbs.item        = item;
  2202.         cbs.closed_tab    = closed_tab;
  2203.         cbs.opened_tab    = opened_tab;
  2204.         cbs.index        = index;
  2205.  
  2206.         XFlush(XtDisplay(w));
  2207.  
  2208.         /* Invoke the Callback List */
  2209.         XtCallCallbackList(w,list,&cbs);
  2210.     }
  2211. }
  2212. /*----------------------------------------------------------------------*/
  2213. static void
  2214. UpdatePositionIndeces(Widget w)
  2215. {
  2216.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  2217.     Cardinal                i;
  2218.     Cardinal                index = 0;
  2219.  
  2220.     /* Update the position_index contraint resource of the items */
  2221.     for (i = 0; i < tp->item_count; i++)
  2222.     {
  2223.         if (_XfeIsAlive(tp->items[i]))
  2224.         {
  2225.             _XfeManagerPositionIndex(tp->items[i]) = index;
  2226.  
  2227.             index++;
  2228.         }
  2229.     }
  2230. }
  2231. /*----------------------------------------------------------------------*/
  2232.  
  2233. /*----------------------------------------------------------------------*/
  2234. /*                                                                        */
  2235. /* Child functions                                                        */
  2236. /*                                                                        */
  2237. /*----------------------------------------------------------------------*/
  2238. static void
  2239. ChildSetDraggable(Widget w,Widget child,Boolean draggable)
  2240. {
  2241.     if (_XfeIsAlive(child))
  2242.     {
  2243.         /* First remove any event handler that might have been added */
  2244.         XtRemoveEventHandler(child,DRAG_EVENTS,True,DescendantEH,w);
  2245.  
  2246.         /* Add the event handler if needed */
  2247.         if (draggable)
  2248.         {
  2249.             XtAddEventHandler(child,DRAG_EVENTS,True,DescendantEH,w);
  2250.         }
  2251.     }
  2252. }
  2253. /*----------------------------------------------------------------------*/
  2254.  
  2255. #if 0
  2256. static void
  2257. UpdatePositionIndeces(Widget w)
  2258. {
  2259.     XfeToolBoxPart *        tp = _XfeToolBoxPart(w);
  2260.     Cardinal                i;
  2261.  
  2262.     /* Update the position_index contraint resource of the items */
  2263.     for (i = 0; i < tp->item_count; i++)
  2264.     {
  2265.         
  2266.         assert( _XfeIsAlive(tp->items[i]) );
  2267.  
  2268.         _XfeManagerPositionIndex(tp->items[i]) = i;
  2269.     }
  2270.  
  2271.  
  2272. }
  2273. /*----------------------------------------------------------------------*/
  2274. #endif
  2275. /*----------------------------------------------------------------------*/
  2276. /*                                                                        */
  2277. /* XfeToolBox Public Methods                                            */
  2278. /*                                                                        */
  2279. /*----------------------------------------------------------------------*/
  2280. /* extern */ Widget
  2281. XfeCreateToolBox(Widget parent,char *name,Arg *args,Cardinal count)
  2282. {
  2283.    return (XtCreateWidget(name,xfeToolBoxWidgetClass,parent,args,count));
  2284. }
  2285. /*----------------------------------------------------------------------*/
  2286.  
  2287. /*----------------------------------------------------------------------*/
  2288. /*                                                                        */
  2289. /* XfeToolBox drag descendant                                            */
  2290. /*                                                                        */
  2291. /*----------------------------------------------------------------------*/
  2292. /* extern */ void
  2293. XfeToolBoxAddDragDescendant(Widget w,Widget descendant)
  2294. {
  2295.     assert( _XfeIsAlive(w) );
  2296.     assert( XfeIsToolBox(w) );
  2297.     assert( _XfeIsAlive(descendant) );
  2298.  
  2299.     ChildSetDraggable(w,descendant,True);
  2300. }
  2301. /*----------------------------------------------------------------------*/
  2302. /* extern */ extern void
  2303. XfeToolBoxRemoveDragDescendant(Widget w,Widget descendant)
  2304. {
  2305.     assert( _XfeIsAlive(w) );
  2306.     assert( XfeIsToolBox(w) );
  2307.  
  2308.     ChildSetDraggable(w,descendant,False);
  2309. }
  2310. /*----------------------------------------------------------------------*/
  2311.  
  2312. /*----------------------------------------------------------------------*/
  2313. /*                                                                        */
  2314. /* XfeToolBox index methods                                                */
  2315. /*                                                                        */
  2316. /*----------------------------------------------------------------------*/
  2317. /* extern */ int
  2318. XfeToolBoxItemGetIndex(Widget w,Widget item)
  2319. {
  2320.     XfeToolBoxPart *    tp = _XfeToolBoxPart(w);
  2321.     Cardinal            i;
  2322.     
  2323.     assert( _XfeIsAlive(w) );
  2324.     assert( XfeIsToolBox(w) );
  2325.     assert( _XfeIsAlive(item) );
  2326.  
  2327.     for (i = 0; i < tp->item_count; i++)
  2328.     {
  2329.         if (item == tp->items[i])
  2330.         {
  2331.             return i;
  2332.         }
  2333.     }
  2334.  
  2335.     return -1;
  2336. }
  2337. /*----------------------------------------------------------------------*/
  2338. #if 0
  2339. /* extern */ int
  2340. XfeToolBoxTabGetIndex(Widget w,Widget tab)
  2341. {
  2342.     XfeToolBoxPart *    tp = _XfeToolBoxPart(w);
  2343.     Cardinal            i;
  2344.     
  2345.     assert( _XfeIsAlive(w) );
  2346.     assert( XfeIsToolBox(w) );
  2347.     assert( _XfeIsAlive(tab) );
  2348.  
  2349.     for (i = 0; i < tp->item_count; i++)
  2350.     {
  2351.         if ((tab == tp->closed_tabs[i]) || (tab == tp->opened_tabs[i]))
  2352.         {
  2353.             return i;
  2354.         }
  2355.     }
  2356.  
  2357.     return -1;
  2358. }
  2359. /*----------------------------------------------------------------------*/
  2360. #endif
  2361. /* extern */ Widget
  2362. XfeToolBoxItemGetByIndex(Widget w,Cardinal index)
  2363. {
  2364.     XfeToolBoxPart *    tp = _XfeToolBoxPart(w);
  2365.     
  2366.     assert( _XfeIsAlive(w) );
  2367.     assert( XfeIsToolBox(w) );
  2368.  
  2369.     if (index >= tp->item_count)
  2370.     {
  2371.         return NULL;
  2372.     }
  2373.  
  2374.     return tp->items[index];
  2375. }
  2376. /*----------------------------------------------------------------------*/
  2377. /* extern */ Widget
  2378. XfeToolBoxItemGetTab(Widget w,Widget item,Boolean opened)
  2379. {
  2380.     XfeToolBoxPart *    tp = _XfeToolBoxPart(w);
  2381.     Cardinal            i = XfeToolBoxItemGetIndex(w,item);
  2382.  
  2383.     if (i != -1)
  2384.     {
  2385.         return opened ? tp->opened_tabs[i] : tp->closed_tabs[i];
  2386.     }
  2387.  
  2388.     return NULL;
  2389. }
  2390. /*----------------------------------------------------------------------*/
  2391.  
  2392. /*----------------------------------------------------------------------*/
  2393. /*                                                                        */
  2394. /* XfeToolBox position methods                                            */
  2395. /*                                                                        */
  2396. /*----------------------------------------------------------------------*/
  2397. /* extern */ void
  2398. XfeToolBoxItemSetPosition(Widget w,Widget item,int pos)
  2399. {
  2400.     XfeToolBoxPart *    tp = _XfeToolBoxPart(w);
  2401.     int                    old_pos;
  2402.     
  2403.     assert( _XfeIsAlive(w) );
  2404.     assert( XfeIsToolBox(w) );
  2405.     assert( tp->item_count > 1 );
  2406.  
  2407.     if (pos == XmLAST_POSITION)
  2408.     {
  2409.         pos = tp->item_count - 1;
  2410.     }
  2411.  
  2412.      assert( pos < tp->item_count );
  2413.     assert( pos >= 0 );
  2414.  
  2415.     if ((tp->item_count < 2) ||
  2416.         (pos < 0) || 
  2417.         (pos >= tp->item_count) || 
  2418.         (pos == _XfeManagerPositionIndex(item)))
  2419.     {
  2420.         return;
  2421.     }
  2422.  
  2423.     /* Last position */
  2424.     if (pos == (tp->item_count - 1))
  2425.     {
  2426.         old_pos = pos - 1;
  2427.     }
  2428.     /* Between 0 and last */
  2429.     else
  2430.     {
  2431.         old_pos = pos + 1;
  2432.     }
  2433.  
  2434.     SwapItems(w,pos,old_pos);
  2435.  
  2436.     /* Update the position_index contraint member of the items */
  2437.     UpdatePositionIndeces(w);
  2438.     
  2439.     LayoutComponents(w);
  2440.     LayoutChildren(w);
  2441.  
  2442. /*     printf("Swap(%s = %d)\n",XtName(tp->items[pos]),pos); */
  2443.  
  2444.     /* Invoke the swap callbacks */
  2445.     InvokeSwapCallbacks(w,NULL,tp->items[pos],tp->items[old_pos],pos,old_pos);
  2446. }
  2447. /*----------------------------------------------------------------------*/
  2448. /* extern */ int
  2449. XfeToolBoxItemGetPosition(Widget w,Widget item)
  2450. {
  2451.     assert( _XfeIsAlive(w) );
  2452.     assert( XfeIsToolBox(w) );
  2453.  
  2454.     return _XfeManagerPositionIndex(item);
  2455. }
  2456. /*----------------------------------------------------------------------*/
  2457.  
  2458. /*----------------------------------------------------------------------*/
  2459. /*                                                                        */
  2460. /* XfeToolBox open methods                                                */
  2461. /*                                                                        */
  2462. /*----------------------------------------------------------------------*/
  2463. /* extern */ void
  2464. XfeToolBoxItemSetOpen(Widget w,Widget item,Boolean open)
  2465. {
  2466.     XfeToolBoxPart *    tp = _XfeToolBoxPart(w);
  2467.     int                    index;
  2468.     
  2469.     assert( _XfeIsAlive(w) );
  2470.     assert( XfeIsToolBox(w) );
  2471.     assert( _XfeIsAlive(item) );
  2472.     assert( tp->item_count >= 1 );
  2473.  
  2474.     index = ItemToIndex(item);
  2475.  
  2476.     assert( CHECK_RANGE(tp,index) );
  2477.     
  2478.     /* Make sure open is different */
  2479.     if (_XfeToolBoxChildOpen(tp->items[index]) == open)
  2480.     {
  2481.         return;
  2482.     }
  2483.  
  2484. #if 0
  2485.     printf("XtVaSetValues(%s,XmNopen,%s,NULL)\n",
  2486.            XtName(item),
  2487.            open ? "open" : "closed");
  2488. #endif
  2489.  
  2490.     XtVaSetValues(item,XmNopen,open,NULL);
  2491. }
  2492. /*----------------------------------------------------------------------*/
  2493. /* extern */ Boolean
  2494. XfeToolBoxItemGetOpen(Widget w,Widget item)
  2495. {
  2496.     assert( _XfeIsAlive(w) );
  2497.     assert( XfeIsToolBox(w) );
  2498.  
  2499.     return _XfeToolBoxChildOpen(item);
  2500. }
  2501. /*----------------------------------------------------------------------*/
  2502. /* extern */  void
  2503. XfeToolBoxItemToggleOpen(Widget w,Widget item)
  2504. {
  2505.     assert( _XfeIsAlive(w) );
  2506.     assert( XfeIsToolBox(w) );
  2507.  
  2508.     XfeToolBoxItemSetOpen(w,item,!_XfeToolBoxChildOpen(item));
  2509. }
  2510. /*----------------------------------------------------------------------*/
  2511.  
  2512. /*----------------------------------------------------------------------*/
  2513. /*                                                                        */
  2514. /* XfeToolBoxIsNeeded()                                                    */
  2515. /*                                                                        */
  2516. /*----------------------------------------------------------------------*/
  2517. /* extern */ Boolean
  2518. XfeToolBoxIsNeeded(Widget w)
  2519. {
  2520.     XfeToolBoxPart *    tp = _XfeToolBoxPart(w);
  2521.     Cardinal            i;
  2522.  
  2523.     assert( _XfeIsAlive(w) );
  2524.     assert( XfeIsToolBox(w) );
  2525.  
  2526.     if (tp->item_count)
  2527.     {
  2528.         for (i = 0; i < tp->item_count; i++)
  2529.         {
  2530.             /* If at least one child is shown, the tool box is needed */
  2531.             if (_XfeChildIsShown(tp->items[i]))
  2532.             {
  2533.                 return True;
  2534.             }
  2535.         }
  2536.     }
  2537.     
  2538.     return False;
  2539. }
  2540. /*----------------------------------------------------------------------*/
  2541.  
  2542. /*----------------------------------------------------------------------*/
  2543. /*                                                                        */
  2544. /* Hackery crap which should go sway real soon                            */
  2545. /*                                                                        */
  2546. /*----------------------------------------------------------------------*/
  2547. static void
  2548. FormResizeEH(Widget            form,
  2549.              XtPointer        client_data,
  2550.              XEvent *        event,
  2551.              Boolean *        cont)
  2552. {
  2553.     XfeToolBoxFormDoLayout(form);
  2554.  
  2555.     *cont = True;
  2556. }
  2557. /*----------------------------------------------------------------------*/
  2558. static void
  2559. ToolBoxTabCB(Widget w,XtPointer client_data,XtPointer call_data)
  2560. {
  2561.     XfeToolBoxFormDoLayout(XtParent(w));
  2562. }
  2563. /*----------------------------------------------------------------------*/
  2564. static void
  2565. ToolBoxChangeManagedCB(Widget w,XtPointer client_data,XtPointer call_data)
  2566. {
  2567.     XfeToolBoxFormDoLayout(XtParent(w));
  2568. }
  2569. /*----------------------------------------------------------------------*/
  2570. /* extern */ void
  2571. XfeToolBoxAddLayoutSupport(Widget form,Widget tool_box)
  2572. {
  2573.     assert( XmIsForm(form) );
  2574.     assert( XfeIsToolBox(tool_box) );
  2575.     assert( XtParent(tool_box) == form );
  2576.  
  2577.     XtAddEventHandler(form,
  2578.                       StructureNotifyMask,
  2579.                       True,
  2580.                       FormResizeEH,
  2581.                       (XtPointer) NULL);
  2582.  
  2583.     XtAddCallback(tool_box,
  2584.                   XmNopenCallback,
  2585.                   ToolBoxTabCB,
  2586.                   (XtPointer) NULL);
  2587.  
  2588.     XtAddCallback(tool_box,
  2589.                   XmNcloseCallback,
  2590.                   ToolBoxTabCB,
  2591.                   (XtPointer) NULL);
  2592.  
  2593.     XtAddCallback(tool_box,
  2594.                   XmNchangeManagedCallback,
  2595.                   ToolBoxChangeManagedCB,
  2596.                   (XtPointer) NULL);
  2597. }
  2598. /*----------------------------------------------------------------------*/
  2599. /* extern */ void
  2600. XfeToolBoxFormDoLayout(Widget form)
  2601. {
  2602.     Widget *        children;
  2603.     Cardinal        num_children;
  2604.     Widget            tool_box = NULL;
  2605.     Widget            view_area = NULL;
  2606.     Widget            above_view_area = NULL;
  2607.     Cardinal        i;
  2608.  
  2609.     Boolean            show_tool_box;
  2610.     Boolean            show_view_area;
  2611.     Boolean            show_above_view_area;
  2612.  
  2613.     /* Make sure the form is alive */
  2614.     if (!_XfeIsAlive(form))
  2615.     {
  2616.         return;
  2617.     }
  2618.  
  2619.     children = _XfemChildren(form);
  2620.     num_children = _XfemNumChildren(form);
  2621.  
  2622.     /* Make sure there is something to layout */
  2623.     if (!children || !num_children)
  2624.     {
  2625.         return;
  2626.     }
  2627.  
  2628.     assert( num_children >= 1 );
  2629.     assert( num_children <= 3 );
  2630.  
  2631.     tool_box = XfeDescendantFindByClass(form,
  2632.                                         xfeToolBoxWidgetClass,
  2633.                                         XfeFIND_ALIVE,
  2634.                                         False);
  2635.  
  2636.     /* Find the view area and above view area */
  2637.     for(i = 0; i < num_children; i++)
  2638.     {
  2639.         if (tool_box && (children[i] != tool_box))
  2640.         {
  2641.             if (!view_area)
  2642.             {
  2643.                 view_area = children[i];
  2644.             }
  2645.             else
  2646.             {
  2647.                 above_view_area = children[i];
  2648.             }
  2649.         }
  2650.     }
  2651.  
  2652.     /* Determine if we need to show the toolbox */
  2653.     show_tool_box = (_XfeIsAlive(tool_box) && XfeToolBoxIsNeeded(tool_box));
  2654.  
  2655.     /* Determine if we to need show the above view area */
  2656.     show_above_view_area = (_XfeIsAlive(above_view_area) && 
  2657.                             XtIsManaged(above_view_area));
  2658.  
  2659.     /* Determine if we need to show the view area */
  2660.     show_view_area = (_XfeIsAlive(view_area) && 
  2661.                       XtIsManaged(view_area));
  2662.     
  2663.     /* Configure the tool box */
  2664.     if (_XfeIsAlive(tool_box))
  2665.     {
  2666.         XtVaSetValues(tool_box,XmNusePreferredHeight,True,NULL);
  2667.  
  2668.         if (show_tool_box)
  2669.         {
  2670.             XtVaSetValues(tool_box,
  2671.                           XmNleftAttachment,    XmATTACH_FORM,
  2672.                           XmNrightAttachment,    XmATTACH_FORM,
  2673.                           XmNtopAttachment,        XmATTACH_FORM,
  2674.                           XmNbottomAttachment,    XmATTACH_NONE,
  2675.                           XmNtopOffset,            0,
  2676.                           NULL);
  2677.  
  2678.             _XfeResizeWidget(tool_box,
  2679.                              _XfeWidth(tool_box),
  2680.                              _XfemPreferredHeight(tool_box));
  2681.  
  2682.                XfeResize(tool_box); 
  2683.         }
  2684.         else
  2685.         {
  2686.             XtVaSetValues(tool_box,XmNtopOffset,-2,NULL);
  2687.         }
  2688.     }
  2689.     
  2690.     /* Configure the above view area */
  2691.     if (show_above_view_area)
  2692.     {
  2693.         /* 
  2694.          * We cant seem to be able to use attachments for the toolbox
  2695.          * because of the dynamic nature of the toolbox geometry.
  2696.          * It should work  but it doesn't so we do this hckery instead.
  2697.          */
  2698.         int offset = 0;
  2699.  
  2700.         /* Place after toolbox if needed */
  2701.         if (show_tool_box)
  2702.         {
  2703.             offset = _XfeX(tool_box) + _XfemPreferredHeight(tool_box);
  2704.         }
  2705.  
  2706.         XtVaSetValues(above_view_area,
  2707.                       XmNleftAttachment,    XmATTACH_FORM,
  2708.                       XmNrightAttachment,    XmATTACH_FORM,
  2709.                       XmNbottomAttachment,    XmATTACH_NONE,
  2710.                       XmNtopAttachment,        XmATTACH_FORM,
  2711.                       XmNtopOffset,            offset,
  2712.                       NULL);
  2713.     }
  2714.  
  2715.     /* Configure the view area */
  2716.     if (show_view_area)
  2717.     {
  2718.         Widget            top_widget = NULL;
  2719.         unsigned char    top_attachment;
  2720.  
  2721.         /* Place after above view area if needed */
  2722.         if (show_above_view_area)
  2723.         {
  2724.             top_widget = above_view_area;
  2725.         }
  2726.         /* Place after tool box if needed */
  2727.         else if (show_tool_box)
  2728.         {
  2729.             top_widget = tool_box;
  2730.         }
  2731.  
  2732.         top_widget        = _XfeIsAlive(top_widget) ? top_widget : NULL;
  2733.         top_attachment    = top_widget ? XmATTACH_WIDGET : XmATTACH_FORM;
  2734.  
  2735.         XtVaSetValues(view_area,
  2736.                       XmNleftAttachment,    XmATTACH_FORM,
  2737.                       XmNrightAttachment,    XmATTACH_FORM,
  2738.                       XmNbottomAttachment,    XmATTACH_FORM,
  2739.                       XmNtopAttachment,        top_attachment,
  2740.                       XmNtopWidget,            top_widget,
  2741.                       NULL);
  2742.     }
  2743. }
  2744. /*----------------------------------------------------------------------*/
  2745.