fluxbox/src/Toolbar.cc

1094 lines
36 KiB
C++
Raw Normal View History

2002-03-19 14:30:43 +00:00
// Toolbar.cc for Fluxbox
// Copyright (c) 2002 Henrik Kinnunen (fluxgen at users.sourceforge.net)
2002-03-19 14:30:43 +00:00
//
2001-12-11 20:47:02 +00:00
// Toolbar.cc for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
2001-12-11 20:47:02 +00:00
//
// 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,
2002-03-19 14:30:43 +00:00
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2001-12-11 20:47:02 +00:00
// 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.
// $Id: Toolbar.cc,v 1.59 2003/02/18 15:11:09 rathnor Exp $
2002-08-04 15:12:51 +00:00
#include "Toolbar.hh"
2002-02-07 15:12:23 +00:00
2001-12-11 20:47:02 +00:00
#include "i18n.hh"
#include "fluxbox.hh"
#include "Screen.hh"
#include "Window.hh"
#include "Workspace.hh"
2002-11-30 20:29:27 +00:00
#include "ImageControl.hh"
#include "ToolbarTheme.hh"
#include "EventManager.hh"
#include "Text.hh"
#include "ArrowButton.hh"
#include "SimpleCommand.hh"
2001-12-11 20:47:02 +00:00
// use GNU extensions
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif // _GNU_SOURCE
2002-10-13 21:51:12 +00:00
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif // HAVE_CONFIG_H
2001-12-11 20:47:02 +00:00
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <cstring>
#include <cstdio>
2001-12-11 20:47:02 +00:00
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
2001-12-11 20:47:02 +00:00
#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
2001-12-11 20:47:02 +00:00
#endif // TIME_WITH_SYS_TIME
#ifdef SHAPE
#include <X11/extensions/shape.h>
#endif // SHAPE
2001-12-11 20:47:02 +00:00
#include <iostream>
using namespace std;
2002-12-04 17:58:01 +00:00
2003-01-12 18:04:39 +00:00
namespace {
class SetToolbarPlacementCmd: public FbTk::Command {
explicit SetToolbarPlacementCmd(Toolbar &tbar, Toolbar::Placement place):m_tbar(tbar), m_place(place) { }
void execute() {
m_tbar.setPlacement(m_place);
}
private:
Toolbar &m_tbar;
Toolbar::Placement m_place;
};
void setupMenus(Toolbar &tbar) {
I18n *i18n = I18n::instance();
using namespace FBNLS;
FbTk::Menu &menu = tbar.menu();
menu.setLabel(i18n->getMessage(
ToolbarSet, ToolbarToolbarTitle,
"Toolbar"));
menu.setInternalMenu();
menu.insert("Layer...", tbar.layermenu());
2003-01-12 18:04:39 +00:00
using namespace FbTk;
RefCount<Command> start_edit(new SimpleCommand<Toolbar>(tbar, &Toolbar::edit));
menu.insert(i18n->getMessage(
ToolbarSet, ToolbarEditWkspcName,
"Edit current workspace name"),
start_edit);
menu.update();
}
}; // end anonymous
2002-12-03 17:02:53 +00:00
// toolbar frame
Toolbar::Frame::Frame(FbTk::EventHandler &evh, int screen_num):
window(screen_num, // screen (parent)
0, 0, // pos
1, 1, // size
// event mask
2002-12-03 17:02:53 +00:00
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
true), // override redirect
workspace_label(window, // parent
0, 0, //pos
1, 1, // size
// event mask
2002-12-03 17:02:53 +00:00
ButtonPressMask | ButtonReleaseMask |
ExposureMask | KeyPressMask),
window_label(window, // parent
0, 0, // pos
1, 1, // size
// event mask
2002-12-03 17:02:53 +00:00
ButtonPressMask | ButtonReleaseMask |
ExposureMask),
clock (window, //parent
0, 0, // pos
1, 1, // size
// event mask
2002-12-03 17:02:53 +00:00
ButtonPressMask | ButtonReleaseMask |
ExposureMask),
psbutton(ArrowButton::LEFT, // arrow type
window, // parent
2002-12-03 17:02:53 +00:00
0, 0, // pos
1, 1), // size
nsbutton(ArrowButton::RIGHT, // arrow type
window, // parent
0, 0, // pos
1, 1), // size
pwbutton(ArrowButton::LEFT, // arrow type
window, // parent
0, 0, // pos
1, 1), // size
nwbutton(ArrowButton::RIGHT, // arrow type
window, // parent
0, 0, // pos
1, 1) // size
2002-12-03 17:02:53 +00:00
{
FbTk::EventManager &evm = *FbTk::EventManager::instance();
// add windows to eventmanager
2002-12-03 17:02:53 +00:00
evm.add(evh, window);
evm.add(evh, workspace_label);
evm.add(evh, window_label);
evm.add(evh, clock);
}
Toolbar::Frame::~Frame() {
FbTk::EventManager &evm = *FbTk::EventManager::instance();
// remove windows from eventmanager
2002-12-03 17:02:53 +00:00
evm.remove(window);
evm.remove(workspace_label);
evm.remove(window_label);
evm.remove(clock);
}
2001-12-11 20:47:02 +00:00
Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, size_t width):
2002-12-01 13:42:15 +00:00
editing(false),
hidden(scrn.doToolbarAutoHide()),
do_auto_hide(scrn.doToolbarAutoHide()),
frame(*this, scrn.getScreenNumber()),
2002-12-01 13:42:15 +00:00
m_screen(scrn),
image_ctrl(*scrn.getImageControl()),
2002-12-01 13:42:15 +00:00
clock_timer(this), // get the clock updating every minute
hide_timer(&hide_handler),
m_toolbarmenu(*scrn.menuTheme(), scrn.getScreenNumber(), *scrn.getImageControl()),
m_layermenu(0),
m_theme(scrn.getScreenNumber()),
m_place(BOTTOMCENTER),
m_themelistener(*this),
m_layeritem(0)
{
m_layermenu = new LayerMenu<Toolbar>(
*scrn.menuTheme(),
scrn.getScreenNumber(),
*scrn.getImageControl(),
*scrn.layerManager().getLayer(Fluxbox::instance()->getMenuLayer()),
this);
// we need to get notified when the theme is reloaded
m_theme.addListener(m_themelistener);
2003-01-12 18:04:39 +00:00
setupMenus(*this);
// geometry settings
frame.width = width;
frame.height = frame.label_h = 10;
frame.window_label_w =
frame.workspace_label_w = frame.clock_w = width/3;
frame.button_w = 20;
frame.bevel_w = 1;
m_layeritem = new FbTk::XLayerItem(frame.window, layer);
2002-12-01 13:42:15 +00:00
timeval delay;
delay.tv_sec = 1;
delay.tv_usec = 0;
clock_timer.setTimeout(delay);
clock_timer.start();
hide_handler.toolbar = this;
hide_timer.setTimeout(Fluxbox::instance()->getAutoRaiseDelay());
hide_timer.fireOnce(true);
frame.grab_x = frame.grab_y = 0;
2002-12-03 17:02:53 +00:00
display = FbTk::App::instance()->display();
2002-12-01 13:42:15 +00:00
frame.base = frame.label = frame.wlabel = frame.clk = frame.button =
frame.pbutton = None;
2001-12-11 20:47:02 +00:00
2002-02-07 15:12:23 +00:00
2002-12-01 13:42:15 +00:00
if (Fluxbox::instance()->useIconBar())
m_iconbar.reset(new IconBar(&screen(), frame.window_label.window()));
2002-11-27 12:20:23 +00:00
2001-12-11 20:47:02 +00:00
2002-12-03 17:02:53 +00:00
XMapSubwindows(display, frame.window.window());
frame.window.show();
// finaly: setup Commands for the buttons in the frame
typedef FbTk::SimpleCommand<BScreen> ScreenCmd;
FbTk::RefCount<FbTk::Command> nextworkspace(new ScreenCmd(screen(),
&BScreen::nextWorkspace));
FbTk::RefCount<FbTk::Command> prevworkspace(new ScreenCmd(screen(),
&BScreen::prevWorkspace));
FbTk::RefCount<FbTk::Command> nextwindow(new ScreenCmd(screen(),
&BScreen::nextFocus));
FbTk::RefCount<FbTk::Command> prevwindow(new ScreenCmd(screen(),
&BScreen::prevFocus));
frame.psbutton.setOnClick(prevworkspace);
frame.nsbutton.setOnClick(nextworkspace);
frame.pwbutton.setOnClick(prevwindow);
frame.nwbutton.setOnClick(nextwindow);
2002-12-01 13:42:15 +00:00
reconfigure();
2002-02-07 15:12:23 +00:00
2001-12-11 20:47:02 +00:00
}
2002-08-04 15:12:51 +00:00
Toolbar::~Toolbar() {
if (frame.base) image_ctrl.removeImage(frame.base);
if (frame.label) image_ctrl.removeImage(frame.label);
if (frame.wlabel) image_ctrl.removeImage(frame.wlabel);
if (frame.clk) image_ctrl.removeImage(frame.clk);
if (frame.button) image_ctrl.removeImage(frame.button);
if (frame.pbutton) image_ctrl.removeImage(frame.pbutton);
if (m_layeritem) delete m_layeritem;
if (m_layermenu) delete m_layermenu;
2002-12-03 17:02:53 +00:00
}
2001-12-11 20:47:02 +00:00
2002-12-03 17:02:53 +00:00
bool Toolbar::isVertical() const {
return (m_place == RIGHTCENTER ||
m_place == RIGHTTOP ||
m_place == RIGHTBOTTOM ||
m_place == LEFTCENTER ||
m_place == LEFTTOP ||
m_place == LEFTBOTTOM);
2001-12-11 20:47:02 +00:00
}
void Toolbar::addIcon(FluxboxWindow *w) {
2002-12-01 13:42:15 +00:00
if (m_iconbar.get() != 0)
FbTk::EventManager::instance()->add(*this, m_iconbar->addIcon(w));
2001-12-11 20:47:02 +00:00
}
void Toolbar::delIcon(FluxboxWindow *w) {
2002-12-01 13:42:15 +00:00
if (m_iconbar.get() != 0)
FbTk::EventManager::instance()->remove(m_iconbar->delIcon(w));
2001-12-11 20:47:02 +00:00
}
2002-08-04 15:12:51 +00:00
void Toolbar::reconfigure() {
2002-03-19 14:30:43 +00:00
frame.bevel_w = screen().getBevelWidth();
2002-12-01 13:42:15 +00:00
2002-12-03 17:02:53 +00:00
// recallibrate size
setPlacement(m_place);
2001-12-11 20:47:02 +00:00
#ifdef HAVE_STRFTIME
2002-12-01 13:42:15 +00:00
time_t ttmp = time(0);
struct tm *tt = 0;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (ttmp != -1) {
tt = localtime(&ttmp);
if (tt) {
char t[1024], *time_string = (char *) 0;
int len = strftime(t, 1024, screen().getStrftimeFormat(), tt);
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
time_string = new char[len + 1];
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
memset(time_string, '0', len);
*(time_string + len) = '\0';
2001-12-11 20:47:02 +00:00
frame.clock_w = m_theme.font().textWidth(time_string, len);
2002-12-01 13:42:15 +00:00
frame.clock_w += (frame.bevel_w * 4);
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
delete [] time_string;
} else
frame.clock_w = 0;
} else
frame.clock_w = 0;
#else // !HAVE_STRFTIME
frame.clock_w = m_theme.font().textWidth(
i18n->getMessage(
ToolbarSet, ToolbarNoStrftimeLength,
"00:00000"),
strlen(i18n->getMessage(
ToolbarSet, ToolbarNoStrftimeLength,
"00:00000"))) + (frame.bevel_w * 4);
#endif // HAVE_STRFTIME
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
unsigned int i;
unsigned int w = 0;
frame.workspace_label_w = 0;
for (i = 0; i < screen().getCount(); i++) {
w = m_theme.font().textWidth(screen().getWorkspace(i)->name().c_str(),
screen().getWorkspace(i)->name().size());
2002-12-01 13:42:15 +00:00
w += (frame.bevel_w * 4);
if (w > frame.workspace_label_w)
frame.workspace_label_w = w;
}
2002-12-04 17:58:01 +00:00
2002-12-01 13:42:15 +00:00
if (frame.workspace_label_w < frame.clock_w)
frame.workspace_label_w = frame.clock_w;
else if (frame.workspace_label_w > frame.clock_w)
frame.clock_w = frame.workspace_label_w;
frame.window_label_w =
(frame.width - (frame.clock_w + (frame.button_w * 4) +
frame.workspace_label_w + (frame.bevel_w * 8) + 6));
2002-12-04 17:58:01 +00:00
2002-12-01 13:42:15 +00:00
if (hidden)
2002-12-03 17:02:53 +00:00
frame.window.moveResize(frame.x_hidden, frame.y_hidden,
frame.width, frame.height);
else {
frame.window.moveResize(frame.x, frame.y,
frame.width, frame.height);
}
2002-12-04 17:58:01 +00:00
2002-12-03 17:02:53 +00:00
bool vertical = isVertical();
2002-12-04 17:58:01 +00:00
unsigned int next_x = frame.workspace_label_w;
unsigned int next_y = frame.window.height();
2002-12-03 17:02:53 +00:00
if (vertical) {
2002-12-04 17:58:01 +00:00
next_x = frame.window.width();
next_y = frame.workspace_label_w;
2002-12-03 17:02:53 +00:00
}
2002-12-04 17:58:01 +00:00
frame.workspace_label.moveResize(frame.bevel_w, frame.bevel_w, next_x, next_y);
next_x = 0;
next_y = 0;
2002-12-03 17:02:53 +00:00
if (vertical) {
2002-12-04 17:58:01 +00:00
next_y += frame.workspace_label.height() + 1;
} else {
next_x += frame.workspace_label.width() + 1;
2002-12-03 17:02:53 +00:00
}
2002-12-04 17:58:01 +00:00
2002-12-03 17:02:53 +00:00
frame.psbutton.moveResize(frame.bevel_w * 2 +
2002-12-04 17:58:01 +00:00
next_x , next_y,
2002-12-03 17:02:53 +00:00
frame.button_w, frame.button_w);
if (vertical)
2002-12-04 17:58:01 +00:00
next_y += frame.psbutton.height() + 1;
2002-12-01 13:42:15 +00:00
else
2002-12-04 17:58:01 +00:00
next_x += frame.psbutton.width() + 1;
2002-12-03 17:02:53 +00:00
frame.nsbutton.moveResize(frame.bevel_w * 3 +
2002-12-04 17:58:01 +00:00
next_x, next_y,
2002-12-03 17:02:53 +00:00
frame.button_w, frame.button_w);
2002-12-04 17:58:01 +00:00
size_t label_w = frame.window_label_w;
size_t label_h = frame.height;
if (vertical) {
next_y += frame.nsbutton.height() + 1;
label_w = frame.width;
label_h = frame.window_label_w - frame.width + frame.height;
} else
next_x += frame.nsbutton.width() + 1;
frame.window_label.moveResize(next_x, next_y,
label_w, label_h);
if (vertical)
next_y += frame.window_label.height() + 1;
else
next_x += frame.window_label.width() + 1;
frame.pwbutton.moveResize(next_x, next_y,
2002-12-03 17:02:53 +00:00
frame.button_w, frame.button_w);
2002-12-04 17:58:01 +00:00
if (vertical)
next_y += frame.pwbutton.height() + 1;
else
next_x += frame.pwbutton.width() + 1;
frame.nwbutton.moveResize(next_x, next_y,
2002-12-03 17:02:53 +00:00
frame.button_w, frame.button_w);
2002-12-04 17:58:01 +00:00
size_t clock_w = frame.width - next_x - frame.nwbutton.width() - 1;
size_t clock_h = frame.height;
if (vertical) {
next_y += frame.nwbutton.height() + 1;
clock_w = frame.width;
clock_h = frame.height - next_y;
} else
next_x += frame.nwbutton.width() + 1;
frame.clock.moveResize(next_x, next_y,
clock_w, clock_h);
2002-12-01 13:42:15 +00:00
Pixmap tmp = frame.base;
const FbTk::Texture *texture = &(m_theme.toolbar());
2002-12-01 13:42:15 +00:00
if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
frame.base = None;
2002-12-03 17:02:53 +00:00
frame.window.setBackgroundColor(texture->color());
2002-12-01 13:42:15 +00:00
} else {
frame.base = image_ctrl.renderImage(frame.window.width(),
frame.window.height(), *texture);
2002-12-03 17:02:53 +00:00
frame.window.setBackgroundPixmap(frame.base);
2002-12-01 13:42:15 +00:00
}
if (tmp) image_ctrl.removeImage(tmp);
2002-12-01 13:42:15 +00:00
tmp = frame.label;
texture = &(m_theme.window());
2002-12-01 13:42:15 +00:00
if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
frame.label = None;
2002-12-03 17:02:53 +00:00
frame.window_label.setBackgroundColor(texture->color());
2002-12-01 13:42:15 +00:00
} else {
frame.label =
image_ctrl.renderImage(frame.window_label.width(),
frame.window_label.height(), *texture);
2002-12-03 17:02:53 +00:00
frame.window_label.setBackgroundPixmap(frame.label);
2002-12-01 13:42:15 +00:00
}
if (tmp) image_ctrl.removeImage(tmp);
2002-12-01 13:42:15 +00:00
tmp = frame.wlabel;
texture = &(m_theme.label());
2002-12-01 13:42:15 +00:00
if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
frame.wlabel = None;
2002-12-03 17:02:53 +00:00
frame.workspace_label.setBackgroundColor(texture->color());
2002-12-01 13:42:15 +00:00
} else {
frame.wlabel =
2002-12-04 17:58:01 +00:00
image_ctrl.renderImage(frame.workspace_label.width(),
frame.workspace_label.height(), *texture);
2002-12-03 17:02:53 +00:00
frame.workspace_label.setBackgroundPixmap(frame.wlabel);
2002-12-01 13:42:15 +00:00
}
if (tmp) image_ctrl.removeImage(tmp);
2002-12-01 13:42:15 +00:00
tmp = frame.clk;
texture = &(m_theme.clock());
2002-12-01 13:42:15 +00:00
if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
frame.clk = None;
2002-12-03 17:02:53 +00:00
frame.clock.setBackgroundColor(texture->color());
2002-12-01 13:42:15 +00:00
} else {
frame.clk =
2002-12-04 17:58:01 +00:00
image_ctrl.renderImage(frame.clock.width(), frame.clock.height(), *texture);
2002-12-03 17:02:53 +00:00
frame.clock.setBackgroundPixmap(frame.clk);
2002-12-01 13:42:15 +00:00
}
if (tmp) image_ctrl.removeImage(tmp);
2002-12-01 13:42:15 +00:00
tmp = frame.button;
texture = &(m_theme.button());
2002-12-01 13:42:15 +00:00
if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
frame.button = None;
2002-12-03 17:02:53 +00:00
const FbTk::Color &color = texture->color();
frame.psbutton.setBackgroundColor(color);
frame.nsbutton.setBackgroundColor(color);
frame.pwbutton.setBackgroundColor(color);
frame.nwbutton.setBackgroundColor(color);
2002-12-01 13:42:15 +00:00
} else {
frame.button =
image_ctrl.renderImage(frame.button_w, frame.button_w, *texture);
2002-12-03 17:02:53 +00:00
frame.psbutton.setBackgroundPixmap(frame.button);
frame.nsbutton.setBackgroundPixmap(frame.button);
frame.pwbutton.setBackgroundPixmap(frame.button);
frame.nwbutton.setBackgroundPixmap(frame.button);
2002-12-01 13:42:15 +00:00
}
if (tmp)
image_ctrl.removeImage(tmp);
2002-12-01 13:42:15 +00:00
// pressed button pixmap
2002-12-01 13:42:15 +00:00
tmp = frame.pbutton;
texture = &(m_theme.pressedButton());
2002-12-01 13:42:15 +00:00
if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
frame.pbutton = None;
} else {
2002-12-01 13:42:15 +00:00
frame.pbutton =
image_ctrl.renderImage(frame.button_w, frame.button_w, *texture);
frame.psbutton.setPressedPixmap(frame.pbutton);
frame.nsbutton.setPressedPixmap(frame.pbutton);
frame.pwbutton.setPressedPixmap(frame.pbutton);
frame.nwbutton.setPressedPixmap(frame.pbutton);
}
// setup button gc
frame.psbutton.setGC(m_theme.buttonPicGC());
frame.nsbutton.setGC(m_theme.buttonPicGC());
frame.pwbutton.setGC(m_theme.buttonPicGC());
frame.nwbutton.setGC(m_theme.buttonPicGC());
2002-12-01 13:42:15 +00:00
if (tmp)
image_ctrl.removeImage(tmp);
2002-12-01 13:42:15 +00:00
frame.window.setBorderColor(*screen().getBorderColor());
frame.window.setBorderWidth(screen().getBorderWidth());
2002-12-03 17:02:53 +00:00
frame.window.clear();
frame.workspace_label.clear();
frame.window_label.clear();
frame.clock.clear();
frame.psbutton.clear();
frame.nsbutton.clear();
frame.pwbutton.clear();
frame.nwbutton.clear();
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
redrawWindowLabel();
redrawWorkspaceLabel();
checkClock(true);
m_toolbarmenu.reconfigure();
if (Fluxbox::instance()->useIconBar()) {
if (m_iconbar.get() == 0) { // create new iconbar if we don't have one
m_iconbar.reset(new IconBar(&screen(), frame.window_label.window()));
if (screen().getIconCount()) {
BScreen::Icons & l = screen().getIconList();
2002-12-01 13:42:15 +00:00
BScreen::Icons::iterator it = l.begin();
BScreen::Icons::iterator it_end = l.end();
for(; it != it_end; ++it) {
addIcon(*it);
}
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
} else
m_iconbar->reconfigure();
} else if (m_iconbar.get() != 0) {
BScreen::Icons & l = screen().getIconList();
2002-12-01 13:42:15 +00:00
BScreen::Icons::iterator it = l.begin();
BScreen::Icons::iterator it_end = l.end();
for(; it != it_end; ++it)
delIcon(*it);
m_iconbar.reset(0); // destroy iconbar
}
2001-12-11 20:47:02 +00:00
}
2002-11-27 12:20:23 +00:00
2002-08-04 15:12:51 +00:00
void Toolbar::checkClock(bool redraw, bool date) {
2002-12-01 13:42:15 +00:00
time_t tmp = 0;
struct tm *tt = 0;
if ((tmp = time(NULL)) != -1) {
if (! (tt = localtime(&tmp))) {
cerr<<__FILE__<<"("<<__LINE__<<"): ! localtime(&tmp)"<<endl;
return;
}
if (tt->tm_min != frame.minute || tt->tm_hour != frame.hour) {
frame.hour = tt->tm_hour;
frame.minute = tt->tm_min;
2002-12-03 17:02:53 +00:00
frame.clock.clear();
2002-12-01 13:42:15 +00:00
redraw = true;
}
} else
cerr<<__FILE__<<"("<<__LINE__<<"): time(null)<0"<<endl;
2001-12-11 20:47:02 +00:00
if (!redraw)
return;
frame.clock.clear();
#ifdef HAVE_STRFTIME
char t[1024];
if (! strftime(t, 1024, screen().getStrftimeFormat(), tt))
return;
#else // !HAVE_STRFTIME
char t[9];
if (date) {
// format the date... with special consideration for y2k ;)
if (screen().getDateFormat() == Blackbox::B_EuropeanDate) {
sprintf(t,
i18n->getMessage(
ToolbarSet, ToolbarNoStrftimeDateFormatEu,
"%02d.%02d.%02d"),
tt->tm_mday, tt->tm_mon + 1,
(tt->tm_year >= 100) ? tt->tm_year - 100 : tt->tm_year);
2002-12-01 13:42:15 +00:00
} else {
sprintf(t,
i18n->getMessage(
ToolbarSet, ToolbarNoStrftimeDateFormat,
"%02d/%02d/%02d"),
tt->tm_mon + 1, tt->tm_mday,
(tt->tm_year >= 100) ? tt->tm_year - 100 : tt->tm_year);
2002-12-01 13:42:15 +00:00
}
} else {
if (screen().isClock24Hour()) {
sprintf(t,
i18n->getMessage(
ToolbarSet, ToolbarNoStrftimeTimeFormat24,
" %02d:%02d "),
frame.hour, frame.minute);
} else {
sprintf(t,
i18n->getMessage(
ToolbarSet, ToolbarNoStrftimeTimeFormat12,
"%02d:%02d %sm"),
((frame.hour > 12) ? frame.hour - 12 :
((frame.hour == 0) ? 12 : frame.hour)), frame.minute,
((frame.hour >= 12) ?
i18n->getMessage(
ToolbarSet, ToolbarNoStrftimeTimeFormatP,
"p") :
i18n->getMessage(
ToolbarSet, ToolbarNoStrftimeTimeFormatA,
"a")));
}
}
#endif // HAVE_STRFTIME
2001-12-11 20:47:02 +00:00
size_t newlen = strlen(t);
int dx = FbTk::doAlignment(frame.clock_w,
frame.bevel_w*2,
m_theme.justify(),
m_theme.font(),
t, strlen(t), newlen);
int dy = 1 + m_theme.font().ascent();
if (m_theme.font().isRotated()) {
int tmp = dy;
dy = frame.clock.height() - dx;
dx = tmp;
}
m_theme.font().drawText(
frame.clock.window(),
screen().getScreenNumber(),
m_theme.clockTextGC(),
t, newlen,
dx, dy);
2001-12-11 20:47:02 +00:00
}
2002-08-04 15:12:51 +00:00
void Toolbar::redrawWindowLabel(bool redraw) {
2002-12-01 13:42:15 +00:00
if (Fluxbox::instance()->getFocusedWindow()) {
if (redraw)
2002-12-03 17:02:53 +00:00
frame.window_label.clear();
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
FluxboxWindow *foc = Fluxbox::instance()->getFocusedWindow();
// don't draw focused window if it's not on the same screen
if (foc->getScreen() != &screen() || foc->getTitle().size() == 0)
2002-12-01 13:42:15 +00:00
return;
2002-12-01 13:42:15 +00:00
size_t newlen = foc->getTitle().size();
int dx = FbTk::doAlignment(frame.window_label_w, frame.bevel_w*2,
m_theme.justify(),
m_theme.font(),
foc->getTitle().c_str(),
foc->getTitle().size(), newlen);
2002-12-04 17:58:01 +00:00
int dy = 1 + m_theme.font().ascent();
if (m_theme.font().isRotated()) {
int tmp = dy;
dy = frame.window_label.height() - dx;
dx = tmp;
}
m_theme.font().drawText(
frame.window_label.window(),
screen().getScreenNumber(),
m_theme.windowTextGC(),
foc->getTitle().c_str(), newlen,
dx, dy);
2002-12-01 13:42:15 +00:00
} else
2002-12-03 17:02:53 +00:00
frame.window_label.clear();
2001-12-11 20:47:02 +00:00
}
2002-08-04 15:12:51 +00:00
void Toolbar::redrawWorkspaceLabel(bool redraw) {
if (screen().getCurrentWorkspace()->name().size()==0)
2002-12-01 13:42:15 +00:00
return;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (redraw)
2002-12-03 17:02:53 +00:00
frame.workspace_label.clear();
const char *text = screen().getCurrentWorkspace()->name().c_str();
size_t textlen = screen().getCurrentWorkspace()->name().size();
2002-12-01 13:42:15 +00:00
size_t newlen = textlen;
int dx = FbTk::doAlignment(frame.workspace_label_w, frame.bevel_w,
m_theme.justify(),
m_theme.font(),
2002-12-01 13:42:15 +00:00
text, textlen, newlen);
2002-12-04 17:58:01 +00:00
int dy = 1 + m_theme.font().ascent();
if (m_theme.font().isRotated()) {
int tmp = dy;
dy = frame.workspace_label_w - dx;
dx = tmp;
}
m_theme.font().drawText(
2002-12-03 17:02:53 +00:00
frame.workspace_label.window(),
screen().getScreenNumber(),
m_theme.labelTextGC(),
2002-12-01 13:42:15 +00:00
text, newlen,
2002-12-04 17:58:01 +00:00
dx, dy);
2001-12-11 20:47:02 +00:00
}
2002-08-04 15:12:51 +00:00
void Toolbar::edit() {
2002-12-01 13:42:15 +00:00
Window window;
int foo;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
editing = true; //mark for editing
2001-12-11 20:47:02 +00:00
2002-12-04 17:58:01 +00:00
//workspace label already has intput focus ?
2002-12-01 13:42:15 +00:00
if (XGetInputFocus(display, &window, &foo) &&
window == frame.workspace_label)
return;
//set input focus to workspace label
2002-12-03 17:02:53 +00:00
XSetInputFocus(display, frame.workspace_label.window(),
((screen().isSloppyFocus() || screen().isSemiSloppyFocus()) ?
2002-12-01 13:42:15 +00:00
RevertToPointerRoot : RevertToParent), CurrentTime);
2002-12-03 17:02:53 +00:00
frame.workspace_label.clear();
2002-12-01 13:42:15 +00:00
Fluxbox * const fluxbox = Fluxbox::instance();
fluxbox->setNoFocus(true);
if (fluxbox->getFocusedWindow()) //disable focus on current focused window
fluxbox->getFocusedWindow()->setFocusFlag(false);
2002-12-03 17:02:53 +00:00
XDrawRectangle(display, frame.workspace_label.window(),
screen().getWindowStyle()->l_text_focus_gc,
2002-12-01 13:42:15 +00:00
frame.workspace_label_w / 2, 0, 1,
frame.label_h - 1);
2001-12-11 20:47:02 +00:00
}
void Toolbar::buttonPressEvent(XButtonEvent &be) {
2002-12-01 13:42:15 +00:00
FluxboxWindow *fluxboxwin=0;
if (be.button == 1) {
if ( m_iconbar.get() != 0 ) {
if ( (fluxboxwin = m_iconbar->findWindow(be.window)) )
2002-12-01 13:42:15 +00:00
fluxboxwin->deiconify();
}
2001-12-11 20:47:02 +00:00
#ifndef HAVE_STRFTIME
else if (be.window == frame.clock) {
2002-12-03 17:02:53 +00:00
frame.clock.clear();
2002-12-01 13:42:15 +00:00
checkClock(true, true);
}
2001-12-11 20:47:02 +00:00
#endif // HAVE_STRFTIME
} else if (be.button == 3) {
2002-12-01 13:42:15 +00:00
FluxboxWindow *fluxboxwin = 0;
// if we clicked on a icon then show window menu
if ( m_iconbar.get() != 0 && (fluxboxwin = m_iconbar->findWindow(be.window)) ) {
2003-01-07 02:07:43 +00:00
const FbTk::Menu &wm = fluxboxwin->getWindowmenu();
int menu_y = be.y_root - wm.height();
int menu_x = be.x_root;
// make sure the menu is visible
if (menu_y < 0) {
menu_y = 0;
2002-12-01 13:42:15 +00:00
}
2003-01-07 02:07:43 +00:00
if (menu_x < 0) {
menu_x = 0;
} else if (menu_x + wm.width() > screen().getWidth()) {
menu_x = screen().getWidth() - wm.width();
2003-01-07 02:07:43 +00:00
}
fluxboxwin->showMenu(menu_x, menu_y);
2002-12-01 13:42:15 +00:00
} else if (! m_toolbarmenu.isVisible()) {
int x, y;
x = be.x_root - (m_toolbarmenu.width() / 2);
y = be.y_root - (m_toolbarmenu.height() / 2);
2002-12-01 13:42:15 +00:00
if (x < 0)
x = 0;
else if (x + m_toolbarmenu.width() > screen().getWidth())
x = screen().getWidth() - m_toolbarmenu.width();
2002-12-01 13:42:15 +00:00
if (y < 0)
y = 0;
else if (y + m_toolbarmenu.height() > screen().getHeight())
y = screen().getHeight() - m_toolbarmenu.height();
2002-12-01 13:42:15 +00:00
m_toolbarmenu.move(x, y);
m_toolbarmenu.show();
} else
m_toolbarmenu.hide();
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
}
void Toolbar::buttonReleaseEvent(XButtonEvent &re) {
if (re.button == 1) {
if (re.window == frame.workspace_label) {
FbTk::Menu *menu = screen().getWorkspacemenu();
2002-12-01 13:42:15 +00:00
//move the workspace label and make it visible
menu->move(re.x_root, re.y_root);
2002-12-01 13:42:15 +00:00
// make sure the entire menu is visible (TODO: this is repeated by other menus, make a function!)
int newx = menu->x(); // new x position of menu
int newy = menu->y(); // new y position of menu
if (menu->x() < 0)
newx = 0;
else if (menu->x() + menu->width() > screen().getWidth())
newx = screen().getWidth() - menu->width();
2002-12-01 13:42:15 +00:00
if (menu->y() < 0)
newy = 0;
else if (menu->y() + menu->height() > screen().getHeight())
newy = screen().getHeight() - menu->height();
2002-12-01 13:42:15 +00:00
// move and show menu
menu->move(newx, newy);
menu->show();
} else if (re.window == frame.window_label)
screen().raiseFocus();
2001-12-11 20:47:02 +00:00
#ifndef HAVE_STRFTIME
else if (re.window == frame.clock) {
2002-12-01 13:42:15 +00:00
XClearWindow(display, frame.clock);
checkClock(true);
}
2001-12-11 20:47:02 +00:00
#endif // HAVE_STRFTIME
} else if (re.button == 4) //mousewheel scroll up
screen().nextWorkspace(1);
else if (re.button == 5) //mousewheel scroll down
screen().prevWorkspace(1);
2001-12-11 20:47:02 +00:00
}
void Toolbar::enterNotifyEvent(XCrossingEvent &not_used) {
2002-12-01 13:42:15 +00:00
if (! do_auto_hide)
return;
if (hidden) {
if (! hide_timer.isTiming())
hide_timer.start();
} else {
if (hide_timer.isTiming())
hide_timer.stop();
}
2001-12-11 20:47:02 +00:00
}
void Toolbar::leaveNotifyEvent(XCrossingEvent &not_used) {
2002-12-01 13:42:15 +00:00
if (! do_auto_hide)
return;
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (hidden) {
if (hide_timer.isTiming())
hide_timer.stop();
} else if (! m_toolbarmenu.isVisible() && ! hide_timer.isTiming())
hide_timer.start();
2002-11-27 12:20:23 +00:00
2001-12-11 20:47:02 +00:00
}
void Toolbar::exposeEvent(XExposeEvent &ee) {
if (ee.window == frame.clock)
2002-12-01 13:42:15 +00:00
checkClock(true);
else if (ee.window == frame.workspace_label && (! editing))
2002-12-01 13:42:15 +00:00
redrawWorkspaceLabel();
else if (m_iconbar.get() != 0)
m_iconbar->exposeEvent(&ee);
2001-12-11 20:47:02 +00:00
}
void Toolbar::keyPressEvent(XKeyEvent &ke) {
if (ke.window == frame.workspace_label && editing) {
2002-12-01 13:42:15 +00:00
KeySym ks;
char keychar[1];
XLookupString(&ke, keychar, 1, &ks, 0);
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
if (ks == XK_Return || ks == XK_Escape) {
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
editing = false;
Fluxbox * const fluxbox = Fluxbox::instance();
fluxbox->setNoFocus(false);
if (fluxbox->getFocusedWindow()) {
fluxbox->getFocusedWindow()->setInputFocus();
fluxbox->getFocusedWindow()->setFocusFlag(true);
} else
XSetInputFocus(display, PointerRoot, None, CurrentTime);
2002-12-01 13:42:15 +00:00
if (ks == XK_Return) //change workspace name if keypress = Return
screen().getCurrentWorkspace()->setName(new_workspace_name.c_str());
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
new_workspace_name.erase(); //erase temporary workspace name
reconfigure();
//save workspace names
Fluxbox::instance()->save_rc();
} else if (! IsModifierKey(ks) && !IsCursorKey(ks)) {
if (ks == XK_BackSpace && new_workspace_name.size())
new_workspace_name.erase(new_workspace_name.size()-1);
else
new_workspace_name += keychar[0];
2002-12-03 17:02:53 +00:00
frame.workspace_label.clear();
2002-12-01 13:42:15 +00:00
int l = new_workspace_name.size(), tw, x;
tw = m_theme.font().textWidth(new_workspace_name.c_str(), l);
2002-12-01 13:42:15 +00:00
x = (frame.workspace_label_w - tw) / 2;
if (x < (signed) frame.bevel_w)
x = frame.bevel_w;
m_theme.font().drawText(
2002-12-03 17:02:53 +00:00
frame.workspace_label.window(),
screen().getScreenNumber(),
screen().getWindowStyle()->l_text_focus_gc,
2002-12-01 13:42:15 +00:00
new_workspace_name.c_str(), l,
x, 1 + m_theme.font().ascent());
2002-12-01 13:42:15 +00:00
2002-12-03 17:02:53 +00:00
XDrawRectangle(display, frame.workspace_label.window(),
screen().getWindowStyle()->l_text_focus_gc, x + tw, 0, 1,
2002-12-01 13:42:15 +00:00
frame.label_h - 1);
}
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
}
2002-08-04 15:12:51 +00:00
void Toolbar::timeout() {
2002-12-01 13:42:15 +00:00
checkClock(true);
2001-12-11 20:47:02 +00:00
2002-12-01 13:42:15 +00:00
timeval delay;
delay.tv_sec = 1;
delay.tv_usec = 0;
clock_timer.setTimeout(delay);
2001-12-11 20:47:02 +00:00
}
void Toolbar::setPlacement(Toolbar::Placement where) {
int head_x = 0,
head_y = 0,
head_w,
head_h;
m_place = where;
head_w = screen().getWidth();
head_h = screen().getHeight();
frame.width = head_w * screen().getToolbarWidthPercent() / 100;
frame.height = m_theme.font().height();
frame.height += 2;
frame.height += (frame.bevel_w * 2);
2002-12-03 17:02:53 +00:00
// should we flipp sizes?
if (isVertical()) {
frame.width = frame.height;
frame.height = head_h * screen().getToolbarWidthPercent() / 100;
2002-12-03 17:02:53 +00:00
if (!m_theme.font().isRotated())
m_theme.font().rotate(90); // rotate to vertical text
frame.label_h = frame.width;
frame.button_w = frame.width;
} else { // horizontal toolbar
if (m_theme.font().isRotated())
m_theme.font().rotate(0); // rotate to horizontal text
frame.label_h = frame.height;
frame.button_w = frame.height;
}
switch (where) {
case TOPLEFT:
frame.x = head_x;
frame.y = head_y;
frame.x_hidden = head_x;
frame.y_hidden = head_y +
screen().getBevelWidth() - screen().getBorderWidth() - frame.height;
break;
case BOTTOMLEFT:
frame.x = head_x;
frame.y = head_y + head_h - frame.height - screen().getBorderWidth2x();
frame.x_hidden = head_x;
frame.y_hidden = head_y + head_h - screen().getBevelWidth() -
screen().getBorderWidth();
break;
case TOPCENTER:
frame.x = head_x + ((head_w - frame.width) / 2);
frame.y = head_y;
frame.x_hidden = frame.x;
frame.y_hidden = head_y +
screen().getBevelWidth() - screen().getBorderWidth() - frame.height;
break;
case TOPRIGHT:
frame.x = head_x + head_w - frame.width - screen().getBorderWidth2x();
frame.y = head_y;
frame.x_hidden = frame.x;
break;
case BOTTOMRIGHT:
frame.x = head_x + head_w - frame.width - screen().getBorderWidth2x();
frame.y = head_y + head_h - frame.height - screen().getBorderWidth2x();
frame.x_hidden = frame.x;
frame.y_hidden = head_y + head_h - screen().getBevelWidth() -
screen().getBorderWidth();
break;
case BOTTOMCENTER: // default is BOTTOMCENTER
default:
2002-12-03 17:02:53 +00:00
frame.x = head_x + (head_w - frame.width) / 2;
frame.y = head_y + head_h - frame.height - screen().getBorderWidth2x();
frame.x_hidden = frame.x;
frame.y_hidden = head_y + head_h - screen().getBevelWidth() -
screen().getBorderWidth();
break;
2002-12-03 17:02:53 +00:00
case LEFTCENTER:
2002-12-04 17:58:01 +00:00
frame.x = head_x;
2002-12-03 17:02:53 +00:00
frame.y = head_y + (head_h - frame.height)/2;
frame.x_hidden = frame.x - frame.width +
screen().getBevelWidth() + screen().getBorderWidth();
2002-12-04 17:58:01 +00:00
frame.y_hidden = frame.y;
break;
case LEFTTOP:
frame.x = head_x;
frame.y = head_y;
frame.x_hidden = frame.x - frame.width +
screen().getBevelWidth() + screen().getBorderWidth();
2002-12-04 17:58:01 +00:00
frame.y_hidden = frame.y;
break;
case LEFTBOTTOM:
frame.x = head_x;
frame.y = head_y + head_h - frame.height;
frame.x_hidden = frame.x - frame.width +
screen().getBevelWidth() + screen().getBorderWidth();
2002-12-04 17:58:01 +00:00
frame.y_hidden = frame.y;
break;
case RIGHTCENTER:
frame.x = head_x + head_w - frame.width;
frame.y = head_y + (head_h - frame.height)/2;
frame.x_hidden = frame.x + frame.width -
screen().getBevelWidth() - screen().getBorderWidth();
2002-12-04 17:58:01 +00:00
frame.y_hidden = frame.y;
break;
case RIGHTTOP:
frame.x = head_x + head_w - frame.width;
frame.y = head_y;
frame.x_hidden = frame.x + frame.width -
screen().getBevelWidth() - screen().getBorderWidth();
2002-12-04 17:58:01 +00:00
frame.y_hidden = frame.y;
break;
case RIGHTBOTTOM:
frame.x = head_x + head_w - frame.width;
frame.y = head_y + head_h - frame.height;
frame.x_hidden = frame.x + frame.width -
screen().getBevelWidth() - screen().getBorderWidth();
2002-12-03 17:02:53 +00:00
frame.y_hidden = frame.y;
break;
}
}
2002-12-03 17:02:53 +00:00
2002-08-04 15:12:51 +00:00
void Toolbar::HideHandler::timeout() {
2002-12-01 13:42:15 +00:00
if (toolbar->isEditing()) { // don't hide if we're editing workspace label
toolbar->hide_timer.fireOnce(false);
toolbar->hide_timer.start(); // restart timer and try next timeout
return;
}
toolbar->hide_timer.fireOnce(true);
toolbar->hidden = ! toolbar->hidden;
if (toolbar->hidden) {
2002-12-03 17:02:53 +00:00
toolbar->frame.window.move(toolbar->frame.x_hidden, toolbar->frame.y_hidden);
2002-12-01 13:42:15 +00:00
} else {
2002-12-03 17:02:53 +00:00
toolbar->frame.window.move(toolbar->frame.x, toolbar->frame.y);
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
}