fluxbox/src/Toolbar.cc

1012 lines
34 KiB
C++
Raw Normal View History

2002-03-19 14:30:43 +00:00
// Toolbar.cc for Fluxbox
2006-02-16 06:53:05 +00:00
// Copyright (c) 2002 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
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.
2002-08-04 15:12:51 +00:00
#include "Toolbar.hh"
2002-02-07 15:12:23 +00:00
#include "ToolbarItem.hh"
2003-08-16 12:10:19 +00:00
#include "ToolbarTheme.hh"
2003-08-29 00:44:41 +00:00
2006-02-27 21:43:01 +00:00
#include "fluxbox.hh"
2007-10-13 21:51:37 +00:00
#include "Keys.hh"
2001-12-11 20:47:02 +00:00
#include "Screen.hh"
#include "ScreenPlacement.hh"
#include "WindowCmd.hh"
2003-06-18 13:55:17 +00:00
#include "Strut.hh"
#include "Layer.hh"
2003-08-11 15:56:10 +00:00
2015-01-23 22:38:34 +00:00
#include "FbTk/CommandParser.hh"
2006-02-27 21:43:01 +00:00
#include "FbTk/I18n.hh"
2003-08-28 13:58:18 +00:00
#include "FbTk/ImageControl.hh"
#include "FbTk/TextUtils.hh"
2003-08-28 13:58:18 +00:00
#include "FbTk/MacroCommand.hh"
#include "FbTk/EventManager.hh"
#include "FbTk/SimpleCommand.hh"
#include "FbTk/StringUtil.hh"
#include "FbTk/Transparent.hh"
2007-12-27 21:55:24 +00:00
#include "FbTk/BoolMenuItem.hh"
#include "FbTk/IntMenuItem.hh"
2007-12-28 06:52:48 +00:00
#include "FbTk/Shape.hh"
#include "FbTk/MemFun.hh"
#include "FbTk/STLUtil.hh"
#include "FbTk/Util.hh"
2003-08-28 13:58:18 +00:00
2001-12-11 20:47:02 +00:00
#include <X11/Xutil.h>
#include <X11/keysym.h>
2004-08-31 15:26:40 +00:00
#ifdef HAVE_CSTRING
#include <cstring>
#else
#include <string.h>
#endif
2003-08-28 13:58:18 +00:00
#include <iterator>
#include <typeinfo>
#include <functional>
#include <algorithm>
2006-10-30 19:31:15 +00:00
using std::string;
using std::pair;
using std::list;
2002-12-04 17:58:01 +00:00
using FbTk::STLUtil::forAll;
namespace {
2015-01-23 22:38:34 +00:00
const struct {
Toolbar::Placement placement;
const char* str;
2015-01-23 22:38:34 +00:00
FbTk::Orientation orient;
unsigned int shape;
} _values[] = {
{ /* unused */ },
{ Toolbar::TOPLEFT, "TopLeft", FbTk::ROT0, FbTk::Shape::BOTTOMRIGHT },
{ Toolbar::TOPCENTER, "TopCenter", FbTk::ROT0, FbTk::Shape::BOTTOMRIGHT | FbTk::Shape::BOTTOMLEFT },
{ Toolbar::TOPRIGHT, "TopRight", FbTk::ROT0, FbTk::Shape::BOTTOMLEFT },
{ Toolbar::BOTTOMLEFT, "BottomLeft", FbTk::ROT0, FbTk::Shape::TOPRIGHT },
{ Toolbar::BOTTOMCENTER, "BottomCenter", FbTk::ROT0, FbTk::Shape::TOPRIGHT | FbTk::Shape::TOPLEFT },
{ Toolbar::BOTTOMRIGHT, "BottomRight", FbTk::ROT0, FbTk::Shape::TOPLEFT },
{ Toolbar::LEFTBOTTOM, "LeftBottom", FbTk::ROT270, FbTk::Shape::TOPRIGHT },
{ Toolbar::LEFTCENTER, "LeftCenter", FbTk::ROT270, FbTk::Shape::TOPRIGHT | FbTk::Shape::BOTTOMRIGHT },
{ Toolbar::LEFTTOP, "LeftTop", FbTk::ROT270, FbTk::Shape::BOTTOMRIGHT },
{ Toolbar::RIGHTBOTTOM, "RightBottom", FbTk::ROT90, FbTk::Shape::TOPLEFT },
{ Toolbar::RIGHTCENTER, "RightCenter", FbTk::ROT90, FbTk::Shape::TOPLEFT | FbTk::Shape::BOTTOMLEFT },
{ Toolbar::RIGHTTOP, "RightTop", FbTk::ROT90, FbTk::Shape::BOTTOMLEFT },
};
}
namespace FbTk {
2004-10-21 10:36:57 +00:00
template<>
string FbTk::Resource<Toolbar::Placement>::
2005-11-22 21:09:14 +00:00
getString() const {
size_t i = (m_value == FbTk::Util::clamp(m_value, Toolbar::TOPLEFT, Toolbar::RIGHTTOP)
? m_value
2015-01-23 22:38:34 +00:00
: Toolbar::DEFAULT);
return _values[i].str;
}
template<>
void FbTk::Resource<Toolbar::Placement>::
setFromString(const char *strval) {
size_t i;
2015-01-23 22:38:34 +00:00
for (i = 1; i < sizeof(_values)/sizeof(_values[0]); ++i) {
if (strcasecmp(strval, _values[i].str) == 0) {
m_value = _values[i].placement;
return;
}
}
setDefaultValue();
}
} // end namespace FbTk
2003-01-12 18:04:39 +00:00
namespace {
class PlaceToolbarMenuItem: public FbTk::RadioMenuItem {
public:
PlaceToolbarMenuItem(const FbTk::FbString &label, Toolbar &toolbar,
Toolbar::Placement place):
FbTk::RadioMenuItem(label), m_toolbar(toolbar), m_place(place) {
setCloseOnClick(false);
}
bool isSelected() const { return m_toolbar.placement() == m_place; }
void click(int button, int time, unsigned int mods) {
m_toolbar.setPlacement(m_place);
m_toolbar.reconfigure();
2008-08-24 00:36:55 +00:00
m_toolbar.placementMenu().reconfigure();
Fluxbox::instance()->save_rc();
2003-01-12 18:04:39 +00:00
}
private:
Toolbar &m_toolbar;
2003-01-12 18:04:39 +00:00
Toolbar::Placement m_place;
};
} // end anonymous
2003-01-12 18:04:39 +00:00
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
10, 10, // size
// event mask
ButtonPressMask | ButtonReleaseMask | ExposureMask |
EnterWindowMask | LeaveWindowMask | SubstructureNotifyMask,
2005-02-07 13:45:31 +00:00
true) // override redirect
2003-08-11 20:22:38 +00:00
{
2002-12-03 17:02:53 +00:00
FbTk::EventManager &evm = *FbTk::EventManager::instance();
evm.add(evh, window);
2003-08-11 15:56:10 +00:00
2002-12-03 17:02:53 +00:00
}
Toolbar::Frame::~Frame() {
FbTk::EventManager &evm = *FbTk::EventManager::instance();
evm.remove(window);
}
2001-12-11 20:47:02 +00:00
Toolbar::Toolbar(BScreen &scrn, FbTk::Layer &layer, size_t width):
m_hidden(false),
2003-05-15 12:00:46 +00:00
frame(*this, scrn.screenNumber()),
2003-08-19 21:28:57 +00:00
m_window_pm(0),
2002-12-01 13:42:15 +00:00
m_screen(scrn),
2004-06-07 21:36:06 +00:00
m_layeritem(frame.window, layer),
2005-02-07 13:45:31 +00:00
m_layermenu(scrn.menuTheme(),
2003-05-15 23:30:07 +00:00
scrn.imageControl(),
*scrn.layerManager().getLayer(ResourceLayer::MENU),
this,
true),
2003-12-18 18:03:23 +00:00
m_placementmenu(scrn.menuTheme(),
2003-12-10 23:08:06 +00:00
scrn.imageControl(),
*scrn.layerManager().getLayer(ResourceLayer::MENU)),
2003-12-18 18:03:23 +00:00
m_toolbarmenu(scrn.menuTheme(),
2003-12-10 23:08:06 +00:00
scrn.imageControl(),
*scrn.layerManager().getLayer(ResourceLayer::MENU)),
#ifdef XINERAMA
m_xineramaheadmenu(0),
#endif // XINERAMA
2003-05-15 12:00:46 +00:00
m_theme(scrn.screenNumber()),
m_tool_factory(scrn),
m_strut(0),
// lock rcmanager here
2005-02-07 13:45:31 +00:00
m_rc_auto_hide(scrn.resourceManager().lock(), false,
scrn.name() + ".toolbar.autoHide", scrn.altName() + ".Toolbar.AutoHide"),
m_rc_maximize_over(scrn.resourceManager(), false,
scrn.name() + ".toolbar.maxOver", scrn.altName() + ".Toolbar.MaxOver"),
2003-12-08 17:29:44 +00:00
m_rc_visible(scrn.resourceManager(), true, scrn.name() + ".toolbar.visible", scrn.altName() + ".Toolbar.Visible"),
m_rc_width_percent(scrn.resourceManager(), 100,
2005-02-07 13:45:31 +00:00
scrn.name() + ".toolbar.widthPercent", scrn.altName() + ".Toolbar.WidthPercent"),
m_rc_alpha(scrn.resourceManager(), 255,
scrn.name() + ".toolbar.alpha", scrn.altName() + ".Toolbar.Alpha"),
m_rc_layernum(scrn.resourceManager(), ResourceLayer(ResourceLayer::DOCK),
scrn.name() + ".toolbar.layer", scrn.altName() + ".Toolbar.Layer"),
m_rc_on_head(scrn.resourceManager(), 1,
scrn.name() + ".toolbar.onhead", scrn.altName() + ".Toolbar.onHead"),
2005-02-07 13:45:31 +00:00
m_rc_placement(scrn.resourceManager(), Toolbar::BOTTOMCENTER,
2003-07-10 11:48:14 +00:00
scrn.name() + ".toolbar.placement", scrn.altName() + ".Toolbar.Placement"),
m_rc_height(scrn.resourceManager(), 0, scrn.name() + ".toolbar.height", scrn.altName() + ".Toolbar.Height"),
m_rc_tools(scrn.resourceManager(), "prevworkspace, workspacename, nextworkspace, iconbar, systemtray, clock",
2003-08-28 15:04:47 +00:00
scrn.name() + ".toolbar.tools", scrn.altName() + ".Toolbar.Tools"),
2007-12-28 06:52:48 +00:00
m_shape(new FbTk::Shape(frame.window, 0)),
m_resize_lock(false) {
2004-06-07 11:46:05 +00:00
_FB_USES_NLS;
2012-10-22 15:39:35 +00:00
frame.window.setWindowRole("fluxbox-toolbar");
// get this on antialias change
m_signal_tracker.join(screen().reconfigureSig(),
FbTk::MemFunIgnoreArgs(*this, &Toolbar::reconfigure));
// we need to get notified when the theme is reloaded
m_signal_tracker.join(m_theme.reconfigSig(), FbTk::MemFun(*this, &Toolbar::reconfigure));
2003-08-24 23:15:02 +00:00
// listen to screen size changes
m_signal_tracker.join(screen().resizeSig(),
FbTk::MemFun(*this, &Toolbar::screenChanged));
moveToLayer((*m_rc_layernum).getNum());
m_layermenu.setLabel(_FB_XTEXT(Toolbar, Layer, "Toolbar Layer", "Title of toolbar layer menu"));
m_placementmenu.setLabel(_FB_XTEXT(Toolbar, Placement, "Toolbar Placement", "Title of toolbar placement menu"));
2003-05-24 13:13:22 +00:00
m_layermenu.setInternalMenu();
m_placementmenu.setInternalMenu();
2006-04-24 13:34:14 +00:00
m_toolbarmenu.setInternalMenu();
setupMenus();
2003-12-07 15:27:52 +00:00
// add menu to screen
screen().addConfigMenu(_FB_XTEXT(Toolbar, Toolbar, "Toolbar", "title of toolbar menu item"), menu());
2005-02-07 13:45:31 +00:00
// geometry settings
frame.width = width;
2003-08-11 20:22:38 +00:00
frame.height = 10;
frame.bevel_w = 1;
2003-08-11 20:22:38 +00:00
frame.grab_x = frame.grab_y = 0;
2005-02-07 13:45:31 +00:00
2003-08-11 15:56:10 +00:00
// setup hide timer
m_hide_timer.setTimeout(Fluxbox::instance()->getAutoRaiseDelay() * FbTk::FbTime::IN_MILLISECONDS);
FbTk::RefCount<FbTk::Command<void> > toggle_hidden(new FbTk::SimpleCommand<Toolbar>(*this, &Toolbar::toggleHidden));
2003-08-11 15:56:10 +00:00
m_hide_timer.setCommand(toggle_hidden);
2003-05-10 13:57:07 +00:00
m_hide_timer.fireOnce(true);
2002-12-01 13:42:15 +00:00
2001-12-11 20:47:02 +00:00
2003-08-11 20:22:38 +00:00
// show all windows
2003-05-17 11:30:59 +00:00
frame.window.showSubwindows();
2004-07-14 23:39:29 +00:00
// frame.window.show();
scrn.resourceManager().unlock();
2003-08-23 15:42:48 +00:00
// setup to listen to child events
FbTk::EventManager::instance()->addParent(*this, window());
Fluxbox::instance()->keys()->registerWindow(window().window(), *this,
2007-10-13 21:51:37 +00:00
Keys::ON_TOOLBAR);
// get everything together
2005-02-07 13:45:31 +00:00
reconfigure();
// this gets done by the screen later as it loads
2001-12-11 20:47:02 +00:00
}
2002-08-04 15:12:51 +00:00
Toolbar::~Toolbar() {
Keys* keys = Fluxbox::instance()->keys();
if (keys)
keys->unregisterWindow(window().window());
2003-08-28 13:58:18 +00:00
FbTk::EventManager::instance()->remove(window());
2003-12-03 00:33:30 +00:00
// remove menu items before we delete tools so we dont end up
// with dangling pointers to old submenu items (internal menus)
// from the tools
2006-04-24 13:34:14 +00:00
screen().removeConfigMenu(menu());
2003-12-03 00:33:30 +00:00
menu().removeAll();
2003-08-28 13:58:18 +00:00
deleteItems();
clearStrut();
2003-08-11 15:56:10 +00:00
2003-08-19 21:28:57 +00:00
if (m_window_pm)
screen().imageControl().removeImage(m_window_pm);
2002-12-03 17:02:53 +00:00
}
2001-12-11 20:47:02 +00:00
2003-06-18 13:55:17 +00:00
void Toolbar::clearStrut() {
if (m_strut) {
screen().clearStrut(m_strut);
m_strut = 0;
}
}
void Toolbar::updateStrut() {
2003-06-22 19:39:47 +00:00
bool had_strut = m_strut ? true : false;
2003-06-18 13:55:17 +00:00
clearStrut();
// we should request space if we're in autohide mode or
// if the user dont want to request space for toolbar.
if (doAutoHide() || *m_rc_maximize_over || ! *m_rc_visible) {
2003-06-22 19:39:47 +00:00
if (had_strut)
2005-02-07 13:45:31 +00:00
screen().updateAvailableWorkspaceArea();
2003-06-18 13:55:17 +00:00
return;
2003-06-22 19:39:47 +00:00
}
2003-06-18 13:55:17 +00:00
// request area on screen
2015-01-23 22:38:34 +00:00
int w = static_cast<int>(width());
int h = static_cast<int>(height());
int bw = theme()->border().width();
2003-06-18 13:55:17 +00:00
int top = 0, bottom = 0, left = 0, right = 0;
switch (placement()) {
2003-06-18 13:55:17 +00:00
case TOPLEFT:
case TOPCENTER:
case TOPRIGHT:
2015-01-23 22:38:34 +00:00
top = h + 2 * bw;
2003-06-18 13:55:17 +00:00
break;
case BOTTOMLEFT:
case BOTTOMCENTER:
case BOTTOMRIGHT:
2015-01-23 22:38:34 +00:00
bottom = h + 2 * bw;
2003-06-18 13:55:17 +00:00
break;
case RIGHTTOP:
case RIGHTCENTER:
case RIGHTBOTTOM:
2015-01-23 22:38:34 +00:00
right = w + 2 * bw;
2003-06-18 13:55:17 +00:00
break;
case LEFTTOP:
case LEFTCENTER:
case LEFTBOTTOM:
2015-01-23 22:38:34 +00:00
left = w + 2 * bw;
2003-06-18 13:55:17 +00:00
break;
};
m_strut = screen().requestStrut(getOnHead(), left, right, top, bottom);
2003-06-18 13:55:17 +00:00
screen().updateAvailableWorkspaceArea();
}
2002-12-03 17:02:53 +00:00
bool Toolbar::isVertical() const {
return (placement() == RIGHTCENTER ||
placement() == RIGHTTOP ||
placement() == RIGHTBOTTOM ||
placement() == LEFTCENTER ||
placement() == LEFTTOP ||
placement() == LEFTBOTTOM);
2001-12-11 20:47:02 +00:00
}
2003-03-03 21:51:13 +00:00
void Toolbar::raise() {
m_layeritem.raise();
}
void Toolbar::lower() {
m_layeritem.lower();
}
2003-03-03 21:51:13 +00:00
void Toolbar::screenChanged(BScreen &screen) {
reconfigure();
}
2002-08-04 15:12:51 +00:00
void Toolbar::reconfigure() {
updateVisibleState();
2003-12-20 19:05:42 +00:00
if (doAutoHide() && !isHidden() && !m_hide_timer.isTiming())
m_hide_timer.start();
2003-12-20 19:05:42 +00:00
if (!doAutoHide() && isHidden())
toggleHidden();
m_tool_factory.updateThemes();
2003-08-28 13:58:18 +00:00
// parse resource tools and determine if we need to rebuild toolbar
bool need_update = false;
// parse and transform to lower case
2006-10-30 19:31:15 +00:00
list<string> tools;
2003-08-28 13:58:18 +00:00
FbTk::StringUtil::stringtok(tools, *m_rc_tools, ", ");
transform(tools.begin(),
tools.end(),
tools.begin(),
FbTk::StringUtil::toLower);
2004-01-21 13:36:09 +00:00
if (!tools.empty() && tools.size() == m_tools.size()) {
2003-08-28 13:58:18 +00:00
StringList::const_iterator tool_it = tools.begin();
StringList::const_iterator current_tool_it = m_tools.begin();
StringList::const_iterator tool_it_end = tools.end();
for (; tool_it != tool_it_end; ++tool_it, ++current_tool_it) {
if (*current_tool_it != *tool_it)
break;
}
// did we find anything that wasn't in the right place or new item?
if (tool_it != tool_it_end)
need_update = true;
} else // sizes does not match so we update
need_update = true;
if (need_update) {
// destroy tools and rebuild them
deleteItems();
// they will be readded later
menu().removeAll();
setupMenus(true); // rebuild menu but skip rebuild of placement menu
2003-08-28 13:58:18 +00:00
m_tools = tools; // copy values
2005-02-07 13:45:31 +00:00
if (!m_tools.empty()) {
2003-08-28 13:58:18 +00:00
// create items
StringList::const_iterator item_it = m_tools.begin();
StringList::const_iterator item_it_end = m_tools.end();
for (; item_it != item_it_end; ++item_it) {
ToolbarItem *item = m_tool_factory.create(*item_it, frame.window, *this);
if (item == 0)
continue;
m_item_list.push_back(item);
m_signal_tracker.join(item->resizeSig(),
FbTk::MemFun(*this, &Toolbar::rearrangeItems));
2003-08-28 13:58:18 +00:00
}
// show all items
frame.window.showSubwindows();
}
2006-10-30 19:31:15 +00:00
} else { // just update the menu
menu().reconfigure();
2003-08-28 13:58:18 +00:00
}
2008-01-05 01:39:19 +00:00
frame.bevel_w = theme()->bevelWidth();
2003-07-10 11:48:14 +00:00
// destroy shape if the theme wasn't specified with one,
2005-02-07 13:45:31 +00:00
// or create one
2008-01-05 01:39:19 +00:00
if (theme()->shape() == false && m_shape.get())
2003-07-10 11:48:14 +00:00
m_shape.reset(0);
2008-01-05 01:39:19 +00:00
else if (theme()->shape() && m_shape.get() == 0) {
2007-12-28 06:52:48 +00:00
m_shape.reset(new FbTk::Shape(frame.window, 0));
2003-07-10 11:48:14 +00:00
}
2003-08-11 15:56:10 +00:00
// recalibrate size
setPlacement(placement());
2001-12-11 20:47:02 +00:00
if (isHidden()) {
2002-12-03 17:02:53 +00:00
frame.window.moveResize(frame.x_hidden, frame.y_hidden,
frame.width, frame.height);
} else {
2002-12-03 17:02:53 +00:00
frame.window.moveResize(frame.x, frame.y,
frame.width, frame.height);
}
2003-08-19 21:28:57 +00:00
// render frame window
Pixmap tmp = m_window_pm;
2008-01-05 01:39:19 +00:00
if (!theme()->toolbar().usePixmap()) {
2003-08-19 21:28:57 +00:00
m_window_pm = 0;
2008-01-05 01:39:19 +00:00
frame.window.setBackgroundColor(theme()->toolbar().color());
2003-08-19 21:28:57 +00:00
} else {
FbTk::Orientation orient = FbTk::ROT0;
Toolbar::Placement where = *m_rc_placement;
if (where == LEFTCENTER || where == LEFTTOP || where == LEFTBOTTOM)
orient = FbTk::ROT270;
if (where == RIGHTCENTER || where == RIGHTTOP || where == RIGHTBOTTOM)
orient = FbTk::ROT90;
m_window_pm = screen().imageControl().renderImage(
frame.window.width(), frame.window.height(),
2008-01-05 01:39:19 +00:00
theme()->toolbar(), orient);
2003-08-19 21:28:57 +00:00
frame.window.setBackgroundPixmap(m_window_pm);
}
if (tmp)
screen().imageControl().removeImage(tmp);
2005-02-07 13:45:31 +00:00
2008-01-05 01:39:19 +00:00
frame.window.setBorderColor(theme()->border().color());
frame.window.setBorderWidth(theme()->border().width());
bool have_composite = FbTk::Transparent::haveComposite();
// have_composite could have changed, so we need to change both
if (have_composite) {
frame.window.setOpaque(alpha());
frame.window.setAlpha(255);
} else {
frame.window.setOpaque(255);
frame.window.setAlpha(alpha());
}
2002-12-03 17:02:53 +00:00
frame.window.clear();
2005-02-07 13:45:31 +00:00
2008-01-05 01:39:19 +00:00
if (theme()->shape() && m_shape.get())
2003-07-10 11:48:14 +00:00
m_shape->update();
forAll(m_item_list, std::mem_fun(&ToolbarItem::updateSizing));
2002-12-01 13:42:15 +00:00
rearrangeItems();
2003-08-11 15:56:10 +00:00
forAll(m_item_list, std::bind2nd(std::mem_fun(&ToolbarItem::renderTheme), alpha()));
2005-02-07 13:45:31 +00:00
// we're done with all resizing and stuff now we can request a new
2003-08-11 20:22:38 +00:00
// area to be reserved on screen
2003-06-18 13:55:17 +00:00
updateStrut();
2003-08-13 15:28:24 +00:00
#ifdef XINERAMA
if (m_xineramaheadmenu)
m_xineramaheadmenu->reloadHeads();
#endif // XINERAMA
2001-12-11 20:47:02 +00:00
}
2002-11-27 12:20:23 +00:00
2003-08-11 20:22:38 +00:00
void Toolbar::buttonPressEvent(XButtonEvent &be) {
2007-10-13 21:51:37 +00:00
if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button,
2008-02-11 18:17:45 +00:00
Keys::ON_TOOLBAR, 0, be.time))
2007-10-13 21:51:37 +00:00
return;
2008-01-22 09:34:02 +00:00
2007-10-13 21:51:37 +00:00
if (be.button == 1)
raise();
if (be.button != 2)
2003-08-11 20:22:38 +00:00
return;
screen()
.placementStrategy()
.placeAndShowMenu(menu(), be.x_root, be.y_root, false);
2001-12-11 20:47:02 +00:00
}
void Toolbar::enterNotifyEvent(XCrossingEvent &ce) {
Fluxbox::instance()->keys()->doAction(ce.type, ce.state, 0,
Keys::ON_TOOLBAR);
2008-01-22 09:34:02 +00:00
2003-12-20 19:05:42 +00:00
if (! doAutoHide()) {
if (isHidden())
toggleHidden();
2002-12-01 13:42:15 +00:00
return;
2003-12-20 19:05:42 +00:00
}
2002-12-01 13:42:15 +00:00
if (isHidden()) {
2003-05-10 13:57:07 +00:00
if (! m_hide_timer.isTiming())
m_hide_timer.start();
2002-12-01 13:42:15 +00:00
} else {
2003-05-10 13:57:07 +00:00
if (m_hide_timer.isTiming())
m_hide_timer.stop();
2002-12-01 13:42:15 +00:00
}
2001-12-11 20:47:02 +00:00
}
2003-12-20 19:05:42 +00:00
void Toolbar::leaveNotifyEvent(XCrossingEvent &event) {
// in autoHide mode we'll receive a leaveNotifyEvent when activating
// the toolbar. so check if we are still inside the toolbar area.
// event.subwindow gets != None if we really left the window (eg the Slit
// was entered ontop of the toolbar)
2003-12-20 19:05:42 +00:00
if (event.x_root > x() && event.x_root <= (int)(x() + width()) &&
event.y_root > y() && event.y_root <= (int)(y() + height()) &&
event.subwindow == None ) {
2003-12-20 19:05:42 +00:00
return;
}
2001-12-11 20:47:02 +00:00
Fluxbox::instance()->keys()->doAction(event.type, event.state, 0,
Keys::ON_TOOLBAR);
2008-01-22 09:34:02 +00:00
if (! doAutoHide())
return;
if (isHidden()) {
2005-02-07 13:45:31 +00:00
if (m_hide_timer.isTiming())
2003-05-10 13:57:07 +00:00
m_hide_timer.stop();
2005-02-07 13:45:31 +00:00
} else if (! menu().isVisible() && ! m_hide_timer.isTiming())
2003-05-10 13:57:07 +00:00
m_hide_timer.start();
2002-11-27 12:20:23 +00:00
2001-12-11 20:47:02 +00:00
}
void Toolbar::exposeEvent(XExposeEvent &ee) {
2003-12-20 19:05:42 +00:00
if (ee.window == frame.window) {
2003-08-28 13:58:18 +00:00
frame.window.clearArea(ee.x, ee.y,
ee.width, ee.height);
2003-12-20 19:05:42 +00:00
}
2001-12-11 20:47:02 +00:00
}
void Toolbar::handleEvent(XEvent &event) {
/* Commented out by Simon 16jun04, since it causes LOTS of rearrangeItems
2004-08-25 17:16:40 +00:00
particularly on startup. This was needed to resize when tool changes its own
size, but it has too many side effects. Use the resizeSig in ToolbarItem instead.
2003-08-28 13:58:18 +00:00
if (event.type == ConfigureNotify &&
event.xconfigure.window != window().window()) {
rearrangeItems();
}
2005-02-07 13:45:31 +00:00
*/
}
2001-12-11 20:47:02 +00:00
void Toolbar::setPlacement(Toolbar::Placement where) {
2003-08-15 15:29:10 +00:00
// disable vertical toolbar
*m_rc_placement = where;
2015-01-23 22:38:34 +00:00
int head_x = 0;
int head_y = 0;
int head_w = screen().width();
int head_h = screen().height();
if (screen().hasXinerama()) {
int head = *m_rc_on_head;
head_x = screen().getHeadX(head);
head_y = screen().getHeadY(head);
head_w = screen().getHeadWidth(head);
head_h = screen().getHeadHeight(head);
}
2015-01-23 22:38:34 +00:00
int bw = theme()->border().width();
int pixel = (bw == 0 ? 1 : 0); // So we get at least one pixel visible in hidden mode
frame.width = (head_w - 2*bw) * (*m_rc_width_percent) / 100;
2005-02-07 13:45:31 +00:00
//!! TODO: change this
// max height of each toolbar items font...
unsigned int max_height = m_tool_factory.maxFontHeight() + 2;
2008-01-05 01:39:19 +00:00
if (theme()->height() > 0)
max_height = theme()->height();
2003-08-27 19:56:56 +00:00
if (*m_rc_height > 0 && *m_rc_height < 100)
max_height = *m_rc_height;
frame.height = max_height;
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 * (*m_rc_width_percent) / 100;
2002-12-03 17:02:53 +00:00
} // else horizontal toolbar
2002-12-03 17:02:53 +00:00
2015-01-23 22:38:34 +00:00
frame.x = head_x;
frame.y = head_y;
frame.x_hidden = head_x;
frame.y_hidden = head_y;
FbTk::Orientation orient = _values[where].orient;
if (m_shape.get())
m_shape->setPlaces(_values[where].shape);
switch (where) {
case TOPLEFT:
2015-01-23 22:38:34 +00:00
frame.y_hidden += pixel - bw - frame.height;
break;
case BOTTOMLEFT:
2015-01-23 22:38:34 +00:00
frame.y += head_h - static_cast<int>(frame.height) - 2*bw;
frame.y_hidden += head_h - bw - pixel;
break;
case TOPCENTER:
2015-01-23 22:38:34 +00:00
frame.x += (head_w - static_cast<int>(frame.width))/2 - bw;
2015-05-03 16:18:40 +00:00
frame.x_hidden = frame.x;
2015-01-23 22:38:34 +00:00
frame.y_hidden += pixel - bw - static_cast<int>(frame.height);
break;
case TOPRIGHT:
2015-01-23 22:38:34 +00:00
frame.x += head_w - static_cast<int>(frame.width) - bw*2;
2015-05-03 16:18:40 +00:00
frame.x_hidden = frame.x;
2015-01-23 22:38:34 +00:00
frame.y_hidden += pixel - bw - static_cast<int>(frame.height);
break;
case BOTTOMRIGHT:
2015-01-23 22:38:34 +00:00
frame.x += head_w - static_cast<int>(frame.width) - bw*2;
frame.y += head_h - static_cast<int>(frame.height) - bw*2;
2015-05-03 16:18:40 +00:00
frame.x_hidden = frame.x;
2015-01-23 22:38:34 +00:00
frame.y_hidden += head_h - bw - pixel;
break;
case BOTTOMCENTER: // default is BOTTOMCENTER
2015-01-23 22:38:34 +00:00
frame.x += (head_w - static_cast<int>(frame.width))/2 - bw;
frame.y += head_h - static_cast<int>(frame.height) - bw*2;
2015-05-03 16:18:40 +00:00
frame.x_hidden = frame.x;
2015-01-23 22:38:34 +00:00
frame.y_hidden += head_h - bw - pixel;
break;
2002-12-03 17:02:53 +00:00
case LEFTCENTER:
2015-01-23 22:38:34 +00:00
frame.y += (head_h - static_cast<int>(frame.height))/2 - bw;
2015-05-03 16:18:40 +00:00
frame.y_hidden = frame.y;
2015-01-23 22:38:34 +00:00
frame.x_hidden += pixel - static_cast<int>(frame.width) - bw;
2002-12-04 17:58:01 +00:00
break;
case LEFTTOP:
2015-01-23 22:38:34 +00:00
frame.x_hidden += pixel - static_cast<int>(frame.width) - bw;
2002-12-04 17:58:01 +00:00
break;
case LEFTBOTTOM:
2015-01-23 22:38:34 +00:00
frame.y = head_h - static_cast<int>(frame.height) - bw*2;
2015-05-03 16:18:40 +00:00
frame.y_hidden = frame.y;
2015-01-23 22:38:34 +00:00
frame.x_hidden += pixel - static_cast<int>(frame.width) - bw;
2002-12-04 17:58:01 +00:00
break;
case RIGHTCENTER:
2015-01-23 22:38:34 +00:00
frame.x += head_w - static_cast<int>(frame.width) - bw*2;
frame.y += (head_h - static_cast<int>(frame.height))/2 - bw;
2015-05-03 16:18:40 +00:00
frame.x_hidden += head_w - bw - pixel;
frame.y_hidden = frame.y;
2002-12-04 17:58:01 +00:00
break;
case RIGHTTOP:
2015-01-23 22:38:34 +00:00
frame.x += head_w - static_cast<int>(frame.width) - bw*2;
2015-05-03 16:18:40 +00:00
frame.x_hidden += head_w - bw - pixel;
2002-12-04 17:58:01 +00:00
break;
case RIGHTBOTTOM:
2015-01-23 22:38:34 +00:00
frame.x += head_w - static_cast<int>(frame.width) - bw*2;
frame.y += head_h - static_cast<int>(frame.height) - bw*2;
2015-05-03 16:18:40 +00:00
frame.x_hidden += head_w - bw - pixel;
frame.y_hidden = frame.y;
2002-12-03 17:02:53 +00:00
break;
}
forAll(m_item_list, std::bind2nd(std::mem_fun(&ToolbarItem::setOrientation), orient));
}
2002-12-03 17:02:53 +00:00
2003-12-08 17:29:44 +00:00
void Toolbar::updateVisibleState() {
*m_rc_visible ? frame.window.show() : frame.window.hide();
}
2003-08-11 15:56:10 +00:00
void Toolbar::toggleHidden() {
2003-12-20 19:05:42 +00:00
// toggle hidden
2003-08-11 15:56:10 +00:00
m_hidden = ! m_hidden;
if (isHidden())
frame.window.move(frame.x_hidden, frame.y_hidden);
else {
2003-08-11 15:56:10 +00:00
frame.window.move(frame.x, frame.y);
forAll(m_item_list, std::mem_fun(&ToolbarItem::parentMoved));
}
2003-08-11 15:56:10 +00:00
2001-12-11 20:47:02 +00:00
}
void Toolbar::moveToLayer(int layernum) {
2005-02-07 13:45:31 +00:00
m_layeritem.moveToLayer(layernum);
*m_rc_layernum = layernum;
}
void Toolbar::setupMenus(bool skip_new_placement) {
2004-06-07 11:46:05 +00:00
_FB_USES_NLS;
using namespace FbTk;
typedef RefCount<Command<void> > RefCommand;
2003-12-08 17:29:44 +00:00
typedef SimpleCommand<Toolbar> ToolbarCommand;
menu().setLabel(_FB_XTEXT(Toolbar, Toolbar,
"Toolbar", "Title of Toolbar menu"));
2003-12-08 17:29:44 +00:00
RefCommand reconfig_toolbar(new ToolbarCommand(*this, &Toolbar::reconfigure));
RefCommand save_resources(FbTk::CommandParser<void>::instance().parse("saverc"));
2003-12-08 17:29:44 +00:00
MacroCommand *toolbar_menuitem_macro = new MacroCommand();
toolbar_menuitem_macro->add(reconfig_toolbar);
toolbar_menuitem_macro->add(save_resources);
2003-12-08 17:29:44 +00:00
RefCommand reconfig_toolbar_and_save_resource(toolbar_menuitem_macro);
2003-12-08 17:29:44 +00:00
MacroCommand *visible_macro = new MacroCommand();
RefCommand toggle_visible(new ToolbarCommand(*this, &Toolbar::updateVisibleState));
visible_macro->add(toggle_visible);
visible_macro->add(reconfig_toolbar);
2003-12-08 17:29:44 +00:00
visible_macro->add(save_resources);
RefCommand toggle_visible_cmd(visible_macro);
menu().insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Common, Visible,
"Visible", "Whether this item is visible"),
2007-12-27 21:55:24 +00:00
m_rc_visible, toggle_visible_cmd));
menu().insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Common, AutoHide,
"Auto hide", "Toggle auto hide of toolbar"),
2007-12-27 21:55:24 +00:00
m_rc_auto_hide,
reconfig_toolbar_and_save_resource));
2006-10-30 19:31:15 +00:00
MenuItem *toolbar_menuitem =
2007-12-27 21:55:24 +00:00
new FbTk::IntMenuItem(_FB_XTEXT(Toolbar, WidthPercent,
2006-10-30 19:31:15 +00:00
"Toolbar width percent",
"Percentage of screen width taken by toolbar"),
m_rc_width_percent,
0, 100, menu()); // min/max value
2006-02-27 21:43:01 +00:00
toolbar_menuitem->setCommand(reconfig_toolbar_and_save_resource);
menu().insertItem(toolbar_menuitem);
menu().insertItem(new FbTk::BoolMenuItem(_FB_XTEXT(Common, MaximizeOver,
2006-10-30 19:31:15 +00:00
"Maximize Over",
"Maximize over this thing when maximizing"),
2007-12-27 21:55:24 +00:00
m_rc_maximize_over,
2003-12-08 17:29:44 +00:00
reconfig_toolbar_and_save_resource));
menu().insertSubmenu(_FB_XTEXT(Menu, Layer, "Layer...", "Title of Layer menu"), &layerMenu());
2006-02-27 21:43:01 +00:00
#ifdef XINERAMA
2003-12-08 17:29:44 +00:00
if (screen().hasXinerama()) {
m_xineramaheadmenu = new XineramaHeadMenu<Toolbar>(screen().menuTheme(),
screen(),
screen().imageControl(),
*screen().layerManager().getLayer(::ResourceLayer::MENU),
*this,
_FB_XTEXT(Toolbar, OnHead, "Toolbar on Head", "Title of toolbar on head menu"));
menu().insertSubmenu(_FB_XTEXT(Menu, OnHead, "On Head...", "Title of On Head menu"), m_xineramaheadmenu);
}
2006-02-27 21:43:01 +00:00
#endif // XINERAMA
2005-02-07 13:45:31 +00:00
2004-06-07 11:46:05 +00:00
// menu is 3 wide, 5 down
if (!skip_new_placement) {
2015-01-23 22:38:34 +00:00
static const struct {
const FbTk::FbString label;
Toolbar::Placement placement;
2015-01-23 22:38:34 +00:00
} pm[] = {
{ _FB_XTEXT(Align, TopLeft, "Top Left", "Top Left"), Toolbar::TOPLEFT},
{ _FB_XTEXT(Align, LeftTop, "Left Top", "Left Top"), Toolbar::LEFTTOP},
{ _FB_XTEXT(Align, LeftCenter, "Left Center", "Left Center"), Toolbar::LEFTCENTER},
{ _FB_XTEXT(Align, LeftBottom, "Left Bottom", "Left Bottom"), Toolbar::LEFTBOTTOM},
{ _FB_XTEXT(Align, BottomLeft, "Bottom Left", "Bottom Left"), Toolbar::BOTTOMLEFT},
{ _FB_XTEXT(Align, TopCenter, "Top Center", "Top Center"), Toolbar::TOPCENTER},
{ "", Toolbar::TOPLEFT},
{ "", Toolbar::TOPLEFT},
{ "", Toolbar::TOPLEFT},
{ _FB_XTEXT(Align, BottomCenter, "Bottom Center", "Bottom Center"), Toolbar::BOTTOMCENTER},
{ _FB_XTEXT(Align, TopRight, "Top Right", "Top Right"), Toolbar::TOPRIGHT},
{ _FB_XTEXT(Align, RightTop, "Right Top", "Right Top"), Toolbar::RIGHTTOP},
{ _FB_XTEXT(Align, RightCenter, "Right Center", "Right Center"), Toolbar::RIGHTCENTER},
{ _FB_XTEXT(Align, RightBottom, "Right Bottom", "Right Bottom"), Toolbar::RIGHTBOTTOM},
{ _FB_XTEXT(Align, BottomRight, "Bottom Right", "Bottom Right"), Toolbar::BOTTOMRIGHT}
};
placementMenu().setMinimumColumns(3);
// create items in sub menu
2015-01-23 22:38:34 +00:00
for (size_t i=0; i< sizeof(pm)/sizeof(pm[0]); ++i) {
if (pm[i].label == "") {
placementMenu().insert(pm[i].label);
placementMenu().setItemEnabled(i, false);
} else
2015-01-23 22:38:34 +00:00
placementMenu().insertItem(new PlaceToolbarMenuItem(pm[i].label, *this,
pm[i].placement));
}
}
menu().insertSubmenu(_FB_XTEXT(Menu, Placement, "Placement", "Title of Placement menu"), &placementMenu());
placementMenu().updateMenu();
2006-10-30 19:31:15 +00:00
// this saves resources and clears the slit window to update alpha value
2005-02-07 13:45:31 +00:00
FbTk::MenuItem *alpha_menuitem =
2007-12-27 21:55:24 +00:00
new FbTk::IntMenuItem(_FB_XTEXT(Common, Alpha, "Alpha", "Transparency level"),
m_rc_alpha,
2005-05-03 13:53:25 +00:00
0, 255, menu());
// setup command for alpha value
2005-02-07 13:45:31 +00:00
MacroCommand *alpha_macrocmd = new MacroCommand();
RefCount<Command<void> > alpha_cmd(new SimpleCommand<Toolbar>(*this, &Toolbar::updateAlpha));
alpha_macrocmd->add(save_resources);
alpha_macrocmd->add(alpha_cmd);
RefCount<Command<void> > set_alpha_cmd(alpha_macrocmd);
alpha_menuitem->setCommand(set_alpha_cmd);
menu().insertItem(alpha_menuitem);
menu().updateMenu();
}
void Toolbar::saveOnHead(int head) {
m_rc_on_head = head;
reconfigure();
}
2004-08-25 17:16:40 +00:00
/*
2005-02-07 13:45:31 +00:00
* Place items next to each other, with a bevel width between,
2004-08-25 17:16:40 +00:00
* above and below each item. BUT, if there is no bevel width, then
* borders should be merged for evenness.
*/
void Toolbar::rearrangeItems() {
2003-08-28 13:58:18 +00:00
if (m_resize_lock || screen().isShuttingdown() ||
m_item_list.empty())
return;
2004-08-25 17:16:40 +00:00
2015-01-23 22:38:34 +00:00
FbTk::Orientation orient = _values[placement()].orient;
// lock this
m_resize_lock = true;
// calculate size for fixed items
ItemList::iterator item_it = m_item_list.begin();
ItemList::iterator item_it_end = m_item_list.end();
2008-01-05 01:39:19 +00:00
int bevel_width = theme()->bevelWidth();
2004-08-25 17:16:40 +00:00
int fixed_width = bevel_width; // combined size of all fixed items
int relative_items = 0;
2004-04-26 15:04:37 +00:00
int last_bw = 0; // we show the largest border of adjoining items
bool first = true;
unsigned int width = this->width(), height = this->height();
unsigned int tmpw, tmph;
FbTk::translateSize(orient, width, height);
for (; item_it != item_it_end; ++item_it) {
2004-04-26 15:04:37 +00:00
if (!(*item_it)->active())
continue;
2004-08-25 17:16:40 +00:00
int borderW = (*item_it)->borderWidth();
if (bevel_width > 0) {
// the bevel and border are fixed whether relative or not
fixed_width += bevel_width + 2*borderW;
} else {
if (!first) {
2013-02-27 08:50:29 +00:00
fixed_width += std::max(borderW, last_bw);
2004-08-25 17:16:40 +00:00
} else {
2004-04-26 15:04:37 +00:00
first = false;
2004-08-25 17:16:40 +00:00
}
}
2004-04-26 15:04:37 +00:00
2004-08-25 17:16:40 +00:00
last_bw = borderW;
2004-04-26 15:04:37 +00:00
tmpw = (*item_it)->width();
tmph = (*item_it)->height();
FbTk::translateSize(orient, tmpw, tmph);
2004-06-10 17:07:58 +00:00
if ((*item_it)->type() == ToolbarItem::FIXED) {
fixed_width += tmpw;
2004-08-25 17:16:40 +00:00
} else if ((*item_it)->type() == ToolbarItem::SQUARE) {
fixed_width += height;
if (bevel_width)
fixed_width -= 2*(borderW + bevel_width);
2004-08-25 17:16:40 +00:00
} else {
relative_items++;
}
}
// calculate what's going to be left over to the relative sized items
int relative_width = 0;
int rounding_error = 0;
if (relative_items == 0)
relative_width = 0;
else { // size left after fixed items / number of relative items
relative_width = (width - fixed_width) / relative_items;
rounding_error = width - fixed_width - relative_items * relative_width;
}
2004-08-25 17:16:40 +00:00
// now move and resize the items
2004-04-26 15:04:37 +00:00
// borderWidth added back on straight away
int next_x = -m_item_list.front()->borderWidth(); // list isn't empty
2004-08-25 17:16:40 +00:00
if (bevel_width != 0)
next_x = 0;
2004-04-26 15:04:37 +00:00
last_bw = 0;
for (item_it = m_item_list.begin(); item_it != item_it_end; ++item_it) {
2004-08-25 17:16:40 +00:00
int borderW = (*item_it)->borderWidth();
if (!(*item_it)->active()) {
(*item_it)->hide();
2004-06-20 10:29:51 +00:00
// make sure it still gets told the toolbar height
tmpw = 1; tmph = height - 2*(bevel_width+borderW);
if (tmph >= (1<<30)) tmph = 1;
FbTk::translateSize(orient, tmpw, tmph);
(*item_it)->resize(tmpw, tmph); // width of 0 changes to 1 anyway
continue;
}
2004-08-25 17:16:40 +00:00
int offset = bevel_width;
int size_offset = 2*(borderW + bevel_width);
if (bevel_width == 0) {
offset = -borderW;
size_offset = 0;
2013-02-27 08:50:29 +00:00
next_x += std::max(borderW, last_bw);
2004-08-25 17:16:40 +00:00
}
2004-04-26 15:04:37 +00:00
last_bw = borderW;
int tmpx = next_x + offset,
tmpy = offset;
if ((*item_it)->type() == ToolbarItem::RELATIVE) {
int extra = 0;
if (rounding_error != 0) { // distribute rounding error over all relatives
extra = 1;
--rounding_error;
}
tmpw = extra + relative_width;
tmph = height - size_offset;
2004-08-25 17:16:40 +00:00
} else if ((*item_it)->type() == ToolbarItem::SQUARE) {
tmpw = tmph = height - size_offset;
} else { // fixed size
unsigned int itemw = (*item_it)->width(), itemh = (*item_it)->height();
FbTk::translateSize(orient, itemw, itemh);
tmpw = itemw;
tmph = height - size_offset;
}
if (tmpw >= (1<<30)) tmpw = 1;
if (tmph >= (1<<30)) tmph = 1;
next_x += tmpw + bevel_width;
2004-08-25 17:16:40 +00:00
if (bevel_width != 0)
next_x += 2*borderW;
FbTk::translateCoords(orient, tmpx, tmpy, width, height);
FbTk::translatePosition(orient, tmpx, tmpy, tmpw, tmph, borderW);
FbTk::translateSize(orient, tmpw, tmph);
(*item_it)->moveResize(tmpx, tmpy, tmpw, tmph);
(*item_it)->show();
}
// unlock
m_resize_lock = false;
frame.window.clear();
}
2003-08-28 13:58:18 +00:00
void Toolbar::deleteItems() {
while (!m_item_list.empty()) {
delete m_item_list.back();
m_item_list.pop_back();
}
m_tools.clear();
}
void Toolbar::updateAlpha() {
// called when the alpha resource is changed
if (FbTk::Transparent::haveComposite()) {
frame.window.setOpaque(*m_rc_alpha);
} else {
frame.window.setAlpha(*m_rc_alpha);
2006-04-17 14:32:20 +00:00
frame.window.updateBackground(false);
frame.window.clear();
ItemList::iterator item_it = m_item_list.begin();
ItemList::iterator item_it_end = m_item_list.end();
for (item_it = m_item_list.begin(); item_it != item_it_end; ++item_it) {
(*item_it)->renderTheme(alpha());
}
}
}