openbox/src/Toolbar.cc

1199 lines
36 KiB
C++
Raw Normal View History

// -*- mode: C++; indent-tabs-mode: nil; -*-
// Toolbar.cc for Blackbox - an X11 Window manager
// Copyright (c) 2001 - 2002 Sean 'Shaleh' Perry <shaleh@debian.org>
2002-04-11 03:20:38 +00:00
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#ifdef HAVE_CONFIG_H
# include "../config.h"
#endif // HAVE_CONFIG_H
extern "C" {
2002-04-11 03:20:38 +00:00
#include <X11/keysym.h>
#ifdef HAVE_STRING_H
2002-04-11 03:20:38 +00:00
# include <string.h>
#endif // HAVE_STRING_H
2002-04-11 03:20:38 +00:00
#ifdef HAVE_STDIO_H
# include <stdio.h>
#endif // HAVE_STDIO_H
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else // !TIME_WITH_SYS_TIME
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else // !HAVE_SYS_TIME_H
# include <time.h>
# endif // HAVE_SYS_TIME_H
#endif // TIME_WITH_SYS_TIME
}
2002-04-11 03:20:38 +00:00
#include <string>
using std::string;
#include "i18n.hh"
#include "blackbox.hh"
#include "Clientmenu.hh"
2002-07-03 06:34:25 +00:00
#include "Font.hh"
#include "GCCache.hh"
#include "Iconmenu.hh"
#include "Image.hh"
#include "Rootmenu.hh"
#include "Screen.hh"
#include "Toolbar.hh"
#include "Window.hh"
#include "Workspace.hh"
#include "Workspacemenu.hh"
#include "Slit.hh"
static long aMinuteFromNow(void) {
timeval now;
gettimeofday(&now, 0);
return ((60 - (now.tv_sec % 60)) * 1000);
}
Toolbar::Toolbar(BScreen *scrn) {
screen = scrn;
blackbox = screen->getBlackbox();
toolbarstr = (string)"session.screen" + itostring(screen->getScreenNumber())
+ ".toolbar.";
config = blackbox->getConfig();
load_rc();
2002-04-11 03:20:38 +00:00
// get the clock updating every minute
clock_timer = new BTimer(blackbox, this);
clock_timer->setTimeout(aMinuteFromNow());
clock_timer->recurring(True);
2002-04-11 03:20:38 +00:00
clock_timer->start();
frame.minute = frame.hour = -1;
2002-04-11 03:20:38 +00:00
hide_handler.toolbar = this;
hide_timer = new BTimer(blackbox, &hide_handler);
hide_timer->setTimeout(blackbox->getAutoRaiseDelay());
2002-04-11 03:20:38 +00:00
editing = False;
2002-04-11 03:20:38 +00:00
new_name_pos = 0;
frame.grab_x = frame.grab_y = 0;
toolbarmenu = new Toolbarmenu(this);
2002-04-11 03:20:38 +00:00
display = blackbox->getXDisplay();
2002-04-11 03:20:38 +00:00
XSetWindowAttributes attrib;
unsigned long create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel |
CWColormap | CWOverrideRedirect | CWEventMask;
2002-04-11 03:20:38 +00:00
attrib.background_pixmap = None;
attrib.background_pixel = attrib.border_pixel =
screen->getBorderColor()->pixel();
attrib.colormap = screen->getColormap();
2002-04-11 03:20:38 +00:00
attrib.override_redirect = True;
attrib.event_mask = ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask;
2002-04-11 03:20:38 +00:00
frame.window =
XCreateWindow(display, screen->getRootWindow(), 0, 0, 1, 1, 0,
screen->getDepth(), InputOutput, screen->getVisual(),
create_mask, &attrib);
blackbox->saveToolbarSearch(frame.window, this);
2002-04-11 03:20:38 +00:00
attrib.event_mask = ButtonPressMask | ButtonReleaseMask | ExposureMask |
KeyPressMask | EnterWindowMask;
2002-04-11 03:20:38 +00:00
frame.workspace_label =
XCreateWindow(display, frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
InputOutput, screen->getVisual(), create_mask, &attrib);
blackbox->saveToolbarSearch(frame.workspace_label, this);
2002-04-11 03:20:38 +00:00
frame.window_label =
XCreateWindow(display, frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
InputOutput, screen->getVisual(), create_mask, &attrib);
blackbox->saveToolbarSearch(frame.window_label, this);
2002-04-11 03:20:38 +00:00
frame.clock =
XCreateWindow(display, frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
InputOutput, screen->getVisual(), create_mask, &attrib);
blackbox->saveToolbarSearch(frame.clock, this);
2002-04-11 03:20:38 +00:00
frame.psbutton =
XCreateWindow(display ,frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
InputOutput, screen->getVisual(), create_mask, &attrib);
blackbox->saveToolbarSearch(frame.psbutton, this);
2002-04-11 03:20:38 +00:00
frame.nsbutton =
XCreateWindow(display ,frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
InputOutput, screen->getVisual(), create_mask, &attrib);
blackbox->saveToolbarSearch(frame.nsbutton, this);
2002-04-11 03:20:38 +00:00
frame.pwbutton =
XCreateWindow(display ,frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
InputOutput, screen->getVisual(), create_mask, &attrib);
blackbox->saveToolbarSearch(frame.pwbutton, this);
2002-04-11 03:20:38 +00:00
frame.nwbutton =
XCreateWindow(display ,frame.window, 0, 0, 1, 1, 0, screen->getDepth(),
InputOutput, screen->getVisual(), create_mask, &attrib);
blackbox->saveToolbarSearch(frame.nwbutton, this);
2002-04-11 03:20:38 +00:00
frame.base = frame.label = frame.wlabel = frame.clk = frame.button =
frame.pbutton = None;
screen->addStrut(&strut);
2002-04-11 03:20:38 +00:00
reconfigure();
2002-05-27 05:06:04 +00:00
mapToolbar();
}
Toolbar::~Toolbar(void) {
2002-05-27 05:06:04 +00:00
unmapToolbar();
2002-04-11 03:20:38 +00:00
if (frame.base) screen->getImageControl()->removeImage(frame.base);
if (frame.label) screen->getImageControl()->removeImage(frame.label);
if (frame.wlabel) screen->getImageControl()->removeImage(frame.wlabel);
if (frame.clk) screen->getImageControl()->removeImage(frame.clk);
if (frame.button) screen->getImageControl()->removeImage(frame.button);
if (frame.pbutton) screen->getImageControl()->removeImage(frame.pbutton);
blackbox->removeToolbarSearch(frame.window);
blackbox->removeToolbarSearch(frame.workspace_label);
blackbox->removeToolbarSearch(frame.window_label);
blackbox->removeToolbarSearch(frame.clock);
blackbox->removeToolbarSearch(frame.psbutton);
blackbox->removeToolbarSearch(frame.nsbutton);
blackbox->removeToolbarSearch(frame.pwbutton);
blackbox->removeToolbarSearch(frame.nwbutton);
2002-04-11 03:20:38 +00:00
XDestroyWindow(display, frame.workspace_label);
XDestroyWindow(display, frame.window_label);
XDestroyWindow(display, frame.clock);
XDestroyWindow(display, frame.window);
delete hide_timer;
delete clock_timer;
delete toolbarmenu;
}
2002-05-27 05:06:04 +00:00
void Toolbar::mapToolbar() {
if (!screen->doHideToolbar()) {
//not hidden, so windows should not maximize over the toolbar
XMapSubwindows(display, frame.window);
XMapWindow(display, frame.window);
}
updateStrut();
}
void Toolbar::unmapToolbar() {
if (toolbarmenu->isVisible())
toolbarmenu->hide();
//hidden so we can maximize over the toolbar
XUnmapWindow(display, frame.window);
updateStrut();
}
void Toolbar::saveOnTop(bool b) {
on_top = b;
config->setValue(toolbarstr + "onTop", on_top);
}
void Toolbar::saveAutoHide(bool b) {
do_auto_hide = b;
config->setValue(toolbarstr + "autoHide", do_auto_hide);
}
void Toolbar::saveWidthPercent(unsigned int w) {
width_percent = w;
config->setValue(toolbarstr + "widthPercent", width_percent);
}
void Toolbar::savePlacement(int p) {
placement = p;
const char *pname;
switch (placement) {
case TopLeft: pname = "TopLeft"; break;
case BottomLeft: pname = "BottomLeft"; break;
case TopCenter: pname = "TopCenter"; break;
case TopRight: pname = "TopRight"; break;
case BottomRight: pname = "BottomRight"; break;
case BottomCenter: default: pname = "BottomCenter"; break;
}
config->setValue(toolbarstr + "placement", pname);
}
void Toolbar::save_rc(void) {
saveOnTop(on_top);
saveAutoHide(do_auto_hide);
saveWidthPercent(width_percent);
savePlacement(placement);
}
void Toolbar::load_rc(void) {
string s;
if (! config->getValue(toolbarstr + "onTop", on_top))
on_top = false;
if (! config->getValue(toolbarstr + "autoHide", do_auto_hide))
do_auto_hide = false;
hidden = do_auto_hide;
if (! config->getValue(toolbarstr + "widthPercent", width_percent) ||
width_percent == 0 || width_percent > 100)
width_percent = 66;
if (config->getValue(toolbarstr + "placement", s)) {
if (s == "TopLeft")
placement = TopLeft;
else if (s == "BottomLeft")
placement = BottomLeft;
else if (s == "TopCenter")
placement = TopCenter;
else if (s == "TopRight")
placement = TopRight;
else if (s == "BottomRight")
placement = BottomRight;
else //if (s == "BottomCenter")
placement = BottomCenter;
} else
placement = BottomCenter;
}
void Toolbar::reconfigure(void) {
2002-07-03 06:34:25 +00:00
unsigned int width, height;
width = (screen->getWidth() * width_percent) / 100;
height = screen->getToolbarStyle()->font->height();
frame.bevel_w = screen->getBevelWidth();
frame.button_w = height;
height += 2;
frame.label_h = height;
height += (frame.bevel_w * 2);
frame.rect.setSize(width, height);
int x, y;
switch (placement) {
2002-04-11 03:20:38 +00:00
case TopLeft:
case TopRight:
case TopCenter:
if (placement == TopLeft)
x = 0;
else if (placement == TopRight)
x = screen->getWidth() - frame.rect.width()
- (screen->getBorderWidth() * 2);
else
x = (screen->getWidth() - frame.rect.width()) / 2;
2002-04-11 03:20:38 +00:00
y = 0;
2002-04-11 03:20:38 +00:00
frame.x_hidden = x;
frame.y_hidden = screen->getBevelWidth() - screen->getBorderWidth()
- frame.rect.height();
2002-04-11 03:20:38 +00:00
break;
case BottomLeft:
case BottomRight:
2002-04-11 03:20:38 +00:00
case BottomCenter:
default:
if (placement == BottomLeft)
x = 0;
else if (placement == BottomRight)
x = screen->getWidth() - frame.rect.width()
- (screen->getBorderWidth() * 2);
else
x = (screen->getWidth() - frame.rect.width()) / 2;
2002-04-11 03:20:38 +00:00
y = screen->getHeight() - frame.rect.height()
- (screen->getBorderWidth() * 2);
2002-04-11 03:20:38 +00:00
frame.x_hidden = x;
frame.y_hidden = screen->getHeight() - screen->getBevelWidth()
- screen->getBorderWidth();
2002-04-11 03:20:38 +00:00
break;
}
frame.rect.setPos(x, y);
updateStrut();
2002-04-11 03:20:38 +00:00
#ifdef HAVE_STRFTIME
time_t ttmp = time(NULL);
frame.clock_w = 0;
2002-04-11 03:20:38 +00:00
if (ttmp != -1) {
struct tm *tt = localtime(&ttmp);
2002-04-11 03:20:38 +00:00
if (tt) {
char t[1024];
int len = strftime(t, 1024, screen->getStrftimeFormat(), tt);
if (len == 0) { // invalid time format found
screen->saveStrftimeFormat("%I:%M %p"); // so use the default
2002-07-03 06:34:25 +00:00
strftime(t, 1024, screen->getStrftimeFormat(), tt);
}
// find the length of the rendered string and add room for two extra
// characters to it. This allows for variable width output of the fonts
2002-07-03 06:34:25 +00:00
BFont *font = screen->getToolbarStyle()->font;
frame.clock_w = font->measureString(t) + font->maxCharWidth() * 2;
2002-04-11 03:20:38 +00:00
}
}
#else // !HAVE_STRFTIME
2002-07-03 06:34:25 +00:00
{
string s = i18n(ToolbarSet, ToolbarNoStrftimeLength, "00:00000");
frame.clock_w = screen->getToolbarStyle()->font->measureString(s);
}
2002-04-11 03:20:38 +00:00
#endif // HAVE_STRFTIME
frame.workspace_label_w = 0;
for (unsigned int i = 0; i < screen->getWorkspaceCount(); i++) {
const string& workspace_name = screen->getWorkspace(i)->getName();
2002-07-03 06:34:25 +00:00
width = screen->getToolbarStyle()->font->measureString(workspace_name);
if (width > frame.workspace_label_w) frame.workspace_label_w = width;
}
frame.workspace_label_w = frame.clock_w =
std::max(frame.workspace_label_w, frame.clock_w) + (frame.bevel_w * 4);
// XXX: where'd the +6 come from?
frame.window_label_w =
(frame.rect.width() - (frame.clock_w + (frame.button_w * 4) +
frame.workspace_label_w + (frame.bevel_w * 8) + 6));
if (hidden) {
XMoveResizeWindow(display, frame.window, frame.x_hidden, frame.y_hidden,
frame.rect.width(), frame.rect.height());
} else {
XMoveResizeWindow(display, frame.window, frame.rect.x(), frame.rect.y(),
frame.rect.width(), frame.rect.height());
}
XMoveResizeWindow(display, frame.workspace_label, frame.bevel_w,
frame.bevel_w, frame.workspace_label_w,
frame.label_h);
XMoveResizeWindow(display, frame.psbutton,
((frame.bevel_w * 2) + frame.workspace_label_w + 1),
frame.bevel_w + 1, frame.button_w, frame.button_w);
XMoveResizeWindow(display, frame.nsbutton,
((frame.bevel_w * 3) + frame.workspace_label_w +
frame.button_w + 2), frame.bevel_w + 1, frame.button_w,
frame.button_w);
XMoveResizeWindow(display, frame.window_label,
((frame.bevel_w * 4) + (frame.button_w * 2) +
frame.workspace_label_w + 3), frame.bevel_w,
frame.window_label_w, frame.label_h);
XMoveResizeWindow(display, frame.pwbutton,
((frame.bevel_w * 5) + (frame.button_w * 2) +
frame.workspace_label_w + frame.window_label_w + 4),
frame.bevel_w + 1, frame.button_w, frame.button_w);
XMoveResizeWindow(display, frame.nwbutton,
((frame.bevel_w * 6) + (frame.button_w * 3) +
frame.workspace_label_w + frame.window_label_w + 5),
frame.bevel_w + 1, frame.button_w, frame.button_w);
XMoveResizeWindow(display, frame.clock,
frame.rect.width() - frame.clock_w - (frame.bevel_w * 2),
frame.bevel_w, frame.clock_w, frame.label_h);
ToolbarStyle *style = screen->getToolbarStyle();
frame.base = style->toolbar.render(frame.rect.width(), frame.rect.height(),
frame.base);
if (! frame.base)
XSetWindowBackground(display, frame.window,
style->toolbar.color().pixel());
else
XSetWindowBackgroundPixmap(display, frame.window, frame.base);
frame.label = style->window.render(frame.window_label_w, frame.label_h,
frame.label);
if (! frame.label)
XSetWindowBackground(display, frame.window_label,
style->window.color().pixel());
else
XSetWindowBackgroundPixmap(display, frame.window_label, frame.label);
frame.wlabel = style->label.render(frame.workspace_label_w, frame.label_h,
frame.wlabel);
if (! frame.wlabel)
XSetWindowBackground(display, frame.workspace_label,
style->label.color().pixel());
else
XSetWindowBackgroundPixmap(display, frame.workspace_label, frame.wlabel);
frame.clk = style->clock.render(frame.clock_w, frame.label_h, frame.clk);
if (! frame.clk)
XSetWindowBackground(display, frame.clock, style->clock.color().pixel());
else
XSetWindowBackgroundPixmap(display, frame.clock, frame.clk);
frame.button = style->button.render(frame.button_w, frame.button_w,
frame.button);
if (! frame.button) {
frame.button_pixel = style->button.color().pixel();
XSetWindowBackground(display, frame.psbutton, frame.button_pixel);
XSetWindowBackground(display, frame.nsbutton, frame.button_pixel);
XSetWindowBackground(display, frame.pwbutton, frame.button_pixel);
XSetWindowBackground(display, frame.nwbutton, frame.button_pixel);
} else {
XSetWindowBackgroundPixmap(display, frame.psbutton, frame.button);
XSetWindowBackgroundPixmap(display, frame.nsbutton, frame.button);
XSetWindowBackgroundPixmap(display, frame.pwbutton, frame.button);
XSetWindowBackgroundPixmap(display, frame.nwbutton, frame.button);
}
frame.pbutton = style->pressed.render(frame.button_w, frame.button_w,
frame.pbutton);
if (! frame.pbutton)
frame.pbutton_pixel = style->pressed.color().pixel();
XSetWindowBorder(display, frame.window,
screen->getBorderColor()->pixel());
XSetWindowBorderWidth(display, frame.window, screen->getBorderWidth());
XClearWindow(display, frame.window);
XClearWindow(display, frame.workspace_label);
XClearWindow(display, frame.window_label);
XClearWindow(display, frame.clock);
XClearWindow(display, frame.psbutton);
XClearWindow(display, frame.nsbutton);
XClearWindow(display, frame.pwbutton);
XClearWindow(display, frame.nwbutton);
redrawWindowLabel();
redrawWorkspaceLabel();
redrawPrevWorkspaceButton();
redrawNextWorkspaceButton();
redrawPrevWindowButton();
redrawNextWindowButton();
checkClock(True);
toolbarmenu->reconfigure();
}
void Toolbar::updateStrut(void) {
// left and right are always 0
strut.top = strut.bottom = 0;
2002-06-21 01:06:29 +00:00
// when hidden only one border is visible
unsigned int border_width = screen->getBorderWidth();
if (! do_auto_hide)
border_width *= 2;
2002-05-27 05:06:04 +00:00
if (! screen->doHideToolbar()) {
switch(placement) {
case TopLeft:
case TopCenter:
case TopRight:
2002-06-21 01:06:29 +00:00
strut.top = getExposedHeight() + border_width;
2002-05-27 05:06:04 +00:00
break;
default:
2002-06-21 01:06:29 +00:00
strut.bottom = getExposedHeight() + border_width;
2002-05-27 05:06:04 +00:00
}
}
screen->updateAvailableArea();
2002-04-11 03:20:38 +00:00
}
#ifdef HAVE_STRFTIME
void Toolbar::checkClock(bool redraw) {
2002-04-11 03:20:38 +00:00
#else // !HAVE_STRFTIME
void Toolbar::checkClock(bool redraw, bool date) {
2002-04-11 03:20:38 +00:00
#endif // HAVE_STRFTIME
time_t tmp = 0;
struct tm *tt = 0;
if ((tmp = time(NULL)) != -1) {
if (! (tt = localtime(&tmp))) return;
if (tt->tm_min != frame.minute || tt->tm_hour != frame.hour) {
frame.hour = tt->tm_hour;
frame.minute = tt->tm_min;
XClearWindow(display, frame.clock);
redraw = True;
2002-04-11 03:20:38 +00:00
}
}
2002-04-11 03:20:38 +00:00
if (redraw) {
2002-04-11 03:20:38 +00:00
#ifdef HAVE_STRFTIME
char t[1024];
if (! strftime(t, 1024, screen->getStrftimeFormat(), tt))
return;
2002-04-11 03:20:38 +00:00
#else // !HAVE_STRFTIME
char t[9];
if (date) {
// format the date... with special consideration for y2k ;)
if (screen->getDateFormat() == Blackbox::B_EuropeanDate)
sprintf(t, 18n(ToolbarSet, ToolbarNoStrftimeDateFormatEu,
"%02d.%02d.%02d"),
tt->tm_mday, tt->tm_mon + 1,
(tt->tm_year >= 100) ? tt->tm_year - 100 : tt->tm_year);
else
sprintf(t, i18n(ToolbarSet, ToolbarNoStrftimeDateFormat,
"%02d/%02d/%02d"),
tt->tm_mon + 1, tt->tm_mday,
(tt->tm_year >= 100) ? tt->tm_year - 100 : tt->tm_year);
} else {
if (screen->isClock24Hour())
sprintf(t, i18n(ToolbarSet, ToolbarNoStrftimeTimeFormat24,
" %02d:%02d "),
frame.hour, frame.minute);
else
sprintf(t, i18n(ToolbarSet, ToolbarNoStrftimeTimeFormat12,
"%02d:%02d %sm"),
((frame.hour > 12) ? frame.hour - 12 :
((frame.hour == 0) ? 12 : frame.hour)), frame.minute,
((frame.hour >= 12) ?
i18n(ToolbarSet, ToolbarNoStrftimeTimeFormatP, "p") :
i18n(ToolbarSet, ToolbarNoStrftimeTimeFormatA, "a")));
}
2002-04-11 03:20:38 +00:00
#endif // HAVE_STRFTIME
ToolbarStyle *style = screen->getToolbarStyle();
2002-04-11 03:20:38 +00:00
2002-07-03 06:34:25 +00:00
int pos = frame.bevel_w * 2; // this is modified by doJustify()
style->doJustify(t, pos, frame.clock_w, frame.bevel_w * 4);
style->font->drawString(frame.clock, pos, 1, style->c_text, t);
}
}
2002-04-11 03:20:38 +00:00
void Toolbar::redrawWindowLabel(bool redraw) {
BlackboxWindow *foc = screen->getBlackbox()->getFocusedWindow();
if (! foc) {
XClearWindow(display, frame.window_label);
return;
2002-04-11 03:20:38 +00:00
}
if (redraw)
XClearWindow(display, frame.window_label);
2002-04-11 03:20:38 +00:00
if (foc->getScreen() != screen) return;
2002-04-11 03:20:38 +00:00
const char *title = foc->getTitle();
ToolbarStyle *style = screen->getToolbarStyle();
2002-04-11 03:20:38 +00:00
2002-07-03 06:34:25 +00:00
int pos = frame.bevel_w * 2; // modified by doJustify()
style->doJustify(title, pos, frame.window_label_w, frame.bevel_w * 4);
style->font->drawString(frame.window_label, pos, 1, style->w_text, title);
}
2002-04-11 03:20:38 +00:00
void Toolbar::redrawWorkspaceLabel(bool redraw) {
const string& name = screen->getCurrentWorkspace()->getName();
2002-04-11 03:20:38 +00:00
if (redraw)
XClearWindow(display, frame.workspace_label);
2002-04-11 03:20:38 +00:00
ToolbarStyle *style = screen->getToolbarStyle();
2002-04-11 03:20:38 +00:00
2002-07-03 06:34:25 +00:00
int pos = frame.bevel_w * 2;
style->doJustify(name.c_str(), pos, frame.workspace_label_w,
frame.bevel_w * 4);
style->font->drawString(frame.workspace_label, pos, 1, style->l_text, name);
}
2002-04-11 03:20:38 +00:00
void Toolbar::redrawPrevWorkspaceButton(bool pressed, bool redraw) {
if (redraw) {
if (pressed) {
if (frame.pbutton)
XSetWindowBackgroundPixmap(display, frame.psbutton, frame.pbutton);
2002-04-11 03:20:38 +00:00
else
XSetWindowBackground(display, frame.psbutton, frame.pbutton_pixel);
} else {
if (frame.button)
XSetWindowBackgroundPixmap(display, frame.psbutton, frame.button);
else
XSetWindowBackground(display, frame.psbutton, frame.button_pixel);
2002-04-11 03:20:38 +00:00
}
XClearWindow(display, frame.psbutton);
2002-04-11 03:20:38 +00:00
}
int hh = frame.button_w / 2, hw = frame.button_w / 2;
2002-04-11 03:20:38 +00:00
XPoint pts[3];
pts[0].x = hw - 2; pts[0].y = hh;
pts[1].x = 4; pts[1].y = 2;
pts[2].x = 0; pts[2].y = -4;
2002-04-11 03:20:38 +00:00
ToolbarStyle *style = screen->getToolbarStyle();
2002-07-03 06:34:25 +00:00
BPen pen(style->b_pic);
XFillPolygon(display, frame.psbutton, pen.gc(),
pts, 3, Convex, CoordModePrevious);
}
2002-04-11 03:20:38 +00:00
void Toolbar::redrawNextWorkspaceButton(bool pressed, bool redraw) {
if (redraw) {
if (pressed) {
if (frame.pbutton)
XSetWindowBackgroundPixmap(display, frame.nsbutton, frame.pbutton);
else
XSetWindowBackground(display, frame.nsbutton, frame.pbutton_pixel);
} else {
if (frame.button)
XSetWindowBackgroundPixmap(display, frame.nsbutton, frame.button);
else
XSetWindowBackground(display, frame.nsbutton, frame.button_pixel);
}
XClearWindow(display, frame.nsbutton);
2002-04-11 03:20:38 +00:00
}
int hh = frame.button_w / 2, hw = frame.button_w / 2;
2002-04-11 03:20:38 +00:00
XPoint pts[3];
pts[0].x = hw - 2; pts[0].y = hh - 2;
pts[1].x = 4; pts[1].y = 2;
pts[2].x = -4; pts[2].y = 2;
2002-04-11 03:20:38 +00:00
ToolbarStyle *style = screen->getToolbarStyle();
2002-07-03 06:34:25 +00:00
BPen pen(style->b_pic);
XFillPolygon(display, frame.nsbutton, pen.gc(),
pts, 3, Convex, CoordModePrevious);
}
2002-04-11 03:20:38 +00:00
void Toolbar::redrawPrevWindowButton(bool pressed, bool redraw) {
if (redraw) {
if (pressed) {
if (frame.pbutton)
XSetWindowBackgroundPixmap(display, frame.pwbutton, frame.pbutton);
else
XSetWindowBackground(display, frame.pwbutton, frame.pbutton_pixel);
} else {
if (frame.button)
XSetWindowBackgroundPixmap(display, frame.pwbutton, frame.button);
else
XSetWindowBackground(display, frame.pwbutton, frame.button_pixel);
}
XClearWindow(display, frame.pwbutton);
2002-04-11 03:20:38 +00:00
}
int hh = frame.button_w / 2, hw = frame.button_w / 2;
2002-04-11 03:20:38 +00:00
XPoint pts[3];
pts[0].x = hw - 2; pts[0].y = hh;
pts[1].x = 4; pts[1].y = 2;
pts[2].x = 0; pts[2].y = -4;
2002-04-11 03:20:38 +00:00
ToolbarStyle *style = screen->getToolbarStyle();
2002-07-03 06:34:25 +00:00
BPen pen(style->b_pic);
XFillPolygon(display, frame.pwbutton, pen.gc(),
pts, 3, Convex, CoordModePrevious);
}
2002-04-11 03:20:38 +00:00
void Toolbar::redrawNextWindowButton(bool pressed, bool redraw) {
if (redraw) {
if (pressed) {
if (frame.pbutton)
XSetWindowBackgroundPixmap(display, frame.nwbutton, frame.pbutton);
else
XSetWindowBackground(display, frame.nwbutton, frame.pbutton_pixel);
} else {
if (frame.button)
XSetWindowBackgroundPixmap(display, frame.nwbutton, frame.button);
else
XSetWindowBackground(display, frame.nwbutton, frame.button_pixel);
}
XClearWindow(display, frame.nwbutton);
2002-04-11 03:20:38 +00:00
}
int hh = frame.button_w / 2, hw = frame.button_w / 2;
2002-04-11 03:20:38 +00:00
XPoint pts[3];
pts[0].x = hw - 2; pts[0].y = hh - 2;
pts[1].x = 4; pts[1].y = 2;
pts[2].x = -4; pts[2].y = 2;
ToolbarStyle *style = screen->getToolbarStyle();
2002-07-03 06:34:25 +00:00
BPen pen(style->b_pic);
XFillPolygon(display, frame.nwbutton, pen.gc(), pts, 3, Convex,
CoordModePrevious);
}
void Toolbar::edit(void) {
Window window;
int foo;
editing = True;
XGetInputFocus(display, &window, &foo);
if (window == frame.workspace_label)
return;
XSetInputFocus(display, frame.workspace_label,
RevertToPointerRoot, CurrentTime);
XClearWindow(display, frame.workspace_label);
blackbox->setNoFocus(True);
if (blackbox->getFocusedWindow())
blackbox->getFocusedWindow()->setFocusFlag(False);
ToolbarStyle *style = screen->getToolbarStyle();
2002-07-03 06:34:25 +00:00
BPen pen(style->l_text);
XDrawRectangle(display, frame.workspace_label, pen.gc(),
frame.workspace_label_w / 2, 0, 1,
frame.label_h - 1);
// change the background of the window to that of an active window label
BTexture *texture = &(screen->getWindowStyle()->l_focus);
frame.wlabel = texture->render(frame.workspace_label_w, frame.label_h,
frame.wlabel);
if (! frame.wlabel)
XSetWindowBackground(display, frame.workspace_label,
texture->color().pixel());
else
XSetWindowBackgroundPixmap(display, frame.workspace_label, frame.wlabel);
}
void Toolbar::buttonPressEvent(XButtonEvent *be) {
if (be->button == 1) {
if (be->window == frame.psbutton)
redrawPrevWorkspaceButton(True, True);
else if (be->window == frame.nsbutton)
redrawNextWorkspaceButton(True, True);
else if (be->window == frame.pwbutton)
redrawPrevWindowButton(True, True);
else if (be->window == frame.nwbutton)
redrawNextWindowButton(True, True);
#ifndef HAVE_STRFTIME
else if (be->window == frame.clock) {
XClearWindow(display, frame.clock);
checkClock(True, True);
}
2002-04-11 03:20:38 +00:00
#endif // HAVE_STRFTIME
else if (! on_top) {
Window w[1] = { frame.window };
screen->raiseWindows(w, 1);
2002-04-11 03:20:38 +00:00
}
} else if (be->button == 2 && (! on_top)) {
XLowerWindow(display, frame.window);
} else if (be->button == 3) {
if (toolbarmenu->isVisible()) {
toolbarmenu->hide();
} else {
int x, y;
2002-04-11 03:20:38 +00:00
x = be->x_root - (toolbarmenu->getWidth() / 2);
y = be->y_root - (toolbarmenu->getHeight() / 2);
2002-04-11 03:20:38 +00:00
if (x < 0)
x = 0;
else if (x + toolbarmenu->getWidth() > screen->getWidth())
x = screen->getWidth() - toolbarmenu->getWidth();
2002-04-11 03:20:38 +00:00
if (y < 0)
y = 0;
else if (y + toolbarmenu->getHeight() > screen->getHeight())
y = screen->getHeight() - toolbarmenu->getHeight();
toolbarmenu->move(x, y);
toolbarmenu->show();
}
2002-04-11 03:20:38 +00:00
}
}
2002-04-11 03:20:38 +00:00
void Toolbar::buttonReleaseEvent(XButtonEvent *re) {
if (re->button == 1) {
if (re->window == frame.psbutton) {
redrawPrevWorkspaceButton(False, True);
if (re->x >= 0 && re->x < static_cast<signed>(frame.button_w) &&
re->y >= 0 && re->y < static_cast<signed>(frame.button_w))
if (screen->getCurrentWorkspace()->getID() > 0)
screen->changeWorkspaceID(screen->getCurrentWorkspace()->
getID() - 1);
else
screen->changeWorkspaceID(screen->getWorkspaceCount() - 1);
} else if (re->window == frame.nsbutton) {
redrawNextWorkspaceButton(False, True);
if (re->x >= 0 && re->x < static_cast<signed>(frame.button_w) &&
re->y >= 0 && re->y < static_cast<signed>(frame.button_w))
if (screen->getCurrentWorkspace()->getID() <
(screen->getWorkspaceCount() - 1))
screen->changeWorkspaceID(screen->getCurrentWorkspace()->
getID() + 1);
else
screen->changeWorkspaceID(0);
} else if (re->window == frame.pwbutton) {
redrawPrevWindowButton(False, True);
if (re->x >= 0 && re->x < static_cast<signed>(frame.button_w) &&
re->y >= 0 && re->y < static_cast<signed>(frame.button_w))
screen->prevFocus();
} else if (re->window == frame.nwbutton) {
redrawNextWindowButton(False, True);
if (re->x >= 0 && re->x < static_cast<signed>(frame.button_w) &&
re->y >= 0 && re->y < static_cast<signed>(frame.button_w))
screen->nextFocus();
} else if (re->window == frame.window_label)
screen->raiseFocus();
#ifndef HAVE_STRFTIME
else if (re->window == frame.clock) {
XClearWindow(display, frame.clock);
checkClock(True);
}
#endif // HAVE_STRFTIME
2002-04-11 03:20:38 +00:00
}
}
2002-04-11 03:20:38 +00:00
void Toolbar::enterNotifyEvent(XCrossingEvent *) {
if (! do_auto_hide)
return;
if (hidden) {
if (! hide_timer->isTiming()) hide_timer->start();
} else {
if (hide_timer->isTiming()) hide_timer->stop();
2002-04-11 03:20:38 +00:00
}
}
2002-04-11 03:20:38 +00:00
void Toolbar::leaveNotifyEvent(XCrossingEvent *) {
if (! do_auto_hide)
return;
2002-04-11 03:20:38 +00:00
if (hidden) {
if (hide_timer->isTiming()) hide_timer->stop();
} else if (! toolbarmenu->isVisible()) {
if (! hide_timer->isTiming()) hide_timer->start();
}
}
2002-04-11 03:20:38 +00:00
void Toolbar::exposeEvent(XExposeEvent *ee) {
if (ee->window == frame.clock) checkClock(True);
else if (ee->window == frame.workspace_label && (! editing))
redrawWorkspaceLabel();
else if (ee->window == frame.window_label) redrawWindowLabel();
else if (ee->window == frame.psbutton) redrawPrevWorkspaceButton();
else if (ee->window == frame.nsbutton) redrawNextWorkspaceButton();
else if (ee->window == frame.pwbutton) redrawPrevWindowButton();
else if (ee->window == frame.nwbutton) redrawNextWindowButton();
}
2002-04-11 03:20:38 +00:00
void Toolbar::keyPressEvent(XKeyEvent *ke) {
if (ke->window == frame.workspace_label && editing) {
if (new_workspace_name.empty()) {
new_name_pos = 0;
}
2002-04-11 03:20:38 +00:00
KeySym ks;
char keychar[1];
XLookupString(ke, keychar, 1, &ks, 0);
// either we are told to end with a return or we hit 127 chars
if (ks == XK_Return || new_name_pos == 127) {
editing = False;
blackbox->setNoFocus(False);
if (blackbox->getFocusedWindow()) {
blackbox->getFocusedWindow()->setInputFocus();
} else {
blackbox->setFocusedWindow(0);
}
Workspace *wkspc = screen->getCurrentWorkspace();
wkspc->setName(new_workspace_name);
wkspc->getMenu()->hide();
screen->getWorkspacemenu()->changeItemLabel(wkspc->getID() + 2,
wkspc->getName());
screen->getWorkspacemenu()->update();
new_workspace_name.erase();
new_name_pos = 0;
// reset the background to that of the workspace label (its normal
// setting)
BTexture *texture = &(screen->getToolbarStyle()->label);
frame.wlabel = texture->render(frame.workspace_label_w, frame.label_h,
frame.wlabel);
if (! frame.wlabel)
XSetWindowBackground(display, frame.workspace_label,
texture->color().pixel());
else
XSetWindowBackgroundPixmap(display, frame.workspace_label,
frame.wlabel);
reconfigure();
} else if (! (ks == XK_Shift_L || ks == XK_Shift_R ||
ks == XK_Control_L || ks == XK_Control_R ||
ks == XK_Caps_Lock || ks == XK_Shift_Lock ||
ks == XK_Meta_L || ks == XK_Meta_R ||
ks == XK_Alt_L || ks == XK_Alt_R ||
ks == XK_Super_L || ks == XK_Super_R ||
ks == XK_Hyper_L || ks == XK_Hyper_R)) {
if (ks == XK_BackSpace) {
if (new_name_pos > 0) {
--new_name_pos;
new_workspace_name.erase(new_name_pos);
} else {
new_workspace_name.resize(0);
}
} else {
new_workspace_name += (*keychar);
++new_name_pos;
}
XClearWindow(display, frame.workspace_label);
2002-07-03 06:34:25 +00:00
unsigned int tw, x;
2002-04-11 03:20:38 +00:00
2002-07-03 06:34:25 +00:00
tw = screen->getToolbarStyle()->font->measureString(new_workspace_name);
x = (frame.workspace_label_w - tw) / 2;
if (x < frame.bevel_w) x = frame.bevel_w;
2002-04-11 03:20:38 +00:00
ToolbarStyle *style = screen->getToolbarStyle();
2002-07-03 06:34:25 +00:00
style->font->drawString(frame.workspace_label, x, 1, style->l_text,
new_workspace_name);
BPen pen(style->l_text);
XDrawRectangle(display, frame.workspace_label, pen.gc(), x + tw, 0, 1,
frame.label_h - 1);
2002-04-11 03:20:38 +00:00
}
}
}
2002-04-11 03:20:38 +00:00
void Toolbar::timeout(void) {
checkClock(True);
2002-04-11 03:20:38 +00:00
clock_timer->setTimeout(aMinuteFromNow());
}
2002-04-11 03:20:38 +00:00
void Toolbar::HideHandler::timeout(void) {
toolbar->hidden = ! toolbar->hidden;
if (toolbar->hidden)
XMoveWindow(toolbar->display, toolbar->frame.window,
toolbar->frame.x_hidden, toolbar->frame.y_hidden);
else
XMoveWindow(toolbar->display, toolbar->frame.window,
toolbar->frame.rect.x(), toolbar->frame.rect.y());
}
void Toolbar::toggleAutoHide(void) {
saveAutoHide(! doAutoHide());
updateStrut();
screen->getSlit()->reposition();
if (do_auto_hide == False && hidden) {
// force the slit to be visible
if (hide_timer->isTiming()) hide_timer->stop();
hide_handler.timeout();
}
}
2002-04-11 03:20:38 +00:00
Toolbarmenu::Toolbarmenu(Toolbar *tb) : Basemenu(tb->screen) {
toolbar = tb;
2002-04-11 03:20:38 +00:00
setLabel(i18n(ToolbarSet, ToolbarToolbarTitle, "Toolbar"));
setInternalMenu();
2002-04-11 03:20:38 +00:00
placementmenu = new Placementmenu(this);
2002-04-11 03:20:38 +00:00
insert(i18n(CommonSet, CommonPlacementTitle, "Placement"),
placementmenu);
insert(i18n(CommonSet, CommonAlwaysOnTop, "Always on top"), 1);
insert(i18n(CommonSet, CommonAutoHide, "Auto hide"), 2);
insert(i18n(ToolbarSet, ToolbarEditWkspcName,
"Edit current workspace name"), 3);
2002-04-11 03:20:38 +00:00
update();
setValues();
}
void Toolbarmenu::setValues() {
setItemSelected(1, toolbar->isOnTop());
setItemSelected(2, toolbar->doAutoHide());
}
Toolbarmenu::~Toolbarmenu(void) {
delete placementmenu;
}
void Toolbarmenu::itemSelected(int button, unsigned int index) {
if (button != 1)
return;
BasemenuItem *item = find(index);
if (! item) return;
switch (item->function()) {
case 1: { // always on top
toolbar->saveOnTop(! toolbar->isOnTop());
setItemSelected(1, toolbar->isOnTop());
if (toolbar->isOnTop()) getScreen()->raiseWindows((Window *) 0, 0);
break;
}
2002-04-11 03:20:38 +00:00
case 2: { // auto hide
toolbar->toggleAutoHide();
setItemSelected(2, toolbar->doAutoHide());
2002-04-11 03:20:38 +00:00
break;
}
2002-04-11 03:20:38 +00:00
case 3: { // edit current workspace name
toolbar->edit();
hide();
2002-04-11 03:20:38 +00:00
break;
}
} // switch
}
2002-04-11 03:20:38 +00:00
void Toolbarmenu::internal_hide(void) {
Basemenu::internal_hide();
if (toolbar->doAutoHide() && ! toolbar->isEditing())
toolbar->hide_handler.timeout();
}
2002-04-11 03:20:38 +00:00
void Toolbarmenu::reconfigure(void) {
setValues();
placementmenu->reconfigure();
2002-04-11 03:20:38 +00:00
Basemenu::reconfigure();
}
2002-04-11 03:20:38 +00:00
Toolbarmenu::Placementmenu::Placementmenu(Toolbarmenu *tm)
: Basemenu(tm->toolbar->screen), toolbar(tm->toolbar) {
setLabel(i18n(ToolbarSet, ToolbarToolbarPlacement, "Toolbar Placement"));
setInternalMenu();
setMinimumSublevels(3);
insert(i18n(CommonSet, CommonPlacementTopLeft, "Top Left"),
Toolbar::TopLeft);
insert(i18n(CommonSet, CommonPlacementBottomLeft, "Bottom Left"),
Toolbar::BottomLeft);
insert(i18n(CommonSet, CommonPlacementTopCenter, "Top Center"),
Toolbar::TopCenter);
insert(i18n(CommonSet, CommonPlacementBottomCenter, "Bottom Center"),
Toolbar::BottomCenter);
insert(i18n(CommonSet, CommonPlacementTopRight, "Top Right"),
Toolbar::TopRight);
insert(i18n(CommonSet, CommonPlacementBottomRight, "Bottom Right"),
Toolbar::BottomRight);
update();
setValues();
}
void Toolbarmenu::Placementmenu::setValues(void) {
int place = 0;
switch (toolbar->getPlacement()) {
case Toolbar::BottomRight:
place++;
case Toolbar::TopRight:
place++;
case Toolbar::BottomCenter:
place++;
case Toolbar::TopCenter:
place++;
case Toolbar::BottomLeft:
place++;
case Toolbar::TopLeft:
break;
}
setItemSelected(0, 0 == place);
setItemSelected(1, 1 == place);
setItemSelected(2, 2 == place);
setItemSelected(3, 3 == place);
setItemSelected(4, 4 == place);
setItemSelected(5, 5 == place);
}
void Toolbarmenu::Placementmenu::reconfigure(void) {
setValues();
Basemenu::reconfigure();
}
2002-04-11 03:20:38 +00:00
void Toolbarmenu::Placementmenu::itemSelected(int button, unsigned int index) {
if (button != 1)
return;
2002-04-11 03:20:38 +00:00
BasemenuItem *item = find(index);
if (! item) return;
2002-04-11 03:20:38 +00:00
toolbar->savePlacement(item->function());
hide();
toolbar->reconfigure();
2002-04-11 03:20:38 +00:00
// reposition the slit as well to make sure it doesn't intersect the
// toolbar
getScreen()->getSlit()->reposition();
}
2002-04-11 03:20:38 +00:00
void ToolbarStyle::doJustify(const std::string &text, int &start_pos,
unsigned int max_length,
unsigned int modifier) const {
2002-07-03 06:34:25 +00:00
size_t text_len = text.size();
unsigned int length;
2002-04-11 03:20:38 +00:00
do {
2002-07-03 06:34:25 +00:00
length = font->measureString(string(text, 0, text_len)) + modifier;
} while (length > max_length && text_len-- > 0);
2002-04-11 03:20:38 +00:00
switch (justify) {
case RightJustify:
start_pos += max_length - length;
break;
2002-04-11 03:20:38 +00:00
case CenterJustify:
start_pos += (max_length - length) / 2;
break;
2002-04-11 03:20:38 +00:00
case LeftJustify:
default:
break;
}
}