home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ool_main.zip / ool / samples / sample4 / SAMPLE4.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-10  |  19.3 KB  |  537 lines

  1. #include "sample4.h"
  2.  
  3. #define DEPARTMENT 1
  4. #define WORKER 2
  5.  
  6. #include <stdlib.h>
  7.  
  8. XIcon depIcon, empIcon;
  9. BOOL icon = FALSE;
  10. XContainerControl * contLeft, *contRight;
  11. SHORT sortType = 1;
  12.  
  13. //our class for container object, it is derived from XContainerObject
  14. class MyObjectClass: public XContainerObject
  15. {
  16.    public:
  17.       SHORT type;
  18.       MyObjectClass( XContainerControl * cont, SHORT r, SHORT columns, SHORT attr = 0):XContainerObject(cont, columns, attr) {type=r; }
  19. };
  20.  
  21. class Employe; //forward
  22.  
  23. //class Department, it holds the employes
  24. class Department: public MyObjectClass
  25. {
  26.    public:
  27.       Department( char * n, XContainerControl * cont);
  28.       SHORT count;                       //how much emps
  29.       Employe ** employe;                //list of emps
  30.       void AddEmploye( Employe *);       //methods
  31.       void RemoveEmploye( Employe*);
  32.       void Update( void );
  33. };
  34.  
  35.  
  36. Department :: Department( char * n, XContainerControl * cont): MyObjectClass( cont, DEPARTMENT, 0, 0) //CON_RECORDREADONLY
  37. {
  38.    SetTitle( n );
  39.    employe = NULL;
  40.    count = 0;
  41.    SetIcon( &depIcon );
  42. }
  43.  
  44.  
  45. //class Employe
  46. class Employe: public MyObjectClass
  47. {
  48.    public:
  49.       XString name;                      //the name
  50.       XString position;                  //what function
  51.       ULONG income;                      //how much income
  52.       Employe( char * n, char * p, ULONG in, XContainerControl * cont);
  53.       SHORT Sort( const XContainerObject * p) const; //sorting method, overridden from XContainerControl
  54.       BOOL AllocMemory( char * oldText, SHORT newTextLength, XContainerColumn* col);
  55.       void TitleEdited( const char * text, XContainerColumn *);
  56. };
  57.  
  58.  
  59. BOOL Employe :: AllocMemory( char * oldText, SHORT newTextLength, XContainerColumn* col)
  60. {
  61.    if( col->GetColumnNumber() == 0)
  62.    {
  63.       name.GetBuffer(newTextLength);
  64.       name.ReleaseBuffer(newTextLength);
  65.    } /* end if */
  66.    else if( col->GetColumnNumber() == 1)
  67.    {
  68.       position.GetBuffer(newTextLength);
  69.       position.ReleaseBuffer(newTextLength);
  70.    }
  71.    return TRUE;
  72. }
  73.  
  74. void Employe :: TitleEdited( const char * text, XContainerColumn * col)
  75. {
  76.    if( col->GetColumnNumber() == 0)
  77.       name= text;
  78.    else if( col->GetColumnNumber() == 1)
  79.       position = text;
  80. }
  81.  
  82. //if a new department is choosen, the employe-container must be updated
  83. void Department :: Update( void )
  84. {
  85.    contRight->RemoveAll( FALSE );           //remove all, but dont delete the objects
  86.  
  87.    for( int i=0; i < count; i ++)
  88.       contRight->AddObject( employe[i], NULL, NULL, FALSE );   //add the employes of this department
  89.  
  90.    //to improve performance we check if we are in icon-mode or not
  91.    if( icon )
  92.       contRight->Arrange();                    //rearrange the objects in icon-mode
  93.    else
  94.       contRight->InvalidateObject();           //draw the object in non-icon mode
  95. }
  96.  
  97.  
  98. //adds an employe to this department
  99. void Department :: AddEmploye( Employe * e)
  100. {
  101.    count += 1;
  102.    employe = (Employe**) realloc( employe, count * sizeof(void*));
  103.    employe[count-1] = e;
  104. }
  105.  
  106.  
  107. //removes an employe from this department
  108. void Department :: RemoveEmploye( Employe * e)
  109. {
  110.    BOOL swap = FALSE;
  111.  
  112.    for( int i=0; i < count-1; i++)
  113.    {
  114.       if( e == employe[i] )
  115.          swap = TRUE;
  116.       if( swap )
  117.          employe[i] = employe[i+1];
  118.    }
  119.    count -= 1;
  120. }
  121.  
  122.  
  123. //the overridden sorting-method
  124. SHORT Employe :: Sort( const XContainerObject * p) const
  125. {
  126.    Employe * e = (Employe*) p;           //typecast
  127.    if(sortType == 1)                     //sorting by income
  128.    {
  129.       if( e->income == income)
  130.          return 0;                        //income is equal
  131.       return income > e->income ? 1 : -1; //income is different
  132.    }
  133.    else
  134.       return name.StrCmp(e->name );    //sort by name
  135. }
  136.  
  137.  
  138. //constructor employe
  139. Employe::Employe(char*n, char*p, ULONG in, XContainerControl*cont): MyObjectClass( cont, WORKER, 3)
  140. {
  141.    name = n;
  142.    position = p;
  143.    income = in;
  144.    SetColumnData( 0, (char*) name);         //set column-data for detail-view, column 1
  145.    SetColumnData( 1, (char*) position);     //column 2
  146.    SetColumnData( 2, income);               //column 3
  147.    SetIcon( &empIcon );
  148.    SetTitle( (char*) name);                 //set the title for icon/name-view
  149. }
  150.  
  151.  
  152. //because we want to catch events from the containers we must generate a handler
  153. class MyHandler: public XContainerHandler
  154. {
  155.    public:
  156.       ULONG HandleEvent(XContainerEvent*);  //override this method
  157.       MyHandler( XContainerControl * c): XContainerHandler(c) { ;}
  158. };
  159.  
  160.  
  161. //our handler handles here
  162. ULONG MyHandler :: HandleEvent( XContainerEvent * e)
  163. {
  164.    static Department * dropDepartment;
  165.  
  166.    switch(e->GetEventID())               //what type of event?
  167.    {
  168.       case CON_EMPHASIS:
  169.          if( e->GetWindowID() == CONT_LEFT)
  170.          {
  171.             Department * d = (Department*) e->GetObject();
  172.             if( d->GetEmphasis() & CON_SELECTED)
  173.                d->Update( );
  174.          }
  175.          break;
  176.       case CON_CONTEXTMENU:
  177.          if( e->GetWindowID() == CONT_RIGHT)
  178.          {
  179.                   XPoint p;
  180.  
  181.                   XPopupMenu * menu = new XPopupMenu( IDM_EMPLOYE, GetWindow());
  182.  
  183.                   XRect r;
  184.                   GetWindow()->GetPointerPos( &p);
  185.  
  186.                   GetWindow()->QueryWindow(QW_PARENT)->GetSize( &r);
  187.                   p.SetX( p.GetX() - r.GetX());
  188.                   p.SetY( p.GetY() - r.GetY());
  189.  
  190.                   GetWindow()->GetSize( &r);
  191.                   p.SetX( p.GetX() - r.GetX());
  192.                   p.SetY( p.GetY() - r.GetY());
  193.                   menu->Display( &p, IDM_VIEW);
  194.                }
  195.                break;
  196.          case CON_DRAGOVER:                             //a flying object about one of our windows
  197.             if( e->GetWindowID() == CONT_LEFT)          //the left container?
  198.                {
  199.                   XContainerDragEvent * dr = (XContainerDragEvent*) e;
  200.                   XContainerObject * o;
  201.                   if( ( o = dr->GetObject()) != NULL)   //is there an object under the mouse?
  202.                      {
  203.                          if( o->GetEmphasis() & CON_SELECTED)  //yes, the current department
  204.                             dr->SetAcceptMode( DRG_NODROP );     //in this case dont accept the objects
  205.                          else
  206.                             {                                    //here is not the actual department under the mouse
  207.                                dr->SetAcceptMode( DRG_DROP );    //accept the object
  208.                                dr->SetOperation( DRG_MOVE );     //moving is our method
  209.                                dropDepartment = (Department*) o; //this department receive the object if they are dropped
  210.                             }
  211.                      }
  212.                   else
  213.                      dr->SetAcceptMode( DRG_NODROP ); //no object under the mouse, disable drop
  214.                }
  215.                return 0;
  216.          case CON_INITDRAG:                                         //initialize dragging
  217.             if( e->GetWindowID() == CONT_RIGHT)                     //the right container?
  218.               {
  219.                   SHORT i = 0;
  220.                   Employe* obj = (Employe*)e->GetObject();          //which object is under the mouse
  221.                   XContainerControl * c = (XContainerControl*) e->GetWindow();  //get a pointer to the window
  222.                   if(obj->GetEmphasis() & CON_SELECTED)           //is the object selected?
  223.                      {
  224.                          XContainerObject * o = c->GetObject();   //count the selected objects
  225.                          do
  226.                             {
  227.                                 o = c->GetObject( o, CON_SELECTED);
  228.                                 i++;
  229.                             } while( o );
  230.                      }
  231.                   else
  232.                      i=1;                                           //nothing selected, only one object to drag
  233.  
  234.                   XWindowDrag wDrag( c, i );                        //our drag-class, give a pointer to the window
  235.                                                                     //and the count of objects to be dragged
  236.                   if( i == 1)                                       //only one (non-selected) object
  237.                      {
  238.                         XDragItem item( c );                        //construct a drag-item
  239.                         wDrag.SetDragItem( &item, 0 );              //add the drag-item at the first position
  240.                         XIcon ico;
  241.                         obj->GetIcon(&ico);
  242.                         wDrag.AddImage( &ico);    //add a image
  243.                      }
  244.                   else
  245.                      {
  246.                         SHORT j=0;                                  //more than one objects to drag
  247.                         XContainerObject * o = c->GetObject();    //ask for the first selected object
  248.                         do                                          //add all selected objects
  249.                            {                                        //to the drag-class
  250.                               XDragItem item( c );                  //create a new drag-item
  251.                               wDrag.SetDragItem( &item, j );        //add it at the right position
  252.                               if( j < 5)                            //for the first 5 items an image is added (stretched)
  253.                                  {
  254.                                     XIcon ico;
  255.                                     o->GetIcon(&ico);
  256.                                     wDrag.AddImage( &ico, IMG_ICON | DRG_STRETCH, j * 10, j * 10, 40 - j * 8);
  257.                                  }
  258.                               o = c->GetObject( o, CON_SELECTED); //ask for the next selected object
  259.                               j++;
  260.                            } while( o );
  261.                      }
  262.                   if( wDrag.PerformDrag() )                         //do the drag operation
  263.                      {
  264.                         Department * d = (Department*) contLeft->GetObject(); //dragging was performed corectly
  265.                                                                                 //ask for the current department
  266.                         if( d)
  267.                            {
  268.                               if(obj->GetEmphasis() & CON_SELECTED)           // if the drag-object was selected...
  269.                                 {
  270.                                    Employe * e = (Employe*) contRight->GetObject();
  271.                                    do                                           //..do this for every selected object
  272.                                       {
  273.                                          d->RemoveEmploye( e );                 //remove the emp from the current department
  274.                                          dropDepartment->AddEmploye( e);        //add the emp to the new department
  275.                                          e = (Employe*) contRight->GetObject( e, CON_SELECTED); //get the next selected object
  276.                                       } while( e );
  277.                                 }
  278.                               else                                              //no object selected, method like above
  279.                                 {
  280.                                     d->RemoveEmploye( obj );
  281.                                     dropDepartment->AddEmploye( obj );
  282.                                 }
  283.                               d->Update( );                                     //update
  284.                            }
  285.                      }
  286.               }
  287.             break;
  288.       }
  289.    return FALSE;
  290. }
  291.  
  292.  
  293. class MyCont: public XContainerControl
  294. {
  295.    public:
  296.       MyCont( XWindow*w, XRect& r):XContainerControl( w, r, CONT_RIGHT, WIN_BORDER|WIN_VISIBLE|CON_MULTIPLESEL, "8.Helv") { ; }
  297.       BOOL DoCommand( LONG com);
  298. };
  299.  
  300.  
  301. BOOL MyCont :: DoCommand( LONG com)
  302. {
  303.    switch( com )
  304.       {
  305.          case IDM_NAME:
  306.             sortType = 0;
  307.             SortObjects();
  308.             break;
  309.          case IDM_INCOME:
  310.             sortType = 1;
  311.             SortObjects();
  312.             break;
  313.          case IDM_BITMAP:
  314.             {
  315.                XContainerInfo info;
  316.                GetInfo( &info);
  317.                BOOL bit = info.IsBackgroundPaintingEnabled();
  318.                if( bit)
  319.                   bit = FALSE;
  320.                else
  321.                   bit = TRUE;
  322.                info.EnableBackgroundPainting( bit );
  323.                SetInfo( &info);
  324.                Invalidate(TRUE);
  325.                Arrange();           //re-arrange the container
  326.             }
  327.             break;
  328.          case IDM_ICON:                        //the user selected a new view from
  329.          case IDM_DETAIL:                      //the popup-menu
  330.          case IDM_TEXT:
  331.             {
  332.                icon = FALSE;
  333.                XContainerInfo info;
  334.                GetInfo( &info);
  335.  
  336.                BOOL bit = info.IsBackgroundPaintingEnabled();
  337.  
  338.                if(com == IDM_ICON)             //icon-view requested
  339.                   {
  340.                      info.SetAttributes( CO_ICON | CO_TITLE );
  341.                      icon = TRUE;
  342.                   }
  343.                if(com == IDM_DETAIL)           //detail-view requested
  344.                   info.SetAttributes( CO_DETAIL | CO_TITLE | CO_DETAILTITLES );
  345.                if(com == IDM_TEXT)             //text-view requested
  346.                   info.SetAttributes( CO_TEXT | CO_TITLE );
  347.  
  348.                if( bit )
  349.                   info.EnableBackgroundPainting( bit );
  350.  
  351.                SetInfo( &info);
  352.                InvalidateObject();           //repaint
  353.                Arrange();           //re-arrange the container
  354.             }
  355.             break;
  356.       }
  357.    return TRUE;
  358. }
  359.  
  360.  
  361. class MyDrawHandler: public XBackgroundDrawHandler
  362. {
  363.       XBitmap * bmp;
  364.    public:
  365.       MyDrawHandler( XWindow * );
  366.       BOOL HandleEvent( XBackgroundDrawEvent *);
  367. };
  368.  
  369.  
  370. MyDrawHandler :: MyDrawHandler( XWindow * w): XBackgroundDrawHandler(w)
  371. {
  372.    bmp = new XBitmap(w);
  373.    bmp->LoadBMP( "back.bmp" );
  374. }
  375.  
  376.  
  377. BOOL MyDrawHandler :: HandleEvent( XBackgroundDrawEvent * e)
  378. {
  379.    e->Draw( bmp );
  380.    return TRUE;
  381. }
  382.  
  383.  
  384. class MyItemDrawHandler: public XItemDrawHandler
  385. {
  386.       XBitmap * greenBmp, * redBmp;
  387.    public:
  388.       MyItemDrawHandler( XWindow * );
  389.       BOOL HandleEvent( XItemDrawEvent *);
  390. };
  391.  
  392.  
  393. MyItemDrawHandler :: MyItemDrawHandler( XWindow * w): XItemDrawHandler(w, 20,20)
  394. {
  395.    //create and load two bitmaps
  396.    greenBmp = new XBitmap( w );
  397.    greenBmp->LoadBMP( "green.bmp" );
  398.  
  399.    redBmp = new XBitmap( w );
  400.    redBmp->LoadBMP( "red.bmp" );
  401. }
  402.  
  403.  
  404. BOOL MyItemDrawHandler :: HandleEvent( XItemDrawEvent * e)
  405. {
  406.    Employe * emp = ( Employe *) e->GetObject(); //ask for the object to draw
  407.  
  408.    if( ! emp )                                  //no object, the title must be redrawn
  409.       return FALSE;                             //let the container do it
  410.  
  411.    XString buffer = (LONG) emp->income;         //convert the income to a string
  412.    if( emp->income < 800 )                      //what? less than 800 ?
  413.       e->DrawItem( redBmp, (char*) buffer );            //draw a red bitmap!
  414.    else                                         //800 or more is ok (per week)
  415.       e->DrawItem( greenBmp, (char*) buffer );          //draw a green bitmap
  416.  
  417.    return TRUE;
  418. }
  419.  
  420.  
  421. MyAppWindow :: MyAppWindow( ): XFrameWindow( (ULONG) 0, "Sample4 - Container", XFrameWindow::defaultDialogStyle | FRM_TASKLIST )
  422. {
  423.    XColor c( COL_PALEGRAY);              //background-color
  424.    SetBackgroundColor( &c);
  425.    XRect re( 100, 100, 600, 400);
  426.    SetSize( &re);                        //size
  427.  
  428.    XRect r1(10,30,280, 330);             //generate a container
  429.    contLeft = new XContainerControl( this, r1, CONT_LEFT, WIN_BORDER|WIN_VISIBLE, "8.Helv");
  430.  
  431.    //setup for the container (tree view)
  432.    XContainerInfo info( "Departments", CO_TREE | CO_TITLE | CO_TREELINE );
  433.  
  434.    //we use only a very small icon
  435.    XSize size(16, 16);
  436.    info.SetBitmapSize( &size );
  437.    info.SetTreeBitmapSize( &size );
  438.  
  439.    //enable the changes
  440.    contLeft->SetInfo( &info);
  441.  
  442.    //second container
  443.    XRect r2( 300,30,280, 330);
  444.    contRight = new MyCont( this, r2);
  445.  
  446.    //setup (detail view)
  447.    XContainerInfo info2( "Employees", CO_DETAIL | CO_TITLE | CO_DETAILTITLES );//| CO_TITLEREADONLY
  448.    info2.EnableSorting();                //enable sorting
  449.    info2.EnableBackgroundPainting();     //we want to draw the background
  450.    contRight->SetInfo( &info2);
  451.  
  452.    //for detail view we genrate 3 columns in the right container:
  453.    XContainerColumn * col = new XContainerColumn( contRight, "Name", 0, COL_HORZSEPARATOR | COL_STRING | COL_SEPARATOR, COL_LEFT | COL_HORZSEPARATOR | COL_TOP );///COL_FITITLEREADONLY |
  454.    contRight->InsertColumn( col);
  455.    XContainerColumn * col2 = new XContainerColumn( contRight, "Function", 1, COL_SEPARATOR | COL_HORZSEPARATOR | COL_STRING, COL_LEFT | COL_FITITLEREADONLY | COL_HORZSEPARATOR | COL_TOP );
  456.    contRight->InsertColumn( col2, col);
  457.    //this column we draw ourselves:
  458.    XContainerColumn * col3 = new XContainerColumn( contRight, "Income", 2, COL_HORZSEPARATOR | COL_ULONG | COL_OWNERDRAW, COL_LEFT | COL_FITITLEREADONLY | COL_HORZSEPARATOR | COL_TOP );
  459.    contRight->InsertColumn( col3, col2);
  460.  
  461.    //update columns
  462.    contRight->UpdateColumns();
  463.  
  464.    //generate 3 departments and add them to the left container
  465.    Department * head = new Department( "Headquarter", contLeft);
  466.    contLeft->AddObject( head);             //this object is the root
  467.  
  468.    Department * dev = new Department( "Development", contLeft);
  469.    contLeft->AddObject( dev, head);        //headQuarter is parent of this object
  470.  
  471.    Department * sell = new Department( "Selling", contLeft);
  472.    contLeft->AddObject( sell, head);         //headQuarter is parent of this object
  473.  
  474.    contLeft->InvalidateObject();
  475.  
  476.    //generate 4 employes
  477.    Employe * e1 = new Employe( "Smith", "Manager", 900, contRight);
  478.    Employe * e2 = new Employe( "Bond", "Manager", 800, contRight);
  479.    Employe * e3 = new Employe( "Stuart", "Programmer", 500, contRight);
  480.    Employe * e4 = new Employe( "Miller", "Clerk", 300, contRight);
  481.    contRight->InvalidateObject();
  482.  
  483.    //add the employes to different departments
  484.    head->AddEmploye( e1 );
  485.    head->AddEmploye( e2 );
  486.    dev->AddEmploye( e3 );
  487.    sell->AddEmploye( e4 );
  488.  
  489.  
  490.    //generate handlers for container-events
  491.    MyHandler * h = new MyHandler( contLeft );
  492.    MyHandler * h2 = new MyHandler( contRight );
  493.  
  494.    //generate a handler to draw the background
  495.    MyDrawHandler * h3 = new MyDrawHandler( contRight );
  496.  
  497.    //generate a handler to draw the items
  498.    MyItemDrawHandler * h4 = new MyItemDrawHandler( contRight );
  499.  
  500.    //select the first department to show the content
  501.    head->Update( );
  502.  
  503.    //go!
  504.    Activate();
  505.  
  506.    ///contLeft->BeginEdit( head );//, NULL, CONT_LEFT);// CID_CNRTITLEWND );
  507.    contRight->BeginEdit( e2, col, CID_LEFTDVWND);//,
  508. }
  509.  
  510.  
  511. MyAppWindow :: ~MyAppWindow()
  512. {
  513. }
  514.  
  515.  
  516. //we only fill the background
  517. void MyAppWindow :: Draw( void )
  518. {
  519.    FillBackground( );
  520. }
  521.  
  522.  
  523. void main ( void)
  524. {
  525.    try
  526.    {
  527.       depIcon.Load( "folder.ico", TRUE);
  528.       empIcon.Load( "person.ico", TRUE);
  529.       MyAppWindow * window = new MyAppWindow( );   //create new framewindow (see above)
  530.       XApplication::GetApplication()->Start();        //let the application work
  531.    }
  532.    catch( XException e)
  533.    {
  534.       e.ShowError();
  535.    }
  536. }
  537.