This commit is contained in:
fluxgen 2003-08-11 20:22:38 +00:00
parent 7d778ce8ac
commit 57b41ae42f
2 changed files with 72 additions and 441 deletions

View file

@ -22,12 +22,12 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Toolbar.cc,v 1.105 2003/08/11 15:56:10 fluxgen Exp $
// $Id: Toolbar.cc,v 1.106 2003/08/11 20:19:16 fluxgen Exp $
#include "Toolbar.hh"
#include "Container.hh"
#include "ClockTool.hh"
#include "TextButton.hh"
#include "IconButton.hh"
#include "IconButtonTheme.hh"
@ -35,6 +35,7 @@
// tools
#include "IconbarTool.hh"
#include "WorkspaceNameTool.hh"
#include "ClockTool.hh"
#include "I18n.hh"
#include "fluxbox.hh"
@ -189,21 +190,12 @@ Toolbar::Frame::Frame(FbTk::EventHandler &evh, int screen_num):
// event mask
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
true), // override redirect
window_label(window, // parent
0, 0, // pos
1, 1, // size
// event mask
ButtonPressMask | ButtonReleaseMask |
ExposureMask |
EnterWindowMask | LeaveWindowMask) {
true) // override redirect
{
FbTk::EventManager &evm = *FbTk::EventManager::instance();
// add windows to eventmanager
evm.add(evh, window);
evm.add(evh, window_label);
}
@ -211,15 +203,12 @@ Toolbar::Frame::~Frame() {
FbTk::EventManager &evm = *FbTk::EventManager::instance();
// remove windows from eventmanager
evm.remove(window);
evm.remove(window_label);
}
Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, FbTk::Menu &menu, size_t width):
m_editing(false),
m_hidden(false),
frame(*this, scrn.screenNumber()),
m_icon_focused_pm(0),
m_icon_unfocused_pm(0),
m_screen(scrn),
m_toolbarmenu(menu),
m_placementmenu(*scrn.menuTheme(),
@ -247,7 +236,9 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, FbTk::Menu &menu, size_t wi
m_rc_placement(scrn.resourceManager(), Toolbar::BOTTOMCENTER,
scrn.name() + ".toolbar.placement", scrn.altName() + ".Toolbar.Placement"),
m_shape(new Shape(frame.window, 0)),
m_tool_theme(scrn.screenNumber(), "toolbar.clock", "Toolbar.Clock") {
m_clock_theme(scrn.screenNumber(), "toolbar.clock", "Toolbar.Clock"),
m_workspace_theme(scrn.screenNumber(), "toolbar.workspace", "Toolbar.Workspace"),
m_iconbar_theme(scrn.screenNumber(), "toolbar.iconbar", "Toolbar.Iconbar") {
// we need to get notified when the theme is reloaded
m_theme.reconfigSig().attach(this);
@ -266,21 +257,14 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, FbTk::Menu &menu, size_t wi
// geometry settings
frame.width = width;
frame.height = frame.label_h = 10;
frame.window_label_w = width/3;
frame.height = 10;
frame.bevel_w = 1;
frame.grab_x = frame.grab_y = 0;
// setup toolbar items
m_item_list.push_back(new ClockTool(frame.window, m_tool_theme, screen()));
m_item_list.push_back(new WorkspaceNameTool(frame.window, m_tool_theme, screen()));
static IconbarTheme iconbar_theme(frame.window.screenNumber(),
"toolbar.iconbar", "Toolbar.Iconbar");
m_item_list.push_back(new IconbarTool(frame.window, iconbar_theme, screen()));
// show all items
frame.window.showSubwindows();
// add toolbar items
m_item_list.push_back(new WorkspaceNameTool(frame.window, m_workspace_theme, screen()));
m_item_list.push_back(new IconbarTool(frame.window, m_iconbar_theme, screen()));
m_item_list.push_back(new ClockTool(frame.window, m_clock_theme, screen()));
m_theme.font().setAntialias(screen().antialias());
@ -290,33 +274,16 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, FbTk::Menu &menu, size_t wi
m_hide_timer.setCommand(toggle_hidden);
m_hide_timer.fireOnce(true);
frame.grab_x = frame.grab_y = 0;
// get everything together
reconfigure();
frame.base = frame.label = 0;
// m_iconbar.reset(new Container(frame.window_label));
// m_iconbar->setBackgroundColor(FbTk::Color("white", 0));
// m_iconbar->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));
reconfigure(); // get everything together
// show all windows
frame.window.showSubwindows();
frame.window.show();
scrn.resourceManager().unlock();
}
Toolbar::~Toolbar() {
while (!m_item_list.empty()) {
delete m_item_list.back();
@ -324,11 +291,6 @@ Toolbar::~Toolbar() {
}
clearStrut();
FbTk::ImageControl &image_ctrl = screen().imageControl();
if (frame.base) image_ctrl.removeImage(frame.base);
if (frame.label) image_ctrl.removeImage(frame.label);
if (m_icon_focused_pm) image_ctrl.removeImage(m_icon_focused_pm);
if (m_icon_unfocused_pm) image_ctrl.removeImage(m_icon_unfocused_pm);
}
void Toolbar::clearStrut() {
@ -386,145 +348,6 @@ bool Toolbar::isVertical() const {
placement() == LEFTBOTTOM);
}
void Toolbar::addIcon(FluxboxWindow *w) {
if (w == 0)
return;
if (m_iconbar.get() != 0) {
// create and setup button for iconbar
FbTk::RefCount<FbTk::Command> on_click(new FbTk::SimpleCommand<FluxboxWindow>(*w, &FluxboxWindow::raiseAndFocus));
IconButton *button = new IconButton(*m_iconbar.get(), theme().iconFont(), *w);
button->setOnClick(on_click);
button->window().setBorderWidth(1);
button->show();
m_icon2winmap[w] = button;
// add button to iconbar
m_iconbar->insertItem(button);
// make sure we listen to focus signal
w->focusSig().attach(this);
// render graphics
updateIconbarGraphics();
}
}
void Toolbar::delIcon(FluxboxWindow *w) {
if (w == 0)
return;
if (m_iconbar.get() != 0) {
IconButton *button = m_icon2winmap[w];
if (button == 0)
return;
int index = m_iconbar->find(button);
if (index >= 0)
m_iconbar->removeItem(index);
m_icon2winmap.erase(w);
delete button;
updateIconbarGraphics();
}
}
void Toolbar::delAllIcons(bool ignore_stuck) {
if (m_iconbar.get() == 0)
return;
m_iconbar->removeAll();
Icon2WinMap::iterator it = m_icon2winmap.begin();
Icon2WinMap::iterator it_end = m_icon2winmap.end();
for (; it != it_end; ++it) {
delete (*it).second;
}
m_icon2winmap.clear();
}
bool Toolbar::containsIcon(const FluxboxWindow &win) const {
return m_icon2winmap.find(const_cast<FluxboxWindow *>(&win)) != m_icon2winmap.end();
}
void Toolbar::enableUpdates() {
}
void Toolbar::disableUpdates() {
}
void Toolbar::updateIconbarGraphics() {
if (m_iconbar.get() == 0)
return;
// render icon pixmaps to correct size
Pixmap tmp = m_icon_focused_pm;
const FbTk::Texture *texture = &(theme().iconbarFocused());
if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
m_icon_focused_pm = 0;
m_icon_focused_color = theme().iconbarFocused().color();
} else {
m_icon_focused_pm = screen().imageControl().renderImage(m_iconbar->maxWidthPerClient(),
m_iconbar->maxHeightPerClient(), *texture);
}
// remove from cache
if (tmp)
screen().imageControl().removeImage(tmp);
// render icon pixmaps to correct size
tmp = m_icon_unfocused_pm;
texture = &(theme().iconbarUnfocused());
if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
m_icon_unfocused_pm = 0;
m_icon_unfocused_color = theme().iconbarUnfocused().color();
} else {
m_icon_unfocused_pm = screen().imageControl().renderImage(m_iconbar->maxWidthPerClient(),
m_iconbar->maxHeightPerClient(), *texture);
}
// remove from cache
if (tmp)
screen().imageControl().removeImage(tmp);
Icon2WinMap::iterator it = m_icon2winmap.begin();
Icon2WinMap::iterator it_end = m_icon2winmap.end();
for (; it != it_end; ++it) {
IconButton &button = *(*it).second;
if (button.win().isFocused()) {
button.setGC(theme().iconTextFocusedGC());
if (m_icon_focused_pm != 0)
button.setBackgroundPixmap(m_icon_focused_pm);
else
button.setBackgroundColor(m_icon_focused_color);
} else { // unfocused
button.setGC(theme().iconTextUnfocusedGC());
if (m_icon_unfocused_pm != 0)
button.setBackgroundPixmap(m_icon_unfocused_pm);
else
button.setBackgroundColor(m_icon_unfocused_color);
}
button.setFont(theme().iconFont());
}
}
void Toolbar::enableIconBar() {
if (m_iconbar.get() != 0)
return; // already on
// m_iconbar.reset(new Container(frame.window_label));
// m_iconbar->show();
}
void Toolbar::disableIconBar() {
if (m_iconbar.get() == 0)
return; // already off
m_iconbar.reset(0); // destroy iconbar
}
void Toolbar::raise() {
m_layeritem.raise();
@ -541,11 +364,6 @@ void Toolbar::reconfigure() {
if (doAutoHide())
m_hide_timer.start();
bool vertical = isVertical();
// if (m_iconbar.get())
// m_iconbar->setVertical(vertical);
frame.bevel_w = theme().bevelWidth();
// destroy shape if the theme wasn't specified with one,
// or create one
@ -558,30 +376,6 @@ void Toolbar::reconfigure() {
// recallibrate size
setPlacement(placement());
unsigned int i;
unsigned int w = 0;
// Right, let's break this one down....
// full width, minus workspace label and the 4 arrow buttons.
// each of the (6) aforementioned items are separated by a bevel width,
// plus outside (+1), plus the window label (+1).
i = 0;
// of course if your toolbar is set too small, this could go negative.
// which is bad mmmkay. Since we are unsigned, we check that *first*.
if (vertical)
w = frame.height;
else
w = frame.width;
if (i > w)
frame.window_label_w = 0;
else
frame.window_label_w = w - i;
if (isHidden())
frame.window.moveResize(frame.x_hidden, frame.y_hidden,
frame.width, frame.height);
@ -591,83 +385,14 @@ void Toolbar::reconfigure() {
}
unsigned int next_x = 0;
unsigned int next_y = frame.window.height();
unsigned int text_x=0, text_y=0;
if (vertical)
text_x = frame.bevel_w;
else
text_y = frame.bevel_w;
next_x = 0;
next_y = 0;
size_t label_w = frame.window_label_w;
size_t label_h = frame.height;
frame.window_label.moveResize(next_x, next_y,
label_w, label_h);
FbTk::ImageControl &image_ctrl = screen().imageControl();
Pixmap tmp = frame.base;
const FbTk::Texture *texture = &(m_theme.toolbar());
if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
frame.base = None;
frame.window.setBackgroundColor(texture->color());
} else {
frame.base = image_ctrl.renderImage(frame.window.width(),
frame.window.height(), *texture);
frame.window.setBackgroundPixmap(frame.base);
}
if (tmp)
image_ctrl.removeImage(tmp);
tmp = frame.label;
texture = &(m_theme.window());
if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
frame.label = None;
frame.window_label.setBackgroundColor(texture->color());
} else {
frame.label =
image_ctrl.renderImage(frame.window_label.width(),
frame.window_label.height(), *texture);
frame.window_label.setBackgroundPixmap(frame.label);
}
if (tmp) image_ctrl.removeImage(tmp);
frame.window.setBorderColor(theme().borderColor());
frame.window.setBorderWidth(theme().borderWidth());
frame.window.clear();
frame.window_label.clear();
frame.window_label.setAlpha(theme().alpha());
if (theme().shape() && m_shape.get())
m_shape->update();
redrawWindowLabel();
// setup icon bar
if (m_iconbar.get()) {
frame.window_label.move(frame.window_label.x(), frame.window_label.y() - 1);
frame.window_label.setBorderWidth(0);
m_iconbar->resize(frame.window_label.width(), frame.window_label.height());
updateIconbarGraphics();
}
redrawWorkspaceLabel();
checkClock(true);
// calculate size for fixed items
ItemList::iterator item_it = m_item_list.begin();
@ -681,110 +406,61 @@ void Toolbar::reconfigure() {
}
}
// calculate what's going to be left over to the relative sized items
int realtive_width = 0;
int relative_width = 0;
if (fixed_items == 0) // no fixed items, then the rest is the entire width
realtive_width = width();
else
realtive_width = (width() - fixed_width)/fixed_items;
relative_width = width();
else {
const int relative_items = m_item_list.size() - fixed_items;
if (relative_items == 0)
relative_width = 0;
else // size left after fixed items / number of relative items
relative_width = (width() - fixed_width)/relative_items;
}
// now move and resize the items
next_x = 0;
int next_x = 0;
for (item_it = m_item_list.begin(); item_it != item_it_end; ++item_it) {
if ((*item_it)->type() == ToolbarItem::RELATIVE) {
(*item_it)->moveResize(next_x, 0, realtive_width, height());
cerr<<"realtive size: "<<(*item_it)->width()<<", "<<(*item_it)->height()<<endl;
} else // fixed size
(*item_it)->moveResize(next_x, 0, relative_width, height());
} else { // fixed size
(*item_it)->moveResize(next_x, 0,
(*item_it)->width(), height());
}
next_x += (*item_it)->width();
}
m_toolbarmenu.reconfigure();
// we're done with all resizing and stuff now we can request a new
// area to be reserv on screen
// area to be reserved on screen
updateStrut();
}
void Toolbar::checkClock(bool redraw, bool date) {
}
void Toolbar::redrawWindowLabel(bool redraw) {
WinClient *winclient = Fluxbox::instance()->getFocusedWindow();
if (winclient) {
if (redraw)
frame.window_label.clear();
const std::string &title = winclient->getTitle();
// don't draw focused window if it's not on the same screen
if (&winclient->screen() != &screen() || title.size() == 0)
return;
unsigned int newlen = title.size();
int dx = FbTk::doAlignment(frame.window_label_w, frame.bevel_w*2,
m_theme.justify(),
m_theme.font(),
title.c_str(),
title.size(), newlen);
int dy = 1 + m_theme.font().ascent();
if (m_theme.font().isRotated()) {
int tmp = dy;
dy = frame.window_label.height() - dx;
dx = tmp + frame.bevel_w;
} else
dy += frame.bevel_w;
m_theme.font().drawText(frame.window_label.window(),
screen().screenNumber(),
m_theme.windowTextGC(),
title.c_str(), newlen,
dx, dy);
} else
frame.window_label.clear();
frame.window_label.updateTransparent();
}
void Toolbar::redrawWorkspaceLabel(bool redraw) {
}
void Toolbar::edit() {
}
void Toolbar::buttonPressEvent(XButtonEvent &be) {
if (be.button == 3) {
if (! m_toolbarmenu.isVisible()) {
int x, y;
if (be.button != 3)
return;
x = be.x_root - (m_toolbarmenu.width() / 2);
y = be.y_root - (m_toolbarmenu.height() / 2);
if (! m_toolbarmenu.isVisible()) {
int x, y;
if (x < 0)
x = 0;
else if (x + m_toolbarmenu.width() > screen().width())
x = screen().width() - m_toolbarmenu.width();
x = be.x_root - (m_toolbarmenu.width() / 2);
y = be.y_root - (m_toolbarmenu.height() / 2);
if (y < 0)
y = 0;
else if (y + m_toolbarmenu.height() > screen().height())
y = screen().height() - m_toolbarmenu.height();
if (x < 0)
x = 0;
else if (x + m_toolbarmenu.width() > screen().width())
x = screen().width() - m_toolbarmenu.width();
m_toolbarmenu.move(x, y);
m_toolbarmenu.show();
} else
m_toolbarmenu.hide();
}
if (y < 0)
y = 0;
else if (y + m_toolbarmenu.height() > screen().height())
y = screen().height() - m_toolbarmenu.height();
m_toolbarmenu.move(x, y);
m_toolbarmenu.show();
} else
m_toolbarmenu.hide();
}
@ -836,28 +512,7 @@ void Toolbar::keyPressEvent(XKeyEvent &ke) {
void Toolbar::update(FbTk::Subject *subj) {
if (typeid(*subj) == typeid(FluxboxWindow::WinSubject) && m_iconbar.get()) { // focus signal
FluxboxWindow &win = dynamic_cast<FluxboxWindow::WinSubject *>(subj)->win();
if (m_icon2winmap[&win] == 0)
return;
FbTk::Button *was_selected = m_iconbar->selected();
int pos = m_iconbar->find(m_icon2winmap[&win]);
m_iconbar->setSelected(pos);
// setup texture for the unseleced and selected button
if (m_iconbar->selected()) {
if (m_icon_focused_pm == 0)
m_iconbar->selected()->setBackgroundColor(m_icon_focused_color);
else
m_iconbar->selected()->setBackgroundPixmap(m_icon_focused_pm);
}
if (was_selected) {
if (m_icon_unfocused_pm == 0)
was_selected->setBackgroundColor(m_icon_unfocused_color);
else
was_selected->setBackgroundPixmap(m_icon_unfocused_pm);
}
return; // nothing more to do
}
// either screen reconfigured or theme was reloaded
reconfigure();
@ -901,11 +556,9 @@ void Toolbar::setPlacement(Toolbar::Placement where) {
if (!m_theme.font().isRotated())
m_theme.font().rotate(90); // rotate to vertical text
frame.label_h = frame.width;
} else { // horizontal toolbar
if (m_theme.font().isRotated())
m_theme.font().rotate(0); // rotate to horizontal text
frame.label_h = frame.height;
}
// So we get at least one pixel visible in hidden mode
@ -1046,12 +699,14 @@ void Toolbar::setupMenus() {
using namespace FbTk;
FbTk::Menu &menu = tbar.menu();
//!! TODO: this should be inserted by the workspace tool
/*
RefCount<Command> start_edit(new SimpleCommand<Toolbar>(tbar, &Toolbar::edit));
menu.insert(i18n->getMessage(FBNLS::ToolbarSet, FBNLS::ToolbarEditWkspcName,
"Edit current workspace name"),
start_edit);
"Edit current workspace name"),
start_edit);
*/
menu.setLabel(i18n->getMessage(FBNLS::ToolbarSet, FBNLS::ToolbarToolbarTitle,
"Toolbar"));
@ -1084,13 +739,13 @@ void Toolbar::setupMenus() {
if (tbar.screen().hasXinerama()) {
// TODO: nls (main label plus menu heading
menu.insert("On Head...", new XineramaHeadMenu<Toolbar>(
*tbar.screen().menuTheme(),
tbar.screen(),
tbar.screen().imageControl(),
*tbar.screen().layerManager().getLayer(Fluxbox::instance()->getMenuLayer()),
tbar,
"Toolbar on Head"
));
*tbar.screen().menuTheme(),
tbar.screen(),
tbar.screen().imageControl(),
*tbar.screen().layerManager().getLayer(Fluxbox::instance()->getMenuLayer()),
tbar,
"Toolbar on Head"
));
}
// setup items in placement menu

View file

@ -22,7 +22,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// $Id: Toolbar.hh,v 1.40 2003/08/11 15:54:24 fluxgen Exp $
// $Id: Toolbar.hh,v 1.41 2003/08/11 20:22:38 fluxgen Exp $
#ifndef TOOLBAR_HH
#define TOOLBAR_HH
@ -30,6 +30,7 @@
#include "Timer.hh"
#include "ToolbarTheme.hh"
#include "ToolTheme.hh"
#include "IconbarTheme.hh"
#include "EventHandler.hh"
#include "FbWindow.hh"
@ -74,22 +75,10 @@ public:
virtual ~Toolbar();
/// add icon to iconbar
void addIcon(FluxboxWindow *w);
/// remove icon from iconbar
void delIcon(FluxboxWindow *w);
bool containsIcon(const FluxboxWindow &win) const;
/// remove all icons
void delAllIcons(bool ignore_stuck = false);
void enableIconBar();
void disableIconBar();
void raise();
void lower();
void toggleHidden();
void enableUpdates();
void disableUpdates();
void moveToLayer(int layernum);
@ -107,13 +96,10 @@ public:
void keyPressEvent(XKeyEvent &ke);
//@}
void redrawWindowLabel(bool redraw= false);
void redrawWorkspaceLabel(bool redraw= false);
/// enter edit mode on workspace label
void edit();
void reconfigure();
void setPlacement(Placement where);
void checkClock(bool redraw = false, bool date = false);
void update(FbTk::Subject *subj);
@ -137,14 +123,13 @@ public:
inline const FbTk::FbWindow &window() const { return frame.window; }
inline BScreen &screen() { return m_screen; }
inline const BScreen &screen() const { return m_screen; }
inline unsigned int width() const { return frame.width; }
inline unsigned int height() const { return frame.height; }
inline unsigned int width() const { return frame.window.width(); }
inline unsigned int height() const { return frame.window.height(); }
inline unsigned int exposedHeight() const { return doAutoHide() ? frame.bevel_w : frame.height; }
inline int x() const { return isHidden() ? frame.x_hidden : frame.x; }
inline int y() const { return isHidden() ? frame.y_hidden : frame.y; }
inline Placement placement() const { return *m_rc_placement; }
/// @return pointer to iconbar if it got one, else 0
inline const IconBar *iconBar() const { return m_iconbar.get(); }
inline const ToolbarTheme &theme() const { return m_theme; }
inline ToolbarTheme &theme() { return m_theme; }
bool isVertical() const;
@ -165,16 +150,12 @@ private:
Frame(FbTk::EventHandler &evh, int screen_num);
~Frame();
Pixmap base, label;
FbTk::FbWindow window, window_label;
FbTk::FbWindow window;
int x, y, x_hidden, y_hidden, grab_x, grab_y;
unsigned int width, height, window_label_w, bevel_w, label_h;
unsigned int width, height, bevel_w;
} frame;
Pixmap m_icon_focused_pm, m_icon_unfocused_pm;
FbTk::Color m_icon_focused_color, m_icon_unfocused_color;
BScreen &m_screen; ///< screen connection
FbTk::Timer m_hide_timer; ///< timer to for auto hide toolbar
@ -182,13 +163,7 @@ private:
FbTk::Menu m_placementmenu;
LayerMenu<Toolbar> m_layermenu;
// icon stuff
std::auto_ptr<Container> m_iconbar;
typedef std::map<FluxboxWindow *, IconButton *> Icon2WinMap;
Icon2WinMap m_icon2winmap;
std::string m_new_workspace_name; ///< temp variable in edit workspace name mode
ToolbarTheme m_theme;
FbTk::XLayerItem m_layeritem;
@ -204,7 +179,8 @@ private:
FbTk::Resource<Placement> m_rc_placement;
std::auto_ptr<Shape> m_shape;
ToolTheme m_tool_theme;
ToolTheme m_clock_theme, m_workspace_theme;
IconbarTheme m_iconbar_theme;
};