window_manager.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:23k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: window_manager.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 21:14:47  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.3
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: window_manager.cpp,v 1000.1 2004/06/01 21:14:47 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Authors:  Andrey Yazhuk
  35.  *
  36.  * File Description:
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <gui/widgets/workspace/window_manager.hpp>
  41. #include <gui/widgets/workspace/wm_tab_control.hpp>
  42. #include <gui/widgets/workspace/wm_frame_window.hpp>
  43. #include <algorithm>
  44. BEGIN_NCBI_SCOPE
  45. DEFINE_MENU(BaseMenu)
  46.     SUBMENU("Window")
  47.         MENU_ITEM(eCmdInsHorzSplitter, "Insert Horz Splitter")
  48.         MENU_ITEM(eCmdInsVertSplitter, "Insert Vert Splitter")
  49.         MENU_ITEM(eCmdIns2x2Splitter, "Insert 2x2 Splitter")
  50.         MENU_ITEM(eCmdInsTabControl, "Insert Tab Control")
  51.     END_SUBMENU()
  52. END_MENU()
  53. BEGIN_CMD_MAP(CWindowManager, CCommandTarget)
  54.     ON_COMMAND_RANGE(eCmdInsHorzSplitter, eCmdInsTabControl, &CWindowManager::OnInsertSplitter)
  55. END_CMD_MAP()
  56. ///////////////////////////////////////////////////////////////////////////////
  57. /// CWindowManager::SClientRec
  58. CWindowManager::SClientRec::SClientRec()
  59. :   m_pClient(NULL),
  60.     m_pContainer(NULL),
  61.     m_bFrame(false)
  62. {
  63. }
  64. ///////////////////////////////////////////////////////////////////////////////
  65. /// CWindowManager
  66. CWindowManager::CWindowManager()
  67. :   Fl_Group(0, 0, 1, 1),
  68.     m_MenuRoot(NULL),
  69.     m_pRootCont(NULL),
  70.     m_PosIncr(40),
  71.     m_pObserver(NULL),
  72.     m_FrameWindow(NULL),
  73.     m_PrevFocus(NULL),
  74.     m_ActiveClient(NULL)
  75. {
  76.     end();
  77.     m_FrameX = Fl::x();
  78.     m_FrameY = Fl::y();
  79.     m_DefFrameW = Fl::w() * 3 / 5;
  80.     m_DefFrameH = Fl::h() * 3 / 5;
  81.     
  82.     static int ar_size[] = { 200, 200, -1    };
  83.     if(m_pRootCont == NULL) {
  84.         CWMTabControl* tab = new CWMTabControl(0, 0, 1, 1);
  85.         tab->SetResizePolicies(CTabControl::fShrink);
  86.         tab->SetManager(this);
  87.         m_pRootCont = tab;
  88.         add(tab);
  89.         resizable(tab);
  90.     }
  91.     m_MenuRoot = CreateMenuItems(BaseMenu);
  92. }
  93. CWindowManager::~CWindowManager()
  94. {
  95.     RemoveAllClients();
  96.     delete m_pRootCont;
  97.     /*ITERATE(TClientToRecMap, it, m_ClientToRec)  {
  98.         delete it->second;
  99.     }*/
  100.     delete m_MenuRoot;
  101. }
  102. void    CWindowManager::SetObserver(IWindowManagerObserver* observer)
  103. {
  104.     m_pObserver = observer;
  105. }
  106. Fl_Group*  CWindowManager::GetRootWMContainer()
  107. {
  108.     return dynamic_cast<Fl_Group*>(m_pRootCont);
  109. }
  110. bool    CWindowManager::AddClientInFrame(IWMClient* client)
  111. {
  112.     return x_AddClient(client, true);
  113. }
  114. bool    CWindowManager::AddClientInTab(IWMClient* client)
  115. {
  116.     return x_AddClient(client, false);
  117. }
  118. bool    CWindowManager::x_AddClient(IWMClient* client, bool b_frame)
  119. {
  120.     Fl_Widget* widget = dynamic_cast<Fl_Widget*>(client);
  121.     if(widget)  {
  122.         if(x_RegisterClient(client))    {
  123.             // menus
  124.             const CMenuItem* root = client->GetMenu();
  125.             if(root)    { // merge Client's menu into Manager's menu
  126.                 m_MenuRoot->Merge(*root);
  127.             }
  128.             if(m_FrameWindow)   { // merge Client's menu into Frame's menu
  129.                 m_FrameWindow->MergeMenu(*root);
  130.             }
  131.             // add to command routing
  132.             CCommandTarget* target = dynamic_cast<CCommandTarget*>(client);
  133.             if(target)  {
  134.                 AddChildCmdTarget(target);
  135.             }
  136.         
  137.             if(b_frame) {
  138.                 x_PutClientInFrame(client);
  139.             }   else {
  140.                 x_PutClientInTab(client);
  141.             }
  142.             return true;
  143.         }
  144.     }
  145.     _ASSERT(false);
  146.     return false;
  147. }
  148. bool    CWindowManager::MoveClientToFrame(IWMClient* client)
  149. {
  150.     if(client  &&  GetClientState(client) != eFloating)  {
  151.         x_RemoveClient(client);
  152.         x_PutClientInFrame(client);
  153.         x_UpdateObserver(client);
  154.         return true;
  155.     }
  156.     return false;
  157. }
  158. bool    CWindowManager::MoveClientToTab(IWMClient* client)
  159. {
  160.     if(client  &&  GetClientState(client) != eDocked)    {
  161.         x_RemoveClient(client);
  162.         x_PutClientInTab(client);
  163.         x_UpdateObserver(client);
  164.         return true;
  165.     }
  166.     return false;
  167. }    
  168. bool    CWindowManager::FrameCommand(IWMClient* client, EFrameCmd cmd)
  169. {
  170.     const SClientRec* p_rec = x_GetClientRec(client);
  171.     if(p_rec)   {
  172.         CWMFrameWindow* p_frame = 
  173.             dynamic_cast<CWMFrameWindow*>(p_rec->m_pContainer);
  174.         if(p_frame) {
  175.             switch(cmd) {
  176.             case    eActivate:  p_frame->show(); break;
  177.             case    eMaximize:  {
  178.                 //if(p_frame->IsMinimized())
  179.                 //    p_frame->show();
  180.                 p_frame->fullscreen(); 
  181.             };  break;
  182.             case    eMinimize:  p_frame->iconize(); break;
  183.             case    eRestore:  {
  184.                 p_frame->show();
  185.                 //p_frame->fullscreen_off();
  186.             }; break;
  187.             };
  188.         }
  189.     }
  190.     return false;
  191. }
  192. void    CWindowManager::GetPopupItems(IWMContainer* container, const IWMPosition& pos, 
  193.                                   vector<CMenuItem*>& items)
  194. {
  195.     m_PseudoCmdCount = 0;
  196.     m_PseudoCmdMap.clear();
  197.     if(container)   {
  198.         /*if(container != m_pRootCont)    {
  199.             items.push_back(new CMenuItem("Delete Container", eCmdDelContainer));
  200.             items.push_back(new CMenuItem()); // separator
  201.         }*/
  202.         if(container->IsVacant(pos))    {
  203.             items.push_back(new CMenuItem("Insert Horz Splitter", eCmdInsHorzSplitter));
  204.             items.push_back(new CMenuItem("Insert Vert Splitter", eCmdInsVertSplitter));
  205.             items.push_back(new CMenuItem("Insert 2x2 Splitter", eCmdIns2x2Splitter));
  206.             items.push_back(new CMenuItem("Insert Tab Control", eCmdInsTabControl));
  207.             
  208.             // eCmdMoveFromFrame submenu
  209.             CMenuItem* submenu = x_GetMoveFromFrameMenu(container, pos);
  210.             if(submenu) {
  211.                 items.push_back(new CMenuItem()); // separator
  212.                 items.push_back(submenu);
  213.             }
  214.             // eCmdMoveHere submenu            
  215.             submenu = x_GetMoveHereMenu(container, pos);
  216.             if(submenu) {
  217.                 items.push_back(new CMenuItem()); // separator
  218.                 items.push_back(submenu);
  219.             }
  220.         } else {
  221.             if(items.size())
  222.                 items.push_back(new CMenuItem());
  223.             
  224.             if(dynamic_cast<const CWMTabPos*>(&pos))  {
  225.                 items.push_back(new CMenuItem("Delete Tab", eCmdDelTabPane));
  226.             }
  227.             items.push_back(new CMenuItem("Move to Frame", eCmdMoveToFrame));
  228.         }
  229.     }
  230. }
  231. /// generates a pseudo-command for popup menus. PSeudo command encodes both the
  232. /// real command and the client this command should be applied to.
  233. int CWindowManager::x_GeneratePseudoCommand(IWMClient* client, int cmd)
  234. {
  235.     int pseudo_cmd = eCmdClientXXXX + m_PseudoCmdCount;
  236.     m_PseudoCmdMap[pseudo_cmd] = make_pair(client, cmd);
  237.     m_PseudoCmdCount++;
  238.     return pseudo_cmd;
  239. }
  240. CMenuItem*  CWindowManager::x_GetMoveFromFrameMenu(IWMContainer* container, 
  241.                                                    const IWMPosition& pos)
  242. {
  243.     CMenuItem* p_submenu = NULL;
  244.     if(container->IsVacant(pos)) {
  245.         int i = 0;
  246.         ITERATE(TClientToRecMap, it, m_ClientToRec) {
  247.             SClientRec* p_rec = it->second;
  248.             if(p_rec->m_pContainer  && p_rec->m_bFrame) {
  249.                 if(! p_submenu)
  250.                     p_submenu = new CMenuItem("Dock Here"); 
  251.                 
  252.                 int pcmd = x_GeneratePseudoCommand(p_rec->m_pClient, eCmdMoveFromFrame);
  253.                 p_submenu->AddSubItem(p_rec->m_pClient->GetLabel(), pcmd);
  254.             }
  255.         }
  256.     }
  257.     return p_submenu;
  258. }
  259. CMenuItem*  CWindowManager::x_GetMoveHereMenu(IWMContainer* container, 
  260.                                                    const IWMPosition& pos)
  261. {
  262.     CMenuItem* p_submenu = NULL;
  263.     if(container->IsVacant(pos)) {
  264.         int i = 0;
  265.         ITERATE(TClientToRecMap, it, m_ClientToRec) {
  266.             SClientRec* p_rec = it->second;
  267.             if(! (p_rec->m_pContainer  && p_rec->m_bFrame)) {
  268.                 if(! p_submenu)
  269.                     p_submenu = new CMenuItem("Move Here");                
  270.                 
  271.                 int pcmd = x_GeneratePseudoCommand(p_rec->m_pClient, eCmdMoveToPos);
  272.                 p_submenu->AddSubItem(p_rec->m_pClient->GetLabel(), pcmd);
  273.             }
  274.         }
  275.     }
  276.     return p_submenu;
  277. }
  278. bool    CWindowManager::OnContainerCommand(IWMContainer* container, const IWMPosition& pos, 
  279.                                            TCmdID cmd)
  280. {
  281.     if(container)   {
  282.         switch(cmd) {
  283.         case eCmdInsHorzSplitter:   {
  284.             x_InsertSplitter(container, pos, CSplitter::eHorizontal);
  285.             return true;
  286.         };
  287.         case eCmdInsVertSplitter:   {
  288.             x_InsertSplitter(container, pos, CSplitter::eVertical);
  289.             return true;
  290.         };
  291.         case eCmdIns2x2Splitter:   {
  292.             x_InsertSplitter(container, pos, CSplitter::eGrid);
  293.             return true;
  294.         };
  295.         case eCmdInsTabControl:   {
  296.             CWMTabControl* tab = new CWMTabControl(0, 0, 200, 200);
  297.             tab->SetManager(this);    
  298.             container->Insert(tab, pos);
  299.             return true;
  300.         }; break;
  301.         case eCmdDelContainer:  x_RemoveContainer(container);
  302.         case eCmdDelTabPane:    x_Remove(container, pos);   return true;
  303.         case eCmdMoveToFrame:   OnMoveToFrame(container, pos);    return true;
  304.         default: 
  305.             if(cmd >= eCmdClientXXXX  &&  cmd < eCmdClientLast)  {
  306.                 return x_OnPseudoCommand(container, pos, cmd);    
  307.             }
  308.         }
  309.     }
  310.     return false;
  311. }
  312. bool    CWindowManager::x_OnPseudoCommand(IWMContainer* container, const IWMPosition& pos, 
  313.                                            TCmdID cmd)
  314. {
  315.     TPseudoCmdMap::iterator it = m_PseudoCmdMap.find(cmd);
  316.     if(it != m_PseudoCmdMap.end())  {
  317.         IWMClient* p_client = it->second.first;
  318.         int orig_cmd = it->second.second;
  319.         
  320.         switch(orig_cmd)    {
  321.         case eCmdMoveToPos:    {
  322.             x_RemoveClient(p_client);
  323.             x_InsertClient(p_client, container, pos);
  324.             x_UpdateObserver(p_client);
  325.             return true;
  326.         }; break;
  327.         case eCmdMoveFromFrame:    {
  328.             x_RemoveClient(p_client);
  329.             x_InsertClient(p_client, container, pos);
  330.             x_UpdateObserver(p_client);
  331.             return true;
  332.         }; break;
  333.         default: break;
  334.         }; //switch
  335.     } else _ASSERT(false);
  336.     return false;
  337. }   
  338. void    CWindowManager::OnMoveToFrame(IWMContainer* container, const IWMPosition& pos)
  339. {
  340.     _ASSERT(pos.IsValid());
  341.     
  342.     Fl_Widget* widget = container->GetChild(pos);
  343.     IWMClient* p_client = dynamic_cast<IWMClient*>(widget);
  344.     if(p_client)    {
  345.         x_RemoveClient(p_client);
  346.         x_PutClientInFrame(p_client);        
  347.         x_UpdateObserver(p_client);
  348.     }
  349. }
  350. void    CWindowManager::x_InsertClient(IWMClient* client, IWMContainer* container,
  351.                                        const IWMPosition& pos)
  352. {
  353.     SClientRec* p_rec = x_GetClientRec(client);
  354.     _ASSERT(p_rec->m_pContainer == NULL);
  355.     p_rec->m_pContainer = container;
  356.     Fl_Widget* widget = dynamic_cast<Fl_Widget*>(client);
  357.     _ASSERT(widget);
  358.     container->Insert(widget, pos);
  359. }                                        
  360. /// removes Client or container from specified position
  361. void    CWindowManager::x_Remove(IWMContainer* container, const IWMPosition& pos)
  362. {
  363.     Fl_Widget* child = container->GetChild(pos);
  364.     x_CascadeRemove(container, child);
  365. }
  366. /// removes widgets from it's container and recursiveli removes all its children
  367. void    CWindowManager::x_CascadeRemove(IWMContainer* container, Fl_Widget* child)
  368. {
  369.     IWMClient* p_client = dynamic_cast<IWMClient*>(child);
  370.     if(p_client)    {
  371.         x_RemoveClient(p_client);
  372.     } else {
  373.         IWMContainer* p_cont = dynamic_cast<IWMContainer*>(child);
  374.         if(p_cont)  {
  375.             container->Remove(child);
  376.             // remove child's children 
  377.             vector<Fl_Widget*> children;
  378.             p_cont->GetChildren(children);            
  379.             for( size_t i = 0; i < children.size(); i++ )    {
  380.                 Fl_Widget* child = children[i];
  381.                 x_CascadeRemove(p_cont, child);
  382.             }
  383.             delete p_cont;
  384.         } else _ASSERT(false); // unexpected
  385.     }
  386. }
  387. void    CWindowManager::x_RemoveContainer(IWMContainer* container)
  388. {
  389.     if(container != m_pRootCont)   {
  390.         Fl_Widget* widget = dynamic_cast<Fl_Widget*>(container);
  391.         _ASSERT(widget);
  392.         IWMContainer* parent_cont = dynamic_cast<IWMContainer*>(widget->parent());
  393.         
  394.         x_CascadeRemove(parent_cont, widget);
  395.     }
  396. }
  397. void    CWindowManager::x_RemoveClient(IWMClient* client)
  398. {
  399.     SClientRec* p_rec = x_GetClientRec(client);
  400.     if(p_rec)
  401.         x_RemoveClient(p_rec);
  402. }
  403. // removes client from its current container, but does not unregister it
  404. void    CWindowManager::x_RemoveClient(SClientRec* rec)
  405. {
  406.     _ASSERT(rec);
  407.     if(rec->m_pClient == m_ActiveClient)   { // reset active client
  408.         m_ActiveClient = NULL;
  409.         m_PrevFocus = NULL;
  410.     }
  411.     
  412.     CCommandTarget* target = dynamic_cast<CCommandTarget*>(rec->m_pClient);
  413.     if(target)  { // disconnect from command routing
  414.         RemoveChildCmdTarget(target);
  415.     }
  416.     // remove from the container
  417.     Fl_Widget* widget = dynamic_cast<Fl_Widget*>(rec->m_pClient);
  418.     if(rec->m_pContainer)   {
  419.         rec->m_pContainer->Remove(widget);
  420.     
  421.         CWMFrameWindow* p_frame = dynamic_cast<CWMFrameWindow*>(rec->m_pContainer);
  422.         if(p_frame) { // if container - frame, destroy it
  423.             delete p_frame;
  424.         }
  425.         rec->m_pContainer = NULL;
  426.         rec->m_bFrame = false;
  427.     }
  428. }
  429. bool    CWindowManager::RemoveClient(IWMClient* client)
  430. {
  431.     TClientToRecMap::iterator it = m_ClientToRec.find(client);
  432.     if(it != m_ClientToRec.end())   {
  433.         SClientRec* p_rec = it->second;
  434.         x_RemoveClient(p_rec);
  435.         x_UnRegisterClient(client);
  436.         x_ResetMenu();
  437.         return true;
  438.     }
  439.     return false;
  440. }
  441. void    CWindowManager::RemoveAllClients()
  442. {
  443.     while(m_ClientToRec.size())  {
  444.         SClientRec* p_rec = m_ClientToRec.begin()->second;
  445.         x_RemoveClient(p_rec);
  446.         x_UnRegisterClient(p_rec->m_pClient);
  447.     }
  448.     x_ResetMenu();
  449. }
  450. IWMClient*  CWindowManager::GetActiveClient()
  451. {
  452.     return m_ActiveClient;
  453. }
  454. /// Regenerate Window Manager's menu and request Frame Window to reset it's menu.
  455. void    CWindowManager::x_ResetMenu()
  456. {
  457.     if(m_FrameWindow)   {
  458.         m_MenuRoot = CreateMenuItems(BaseMenu);
  459.         ITERATE(TClientToRecMap, it, m_ClientToRec) {
  460.             SClientRec* p_rec = it->second;
  461.             if(p_rec->m_pContainer)    { ///###
  462.                 const CMenuItem* root = p_rec->m_pClient->GetMenu();
  463.                 if(root)    { // merge Client's menu into Manager's menu
  464.                     m_MenuRoot->Merge(*root);
  465.                 }
  466.             }
  467.         }
  468.         
  469.         // Reseting Frame Window's will automatically request the new menu from Window Manager
  470.         // so that our changes to it will take effect
  471.         m_FrameWindow->ResetMenu();
  472.     }
  473. }
  474. // creates entry in m_ClientToRec table if it does not exist
  475. bool    CWindowManager::x_RegisterClient(IWMClient* client)
  476. {
  477.     if(client  &&  m_ClientToRec.find(client) == m_ClientToRec.end())   {
  478.         SClientRec* p_rec = new SClientRec;
  479.         p_rec->m_pClient = client;
  480.         p_rec->m_pContainer = NULL;
  481.         p_rec->m_bFrame = false;
  482.         
  483.         m_ClientToRec[client] = p_rec;
  484.         return true;
  485.     }
  486.     return false;
  487. }
  488. // deletes m_ClientToRec entry corresponding to the client
  489. bool    CWindowManager::x_UnRegisterClient(IWMClient* client)
  490. {
  491.     TClientToRecMap::iterator it = m_ClientToRec.find(client);
  492.     if(it != m_ClientToRec.end())   {
  493.         delete it->second;
  494.         m_ClientToRec.erase(it);
  495.         return true;
  496.     }
  497.     return false;
  498. }
  499. CWindowManager::EClientState    CWindowManager::GetClientState(IWMClient* client)
  500. {
  501.     SClientRec* p_rec = x_GetClientRec(client);
  502.     if(p_rec)   {
  503.         if(p_rec->m_pContainer) {
  504.             return p_rec->m_bFrame ? eFloating : eDocked;
  505.         } else  return eHidden;
  506.     }
  507.     return eInvalid;
  508. }
  509. CWindowManager::SClientRec* CWindowManager::x_GetClientRec(IWMClient* client)
  510. {
  511.     TClientToRecMap::iterator it = m_ClientToRec.find(client);
  512.     return (it == m_ClientToRec.end()) ? NULL : it->second;
  513. }
  514. /// Creates new CWMFrameWindow and inserts client into it.
  515. void    CWindowManager::x_PutClientInFrame(IWMClient* client)
  516. {    
  517.     Fl_Widget* widget = dynamic_cast<Fl_Widget*>(client);
  518.     SClientRec* p_rec = m_ClientToRec[client];
  519.     _ASSERT(widget);
  520.     
  521.     CWMFrameWindow* p_frame = 
  522.         new CWMFrameWindow(m_FrameX, m_FrameY, m_DefFrameW, m_DefFrameH, 
  523.                            widget->label());
  524.     m_FrameX += m_PosIncr;
  525.     if(m_FrameX + m_DefFrameW > Fl::x() + Fl::w())  {
  526.         m_FrameX = Fl::x();
  527.     }
  528.     m_FrameY += m_PosIncr;
  529.     if(m_FrameY + m_DefFrameH > Fl::y() + Fl::h())  {
  530.         m_FrameY = Fl::y();
  531.     }
  532.     
  533.     CWMFrameWndPos* p_pos = new CWMFrameWndPos(true);
  534.     bool b_ok = p_frame->Insert(widget, *p_pos);
  535.     _ASSERT(b_ok);
  536.     // filling SClientRec
  537.     p_rec->m_pContainer = static_cast<IWMContainer*>(p_frame);
  538.     p_rec->m_bFrame = true;
  539.     p_frame->show();
  540. }
  541. void    CWindowManager::x_PutClientInTab(IWMClient* client)
  542. {
  543.     CWMTabControl* p_tab = dynamic_cast<CWMTabControl*>(m_pRootCont);
  544.     _ASSERT(p_tab);
  545.     int index = p_tab->GetTabsCount();
  546.     CWMTabPos pos(index);
  547.     
  548.     x_InsertClient(client, m_pRootCont, pos);
  549. }
  550. void    CWindowManager::x_GetFramedClients(TClients& clients)
  551. {
  552.     clients.clear();
  553.     ITERATE(TClientToRecMap, it, m_ClientToRec) {
  554.         SClientRec* p_rec = it->second;
  555.         if(p_rec->m_bFrame) {
  556.             clients.push_back(it->first);
  557.         }
  558.     }
  559. }
  560. static int s_iColor = 0;
  561. const static int kColors = 4;
  562. static Fl_Color    GetRandomColor()
  563. {
  564.     s_iColor = (s_iColor + 1) % kColors;
  565.     switch(s_iColor)    {
  566.     case 0: return fl_rgb_color(192, 192, 255);
  567.     case 1: return fl_rgb_color(255, 192, 192);
  568.     case 2: return fl_rgb_color(192, 255, 192);
  569.     case 3: return fl_rgb_color(255, 192, 255);
  570.     }
  571.     return FL_MAGENTA;
  572. }
  573. void    CWindowManager::x_InsertSplitter(IWMContainer* container, const IWMPosition& pos, 
  574.                                          CSplitter::EMode mode)
  575. {
  576.     CWMSplitter* splitter = new CWMSplitter();
  577.     splitter->SetManager(this);
  578.     splitter->color(GetRandomColor());
  579.     container->Insert(splitter, pos);
  580.     
  581.     switch(mode)    {
  582.     case CSplitter::eHorizontal: splitter->Create(2, 1); break;
  583.     case CSplitter::eVertical:   splitter->Create(1, 2); break;
  584.     case CSplitter::eGrid:   splitter->Create(2, 2); break;
  585.     }
  586. }
  587. void    CWindowManager::x_UpdateObserver(IWMClient* client)
  588. {
  589.     if(m_pObserver)
  590.         m_pObserver->OnClientChanged(client);
  591. }
  592. const CMenuItem*    CWindowManager::GetMenu() const
  593. {
  594.     return m_MenuRoot;
  595. }
  596. void   CWindowManager::SetFrameWindow(CFrameWindow* frame)
  597. {
  598.     m_FrameWindow = frame;
  599. }
  600. bool   CWindowManager::x_ChildrenHandleCommand(const TCmdID cmd)
  601. {
  602.     // update pointer to active client
  603.     Fl_Widget* focused = Fl::focus();
  604.     if(focused != m_PrevFocus)  {
  605.         m_PrevFocus = focused;
  606.         m_ActiveClient = NULL;
  607.         //check is focused widget is our client or a child of our client
  608.         for( Fl_Widget* wid = focused; wid != NULL; wid = wid->parent())  {
  609.             IWMClient* client = dynamic_cast<IWMClient*>(wid);
  610.             if(client  &&  x_GetClientRec(client))  { // this our client
  611.                 m_ActiveClient = client;
  612.                 break;
  613.             }
  614.         }
  615.     }
  616.     bool b_handled = false;
  617.     ///### overhead
  618.     CCommandTarget* target = dynamic_cast<CCommandTarget*>(m_ActiveClient);
  619.     if(target) {
  620.         b_handled = target->OnCommand(cmd);
  621.     }
  622.     if(! b_handled) {
  623.         NON_CONST_ITERATE(TChildTargets, it, m_ChildTargets)    {            
  624.             if(*it != target  && (*it)->OnCommand(cmd))
  625.                 return true;
  626.         }
  627.     }
  628.     return b_handled;
  629. }
  630. bool   CWindowManager::x_ChildrenUpdateCommand(const TCmdID cmd, ICmdUI* pCmdUI)
  631. {
  632.     // update pointer to active client
  633.     Fl_Widget* focused = Fl::focus();
  634.     if(focused != m_PrevFocus)  {
  635.         m_PrevFocus = focused;
  636.         m_ActiveClient = NULL;
  637.         //check is focused widget is our client or a child of our client
  638.         for( Fl_Widget* wid = focused; wid != NULL; wid = wid->parent())  {
  639.             IWMClient* client = dynamic_cast<IWMClient*>(wid);
  640.             if(client  &&  x_GetClientRec(client))  { // this our client
  641.                 m_ActiveClient = client;
  642.                 break;
  643.             }
  644.         }
  645.     }
  646.     bool b_handled = false;
  647.     ///### overhead
  648.     CCommandTarget* target = dynamic_cast<CCommandTarget*>(m_ActiveClient);
  649.     if(target) {
  650.         b_handled = target->OnUpdateCommand(cmd, pCmdUI);
  651.     }
  652.     if(! b_handled) {
  653.         NON_CONST_ITERATE(TChildTargets, it, m_ChildTargets)    {            
  654.             if(*it != target  && (*it)->OnUpdateCommand(cmd, pCmdUI))
  655.                 return true;
  656.         }
  657.     }
  658.     return b_handled;
  659. }
  660. void    CWindowManager::OnInsertSplitter(TCmdID cmd)
  661. {
  662.     CWMTabPos pos(m_pRootCont->GetTabsCount());
  663.     OnContainerCommand(m_pRootCont, pos, cmd);  
  664. }
  665. END_NCBI_SCOPE
  666. /*
  667.  * ===========================================================================
  668.  * $Log: window_manager.cpp,v $
  669.  * Revision 1000.1  2004/06/01 21:14:47  gouriano
  670.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.3
  671.  *
  672.  * Revision 1.3  2004/05/21 22:27:56  gorelenk
  673.  * Added PCH ncbi_pch.hpp
  674.  *
  675.  * Revision 1.2  2004/05/07 14:26:58  yazhuk
  676.  * Inherited CWindowManager from Fl_Group, CCommandTarget; implemented IFrameWindowClient
  677.  *
  678.  * Revision 1.1  2004/02/04 19:41:55  yazhuk
  679.  * Initial revision
  680.  *
  681.  * ===========================================================================
  682.  */