fluxbox/src/IconbarTool.cc

924 lines
30 KiB
C++
Raw Normal View History

2003-08-11 15:42:29 +00:00
// IconbarTool.cc
2004-06-27 13:45:20 +00:00
// Copyright (c) 2003-2004 Henrik Kinnunen (fluxgen at users.sourceforge.net)
2003-08-11 15:42:29 +00:00
// and Simon Bowden (rathnor at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
2004-11-19 11:37:27 +00:00
// $Id$
2003-08-11 15:42:29 +00:00
#include "IconbarTool.hh"
#include "Screen.hh"
#include "IconbarTheme.hh"
#include "Window.hh"
#include "IconButton.hh"
#include "Workspace.hh"
2003-09-08 17:52:34 +00:00
#include "fluxbox.hh"
#include "FbMenu.hh"
2003-11-27 14:30:11 +00:00
#include "BoolMenuItem.hh"
#include "CommandParser.hh"
#include "WinClient.hh"
2003-09-08 17:52:34 +00:00
2004-06-07 11:46:05 +00:00
#include "FbTk/I18n.hh"
2003-09-08 17:52:34 +00:00
#include "FbTk/Menu.hh"
#include "FbTk/MenuItem.hh"
#include "FbTk/RefCount.hh"
#include "FbTk/SimpleCommand.hh"
#include "FbTk/ImageControl.hh"
2003-11-27 14:30:11 +00:00
#include "FbTk/MacroCommand.hh"
2004-06-07 21:43:02 +00:00
#include "FbTk/MenuSeparator.hh"
2003-08-11 15:42:29 +00:00
#include <typeinfo>
2003-09-08 17:52:34 +00:00
#include <string>
#include <iterator>
using namespace std;
template<>
void FbTk::Resource<IconbarTool::Mode>::setFromString(const char *strval) {
if (strcasecmp(strval, "None") == 0)
m_value = IconbarTool::NONE;
else if (strcasecmp(strval, "Icons") == 0)
m_value = IconbarTool::ICONS;
else if (strcasecmp(strval, "WorkspaceIcons") == 0)
m_value = IconbarTool::WORKSPACEICONS;
else if (strcasecmp(strval, "Workspace") == 0)
m_value = IconbarTool::WORKSPACE;
else if (strcasecmp(strval, "AllWindows") == 0)
m_value = IconbarTool::ALLWINDOWS;
else
setDefaultValue();
}
template<>
void FbTk::Resource<IconbarTool::DeiconifyMode>::setDefaultValue() {
m_value = IconbarTool::FOLLOW;
}
template<>
void FbTk::Resource<IconbarTool::DeiconifyMode>::setFromString(const char* strval) {
if (strncasecmp(strval, "Current", strlen("Current")) == 0)
m_value = IconbarTool::CURRENT;
else if (strncasecmp(strval, "Follow", strlen("Follow")) == 0)
m_value = IconbarTool::FOLLOW;
else if (strncasecmp(strval, "SemiFollow", strlen("SemiFollow")) == 0)
m_value = IconbarTool::SEMIFOLLOW;
else
setDefaultValue();
}
template<>
std::string FbTk::Resource<IconbarTool::DeiconifyMode>::getString() {
switch (m_value) {
case IconbarTool::SEMIFOLLOW:
return std::string("SemiFollow");
break;
case IconbarTool::CURRENT:
return std::string("Current");
break;
};
return std::string("Follow");
}
template<>
void FbTk::Resource<IconbarTool::WheelMode>::setDefaultValue() {
m_value = IconbarTool::SCREEN;
}
template<>
void FbTk::Resource<IconbarTool::WheelMode>::setFromString(const char* strval) {
if (strncasecmp(strval, "off", strlen("off")) == 0)
m_value = IconbarTool::OFF;
else if (strncasecmp(strval, "on", strlen("on")) == 0)
m_value = IconbarTool::ON;
else if (strncasecmp(strval, "screen", strlen("screen")) == 0)
m_value = IconbarTool::SCREEN;
else
setDefaultValue();
}
template<>
std::string FbTk::Resource<IconbarTool::WheelMode>::getString() {
switch(m_value) {
case IconbarTool::ON:
return std::string("On");
break;
case IconbarTool::SCREEN:
return std::string("Screen");
break;
};
return std::string("Off");
}
2003-12-12 14:36:22 +00:00
template<>
void FbTk::Resource<Container::Alignment>::setDefaultValue() {
m_value = Container::RELATIVE;
}
template<>
string FbTk::Resource<Container::Alignment>::getString() {
switch (m_value) {
case Container::LEFT:
return string("Left");
case Container::RIGHT:
return string("Right");
case Container::RELATIVE:
return string("Relative");
}
return string("Left");
}
template<>
void FbTk::Resource<Container::Alignment>::setFromString(const char *str) {
if (strcasecmp(str, "Left") == 0)
m_value = Container::LEFT;
else if (strcasecmp(str, "Right") == 0)
m_value = Container::RIGHT;
2004-06-07 11:46:05 +00:00
else if (strcasecmp(str, "Relative") == 0)
2003-12-12 14:36:22 +00:00
m_value = Container::RELATIVE;
else
setDefaultValue();
}
2003-09-08 17:52:34 +00:00
template<>
string FbTk::Resource<IconbarTool::Mode>::getString() {
switch (m_value) {
case IconbarTool::NONE:
return string("None");
break;
case IconbarTool::ICONS:
return string("Icons");
break;
case IconbarTool::WORKSPACEICONS:
return string("WorkspaceIcons");
break;
case IconbarTool::WORKSPACE:
return string("Workspace");
break;
case IconbarTool::ALLWINDOWS:
return string("AllWindows");
break;
}
// default string
return string("Icons");
}
namespace {
class ToolbarModeMenuItem : public FbTk::MenuItem {
public:
ToolbarModeMenuItem(const char *label, IconbarTool &handler,
IconbarTool::Mode mode,
FbTk::RefCount<FbTk::Command> &cmd):
FbTk::MenuItem(label, cmd), m_handler(handler), m_mode(mode) {
}
bool isEnabled() const { return m_handler.mode() != m_mode; }
void click(int button, int time) {
m_handler.setMode(m_mode);
FbTk::MenuItem::click(button, time);
}
private:
IconbarTool &m_handler;
IconbarTool::Mode m_mode;
};
2003-12-12 14:36:22 +00:00
class ToolbarAlignMenuItem: public FbTk::MenuItem {
public:
ToolbarAlignMenuItem(const char *label, IconbarTool &handler,
Container::Alignment mode,
FbTk::RefCount<FbTk::Command> &cmd):
FbTk::MenuItem(label, cmd), m_handler(handler), m_mode(mode) {
}
bool isEnabled() const { return m_handler.alignment() != m_mode; }
void click(int button, int time) {
m_handler.setAlignment(m_mode);
FbTk::MenuItem::click(button, time);
}
private:
IconbarTool &m_handler;
Container::Alignment m_mode;
};
2003-09-08 17:52:34 +00:00
void setupModeMenu(FbTk::Menu &menu, IconbarTool &handler) {
using namespace FbTk;
2004-06-07 11:46:05 +00:00
_FB_USES_NLS;
2003-09-08 17:52:34 +00:00
2004-06-07 11:46:05 +00:00
menu.setLabel(_FBTEXT(Toolbar, IconbarMode, "Iconbar Mode", "Menu title - chooses which set of icons are shown in the iconbar"));
2003-09-08 17:52:34 +00:00
RefCount<Command> saverc_cmd(new SimpleCommand<Fluxbox>(
*Fluxbox::instance(),
&Fluxbox::save_rc));
2004-06-07 21:43:02 +00:00
menu.insert(new ToolbarModeMenuItem(_FBTEXT(Toolbar, IconbarModeNone,
"None", "No icons are shown in the iconbar"),
2004-06-07 11:46:05 +00:00
handler,
IconbarTool::NONE, saverc_cmd));
menu.insert(new ToolbarModeMenuItem(
2004-06-07 21:43:02 +00:00
_FBTEXT(Toolbar, IconbarModeIcons,
"Icons", "Iconified windows from all workspaces are shown"),
2004-06-07 11:46:05 +00:00
handler,
IconbarTool::ICONS, saverc_cmd));
menu.insert(new ToolbarModeMenuItem(
2004-06-07 21:43:02 +00:00
_FBTEXT(Toolbar, IconbarModeWorkspaceIcons,
"WorkspaceIcons", "Iconified windows from this workspace are shown"),
2004-06-07 11:46:05 +00:00
handler,
IconbarTool::WORKSPACEICONS, saverc_cmd));
menu.insert(new ToolbarModeMenuItem(
2004-06-07 21:43:02 +00:00
_FBTEXT(Toolbar, IconbarModeWorkspace,
"Workspace", "Normal and iconified windows from this workspace are shown"),
2004-06-07 11:46:05 +00:00
handler,
IconbarTool::WORKSPACE, saverc_cmd));
menu.insert(new ToolbarModeMenuItem(
_FBTEXT(Toolbar, IconbarModeAllWindows, "All Windows", "All windows are shown"),
handler,
IconbarTool::ALLWINDOWS, saverc_cmd));
2004-06-27 13:45:20 +00:00
menu.insert(new FbTk::MenuSeparator());
2004-06-07 11:46:05 +00:00
menu.insert(new ToolbarAlignMenuItem(
_FBTEXT(Align, Left, "Left", "Align to the left"),
handler,
Container::LEFT, saverc_cmd));
menu.insert(new ToolbarAlignMenuItem(
_FBTEXT(Align, Relative, "Relative", "Align relative to the width"),
handler,
Container::RELATIVE, saverc_cmd));
menu.insert(new ToolbarAlignMenuItem(
_FBTEXT(Align, Right, "Right", "Align to the right"),
handler,
Container::RIGHT, saverc_cmd));
2004-06-07 21:43:02 +00:00
menu.insert(new FbTk::MenuSeparator());
menu.updateMenu();
2003-09-08 17:52:34 +00:00
}
inline bool checkAddWindow(IconbarTool::Mode mode, const FluxboxWindow &win) {
2004-01-19 18:28:08 +00:00
bool ret_val = false;
2003-09-08 17:52:34 +00:00
// just add the icons that are on the this workspace
switch (mode) {
case IconbarTool::NONE:
break;
case IconbarTool::ICONS:
if (win.isIconic())
2004-01-19 18:28:08 +00:00
ret_val = true;
2003-09-08 17:52:34 +00:00
break;
case IconbarTool::WORKSPACEICONS:
if(win.workspaceNumber() == win.screen().currentWorkspaceID() &&
win.isIconic())
2004-01-19 18:28:08 +00:00
ret_val = true;
2003-09-08 17:52:34 +00:00
break;
case IconbarTool::WORKSPACE:
if (win.workspaceNumber() == win.screen().currentWorkspaceID())
2004-01-19 18:28:08 +00:00
ret_val = true;
2003-09-08 17:52:34 +00:00
break;
case IconbarTool::ALLWINDOWS:
2004-01-19 18:28:08 +00:00
ret_val = true;
2003-09-08 17:52:34 +00:00
break;
}
if (win.isIconHidden())
2004-01-19 18:28:08 +00:00
ret_val = false;
return ret_val;
2003-09-08 17:52:34 +00:00
}
void removeDuplicate(const IconbarTool::IconList &iconlist, std::list<FluxboxWindow *> &windowlist) {
IconbarTool::IconList::const_iterator win_it = iconlist.begin();
IconbarTool::IconList::const_iterator win_it_end = iconlist.end();
std::list<FluxboxWindow *>::iterator remove_it = windowlist.end();
for (; win_it != win_it_end; ++win_it)
remove_it = remove(windowlist.begin(), remove_it, &(*win_it)->win());
// remove already existing windows
windowlist.erase(remove_it, windowlist.end());
windowlist.unique();
2003-09-08 17:52:34 +00:00
}
}; // end anonymous namespace
2003-08-13 09:57:40 +00:00
2003-09-08 17:52:34 +00:00
IconbarTool::IconbarTool(const FbTk::FbWindow &parent, IconbarTheme &theme, BScreen &screen,
FbTk::Menu &menu):
2003-08-11 15:42:29 +00:00
ToolbarItem(ToolbarItem::RELATIVE),
m_screen(screen),
m_icon_container(parent),
m_theme(theme),
m_focused_pm(0),
m_unfocused_pm(0),
m_focused_err_pm(0),
m_unfocused_err_pm(0),
2003-09-08 17:52:34 +00:00
m_empty_pm(0),
m_rc_mode(screen.resourceManager(), WORKSPACE,
screen.name() + ".iconbar.mode", screen.altName() + ".Iconbar.Mode"),
m_deiconify_mode(screen.resourceManager(), FOLLOW,
screen.name() + ".iconbar.deiconifyMode",
screen.name() + ".iconbar.DeiconifyMode"),
m_wheel_mode(screen.resourceManager(), OFF,
screen.name() + ".iconbar.wheelMode",
screen.name() + ".iconbar.WheelMode"),
2003-12-12 14:36:22 +00:00
m_rc_alignment(screen.resourceManager(), Container::LEFT,
screen.name() + ".iconbar.alignment", screen.altName() + ".Iconbar.Alignment"),
m_rc_client_width(screen.resourceManager(), 70,
2004-08-30 13:42:13 +00:00
screen.name() + ".iconbar.iconWidth", screen.altName() + ".Iconbar.IconWidth"),
2004-10-10 16:11:25 +00:00
m_rc_client_padding(screen.resourceManager(), 10,
screen.name() + ".iconbar.iconTextPadding", screen.altName() + ".Iconbar.IconTextPadding"),
2003-11-27 14:30:11 +00:00
m_rc_use_pixmap(screen.resourceManager(), true,
screen.name() + ".iconbar.usePixmap", screen.altName() + ".Iconbar.UsePixmap"),
2003-12-18 18:03:23 +00:00
m_menu(screen.menuTheme(), screen.imageControl(),
*screen.layerManager().getLayer(Fluxbox::instance()->getMenuLayer())) {
2003-09-08 17:52:34 +00:00
2003-11-27 14:30:11 +00:00
// setup mode menu
2003-09-08 17:52:34 +00:00
setupModeMenu(m_menu, *this);
_FB_USES_NLS;
2003-11-27 14:30:11 +00:00
using namespace FbTk;
// setup use pixmap item to reconfig iconbar and save resource on click
MacroCommand *save_and_reconfig = new MacroCommand();
RefCount<Command> reconfig(new SimpleCommand<IconbarTool>(*this, &IconbarTool::renderTheme));
RefCount<Command> save(CommandParser::instance().parseLine("saverc"));
save_and_reconfig->add(reconfig);
save_and_reconfig->add(save);
RefCount<Command> s_and_reconfig(save_and_reconfig);
m_menu.insert(new BoolMenuItem(_FBTEXT(Toolbar, ShowIcons, "Show Pictures", "chooses if little icons are shown next to title in the iconbar") ,
*m_rc_use_pixmap, s_and_reconfig));
m_menu.updateMenu();
2003-12-03 00:16:56 +00:00
// must be internal menu, otherwise toolbar main menu tries to delete it.
m_menu.setInternalMenu();
2003-11-27 14:30:11 +00:00
// add iconbar menu to toolbar menu
2003-09-08 17:52:34 +00:00
menu.insert(m_menu.label().c_str(), &m_menu);
2003-08-11 15:42:29 +00:00
2003-08-12 11:09:46 +00:00
// setup signals
2003-08-11 15:42:29 +00:00
theme.reconfigSig().attach(this);
screen.clientListSig().attach(this);
2003-09-08 17:52:34 +00:00
screen.iconListSig().attach(this);
screen.currentWorkspaceSig().attach(this);
// setup focus timer
FbTk::RefCount<FbTk::Command> timer_cmd(new FbTk::SimpleCommand<IconbarTool>(*this, &IconbarTool::timedRender));
timeval to;
to.tv_sec = 0;
to.tv_usec = 1; // so it updates next event round
m_focus_timer.setCommand(timer_cmd);
m_focus_timer.setTimeout(to);
m_focus_timer.fireOnce(true);
2003-08-11 15:42:29 +00:00
}
IconbarTool::~IconbarTool() {
2003-08-12 12:16:28 +00:00
deleteIcons();
// remove cached images
if (m_focused_pm)
m_screen.imageControl().removeImage(m_focused_pm);
if (m_unfocused_pm)
m_screen.imageControl().removeImage(m_unfocused_pm);
if (m_focused_err_pm)
m_screen.imageControl().removeImage(m_focused_err_pm);
if (m_unfocused_err_pm)
m_screen.imageControl().removeImage(m_unfocused_err_pm);
if (m_empty_pm)
m_screen.imageControl().removeImage(m_empty_pm);
}
2003-08-11 15:42:29 +00:00
void IconbarTool::move(int x, int y) {
m_icon_container.move(x, y);
}
void IconbarTool::resize(unsigned int width, unsigned int height) {
m_icon_container.resize(width, height);
renderTheme();
}
void IconbarTool::moveResize(int x, int y,
unsigned int width, unsigned int height) {
m_icon_container.moveResize(x, y, width, height);
renderTheme();
}
void IconbarTool::show() {
m_icon_container.show();
}
void IconbarTool::hide() {
m_icon_container.hide();
}
2003-12-12 14:36:22 +00:00
void IconbarTool::setAlignment(Container::Alignment align) {
*m_rc_alignment = align;
update(0);
}
2003-09-08 17:52:34 +00:00
void IconbarTool::setMode(Mode mode) {
if (mode == *m_rc_mode)
return;
*m_rc_mode = mode;
// lock graphics update
m_icon_container.setUpdateLock(true);
deleteIcons();
// update mode
2003-09-10 11:17:53 +00:00
switch (mode) {
case NONE: // nothing
2003-09-08 17:52:34 +00:00
break;
2003-09-10 11:17:53 +00:00
case ICONS: // all icons from all workspaces
case WORKSPACEICONS: // all icons on current workspace
2003-09-08 17:52:34 +00:00
updateIcons();
break;
2003-09-10 11:17:53 +00:00
case WORKSPACE: // all windows and all icons on current workspace
2003-09-08 17:52:34 +00:00
updateWorkspace();
break;
2003-09-10 11:17:53 +00:00
case ALLWINDOWS: // all windows and all icons from all workspaces
2003-09-08 17:52:34 +00:00
updateAllWindows();
break;
};
// unlock graphics update
m_icon_container.setUpdateLock(false);
m_icon_container.update();
m_icon_container.showSubwindows();
renderTheme();
}
void IconbarTool::setDeiconifyMode(DeiconifyMode mode) {
if (mode == *m_deiconify_mode)
return;
*m_deiconify_mode = mode;
}
void IconbarTool::setWheelMode(WheelMode mode) {
if (mode == *m_wheel_mode)
return;
*m_wheel_mode = mode;
}
2003-08-11 15:42:29 +00:00
unsigned int IconbarTool::width() const {
return m_icon_container.width();
}
unsigned int IconbarTool::height() const {
return m_icon_container.height();
}
2003-08-13 09:57:40 +00:00
unsigned int IconbarTool::borderWidth() const {
return m_icon_container.borderWidth();
}
void IconbarTool::update(FbTk::Subject *subj) {
2003-08-12 12:16:28 +00:00
// ignore updates if we're shutting down
if (m_screen.isShuttingdown()) {
m_screen.clientListSig().detach(this);
m_screen.iconListSig().detach(this);
m_screen.currentWorkspaceSig().detach(this);
if (!m_icon_list.empty())
deleteIcons();
2003-08-12 12:16:28 +00:00
return;
}
2003-08-12 01:01:16 +00:00
2003-12-12 14:36:22 +00:00
m_icon_container.setAlignment(*m_rc_alignment);
// clamp to normal values
if (*m_rc_client_width < 1)
*m_rc_client_width = 10;
else if (*m_rc_client_width > 400)
*m_rc_client_width = 400;
m_icon_container.setMaxSizePerClient(*m_rc_client_width);
2003-09-08 17:52:34 +00:00
if (mode() == NONE) {
2003-09-15 20:19:36 +00:00
if (subj != 0 && typeid(*subj) == typeid(IconbarTheme))
2003-09-08 17:52:34 +00:00
renderTheme();
return;
}
// handle window signal
if (subj != 0 && typeid(*subj) == typeid(FluxboxWindow::WinSubject)) {
2003-08-12 01:01:16 +00:00
// we handle everything except die signal here
FluxboxWindow::WinSubject *winsubj = static_cast<FluxboxWindow::WinSubject *>(subj);
if (subj == &(winsubj->win().focusSig())) {
// start focus timer, so we can update without flicker
m_focus_timer.start();
2003-08-12 01:01:16 +00:00
return;
} else if (subj == &(winsubj->win().workspaceSig())) {
2003-09-08 17:52:34 +00:00
// we can ignore this signal if we're in ALLWINDOWS mode
if (mode() == ALLWINDOWS)
return;
// workspace changed for this window, and if it's not on current workspace we remove it
2003-09-08 17:52:34 +00:00
if (m_screen.currentWorkspaceID() != winsubj->win().workspaceNumber()) {
removeWindow(winsubj->win());
2003-09-08 17:52:34 +00:00
renderTheme();
}
return;
2003-09-08 17:52:34 +00:00
} else if (subj == &(winsubj->win().dieSig())) { // die sig
removeWindow(winsubj->win());
2003-09-08 17:52:34 +00:00
renderTheme();
2003-08-12 12:16:28 +00:00
return; // we don't need to update the entire list
2003-09-08 17:52:34 +00:00
} else if (subj == &(winsubj->win().stateSig())) {
2004-01-19 18:28:08 +00:00
if (!checkAddWindow(mode(), winsubj->win())) {
removeWindow(winsubj->win());
renderTheme();
2003-09-08 17:52:34 +00:00
}
2004-01-19 18:28:08 +00:00
2003-09-08 17:52:34 +00:00
return;
2003-12-07 17:51:02 +00:00
} else if (subj == &(winsubj->win().titleSig())) {
renderWindow(winsubj->win());
return;
2003-09-08 17:52:34 +00:00
} else {
// signal not handled
return;
2003-08-12 01:01:16 +00:00
}
}
bool remove_all = false; // if we should readd all windows
2003-09-08 17:52:34 +00:00
if (subj != 0 && typeid(*subj) == typeid(BScreen::ScreenSubject) && mode() != ALLWINDOWS) {
BScreen::ScreenSubject *screen_subj = static_cast<BScreen::ScreenSubject *>(subj);
2003-09-08 17:52:34 +00:00
// current workspace sig
if (&m_screen.currentWorkspaceSig() == screen_subj &&
mode() != ALLWINDOWS && mode() != ICONS) {
remove_all = true; // remove and readd all windows
2004-06-27 13:45:20 +00:00
}
}
2003-09-08 17:52:34 +00:00
// lock graphic update
m_icon_container.setUpdateLock(true);
2003-09-08 17:52:34 +00:00
if (remove_all)
deleteIcons();
2003-09-08 17:52:34 +00:00
// ok, we got some signal that we need to update our iconbar container
switch (mode()) {
case NONE:
return;
break;
case ICONS:
case WORKSPACEICONS:
updateIcons();
break;
case WORKSPACE:
updateWorkspace();
break;
case ALLWINDOWS:
updateAllWindows();
break;
}
2003-09-08 17:52:34 +00:00
// unlock container and update graphics
m_icon_container.setUpdateLock(false);
m_icon_container.update();
2003-10-09 16:48:09 +00:00
m_icon_container.showSubwindows();
// another renderTheme we hopefully shouldn't need? These renders
// should be done individually above
// renderTheme();
2003-08-11 15:42:29 +00:00
}
IconButton *IconbarTool::findButton(FluxboxWindow &win) {
2003-08-12 11:09:46 +00:00
IconList::iterator icon_it = m_icon_list.begin();
IconList::iterator icon_it_end = m_icon_list.end();
for (; icon_it != icon_it_end; ++icon_it) {
if (&(*icon_it)->win() == &win)
return *icon_it;
2003-08-12 11:09:46 +00:00
}
2003-08-12 12:16:28 +00:00
return 0;
}
2003-08-12 11:09:46 +00:00
void IconbarTool::renderWindow(FluxboxWindow &win) {
IconButton *button = findButton(win);
if (button == 0)
return;
renderButton(*button);
2003-08-12 11:09:46 +00:00
}
2004-08-29 08:33:13 +00:00
void IconbarTool::updateSizing() {
m_icon_container.setBorderWidth(m_theme.border().width());
IconList::iterator icon_it = m_icon_list.begin();
const IconList::iterator icon_it_end = m_icon_list.end();
for (; icon_it != icon_it_end; ++icon_it) {
if ((*icon_it)->win().isFocused())
(*icon_it)->setBorderWidth(m_theme.focusedBorder().width());
else // unfocused
(*icon_it)->setBorderWidth(m_theme.unfocusedBorder().width());
}
2004-08-29 08:33:13 +00:00
}
void IconbarTool::renderTheme(unsigned char alpha) {
m_alpha = alpha;
renderTheme();
}
2004-08-29 08:33:13 +00:00
void IconbarTool::renderTheme() {
// update button sizes before we get max width per client!
updateSizing();
2003-08-11 15:42:29 +00:00
Pixmap tmp = m_focused_pm;
Pixmap err_tmp = m_focused_err_pm;
unsigned int icon_width = m_icon_container.maxWidthPerClient();
2003-12-07 16:39:43 +00:00
if (!m_theme.focusedTexture().usePixmap()) {
m_focused_pm = 0;
m_focused_err_pm = 0;
2003-08-11 15:42:29 +00:00
} else {
m_focused_pm = m_screen.imageControl().renderImage(icon_width,
m_icon_container.height(),
m_theme.focusedTexture());
m_focused_err_pm = m_screen.imageControl().renderImage(icon_width+1,
m_icon_container.height(),
m_theme.focusedTexture());
2003-08-11 15:42:29 +00:00
}
if (tmp)
m_screen.imageControl().removeImage(tmp);
if (err_tmp)
m_screen.imageControl().removeImage(err_tmp);
2003-08-11 15:42:29 +00:00
tmp = m_unfocused_pm;
err_tmp = m_unfocused_err_pm;
2003-12-07 16:39:43 +00:00
if (!m_theme.unfocusedTexture().usePixmap()) {
m_unfocused_pm = 0;
m_unfocused_err_pm = 0;
2003-08-11 15:42:29 +00:00
} else {
m_unfocused_pm = m_screen.imageControl().renderImage(icon_width,
m_icon_container.height(),
m_theme.unfocusedTexture());
m_unfocused_err_pm = m_screen.imageControl().renderImage(icon_width+1,
m_icon_container.height(),
2003-08-11 15:42:29 +00:00
m_theme.unfocusedTexture());
}
if (tmp)
m_screen.imageControl().removeImage(tmp);
if (err_tmp)
m_screen.imageControl().removeImage(err_tmp);
2003-08-11 15:42:29 +00:00
// if we dont have any icons then we should render empty texture
tmp = m_empty_pm;
2003-12-07 16:39:43 +00:00
if (!m_theme.emptyTexture().usePixmap()) {
m_empty_pm = 0;
m_icon_container.setBackgroundColor(m_theme.emptyTexture().color());
} else {
2003-10-26 20:13:11 +00:00
m_empty_pm = m_screen.imageControl().renderImage(m_icon_container.width(),
m_icon_container.height(),
m_theme.emptyTexture());
m_icon_container.setBackgroundPixmap(m_empty_pm);
}
if (tmp)
2003-10-26 20:13:11 +00:00
m_screen.imageControl().removeImage(tmp);
2003-08-11 15:42:29 +00:00
// set to zero so its consistent and not ugly
2004-08-25 17:16:40 +00:00
m_icon_container.setBorderWidth(m_theme.border().width());
m_icon_container.setBorderColor(m_theme.border().color());
m_icon_container.setAlpha(m_alpha);
2003-08-13 09:57:40 +00:00
2003-08-11 15:42:29 +00:00
// update buttons
2004-08-29 08:33:13 +00:00
IconList::iterator icon_it = m_icon_list.begin();
const IconList::iterator icon_it_end = m_icon_list.end();
for (; icon_it != icon_it_end; ++icon_it) {
2003-08-12 12:16:28 +00:00
renderButton(*(*icon_it));
}
2003-08-12 12:16:28 +00:00
}
void IconbarTool::renderButton(IconButton &button, bool clear) {
2003-08-11 15:42:29 +00:00
2003-11-27 14:30:11 +00:00
button.setPixmap(*m_rc_use_pixmap);
button.setAlpha(m_alpha);
2003-11-27 14:30:11 +00:00
// The last button is always the regular width
2004-04-26 15:04:37 +00:00
bool wider_button = false;
if (!m_icon_container.empty())
wider_button = (button.width() != m_icon_container.back()->width());
2003-08-12 12:16:28 +00:00
if (button.win().isFocused()) { // focused texture
m_icon_container.setSelected(m_icon_container.find(&button));
2003-08-12 12:16:28 +00:00
button.setGC(m_theme.focusedText().textGC());
button.setFont(m_theme.focusedText().font());
button.setJustify(m_theme.focusedText().justify());
button.setBorderWidth(m_theme.focusedBorder().width());
button.setBorderColor(m_theme.focusedBorder().color());
2003-08-11 15:42:29 +00:00
if (!wider_button && m_focused_pm != 0)
2003-08-12 12:16:28 +00:00
button.setBackgroundPixmap(m_focused_pm);
else if (wider_button && m_focused_err_pm != 0)
button.setBackgroundPixmap(m_focused_err_pm);
2003-08-12 12:16:28 +00:00
else
button.setBackgroundColor(m_theme.focusedTexture().color());
2003-08-13 09:57:40 +00:00
2003-08-12 12:16:28 +00:00
} else { // unfocused
if (m_icon_container.selected() == &button)
m_icon_container.setSelected(-1);
2003-08-12 12:16:28 +00:00
button.setGC(m_theme.unfocusedText().textGC());
button.setFont(m_theme.unfocusedText().font());
button.setJustify(m_theme.unfocusedText().justify());
button.setBorderWidth(m_theme.unfocusedBorder().width());
button.setBorderColor(m_theme.unfocusedBorder().color());
2003-08-11 15:42:29 +00:00
if (!wider_button && m_unfocused_pm != 0)
2003-08-12 12:16:28 +00:00
button.setBackgroundPixmap(m_unfocused_pm);
else if (wider_button && m_unfocused_err_pm != 0)
button.setBackgroundPixmap(m_unfocused_err_pm);
2003-08-12 12:16:28 +00:00
else
button.setBackgroundColor(m_theme.unfocusedTexture().color());
}
2003-08-15 17:23:23 +00:00
if (clear)
button.clear(); // the clear also updates transparent
2003-08-12 12:16:28 +00:00
}
2003-08-11 15:42:29 +00:00
2003-08-12 12:16:28 +00:00
void IconbarTool::deleteIcons() {
m_icon_container.removeAll();
while (!m_icon_list.empty()) {
delete m_icon_list.back();
m_icon_list.pop_back();
2003-08-11 15:42:29 +00:00
}
}
void IconbarTool::removeWindow(FluxboxWindow &win) {
// got window die signal, lets find and remove the window
IconList::iterator it = m_icon_list.begin();
IconList::iterator it_end = m_icon_list.end();
for (; it != it_end; ++it) {
if (&(*it)->win() == &win)
break;
}
// did we find it?
if (it == m_icon_list.end()) {
return;
}
#ifdef DEBUG
cerr<<"IconbarTool::"<<__FUNCTION__<<"( 0x"<<&win<<" title = "<<win.title()<<") found!"<<endl;
#endif // DEBUG
2003-12-07 17:51:02 +00:00
// detach from all signals
2003-09-08 17:52:34 +00:00
win.focusSig().detach(this);
win.dieSig().detach(this);
win.workspaceSig().detach(this);
win.stateSig().detach(this);
2003-12-07 17:51:02 +00:00
win.titleSig().detach(this);
// remove from list and render theme again
2003-09-08 17:52:34 +00:00
IconButton *button = *it;
m_icon_container.removeItem(m_icon_container.find(*it));
2003-09-08 17:52:34 +00:00
m_icon_list.erase(it);
delete button;
}
void IconbarTool::addWindow(FluxboxWindow &win) {
// we just want windows that has clients
if (win.clientList().empty() || win.isIconHidden() )
2003-09-08 17:52:34 +00:00
return;
#ifdef DEBUG
cerr<<"IconbarTool::addWindow(0x"<<&win<<" title = "<<win.title()<<")"<<endl;
#endif // DEBUG
IconButton *button = new IconButton(*this,
m_icon_container,
m_theme.focusedText().font(),
win);
2004-10-10 16:11:25 +00:00
button->setTextPadding(*m_rc_client_padding);
renderButton(*button, false); // update the attributes, but don't clear it
2003-09-08 17:52:34 +00:00
m_icon_container.insertItem(button);
m_icon_list.push_back(button);
// dont forget to detach signal in removeWindow
win.focusSig().attach(this);
win.dieSig().attach(this);
win.workspaceSig().attach(this);
win.stateSig().attach(this);
2003-12-07 17:51:02 +00:00
win.titleSig().attach(this);
2003-09-08 17:52:34 +00:00
}
void IconbarTool::updateIcons() {
std::list<FluxboxWindow *> itemlist;
// add icons to the itemlist
BScreen::Icons::iterator icon_it = m_screen.getIconList().begin();
BScreen::Icons::iterator icon_it_end = m_screen.getIconList().end();
for (; icon_it != icon_it_end; ++icon_it) {
if (mode() == ICONS)
itemlist.push_back(*icon_it);
else if (mode() == WORKSPACEICONS && (*icon_it)->workspaceNumber() == m_screen.currentWorkspaceID())
itemlist.push_back(*icon_it);
}
removeDuplicate(m_icon_list, itemlist);
addList(itemlist);
}
2003-09-08 17:52:34 +00:00
void IconbarTool::updateWorkspace() {
std::list<FluxboxWindow *> itemlist;
2003-09-10 11:17:53 +00:00
// add current workspace windows
2003-09-08 17:52:34 +00:00
Workspace &space = *m_screen.currentWorkspace();
2003-09-10 11:17:53 +00:00
Workspace::Windows::iterator win_it = space.windowList().begin();
Workspace::Windows::iterator win_it_end = space.windowList().end();
for (; win_it != win_it_end; ++win_it) {
if (checkAddWindow(mode(), **win_it))
itemlist.push_back(*win_it);
2003-09-08 17:52:34 +00:00
}
2003-09-10 11:17:53 +00:00
// add icons from current workspace
BScreen::Icons::iterator icon_it = m_screen.getIconList().begin();
BScreen::Icons::iterator icon_it_end = m_screen.getIconList().end();
for (; icon_it != icon_it_end; ++icon_it) {
if ((*icon_it)->workspaceNumber() == m_screen.currentWorkspaceID())
itemlist.push_back(*icon_it);
}
2003-09-08 17:52:34 +00:00
removeDuplicate(m_icon_list, itemlist);
addList(itemlist);
}
void IconbarTool::updateAllWindows() {
std::list<FluxboxWindow *> full_list;
// for each workspace add clients to full list
BScreen::Workspaces::iterator workspace_it = m_screen.getWorkspacesList().begin();
BScreen::Workspaces::iterator workspace_it_end = m_screen.getWorkspacesList().end();
for (; workspace_it != workspace_it_end; ++workspace_it) {
full_list.insert(full_list.end(),
(*workspace_it)->windowList().begin(),
(*workspace_it)->windowList().end());
}
// add icons
full_list.insert(full_list.end(),
m_screen.getIconList().begin(),
m_screen.getIconList().end());
removeDuplicate(m_icon_list, full_list);
addList(full_list);
}
void IconbarTool::addList(std::list<FluxboxWindow *> &winlist) {
// ok, now we should have a list of icons that we need to add
std::list<FluxboxWindow *>::iterator it = winlist.begin();
std::list<FluxboxWindow *>::iterator it_end = winlist.end();
for (; it != it_end; ++it)
addWindow(**it);
renderTheme();
2003-09-08 17:52:34 +00:00
}
void IconbarTool::timedRender() {
WinClient *client = Fluxbox::instance()->getFocusedWindow();
if (client == 0 || client->fbwindow() == 0)
return;
IconButton *button = findButton(*client->fbwindow());
IconButton *current_button = static_cast<IconButton *>(m_icon_container.selected());
// if old window is the same as the new focused window then ignore this render
// else render old client and new client
if (button == current_button)
return;
if (button != 0)
renderButton(*button);
if (current_button != 0)
renderButton(*current_button);
}
2003-09-08 17:52:34 +00:00