/*
* 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"
Toolbar::Toolbar()
{
font_width=0;
frame_pix=None;
clock_pix=None;
button_pix=None;
root_pix=None;
toolbarMenuVisible=False;
Month[0] = "January";
Month[1] = "February";
Month[2] = "March";
Month[3] = "April";
Month[4] = "May";
Month[5] = "June";
Month[6] = "July";
Month[7] = "August";
Month[8] = "September";
Month[9] = "October";
Month[10] = "November";
Month[11] = "December";
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 = StructureNotifyMask |
LeaveWindowMask |
ButtonPressMask |
ButtonReleaseMask |
ExposureMask;
default_button_width=15;
default_button_height=15;
createToolbarWindow();
createClockWindow();
createCycleUpButtonWindow();
createCycleDownButtonWindow();
createStartMenuButtonWindow();
tm = new ToolbarMenu();
reconfigure();
if(wm->getTheme()->getRootExtraStyle() & ROOT_ON) createRootImage();
if (wm->getTheme()->getToolbarExtraStyle())
{
XMapSubwindows(wm->getDisplay(), frame.window);
XMapWindow(wm->getDisplay(), frame.window);
}
}
Toolbar::~Toolbar()
{
wm->getImageControl()->removeImage(clock_pix);
wm->getImageControl()->removeImage(frame_pix);
wm->getImageControl()->removeImage(button_pix);
XDestroyWindow(wm->getDisplay(), clock.window);
XDestroyWindow(wm->getDisplay(), cycleUp.window);
XDestroyWindow(wm->getDisplay(), cycleDown.window);
XDestroyWindow(wm->getDisplay(), startmenu.window);
XDestroyWindow(wm->getDisplay(), frame.window);
if(root_pix) wm->getImageControl()->removeImage(root_pix);
delete tm;
}
void Toolbar::createToolbarWindow()
{
// check to see if toolbar is to be at top or bottom of the screen
// then place toolbar in correct location
if (wm->getTheme()->getToolbarExtraStyle() & TOOLBAR_TOP)
{
frame.width=wm->getXRes() / 2;
frame.height = 25;
frame.x = wm->getXRes() / 2 - frame.width / 2;
frame.y = 0;
} else {
frame.width = wm->getXRes() / 2;
frame.height = 25;
frame.x = wm->getXRes() / 2 - frame.width / 2;
frame.y = wm->getYRes() - frame.height;
}
frame.window =
XCreateWindow(wm->getDisplay(), wm->getRootWindow(), frame.x, frame.y,
frame.width, frame.height, 1, DefaultDepth(wm->getDisplay(), wm->getScreen()),
InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib);
}
void Toolbar::createClockWindow()
{
clock.x = frame.width - 160;
clock.y = 3;
clock.width = 130;
clock.height = wm->getXFont()->ascent + wm->getXFont()->descent+2;
clock.window = XCreateWindow(wm->getDisplay(), frame.window, clock.x, clock.y,
clock.width, clock.height, 1, DefaultDepth(wm->getDisplay(), wm->getScreen()),
InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib);
}
void Toolbar::createCycleUpButtonWindow()
{
cycleUp.x = 36;
cycleUp.y = 4;
cycleUp.width = default_button_width;
cycleUp.height = default_button_height;
cycleUp.window =
XCreateWindow(wm->getDisplay(), frame.window, cycleUp.x, cycleUp.y,
cycleUp.width, cycleUp.height, 1, DefaultDepth(wm->getDisplay(), wm->getScreen()),
InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib);
}
void Toolbar::createCycleDownButtonWindow()
{
cycleDown.x = 54;
cycleDown.y = 4;
cycleDown.width = default_button_width;
cycleDown.height = default_button_height;
cycleDown.window =
XCreateWindow(wm->getDisplay(), frame.window, cycleDown.x, cycleDown.y,
cycleDown.width, cycleDown.height, 1, DefaultDepth(wm->getDisplay(), wm->getScreen()),
InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib);
}
void Toolbar::createStartMenuButtonWindow()
{
startmenu.x = 10;
startmenu.y = 4;
startmenu.width = default_button_width;
startmenu.height = default_button_height;
startmenu.window =
XCreateWindow(wm->getDisplay(), frame.window, startmenu.x, startmenu.y,
startmenu.width, startmenu.height, 1, DefaultDepth(wm->getDisplay(), wm->getScreen()),
InputOutput, DefaultVisual(wm->getDisplay(), wm->getScreen()), create_mask, &attrib);
}
void Toolbar::createToolBarImage()
{
unsigned long style=0;
style = wm->getTheme()->getToolbarStyle();
frame_pix = wm->getImageControl()->renderImage(
//"toolbar_frame",
frame.width,
frame.height,
style,
wm->getTheme()->getToolbarColorFrom(),
wm->getTheme()->getToolbarColorTo()
);
XSetWindowBackgroundPixmap(wm->getDisplay(), frame.window, frame_pix);
}
void Toolbar::createButtonImage()
{
unsigned long style=0;
style = wm->getTheme()->getButtonStyle();
button_pix = wm->getImageControl()->renderImage(
//"toolbar_button",
default_button_width,
default_button_height,
style,
wm->getTheme()->getButtonColorFrom(),
wm->getTheme()->getButtonColorTo()
);
XSetWindowBackgroundPixmap(wm->getDisplay(), startmenu.window, button_pix);
XSetWindowBackgroundPixmap(wm->getDisplay(), cycleUp.window, button_pix);
XSetWindowBackgroundPixmap(wm->getDisplay(), cycleDown.window, button_pix);
}
void Toolbar::createClockImage()
{
unsigned long style=0;
style = wm->getTheme()->getClockStyle();
clock_pix = wm->getImageControl()->renderImage(
//"toolbar_clock",
clock.width,
clock.height,
style,
wm->getTheme()->getClockColorFrom(),
wm->getTheme()->getClockColorTo()
);
XSetWindowBackgroundPixmap(wm->getDisplay(), clock.window, clock_pix);
}
void Toolbar::createRootImage()
{
unsigned long style=0;
style = wm->getTheme()->getRootStyle();
root_pix = wm->getImageControl()->renderImage(
//"root",
wm->getXRes(),
wm->getYRes(),
style,
wm->getTheme()->getRootColorFrom(),
wm->getTheme()->getRootColorTo()
);
XSetWindowBackgroundPixmap(wm->getDisplay(), wm->getRootWindow(), root_pix);
XClearWindow(wm->getDisplay(), wm->getRootWindow());
}
void Toolbar::changeTheme()
{
XFreePixmap(wm->getDisplay(), clock_pix);
XFreePixmap(wm->getDisplay(), frame_pix);
XFreePixmap(wm->getDisplay(), button_pix);
if(wm->getTheme()->getRootExtraStyle() & ROOT_ON)
{
XFreePixmap(wm->getDisplay(), root_pix);
createRootImage();
}
createToolBarImage();
createButtonImage();
createClockImage();
XClearWindow(wm->getDisplay(), frame.window);
XClearWindow(wm->getDisplay(), clock.window);
redraw();
}
void Toolbar::reconfigure()
{
createToolBarImage();
createButtonImage();
createClockImage();
XClearWindow(wm->getDisplay(), frame.window);
XClearWindow(wm->getDisplay(), clock.window);
XClearWindow(wm->getDisplay(), cycleUp.window);
XClearWindow(wm->getDisplay(), cycleDown.window);
XClearWindow(wm->getDisplay(), startmenu.window);
// check to see if toolbar is to be at top or bottom of the screen
// then place toolbar in correct location
if (wm->getTheme()->getToolbarExtraStyle() & TOOLBAR_TOP)
{
frame.width=wm->getXRes() / 2;
frame.height = 25;
frame.x = wm->getXRes() / 2 - frame.width / 2;
frame.y = 0;
XMoveResizeWindow(wm->getDisplay(), frame.window, frame.x, frame.y , frame.width, frame.height);
} else {
frame.width = wm->getXRes() / 2;
frame.height = 25;
frame.x = wm->getXRes() / 2 - frame.width / 2;
frame.y = wm->getYRes() - frame.height;
XMoveResizeWindow(wm->getDisplay(), frame.window, frame.x, frame.y , frame.width, frame.height);
}
checkClock(True);
}
void Toolbar::do_button_press_event(XButtonEvent *e)
{
wm->Grab();
switch (e->button) {
case Button1:
{
if (startmenu.window == e->window)
{
popup_toolbar_menu();
break;
}
else if(cycleUp.window == e->window)
{
cycle_windows_up();
break;
} else if(cycleDown.window == e->window)
{
cycle_windows_down();
break;
}
break;
}
//case Button2:
//{
//break;
//}
//case Button3:
//{
//break;
//}
}
wm->Ungrab();
}
void Toolbar::redraw()
{
XClearWindow(wm->getDisplay(), cycleUp.window);
XClearWindow(wm->getDisplay(), cycleDown.window);
XClearWindow(wm->getDisplay(), startmenu.window);
int hh = cycleUp.height / 2, hw = cycleUp.width / 2;
XPoint cycleDownpts[3];
cycleDownpts[0].x = hw + 3;
cycleDownpts[0].y = hh -2;
cycleDownpts[1].x = -3;
cycleDownpts[1].y = 6;
cycleDownpts[2].x = -3;
cycleDownpts[2].y = -6;
XFillPolygon(wm->getDisplay(), cycleDown.window, wm->getBorderGC(), cycleDownpts, 3, Convex,
CoordModePrevious);
XPoint cycleUppts[3];
cycleUppts[0].x = hw - 4;
cycleUppts[0].y = hh + 4;
cycleUppts[1].x = 7;
cycleUppts[1].y = 0;
cycleUppts[2].x = -3;
cycleUppts[2].y = -7;
XFillPolygon(wm->getDisplay(), cycleUp.window, wm->getBorderGC(), cycleUppts, 3, Convex,
CoordModePrevious);
drawStartMenuButton();
checkClock(True);
}
void Toolbar::handle_expose_event(XExposeEvent *e)
{
if(e->count == 0) redraw();
}
void Toolbar::checkClock(bool redraw)
{
static int hour, minute, day, month, year;
time_t tmp;
struct tm *tt=NULL;
if ((tmp = time(NULL)) != -1) {
tt = localtime(&tmp);
if (tt->tm_min != minute || tt->tm_hour != hour || day != tt->tm_mday ||
month != tt->tm_mon || year != tt->tm_year) {
hour = tt->tm_hour;
minute = tt->tm_min;
day = tt->tm_mday;
month = tt->tm_mon;
year = tt->tm_year;
XClearWindow(wm->getDisplay(), clock.window);
redraw = True;
}
}
if (redraw) {
char t[25];
strftime(t, 256,wm->getClockFormat(),tt);
int len = strlen(t);
int font_width_test = XTextWidth(wm->getXFont(), t, strlen(t)) + 8;
int x_pos=0;
font_width = font_width_test;
x_pos = frame.width - font_width - 5;
clock.width = font_width;
//clock.height = wm->getXFont()->ascent + wm->getXFont()->descent * DEFAULT_SPACE - 2;
clock.height = 20;
int y_pos = 1;
createClockImage();
XMoveResizeWindow(wm->getDisplay(), clock.window, x_pos , y_pos , font_width, clock.height);
XDrawString(wm->getDisplay(), clock.window, wm->getStringGC(),
3, 25 / 2 + wm->getXFont()->descent, t, len);
}
}
void Toolbar::hideToolbar()
{
XUnmapSubwindows(wm->getDisplay(), frame.window);
}
void Toolbar::showToolbar()
{
XMapSubwindows(wm->getDisplay(), frame.window);
XMapWindow(wm->getDisplay(), frame.window);
}
void Toolbar::popup_toolbar_menu()
{
XSetWindowBorderWidth(wm->getDisplay(), startmenu.window, 2);
XEvent ev;
for (;;) {
XMaskEvent(wm->getDisplay(), ButtonReleaseMask | LeaveWindowMask, &ev);
switch (ev.type)
{
case LeaveNotify:
{
XSetWindowBorderWidth(wm->getDisplay(), startmenu.window, 1);
return;
}
case ButtonRelease:
{
XSetWindowBorderWidth(wm->getDisplay(), startmenu.window, 1);
if(! toolbarMenuVisible)
{
wm->reconfigureMenu();
toolbarMenuVisible=True;
tm->hideAllVisibleSubmenus();
tm->setAllMenuTitlesVisible(tm, False);
if(wm->getTheme()->getToolbarExtraStyle() & TOOLBAR_TOP)
tm->show(frame.x, frame.y + frame.height + 1);
else
tm->show(frame.x, frame.y - tm->getMenuHeight() - 2);
} else {
toolbarMenuVisible=False;
tm->hideAllVisibleSubmenus();
tm->setAllMenuTitlesVisible(tm, True);
}
return;
}
}
}
}
void Toolbar::cycle_windows_up()
{
XSetWindowBorderWidth(wm->getDisplay(), cycleUp.window, 2);
XEvent ev;
for (;;) {
XMaskEvent(wm->getDisplay(), ButtonReleaseMask | LeaveWindowMask, &ev);
switch (ev.type)
{
case LeaveNotify:
{
XSetWindowBorderWidth(wm->getDisplay(), cycleUp.window, 1);
return;
}
case ButtonRelease:
{
XSetWindowBorderWidth(wm->getDisplay(), cycleUp.window, 1);
XCirculateSubwindowsUp(wm->getDisplay(), wm->getRootWindow());
return;
}
}
}
}
void Toolbar::cycle_windows_down()
{
XSetWindowBorderWidth(wm->getDisplay(), cycleDown.window, 2);
XEvent ev;
for (;;) {
XMaskEvent(wm->getDisplay(), ButtonReleaseMask | LeaveWindowMask, &ev);
switch (ev.type)
{
case LeaveNotify:
{
XSetWindowBorderWidth(wm->getDisplay(), cycleDown.window, 1);
return;
}
case ButtonRelease:
{
XSetWindowBorderWidth(wm->getDisplay(), cycleDown.window, 1);
XCirculateSubwindowsDown(wm->getDisplay(), wm->getRootWindow());
return;
}
}
}
}
void Toolbar::setStartMenuButtonStateNotPressed()
{
if(toolbarMenuVisible)
{
tm->hideAllVisibleSubmenus();
toolbarMenuVisible=False;
drawStartMenuButton();
}
}
void Toolbar::drawStartMenuButton()
{
bool top = wm->getTheme()->getToolbarExtraStyle() & TOOLBAR_TOP;
XClearWindow(wm->getDisplay(), startmenu.window);
if(top)
{
if (toolbarMenuVisible)
{
// Draws a triangle pointing down
//
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
3, 6, 12, 6);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
4, 7, 11, 7);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
5, 8, 10, 8);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
6, 9, 9, 9);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
7, 10, 8, 10);
} else {
// Draws a triangle pointing up
//
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
7, 6, 8, 6);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
6, 7, 9, 7);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
5, 8, 10, 8);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
4, 9, 11, 9);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
3, 10, 12, 10);
}
} else {
if (!toolbarMenuVisible)
{
// Draws a triangle pointing down
//
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
3, 6, 12, 6);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
4, 7, 11, 7);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
5, 8, 10, 8);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
6, 9, 9, 9);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
7, 10, 8, 10);
} else {
// Draws a triangle pointing up
//
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
7, 6, 8, 6);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
6, 7, 9, 7);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
5, 8, 10, 8);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
4, 9, 11, 9);
XDrawLine(wm->getDisplay(), startmenu.window,wm->getBorderGC(),
3, 10, 12, 10);
}
}
}
// ToolbarMenu Class Definition below
ToolbarMenu::ToolbarMenu() : BaseMenu()
{
setMenuTitle("Toolbar Menu");
update_all();
wm->addToExtraMenuList(this);
}
void ToolbarMenu::addMenu(char *title, BaseMenu *sub)
{
insert(title, sub);
update_all();
}
syntax highlighted by Code2HTML, v. 0.9.1