home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ool.zip / OOL / samples / sample4 / SAMPLE4.CPP < prev    next >
Text File  |  1997-04-03  |  23KB  |  608 lines

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