fluxbox/src/IconButton.cc

204 lines
6.1 KiB
C++
Raw Normal View History

2003-08-11 15:45:50 +00:00
// IconButton.cc
// Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
// 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.
2003-11-27 14:30:11 +00:00
// $Id: IconButton.cc,v 1.13 2003/11/27 14:27:48 fluxgen Exp $
2003-08-11 15:45:50 +00:00
#include "IconButton.hh"
#include "FbTk/App.hh"
#include "FbTk/EventManager.hh"
2003-08-24 16:24:19 +00:00
#include "fluxbox.hh"
#include "Screen.hh"
2003-08-11 15:45:50 +00:00
#include "Window.hh"
#include "WinClient.hh"
#include "SimpleCommand.hh"
2003-08-11 15:45:50 +00:00
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif // HAVE_CONFIG_H
#include <X11/Xutil.h>
#ifdef SHAPE
#include <X11/extensions/shape.h>
#endif // SHAPE
2003-08-24 16:24:19 +00:00
namespace {
class ShowMenu: public FbTk::Command {
public:
explicit ShowMenu(FluxboxWindow &win):m_win(win) { }
void execute() {
// get last button pos
const XEvent &event = Fluxbox::instance()->lastEvent();
int x = event.xbutton.x_root - (m_win.menu().width() / 2);
int y = event.xbutton.y_root - (m_win.menu().height() / 2);
2003-11-19 12:57:27 +00:00
m_win.showMenu(x, y);
2003-08-24 16:24:19 +00:00
}
private:
FluxboxWindow &m_win;
};
} // end anonymous namespace
2003-08-11 15:45:50 +00:00
IconButton::IconButton(const FbTk::FbWindow &parent, const FbTk::Font &font,
FluxboxWindow &win):
2003-08-19 16:15:32 +00:00
FbTk::TextButton(parent, font, win.winClient().title()),
2003-08-11 15:45:50 +00:00
m_win(win),
2003-08-13 10:03:45 +00:00
m_icon_window(*this, 1, 1, 1, 1,
2003-11-27 14:30:11 +00:00
ExposureMask | ButtonPressMask | ButtonReleaseMask),
m_use_pixmap(true) {
2003-08-11 15:45:50 +00:00
FbTk::RefCount<FbTk::Command> focus(new FbTk::SimpleCommand<FluxboxWindow>(m_win, &FluxboxWindow::raiseAndFocus));
2003-08-24 16:24:19 +00:00
FbTk::RefCount<FbTk::Command> menu(new ::ShowMenu(m_win));
setOnClick(focus, 1);
setOnClick(menu, 3);
2003-08-11 15:45:50 +00:00
m_win.hintSig().attach(this);
2003-08-19 16:15:32 +00:00
2003-08-11 15:45:50 +00:00
FbTk::EventManager::instance()->add(*this, m_icon_window);
update(0);
}
IconButton::~IconButton() {
}
void IconButton::exposeEvent(XExposeEvent &event) {
if (m_icon_window == event.window)
m_icon_window.clear();
else
2003-09-10 21:41:18 +00:00
FbTk::TextButton::exposeEvent(event);
2003-08-11 15:45:50 +00:00
}
void IconButton::moveResize(int x, int y,
unsigned int width, unsigned int height) {
2003-09-10 21:41:18 +00:00
FbTk::TextButton::moveResize(x, y, width, height);
2003-08-11 15:45:50 +00:00
if (m_icon_window.width() != FbTk::Button::width() ||
m_icon_window.height() != FbTk::Button::height())
update(0); // update icon window
}
void IconButton::resize(unsigned int width, unsigned int height) {
2003-09-10 21:41:18 +00:00
FbTk::TextButton::resize(width, height);
2003-08-11 15:45:50 +00:00
if (m_icon_window.width() != FbTk::Button::width() ||
m_icon_window.height() != FbTk::Button::height())
update(0); // update icon window
}
void IconButton::clear() {
setupWindow();
}
2003-09-10 21:41:18 +00:00
void IconButton::clearArea(int x, int y,
unsigned int width, unsigned int height,
bool exposure) {
FbTk::TextButton::clearArea(x, y,
width, height, exposure);
}
2003-11-27 14:30:11 +00:00
void IconButton::setPixmap(bool use) {
if (m_use_pixmap != use) {
m_use_pixmap = use;
update(0);
}
}
2003-08-11 15:45:50 +00:00
void IconButton::update(FbTk::Subject *subj) {
// we got signal that either title or
// icon pixmap was updated,
// so we refresh everything
2003-08-12 01:19:22 +00:00
// we need to check our client first
if (m_win.clientList().size() == 0)
return;
2003-08-11 15:45:50 +00:00
XWMHints *hints = XGetWMHints(FbTk::App::instance()->display(), m_win.winClient().window());
if (hints == 0)
return;
2003-11-27 14:30:11 +00:00
if (m_use_pixmap && (hints->flags & IconPixmapHint) && hints->icon_pixmap != 0) {
2003-08-11 15:45:50 +00:00
// setup icon window
m_icon_window.show();
int new_height = height() - 2*m_icon_window.y(); // equally padded
int new_width = new_height;
m_icon_window.resize((new_width>0) ? new_width : 1, (new_height>0) ? new_height : 1);
2003-08-11 15:45:50 +00:00
m_icon_pixmap.copy(hints->icon_pixmap);
m_icon_pixmap.scale(m_icon_window.width(), m_icon_window.height());
2003-08-11 15:45:50 +00:00
m_icon_window.setBackgroundPixmap(m_icon_pixmap.drawable());
2003-08-11 15:45:50 +00:00
} else {
// no icon pixmap
2003-08-12 01:19:22 +00:00
m_icon_window.move(0, 0);
2003-08-11 15:45:50 +00:00
m_icon_window.hide();
m_icon_pixmap = 0;
}
2003-11-27 14:30:11 +00:00
if(m_use_pixmap && (hints->flags & IconMaskHint)) {
2003-08-11 15:45:50 +00:00
m_icon_mask.copy(hints->icon_mask);
m_icon_mask.scale(m_icon_pixmap.width(), m_icon_pixmap.height());
2003-08-11 15:45:50 +00:00
} else
m_icon_mask = 0;
XFree(hints);
hints = 0;
2003-08-11 15:45:50 +00:00
#ifdef SHAPE
if (m_icon_mask.drawable() != 0) {
2003-08-11 15:45:50 +00:00
XShapeCombineMask(FbTk::App::instance()->display(),
m_icon_window.drawable(),
ShapeBounding,
0, 0,
m_icon_mask.drawable(),
ShapeSet);
}
2003-08-11 15:45:50 +00:00
#endif // SHAPE
setupWindow();
}
void IconButton::setupWindow() {
2003-08-12 01:19:22 +00:00
m_icon_window.clear();
if (!m_win.clientList().empty()) {
setText(m_win.winClient().title());
// draw with x offset and y offset
}
FbTk::TextButton::clear();
2003-09-10 21:41:18 +00:00
}
void IconButton::drawText(int x, int y) {
// offset text
2003-11-27 14:30:11 +00:00
if (m_icon_pixmap.drawable() != 0)
FbTk::TextButton::drawText(m_icon_window.x() + m_icon_window.width() + 1, y);
else
FbTk::TextButton::drawText(1, y);
2003-08-11 15:45:50 +00:00
}
2003-09-10 21:41:18 +00:00
2003-08-11 15:45:50 +00:00