/*
* 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<BaseMenuItem>;
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<BaseMenuItem> 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<BaseMenuItem> 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<BaseMenuItem> 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<BaseMenuItem> 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<BaseMenuItem> *temp_mi;
LinkedListIterator<BaseMenuItem> 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<BaseMenuItem> 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<BaseMenuItem> *temp_mi;
hide(this);
LinkedListIterator<BaseMenuItem> 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<BaseMenuItem> 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<BaseMenuItem> 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;
}
syntax highlighted by Code2HTML, v. 0.9.1