2003-08-11 15:45:50 +00:00
|
|
|
// IconButton.cc
|
2006-02-16 06:53:05 +00:00
|
|
|
// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
|
2003-08-11 15:45:50 +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.
|
|
|
|
|
|
|
|
#include "IconButton.hh"
|
2004-10-22 00:35:29 +00:00
|
|
|
#include "IconbarTool.hh"
|
2007-10-13 21:51:37 +00:00
|
|
|
#include "IconbarTheme.hh"
|
2003-08-11 15:45:50 +00:00
|
|
|
|
2003-08-24 16:24:19 +00:00
|
|
|
#include "Screen.hh"
|
2004-01-11 16:08:57 +00:00
|
|
|
|
|
|
|
#include "FbTk/App.hh"
|
2007-10-13 21:51:37 +00:00
|
|
|
#include "FbTk/Command.hh"
|
2004-01-11 16:08:57 +00:00
|
|
|
#include "FbTk/EventManager.hh"
|
2007-10-13 21:51:37 +00:00
|
|
|
#include "FbTk/ImageControl.hh"
|
2008-01-15 07:45:57 +00:00
|
|
|
#include "FbTk/TextUtils.hh"
|
2004-01-11 16:08:57 +00:00
|
|
|
#include "FbTk/MacroCommand.hh"
|
2004-05-02 20:46:19 +00:00
|
|
|
#include "FbTk/Menu.hh"
|
2007-10-13 21:51:37 +00:00
|
|
|
#include "FbTk/RefCount.hh"
|
|
|
|
#include "FbTk/SimpleCommand.hh"
|
2004-01-11 16:08:57 +00:00
|
|
|
|
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
|
|
|
|
2008-01-05 01:39:19 +00:00
|
|
|
IconButton::IconButton(const FbTk::FbWindow &parent,
|
2008-01-07 10:26:32 +00:00
|
|
|
FbTk::ThemeProxy<IconbarTheme> &focused_theme,
|
|
|
|
FbTk::ThemeProxy<IconbarTheme> &unfocused_theme, Focusable &win):
|
|
|
|
FbTk::TextButton(parent, focused_theme->text().font(), win.title()),
|
2007-12-30 15:32:53 +00:00
|
|
|
m_win(win),
|
|
|
|
m_icon_window(*this, 1, 1, 1, 1,
|
2008-05-05 12:05:52 +00:00
|
|
|
ExposureMask |EnterWindowMask | LeaveWindowMask |
|
|
|
|
ButtonPressMask | ButtonReleaseMask),
|
2007-10-13 21:51:37 +00:00
|
|
|
m_use_pixmap(true),
|
2008-05-09 17:39:02 +00:00
|
|
|
m_has_tooltip(false),
|
2008-01-07 10:26:32 +00:00
|
|
|
m_theme(win, focused_theme, unfocused_theme),
|
|
|
|
m_pm(win.screen().imageControl()) {
|
2004-10-22 00:35:29 +00:00
|
|
|
|
2006-04-17 23:34:01 +00:00
|
|
|
m_win.titleSig().attach(this);
|
2007-10-13 21:51:37 +00:00
|
|
|
m_win.focusSig().attach(this);
|
|
|
|
m_win.attentionSig().attach(this);
|
2007-12-30 15:32:53 +00:00
|
|
|
|
2003-08-11 15:45:50 +00:00
|
|
|
FbTk::EventManager::instance()->add(*this, m_icon_window);
|
2004-06-16 15:38:19 +00:00
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
reconfigTheme();
|
2003-08-11 15:45:50 +00:00
|
|
|
update(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
IconButton::~IconButton() {
|
2004-05-04 14:33:38 +00:00
|
|
|
// ~FbWindow cleans event manager
|
2008-09-03 13:53:30 +00:00
|
|
|
if (m_has_tooltip)
|
|
|
|
m_win.screen().hideTooltip();
|
2003-08-11 15:45:50 +00:00
|
|
|
}
|
|
|
|
|
2004-01-13 12:27:51 +00:00
|
|
|
|
2003-08-11 15:45:50 +00:00
|
|
|
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
|
|
|
}
|
2004-06-16 15:38:19 +00:00
|
|
|
|
2008-05-05 12:05:52 +00:00
|
|
|
void IconButton::enterNotifyEvent(XCrossingEvent &ev) {
|
2008-05-09 17:39:02 +00:00
|
|
|
m_has_tooltip = true;
|
|
|
|
showTooltip();
|
2008-05-05 12:05:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void IconButton::leaveNotifyEvent(XCrossingEvent &ev) {
|
2008-05-09 17:39:02 +00:00
|
|
|
m_has_tooltip = false;
|
2008-05-05 12:05:52 +00:00
|
|
|
m_win.screen().hideTooltip();
|
|
|
|
}
|
|
|
|
|
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() ||
|
2004-06-16 15:38:19 +00:00
|
|
|
m_icon_window.height() != FbTk::Button::height()) {
|
2009-06-28 16:39:28 +00:00
|
|
|
reconfigTheme();
|
2003-08-11 15:45:50 +00:00
|
|
|
update(0); // update icon window
|
2004-06-16 15:38:19 +00:00
|
|
|
}
|
2003-08-11 15:45:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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() ||
|
2004-06-16 15:38:19 +00:00
|
|
|
m_icon_window.height() != FbTk::Button::height()) {
|
2009-06-28 16:39:28 +00:00
|
|
|
reconfigTheme();
|
2003-08-11 15:45:50 +00:00
|
|
|
update(0); // update icon window
|
2004-06-16 15:38:19 +00:00
|
|
|
}
|
2003-08-11 15:45:50 +00:00
|
|
|
}
|
|
|
|
|
2008-05-09 17:39:02 +00:00
|
|
|
void IconButton::showTooltip() {
|
|
|
|
int xoffset = 1;
|
|
|
|
if (m_icon_pixmap.drawable() != 0)
|
|
|
|
xoffset = m_icon_window.x() + m_icon_window.width() + 1;
|
|
|
|
|
|
|
|
if (FbTk::TextButton::textExceeds(xoffset))
|
|
|
|
m_win.screen().showTooltip(m_win.title());
|
2008-10-07 21:32:42 +00:00
|
|
|
else
|
|
|
|
m_win.screen().hideTooltip();
|
2008-05-09 17:39:02 +00:00
|
|
|
}
|
|
|
|
|
2003-08-11 15:45:50 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
void IconButton::reconfigTheme() {
|
|
|
|
|
2008-01-07 10:26:32 +00:00
|
|
|
if (m_theme->texture().usePixmap())
|
|
|
|
m_pm.reset(m_win.screen().imageControl().renderImage(
|
|
|
|
width(), height(), m_theme->texture(),
|
|
|
|
orientation()));
|
2007-10-13 21:51:37 +00:00
|
|
|
else
|
2008-01-07 10:26:32 +00:00
|
|
|
m_pm.reset(0);
|
2007-10-13 21:51:37 +00:00
|
|
|
|
|
|
|
setAlpha(parent()->alpha());
|
|
|
|
|
2008-01-07 10:26:32 +00:00
|
|
|
if (m_pm != 0)
|
|
|
|
setBackgroundPixmap(m_pm);
|
|
|
|
else
|
|
|
|
setBackgroundColor(m_theme->texture().color());
|
2007-10-13 21:51:37 +00:00
|
|
|
|
2008-01-07 10:26:32 +00:00
|
|
|
setGC(m_theme->text().textGC());
|
|
|
|
setFont(m_theme->text().font());
|
|
|
|
setJustify(m_theme->text().justify());
|
|
|
|
setBorderWidth(m_theme->border().width());
|
|
|
|
setBorderColor(m_theme->border().color());
|
2007-10-13 21:51:37 +00:00
|
|
|
|
2007-11-09 17:30:34 +00:00
|
|
|
updateBackground(false);
|
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
}
|
|
|
|
|
2003-08-11 15:45:50 +00:00
|
|
|
void IconButton::update(FbTk::Subject *subj) {
|
2007-10-13 21:51:37 +00:00
|
|
|
// if the window's focus state changed, we need to update the background
|
|
|
|
if (subj == &m_win.focusSig() || subj == &m_win.attentionSig()) {
|
|
|
|
reconfigTheme();
|
|
|
|
clear();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-12-30 15:32:53 +00:00
|
|
|
// we got signal that either title or
|
|
|
|
// icon pixmap was updated,
|
2003-08-11 15:45:50 +00:00
|
|
|
// so we refresh everything
|
|
|
|
|
2005-04-27 17:45:56 +00:00
|
|
|
Display *display = FbTk::App::instance()->display();
|
|
|
|
int screen = m_win.screen().screenNumber();
|
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
if (m_use_pixmap && m_win.icon().pixmap().drawable() != None) {
|
2003-08-11 15:45:50 +00:00
|
|
|
// setup icon window
|
|
|
|
m_icon_window.show();
|
2006-04-15 16:41:11 +00:00
|
|
|
unsigned int w = width();
|
|
|
|
unsigned int h = height();
|
|
|
|
FbTk::translateSize(orientation(), w, h);
|
|
|
|
int iconx = 1, icony = 1;
|
|
|
|
unsigned int neww = w, newh = h;
|
2006-04-16 11:18:22 +00:00
|
|
|
if (newh > 2*static_cast<unsigned>(icony))
|
2006-04-15 16:41:11 +00:00
|
|
|
newh -= 2*icony;
|
|
|
|
else
|
|
|
|
newh = 1;
|
|
|
|
neww = newh;
|
|
|
|
|
|
|
|
FbTk::translateCoords(orientation(), iconx, icony, w, h);
|
|
|
|
FbTk::translatePosition(orientation(), iconx, icony, neww, newh, 0);
|
2007-12-30 15:32:53 +00:00
|
|
|
|
2006-04-15 16:41:11 +00:00
|
|
|
m_icon_window.moveResize(iconx, icony, neww, newh);
|
2003-08-11 15:45:50 +00:00
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
m_icon_pixmap.copy(m_win.icon().pixmap().drawable(),
|
|
|
|
DefaultDepth(display, screen), screen);
|
2003-10-31 19:32:40 +00:00
|
|
|
m_icon_pixmap.scale(m_icon_window.width(), m_icon_window.height());
|
2003-08-11 15:45:50 +00:00
|
|
|
|
2006-04-15 16:41:11 +00:00
|
|
|
// rotate the icon or not?? lets go not for now, and see what they say...
|
|
|
|
// need to rotate mask too if we do do this
|
|
|
|
m_icon_pixmap.rotate(orientation());
|
|
|
|
|
2003-10-31 19:32:40 +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;
|
|
|
|
}
|
|
|
|
|
2007-10-13 21:51:37 +00:00
|
|
|
if(m_icon_pixmap.drawable() && m_win.icon().mask().drawable() != None) {
|
|
|
|
m_icon_mask.copy(m_win.icon().mask().drawable(), 0, 0);
|
2003-08-12 00:16:16 +00:00
|
|
|
m_icon_mask.scale(m_icon_pixmap.width(), m_icon_pixmap.height());
|
2006-04-15 16:41:11 +00:00
|
|
|
m_icon_mask.rotate(orientation());
|
2003-08-11 15:45:50 +00:00
|
|
|
} else
|
|
|
|
m_icon_mask = 0;
|
|
|
|
|
|
|
|
#ifdef SHAPE
|
2003-08-12 00:16:16 +00:00
|
|
|
|
2006-04-17 23:34:01 +00:00
|
|
|
XShapeCombineMask(display,
|
|
|
|
m_icon_window.drawable(),
|
|
|
|
ShapeBounding,
|
|
|
|
0, 0,
|
|
|
|
m_icon_mask.drawable(),
|
|
|
|
ShapeSet);
|
2003-08-12 00:16:16 +00:00
|
|
|
|
2003-08-11 15:45:50 +00:00
|
|
|
#endif // SHAPE
|
|
|
|
|
2004-06-16 15:38:19 +00:00
|
|
|
if (subj != 0) {
|
|
|
|
setupWindow();
|
|
|
|
} else {
|
|
|
|
m_icon_window.clear();
|
|
|
|
}
|
2008-10-07 21:32:42 +00:00
|
|
|
|
|
|
|
// if the title was changed AND the mouse is over *this,
|
|
|
|
// update the tooltip
|
|
|
|
if (subj == &m_win.titleSig() && m_has_tooltip)
|
|
|
|
showTooltip();
|
2008-05-09 17:39:02 +00:00
|
|
|
|
2003-08-11 15:45:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void IconButton::setupWindow() {
|
2003-10-31 19:32:40 +00:00
|
|
|
m_icon_window.clear();
|
2007-10-13 21:51:37 +00:00
|
|
|
setText(m_win.title());
|
2003-10-31 10:37:09 +00:00
|
|
|
FbTk::TextButton::clear();
|
2003-09-10 21:41:18 +00:00
|
|
|
}
|
|
|
|
|
2005-04-26 01:41:55 +00:00
|
|
|
void IconButton::drawText(int x, int y, FbTk::FbDrawable *drawable) {
|
2003-09-10 21:41:18 +00:00
|
|
|
// offset text
|
2003-11-27 14:30:11 +00:00
|
|
|
if (m_icon_pixmap.drawable() != 0)
|
2005-04-26 01:41:55 +00:00
|
|
|
FbTk::TextButton::drawText(m_icon_window.x() + m_icon_window.width() + 1, y, drawable);
|
2003-11-27 14:30:11 +00:00
|
|
|
else
|
2005-04-26 01:41:55 +00:00
|
|
|
FbTk::TextButton::drawText(1, y, drawable);
|
2003-08-11 15:45:50 +00:00
|
|
|
}
|
2007-12-30 15:32:53 +00:00
|
|
|
|
2006-04-15 16:41:11 +00:00
|
|
|
bool IconButton::setOrientation(FbTk::Orientation orient) {
|
|
|
|
if (orientation() == orient)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (FbTk::TextButton::setOrientation(orient)) {
|
|
|
|
int iconx = 1, icony = 1;
|
|
|
|
unsigned int tmpw = width(), tmph = height();
|
|
|
|
FbTk::translateSize(orient, tmpw, tmph);
|
|
|
|
FbTk::translateCoords(orient, iconx, icony, tmpw, tmph);
|
|
|
|
FbTk::translatePosition(orient, iconx, icony, m_icon_window.width(), m_icon_window.height(), 0);
|
|
|
|
m_icon_window.move(iconx, icony);
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2003-08-11 15:45:50 +00:00
|
|
|
|