/* * Copyright (C) 1999,2000,2001 Frank Hale * frankhale@yahoo.com * http://sapphire.sourceforge.net/ * * Updated: 3 Nov 2001 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sapphire.hh" BaseMenu::BaseMenu() { menu_pix=None; select_pix=None; title_pix=None; select_gc = None; menu_gc = None; back_gc = None; mi = new LinkedList; menu.menuTitle="Sapphire Menu"; menu.hasTitle=False; bottom_edge=False; right_edge=False; counter=0; extra_width=0; font = XLoadQueryFont(wm->getDisplay(), wm->getTheme()->getMenuFont()); create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel | CWOverrideRedirect | CWEventMask; attrib.background_pixmap = None; attrib.background_pixel = wm->getBackgroundColor().pixel; attrib.border_pixel = wm->getBorderColor().pixel; attrib.override_redirect = True; attrib.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | EnterWindowMask | LeaveWindowMask; //gv.background = wm->getBackgroundColor().pixel; //select_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile , &gv); //back_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile, &gv); menu.x = 1; menu.y = 1; menu.x_move = 1; menu.y_move = 1; menu.height=1; menu.width=1; menu.total_item_height=1; item_width = menu.width; item_height = font->ascent + font->descent + 8; menu.window = XCreateWindow(wm->getDisplay(), wm->getRootWindow(), menu.x, menu.y, menu.width, menu.height, 1, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib); menu.title = XCreateWindow(wm->getDisplay(), menu.window, 0, 0, menu.width, item_height, 0, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib); menu.item_window = XCreateWindow(wm->getDisplay(), menu.window, 0, item_height - 2, menu.width, menu.height-item_height, 0, DefaultDepth(wm->getDisplay(), wm->getScreen()), InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib); curs = XDefineCursor(wm->getDisplay(), menu.window, XCreateFontCursor(wm->getDisplay(), XC_left_ptr)); menu.isVisible = False; curr = new BaseMenuItem(); curr = None; enterOnce = True; } BaseMenu::~BaseMenu() { mi->removeAll(); XDestroyWindow(wm->getDisplay(), menu.title); XDestroyWindow(wm->getDisplay(), menu.item_window); XDestroyWindow(wm->getDisplay(), menu.window); XFreeGC(wm->getDisplay(), menu_gc); XFreeGC(wm->getDisplay(), select_gc); XFreeGC(wm->getDisplay(), back_gc); wm->getImageControl()->removeImage(title_pix); wm->getImageControl()->removeImage(menu_pix); wm->getImageControl()->removeImage(select_pix); wm->getImageControl()->removeImage(menufont_pix); delete mi; delete curr; } // This updates all graphics contexts, gradient pixmaps and determines placement of all menu items. void BaseMenu::update_all() { LinkedListIterator it(mi); int temp_width=0; int temp_ascent=0; int temp_descent=0; unsigned int count=0; unsigned int char_count=0; menu.total_item_height=1; // If menu is created with no items lets make a few defaults // so things work out nice. if (mi->count() == 0) { char_count = strlen(menu.menuTitle); menu.width = XTextWidth(wm->getXFont(), menu.menuTitle, strlen(menu.menuTitle)); XTextExtents(font, menu.menuTitle , char_count, &direction, &ascent, &descent, &overall); temp_width = overall.width; temp_ascent = overall.ascent; temp_descent= overall.descent; menu.width = temp_width + 40; item_width = temp_ascent + temp_descent + 8; menu.height = item_height; menu.total_item_height = item_height+3; } else { //============================================================= for(; it.current(); it++) { char_count = strlen(it.current()->name); XTextExtents(font, it.current()->name , char_count, &direction, &ascent, &descent, &overall); if (char_count < strlen(menu.menuTitle)) { char_count = strlen(menu.menuTitle); XTextExtents(font, menu.menuTitle , char_count, &direction, &ascent, &descent, &overall); } if (char_count > count) { count = char_count; temp_width = overall.width; temp_ascent = overall.ascent; temp_descent= overall.descent; } menu.width = temp_width + 40; item_width = temp_ascent + temp_descent + 8; menu.height = item_height * mi->count(); it.current()->item_x = item_width/2+4; it.current()->item_y = item_height/2+4+menu.total_item_height; menu.total_item_height += item_height; } menu.total_item_height += item_height; } menu.width+=extra_width; setTitleVisible(menu.hasTitle); createMenuImage(); createMenuSelectImage(); createMenuTitleImage(); createMenuFontImage(); XClearWindow(wm->getDisplay(), menu.title); XClearWindow(wm->getDisplay(), menu.item_window); XGCValues gv; gv.tile = select_pix; select_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile , &gv); XSetFillStyle(wm->getDisplay(), select_gc, FillTiled); gv.tile = menu_pix; back_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile, &gv); XSetFillStyle(wm->getDisplay(), back_gc, FillTiled); gv.font = font->fid; gv.tile = menufont_pix; menu_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile | GCFont, &gv); XSetFillStyle(wm->getDisplay(), menu_gc, FillTiled); testMenuEdgeDetect(this); if (menu.y + menu.height >= wm->getYRes()) { bottom_edge=True; }else { bottom_edge=False; } if(bottom_edge) { XMoveWindow(wm->getDisplay(), menu.window, menu.x, wm->getYRes() - menu.height - item_height - 4); } } // This updates all graphics contexts, gradient pixmaps and determines placement of all menu items. void BaseMenu::update_menu() { LinkedListIterator it(mi); int temp_width=0; int temp_ascent=0; int temp_descent=0; unsigned int count=0; unsigned int char_count=0; menu.total_item_height=1; // If menu is created with no items lets make a few defaults // so things work out nice. if (mi->count() == 0) { char_count = strlen(menu.menuTitle); menu.width = XTextWidth(wm->getXFont(), menu.menuTitle, strlen(menu.menuTitle)); XTextExtents(font, menu.menuTitle , char_count, &direction, &ascent, &descent, &overall); temp_width = overall.width; temp_ascent = overall.ascent; temp_descent= overall.descent; menu.width = temp_width + 40; item_width = temp_ascent + temp_descent + 8; menu.height = item_height; menu.total_item_height = item_height+3; } else { //============================================================= for(; it.current(); it++) { char_count = strlen(it.current()->name); XTextExtents(font, it.current()->name , char_count, &direction, &ascent, &descent, &overall); if (char_count < strlen(menu.menuTitle)) { char_count = strlen(menu.menuTitle); XTextExtents(font, menu.menuTitle , char_count, &direction, &ascent, &descent, &overall); } if (char_count > count) { count = char_count; temp_width = overall.width; temp_ascent = overall.ascent; temp_descent= overall.descent; } menu.width = temp_width + 40; item_width = temp_ascent + temp_descent + 8; menu.height = item_height * mi->count(); it.current()->item_x = item_width/2+4; it.current()->item_y = item_height/2+4+menu.total_item_height; menu.total_item_height += item_height; } menu.total_item_height += item_height; } menu.width+=extra_width; setTitleVisible(menu.hasTitle); } void BaseMenu::hide() { XUnmapWindow(wm->getDisplay(), menu.window); } void BaseMenu::setTitleVisible(bool s) { menu.hasTitle=s; if(menu.hasTitle) { XResizeWindow(wm->getDisplay(), menu.window, menu.width, menu.total_item_height); XResizeWindow(wm->getDisplay(), menu.title, menu.width, item_height); XMoveResizeWindow(wm->getDisplay(), menu.item_window, 0, item_height, menu.width, menu.total_item_height); } else { XResizeWindow(wm->getDisplay(), menu.window, menu.width, menu.total_item_height - item_height); XResizeWindow(wm->getDisplay(), menu.title, menu.width, item_height); XMoveResizeWindow(wm->getDisplay(), menu.item_window, 0, 0, menu.width, menu.total_item_height); } } void BaseMenu::reconfigure() { XGCValues gv; XFreeFont(wm->getDisplay(), font); font = XLoadQueryFont(wm->getDisplay(), wm->getTheme()->getMenuFont()); update_menu(); XFreePixmap(wm->getDisplay(), title_pix); XFreePixmap(wm->getDisplay(), menu_pix); XFreePixmap(wm->getDisplay(), select_pix); XFreePixmap(wm->getDisplay(), menufont_pix); createMenuImage(); createMenuSelectImage(); createMenuTitleImage(); createMenuFontImage(); XClearWindow(wm->getDisplay(), menu.title); XClearWindow(wm->getDisplay(), menu.item_window); XFreeGC(wm->getDisplay(), menu_gc); XFreeGC(wm->getDisplay(), select_gc); XFreeGC(wm->getDisplay(), back_gc); gv.tile = select_pix; select_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile , &gv); XSetFillStyle(wm->getDisplay(), select_gc, FillTiled); gv.tile = menu_pix; back_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile, &gv); XSetFillStyle(wm->getDisplay(), back_gc, FillTiled); gv.font = font->fid; gv.tile = menufont_pix; menu_gc = XCreateGC(wm->getDisplay(), wm->getRootWindow(), GCTile | GCFont, &gv); XSetFillStyle(wm->getDisplay(), menu_gc, FillTiled); redraw(); } // Redraws the entire contents of the menu. void BaseMenu::redraw() { //int text_width=0; // We need an Iterator for our menu items. This lets us traverse through // the list and paint each menu item. LinkedListIterator it(mi); for(; it.current(); it++) { if(strcmp(it.current()->name, "separator")==0) { XDrawLine(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x - 14, it.current()->item_y-5, menu.width-1, it.current()->item_y-5); XDrawLine(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x - 14, it.current()->item_y-6, menu.width-1, it.current()->item_y-6); } else { XDrawString(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x, it.current()->item_y + 2, it.current()->name, strlen(it.current()->name)); if(it.current()->sub) { XDrawRectangle(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x + menu.width - 35, it.current()->item_y - 7, 8, 8); } } // Draws a bounding box around each menu item. This helped me figure out the algorithm to test which item the // pointer was over. // //XDrawRectangle(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x - 14, it.current()->item_y - 14, menu.width-1, it.current()->item_y + item_height - 15); } XDrawString(wm->getDisplay(), menu.title, menu_gc, 8, 16 , menu.menuTitle, strlen(menu.menuTitle)); //text_width=XTextWidth(wm->font, menu.menuTitle, strlen(menu.menuTitle)); //XDrawString(wm->getDisplay(), menu.title, menu_gc, // menu.width/2 - text_width/2, // 14 , // menu.menuTitle, strlen(menu.menuTitle)); } // Redraws a single menu item on the menu. void BaseMenu::redraw(BaseMenuItem *i) { if(strcmp(i->name, "separator")==0) { XDrawLine(wm->getDisplay(), menu.item_window, menu_gc, i->item_x - 14, i->item_y-5, menu.width-1, i->item_y-5); XDrawLine(wm->getDisplay(), menu.item_window, menu_gc, i->item_x - 14, i->item_y-6, menu.width-1, i->item_y-6); } else { XDrawString(wm->getDisplay(), menu.item_window, menu_gc, i->item_x, i->item_y + 2, i->name, strlen(i->name)); if(i->sub) { XDrawRectangle(wm->getDisplay(), menu.item_window, menu_gc, i->item_x + menu.width - 35, i->item_y - 7, 8, 8); } } // Draws a bounding box around each menu item. This helped me figure out the algorithm to test which item the // pointer was over. // //XDrawRectangle(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x - 14, it.current()->item_y - 14, menu.width-1, it.current()->item_y + item_height - 15); } void BaseMenu::insert(char *n, BaseMenu *sub) { BaseMenuItem *item = new BaseMenuItem(); item->name = new char[strlen(n)+1]; strcpy(item->name, n); item->sub = sub; // defaults item->isSelected=False; item->exec = ""; item->function = 0; item->item_x = item->item_y = 0; mi->insert(item); } void BaseMenu::insert(char *n, char *exec, int func) { BaseMenuItem *item = new BaseMenuItem(); char *buffer = new char[100]; if (exec[0] == '~') { sprintf(buffer, "%s%s", getenv("HOME"), exec+1); strcpy(exec, buffer); } delete [] buffer; item->exec = new char[strlen(exec)+1]; strcpy(item->exec, exec); item->name = new char[strlen(n)+1]; strcpy(item->name, n); item->function = func; // defaults item->isSelected=False; item->sub = None; item->item_x = item->item_y = 0; mi->insert(item); } void BaseMenu::insert(char *n, char *exec, BaseMenu *sub, int func) { BaseMenuItem *item = new BaseMenuItem(); char *buffer = new char[100]; if (exec[0] == '~') { sprintf(buffer, "%s%s", getenv("HOME"), exec+1); strcpy(exec, buffer); } delete [] buffer; item->exec = new char[strlen(exec)+1]; strcpy(item->exec, exec); item->name = new char[strlen(n)+1]; strcpy(item->name, n); item->isSelected=False; item->sub = sub; item->function = func; item->item_x = item->item_y = 0; mi->insert(item); } int BaseMenu::remove(BaseMenuItem* element) { mi->remove(element); return mi->count(); } void BaseMenu::removeAll() { mi->removeAll(); update_all(); } void BaseMenu::execute(char *s) { char command[strlen(s)+8]; sprintf(command, "exec %s &", s); system(command); } void BaseMenu::show() { int mouse_x=0; int mouse_y=0; // Gets the coordinates of the mouse getMousePosition(&mouse_x, &mouse_y); // Check to make sure menu will be displayed on the screen. if (mouse_x + menu.width > wm->getXRes()) { menu.x = wm->getXRes() - menu.width - 1; right_edge=True; } else { menu.x = mouse_x; right_edge=False; } if (mouse_y + menu.height > wm->getYRes()) { menu.y = wm->getYRes() - menu.height - item_height - 4; bottom_edge=True; }else { menu.y = mouse_y; bottom_edge=False; } // Move the menu to the position of the mouse pointer XMoveWindow(wm->getDisplay(), menu.window, menu.x, menu.y); // Show the menu windows XMapRaised(wm->getDisplay(), menu.window); XMapSubwindows(wm->getDisplay(),menu.window); menu.isVisible=True; } void BaseMenu::getMousePosition(int *x, int *y) { Window dw1=None; Window dw2=None; int t1=0; int t2=0; unsigned int t3=0; XQueryPointer(wm->getDisplay(), wm->getRootWindow(), &dw1, &dw2, x, y, &t1, &t2, &t3); } void BaseMenu::show(int x, int y) { menu.x = x; menu.y = y; XMoveWindow(wm->getDisplay(), menu.window, x, y); // Show the menu windows XMapSubwindows(wm->getDisplay(),menu.window); XMapRaised(wm->getDisplay(), menu.window); XClearWindow(wm->getDisplay(), menu.item_window); menu.isVisible=True; } void BaseMenu::showSub(BaseMenu *sub, int x, int y) { sub->menu.x = x; sub->menu.y = y; XMoveWindow(wm->getDisplay(), sub->menu.window, x, y); // Show the menu windows XMapSubwindows(wm->getDisplay(), sub->menu.window); XMapRaised(wm->getDisplay(), sub->menu.window); sub->menu.isVisible=True; } void BaseMenu::hide(BaseMenu *sub) { if (sub->menu.isVisible) { // hide the menu windows XUnmapSubwindows(wm->getDisplay(), sub->menu.window); XUnmapWindow(wm->getDisplay(), sub->menu.window); sub->menu.isVisible=False; } } BaseMenuItem *BaseMenu::findMenuItem(int x, int y) { int item_xpos2=0; int item_ypos2=0; if(mi->count()) { LinkedListIterator it(mi); for(; it.current(); it++) { // Draws a bounding box around each menu item. This helped me figure out the algorithm to test which item the // pointer was over. // //XDrawRectangle(wm->getDisplay(), menu.item_window, menu_gc, it.current()->item_x - 14, // it.current()->item_y - 14, menu.width-1, it.current()->item_y + item_height - 15); item_xpos2 = menu.width-1; item_ypos2 = it.current()->item_y + item_height - 15; if ( (x >= it.current()->item_x - 14) && (x < item_xpos2) && (y >= it.current()->item_y - 14) && (y < item_ypos2) ) { return it.current(); } } } return NULL; } void BaseMenu::handle_button_press_event(XButtonEvent *e) { switch (e->button) { case Button1: { if(e->window == menu.title) move(); else if (curr) handle_button1_press(curr); break; } case Button2: { if(curr) handle_button2_press(curr); break; } case Button3: { if (curr) handle_button3_press(curr); break; } } } void BaseMenu::handle_button_release_event(XButtonEvent *e) { switch (e->button) { case Button1: { if (curr) { handle_button1_release(curr); switch( curr->function ) { // function 1 is wm shutdown case 1: { wm->quit_nicely(); } break; case 2: // do nothing this is a menu separator { } break; case 3: // This will start another window manager { //wm->start_another_windowmanager(curr->exec); } break; case 4: // restart Sapphire { wm->restart(); } break; case 5: // reconfigure Sapphire (theme, menu) { wm->reconfigureMenu(); } break; case 6: // change theme { Toolbar *t = wm->getToolbar(); t->setStartMenuButtonStateNotPressed(); t->getToolbarMenu()->hide(t->getToolbarMenu()); wm->getRootMenu()->hideAllVisibleSubmenus(); wm->changeTheme(curr->exec); } break; default: // Default is to execute a command or file { Toolbar *t = wm->getToolbar(); t->setStartMenuButtonStateNotPressed(); t->getToolbarMenu()->hide(t->getToolbarMenu()); wm->getRootMenu()->hideAllVisibleSubmenus(); execute(curr->exec); } break; } } break; } case Button2: { if (curr) handle_button2_release(curr); break; } case Button3: { if(e->window == menu.title) hideAllVisibleSubmenus(); else if (curr) handle_button3_release(curr); break; } } } void BaseMenu::move() { wm->setMenu(this); wm->setMenuEvent(true); } void BaseMenu::setMenuPos(int x, int y) { menu.x = x; menu.y = y; XMoveWindow(wm->getDisplay(), menu.window, x, y); } void BaseMenu::handle_enter_notify(XCrossingEvent *e) { if(curr) { LinkedList *temp_mi; LinkedListIterator it(mi); for(; it.current(); it++) { if (it.current()->sub && it.current()->sub->menu.isVisible) { it.current()->sub->hide(it.current()->sub); temp_mi = it.current()->sub->mi; LOOP: LinkedListIterator n(temp_mi); for(; n.current(); n++) { if(n.current()->sub && n.current()->sub->menu.isVisible) { n.current()->sub->hide(n.current()->sub); temp_mi = n.current()->sub->mi; goto LOOP; } } } } XFillRectangle(wm->getDisplay(), menu.item_window, select_gc, 0, curr->item_y - 15, item_width - item_height - 2, item_height - 1 ); if(curr->sub) { testMenuEdgeDetect(curr->sub); if(curr->sub->right_edge) { if(curr->sub->bottom_edge) showSub(curr->sub,menu.x - curr->sub->menu.width - 1, wm->getYRes() - curr->sub->menu.height - 27); else showSub(curr->sub,menu.x - curr->sub->menu.width - 1, menu.y + curr->item_y - 15); } else { if(curr->sub->bottom_edge) { showSub(curr->sub,menu.x + menu.width + 1, wm->getYRes() - curr->sub->menu.height - 27); } else { showSub(curr->sub,menu.x + menu.width + 1, menu.y + curr->item_y - 15); } } } redraw(curr); } } void BaseMenu::handle_leave_notify(XCrossingEvent *e) { if(curr) { XFillRectangle(wm->getDisplay(), menu.item_window, back_gc, 0, curr->item_y -15, item_width - item_height - 2, item_height - 1); redraw(curr); curr = NULL; } } void BaseMenu::hideAllVisibleSubmenus() { LinkedList *temp_mi; hide(this); LinkedListIterator it(mi); for(; it.current(); it++) { if (it.current()->sub && it.current()->sub->menu.isVisible) { it.current()->sub->hide(it.current()->sub); temp_mi = it.current()->sub->mi; LOOP: // Yuck I'm using a goto... ;-( LinkedListIterator n(temp_mi); for(; n.current(); n++) { if(n.current()->sub && n.current()->sub->menu.isVisible) { n.current()->sub->hide(n.current()->sub); temp_mi = n.current()->sub->mi; goto LOOP; } } } } } void BaseMenu::setAllMenuTitlesVisible(BaseMenu *sub, bool s) { sub->setTitleVisible(s); LinkedListIterator it(sub->mi); for(; it.current(); it++) { if (it.current()->sub) setAllMenuTitlesVisible(it.current()->sub, s); } } void BaseMenu::handle_expose_event(XExposeEvent *e) { if(e->count == 0) redraw(); } void BaseMenu::handle_motion_notify_event(XMotionEvent *e) { // for moving the menu. menu.x_move = e->x; menu.y_move = e->y; //---------------------- XEvent temp; if(e->window == menu.title) { /* DO NOTHING */ } else if(e->window == menu.item_window) { BaseMenuItem *i = findMenuItem(e->x, e->y); if (i && enterOnce) { curr = i; if(! strcmp(i->name, "separator")==0) handle_enter_notify(&temp.xcrossing); enterOnce=False; } else { BaseMenuItem *i = findMenuItem(e->x, e->y); if (i != curr) { handle_leave_notify(&temp.xcrossing); curr = i; enterOnce=True; } } } } void BaseMenu::handle_config_notify_event(XConfigureEvent *e) { } void BaseMenu::createMenuImage() { unsigned long style=0; style = wm->getTheme()->getMenuStyle(); menu_pix = wm->getImageControl()->renderImage( //"menu_frame", menu.width, menu.height, style, wm->getTheme()->getMenuColorFrom(), wm->getTheme()->getMenuColorTo() ); XSetWindowBackgroundPixmap(wm->getDisplay(), menu.item_window, menu_pix); } void BaseMenu::createMenuSelectImage() { unsigned long style=0; style = wm->getTheme()->getMenuSelectStyle(); select_pix = wm->getImageControl()->renderImage( //"menu_select", menu.width, item_height, style, wm->getTheme()->getMenuSelectColorFrom(), wm->getTheme()->getMenuSelectColorTo() ); } void BaseMenu::createMenuFontImage() { unsigned long style=0; style = wm->getTheme()->getFontStyle(); menufont_pix = wm->getImageControl()->renderImage( //"menu_font", font->ascent, font->descent, style, wm->getTheme()->getMenuFontColorFrom(), wm->getTheme()->getMenuFontColorTo() ); } void BaseMenu::createMenuTitleImage() { unsigned long style=0; style = wm->getTheme()->getMenuTitleStyle(); title_pix = wm->getImageControl()->renderImage( //"menu_title", menu.width, item_height+1, style, wm->getTheme()->getMenuTitleColorFrom(), wm->getTheme()->getMenuTitleColorTo() ); XSetWindowBackgroundPixmap(wm->getDisplay(), menu.title, title_pix); } void BaseMenu::testMenuEdgeDetect(BaseMenu *sub) { int mouse_x=0; int mouse_y=0; bool rightEdge=False; bool bottomEdge=False; // Gets the coordinates of the mouse getMousePosition(&mouse_x, &mouse_y); rightEdge = ( ( this->menu.x + sub->menu.width + 150 ) < (wm->getXRes()) ) ? True : False; bottomEdge = ( mouse_y + sub->menu.height >= wm->getYRes() ) ? True : False; // Check to make sure menu will be displayed on the screen. if (rightEdge) sub->right_edge=False; else sub->right_edge=True; if (bottomEdge) sub->bottom_edge=True; else sub->bottom_edge=False; }