00001 #ifdef WIN32 00002 #pragma warning(disable : 4786 ) 00003 #endif 00004 00005 #include "CSMenu.h" 00006 #include "CSPanel.h" 00007 #include "CSIcon.h" 00008 #include "CSLAF.h" 00009 #include "CSDesktop.h" 00010 #include "CSMenuItem.h" 00011 #include "CSMenuBar.h" 00012 #include "CSMessage.h" 00013 #include "CSFont.h" 00014 #include "CSLayoutManager.h" 00015 00016 const char *CSMenu::CLASS = "CSMenu"; 00017 00018 CSMenu::CSMenu(const std::string &menuTitle) : CSButton(CSTextIcon::buildIcon(menuTitle)) 00019 { 00020 static char *functionName="CSMenu"; 00021 LOG_ENTER 00022 mTitle = menuTitle; 00023 mMenuBar = 0; 00024 mMenuIsOpen = false; 00025 getLayoutDataInternal()->setPosition(POSITION_WEST); 00026 00027 mMenuPanel = new CSPanel(0, 0); 00028 mMenuPanel->setVisible(true); 00029 mMenuPanel->setLayoutManager(new CSLayoutManagerStackVertical()); 00030 CSLayoutData layout = mMenuPanel->getLayoutData(); 00031 layout.setPackedHorizontal(true); 00032 layout.setPackedVertical(true); 00033 mMenuPanel->setLayoutData(layout); 00034 mMenuPanel->setGUIType("MenuWindow"); 00035 this->setFocusable(false); 00036 mBorderState = 0; 00037 LOG_EXIT 00038 } 00039 00040 CSMenu::~CSMenu() 00041 { 00042 static char *functionName="~CSMenu"; 00043 if (mMenuPanel != 0) 00044 { 00045 delete (mMenuPanel); 00046 mMenuPanel = 0; 00047 } 00048 } 00049 00050 void CSMenu::reactOnMessage(CSMessage *message) 00051 { 00052 reactOnMessageMenu(message); 00053 } 00054 00055 void CSMenu::reactOnMessageMenu(CSMessage *message) 00056 { 00057 static char *functionName="reactOnMessage"; 00058 if (message->mIsHandled) 00059 { 00060 reactOnMessageButton(message); 00061 return; 00062 } 00063 if (message->getType() == GUI_MESSAGE) 00064 { 00065 GuiMessage *gm = (GuiMessage *) message; 00066 if (isChild(gm->receiver)) 00067 { 00068 switch (message->getSubtype()) 00069 { 00070 case MOUSE_MOTION_LOST_MESSAGE: 00071 { 00072 mBorderState = mBorderState & (~BUTTON_VISIBLE); 00073 gm->mIsHandled = true; 00074 break; 00075 } 00076 case MOUSE_MOTION_MESSAGE: 00077 { 00078 mBorderState = mBorderState | BUTTON_VISIBLE; 00079 mBorderState = mBorderState | BUTTON_HOVERING; 00080 if (getMenuBar() != 0) 00081 { 00082 if ((getMenuBar()->getMenuState(this) & BUTTON_PRESSED) == BUTTON_PRESSED) 00083 { 00084 if (getMenuBar()->getActiveMenu() != this) 00085 { 00086 mBorderState = mBorderState | BUTTON_PRESSED; 00087 getMenuBar()->setActiveMenu(this); 00088 getMenuBar()->closeLastMenu(); 00089 openMenu(); 00090 } 00091 } 00092 } 00093 gm->mIsHandled = true; 00094 break; 00095 } 00096 case MOUSE_BUTTON_PRESSED_MESSAGE: 00097 { 00098 mBorderState = mBorderState | BUTTON_PRESSED; 00099 if (getMenuBar() != 0) 00100 { 00101 getMenuBar()->setMenuState(mBorderState); 00102 getMenuBar()->setActiveMenu(this); 00103 openMenu(); 00104 } 00105 gm->mIsHandled = true; 00106 break; 00107 } 00108 } 00109 } 00110 else // receiver is not a child 00111 { 00112 switch (message->getSubtype()) 00113 { 00114 case FOCUS_LOST_MESSAGE: 00115 { 00116 if (getMenuBar() != 0) 00117 { 00118 CSGrafikElement *lastActiveMenu = 0; 00119 // check whether we just switched menus in the same menuBar 00120 // if the lastActiveMenu was ourselfs AND the component that lost 00121 // the focus was we ourself too -> than there was just a switch 00122 // in menus (if another outsider component had received the focus 00123 // we would still be the active menu!) 00124 if (getMenuBar()->getLastActiveMenu()) 00125 { 00126 lastActiveMenu = getMenuBar()->getLastActiveMenu()->mMenuPanel; 00127 } 00128 CSGrafikElement *lastFocusedComponent = gm->receiver; 00129 if (lastActiveMenu != lastFocusedComponent) 00130 { 00131 getMenuBar()->resetMenu(); 00132 mBorderState = mBorderState & (~BUTTON_VISIBLE); 00133 mBorderState = mBorderState & (~(BUTTON_PRESSED | BUTTON_HOVERING)); 00134 } 00135 00136 getMenuBar()->setMenuState(mBorderState); 00137 getMenuBar()->setActiveMenu(0); 00138 } 00139 closeMenu(); 00140 00141 gm->mIsHandled = true; 00142 } 00143 } 00144 } 00145 } 00146 } 00147 00148 int CSMenu::getButtonState() 00149 { 00150 if (getMenuBar() != 0) 00151 { 00152 return getMenuBar()->getMenuState(this); 00153 } 00154 return mBorderState; 00155 } 00156 00157 // MenuItems added are freed by CSMenu 00158 void CSMenu::addMenuItem(CSMenuItem *item) 00159 { 00160 item->setGUIType("Menu"); 00161 CSLayoutData layoutData(POSITION_ORDER_TOP); 00162 layoutData.setStretchedHorizontal(true); 00163 layoutData.setStretchedVertical(true); 00164 item->setLayoutData(layoutData); 00165 mMenuPanel->addElement(item); 00166 } 00167 00168 void CSMenu::removeMenuItem(CSMenuItem *item) 00169 { 00170 mMenuPanel->removeElement(item); 00171 } 00172 00173 void CSMenu::closeMenu() 00174 { 00175 CSDesktop *desktop = getDesktop(); 00176 if (desktop == 0) 00177 { 00178 return; 00179 } 00180 // desktop->removeElement(mMenuPanel); 00181 desktop->removeFrontElement(mMenuPanel); 00182 mMenuIsOpen = false; 00183 } 00184 00185 void CSMenu::openMenu() 00186 { 00187 if (mMenuIsOpen) 00188 { 00189 return; 00190 } 00191 if (getMenuBar() != 0) 00192 { 00193 getMenuBar()->closeLastMenu(); 00194 } 00195 CSDesktop *desktop = getDesktop(); 00196 if (desktop) 00197 { 00198 CSLAF *laf = CSLAF::getCurrentLAF(); 00199 00200 if ((getMenuBar() != 0) && (getMenuBar()->getPosition() == POSITION_SOUTH)) 00201 { 00202 int x = laf->getMenuOpenXOffset(); 00203 int y = getY() - laf->getMenuOpenYOffset() - mMenuPanel->getHeight(); 00204 translateToDesktop(x, y); 00205 desktop->addFrontElement(mMenuPanel, x, y); 00206 00207 } 00208 else 00209 { 00210 int x = laf->getMenuOpenXOffset(); 00211 int y = laf->getMenuOpenYOffset() + getHeight(); 00212 translateToDesktop(x, y); 00213 desktop->addFrontElement(mMenuPanel, x, y); 00214 } 00215 mMenuPanel->getLayoutManager()->pack(mMenuPanel); 00216 desktop->setFocusedComponent(mMenuPanel); 00217 mMenuPanel->addMessageListener(this, GUI_MESSAGE); 00218 mMenuIsOpen = true; 00219 } 00220 } 00221 00222 void CSMenu::setMenuBar(CSMenuBar *bar) 00223 { 00224 mMenuBar=bar; 00225 } 00226 00227 CSMenuBar *CSMenu::getMenuBar() 00228 { 00229 static char *functionName="setParent"; 00230 LOG_ENTER 00231 if (mMenuBar != 0) 00232 { 00233 return mMenuBar; 00234 } 00235 00236 CSGrafikElement *parent = getParent(); 00237 while (parent != 0) 00238 { 00239 std::string type = parent->getType(); 00240 if (type.compare(CSMenuBar::CLASS) == 0) 00241 { 00242 mMenuBar = (CSMenuBar *) parent; 00243 mMenuBar->setMenuState(mBorderState); 00244 break; 00245 } 00246 parent = parent->getParent(); 00247 } 00248 LOG_EXIT 00249 return mMenuBar; 00250 } 00251 00252 void CSMenu::layoutSetupMenu() 00253 { 00254 static char *functionName="layoutSetupMenu"; 00255 LOG_ENTER 00256 layoutSetupButton(); 00257 LOG_EXIT 00258 }